pipe-rename
pipe-rename copied to clipboard
using pipe-rename in a pipe seems to misconfigure terminal
$ 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.
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.
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.
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!
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
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:
- https://www.in-ulm.de/~mascheck/various/stty/
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.