Skip to content
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

using pipe-rename in a pipe seems to misconfigure terminal #54

Open
kanliot opened this issue Sep 17, 2022 · 6 comments
Open

using pipe-rename in a pipe seems to misconfigure terminal #54

kanliot opened this issue Sep 17, 2022 · 6 comments

Comments

@kanliot
Copy link

kanliot commented Sep 17, 2022

$ echo unum.pl |renamer

This should work well, but instead on exit from vim, my terminal doesn't convert line endings correctly anymore. I'm using vim 8.2.1525. bash 5.1.4.

I think your project is fine, and some new ideas, which is why I'm using it in my mpvreadname project.

If you used a temporary file I think the problems would go away. please remember bash might close the piping subshell after it reconfigures the terminal for the bash prompt and readline.

@assarbad
Copy link
Contributor

assarbad commented Nov 28, 2022

Still looking into this, but it appears that vim uses the Alternate Screen Buffer of the terminal and restores back the old state, whereas renamer doesn't handle any of that (as of yet).

This documentation could be interesting: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h2-The-Alternate-Screen-Buffer (potentially also relevant ... and linking to the aforementioned)

Generally this seems to occur only when piping something into renamer, thereby altering how stdin/stderr/stdout get handled.

@kanliot
Copy link
Author

kanliot commented Nov 30, 2022

Your problem is simple. you need to terminate vim, before you exit your program.

here's your error mode: launch vim, vim exits, you return to shell, then vim cleans up.

you need vim to clean up before you return to shell.

I'll save myself from poking around in yer code to find what causes this, but whatever is wrapping vim isn't closing the pipes early.

I hope this doesn't waste you an hour looking for a missing close() but I think this is the problem.

'***
if you like, i can write the wrapper code in perl, so at least you have this 100% working

this is unituitive, because the shell launches piped processes in a separate process, and the last program can exit before the other piped processes exit normally.

@assarbad
Copy link
Contributor

assarbad commented Dec 5, 2022

NB: If you haven't noticed, I am merely someone trying to help, not the original author.

And it may be due to me not being a native speaker of English, but I have trouble comprehending what it is you are trying to say. Whenever I use Vim it works fine. So to me the question is why it doesn't work with your Perl script but does with Vim. I was surmising it could have to do with how Vim uses the alternate screen buffer. You seem to have a different view, right?

Are you saying that renamer needs to read the full contents from stdin then close that and only then launch the editor? If so, that sounds like a very helpful remark. Could you please indicate if that's what you're saying? Thanks!

@kanliot
Copy link
Author

kanliot commented Jan 1, 2023

Good wishes for 2023 to you.

I am saying that the subshell from

$ find|pipe-rename

should not exit before the new vim process manages to clean up the terminal.

Honestly I'm not sure if the problem is that your program is exiting early, or if the problem is closing the pipe early.

So here is what I don't know:

Scenario 1: pipe-rename exits too early, and vim cleans up after exit()
Scenario 2: pipe-rename closes pipe, and the bash subshell returns

https://brandonwamboldt.ca/how-linux-pipes-work-under-the-hood-1518/

Cheers

@assarbad
Copy link
Contributor

Alright, slowly understanding what you wrote.

Additionally I ran a test on Linux, where this can be reproduced all the same. For starters we record the sane terminal settings (also see attached files):

$ stty -a
speed 0 baud; rows 47; columns 192; line = 0;
intr = ^C; quit = ^\; erase = ^?; kill = ^U; eof = ^D; eol = <undef>; eol2 = <undef>; swtch = <undef>; start = ^Q; stop = ^S; susp = ^Z; rprnt = ^R; werase = ^W; lnext = ^V; discard = ^O;
min = 1; time = 0;
-parenb -parodd -cmspar cs8 -hupcl -cstopb cread -clocal -crtscts
-ignbrk brkint -ignpar -parmrk -inpck -istrip -inlcr -igncr icrnl -ixon -ixoff -iuclc -ixany imaxbel -iutf8
opost -olcuc -ocrnl onlcr -onocr -onlret -ofill -ofdel nl0 cr0 tab0 bs0 vt0 ff0
isig icanon iexten echo echoe echok -echonl -noflsh -xcase -tostop -echoprt echoctl echoke -flusho -extproc

Then we "mess it up" using Vim, invoked by renamer which in turn gets its input from stdin:

$ find -maxdepth 1  -type f| target/debug/renamer -e vim
Vim: Warning: Input is not from a terminal
Error: No replacements found
                            $

At this point Enter won't produce a line break anymore. But we can still execute commands. For example another stty -a but piping its output into a file. I hope this shows the info about the messed up terminal and not the pipe, but I am not a 100% sure. We can then restore the terminal to a sane state via stty sane.

One thing I am puzzled about, though, is whether one should simply invoke tput and stty after Vim closes or instead roll one's own code. Termion seems to have some utility functions for this.

Further reading:

@kanliot
Copy link
Author

kanliot commented Jan 10, 2023

You'll figure it out soon enough.

Look at my last comment- scenario #1 and scenario #2

the problem has nothing to do with the terminal. It has everything to do with the bash subshell cleaning up the terminal before vim exits.

it means the order of operations is wrong.

instead of calling vim, call this bash script

#!/bin/sh

echo -e "ok test\n" | vim -
sleep 1
exit

the sleep command will prevent the subshell from exiting before vim exits. The subshell doesn't exit because we haven't closed STDIN.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants