Skip to content

Commit

Permalink
Merge pull request #55 from kana/keep-marks
Browse files Browse the repository at this point in the history
Keep marks before and after selection
  • Loading branch information
kana committed Sep 23, 2017
2 parents 8e885f9 + fd1811a commit 7e67965
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 12 deletions.
46 changes: 34 additions & 12 deletions autoload/textobj/user.vim
Expand Up @@ -442,42 +442,47 @@ endfunction


function! s:plugin.define_interface_key_mappings() "{{{3
let RHS_PATTERN =
\ ':<C-u>call g:__textobj_' . self.name . '.do_by_pattern('
\ . '"%s",'
\ . '"%s",'
\ . '"<mode>"'
\ . ')<Return>'
let RHS_FUNCTION =
\ ':<C-u>call g:__textobj_' . self.name . '.do_by_function('
let RHS_FORMAT =
\ '%s'
\ . ':<C-u>call g:__textobj_' . self.name . '.%s('
\ . '"%s",'
\ . '"%s",'
\ . '"<mode>"'
\ . ')<Return>'
\ . '%s'

for [obj_name, specs] in items(self.obj_specs)
for spec_name in filter(keys(specs), 's:is_ui_property_name(v:val)')
if spec_name =~# '^move'
let save = ''
let restore = ''
else " spec_name =~# '^select'
let save = '<SID>(save-marks)'
let restore = '<SID>(restore-marks)'
endif

" lhs
let lhs = '<silent> ' . self.interface_mapping_name(obj_name, spec_name)
let lhs = self.interface_mapping_name(obj_name, spec_name)

" rhs
let _ = spec_name . '-function'
if has_key(specs, _)
let rhs = printf(RHS_FUNCTION, spec_name, obj_name)
let do = 'do_by_function'
elseif has_key(specs, 'pattern')
let rhs = printf(RHS_PATTERN, spec_name, obj_name)
let do = 'do_by_pattern'
else
" skip to allow to define user's own {rhs} of the interface mapping.
continue
endif
let rhs = printf(RHS_FORMAT, save, do, spec_name, obj_name, restore)

" map
if spec_name =~# '^move'
let MapFunction = function('s:noremap')
else " spec_name =~# '^select'
let MapFunction = function('s:objnoremap')
endif
call MapFunction(1, lhs, rhs)
call MapFunction(1, '<silent> <script>' . lhs, rhs)
endfor
endfor
endfunction
Expand Down Expand Up @@ -776,6 +781,23 @@ function! s:fail(interface_key_mapping_lhs)
throw printf('Text object %s is not defined', a:interface_key_mapping_lhs)
endfunction

noremap <expr> <SID>(save-marks) <SID>save_marks()
noremap <expr> <SID>(restore-marks) <SID>restore_marks()
let s:original_marks = {}

function! s:save_marks()
let s:original_marks['<'] = getpos("'<")
let s:original_marks['>'] = getpos("'>")
return ''
endfunction

function! s:restore_marks()
call setpos("'<", s:original_marks['<'])
call setpos("'>", s:original_marks['>'])
return ''
endfunction




Expand Down
72 changes: 72 additions & 0 deletions t/keep-marks.vim
@@ -0,0 +1,72 @@
call textobj#user#plugin('line', {
\ '-': {
\ 'select-a': 'al',
\ 'select-a-function': 'SelectA',
\ 'select': 'il',
\ 'pattern': '^\s*\zs.\{-}\ze\s*$',
\ },
\ })

function! SelectA()
if empty(getline('.'))
return 0
endif

normal! 0
let head_pos = getpos('.')

normal! $
let tail_pos = getpos('.')

return ['v', head_pos, tail_pos]
endfunction

describe 'Custom text object'
before
new

silent 1 put! =[
\ 'if (!foo) {',
\ ' bar = ''baz''',
\ ' qux()',
\ '}',
\ ]
let @0 = '*nothing yanked*'
execute 'normal!' "1G2|vj\<Esc>"
end

after
close!
end

context 'defined by a function'
it 'keeps ''< and ''> marks'
Expect @0 ==# '*nothing yanked*'
Expect [line("'<"), col("'<")] == [1, 2]
Expect [line("'>"), col("'>")] == [2, 2]

normal 3Gyal

Expect @0 ==# ' qux()'
Expect [line("'<"), col("'<")] == [1, 2]
Expect [line("'>"), col("'>")] == [2, 2]
end
end

context 'defined by a pattern'
it 'keeps ''< and ''> marks'
Expect @0 ==# '*nothing yanked*'
Expect [line("'<"), col("'<")] == [1, 2]
Expect [line("'>"), col("'>")] == [2, 2]

normal 3Gyil

Expect @0 ==# 'qux()'
Expect [line("'<"), col("'<")] == [1, 2]
Expect [line("'>"), col("'>")] == [2, 2]
end
end
end

" __END__ "{{{1
" vim: foldmethod=marker

0 comments on commit 7e67965

Please sign in to comment.