vis icon indicating copy to clipboard operation
vis copied to clipboard

V+u removes new line

Open sg-hk opened this issue 9 months ago • 7 comments

Problem

When selecting a line in visual line mode with V and then converting to lowercase with u, the selected line is joined with the following line. This differs from Vim's behavior, where u only changes the case and preserves line structure. I believe this is a bug or unintended behavior.

Steps to reproduce

Steps to reproduce:

  1. Open a file in Vis.
  2. Move to any non-empty line followed by another non-empty line.
  3. Press V to select the line in visual line move.
  4. Press u.

Expected behavior:

  • Line case is changed to lowercase; line structure remains unchanged.

Actual behavior:

  • Line is lowercased and joined with the next line.

vis version (vis -v)

vis v0.9-308-g286fd30-dirty +curses +lua +tre

Terminal name/version

No response

$TERM environment variable

No response

sg-hk avatar Apr 14 '25 15:04 sg-hk

Hmm, cannot reproduce here with 0.9+git.1743662388.48639f5a.

mcepl avatar Apr 15 '25 21:04 mcepl

@sg-hk This is where it happens: d3e4af1f

Awk "eats" the newlines (by design).

TwoF1nger avatar Apr 17 '25 11:04 TwoF1nger

I also can't reproduce on my end.

Awk "eats" the newlines (by design).

No? That would be antithetical to the purpose of awk which is to filter specific lines of a text stream and perform operations on them.

rnpnr avatar Apr 17 '25 11:04 rnpnr

Maybe more information about my configuration is relevant. This is on macOS, using wezterm. Both V+u and V+U consume the newline. If it's awk then it might be a BSD awk vs gawk problem? But symlinking gawk to awk doesn't resolve the issue

Image

sg-hk avatar Apr 17 '25 17:04 sg-hk

@rnpnr I could have worded this better. I meant that $0 does not include the terminating newline character from the input (and this is by design). And the printf in the above Awk script does not add a newline to the output, which results in the newline that was in the input appear "eaten".

With selections shorter than one line, there won't be any newlines in the first place, so the above Awk script will appear to work. With longer selections, though, there will be, and the script will make them disappear.

I can reproduce with GNU Awk on Linux. u/U on any selection that includes one or more newlines removes them.

TwoF1nger avatar Apr 17 '25 20:04 TwoF1nger

Setting RS to something that won't appear in the input seems to fix the problem:

vis:map(vis.modes.VISUAL, 'gu', [[:|awk 'BEGIN {RS = "\0"} {printf "%s", tolower($0)}'<Enter>]])
vis:map(vis.modes.VISUAL, 'gU', [[:|awk 'BEGIN {RS = "\0"} {printf "%s", toupper($0)}'<Enter>]])

BTW, I noticed that there are OPERATOR-PENDING mode mappings for gu and gU that don't seem to work at all. They were probably meant for use with count.

TwoF1nger avatar Apr 17 '25 22:04 TwoF1nger

It may be worthy to study the development of this solution in the threads

https://lists.sr.ht/~martanne/devel/patches/49637, https://lists.sr.ht/~martanne/devel/patches/49527

and

https://lists.sr.ht/~martanne/devel/<20240205215719.17993-1-mcepl%40cepl.eu>

I have been personally uneasy with this solution and I would be all for cutting *BSD folks loose and use some proper C functions or GNU utils (or at least use #ifdef), but that’s probably politically impossible.

mcepl avatar Apr 18 '25 19:04 mcepl