Emacs evil-mode and ensime



我是一个VIM的人 - 但是邪恶模式允许我有效地使用Emacs进行Scala开发,它做得非常好,以至于我有点着迷......我想根据自己的喜好自定义环境,所以我将这些添加到我的.emacs

(define-key evil-normal-state-map (kbd "<f7>") 'ensime-typecheck-all)
(define-key evil-normal-state-map (kbd "C-]") 'ensime-edit-definition)

邪恶正常模式下,第一行允许我通过按 F7 对我的 Scala 代码进行类型检查,而第二行通过肌肉记忆Ctrl-](用于 VIM 中基于标签的导航(将我导航到类型/val 定义。

唯一的问题是,到目前为止我所做的是一个"全局"赋值 - 如果我打开一个 Python 文件,我希望 F7 做一个不同的事情(pyflakes 或 pylint(。如何根据我正在查看的缓冲区中当前打开的文件类型为同一键分配不同的操作?

如果有帮助,在我的.vimrc中,我已经通过以下部分完成了此操作:

au BufNewFile,BufRead *.ml call SetupOCamlEnviron()
function! SetupOCamlEnviron()
    se shiftwidth=2
    "
    " Remap F7 to make if the file is an .ml one
    "
    noremap <buffer> <special> <F7> :make<CR>
    noremap! <buffer> <special> <F7> <ESC>:make<CR>
    "
    " Thanks to Merlin
    "
    noremap <buffer> <silent> <F6> :SyntasticCheck<CR>
    noremap! <buffer> <silent> <F6> <ESC>:SyntasticCheck<CR>
    inoremap <buffer> <C-Space> <C-x><C-o>
    noremap <buffer> <C-]> :Locate<CR>
    inoremap <buffer> <C-]> <ESC>:Locate<CR>
endfunction

我如何在 Emacs/evil 中做这种事情?

编辑:为了寻找一种方法来做到这一点,我意识到当在正常模式下按下 F7 时,我可以调度不同的代码 - 所以我写了这个 Emacs lisp:

(defun current-buffer-extension ()
  (if (stringp (buffer-file-name))
    (file-name-extension buffer-file-name) 
    "Unknown"))
(defun handle-f7 ()
  (interactive)
  (if (string= (current-buffer-extension) "scala")
    (ensime-typecheck-all)))
(define-key evil-normal-state-map (kbd "<f7>") 'handle-f7)

。随着我对 Emacs 的了解越来越多,可以通过添加基于文件扩展名的操作来扩展其他工具调用。

作为 Emacs 的新手,我愿意接受建议...

我在这里走在正确的轨道上吗?有没有更好的方法来做我想做的事?我是否通过钩住邪恶正常模式的击键违反了某些原则?

您要查找的东西称为hook。 emacs 运行的钩子有很多特定的时刻,并且完全可以由用户自定义。

例如,每当进入模式时,都会运行"模式钩子"。 所以你可以做:

(add-hook 'python-mode-hook (lambda ()
                        (setq fill-column 79)
                        (local-set-key [(f3)] 'run-flake8)))

钩子是在 emacs 中自定义很多东西的规范方式,关于这些东西的例子很多。 在上面的例子中,我定义了键 F3 来在我处于 python 模式时执行某些操作。

请注意,该示例不处理邪恶的键盘映射,而是使用应该具有首选项的本地键。 如果你想分配一个键来根据邪恶状态做不同的事情,你应该添加一些额外的逻辑,或者使邪恶-X-state-map缓冲区在本地,然后按照你想要的方式改变它(你可以在钩子中做到这一点(

编辑:关于你关于你是否"违反了某些原则"的问题......假设由于钩子和设置局部变量的能力,除了设置模式(这是在内部完成(之外,检查文件扩展名以自定义行为永远不会(AFAIK(。 甚至检查主要模式(比检查扩展更可取(也没有完成,因为它的可扩展性不如将首选项和功能挂钩到模式中。

Evil 对于特定于模式的键绑定有一个有用的工具:evil-define-key 。 作为参数,它需要:

  • 状态(作为引号,在您的情况下,'normal (,
  • 一个不带引号的键盘映射(我不使用ensime,但它可能是类似ensime-mode-map(,
  • 键序列,以及
  • 要绑定的命令。

因此,要使绑定ensime特定于 -(再次,请摆弄特定的映射名称以确保它是正确的(:

(evil-define-key 'normal ensime-mode-map (kbd "<f7>") #'ensime-typecheck-all)
(evil-define-key 'normal ensime-mode-map (kbd "C-]") #'ensime-edit-definition)

您还可以将 f7 绑定到其他内容以用于python(同样,相应地修改映射名称和命令(:

(evil-define-key 'normal python-mode-map (kbd "<f7>") #'run-flake8)
(

旁白:我在命令名称前面使用尖引号(#',这是"函数"的lisp简写(,而不是纯引号('(。就您的目的而言,两者基本上是等价的,但是如果您开始对安装文件进行字节编译,最好养成前者的习惯,因为字节编译器会在您尖引号时警告您有问题的函数是否未定义,但如果您简单引用则不会。 在 Emacs Stack Exchange 站点上查看相关讨论。

最新更新