replit/codemirror-vim

Replaying a macro while it is being recorded hangs the page

Opened this issue · 3 comments

Minimal repro:

import {EditorView, basicSetup} from "codemirror"
import {vim} from "@replit/codemirror-vim"
let editor : EditorView = new EditorView({
  extensions: [vim(), basicSetup, solarizedDark],
  parent: document.body
})

In the resulting editor, typing qaihello<ESC>@a instantly hangs the page, without any obvious way to recover that I could find.

The behaviour in (neo)vim is somewhat better - qaihello<ESC>@a creates an infinite loop of writing hello - but I feel like even that behaviour would be problematic in a web environment, as the user doesn't have a way to interact with the page once this happens.

Currently we rely on maximum call stack size exceptions, so @A repeats the macro 512 times.

Unfortunately performance of the extension on v6 is worse than v5, so repeating macro 500 times takes about a minute.
Aside from fixing performance issue, should we also always prevent macro recursion, or can that be useful in some situations and keeping behavior from https://codemirror.net/5/demo/vim.html is ok?

I admit I didn't expect that repeating the macro 500 times would lock up the page this badly :-)

I can't at the moment think of a usecase where macro recursion would be useful, but IMO it's best to stick to the vim behaviour if possible (i e. Allow recursion)

For the case of tail-recursion, so playing the macro at the end of recording, we could avoid using a call stack entirely. This would also extend to mutually-recursive recordings like qa@bqqb@aq.

If the recursive call takes place in the middle of a recording then it's down to classic optimizations.