5

I have a git repo with a .clang-format and a simple.c source code. In local mode, namely editing off local disk, it respects the style file. However if I edit using tramp mode the same repo, then clang-format will format the source code using some default style file (I don't know where it's picked up), and will NOT honor the style file existing in the same remote directory.

Q1: How do I fix this?

Q2: (Maybe it's easier) Where does clang-format in tramp-mode pick up the style file by default?

Covi
  • 1,331
  • 1
  • 14
  • 17
  • I suppose you're using `clang-format.el` from MELPA. I don't know anything about, but scanning this file shortly it looks like it doesn't support remote work. For example, it uses `call-process-region`, which isn't aware of remote hosts. – Michael Albinus Feb 08 '18 at 07:33
  • I've tried `tramp-call-process-region` and `tramp-sh-handle-call-process-region`; both didn't work. As I understand it, `tramp-mode` copies the remote file to a local directory under `/var`; I've also tried placing `.clang-format` under `/var` to no avail. – Covi Feb 26 '18 at 01:50
  • 1
    No, that's not the way. `call-process-region` would need a counterpart `process-file-region`, which doesn't exist. So one must write this function first. – Michael Albinus Feb 26 '18 at 07:38
  • @MichaelAlbinus I'm not familiar with how tramp-mode works. Could you describe what the supposed functionality of `process-file-region` would be? – Covi Feb 27 '18 at 17:15

2 Answers2

4

If you have root permissions on the local host, creating a directory /ssh:host: and copying .clang-format from the remote host to /ssh:host:/path/to/.clang-format will solve the issue.

This is because clang-format package for Emacs passes buffer-file-name to the local clang-format executable, and for remote files buffer-file-name is a Tramp file name, which is handled specially by Emacs, but is unknown to clang-format. Nothing prevents you from creating a file with that exact name on the local host, after which clang-format will be able to find and read the corresponding .clang-format config file.

eush77
  • 3,870
  • 1
  • 23
  • 30
3

Here's how I was able to work around this issue:

  1. I copied the .clang-format file from the remote location into my home directory.
  2. I wrote the following wrapper function to replace the --assume-filename argument with a path referring to a file with the same name in the home directory:
  (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)

It seems that --assume-filename can specify a path to a file that doesn't exist. All clang-format seems to care about is the file's extension and directory path; it uses the directory path as a location to look for the .clang-format file. If it doesn't find the file there, it looks in every ancestor directory starting from that location.

This worked for me with versions 9.0 and 10.0 of the clang-format executable, and clang-format.el version 20190824.2216 from melpa.

richls
  • 31
  • 3