[Toybox] [PATCH] vi.c: Backspace to merge lines when at beginning, get_endline is no more, cleanup

Jarno Mäkipää jmakip87 at gmail.com
Fri Mar 8 00:47:10 PST 2024


On Fri, Mar 8, 2024 at 3:07 AM Oliver Webb <aquahobbyist at proton.me> wrote:
>
> On Thursday, March 7th, 2024 at 14:23, Jarno Mäkipää <jmakip87 at gmail.com> wrote:
> [...]
> > Feel free to fix it up, some other features are simpler since you can
> > just read the man page and make it behave accordingly, but backspace
> > is maybe not very trivial one since its either you follow heirloom vi,
> > or make some educated assumption how average person would want to use
> > it. To me this patch is not necessarily fixing it, but making it
> > behave the way you want, maybe more vim way?
>
> The way most people use vi-like text editors today is with
> vim (or one of it's many forks). The same way that people usually interact
> with unix-like operating systems with linux. Making toybox vi act more
> vim-like would it easier to use for 90% of vi users.

I use vim myself, but the thing is vim behavior is not constant
target, every vim user tend to have different vimrc, either modified
by them or by distro vendor.
On my distro there default is vimrc.tiny that does not allow you
backspacing into previous line. So for these features that are not
really standard vi stuff, its just someones personal preference. I
dont personally mind either way.

if you want backspace to jump into previous line, you should not call
ex commands dispatcher in middle of normal mode. but instead just
teach cur_left to ignore /n so it jumps over newline...

static int cur_left_force(int count0, int count1, char *unused)
{
  int count = count0*count1;

  TT.vi_mov_flag |= 0x80000000;
  for (;count && TT.cursor; count--) {
    TT.cursor--;
    check_cursor_bounds();
  }
  return 1;
}

and call that instead of normal cursor left? would this do the trick
with simpler code path...

  size_t from = 0;
  size_t to = TT.cursor;
  cur_left_force(1, 1, 0);
  from = TT.cursor;
  if (from != to)
    vi_delete(reg, to, 0);
  check_cursor_bounds();
  return 1;

every delete, yank action should work the same, you find two cursor
locations and delete or yank between them...

>
> > About join lines function I dont see any issues with original version,
> > its doing what it supposed to do, searching newline and taking it out,
> > (with some buffer management magic called piece table method, here is
> > some info if you interested on how it works
> > https://www.cs.unm.edu/~crowley/papers/sds.pdf)
>
> Vim does insert a space in the merged line, which is nice for formatting
> and would fix the "deletion of last character" problem. Dunno how to implement
> it yet without doing ugly stuff with run_vi_cmd() yet

if you want to insert something just use the same function as any
other place in code uses. for example space at cursor position, which
should be correct if you just deleted "/n" at TT.cursor...
insert_str(xstrdup(" "), TT.cursor, 1, 1, HEAP);

but thing is join should not always add space, it was implemented the
simplest way "just join, let user handle whitespace". If you wanna
teach it to handle whitespace better, you need to implement following
from man page:

        1. Discard leading <space> characters from the line to be
           joined.

        2. If the line to be joined is now empty, delete it, and skip
           steps 3 through 5.

        3. If the current line ends in a <blank>, or the first character
           of the line to be joined is a ')' character, join the lines
           without further modification.

        4. If the last character of the current line is a '.', join the
           lines with two <space> characters between them.

        5. Otherwise, join the lines with a single <space> between them.


>
> > My original idea was to make vi as simple as possible: move with
> > simple motions, delete, yank and push and insert few words with insert
> > mode. Kinda rescue editor, in 1000 lines of code and leave it to Rob
> > to clean up, (or yank out and rewrite.) Then people started using it,
> > at least as rescue editor, so some quality of life patches came in,
> > and now its near 2000 lines.
>
> A minimal development environment needs at least a basic text editor.
> I noticed while trying to do stuff with mkroot (Getting runtest.sh to run on it
> so we can test commands like passwd (or nommu support assuming qemu has options for it)) That
> vi didn't have any ex commands other then write and quit. Since batch processing
> with ex commands is convenient (I know sed exists, but having it built in is more useful)
> I tried (am trying) to implement some of them. And once you have ex commands, implementing ed
> (and ex) are really easy (a for loop with run_ex_cmd()).

I was not that interested on ex, and I think Rob said ex is obsolete
and not on his roadmap. But yes some of ex commands are just vi normal
mode commands, with special addressing. If someone needs them, I think
first thing to do is implement better ex command parsing and
dispatching, original version was intended only to parse write and
quit commands. (the 90% vi user case, rest of 9% not knowing how to
quit and 1% needing something else)

>
> - Oliver Webb aquahobbyist at proton.me

Jarno


More information about the Toybox mailing list