Emacs邪恶模式和奴隶

时间:2014-12-15 08:47:47

标签: emacs

我是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)

evil-normal-mode 中,第一行允许我通过点击F7来执行我的Scala代码的类型检查,而第二行允许我通过命令导航到类型/ val定义肌肉记忆Ctrl-](用于VIM中基于标签的导航)。

我唯一的问题是到目前为止我所做的是一个“全局”任务 - 如果我打开一个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的新手,我愿意接受建议......

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

2 个答案:

答案 0 :(得分:1)

您正在寻找的东西称为hook。 emacs运行的大量钩子是具体的时刻,并且可由用户完全自定义。

例如,每当进入模式时,都会运行“模式挂钩”。所以你可以这样做:

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

Hooks是在emacs中定制很多东西的规范方式,并且有很多关于这些的例子。在上面的例子中,我定义了键F3,以便在我处于python模式时执行某些操作。

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

编辑:关于你是否“违反了一些原则”的问题...让我们说因为钩子和设置局部变量的能力,检查文件扩展名以定制行为永远不会(afaik)完成除了设置模式(并在内部完成)。即使检查主模式(最好是检查扩展名)也没有完成,因为它的可扩展性不如仅仅将偏好和功能挂钩到模式中。

答案 1 :(得分:1)

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)

(旁白:我在命令名称前面使用尖引号(#',这是&#34;函数&#34;)的lisp简写而不是普通引号({ {1}})。为了你的目的,这两个基本上是等价的,但是如果你开始字节编译你的设置文件,那么养成前者的习惯会很好,因为字节编译器会警告你如果您使用简单引用,则有问题的函数未定义,但如果您使用简单引用则不会定义。请参阅a related discussion上的Emacs Stack Exchange site。)