Not sure what to classify this as, bug or feature request. Or if this existing functionality is in the tool, and I'm just unable to configure vim
properly.
When I run a command in a terminal window, like :term find
or :term grep
, the output of the window is strangely wrapped when the command completes. By this I mean that lines returned by find
or grep
contain line feeds where the original shell output had none. In particular, if a line is longer than Vim's current terminal width, a linefeed is inserted into the command output.
This causes a ton of frustration when I attempt a :term find
or :term grep
and the line containing a path is longer than this limit: the path is now broken into two lines by a newline. If I want to open it with gf
(how I typically interact with the contents of this window), I must make the window modifiable, edit the line, split the window (otherwise vim won't switch files due to "unsaved changes"), and close the old window. Perhaps there's a simpler way to accomplish this, but the point remains: if I could simply turn off the wrapping of the output, none of this would be necessary.
I've tried all the options I can think of. set nowrap
has no effect, set formatoptions-=t
, set wrapmargin=0
, set textwidth=0
, to no avail. I've tried setting setterm -linewrap off
before running the command. No dice. No matter what I do, the output gets wrapped to the size of the output window. Running the same command to a temporary file shows no line wrapping.
The only workaround I have is increasing the size of my window temporarily before running the command. That's not a permanent solution for obvious reasons,
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub, or unsubscribe.
I think there might be a misunderstanding here. The output of the tool does not contain linefeeds. I'm not upset with the fact that the terminal scrolls. That's not the issue.
The issue is that the resulting text in the buffer that Vim uses to display the command's stdout contains linefeeds.
Open up a Vim window and shrink the terminal so that the width is around 80 characters, and then type :term echo "This is an incredibly long line that will cause the screen to scroll and insert a linefeed where the should not be one, because there wasn't one in the command's actual output. It is artificially inserted into the text."
(or something of that nature).
What you will see is something like
What I want to be able to see (with some kind of configuration of vim)
At present, it looks like my only option to cause Vim to output the latter is to set termwinsize
so that the width of the terminal is artificially much longer. While this does achieve the desired effect, it has the unwanted effect of causing the lines to not visually wrap while the command is running. Also, I have to set termwinsize
back to something reasonable (via set termwinsize&
) when I want to use the terminal window interactively. I can live with it if I have to, but I'm just surprised this behavior isn't configurable.
I took a look at what I think is the relevant code here (in terminal.c
). I think now perhaps I understand the issue. If my reading of the source is correct, Vim creates a buffer from the terminal's output row by row, and hence if the terminal emulator visually wraps (due to termwinsize
), then the output will appear as though a linefeed was inserted simply due to the action by which Vim fills the buffer. Is that relatively correct?
—
Yeah, I realize now what I'm asking might be more difficult than I imagined. I'll leave this issue open if you feel someone might want to take a stab at it (or could), but otherwise you can close it.
I would be interested in seeing this solved for vim :terminal.
I am used to using a terminal, Terminator, which does not wrap long lines, and it's a very natural behaviour. Terminator appears to advertise the actual window size (rows*columns) so viewport aware programs like ls
, and visual programs like vim
and less
will size their output appropriately. But if a program writes long lines, e.g. cat, then Terminator does not enforce wrapping on the text. Instead it supports horizontal scrolling as a first class operation. See neovim/neovim#2380 (comment) for an example.
there are (or that is) 2 cases actually, IMO.
// well, though if item.1 solved, then item.2 looks not an issue too, or at least it can manually adjust the size.
@brammool One use case where I run into this use is when using termdebug. Often I need to copy off the output/contents from gdb (terminal) window like backtraces, etc. and it introduces new lines where they wrapped.
Currently I work around it by maximizing the window as much as possible (full screen), rerunning the gdb command so lines don't wrap and then copying the lines I want. Would be nice to have an option to not introduce real newline characters or to not split up the wraps somehow.
@damnskippy it seems the way to prevent those wraps is to set the size of that buffer wider than it actually is (but I don't know how to achieve that). A workaround that may be useful for you instead of/additional to maximizing:
:q
, now the GDB bufffer "window" is full-width and you the last window (gdb) is activeup
, down
-> the source window is shown again@GitMensch yes, that works (around this) too, thanks.
Upon closer inspection this seems to be the same as #2865 (maybe better expressed here?).
Indeed many terminal emulators handle wrapped lines naturally, by moving linebreaks on window resizes or ignoring them when copying text. vim does this naturally for its buffers, so it is reasonably easy to do this too for the buffer displaying a terminal’s contents.
PR #8365 implements that, so you can try to check out that code and compile vim with it to test the feature. Note that:
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub.
Triage notifications on the go with GitHub Mobile for iOS or Android.
I can set termwinsize=20*2000 or something similarly large before I run the command, and then after run set termwinsize&, but this requires me to wrap every command I care about in a convenience macro that does this.
Another workaround is using channels.
For example:
:call job_start([&shell, &shellcmdflag, "for i in $(seq 1 1000); do echo -n \"$i \"; done"], {'out_io': 'buffer', 'out_name': 'tmpshell', 'out_msg': ''}) :sbuffer tmpshell
Screenshot demonstrating channels (via job_start()
) vs :terminal
:
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.
:call job_start([&shell, &shellcmdflag, "for i in $(seq 1 1000); do echo -n \"$i \"; done"], {'out_io': 'buffer', 'out_name': 'tmpshell', 'out_msg': ''}) :sbuffer tmpshell
Maybe this could be packaged as a convenience command?
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.
Sadly the problem still exists after nearly 4 years.
—
Reply to this email directly, view it on GitHub.
You are receiving this because you are subscribed to this thread.