Snakemake的Emacs模式是什么?

6

snakemake是一个类似于Python的替代make工具,更适用于工作流程而非编译。它非常好用,但也很新,我在Emacs中找不到相应的模式。我只需要一个非常简单的东西:从fundamental-mode稍微修改一下,因此在查看Emacs手册时,我在init.el中开始了以下操作:

(define-derived-mode snake-mode fundamental-mode
   ...
)

和make一样,snakemake对缩进(实际的制表符"\t"字符)非常严格,不是像emacs默认情况下输入TAB时的行为。如果我使用"C-q TAB"键,则会将一个真正的制表符字符放入缓冲区:这个方法可以运行,在fundamental-mode下尝试过Snakefile,运行得很完美。所以为了避免在此模式下每次想要一个TAB时都需要键入"C-q TAB",我想在snake-mode中做的第一个添加就是重新绑定TAB键为"C-q TAB"(或类似的内容)。所以我研究了emacs手册并尝试:

(define-derived-mode snake-mode fundamental-mode
  (global-set-key (kbd "\t") (kbd "C-q \t"))
  ...
)

但这些替代方案都不起作用...也许重新绑定标准键如TAB键并不是一种推荐的做法?
我希望snake-mode的另一个改进是根据python语法进行语法高亮(但不具有任何python行为,例如python缩进行为)。
总之,只需要对fundamental-mode进行这两个简单的修改,创建一个“snake-mode”,并且如果文件名为“Snakefile”,还可以调用snake-mode。但我已经花费了数小时阅读emacs手册和搜索一些内容,似乎还没有接近解决。这很简单,我相信这是可能的。有什么建议吗?
谢谢
默里
4个回答

5

4
下面的(我认为有点优雅...至少很短)权宜之计暂时解决了问题。它确实做到了我所要求的两件事,即(1)重新绑定TAB键(以一种好的方式),并且(2)根据python进行语法高亮(仅在文件名为“Snakefile”时才进入此模式,这很好),因此这回答了我的问题。
; snake-mode
(add-to-list 'auto-mode-alist '("Snakefile" . snake-mode))

(defun insert-tab ()
  (interactive)
  (insert "     ")) ; a "real" tab, i.e., what "C-q \t" would give

(define-minor-mode snake-mode
  "Snakemake."
  :lighter " snake-make"
     (python-mode)
     (setq indent-line-function 'insert-tab)
)

; how to hard-code "\t" to a "real" tab (not recommended)
; (global-set-key "\t" `insert-tab)

; end snake-mode

这是否优雅,我相信还有待商榷。这只是为了寻找适合snakemake的正确模式之旅的开始(该模式可以对诸如“rule”和“output:”等snakemake特定单词进行高亮处理等)。


这个“解决方案”的一个小补充:在emacs中,“insert-tab”函数已经被定义,因此应该使用另一个名称(而不是已经存在的名称)来定义(defun)“snake-tab()”。 - Murray Patterson

1
< p > define-derived-mode 宏会自动提供一个与定义的模式同名的按键映射。您可以使用它和 define-key 一起来使 TAB 键像这样简单地插入一个制表符:

(define-derived-mode snake-mode fundamental-mode "Snake"
  "A mode for Python's snakemake."
  (define-key snake-mode-map "\t" 'self-insert-command))

或者,您可以设置模式的缩进机制,以便在适当时在行首插入(单个)TAB,从而智能缩进一行。这样,您就不必重新绑定TAB,尽管当然实现智能缩进比简单地重新绑定键要困难得多。有关更多信息,请参见lunaryorn的答案。


1
不要这样做。这不是主模式处理缩进的正确方式。它们不应该重新绑定TAB键,参见C-h v indent-line-function:
当前行缩进的函数。此函数将在没有参数的情况下调用。如果在无法进行自动缩进的地方调用它(例如在字符串内部),则函数应该简单地返回“noindent”。设置此函数就足以使TAB键适当地缩进。除非确有必要,否则不要重新绑定TAB键。
无论如何,这种方法都行不通,因为您不能将按键绑定到其他按键。
相反,在您的模式函数中将indent-tabs-mode设置为t,以使Emacs使用制表符进行缩进,并将indent-line-function在缓冲区本地设置为一个根据语言规则适当缩进的函数。显然,您必须自己编写此函数。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接