作为资深vimer(到底多深呢? 配置vim为c/c++集成开发环境,采用了
taglist+project+mur+alter+highlight+grepit 插件,除taglist插件因太大,
其它均阅读掌握了源码,配置为自己顺手的模式,可以写vim 插件,
使用vim 得心应手!vim 是编辑器之神!)
初学emacs 会觉得很多地方需要改进,
有一些基本功能必需要调整的, 以使其更容易使用
我知道有vimer 模式, 不过,要学emacs, 我需要自己折腾....
前言:由于要定制的比较多,是一组按键,所以要找一个前缀键。
C-z 就很合适,原来意思是挂起emacs, 用途不大,就选它了。
(define-prefix-command 'ctlz-map)
(global-set-key (kbd "C-z") ctlz-map)
------------------------------------------------------------
1.怀念vim 的f 前向搜索,F 后向 到某个特定字符,按;继续查找下一个字符
没有它我活不下去. emacs按M-f, C-f 太没有效率了!
emacs 如何实现?
------------------------------------------------------------
emacs 添加如下函数,并绑定到C-z f 键C-z F键
(defun my-go-to-char (char)
"Move forward to CHAR.
Typing CHAR again will move forwad to the next occurence of CHAR."
(interactive "cGo to char: ")
(let ((case-fold-search nil))
(search-forward (string char) nil nil 1)
(backward-char)
(while (equal (read-key) char)
(forward-char)
(search-forward (string char) nil nil 1)
(backward-char))
)
(setq unread-command-events (list last-input-event)))
(defun my-backward-go-to-char (char)
"Move backward to CHAR.
Typing CHAR again will move backward to the next occurence of CHAR."
(interactive "cGo to char: ")
(let ((case-fold-search nil))
;; backward
(search-backward (string char) nil nil )
(while (equal (read-key) char)
(search-backward (string char) nil nil )))
(setq unread-command-events (list last-input-event)))
(global-set-key (kbd "C-z f") 'my-go-to-char)
(global-set-key (kbd "C-z F") 'my-backward-go-to-char)
------------------------------------------------------------
2. 怀念vim 的ma, mA 等标记位置寄存器,‘a,'A 可以跳转回。
emacs 可以用C-x r SPACE x 来标记, C-x r j 来转回,但是
效率是差了不少。
怎样调整emacs 的临时标记功能?
C-z. 做标记
C-z, 来回跳转
------------------------------------------------------------
(global-set-key "\C-z." 'my-point-to-register)
(global-set-key "\C-z," 'my-jump-to-register)
(defun my-point-to-register()
"Store cursor position to a register.
Use my-jump-to-register to jump back to the stored
position."
(interactive)
(setq zmacs-region-stays t)
(point-to-register 8))
(defun my-jump-to-register()
"Switches between current cursor position and position
that was stored with my-point-to-register."
(interactive)
(setq zmacs-region-stays t)
(let ((tmp (point-marker)))
(jump-to-register 8)
(set-register 8 tmp)))
------------------------------------------------------------
3. 怀念vim 的H,M,L 光标到屏幕顶,中间,底部。
emacs M-r 只能依次到屏幕中,上,底。(加上前缀参数,也可勉强抗衡..)
答案: 绑定到C-zh, C-zm, C-zl 上,用如下代码 (也不用如此挑剔!)
------------------------------------------------------------
;;C-zh, C-zm, C-zl 类似于vim的H,M,L
(global-set-key (kbd "C-z h") 'cursor-to-top-of-window)
(global-set-key (kbd "C-z m") 'cursor-to-middle-of-window)
(global-set-key (kbd "C-z l") 'cursor-to-bottom-of-window)
(defun cursor-to-top-of-window()
"Move cursor to top of window."
(interactive)
(move-to-window-line 0))
(defun cursor-to-bottom-of-window()
"Move cursor to bottom of window."
(interactive)
(move-to-window-line -1))
(defun cursor-to-middle-of-window()
"Move cursor to middle of window."
(interactive)
(move-to-window-line nil))
------------------------------------------------------------
4. 怀念vim 的zT ,zz功能,把屏幕从光标处上滚到顶部和中部,方便阅读。
emacs 如何实现? C-l 加前缀参数勉强可以抗衡, 但...
答案: 绑定到C-zt, C-zb, C-zz上,用如下代码 (纯emacser 也不要如此挑剔!)
------------------------------------------------------------
;; C-zt, C-zb C-zz 类似于vim 的zt, zb ,zz
(global-set-key (kbd "C-z t") 'line-to-top-of-window)
(global-set-key (kbd "C-z b") 'line-to-bottom-of-window)
(global-set-key (kbd "C-z z") 'line-to-center-of-window)
; replace C-u 0 C-l
(defun line-to-top-of-window ()
"Move the line point is on to top of window."
(interactive)
(recenter 0))
; replace C-u - C-l
(defun line-to-bottom-of-window ()
"Move the line point is on to botton of window."
(interactive)
(recenter -1))
(defun line-to-center-of-window ()
"Move the line point is on to center of window."
(interactive)
(recenter ))
----------------------------------------
5. 怀念vim % 可以跳转到匹配的括号,
Emacs: 按 C-M-f 和 C-M-b (太麻烦了?,消灭C-M)
----------------------------------------
实现:取巧的办法,添加一个函数,绑定到% 键上
当%在括号上按下时,那么匹配括号,否则输入一个%,
这样保留了默认输入%的功能
(global-set-key "%" 'match-paren)
(defun match-paren (arg) "Go to the matching parenthesis if on parenthesis otherwise insert %." (interactive "p") (cond ((looking-at "\\s\(") (forward-list 1) (backward-char 1)) ((looking-at "\\s\)") (forward-char 1) (backward-list 1)) (t (self-insert-command (or arg 1)))))
------------------------------------------------------------
6. 怀念vim 的yy copy整行命令,dd 删除整行命令
emacs C-a 跳到行首,C-S-2 设定区块, C-e跳到行尾 M-w copy,
C-w 删除.
效率是差了不少,怎么改进呢?
------------------------------------------------------------
改进M-w 和 C-w 键邦定函数,使支持行操作。
;; copy region or whole line
(global-set-key "\M-w"
(lambda ()
(interactive)
(if mark-active
(kill-ring-save (region-beginning)
(region-end))
(progn
(kill-ring-save (line-beginning-position)
(line-end-position))
(message "copied line")))))
;; kill region or whole line
(global-set-key "\C-w"
(lambda ()
(interactive)
(if mark-active
(kill-region (region-beginning)
(region-end))
(progn
(kill-region (line-beginning-position)
(line-end-position))
(message "killed line")))))
最后: 如果你觉得折腾的差不多了的时候。
嫌emacs 启动慢,改进!
emacs 服务器模式启动: emacs --daemon
服务器启动加到系统启动里,例如~/.profile中
emacs 客户端启动: emacsclient -t
这样就块多了
如此emacs 的使用顺手多了,可以与vim 相抗衡,但是,且慢...
我的vim 有那么多插件为它插上翅膀,使它成为c/c++集成环境,
emacs 也需要插件帮手,才能与之抗衡,且看下集....