@@ -601,6 +601,7 @@ MiniClue.enable_all_triggers = function()
601601 -- Map only inside valid listed buffers
602602 if vim .fn .buflisted (buf_id ) == 1 then H .map_buf_triggers (buf_id ) end
603603 end
604+ H .state .disable_autocmd_triggers = false
604605end
605606
606607--- Enable triggers in buffer
@@ -617,6 +618,7 @@ MiniClue.disable_all_triggers = function()
617618 for _ , buf_id in ipairs (vim .api .nvim_list_bufs ()) do
618619 H .unmap_buf_triggers (buf_id )
619620 end
621+ H .state .disable_autocmd_triggers = true
620622end
621623
622624--- Disable triggers in buffer
@@ -1190,6 +1192,10 @@ H.create_autocommands = function(config)
11901192 au (' RecordingLeave' , ' *' , MiniClue .enable_all_triggers , ' Enable all triggers' )
11911193
11921194 au (' VimResized' , ' *' , H .window_update , ' Update window on resize' )
1195+
1196+ if vim .fn .has (' nvim-0.10' ) == 1 then
1197+ au (' ModeChanged' , ' n:no' , function () H .start_query ({ mode = " o" , keys = " " }) end , ' Trigger on change to operator-pending mode' )
1198+ end
11931199end
11941200
11951201-- stylua: ignore
@@ -1229,6 +1235,31 @@ H.get_buf_var = function(buf_id, name)
12291235end
12301236
12311237-- Triggers -------------------------------------------------------------------
1238+ H .start_query = function (trigger )
1239+ if vim .fn .has (' nvim-0.10' ) == 1 and vim .fn .state (' m' ) ~= ' ' then
1240+ return
1241+ end
1242+
1243+ if H .state .disable_autocmd_triggers then
1244+ return
1245+ end
1246+
1247+ -- Don't act if for some reason entered another trigger is already active
1248+ local is_in_exec = type (H .exec_trigger ) == ' table'
1249+ if is_in_exec then
1250+ return
1251+ end
1252+
1253+ -- Start user query
1254+ H .state_set (trigger , { trigger .keys })
1255+
1256+ -- Do not advance if no other clues to query. NOTE: it is `<= 1` and not
1257+ -- `<= 0` because the "init query" mapping should match.
1258+ if vim .tbl_count (H .state .clues ) <= 1 then return H .state_exec () end
1259+
1260+ H .state_advance ()
1261+ end
1262+
12321263H .map_buf_triggers = function (buf_id )
12331264 if not H .is_valid_buf (buf_id ) or H .is_disabled (buf_id ) then return end
12341265
@@ -1252,33 +1283,13 @@ H.map_trigger = function(buf_id, trigger)
12521283 trigger .keys = H .replace_termcodes (trigger .keys )
12531284 local keys_trans = H .keytrans (trigger .keys )
12541285
1255- local rhs = function ()
1256- -- Don't act if for some reason entered the same trigger during state exec
1257- local is_in_exec = type (H .exec_trigger ) == ' table'
1258- and H .exec_trigger .mode == trigger .mode
1259- and H .exec_trigger .keys == trigger .keys
1260- if is_in_exec then
1261- H .exec_trigger = nil
1262- return
1263- end
1264-
1265- -- Start user query
1266- H .state_set (trigger , { trigger .keys })
1267-
1268- -- Do not advance if no other clues to query. NOTE: it is `<= 1` and not
1269- -- `<= 0` because the "init query" mapping should match.
1270- if vim .tbl_count (H .state .clues ) <= 1 then return H .state_exec () end
1271-
1272- H .state_advance ()
1273- end
1274-
12751286 -- Use buffer-local mappings and `nowait` to make it a primary source of
12761287 -- keymap execution
12771288 local desc = string.format (' Query keys after "%s"' , keys_trans )
12781289 local opts = { buffer = buf_id , nowait = true , desc = desc }
12791290
12801291 -- Create mapping. Use translated variant to make it work with <F*> keys.
1281- vim .keymap .set (trigger .mode , keys_trans , rhs , opts )
1292+ vim .keymap .set (trigger .mode , keys_trans , function () H . start_query ( trigger ) end , opts )
12821293end
12831294
12841295H .unmap_trigger = function (buf_id , trigger )
@@ -1372,20 +1383,20 @@ H.state_exec = function()
13721383 local has_postkeys = (clue or {}).postkeys ~= nil
13731384 H .state_reset (has_postkeys )
13741385
1375- -- Disable trigger !!!VERY IMPORTANT!!!
1386+ -- Disable triggers !!!VERY IMPORTANT!!!
13761387 -- This is a workaround against infinite recursion (like if `g` is trigger
13771388 -- then typing `gg`/`g~` would introduce infinite recursion).
13781389 local buf_id = vim .api .nvim_get_current_buf ()
1379- H . unmap_trigger ( buf_id , trigger )
1390+ MiniClue . disable_all_triggers ( )
13801391
13811392 -- Execute keys. The `i` flag is used to fully support Operator-pending mode.
13821393 -- Flag `t` imitates keys as if user typed, which is reasonable but has small
13831394 -- downside with edge cases of 'langmap' (like ':\;;\;:') as it "inverts" key
13841395 -- meaning second time (at least in Normal mode).
13851396 vim .api .nvim_feedkeys (keys_to_type , ' mit' , false )
13861397
1387- -- Enable trigger back after it can no longer harm
1388- vim .schedule (function () H . map_trigger ( buf_id , trigger ) end )
1398+ -- Enable triggers back after it can no longer harm
1399+ vim .schedule (function () MiniClue . enable_all_triggers ( ) end )
13891400
13901401 -- Apply postkeys (in scheduled fashion)
13911402 if has_postkeys then H .state_apply_postkeys (clue .postkeys ) end
@@ -1438,8 +1449,11 @@ H.compute_exec_keys = function()
14381449 -- Using `feedkeys()` inside Operator-pending mode leads to its cancel into
14391450 -- Normal/Insert mode so extra work should be done to rebuild all keys
14401451 if vim .startswith (cur_mode , ' no' ) then
1441- local operator_tweak = H .operator_tweaks [vim .v .operator ] or function (x ) return x end
1442- res = operator_tweak (vim .v .operator .. H .get_forced_submode () .. res )
1452+ res = H .get_forced_submode () .. res
1453+ if H .state .trigger .keys ~= " " then
1454+ local operator_tweak = H .operator_tweaks [vim .v .operator ] or function (x ) return x end
1455+ res = operator_tweak (vim .v .operator .. res )
1456+ end
14431457 elseif not vim .startswith (cur_mode , ' i' ) and H .get_default_register () ~= vim .v .register then
14441458 -- Force non-default register but not in Insert mode
14451459 res = ' "' .. vim .v .register .. res
0 commit comments