-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support formatting remote files with Tramp #76
Conversation
CLOSES radian-software#33 Adds support for formatting remote files. The new `apheleia-remote-algorithm` option configures this. The default behaviour is consistent with what we had before, with `apheleia` aborting a formatting when dealing with a remote file/buffer. Users can customise apheleia to run the formatter on the remote machine, in which case any temporary files or other checks such as `npx` will be fully handled on the remote machine. Users can also make apheleia run the formatter on the local machine. This works exactly like one would expect, except if the formatter requires access to the physical file (meaning it uses 'file in `apheleia-formatters`) because the file isn't available on the local machine. This PR also fixes a bug in apheleia where `input-fname` was assigned in local let scope, instead of being returned by `apheleia--format-command`, meaning any formatters using a 'input file weren't cleaned up after formatting.
I've tested this by ssh-ing into my own machine within emacs and using tramp. I've found both |
If a file being diffed is remote, but the program is being run locally, then we create a temporary file on the current machine.
I also found and fixed a bug where if we created a file for the |
Thank you! I made a couple of stylistic changes; do those look okay to you? If so then I can go ahead and merge this. |
Also, looks like linting was failing on Emacs 25 because |
Probably should wait until we've addressed why running formatter processes on the remote hangs sometimes. That's still an issue. I can run the process on the local machine for remote buffers, but if I try to run it on the remote machine it never manages to finish. The other day it hanged at the formatter stage, and not the diff one, so I'm not sure what's really causing it. We could also disable the running on remote functionality, and merge in running apheleia on remote buffers with local processes (that's honestly fine for my use-case), but I'd like to fix this if we can. |
This is actually the bug that is more concerning to me. When formatting a remote buffer on save, I get this: And then if saying yes, then the following backtrace: Backtrace
This occurs only when the formatting operation needs to change the buffer. |
It looks like what's happening there is that since we are running the formatter asynchronously, but all TRAMP commands share a common connection process, we try to I'd like to take a look at a couple other issues before investigating this further, but thought I would drop my findings here. |
Yeah, damn, I'm encountering this issue as well. From this issue it looks like there isn't much library writers can do to work around this atm. On the apheleia side we might be able to pool pending writes into a queue and only write one at a time, but no solution seems very practical from my POV. Might be worth closing this issue |
@PythonNut I know you've done a lot of work with TRAMP and were the original person to request remote file formatting support; any thoughts on if there's a good workaround for this issue? |
What do you think about making apheleia blocking if run remotely? The main issue at this stage is the user could modify the file whilst its being formatted or a myriad of other tramp issues stepping over each other. If apheleia locked emacs while it was formatting it should fix most of those issues, and that's better than just refusing to run altogether or throwing errors while saving. |
I mean, if we previously didn't have any support for remote formatting, and we add support in a degraded mode, then it seems like an improvement to me. I think anything involving tramp always involves some synchronous waiting, unfortunately, just due to the way they've designed things. So it's kind of par for the course. Be warned though, I've tried on a number of occasions over the years to synchronously wait for You're probably best off adding a higher-level interface that will delegate calls either to |
Okay, I got started on it but this is kind of a nightmare 😱. The interface for
That means if there's a STDIN buffer and we're running the formatter remotely then there's no way to execute it and pass standard input without first saving stdin on the remote and then doing some funky sort of subshell redirection. |
Also added a metadata field to function based formatters.
What I have now should work, but it's failing with black because TRAMP seems to be including some junk at the end of the copied file :/. |
apheleia.el
Outdated
(with-current-buffer stdin | ||
(apheleia--write-region-silently nil nil | ||
remote-stdin)) | ||
|
||
(process-file | ||
shell nil (nth 2 args) nil "-c" shell-command)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Copying happens here, black is saying error: cannot format -: '\x1b'
and the remote file ends with a ^[[0m
for some reason/
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Weird -- one thing I'll note is \x1b[0m
is the ANSI control sequence for "reset color" -- maybe TRAMP adds that for some reason because it's trying to reuse the same shell session and doesn't want the color to be messed up by a poorly behaved program?
Thanks! I should be able to take a look at this next weekend and see if I can help resolve the outstanding issues. |
Interesting, what you have now actually does seem to work for me as is! It takes forever to do all the round-tripping, but I am able to format a Python file over TRAMP using the Here's a sample Python file that formats successfully using this method: https://github.com/raxod502/radian/blob/58ba58bd827e719c0eeb3d3c996d59cf4d00acd5/scripts/print_env.py Do you perhaps have a different buffer coding system? Maybe you are using the |
Hmm... I'm using sshx (ssh has pretty never worked for me). Maybe it's because I'm configured to use both black and isort with apheleia. I'll try with just black a little later and see whether it's a chained formatter issue. Edit: Yep, black by itself works. When I try to run isort then black ( |
Hmm, that's odd, I still can't reproduce. I set (setq apheleia-remote-algorithm 'remote)
(setf (alist-get 'python-mode apheleia-mode-alist) '(isort black)) and verified that Maybe you have a different version of Black? I know Black likes to use escape sequences to colorize stuff and do emojis and stuff, so maybe somehow that's getting triggered in your setup and not mine? |
I have |
You might be able to get rid of this by customizing the value of |
I tried that before commenting it but sadly it didn't work. My guess is it's not tramp outputting the message, it's rename-file or whatever other command is calling tramp under the hood.
Good suggestion, I'll try that out :-). |
Also fixed any linter complaints.
Yep, I managed to suppress the annoying messages. It took a while, and is slow as hell, but we can finally format remote buffers with apheleia. I'm hoping docker-tramp is much more performant than sshx for this (since that's what I'm planning to use it with). Let me know if there's anything else you'd like to get worked on with this PR, otherwise I think it's ready to merge :-). |
Update: I just noticed |
More re-entrant tramp issues.
Okay, what I have now should work but the code is really tangly so it might need a good refactoring to make it easier to understand. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Aside from my one comment below, this looks great, thank you!
apheleia.el
Outdated
@@ -690,6 +901,8 @@ formatter being run, for diagnostic purposes." | |||
(unwind-protect | |||
(funcall callback scratch) | |||
(kill-buffer scratch))) | |||
;; A metadata field | |||
`((remote . ,remote)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this changing the expected interface of Elisp-based formatters? If so we would want to update the docstring of apheleia-formatters
and announce a breaking change.
If we are making a breaking change anyway, it might be a good time to make the interface extensible, by saying that the function must receive its parameters using keyword arguments, and ignore any unknown keys.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, I didn't think anyone had had a chance to use it yet but I definitely should've mentioned my most recent commits had a breaking change like this. Good job on spotting it.
If we are making a breaking change anyway, it might be a good time to make the interface extensible, by saying that the function must receive its parameters using keyword arguments, and ignore any unknown keys.
That would work. I was basically going down that route already by having an alist of optional parameters, but having nice deconstruction with key-value pairs would definitely be better. When I get a chance I'll refactor what I've implemented, make the interface switch to what you've suggested and then update the PR :-).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like functional formatters are still unreleased (in the CHANGELOG), so is a breaking change still necessary?
I'm extremely excited about this change - it might turn apheleia into the single autoformatting emacs mode that can deal with remote files (: So, I tried this out and there's a bit of an annoying issue that I haven't debugged fully yet: Accessing a linux box from a macOS-based emacs, it tries to write files to a macOS-specific temporary directory (which isn't set up on the linux side):
Update: This is fixed with |
Could invoke |
So, funny story, I looked at |
Deal with very slowly, but yes that is the hope 😂.
Good spot, I didn't notice this existed. I'll update the PR to use that over an apheleia specific wrapper. |
+ Reordered parameters to ensure remote always comes before callback. + Updated some docstrings.
We don't always want to create a temporary file on the remote, only when apheleia-remote-algorithm is 'remote.
Okay. I've tried refactoring (as best as I can) but its mostly identical since the high level flow between the functions is the same. I did rename some of the process oriented functions to make their behaviour a little clearer (but it might be just as confusing 😓). I've adapted I've tested all these changes using isort+black both locally and on a remote machine with sshx using both I'd suggest maybe keeping this PR open for a little while to test (since we've had multiple issues prop up in actual usage) before merging. But otherwise, fingers crossed, I think this is finally ready 😩. |
I pulled this in, removed my I'll work with this for few more days (working on nix, prettier-formatted typescript, yaml and rustfmt-formatted rust); if something should look weird, I'll let you know here. |
Hmmm... I'm encountering this error while running apheleia locally (not through tramp). Debugger entered--Lisp error: (error "process apheleia-diff no longer connected to pipe; closed it")
process-send-string(#<process apheleia-diff> #("\"\"\"\nConnect to the database and get infor..." 0 2 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil) 2 3 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil syntax-table (15)) 3 152 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil) 152 153 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil syntax-table (15)) 153 155 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil) 155 157 (fontified nil) 157 163 (face tree-sitter-hl-face:keyword fontified nil) 163 176 (fontified nil) 176 182 (face tree-sitter-hl-face:keyword fontified nil) 182 192 (fontified nil) 192 198 (face tree-sitter-hl-face:keyword fontified nil) 198 204 (fontified nil) 204 210 (face tree-sitter-hl-face:keyword fontified nil) 210 221 (fontified nil) 221 227 (face tree-sitter-hl-face:keyword fontified nil) 227 236 (fontified nil) ...))
apheleia--make-process(:name "apheleia-diff" :stdin #<buffer group_config.py> :stdout #<buffer *apheleia-diff-stdout*> :stderr #<buffer *apheleia-diff-stderr*> :command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleiaiJNsm7") :remote nil :noquery t :callback #f(compiled-function (proc-exit-status) #<bytecode -0xfed67df59ad9fc5>))
apheleia--execute-formatter-process(:command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleiaiJNsm7") :stdin #<buffer group_config.py> :callback #f(compiled-function (patch-buffer) #<bytecode -0x6d3b376c77c055b>) :remote nil :ensure #f(compiled-function () #<bytecode -0x1fa365b9d834b280>) :exit-status #f(compiled-function (status) #<bytecode -0x1d95bbb5ac5fb746>))
apheleia--create-rcs-patch(#<buffer group_config.py> #<buffer *apheleia-black-stdout*> nil #f(compiled-function (patch-buffer) #<bytecode -0x6d3b376c77c055b>))
#f(compiled-function (formatted-buffer) #<bytecode 0x13d4b009a176819d>)(#<buffer *apheleia-black-stdout*>)
#f(compiled-function (stdout) #<bytecode -0x1c46680c0673027b>)(#<buffer *apheleia-black-stdout*>)
#f(compiled-function (stdout) #<bytecode -0xa45069ec37881d3>)(#<buffer *apheleia-black-stdout*>)
#f(compiled-function (proc-exit-status) #<bytecode -0x846ca31eb9b4a11>)(0)
#f(compiled-function (proc event) #<bytecode 0x1c56358a7501e31d>)(#<process apheleia-black> "finished\n") I'll try loading apheleia directly (without byte compiling) to get a more helpful error message. Edit: Here it is: Debugger entered--Lisp error: (error "Process apheleia-diff not running")
process-send-string(#<process apheleia-diff> #("\"\"\"\nConnect to the database and get infor..." 0 2 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil) 2 3 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil syntax-table (15)) 3 152 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil) 152 153 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil syntax-table (15)) 153 155 (face (tree-sitter-hl-face:doc tree-sitter-hl-face:string) fontified nil) 155 157 (fontified nil) 157 163 (face tree-sitter-hl-face:keyword fontified nil) 163 176 (fontified nil) 176 182 (face tree-sitter-hl-face:keyword fontified nil) 182 192 (fontified nil) 192 198 (face tree-sitter-hl-face:keyword fontified nil) 198 204 (fontified nil) 204 210 (face tree-sitter-hl-face:keyword fontified nil) 210 221 (fontified nil) 221 227 (face tree-sitter-hl-face:keyword fontified nil) 227 236 (fontified nil) ...))
(progn (set-process-coding-system proc nil (buffer-local-value 'buffer-file-coding-system stdin)) (process-send-string proc (save-current-buffer (set-buffer stdin) (buffer-string))))
(if stdin (progn (set-process-coding-system proc nil (buffer-local-value 'buffer-file-coding-system stdin)) (process-send-string proc (save-current-buffer (set-buffer stdin) (buffer-string)))))
(let ((proc (make-process :name name :buffer stdout :stderr stderr :command command :file-handler remote :noquery noquery :sentinel #'(lambda (proc _event) (if (process-live-p proc) nil (funcall callback ...)))))) (set-process-sentinel (get-buffer-process stderr) #'ignore) (if stdin (progn (set-process-coding-system proc nil (buffer-local-value 'buffer-file-coding-system stdin)) (process-send-string proc (save-current-buffer (set-buffer stdin) (buffer-string))))) (process-send-eof proc) proc)
(progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:name :stdin :stdout :stderr :command :remote :noquery :callback :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:name :stdin :stdo..." (car --cl-keys--)))))) (let ((proc (make-process :name name :buffer stdout :stderr stderr :command command :file-handler remote :noquery noquery :sentinel #'(lambda (proc _event) (if ... nil ...))))) (set-process-sentinel (get-buffer-process stderr) #'ignore) (if stdin (progn (set-process-coding-system proc nil (buffer-local-value 'buffer-file-coding-system stdin)) (process-send-string proc (save-current-buffer (set-buffer stdin) (buffer-string))))) (process-send-eof proc) proc))
(let* ((name (car (cdr (plist-member --cl-rest-- ':name)))) (stdin (car (cdr (plist-member --cl-rest-- ':stdin)))) (stdout (car (cdr (plist-member --cl-rest-- ':stdout)))) (stderr (car (cdr (plist-member --cl-rest-- ':stderr)))) (command (car (cdr (plist-member --cl-rest-- ':command)))) (remote (car (cdr (plist-member --cl-rest-- ':remote)))) (noquery (car (cdr (plist-member --cl-rest-- ':noquery)))) (callback (car (cdr (plist-member --cl-rest-- ':callback))))) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '...) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:name :stdin :stdo..." (car --cl-keys--)))))) (let ((proc (make-process :name name :buffer stdout :stderr stderr :command command :file-handler remote :noquery noquery :sentinel #'(lambda ... ...)))) (set-process-sentinel (get-buffer-process stderr) #'ignore) (if stdin (progn (set-process-coding-system proc nil (buffer-local-value 'buffer-file-coding-system stdin)) (process-send-string proc (save-current-buffer (set-buffer stdin) (buffer-string))))) (process-send-eof proc) proc)))
apheleia--make-process(:name "apheleia-diff" :stdin #<buffer group_config.py> :stdout #<buffer *apheleia-diff-stdout*> :stderr #<buffer *apheleia-diff-stderr*> :command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") :remote nil :noquery t :callback (closure ((log-name . " *apheleia-diff-log*") (stderr . #<buffer *apheleia-diff-stderr*>) (stdout . #<buffer *apheleia-diff-stdout*>) (name . "diff") (formatter) (exit-status closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...))) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) (status) (memq status '(0 1))) (ensure closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...))) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) nil (let ((--dolist-tail-- clear-files)) (while --dolist-tail-- (let (...) (condition-case nil ... ...) (setq --dolist-tail-- ...))))) (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch ... patch-buffer) (if callback ...))))) (remote) (stdin . #<buffer group_config.py>) (command "diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") (--cl-rest-- :command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") :stdin #<buffer group_config.py> :callback (closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash ...) (progn ... ...)))) :remote nil :ensure (closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure (... ... ... ... ... ... t) (patch-buffer) (save-current-buffer ... ...)) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) nil (let ((--dolist-tail-- clear-files)) (while --dolist-tail-- (let ... ... ...)))) :exit-status (closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure (... ... ... ... ... ... t) (patch-buffer) (save-current-buffer ... ...)) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) (status) (memq status '(0 1)))) t) (proc-exit-status) (let ((exit-ok (funcall (or exit-status #'zerop) proc-exit-status))) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer (set-buffer (get-buffer-create log-name)) (special-mode) (save-restriction (widen) (let (... ... ... ...) (goto-char ...) (skip-chars-backward "\n") (delete-region ... ...) (if ... nil ...) (if exit-ok nil ...) (insert ... " :: " ... "\n$ " ... "\n\n" ... "\n\n" "Command " ... " with exit code " ... ".\n") (goto-char ...) (goto-char ...))))) (if formatter (progn (run-hook-with-args 'apheleia-formatter-exited-hook :formatter formatter :error (not exit-ok) :log (get-buffer log-name)))) (unwind-protect (if exit-ok (if callback (progn (funcall callback stdout))) (message (concat "Failed to run %s: exit status %s " "(see %s %s)") (car command) proc-exit-status (if (string-prefix-p " " log-name) "hidden buffer" "buffer") (string-trim log-name))) (if ensure (progn (funcall ensure))) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil))))))
funcall(apheleia--make-process :name "apheleia-diff" :stdin #<buffer group_config.py> :stdout #<buffer *apheleia-diff-stdout*> :stderr #<buffer *apheleia-diff-stderr*> :command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") :remote nil :noquery t :callback (closure ((log-name . " *apheleia-diff-log*") (stderr . #<buffer *apheleia-diff-stderr*>) (stdout . #<buffer *apheleia-diff-stdout*>) (name . "diff") (formatter) (exit-status closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...))) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) (status) (memq status '(0 1))) (ensure closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...))) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) nil (let ((--dolist-tail-- clear-files)) (while --dolist-tail-- (let (...) (condition-case nil ... ...) (setq --dolist-tail-- ...))))) (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch ... patch-buffer) (if callback ...))))) (remote) (stdin . #<buffer group_config.py>) (command "diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") (--cl-rest-- :command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") :stdin #<buffer group_config.py> :callback (closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash ...) (progn ... ...)))) :remote nil :ensure (closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure (... ... ... ... ... ... t) (patch-buffer) (save-current-buffer ... ...)) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) nil (let ((--dolist-tail-- clear-files)) (while --dolist-tail-- (let ... ... ...)))) :exit-status (closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure (... ... ... ... ... ... t) (patch-buffer) (save-current-buffer ... ...)) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) (status) (memq status '(0 1)))) t) (proc-exit-status) (let ((exit-ok (funcall (or exit-status #'zerop) proc-exit-status))) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer (set-buffer (get-buffer-create log-name)) (special-mode) (save-restriction (widen) (let (... ... ... ...) (goto-char ...) (skip-chars-backward "\n") (delete-region ... ...) (if ... nil ...) (if exit-ok nil ...) (insert ... " :: " ... "\n$ " ... "\n\n" ... "\n\n" "Command " ... " with exit code " ... ".\n") (goto-char ...) (goto-char ...))))) (if formatter (progn (run-hook-with-args 'apheleia-formatter-exited-hook :formatter formatter :error (not exit-ok) :log (get-buffer log-name)))) (unwind-protect (if exit-ok (if callback (progn (funcall callback stdout))) (message (concat "Failed to run %s: exit status %s " "(see %s %s)") (car command) proc-exit-status (if (string-prefix-p " " log-name) "hidden buffer" "buffer") (string-trim log-name))) (if ensure (progn (funcall ensure))) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil))))))
(setq apheleia--current-process (funcall (if remote #'apheleia--call-process #'apheleia--make-process) :name (format "apheleia-%s" name) :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback #'(lambda (proc-exit-status) (let ((exit-ok (funcall ... proc-exit-status))) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer (set-buffer ...) (special-mode) (save-restriction ... ...))) (if formatter (progn (run-hook-with-args ... :formatter formatter :error ... :log ...))) (unwind-protect (if exit-ok (if callback ...) (message ... ... proc-exit-status ... ...)) (if ensure (progn ...)) (condition-case nil (progn ...) (error nil)) (condition-case nil (progn ...) (error nil)))))))
(progn (setq apheleia--current-process (funcall (if remote #'apheleia--call-process #'apheleia--make-process) :name (format "apheleia-%s" name) :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback #'(lambda (proc-exit-status) (let ((exit-ok ...)) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer ... ... ...)) (if formatter (progn ...)) (unwind-protect (if exit-ok ... ...) (if ensure ...) (condition-case nil ... ...) (condition-case nil ... ...)))))))
(condition-case e (progn (setq apheleia--current-process (funcall (if remote #'apheleia--call-process #'apheleia--make-process) :name (format "apheleia-%s" name) :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback #'(lambda (proc-exit-status) (let (...) (if ... nil ...) (if formatter ...) (unwind-protect ... ... ... ...)))))) ((debug error) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil)) (message "Failed to run %s: %s" name (error-message-string e))))
(let* ((name (file-name-nondirectory (car command))) (stdout (generate-new-buffer (format " *apheleia-%s-stdout*" name))) (stderr (generate-new-buffer (format " *apheleia-%s-stderr*" name))) (log-name (format "%s*apheleia-%s-log*" (if apheleia-hide-log-buffers " " "") name))) (condition-case e (progn (setq apheleia--current-process (funcall (if remote #'apheleia--call-process #'apheleia--make-process) :name (format "apheleia-%s" name) :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback #'(lambda (proc-exit-status) (let ... ... ... ...))))) ((debug error) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil)) (message "Failed to run %s: %s" name (error-message-string e)))))
(progn (if (process-live-p apheleia--current-process) (progn (message "Interrupting %s" apheleia--current-process) (interrupt-process apheleia--current-process) (accept-process-output apheleia--current-process 0.1 nil 'just-this-one) (if (process-live-p apheleia--current-process) (progn (kill-process apheleia--current-process))))) (let* ((name (file-name-nondirectory (car command))) (stdout (generate-new-buffer (format " *apheleia-%s-stdout*" name))) (stderr (generate-new-buffer (format " *apheleia-%s-stderr*" name))) (log-name (format "%s*apheleia-%s-log*" (if apheleia-hide-log-buffers " " "") name))) (condition-case e (progn (setq apheleia--current-process (funcall (if remote #'apheleia--call-process #'apheleia--make-process) :name (format "apheleia-%s" name) :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback #'(lambda ... ...)))) ((debug error) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil)) (message "Failed to run %s: %s" name (error-message-string e))))))
(progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '(:command :stdin :remote :callback :ensure :exit-status :formatter :allow-other-keys)) (setq --cl-keys-- (cdr (cdr --cl-keys--)))) ((car (cdr (memq ... --cl-rest--))) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:command :stdin :r..." (car --cl-keys--)))))) (progn (if (process-live-p apheleia--current-process) (progn (message "Interrupting %s" apheleia--current-process) (interrupt-process apheleia--current-process) (accept-process-output apheleia--current-process 0.1 nil 'just-this-one) (if (process-live-p apheleia--current-process) (progn (kill-process apheleia--current-process))))) (let* ((name (file-name-nondirectory (car command))) (stdout (generate-new-buffer (format " *apheleia-%s-stdout*" name))) (stderr (generate-new-buffer (format " *apheleia-%s-stderr*" name))) (log-name (format "%s*apheleia-%s-log*" (if apheleia-hide-log-buffers " " "") name))) (condition-case e (progn (setq apheleia--current-process (funcall (if remote ... ...) :name (format "apheleia-%s" name) :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback #'...))) ((debug error) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil)) (message "Failed to run %s: %s" name (error-message-string e)))))))
(let* ((command (car (cdr (plist-member --cl-rest-- ':command)))) (stdin (car (cdr (plist-member --cl-rest-- ':stdin)))) (remote (car (cdr (plist-member --cl-rest-- ':remote)))) (callback (car (cdr (plist-member --cl-rest-- ':callback)))) (ensure (car (cdr (plist-member --cl-rest-- ':ensure)))) (exit-status (car (cdr (plist-member --cl-rest-- ':exit-status)))) (formatter (car (cdr (plist-member --cl-rest-- ':formatter))))) (progn (let ((--cl-keys-- --cl-rest--)) (while --cl-keys-- (cond ((memq (car --cl-keys--) '...) (setq --cl-keys-- (cdr ...))) ((car (cdr ...)) (setq --cl-keys-- nil)) (t (error "Keyword argument %s not one of (:command :stdin :r..." (car --cl-keys--)))))) (progn (if (process-live-p apheleia--current-process) (progn (message "Interrupting %s" apheleia--current-process) (interrupt-process apheleia--current-process) (accept-process-output apheleia--current-process 0.1 nil 'just-this-one) (if (process-live-p apheleia--current-process) (progn (kill-process apheleia--current-process))))) (let* ((name (file-name-nondirectory (car command))) (stdout (generate-new-buffer (format " *apheleia-%s-stdout*" name))) (stderr (generate-new-buffer (format " *apheleia-%s-stderr*" name))) (log-name (format "%s*apheleia-%s-log*" (if apheleia-hide-log-buffers " " "") name))) (condition-case e (progn (setq apheleia--current-process (funcall ... :name ... :stdin stdin :stdout stdout :stderr stderr :command command :remote remote :noquery t :callback ...))) ((debug error) (condition-case nil (progn ...) (error nil)) (condition-case nil (progn ...) (error nil)) (message "Failed to run %s: %s" name (error-message-string e))))))))
apheleia--execute-formatter-process(:command ("diff" "--rcs" "--strip-trailing-cr" "--" "/home/mkaleem2/prog/repos/..." "/tmp/apheleia99PfyF") :stdin #<buffer group_config.py> :callback (closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch (current-buffer) patch-buffer) (if callback (progn (funcall callback))))))) :remote nil :ensure (closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch ... patch-buffer) (if callback ...))))) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) nil (let ((--dolist-tail-- clear-files)) (while --dolist-tail-- (let ((file (car --dolist-tail--))) (condition-case nil (progn (delete-file file)) (error nil)) (setq --dolist-tail-- (cdr --dolist-tail--)))))) :exit-status (closure ((run-on-remote) (clear-files "/tmp/apheleia99PfyF") (new-fname . "/tmp/apheleia99PfyF") (old-fname . "/home/mkaleem2/prog/repos/...") (callback closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch ... patch-buffer) (if callback ...))))) (remote) (new-buffer . #<buffer *apheleia-black-stdout*>) (old-buffer . #<buffer group_config.py>) t) (status) (memq status '(0 1))))
(let ((old-fname (save-current-buffer (set-buffer old-buffer) (and (not (buffer-modified-p)) buffer-file-name))) (new-fname (save-current-buffer (set-buffer new-buffer) (and (not (buffer-modified-p)) buffer-file-name))) (clear-files nil) (run-on-remote (and (eq apheleia-remote-algorithm 'remote) remote))) (let* ((--cl-apheleia--make-temp-file-for-rcs-patch-- #'(lambda (buffer &optional fname) (let (...) (if ... ...) (apheleia--strip-remote fname))))) (progn (setq old-fname (funcall --cl-apheleia--make-temp-file-for-rcs-patch-- old-buffer old-fname) new-fname (funcall --cl-apheleia--make-temp-file-for-rcs-patch-- new-buffer new-fname)) (if (or old-fname new-fname) nil (setq new-fname (funcall --cl-apheleia--make-temp-file-for-rcs-patch-- "apheleia"))))) (apheleia--execute-formatter-process :command (list "diff" "--rcs" "--strip-trailing-cr" "--" (or old-fname "-") (or new-fname "-")) :stdin (if new-fname old-buffer new-buffer) :callback callback :remote remote :ensure #'(lambda nil (let ((--dolist-tail-- clear-files)) (while --dolist-tail-- (let (...) (condition-case nil ... ...) (setq --dolist-tail-- ...))))) :exit-status #'(lambda (status) (memq status '(0 1)))))
apheleia--create-rcs-patch(#<buffer group_config.py> #<buffer *apheleia-black-stdout*> nil (closure ((formatted-buffer . #<buffer *apheleia-black-stdout*>) (remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch (current-buffer) patch-buffer) (if callback (progn (funcall callback))))))))
(progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote #'(lambda (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--apply-rcs-patch ... patch-buffer) (if callback ...)))))))
(if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote #'(lambda (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash ...) (progn ... ...)))))))
(save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote #'(lambda (patch-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...)))))))
(closure ((remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (formatted-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote #'(lambda ... ...))))))(#<buffer *apheleia-black-stdout*>)
funcall((closure ((remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (formatted-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote #'(lambda ... ...)))))) #<buffer *apheleia-black-stdout*>)
(if (cdr formatters) (apheleia--run-formatters (cdr formatters) buffer remote callback stdout) (funcall callback stdout))
(closure ((command "black" "--line-length" "79" "-") (stdin . #<killed buffer>) (callback closure ((remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (formatted-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote ...))))) (remote) (buffer . #<buffer group_config.py>) (formatters black) t) (stdout) (if (cdr formatters) (apheleia--run-formatters (cdr formatters) buffer remote callback stdout) (funcall callback stdout)))(#<buffer *apheleia-black-stdout*>)
funcall((closure ((command "black" "--line-length" "79" "-") (stdin . #<killed buffer>) (callback closure ((remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (formatted-buffer) (save-current-buffer (set-buffer cur-buffer) (if (equal apheleia--buffer-hash (apheleia--buffer-hash)) (progn (apheleia--create-rcs-patch cur-buffer formatted-buffer remote ...))))) (remote) (buffer . #<buffer group_config.py>) (formatters black) t) (stdout) (if (cdr formatters) (apheleia--run-formatters (cdr formatters) buffer remote callback stdout) (funcall callback stdout))) #<buffer *apheleia-black-stdout*>)
(closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure ((command "black" "--line-length" "79" "-") (stdin . #<killed buffer>) (callback closure ((remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (formatted-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...))) (remote) (buffer . #<buffer group_config.py>) (formatters black) t) (stdout) (if (cdr formatters) (apheleia--run-formatters (cdr formatters) buffer remote callback stdout) (funcall callback stdout))) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) (stdout) (if output-fname (progn (erase-buffer) (insert-file-contents-literally output-fname))) (funcall callback stdout))(#<buffer *apheleia-black-stdout*>)
funcall((closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure ((command "black" "--line-length" "79" "-") (stdin . #<killed buffer>) (callback closure ((remote) (cur-buffer . #<buffer group_config.py>) (formatters isort black) (callback) (formatter isort black) t) (formatted-buffer) (save-current-buffer (set-buffer cur-buffer) (if ... ...))) (remote) (buffer . #<buffer group_config.py>) (formatters black) t) (stdout) (if (cdr formatters) (apheleia--run-formatters (cdr formatters) buffer remote callback stdout) (funcall callback stdout))) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) (stdout) (if output-fname (progn (erase-buffer) (insert-file-contents-literally output-fname))) (funcall callback stdout)) #<buffer *apheleia-black-stdout*>)
(progn (funcall callback stdout))
(if callback (progn (funcall callback stdout)))
(if exit-ok (if callback (progn (funcall callback stdout))) (message (concat "Failed to run %s: exit status %s " "(see %s %s)") (car command) proc-exit-status (if (string-prefix-p " " log-name) "hidden buffer" "buffer") (string-trim log-name)))
(unwind-protect (if exit-ok (if callback (progn (funcall callback stdout))) (message (concat "Failed to run %s: exit status %s " "(see %s %s)") (car command) proc-exit-status (if (string-prefix-p " " log-name) "hidden buffer" "buffer") (string-trim log-name))) (if ensure (progn (funcall ensure))) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil)))
(let ((exit-ok (funcall (or exit-status #'zerop) proc-exit-status))) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer (set-buffer (get-buffer-create log-name)) (special-mode) (save-restriction (widen) (let ((inhibit-read-only t) (orig-point (point)) (keep-at-end (eobp)) (stderr-string (save-current-buffer ... ...))) (goto-char (point-max)) (skip-chars-backward "\n") (delete-region (point) (point-max)) (if (bobp) nil (insert "\n\n\f\n")) (if exit-ok nil (if apheleia--last-error-marker nil (setq apheleia--last-error-marker ...) (move-marker apheleia--last-error-marker ...))) (insert (current-time-string) " :: " (buffer-local-value 'default-directory stdout) "\n$ " (mapconcat #'shell-quote-argument command " ") "\n\n" (if (string-empty-p stderr-string) "(no output on stderr)" stderr-string) "\n\n" "Command " (if exit-ok "succeeded" "failed") " with exit code " (number-to-string proc-exit-status) ".\n") (goto-char (if keep-at-end (point-max) (min ... orig-point))) (goto-char (point-max)))))) (if formatter (progn (run-hook-with-args 'apheleia-formatter-exited-hook :formatter formatter :error (not exit-ok) :log (get-buffer log-name)))) (unwind-protect (if exit-ok (if callback (progn (funcall callback stdout))) (message (concat "Failed to run %s: exit status %s " "(see %s %s)") (car command) proc-exit-status (if (string-prefix-p " " log-name) "hidden buffer" "buffer") (string-trim log-name))) (if ensure (progn (funcall ensure))) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil))))
(closure ((log-name . " *apheleia-black-log*") (stderr . #<buffer *apheleia-black-stderr*>) (stdout . #<buffer *apheleia-black-stdout*>) (name . "black") (formatter . black) (exit-status) (ensure closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure ... ... ...) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) nil (condition-case nil (progn ... ...) (error nil))) (callback closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure ... ... ...) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) (stdout) (if output-fname (progn ... ...)) (funcall callback stdout)) (remote) (stdin . #<killed buffer>) (command "black" "--line-length" "79" "-") (--cl-rest-- :command ("black" "--line-length" "79" "-") :stdin #<killed buffer> :callback (closure (... ... ... ... ... ... ... ... ... ... ... t) (stdout) (if output-fname ...) (funcall callback stdout)) :ensure (closure (... ... ... ... ... ... ... ... ... ... ... t) nil (condition-case nil ... ...)) :remote nil :formatter black) t) (proc-exit-status) (let ((exit-ok (funcall ... proc-exit-status))) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer (set-buffer ...) (special-mode) (save-restriction ... ...))) (if formatter (progn (run-hook-with-args ... :formatter formatter :error ... :log ...))) (unwind-protect (if exit-ok (if callback ...) (message ... ... proc-exit-status ... ...)) (if ensure (progn ...)) (condition-case nil (progn ...) (error nil)) (condition-case nil (progn ...) (error nil)))))(0)
funcall((closure ((log-name . " *apheleia-black-log*") (stderr . #<buffer *apheleia-black-stderr*>) (stdout . #<buffer *apheleia-black-stdout*>) (name . "black") (formatter . black) (exit-status) (ensure closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure ((command "black" "--line-length" "79" "-") (stdin . #<killed buffer>) (callback closure ... ... ...) (remote) (buffer . #<buffer group_config.py>) (formatters black) t) (stdout) (if (cdr formatters) (apheleia--run-formatters ... buffer remote callback stdout) (funcall callback stdout))) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) nil (condition-case nil (progn (if input-fname (progn ...)) (if output-fname (progn ...))) (error nil))) (callback closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure ((command "black" "--line-length" "79" "-") (stdin . #<killed buffer>) (callback closure ... ... ...) (remote) (buffer . #<buffer group_config.py>) (formatters black) t) (stdout) (if (cdr formatters) (apheleia--run-formatters ... buffer remote callback stdout) (funcall callback stdout))) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) (stdout) (if output-fname (progn (erase-buffer) (insert-file-contents-literally output-fname))) (funcall callback stdout)) (remote) (stdin . #<killed buffer>) (command "black" "--line-length" "79" "-") (--cl-rest-- :command ("black" "--line-length" "79" "-") :stdin #<killed buffer> :callback (closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure (... ... ... ... ... ... t) (stdout) (if ... ... ...)) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) (stdout) (if output-fname (progn (erase-buffer) (insert-file-contents-literally output-fname))) (funcall callback stdout)) :ensure (closure ((stdin . #<killed buffer>) (output-fname) (input-fname) (command "black" "--line-length" "79" "-") (ret nil nil #<killed buffer> "black" "--line-length" "79" "-") (formatter . black) (stdin . #<killed buffer>) (callback closure (... ... ... ... ... ... t) (stdout) (if ... ... ...)) (remote) (buffer . #<buffer group_config.py>) (command "black" "--line-length" "79" "-") t) nil (condition-case nil (progn (if input-fname ...) (if output-fname ...)) (error nil))) :remote nil :formatter black) t) (proc-exit-status) (let ((exit-ok (funcall (or exit-status #'zerop) proc-exit-status))) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer (set-buffer (get-buffer-create log-name)) (special-mode) (save-restriction (widen) (let (... ... ... ...) (goto-char ...) (skip-chars-backward "\n") (delete-region ... ...) (if ... nil ...) (if exit-ok nil ...) (insert ... " :: " ... "\n$ " ... "\n\n" ... "\n\n" "Command " ... " with exit code " ... ".\n") (goto-char ...) (goto-char ...))))) (if formatter (progn (run-hook-with-args 'apheleia-formatter-exited-hook :formatter formatter :error (not exit-ok) :log (get-buffer log-name)))) (unwind-protect (if exit-ok (if callback (progn (funcall callback stdout))) (message (concat "Failed to run %s: exit status %s " "(see %s %s)") (car command) proc-exit-status (if (string-prefix-p " " log-name) "hidden buffer" "buffer") (string-trim log-name))) (if ensure (progn (funcall ensure))) (condition-case nil (progn (kill-buffer stdout)) (error nil)) (condition-case nil (progn (kill-buffer stderr)) (error nil))))) 0)
(if (process-live-p proc) nil (funcall callback (process-exit-status proc)))
(closure ((callback closure ((log-name . " *apheleia-black-log*") (stderr . #<buffer *apheleia-black-stderr*>) (stdout . #<buffer *apheleia-black-stdout*>) (name . "black") (formatter . black) (exit-status) (ensure closure (... ... ... ... ... ... ... ... ... ... ... t) nil (condition-case nil ... ...)) (callback closure (... ... ... ... ... ... ... ... ... ... ... t) (stdout) (if output-fname ...) (funcall callback stdout)) (remote) (stdin . #<killed buffer>) (command "black" "--line-length" "79" "-") (--cl-rest-- :command ("black" "--line-length" "79" "-") :stdin #<killed buffer> :callback (closure ... ... ... ...) :ensure (closure ... nil ...) :remote nil :formatter black) t) (proc-exit-status) (let ((exit-ok ...)) (if (and exit-ok apheleia-log-only-errors) nil (save-current-buffer ... ... ...)) (if formatter (progn ...)) (unwind-protect (if exit-ok ... ...) (if ensure ...) (condition-case nil ... ...) (condition-case nil ... ...)))) (noquery . t) (remote) (command "black" "--line-length" "79" "-") (stderr . #<buffer *apheleia-black-stderr*>) (stdout . #<buffer *apheleia-black-stdout*>) (stdin . #<killed buffer>) (name . "apheleia-black") (--cl-rest-- :name "apheleia-black" :stdin #<killed buffer> :stdout #<buffer *apheleia-black-stdout*> :stderr #<buffer *apheleia-black-stderr*> :command ("black" "--line-length" "79" "-") :remote nil :noquery t :callback (closure ((log-name . " *apheleia-black-log*") (stderr . #<buffer *apheleia-black-stderr*>) (stdout . #<buffer *apheleia-black-stdout*>) (name . "black") (formatter . black) (exit-status) (ensure closure ... nil ...) (callback closure ... ... ... ...) (remote) (stdin . #<killed buffer>) (command "black" "--line-length" "79" "-") (--cl-rest-- :command ... :stdin #<killed buffer> :callback ... :ensure ... :remote nil :formatter black) t) (proc-exit-status) (let (...) (if ... nil ...) (if formatter ...) (unwind-protect ... ... ... ...)))) t) (proc _event) (if (process-live-p proc) nil (funcall callback (process-exit-status proc))))(#<process apheleia-black> "finished\n") Edit: Looks to be because the diff process creator is making more temp-files than it needs to. Will investigate and fix. |
Previously we always made a temp-file for diffing the formatted and unformatted buffer leading to a bug when trying to send stdin to the formatter process. Now we only perform this check when running both locally and remotely.
I've pushed a fix for the above issue and tested locally. Can't test on a remote ATM so I'd appreciate someone else doing that. |
Works for me on a remote machine with both the |
The README still says TRAMP isn't supported, but I tested TRAMP support out and it seems to work. Can the README be updated and some documentation about |
Adds support for formatting remote files.
The new
apheleia-remote-algorithm
option configures this. The defaultbehaviour is consistent with what we had before, with
apheleia
aborting a formatting when dealing with a remote file/buffer.
Users can customise apheleia to run the formatter on the remote machine,
in which case any temporary files or other checks such as
npx
will befully handled on the remote machine.
Users can also make apheleia run the formatter on the local machine.
This works exactly like one would expect, except if the formatter
requires access to the physical file (meaning it uses 'file in
apheleia-formatters
) because the file isn't available on the localmachine.
This PR also fixes a bug in apheleia where
input-fname
was assigned inlocal let scope, instead of being returned by
apheleia--format-command
,meaning any formatters using a 'input file weren't cleaned up after
formatting.
Closes #33.