@@ -257,6 +257,31 @@ local function get_first_mutable_column_col(adapter, ranges)
257257 return min_col
258258end
259259
260+ --- @param bufnr integer
261+ --- @param adapter oil.Adapter
262+ --- @param mode false | " name" | " editable"
263+ --- @param cur integer[]
264+ --- @return integer[] | nil
265+ local function calc_constrained_cursor_pos (bufnr , adapter , mode , cur )
266+ local parser = require (" oil.mutator.parser" )
267+ local line = vim .api .nvim_buf_get_lines (bufnr , cur [1 ] - 1 , cur [1 ], true )[1 ]
268+ local column_defs = columns .get_supported_columns (adapter )
269+ local result = parser .parse_line (adapter , line , column_defs )
270+ if result and result .ranges then
271+ local min_col
272+ if mode == " editable" then
273+ min_col = get_first_mutable_column_col (adapter , result .ranges )
274+ elseif mode == " name" then
275+ min_col = result .ranges .name [1 ]
276+ else
277+ error (string.format (' Unexpected value "%s" for option constrain_cursor' , mode ))
278+ end
279+ if cur [2 ] < min_col then
280+ return { cur [1 ], min_col }
281+ end
282+ end
283+ end
284+
260285--- Force cursor to be after hidden/immutable columns
261286--- @param bufnr integer
262287--- @param mode false | " name" | " editable"
@@ -267,28 +292,30 @@ local function constrain_cursor(bufnr, mode)
267292 if bufnr ~= vim .api .nvim_get_current_buf () then
268293 return
269294 end
270- local parser = require (" oil.mutator.parser" )
271295
272296 local adapter = util .get_adapter (bufnr , true )
273297 if not adapter then
274298 return
275299 end
276300
277- local cur = vim .api .nvim_win_get_cursor (0 )
278- local line = vim .api .nvim_buf_get_lines (bufnr , cur [1 ] - 1 , cur [1 ], true )[1 ]
279- local column_defs = columns .get_supported_columns (adapter )
280- local result = parser .parse_line (adapter , line , column_defs )
281- if result and result .ranges then
282- local min_col
283- if mode == " editable" then
284- min_col = get_first_mutable_column_col (adapter , result .ranges )
285- elseif mode == " name" then
286- min_col = result .ranges .name [1 ]
287- else
288- error (string.format (' Unexpected value "%s" for option constrain_cursor' , mode ))
289- end
290- if cur [2 ] < min_col then
291- vim .api .nvim_win_set_cursor (0 , { cur [1 ], min_col })
301+ local mc = package.loaded [" multicursor-nvim" ]
302+ if mc then
303+ mc .onSafeState (function ()
304+ mc .action (function (ctx )
305+ ctx :forEachCursor (function (cursor )
306+ local new_cur =
307+ calc_constrained_cursor_pos (bufnr , adapter , mode , { cursor :line (), cursor :col () - 1 })
308+ if new_cur then
309+ cursor :setPos ({ new_cur [1 ], new_cur [2 ] + 1 })
310+ end
311+ end )
312+ end )
313+ end , { once = true })
314+ else
315+ local cur = vim .api .nvim_win_get_cursor (0 )
316+ local new_cur = calc_constrained_cursor_pos (bufnr , adapter , mode , cur )
317+ if new_cur then
318+ vim .api .nvim_win_set_cursor (0 , new_cur )
292319 end
293320 end
294321end
0 commit comments