evil初始state及注释操作问题

使用evil有一小段时间,每个buffer默认使用normal-state不方便,如dired、info等,和原有按键绑定易冲突,临时切到emacs-state当然也是可以的,但是想有个更好的方案。

看evil文档,setq设置变量evil-default-state为“emacs”,打开buffer时modeline没有任何提示显示什么state(以为是evil没加载),拿鼠标选中文本后发现进入了visual-state,按esc也不能退出切到normal,必须c-z切到emacs-state,再切回来进入normal-state,真是越搞越麻烦。evil-default-state不能这么用吗?

第二个问题是注释,vim里有gc操作,evil里好像没实现,翻文档也没找到comment。

第三个问题是motion、replace等少用的state怎么和normal、insert之间切换,文档也没说明。

求助道友。感谢。

evil-set-initial-state is a byte-compiled Lisp function in
‘evil-core.el’.

(evil-set-initial-state MODE STATE)

Set the initial state for major mode MODE to STATE.
This is the state the buffer comes up in.

[back]
  (evil-set-initial-state 'dired-mode 'emacs)
  1. https://www.gnu.org/software/emacs/manual/html_node/emacs/Comment-Commands.html
  2. 你要想打断C-g,motion replace切到normal,insert是什么用例,我好像没用过

initial-state我看过,要想对每种mode都配好,只能上evil-collection。把所有mode的initial-state都设成“emacs”呢怎么操作?和default-state有什么区别?

注释,我是想说evil为啥没有做gc绑定,和vim保持一致。

我目前就是使用 evil collection,体验还不错,以前都是自己一个个去设置,很麻烦

1 个赞

子龙山人的教程有提到,可以这样设置某个mode的默认evil状态

(cl-loop for (mode . state) in
	 '((org-agenda-mode . normal)
	   (lsp-bridge-ref-mode . emacs)
	   (eshell-mode . emacs)
	   (magit-mode . emacs)
	   )
	 do (evil-set-initial-state mode state))

另外下面这个函数也比较有用,让q对于只读的buffer也是delete-buffer

(defun smart-q ()
  "Delete window in read-only buffers, otherwise record macro."
  (interactive)
  (if buffer-read-only
      (if (= 1 (count-windows))
          (bury-buffer)
        (delete-window))
    (call-interactively 'evil-record-macro)))
(define-key evil-normal-state-map (kbd "q") 'smart-q)

代码注释的话用这个插件

(use-package evil-nerd-commenter
  :after (evil)
  :ensure t
  :config (evilnc-default-hotkeys))

第三个问题你得说下具体的场景吧,一般没有这种使用的需求。

1 个赞

看来非evil-collection不可了

注释,不记得在哪儿抄过smart-comment-or-uncomment-region,目前对于我是够用了,emacs内部也有注释命令,我只是想搞清楚,evil为啥没有做gc健绑定。

第三个,场景是误操作,自己都没明白怎么进去的,回不来,evil文档只介绍这几个state,没说咋切换。

smart-q,纯好奇,用:q不行吗?

可以呀,但是按一下q更方便,和emacs state下保持一致。而且只读buffer也用不到宏操作

我的办法:

(setq evil-emacs-state-modes nil
      evil-motion-state-modes nil)
(evil-define-key* 'normal dired-mode-map  ","  dired-mode-map)

配合 which-key-mode ,还可以展示按键提示,省得记。 还可以自定义自己喜欢的按键,因为原生的按键已经有了引导键,没大的冲突:

(evil-define-key* 'normal dired-mode-map
    "." 'find-file
    "e" 'wdired-change-to-wdired-mode
    "h" 'dired-up-directory
    "j" 'dired-next-line
    "k" 'dired-previous-line
    "n" 'evil-ex-search-next
    "N" 'evil-ex-search-previous)
1 个赞

不要再一直强调gc了,vim没有这个命令,你用的是vim插件给你的

2 个赞

你最好使用一个发行版, 例如我的配置, https://github.com/redguardtoo/emacs.d,这些问题都早已解决了. 技术细节见lisp/init-evil.el

我的配置通过modeline的颜色来提示当前的state.

gc我配置为调用插件evil-nerd-commenter的命令

切换状态和vim按键没什么两样.不太明白你的问题是什么, emacs用户会额外使用一个evil-escape的插件.

其他发行版如spacemacs或doomemacs配置也类似.

1 个赞

用 evil collection 吧。大部分的非文本模式的快捷键配置的都挺好的。少部分的在进入主模式的时候加个钩子设置为 emacs state 就好了。

1 个赞

和我个人使用习惯有关系吧,不喜欢直接套发行版配置,一是不喜欢装太多插件,尤其是不了解或是工作流中碰不到的,不想把emacs整得过于庞大复杂,一切尽可能内置插件,用不上的诸如日历、计算器、org等恨不得删掉;二是他人的配置,不了解配置思路,不易理解,无法掌控,小部分配置倒是可以抄一抄。

注释用visual-block模式或者visual-line模式

  • visual-block:先把光标置于行首,然后C-v,上下移动光标选择范围,按i进入insert,输入注释,ESC退出
  • visual-line:S-v之后选择行,按I行首输入注释,ESC退出

另外真的没必要排斥evil-collection,我之前用evil的时候光按键绑定就1k多行,除非你的绑定习惯和evil-colletion很不一样否则没必要自己搞

1 个赞

C-v进入visual-block之后,按i并没有切到insert,报错“i ; is undefined”,按x删除字符倒是可以。

S-v进入visual-line后,上下移动选择多行,按I切到insert,但是只有一行生效。

用大写的I进入吧

1 个赞

写错了,C-v是按大写I进入,S-v这个操作仅限evil-mode,vim和nvim都不支持

C-v进入visual-block之后,上下移动选择多行,按I切到insert,但是只有一行生效。

S-v进入visual-line后,上下移动选择多行,按I切到insert,但是只有一行生效。

我太傻了,直到昨天看到一个动图这样操作,原来我是最后没有按esc退出,所以没看到生效,只看到当前行编辑。

我太傻了。 :rofl:

visual block操作可以了,visual line还是无效的。