【问题标题】:Emacs evil-mode and ensimeEmacs 邪恶模式和 ensime
【发布时间】:2014-12-15 08:47:47
【问题描述】:

我是一个 VIM 人 - 但是 evil-mode 让我能够高效地使用 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 代码进行类型检查,而第二行通过肌肉记忆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 的新手,我愿意接受建议...

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

【问题讨论】:

    标签: emacs


    【解决方案1】:

    你要找的东西叫做hook。 emacs 运行的许多钩子都是特定时刻的,并且完全可以由用户自定义。

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

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

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

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

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

    【讨论】:

    • 建议不要将 lambdas 放入模式挂钩中,以便在点击 C-h k 时获得调用的函数名称。同样,您应该向模式映射添加新绑定,而不是在模式挂钩中添加本地密钥(因为每次加载模式时都会添加本地密钥,从而使您的挂钩复杂化)
    【解决方案2】:

    Evil 为特定模式的键绑定提供了有用的工具:evil-define-key。作为参数,它需要:

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

    所以,让你的绑定ensime-specific(再次,摆弄特定的地图名称以确保它是正确的):

    (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 site 上的a related discussion。)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-06-18
      • 2012-05-01
      • 2014-05-17
      • 1970-01-01
      • 2016-07-17
      • 1970-01-01
      相关资源
      最近更新 更多