Emacs Tramp 模式不遵循远程目录中的 .clang-format 文件。

5
我有一个git仓库,里面包含一个.clang-format文件和一个simple.c源代码文件。在本地模式下,也就是从本地硬盘上编辑时,它会遵循样式文件。但是如果我使用tramp模式编辑同一个仓库,那么clang-format将使用一些默认的样式文件(我不知道它是从哪里获取的),并且不会遵循同一远程目录中存在的样式文件。
问题1:我该如何解决这个问题?
问题2:(可能更容易)在tramp-mode下,clang-format默认从哪里获取样式文件?

我猜你正在使用来自 MELPA 的 clang-format.el。虽然我对此一无所知,但简短地浏览了一下该文件,似乎它不支持远程工作。例如,它使用 call-process-region,该函数并不意识到远程主机。 - Michael Albinus
我已经尝试过 tramp-call-process-regiontramp-sh-handle-call-process-region,但都没有成功。据我所知,tramp-mode 会将远程文件复制到 /var 目录下的本地目录中;我还尝试将 .clang-format 放置在 /var 下,但也没有成功。 - Covi
1
不,那不是正确的方法。call-process-region 需要一个对应的 process-file-region,但这个函数并不存在。因此,必须先编写这个函数。 - Michael Albinus
@MichaelAlbinus 我不熟悉 tramp-mode 的工作原理。你能描述一下 process-file-region 的预期功能吗? - Covi
2个回答

4
如果您在本地主机上拥有root权限,则创建目录/ssh:host:,并将远程主机上的.clang-format复制到/ssh:host:/path/to/.clang-format中,将解决此问题。
这是因为Emacs的clang-format包将buffer-file-name传递给本地的clang-format可执行文件,对于远程文件,buffer-file-name是一个Tramp文件名,由Emacs特殊处理,但clang-format不知道。在本地主机上创建具有该确切名称的文件之后,clang-format将能够找到并读取相应的.clang-format配置文件。

3
以下是我的解决方法:
  1. 我将.clang-format文件从远程位置复制到了我的主目录。
  2. 我编写了下面的包装函数,用主目录中同名文件的路径替换了--assume-filename参数:
  (defun my-clang-format-region ()
    (interactive)
    (let ((start (if (use-region-p) (region-beginning) (point)))
          (end (if (use-region-p) (region-end) (point)))
          (assumed-filename (if (file-remote-p buffer-file-name)
                                (concat (getenv "HOME") "/" (file-name-nondirectory buffer-file-name))
                               buffer-file-name)))
      (clang-format-region start end clang-format-style assumed-filename)))
  (global-set-key '[(control meta tab)] 'my-clang-format-region)
--assume-filename似乎可以指定一个不存在的文件路径。所有clang-format关心的是文件的扩展名和目录路径; 它使用目录路径作为查找.clang-format文件的位置。 如果它在那里找不到该文件,则从该位置开始查找每个祖先目录。 在版本9.0和10.0的clang-format可执行文件以及来自melpa的clang-format.el版本20190824.2216中,我成功地使用了这种方法。

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