mirror of
https://github.com/neovim/neovim.git
synced 2026-09-04 05:10:36 +00:00
fix(multicursor): live-mirror Visual-mode operator mapping #41655
Problem: Insert entered by a Visual-mode operator mapping (`xnoremap c c`) does not live-mirror at cursors. Solution: Decide `typed` from the Visual session's own provenance (`vatom`, which spans the selection and knows whether it was user input) instead of only negating it.
This commit is contained in:
@@ -77,7 +77,7 @@ static struct {
|
||||
///< ("f(" + mapped key in one batch). 0: none.
|
||||
} composite;
|
||||
|
||||
/// State of a Visual composite atom.
|
||||
/// State of a Visual session atom.
|
||||
typedef enum {
|
||||
kVatomNone = 0, ///< No pending Visual atom.
|
||||
|
||||
@@ -88,7 +88,10 @@ typedef enum {
|
||||
kVatomVoid = 4, ///< Not replayable: tainted/poisoned (by mouse, gv, …). But may emit CmdAtom.
|
||||
} VatomState;
|
||||
|
||||
/// Accumulating Visual composite: the full Visual keysequence (selection keys + operator).
|
||||
/// Accumulating Visual session atom: the full Visual keysequence (selection keys + operator).
|
||||
///
|
||||
/// NOTE: Visual session is not modeled as `composite` bc they may overlap (not clean nesting):
|
||||
/// a mapping can open before `v` and end mid-selection ("nmap X vjj" followed by "d").
|
||||
static struct {
|
||||
CmdAtomVec atoms; ///< Accumulated subatoms. A void session collects them as the `lhs` label.
|
||||
VatomState state;
|
||||
@@ -1147,9 +1150,10 @@ InsSession atom_ins_start(int cmd, long count, VisualIns vis, bool vblock)
|
||||
: cur_frame != NULL ? cur_frame->origin : atom_origin(),
|
||||
};
|
||||
if (vis != kVInsNone && !mc_replaying()) {
|
||||
if (vis == kVInsKeys && !(atom_visual_replayable() && (vatom.state & kVatomTyped))) {
|
||||
// The selection came from fed keys (":norm", scheduled feedkeys).
|
||||
session.typed = false;
|
||||
if (vis == kVInsKeys) {
|
||||
// Internal (non-user) keys (":norm", scheduled feedkeys) are not user-input.
|
||||
// But a Visual-mode operator mapping ("xnoremap c c") is user-input. #41605
|
||||
session.typed = atom_visual_replayable() && (vatom.state & kVatomTyped) != 0;
|
||||
}
|
||||
// The selection is consumed: already in the redo body. Also clears selection display.
|
||||
atom_visual_reset();
|
||||
|
||||
@@ -1132,7 +1132,7 @@ describe('multicursor', function()
|
||||
]])
|
||||
end)
|
||||
|
||||
it('typed text appears at cursors before leaving insert-mode', function()
|
||||
it('typed text live-mirrors at cursors', function()
|
||||
local screen = Screen.new(30, 6)
|
||||
cursors({ 'aaa', 'bbb', 'ccc' })
|
||||
-- Still in insert mode (no <Esc> yet): the text already cascaded; each cursor displays
|
||||
@@ -1155,8 +1155,7 @@ describe('multicursor', function()
|
||||
{1:~ }|*2
|
||||
|
|
||||
]])
|
||||
-- Entering insert mode displays each cursor at its insertion point
|
||||
-- right away, BEFORE any text is typed ("a": one char to the right).
|
||||
-- Entering insert mode ("a") displays each cursor at its insertion-point immediately.
|
||||
feed('a')
|
||||
screen:expect([[
|
||||
XY{17:a}aa |
|
||||
@@ -1166,8 +1165,7 @@ describe('multicursor', function()
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
-- An operator entry ("ciw") live-mirrors the same way: the entry
|
||||
-- replay changes each cursor's OWN word, still in insert mode.
|
||||
-- Operator entry ("ciw") live-mirrors the per-cursor change, still in insert mode.
|
||||
feed('0ciwZ')
|
||||
screen:expect([[
|
||||
Z{17: } |
|
||||
@@ -1177,8 +1175,7 @@ describe('multicursor', function()
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
-- A Visual-entered change ("viwc") live-mirrors too: the entry replay
|
||||
-- re-executes the selection at each cursor.
|
||||
-- Visual-change entry ("viwc") live-mirrors the selection at each cursor.
|
||||
feed('viwcW')
|
||||
screen:expect([[
|
||||
W{17: } |
|
||||
@@ -1188,6 +1185,17 @@ describe('multicursor', function()
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
-- Also when "c" is a Visual-mode operator mapping. #41605
|
||||
command('xnoremap c "_c')
|
||||
feed('viwcM')
|
||||
screen:expect([[
|
||||
M{17: } |
|
||||
M{17: } |
|
||||
M^ |
|
||||
{1:~ }|*2
|
||||
{5:-- INSERT --} |
|
||||
]])
|
||||
feed('<Esc>')
|
||||
end)
|
||||
end)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user