Emacs 如何根据文件位置运行钩子

Emacs 如何根据文件位置运行钩子,emacs,elisp,Emacs,Elisp,我参与了使用制表符的python项目,但我并没有在我编写的所有其他代码中使用制表符,在特定的项目中使用制表符是至关重要的。项目位于特定目录下的一个目录中。即: \main_folder \project1 \project2 \project3 ...etc 我在打开的文件上有两个函数/钩子,并保存我处理的整个缓冲区的untabify和tabify ;; My Functions (defun untabify-buffer () "Untab

我参与了使用制表符的python项目,但我并没有在我编写的所有其他代码中使用制表符,在特定的项目中使用制表符是至关重要的。项目位于特定目录下的一个目录中。即:

\main_folder
    \project1
    \project2
    \project3
...etc
我在打开的文件上有两个函数/钩子,并保存我处理的整个缓冲区的untabify和tabify

 ;; My Functions
(defun untabify-buffer ()
            "Untabify current buffer"
        (interactive)
        (untabify (point-min) (point-max)))

(defun tabify-buffer ()
        "Tabify current buffer"
        (interactive)
        (tabify (point-min) (point-max)))

;; HOOKS
; untabify buffer on open
(add-hook 'find-file-hook 'untabify-buffer)
; tabify on save
(add-hook 'before-save-hook 'tabify-buffer)

如果我把它放在.emacs文件中,它会在我打开的每个.py文件上运行,这不是我想要的。我想让这些钩子只在一个特定的文件夹中使用,其中包含相应的子文件夹。尝试了.dir\u局部变量,但它仅适用于属性,而不适用于挂钩。我不能在特定模式(即python模式)中使用钩子,因为几乎所有项目都是用python编写的。老实说,我尝试编写elisp条件保存,但失败了。

一个非常简单的解决方案是只添加一个可用于禁用挂钩的配置变量。例如:

(defvar tweak-tabs t)
(add-hook 'find-file-hook
          (lambda () (when tweak-tabs (untabify (point-min) (point-max)))))
(add-hook 'before-save-hook
          (lambda () (when tweak-tabs (tabify (point-min) (point-max)))))
现在,您可以在相关目录中添加一个
.dir locals.el
文件,将
tweak tabs
设置为
nil
,在那里禁用此功能


(但另一个问题是,这是处理选项卡的一种非常糟糕的方法。例如,保存文件后,您确实会看到其中的选项卡。)

仅为记录,回答标题中的文字问题(当我通过web搜索找到此问题时):添加依赖于文件位置的钩子的一种方法是使其成为检查
缓冲区文件名的函数。(这是我的想法。)

例如,对于完全相同的问题(仅在特定目录中打开选项卡,而在其他目录中关闭选项卡),我目前正在执行类似的操作(在使用
m-x package install安装
安装软件包
智能选项卡模式
后):


(这有点颠倒,因为
智能标签暗示了
本身修改了
python模式钩子,然后我们将其修改回来,但它应该作为一个示例。)

谢谢。这实际上是我问题的答案,但你提出了一个很好的观点。保存后,我会在缓冲区中设置标签。我做了一些调查,因为我想钩住函数来杀死缓冲区或杀死emacs,但不幸的是,它们是在文件已经保存之后运行的。如果只有在kill buffer或kill emacs的情况下,才有可能实际检查在buffer和aply函数上调用了“save”的内容。在这种情况下,您还有其他建议或经验吗?我可能会从
编写文件函数开始,然后让它创建一个缓冲区副本,将其制表,保存并返回
t
。另请参见,尽管他们不这样做,因为他们希望缓冲区保持不变。
(smart-tabs-insinuate 'python) ; This screws up all Python files (inserts tabs)
(add-hook 'python-mode-hook    ; So we need to un-screw most of them
          (lambda ()
            (unless (and (stringp buffer-file-name)
                         (string-match "specialproject" buffer-file-name))
              (setq smart-tabs-mode nil)))
          t)                   ; Add this hook to end of the list