emacs按键绑定详解
key-binding:
https://crazylxr.github.io/spacemacas-zh_CH-doc/binding-keys.html
概述:Emacs的键绑定方式看起来花样繁多,其本质上都是同一个机制
(define-key keymap key def)
这里的key是你要绑定的键。keymap是这个key所属的集合,不同的keymap决定了这个key在什么情况下触发,什么情况下隐藏,优先级如何。def代表了这个key的定义,它可以是很多东西,常见的有
- 一个interactive function,即一个command,这也是键绑定最直接的方式。
- 一个key,仅对于keymap为'key-translation-map这种情况,意味着映射到另一个键。
- 一个keymap,通过这种方式用户可以自定义prefix key。
- 一个nil,代表注销这个key。
keymap也有很多种,如(current-global-map)返回全局keymap,(current-local-map)返回局部keymap。对于这两种情况,Emacs提供了更直接的函数:'global-set-key和'local-set-key。另外还有上面提到的key-translation-map,以及许多minor-mode下定义的keymap。
这四种不同种类的keymap,正代表了Emacs里常见的四种不同的快捷键设置方式。虽然看起来较为复杂繁琐,但如果配合巧妙,完全可以实现一键多用,让用户做到在不使用Ctrl键、不叠加修饰键,不连击超过两次组合键,甚至不开Evil的前提下,执行Emacs连同各种插件包里所支持的所有编辑命令。
一、key-translation-map,优先级最高
(define-key key-translation-map (kbd "your-key") (kbd "target-key"))
你在任何时候按下"your-key",编辑器将执行"target-key"所绑定的命令。无论当时处于何种编辑状态,是否有minor-mode触发,该映射都不受影响,属于优先级最高的键绑定方式。
特点:由于映射键是完全的跳转到了另一个键上,所以一旦目标键的定义发生了变化,该键也会随之受到影响。
注销方式:把这个key重新映射为它自己。
适用情况:
- 常用的、重要的,但按键较为复杂的命令,如"C-x C-s"固定的绑定的'save-buffer,"C-M-i"固定绑定的'completion-at-point,"C-M-%"固定绑定的'query-replace-regexp。你可以用更简单的键来映射它们。
- 常用的,重要的,但在不同mode下会发生变动的命令,如常规编辑中的"C-g"对应的是'keyboard-quit,在minibuffer下会变成'minibuffer-keyboard-quit。如果你将某个键绑定为'keyboard-quit,你会发现它在minibuffer下就没法用了。对于这种情况,最好的办法就是直接映射。
二、minor-mode-map,优先级第二
(define-key some-minor-mode-map (kbd "your-key") 'your-command)
一般而言,大部分Emacs用户没有自定义minor-mode的需求,往往也不知道怎么定义,但minor-mode-map对所有用户而言并不陌生,最常见的便是在isearch-mode下的'isearch-repeat-forward和'isearch-repeat-backward。
当你按"C-s"触发isearch-mode并搜索某段文字的时候,重复按"C-s"将跳转到下一个匹配,看起来是顺理成章的事其实对应的是两个不同的函数。之所以这里能一键多用,是因为在'isearch-mode触发同时也激活了它的minor-mode-map,也就是'isearch-mode-map,它里边将"C-s"绑定到了'isearch-repeat-forward上,在激活状态下便覆盖掉了它的初始定义'isearch-forward。
特点:仅在minor-mode激活时有效,定义方便且优先级高,不用担心键冲突。
注销方式:绑定为nil。
适用情况:
- 各种系统自带minor-mode如'isearch-mode,'query-replace,'edmacro-mode
- 各种常见插件如'cua--rect,'with-editor
- 自定义minor-mode
三、local-set-key,优先级第三
(local-set-key (kbd "your-key") 'your-command)
local-set-key主要是在各种major-mode下使用,一般是通过hook设置
(add-hook 'some-major-mode-hook '(lambda () (local-set-key ...)))
特点:通过这种方式设置的键绑定仅在该major-mode下生效,不影响其他major-mode,实惠好用。
注销方式:绑定为nil,或者
(local-unset-key (kbd "your-key")
适用情况:
- 在不同major-mode下调用类似的命令,如运行当前文件,当前选区,当前行等等,在不同的语言做的是类似的事情,所以可通过这种方式把不同的命令绑定到同一个键上。
- 通过hook来local-set-key本质上修改的只是一个变量(如果该变量不存在自动创建),不需要提前加载对应的major-mode,相比直接定义该mode下的各种keymap更加安全。
四、global-set-key,优先级最低
(global-set-key (kbd "your-key") 'your-command)
特点:最简单的键绑定方式,一行搞定,无须关心到底是哪个keymap。然而需小心在某些major-mode时会被覆盖。
注销方式:绑定为nil,或者
(global-unset-key (kbd "your-key")
适用情况:
- 一些不常用的命令
- 一些冷门的按键
需要注意的是
对于上述不同优先级的键绑定方式,其对应的逆操作(即注销键)也遵循同样的优先级,例如注销了minor-mode的快捷键,它便会恢复为当前major-mode下的定义,如果当前major-mode下没有定义,那便执行全局默认的命令。
键冲突问题
尽管已有如此多的键绑定方式,由于Emacs默认的键布局已十分紧张,用户往往容易碰到各种各样的键冲突问题。
比如你想设置一个快捷键,使它在任何情况下都绑定为一个固定的命令。如果你用global-set-key,那它有可能会被其他major-mode覆盖;如果你用key-translation-map,它所映射的那个键同样可能被覆盖;如果你用local-set-key,那你不得不在所有出问题的major-mode里挨个设置。你该怎么办?——可以暂时参考本专栏之前的一篇文章:快捷键(一)
又比如你写了一个minor-mode,你想定义一个快捷键让它执行"C-g"的功能,正常编辑时为'keyboard-quit,在minibuffer下则为'minibuffer-keyboard-quit。但遗憾的是minor-mode里是不支持键的映射的,你又该怎么办?——我会在新的文章中分享解决方案。
相关文章
快捷键篇:
Emacs常见键绑定方式汇总
快捷键(一)(待整合)
快捷键(二) (待整合)
个人配置文件
https://github.com/wolray/emacs.d
在emacs中我们可以将一个交互式的命令绑定到一个按键序列中。比如C-x C-f就绑定了命令find-file,而一般的字母和数字则绑定到了self-insert命令。使用这一个方式我们就可以做很灵活的绑定,让那些我们经常使用的命令绑定到非常方便的key sequence上面。这种命令绑定是通过key-map数据结构实现的。但是我们知道在emacs之中存在不同的major mode和minor mode,而且不同key-sequence的长度也不相同,那么这些因素对键盘绑定有什么影响呢?
1. 存在不同major mode和minor mode对命令绑定的影响
一个很明显的需求就是同样的key sequence在不同的major mode和minor mode中绑定不同的命令。这样就产生了一个全局key-map和局部key-map的需求,全局key-map只有一个,但是不同的major mode 和 minor mode都有一个自己的key-map。当你编辑的文件处于某个major-mode,并启用了一些minor-mode时,只有相关的minor-mode key-map,major-mode key-map和global key-map是可以影响到key-sequence的解释的。当需要给出一个key-sequence所绑定的命令时,首先搜索minor-mode的key-map,然后是major-mode的key-map,最后是global-key-map;当在前一个key-map中找不到时,才会到后一个key-map中寻找。当需要定义全局的key-map时可以使用global-set-key这个函数,如果需要定义局部key-map,使用local-set-key。
2. key-sequence长度对键盘映射的影响
有些键盘操作只需一次即可完成某个命令,比如C-f,C-b;但是另外一些则需要多次的按键,比如打开文件的命令C-x C-f就需要两个键盘操作。一个key-map数据结构只能对一个按键操作映射,因此需要多个键盘操作的命令需要多个key-map,而且第一个键盘操作绑定的不是一个命令,而是另外一个key-map,后面的按键就是根据这个key-map来找到要绑定对象。对于C-x C-f操作,定义了一个global key-map,将C-x绑定到ctl-x-map中,注意这个ctl-x-map并不是一个可执行的emacs函数,而是一个key-map,在这个key-map里面,C-f绑定到了命令find-file,因此按下C-x C-f这个key-sequence时,有两个key-map,而且涉及到了两个绑定。这里C-x就被叫做prefix-key,这里的意思就是这个key只是命令的前缀,但是具体的是那个命令还需要继续给出其他的key才可以。
在emacs中定义了很多这样的prefix-key,比如C-x,Esc,C-x 4,C-x 5,M-g,C-c等等,每一个prefix-key都绑定到一个key-map上面。在相应的key-map用于解释紧接着prefix-key的绑定,这样一直循环下去,直到最后一个key-map将一个key绑定到一个命令上,输入完成之后就执行。
那么global key-map,local key-map跟这些prefix-key绑定到的key-map有什么区别和联系吗?首先这些都是key-map数据结构,作用都是为了完成键的映射。不同的major mode和minor mode都有自己的local key-map,global key-map则只有一个。可以在local key-map里创建prefix-key,也可以在global key-map里创建prefix-key。(note!prefix-key所绑定的是一个key-map,但是prefix-key同样也是一个key,也必须在某个local key-map或者global key-map里创建才行)。
3. 如何创建prefix-key
简单一个函数(define-prefix-command 'key-map-name),然后绑定键值到新建的key-map就可以了。加入我们想把C-r C-t C-z a绑定到find-file命令。a. (define-prefix-command 'ctl-r-map); (local-set-key (kbd "C-r") 'ctl-r-map); (local-set-key (kbd "C-r C-t C-z a") 'find-file);这样就可以使用C-r C-t C-z a来打开文件了。但是在这里需要说明几点a. 如果已经存在相应的prefix-key定义,不需要重新重新创建,如果不存在,那么必须首先创建prefix-key b. 可以看到C-r C-t也是一个prefix-key,C-r C-t C-z也是prefix-key,这些都是emacs自动创建的,当我们也可以自己动手。所以对于一连串的key sequence,只需要对第一个key创建prefix-key就可以了。
相关文章:

【面试】重建二叉树
一、描述 输入某二叉树的前序遍历和中序遍历的结果,请重建出该二叉树,假设输入的前序遍历和中序遍历的结果中都不含重复的数字,例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出该二叉树。二叉树结…

【ACM】杭电OJ 2034
开了三个数组 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <set> #include <algorithm> using namespace std; const int maxn 105; int a[maxn],b[maxn],c[maxn];…

Android 依赖库发布(上传 Library 到 JCenter)gradle最高支持4.4
1.注册 Bintray 注册时要注意哦,千万不要注册成组织的账户,一定要注册为个人。因为组织账户只有一个月的免费使用时间。 个人账户注册地址:bintray.com/signup/oss 有Github、Google、Twitter账号的可以直接登录哦 2.创建Maven仓库࿰…

emacs参考资料整理
spacemacs dired模式用法: https://blog.slegetank.com/blog/20170106-dired.htmlEmacs文件管理神器--dired常用操作说明 - 暗无天日快捷键用法:https://yuyang0.github.io/notes/spacemacs.htmlemacs官方参考手册:https://www.gnu.org/software/emacs/m…

Codeigniter文件上传类型不匹配错误
Codeigniter的文件上传类方便了我们使用PHP来处理文件上传的操作,使用起来非常简单,如下:$config[upload_path] ./uploads/;$config[allowed_types] gif|jpg|png;$config[max_size] 100;$config[max_width] 1024;$config[max_height] …

【ACM】杭电OJ 2036(待更)
AC代码 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <set> #include <algorithm> using namespace std; const int maxn 105; double a[maxn][3]; int main () {in…

Spring_boot_pom.xml和启动方式
spring-boot-starter-parent 整合第三方常用框架信息(各种依赖信息) spring-boot-starter-web 是Springboot整合SpringMvc Web 实现原理:Maven依赖继承关系 相当于把第三方常用maven依赖信息,在parent项目中已经封装好了 提供依赖信息关联整合的jar包 springboot中快速原理…

ubuntu18安装virtualbox
1. 报错No rule to make target arch/x86/tools/relocs_32.c 解决办法:sudo apt install linux-source sudo apt-get install linux-headers-5.4.0-42:i386 安装步骤: https://blog.csdn.net/AAMahone/article/details/86428040 安装完成后&…
10分钟学会php面相对象基础(Ⅰ)
<?php 声明一个类 class mycar{ etc. //成员方法 } class mycar{ function drive(){ etc. } } ?> 对象的实例化 内存中分栈和堆,栈定长,堆较大不能直接访问。实例化后,实例名称放在栈内,实例放在堆内,通过实例…

【ACM】杭电OJ 2039
先让啊、三边边长a,b,c按从小到大顺序排列,然后再用两边之和大于第三边,两边之差小于第三边来判断 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib&…

AI一周热闻:GitHub免费开放无限私有库;苹果市值蒸发超450亿美元;小米入股TCL...
CES 2019:英伟达发布RTX 2060和RTX 2080移动版小米入股TCL,增强供应链话语权苹果市值蒸发价值超过Facebook,全球市值第一不保GitHub开放无限私有仓库免费使用英特尔和Facebook等发布计算机视觉系统测试新基准旷视创建高性能的“姿态估计”网络…

ubuntu使用相关
ubuntu查看显卡驱动并安装适配的显卡驱动https://blog.csdn.net/qiancaobaicheng/article/details/95096354ubuntu20设置openssl tls versionhttps://www.coder.work/article/7495451

Atitit.提升 升级类库框架后的api代码兼容性设计指南
Atitit.提升 升级类库框架后的api代码兼容性设计指南 1. 增加api直接增加,版本号在注释上面增加1 2. 废弃api,使用主见dep1 3. 修改api,1 4. 修改依赖import,雅瑶增加文件模式。保持兼容性。。1 5. 优先选择同一个文件内的修改&am…
【ACM】杭电OJ 2040
第一个程序是 15MS #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <set> #include <algorithm> using namespace std; const int maxn 600000; int vis[maxn]; int ma…

阿里云 Aliplayer高级功能介绍(二):缩略图
为什么80%的码农都做不了架构师?>>> 基本介绍 Aliplayer提供了缩略图的功能,让用户在拖动进度条之前知道视频的内容,用户能够得到很好的播放体验,缩略图是显示在Controlbar的上面,并且包含当前的时间&…

【ACM】杭电OJ 2044 2045
一开始全部使用int型,显示WA,百度之后,要全部改成long long 两个题都是死在long long 上 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <s…

POJO、JavaBean、DAO
POJO POJO全称是Plain Ordinary Java Object / Plain Old Java Object,中文可以翻译成:普通Java类,具有一部分getter/setter方法的那种类就可以称作POJO。一般在web应用程序中建立一个数据库的映射对象时,我们只能称它为POJO。 Ja…

jupyter notebook用法积累(快捷键)
打开Anaconda promt,如果想把代打都存在H:\python\py,则输入命令 h: 回车进入h盘,再输入 cd python\py回车就进入这个H:\python\py目录下再输入jupter notebook 回车就打开了浏览器 ctrl回车 可以当前块运行࿰…

android资料整理
1. android native内存分析:全民K歌Android端Native内存分析与监控方案实践总结 - 知乎一、背景在2020年的上半年,我们在用户反馈后台发现闪退、白屏问题不断增多,这些问题严重影响用户体验。观察Crash监控平台发现Crash率也在逐步升高,其中N…

Java读取property配置文件
读取配置文件已经成了Java程序员工作的一项必备技能。 配置文件的优点: 可维护性好 怎么个可维护性好呢? 它会让程序中变化的地方很灵活的配置,不需要修改代码。Java程序部署到服务器上去之后就变成了class文件,修改困难…

【ACM】杭电OJ 2048 2049
两题均是错排公式与阶乘的运用 2048算的是一个比例,2049计算的是一个事情发生的总数 一个用double 来存放数据,一个用long long来存放数据 2048 #include <iostream> #include <cstdio> #include <cstring> #include <cmath&g…

百度成立小度蓝牙联盟,DMA+小度App打造蓝牙语音风口
人机交互经历了三个阶段键鼠、触屏和语音交互。在国外,谷歌、亚马逊、苹果等巨头的竞争已经到达白热化状态;在国内,百度的DuerOS正是这方面的一位大玩家。 在技术发展的各个时代中,提前入局的厂商,必然能够第一时间享…

ptam tracking
并行追踪与制图(Parallel Tracking and Mapping)简称PTAM,于2007年由英国牛津大学主动视觉实验室的Georg Klein和David Murray提出。PTAM在机器导航,机器探索,人机互动,三维重建等方面都有应用。在这之前已…
【ACM】杭电OJ 2050
直线: 平行线 折线 #include <iostream> #include <cstdio> #include <cstring> #include <cmath> #include <cstdlib> #include <algorithm> using namespace std; int main () {int n,m;scanf("%d",&n);while…

ASP.NETCore学习记录(一)
ASP.NETCore学习记录(一) asp.net core介绍 Startup.cs ConfigureServices Configure 0. ASP.NETCore 介绍 ASP.NETCore是一个新的开源和跨平台的框架,用于构建如Web应用、物联网(IoT)应用和移动后端应用等连接到互联网的基于云的现代应用程序。ASP.NET …

ptam程序流程
程序运行基本流程:Step1: System::System(){ 1、注册一系列命令、添加相对应的功能按钮。 2、创建摄像机mpCamera new ATANCamera("Camera"); 实现的功能包括:加载camera.cfg配置文件中的摄像机内参(mvFocal[0]、mvFocal[1]、mvCe…

js / jquery 零散收集
2019独角兽企业重金招聘Python工程师标准>>> <select id"typeSelector" οnchange"choiceoption(this.options[this.options.selectedIndex])"> <option id"xx" value"a">A</option> </select> &…

【ACM】杭电OJ 2057
思路: 本题注意十六进制的输入输出格式。 注意: 1.别忘了需要用__int64,因为数据比较大; 2.两数相加为负数的时候,想着分开考虑。 #include <iostream> #include <cstdio> #include <cstring> #…

OpenCV学习系列教程第五篇:测试和提高代码的效率
Opencv-Python学习系列教程第五篇 来自opencv-python官方学习文档,本人谨做翻译和注释,以及一些自己的理解 本文由作者翻译并进行代码验证,转载请注明出处~ 官方文档请参阅:https://docs.opencv.org/4.0.1/dc/d71/tutorial_py_opt…

ORB-SLAM论文翻译
ORB-SLAM: a Versatile and Accurate Monocular SLAM System 原文发表于:IEEE Transactions on Robotics (Impact Factor: 2.43). 10/2015 摘要: 本文主要讲了ORB-SLAM,一个基于特征识别的单目slam系统,可以实时运行࿰…