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
Escape sequences in magit-process-buffer #3549
Comments
I'll probably do something about that eventually, but for now check if your script can be told that it isn't being run in a terminal that fully understands escape sequences. |
I think the root cause is For example, the venerable coreutils
|
Traced this to here: Lines 526 to 531 in 8adbe43
magit is using a |
We need a pty because we have to send user input to the |
You don't need a pty to communicate, you can send that over a pipe. pre-commit hooks are also invoked with stdin closed |
The problem is that git and ssh will only prompt for passwords on a tty. |
Can commit trigger a prompt? Can you configure the pty so stdout is a pipe but stdin is tty-like? |
It might: |
Where does that prompt come from? I don't see it in |
I invented that prompt on the fly. My point is: |
They can't because git hooks don't have stdin attached: $ tail -n999 .git/hooks/{commit-msg,pre-commit}
==> .git/hooks/commit-msg <==
#!/usr/bin/env python3
import sys
print(f'isatty: {sys.stdin.isatty()}')
print(f'hello from {sys.argv[0]}')
==> .git/hooks/pre-commit <==
#!/usr/bin/env python3
import sys
print(f'isatty: {sys.stdin.isatty()}')
print(f'hello from {sys.argv[0]}')
$ git commit -mtest --allow-empty
isatty: False
hello from .git/hooks/pre-commit
isatty: False
hello from .git/hooks/commit-msg
[master c91af40] test |
This works: #!/bin/sh
exec < /dev/tty
echo "Password: "
read password
echo "password is $password"
|
fair, that's cheating I would think 😆 Anyway, all I'm asking here is that stdout be a pipe, stdin can continue to be a pty if that's necessary I'm not at all familiar with elisp but here's how this would be done with python: t.py#!/usr/bin/env python3
import sys
print(f'in: {sys.stdin.isatty()}')
print(f'out: {sys.stdout.isatty()}')
print(f'err: {sys.stderr.isatty()}')
print(f'read: {sys.stdin.readline()}') pty_ex.pyimport os
import pty
import subprocess
master, slave = pty.openpty()
proc = subprocess.Popen(
('./t.py',),
stdin=slave,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
)
os.close(slave)
with os.fdopen(master, 'wb', 0) as stdin:
stdin.write(b'hello\n')
out, err = proc.communicate()
print('RETC:')
print(proc.returncode)
print('OUT:')
print(out.decode(), end='')
print('ERR:')
print(err.decode(), end='') outputRETC:
0
OUT:
in: True
out: False
err: False
read: hello
ERR: |
I don't think that's possible in elisp. |
😆 surely it can, elisp is turing complete! |
Go ahead and re-implement a better emacs/elisp in elisp 😉 |
Closing as In a far away future I might actually start dealing with control sequences in the output of |
Also added the semi-secret |
For anyone interested, I've hacked on this a bit and created https://gist.github.com/Fuco1/f0cc2c866926f433a32ffa882887e960 which is at least lint-staged aware... it does not implement all the ANSI escapes but it is good enough for my needs. Feel free to extend it and submit patches. To use this copy the form somewhere in your emacs and eval it. Probably don't do this if you don't know what you're doing. |
Unfortunately more and more tools decide to include various ANSI goodness and there is no way to tell if that things is really interactive or not. https://no-color.org/ is one initiative to solve at least the color problem. |
Here are some facts of the interesting discussion between @asottile and @tarsius
Since it seems that it is not possible in emacs to create subprocesses where stdin is attached to a pty but not stdout, I'll create a bug report. |
Please post a link when you have done that. |
Sure. Here it is: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=48129 |
Eli asked in the thread if we could use |
I've been running into this issue too. Would be great if there were a solution. |
I'm not sure if this is the right solution, but adding this code from @LaloHao (from here) worked for me: (defun color-buffer (proc &rest args)
(interactive)
(with-current-buffer (process-buffer proc)
(read-only-mode -1)
(ansi-color-apply-on-region (point-min) (point-max))
(read-only-mode 1)))
(advice-add 'magit-process-filter :after #'color-buffer) |
We use a git hook to lint staged files before committing, when I run
git commit
from cli, the output looks as follows:The library we use here (https://github.com/okonet/lint-staged) makes heavy use of escape sequences to render that progress indicator. This causes the output shown in
magit-process-buffer
to be mangled:I've already tried setting
magit-process-finish-apply-ansi-colors
as indicated in #3159 but that just makes things worse: Everything is a lot slower, and the escape sequences are still not interpreted correctly (I think that only affects colors but not cursor-movement-escape sequences).Magit version:
Magit 20180630.1235, Git 2.18.0, Emacs 26.1, darwin
The text was updated successfully, but these errors were encountered: