Repository: neovim
Issue: Decouple cursor from UI, allow more instances.
Labels: multicursor

<!-- Before reporting: search existing issues and check the FAQ. -->

This is a feature request.

- `nvim --version`: all, up to current (v0.4.0-1078)
- Vim (version: ) behaves differently? No. Same behavior in Vim
- Operating system/version: all
- Terminal name/version: n/a
- `$TERM`: n/a

### Steps to reproduce using `nvim -u NORC`

```
nvim -u NORC
# Alternative for shell-related problems:

n/a

# env -i TERM=ansi-256color "$(which nvim)"

n/a

```

### Actual behaviour

There is only one cursor, tied inextricably with the user interface (*input* as well as output). Trying to perform Vim commands that require moving the cursor around is tricky if side-effects are undesirable. This limits the abilities of functions and plugins that are meant to work in the background or otherwise refrain from bothering the user.

### Expected behaviour

A cursor class with different kinds of instances. Some new instance properties might be visibility, or which other cursor to echo, or a function to call upon to transform the output of a particular cursor (taking all data since a given event would be more powerful than per-keystroke).  Only one of them can be the “real” one (make it a static property of the class), and it must be visible and undeletable. Visible secondary cursors that echo the primary cursor would be equivalent to the multi-cursor functionality found in some other editors, especially with the addition of a new search flag or a new type of search--one that allows limiting results to a visual selection or other ranges would probably be desirable. A command allowing users to input a position for a new cursor would allow users to implement such capability themselves, but built-in UI support would make it available to users who prefer a vanilla neovim experience.

Visible secondary cursors that output based on arbitrary code (perhaps tied to what occurs with the primary cursor) would have uses, as well. One example is extremely powerful snippets that can change other fields’ contents automatically in any way wanted (e.g. based on the type of data typed into a particular field).

Grouping cursor objects together in hierarchies with effective range data (in user code) would allow for such things as nested snippets that stay “snippety” when the user leaves the range of the snippet-generated text. If cursor data were preservable in yanked text (but how would this be implemented?), snippets could even maintain this ability after shuffling text around. Multiple puts would then probably have to automatically make new cursors, rather than just keeping the cursors around even when they’re only pointing to positions in registers. Yanks to the clipboard probably wouldn’t be a good place to preserve this data, unless the OS clipboard can be leveraged to paste data that doesn’t need to preserve all meta data (we see such things when pasting formatted text into a plain text file, for example).

Many of the plugins and user code that emulate this kind of behavior could be dramatically simplified. For one thing, making all buffer changes in one insert be part of the same node in the undo history would preserve users and plugin writers from having to implement this behavior themselves. Direct support in the nvim binary would likely speed up these applications as well.

It’s possible that such a feature as this would be unnecessary, since direct editing at arbitrary positions is already possible. However, decoupled cursors would still have some advantages. For one, editing text that shifts around future desired input points requires the script to be able to re-assess where the desired point has moved to. Cursors would track their position with changes to the buffer. Further, decoupling code in a codebase is good in general, especially when talking about links between internal behavior and the UI--though admittedly, I haven’t actually taken a look at the cursor code myself. Maybe it’s already decoupled, but as far as I know, there’s still only one instance, without the same sets of properties that I’ve suggested.