[vim/vim] Wrap lines in vim in an active terminal session (#2865)

189 views
Skip to first unread message

Cimbali

unread,
May 3, 2018, 10:38:11 AM5/3/18
to vim/vim, Subscribed

I've been enjoying the Termdebug feature, but one thing has been nagging me, which that lines are wrapped by inserting newlines in the terminal's output, instead of letting vim handle the wrapping. This has several drawbacks:

  • When resizing windows, this is ugly.
  • In particular, when switching from terminal to normal mode, showing line numbers causes every line to be 3-4 characters overlength, which wastes 50% of vertical space.
  • long strings (e.g. filepaths) can't be copied in normal mode and used directly, as they now contain arbitrary newlines.

Both bash and gdb support not wrapping their output, through a set width 0 option in gdb, and setterm --linewrap off (from the util-linux package, so this is probably wider than just bash).

With these options enabled, switching a terminal's output to normal mode causes non-terminal-wrapped lines appear as expected, wrapped by vim to whatever the current window width is. However, :set wrap does not seem to do anything in terminal mode.

Would it be possible to wrap lines in an active terminal output?

That way, we could enable wrapping whenever we detect that wrapping can be disabled in what the :terminal is running (potentially as a vimrc option). This would make the :terminal option much more useful IMHO.


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub

Bram Moolenaar

unread,
May 3, 2018, 3:26:19 PM5/3/18
to vim/vim, Subscribed

> I've been enjoying the Termdebug feature, but one thing has been
> nagging me, which that lines are wrapped by inserting newlines in the
> terminal's output, instead of letting vim handle the wrapping. This
> has several drawbacks:
>
> - When resizing windows, this is ugly.
> - In particular, when switching from terminal to normal mode, showing

> line numbers causes every line to be 3-4 characters overlength, which
> wastes 50% of vertical space.
> - long strings (e.g. filepaths) can't be copied in normal mode and used directly, as they now contain arbitrary newlines.
>
> Both bash and gdb support not wrapping their output, through a [`set width 0`](https://ftp.gnu.org/old-gnu/Manuals/gdb/html_node/gdb_183.html) option in gdb, and `setterm --linewrap off` (from the [util-linux package](https://www.kernel.org/pub/linux/utils/util-linux/), so this is probably wider than just bash).

>
> With these options enabled, switching a terminal's output to normal mode causes non-terminal-wrapped lines appear as expected, wrapped by vim to whatever the current window width is. However, `:set wrap` does not seem to do anything in terminal mode.
>
> Would it be possible to wrap lines in an active terminal output?
>
> That way, we could enable wrapping whenever we detect that wrapping can be disabled in what the `:terminal` is running (potentially as a vimrc option). This would make the `:terminal` option much more useful IMHO.

It's not clear to me what you are talking about. Is this about the gdb
command running in a terminal window? Compare that with running gdb in
a terminal directly (such as xterm). Doesn't it then do the same thing
when resizing the window?

--
We do not stumble over mountains, but over molehills.
Confucius

/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Cimbali

unread,
May 4, 2018, 9:22:52 AM5/4/18
to vim/vim, Subscribed

Yes, the same happens with a normal terminal. I just thought vim could handle the line wrapping instead of the terminal?

The reason this is especially annoying in vim, is that switching from terminal to normal mode resizes the window, thus causing every full line to wrap with only a couple of characters after the line break.

Other work-arounds could be to force the terminal to wrap lines a little earlier to account for switching to normal mode, or to allow line numbers in terminal mode so the window won't resize.

Christian Brabandt

unread,
May 4, 2018, 9:29:42 AM5/4/18
to vim/vim, Subscribed

it might be silly, but have you checked setting the $COLUMNS environment variable to a smaller size?

Bram Moolenaar

unread,
May 4, 2018, 11:46:58 AM5/4/18
to vim/vim, Subscribed

> Yes, the same happens with a normal terminal. I just thought vim could handle the line wrapping instead of the terminal?
>
> The reason this is *especially* annoying in vim, is that switching from terminal to normal mode resizes the window, thus causing every full line to wrap with only a couple of characters after the line break.

>
> Other work-arounds could be to force the terminal to wrap lines a little earlier to account for switching to normal mode, or to allow line numbers in terminal mode so the window won't resize.

This would require Vim to detect that the job is only sending lines of
text without being aware of the terminal width. We do have the
scrollback, thus in a sense we do some of this.

Perhaps we can detect that the job does not output a line break, but an
automatic wrap happens after the rightmost column. We do something like
that for clipboard support.


--
ARTHUR: I did say sorry about the `old woman,' but from the behind you
looked--
DENNIS: What I object to is you automatically treat me like an inferior!
ARTHUR: Well, I AM king...
The Quest for the Holy Grail (Monty Python)


/// Bram Moolenaar -- Br...@Moolenaar.net -- http://www.Moolenaar.net \\\
/// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\
\\\ an exciting new programming language -- http://www.Zimbu.org ///
\\\ help me help AIDS victims -- http://ICCF-Holland.org ///

Ruslan Osipov

unread,
Jan 16, 2019, 4:54:32 PM1/16/19
to vim/vim, Subscribed

+1 on this, as I often resize the same Vim window (depending on where I SSH from). This becomes pretty comical (and unwieldy) if I had a command running as I'm resizing the window (connecting to a tmux session from a smaller screen often forces rightmost window to be of width 1):

$
p
y
t
h
o
n

sambanks

unread,
Jan 16, 2019, 5:12:31 PM1/16/19
to vim/vim, Subscribed

I still haven't managed to find a workaround to copy multiline strings in vim terminal (normal) mode without it inserting arbitrary newlines for linewraps. I have to bounce back to a normal terminal when I want to do that. Would be amazing if there was some way around it.

Jesus E. Larios Murillo

unread,
Mar 13, 2019, 3:58:03 AM3/13/19
to vim/vim, Subscribed

+1 on this

Guirec Corbel

unread,
Apr 4, 2019, 11:52:00 AM4/4/19
to vim/vim, Subscribed

Is there an update on this issue ? I have the problem and I still didn't found any good solution.

Bram Moolenaar

unread,
Apr 4, 2019, 1:13:17 PM4/4/19
to vim/vim, Subscribed

Please answer my question: Does the same happen when running the command in an xterm (or other terminal emulator)? If yes, then there is nothing that Vim can do, since it's just providing a terminal emulator to run the command in.

Guirec Corbel

unread,
Apr 4, 2019, 1:26:31 PM4/4/19
to vim/vim, Subscribed

Yes, it's the same. When I run xterm, run a command with long lines and resize the windows, all characters wrapped to the left.

Peek 04-04-2019 13-25

Guirec Corbel

unread,
Apr 4, 2019, 2:23:18 PM4/4/19
to vim/vim, Subscribed

I tried by using screen in xterm and gnome-terminal and it works well
Peek 04-04-2019 14-14

It's also better with vim but when I select and paste I have multiple line when I should have one.

In this gif, I start without screen and resize to reproduce the problem. Then, I use screen to show than it's better and I do a copy/paste to show than one line in the terminal is pasted as multiple lines.

Peek 04-04-2019 14-18

I hope it's clear.

Do you think there is a solution?

Cimbali

unread,
Apr 5, 2019, 7:35:27 AM4/5/19
to vim/vim, Subscribed

Yes screen is a good example of what is desirable.

Instead of inserting hard linebreaks in the terminal output to wrap lines (which then breaks functionalities on resize, on copy/paste, etc. and additionally in vim mucks up the display on entering/exiting normal mode in the terminal buffer), it handles line wrapping dynamically, at every resize.

It's only on text input, not with programs drawing in the terminal that this happens, so this block in on_text() seems to be where the automatic wraps after the rightmost column are inserted:

https://github.com/vim/vim/blob/577fadfc100ff8fa569a34b89f5ad055ad726646/src/libvterm/src/state.c#L358-L362

Isaac Elenbaas

unread,
Jun 8, 2021, 8:05:21 PM6/8/21
to vim/vim, Subscribed

In particular, when switching from terminal to normal mode, showing line numbers causes every line to be 3-4 characters overlength, which wastes 50% of vertical space.

This will fix that, at least. The 6 should be adjusted based on your max scrollback digits and gutter width.

augroup Terminal
	autocmd!
	autocmd TerminalOpen * execute "set termwinsize=0x" . (winwidth("%")-6)
	autocmd VimResized * execute "set termwinsize=0x" . (winwidth("%")-6)
augroup END

#5769 has some more info on why fixing wrapping is hard. Unfortunately, running screen inside vim isn't an option as it prevents using marks or searching through history.


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

Cimbali

unread,
Jun 10, 2021, 4:58:31 PM6/10/21
to vim/vim, Subscribed

Please answer my question: Does the same happen when running the command in an xterm (or other terminal emulator)? If yes, then there is nothing that Vim can do, since it's just providing a terminal emulator to run the command in.

To clarify, some terminal emulators handle wrapping well.

  • xterm doesn’t. Lines are wrapped when they are too long.
    • When resizing to a smaller window size, any line that is too long is cut off without wrapping, as @GCorbel showed. Any content hidden by a resize (window made smaller) does not reappear when the window size is restored. This is also how vim currently functions.
    • However xterm does allow selecting and copying across several wrapped lines ignoring continuation lines breaks. There is no way to achieve this with vim the way it currently is.
  • Konsole (from personal experience − I use it daily), gnome-terminal, screen (both shown by @GCorbel too) handle wrapping of lines correctly:
    • change the place where the line wraps on resize (vim would have the additional burden of doing this when moving from active terminal to normal-mode buffer)
    • allow selecting/copying across line wraps

I understand it’s giving the appearance of being a line wrapping when in fact something more complicated happens in the background. It’s likely no terminal emulator maintains in memory lines that are longer than it’s display columns just so it can wrap them nicely on display − that would be a nightmare just to figure out where to vertically start the screen.

I’ve digged through the Konsole sources, it’s basically any blocks conditioned on _enableReflowLines inside the Screen::resizeImage(lines, cols) function. So they call it « reflowing » the outputs. In short, it consist of:

  • joining back together lines that are wrapped lines
  • split them again onto several lines if and as need
  • some extra fiddling with sending now off-screen lines to history or getting them from history as needed for the rows resize. From what I understand they do not reflow the entire history, only what’s on screen.

I see that the inserted line breaks now marked the following lines with continuation = 1 in their lineinfo:

https://github.com/vim/vim/blob/7b4f76c0300f0bd9bf54ca1968fe9ae5e4dbdef4/src/libvterm/src/state.c#L402-L407

That is probably enough to:

  • remove them when toggling to normal mode thus letting vim’s usual buffer wrapping happen
  • remove them when resizing the active terminal,
    • and insert new ones as needed with the new line length
  • remove them from selected/copied text (as with normal buffers)

I do not have a clear picture of how the internals of the vim terminal work however, so I can’t quite estimate how much work this is or promise I can whip up a PR at some point.


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

Guirec Corbel

unread,
Jun 10, 2021, 5:39:02 PM6/10/21
to vim/vim, Subscribed

Thanks @Cimbali for investigation, two years after my comments, this is still a problem I have daily.


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

Isaac Elenbaas

unread,
Jun 10, 2021, 5:41:48 PM6/10/21
to vim/vim, Subscribed

Nice catch on the lineinfo - note that the buffer and terminal are distinct: I believe that a few changes to this could easily give an effect equivalent to set termwinsize=0*∞. Just check continuation and reset pos.col here, and then add some % term->tl_cols where the characters are added just below that. That would fix all wrapping in terminal normal mode, make termwinscroll affect lines period (not visual lines), and prevent having to remove newlines all the time.

Then the terminal just needs to manage its own printing (and only on the visible lines), same as Konsole or screen or anything else.


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

sambanks

unread,
Jun 10, 2021, 6:59:19 PM6/10/21
to vim/vim, Subscribed

Thanks @Cimbali for investigation, two years after my comments, this is still a problem I have daily.

Me too! I will never stop following this thread and hoping for a solution. Would love to shut up my Tmux using colleagues :)


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

wwade

unread,
Jun 10, 2021, 7:35:11 PM6/10/21
to vim/vim, Subscribed

Thanks @Cimbali for investigation, two years after my comments, this is still a problem I have daily.

Me too! I will never stop following this thread and hoping for a solution. Would love to shut up my Tmux using colleagues :)

And the emacs ones, too 😬


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub, or unsubscribe.

Risyanggi Azmi Faizin

unread,
Jul 25, 2023, 5:52:26 AM7/25/23
to vim/vim, Subscribed

Konsole (from personal experience − I use it daily), gnome-terminal, screen (both shown by @GCorbel too) handle wrapping of lines correctly

thanks for the explanation. just jumping here, I use iTerm for my Mac and the problem also occurs. any recommended terminal for Mac?


Reply to this email directly, view it on GitHub, or unsubscribe.
You are receiving this because you are subscribed to this thread.Message ID: <vim/vim/issues/2865/1649496842@github.com>

Reply all
Reply to author
Forward
0 new messages