(ragne) use g@ for Range.from_motion
	
		
			
	
		
	
	
		
	
		
			All checks were successful
		
		
	
	
		
			
				
	
				NeoVim tests / plenary-tests (push) Successful in 10s
				
			
		
		
	
	
				
					
				
			
		
			All checks were successful
		
		
	
	NeoVim tests / plenary-tests (push) Successful in 10s
				
			This commit is contained in:
		
							parent
							
								
									c760c495b7
								
							
						
					
					
						commit
						fcb2c3ddd7
					
				@ -1,15 +1,5 @@
 | 
				
			|||||||
local Pos = require 'u.pos'
 | 
					local Pos = require 'u.pos'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
-- Certain functions in the Range class yank text. In order to prevent unwanted
 | 
					 | 
				
			||||||
-- highlighting, we intercept and discard some calls to the `on_yank` callback.
 | 
					 | 
				
			||||||
local orig_on_yank = vim.hl.on_yank
 | 
					 | 
				
			||||||
local on_yank_enabled = true
 | 
					 | 
				
			||||||
--- @diagnostic disable-next-line: duplicate-set-field
 | 
					 | 
				
			||||||
function vim.hl.on_yank(opts)
 | 
					 | 
				
			||||||
  if not on_yank_enabled then return end
 | 
					 | 
				
			||||||
  return orig_on_yank(opts)
 | 
					 | 
				
			||||||
end
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
--- @class u.Range
 | 
					--- @class u.Range
 | 
				
			||||||
--- @field start u.Pos
 | 
					--- @field start u.Pos
 | 
				
			||||||
--- @field stop u.Pos|nil
 | 
					--- @field stop u.Pos|nil
 | 
				
			||||||
@ -133,10 +123,6 @@ function Range.from_motion(motion, opts)
 | 
				
			|||||||
  local is_txtobj = scope == 'a' or scope == 'i'
 | 
					  local is_txtobj = scope == 'a' or scope == 'i'
 | 
				
			||||||
  local is_quote_txtobj = is_txtobj and vim.tbl_contains({ "'", '"', '`' }, motion_rest)
 | 
					  local is_quote_txtobj = is_txtobj and vim.tbl_contains({ "'", '"', '`' }, motion_rest)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  --- @type u.Pos
 | 
					 | 
				
			||||||
  local start
 | 
					 | 
				
			||||||
  --- @type u.Pos
 | 
					 | 
				
			||||||
  local stop
 | 
					 | 
				
			||||||
  -- Capture the original state of the buffer for restoration later.
 | 
					  -- Capture the original state of the buffer for restoration later.
 | 
				
			||||||
  local original_state = {
 | 
					  local original_state = {
 | 
				
			||||||
    winview = vim.fn.winsaveview(),
 | 
					    winview = vim.fn.winsaveview(),
 | 
				
			||||||
@ -144,59 +130,57 @@ function Range.from_motion(motion, opts)
 | 
				
			|||||||
    cursor = vim.fn.getpos '.',
 | 
					    cursor = vim.fn.getpos '.',
 | 
				
			||||||
    pos_lbrack = vim.fn.getpos "'[",
 | 
					    pos_lbrack = vim.fn.getpos "'[",
 | 
				
			||||||
    pos_rbrack = vim.fn.getpos "']",
 | 
					    pos_rbrack = vim.fn.getpos "']",
 | 
				
			||||||
 | 
					    opfunc = vim.go.operatorfunc,
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					  --- @type u.Range|nil
 | 
				
			||||||
 | 
					  local captured_range = nil
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  vim.api.nvim_buf_call(opts.bufnr, function()
 | 
					  vim.api.nvim_buf_call(opts.bufnr, function()
 | 
				
			||||||
    if opts.pos ~= nil then opts.pos:save_to_pos '.' end
 | 
					    if opts.pos ~= nil then opts.pos:save_to_pos '.' end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    Pos.invalid():save_to_pos "'["
 | 
					    _G.Range__from_motion_opfunc = function(ty) captured_range = Range.from_op_func(ty) end
 | 
				
			||||||
    Pos.invalid():save_to_pos "']"
 | 
					    vim.go.operatorfunc = 'v:lua.Range__from_motion_opfunc'
 | 
				
			||||||
 | 
					 | 
				
			||||||
    local prev_on_yank_enabled = on_yank_enabled
 | 
					 | 
				
			||||||
    on_yank_enabled = false
 | 
					 | 
				
			||||||
    vim.cmd {
 | 
					    vim.cmd {
 | 
				
			||||||
      cmd = 'normal',
 | 
					      cmd = 'normal',
 | 
				
			||||||
      bang = not opts.user_defined,
 | 
					      bang = not opts.user_defined,
 | 
				
			||||||
      args = { '""y' .. motion },
 | 
					      args = { 'g@' .. motion },
 | 
				
			||||||
      mods = { silent = true },
 | 
					      mods = { silent = true },
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    on_yank_enabled = prev_on_yank_enabled
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    start = Pos.from_pos "'["
 | 
					 | 
				
			||||||
    stop = Pos.from_pos "']"
 | 
					 | 
				
			||||||
  end)
 | 
					  end)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -- Restore original state:
 | 
					  -- Restore original state:
 | 
				
			||||||
  vim.fn.winrestview(original_state.winview)
 | 
					  vim.fn.winrestview(original_state.winview)
 | 
				
			||||||
  vim.fn.setreg('"', original_state.regquote)
 | 
					  vim.fn.setreg('"', original_state.regquote)
 | 
				
			||||||
  vim.fn.setpos('.', original_state.cursor)
 | 
					  vim.fn.setpos('.', original_state.cursor)
 | 
				
			||||||
  vim.fn.setpos("'[", original_state.pos_lbrack)
 | 
					  vim.fn.setpos("'[", original_state.pos_lbrack)
 | 
				
			||||||
  vim.fn.setpos("']", original_state.pos_rbrack)
 | 
					  vim.fn.setpos("']", original_state.pos_rbrack)
 | 
				
			||||||
 | 
					  vim.go.operatorfunc = original_state.opfunc
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if start == stop and start:is_invalid() then return nil end
 | 
					  if not captured_range then return nil end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  -- Fixup the bounds:
 | 
					  -- Fixup the bounds:
 | 
				
			||||||
  if
 | 
					  if
 | 
				
			||||||
    -- I have no idea why, but when yanking `i"`, the stop-mark is
 | 
					    -- I have no idea why, but when yanking `i"`, the stop-mark is
 | 
				
			||||||
    -- placed on the ending quote. For other text-objects, the stop-
 | 
					    -- placed on the ending quote. For other text-objects, the stop-
 | 
				
			||||||
    -- mark is placed before the closing character.
 | 
					    -- mark is placed before the closing character.
 | 
				
			||||||
    (is_quote_txtobj and scope == 'i' and stop:char() == motion_rest)
 | 
					    (is_quote_txtobj and scope == 'i' and captured_range.stop:char() == motion_rest)
 | 
				
			||||||
    -- *Sigh*, this also sometimes happens for `it` as well.
 | 
					    -- *Sigh*, this also sometimes happens for `it` as well.
 | 
				
			||||||
    or (motion == 'it' and stop:char() == '<')
 | 
					    or (motion == 'it' and captured_range.stop:char() == '<')
 | 
				
			||||||
  then
 | 
					  then
 | 
				
			||||||
    stop = stop:next(-1) or stop
 | 
					    captured_range.stop = captured_range.stop:next(-1) or captured_range.stop
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
  if is_quote_txtobj and scope == 'a' then
 | 
					  if is_quote_txtobj and scope == 'a' then
 | 
				
			||||||
    start = start:find_next(1, motion_rest) or start
 | 
					    captured_range.start = captured_range.start:find_next(1, motion_rest) or captured_range.start
 | 
				
			||||||
    stop = stop:find_next(-1, motion_rest) or stop
 | 
					    captured_range.stop = captured_range.stop:find_next(-1, motion_rest) or captured_range.stop
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  if
 | 
					  if
 | 
				
			||||||
    opts.contains_cursor
 | 
					    opts.contains_cursor and not captured_range:contains(Pos.new(unpack(original_state.cursor)))
 | 
				
			||||||
    and not Range.new(start, stop):contains(Pos.new(unpack(original_state.cursor)))
 | 
					 | 
				
			||||||
  then
 | 
					  then
 | 
				
			||||||
    return nil
 | 
					    return nil
 | 
				
			||||||
  end
 | 
					  end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  return Range.new(start, stop)
 | 
					  return captured_range
 | 
				
			||||||
end
 | 
					end
 | 
				
			||||||
 | 
					
 | 
				
			||||||
--- Get range information from the currently selected visual text.
 | 
					--- Get range information from the currently selected visual text.
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user