Wrap the main function in a try..catch..finally loop

The script throws exceptions when cancelled or when there's no matches.
The catch block displays the message and restores the cursor position.
The finally block restores buffer properties.
This commit is contained in:
Kim Silkebækken 2011-03-28 17:48:09 +02:00
parent 99afbc1b88
commit a5119b9981

View File

@ -183,11 +183,6 @@
let lines_items = items(lines)
" }}}
" Store original buffer properties {{{
let modified = &modified
let modifiable = &modifiable
let readonly = &readonly
" }}}
let input_char = ''
@ -195,16 +190,6 @@
" Highlight source
let target_hl_id = matchadd(g:EasyMotion_target_hl, join(hl_coords, '\|'), 1)
" Make sure we can change the buffer {{{
if modifiable == 0
silent setl modifiable
endif
if readonly == 1
silent setl noreadonly
endif
" }}}
" Set lines with markers
for [line_num, line] in lines_items
try
@ -242,20 +227,6 @@
redraw
" Restore original properties {{{
if modified == 0
silent setl nomodified
endif
if modifiable == 0
silent setl nomodifiable
endif
if readonly == 1
silent setl readonly
endif
" }}}
" Check if the input char is valid
if ! has_key(s:key_to_index, input_char) || s:key_to_index[input_char] >= targets_len
" Invalid input char
@ -276,94 +247,114 @@
let targets = []
let visualmode = a:0 > 0 ? a:1 : ''
" Store original scrolloff value
let scrolloff = &scrolloff
setl scrolloff=0
try
" Reset properties
call <SID>VarReset('&scrolloff', 0)
call <SID>VarReset('&modified', 0)
call <SID>VarReset('&modifiable', 1)
call <SID>VarReset('&readonly', 0)
" Find motion targets
while 1
let search_direction = (a:direction == 1 ? 'b' : '')
let search_stopline = line(a:direction == 1 ? 'w0' : 'w$')
" Find motion targets
while 1
let search_direction = (a:direction == 1 ? 'b' : '')
let search_stopline = line(a:direction == 1 ? 'w0' : 'w$')
let pos = searchpos(a:regexp, search_direction, search_stopline)
let pos = searchpos(a:regexp, search_direction, search_stopline)
" Reached end of search range
if pos == [0, 0]
break
" Reached end of search range
if pos == [0, 0]
break
endif
" Skip folded lines
if foldclosed(pos[0]) != -1
continue
endif
call add(targets, pos)
endwhile
let targets_len = len(targets)
let groups_len = len(s:index_to_key)
if targets_len == 0
throw 'No matches'
endif
" Skip folded lines
if foldclosed(pos[0]) != -1
continue
endif
call add(targets, pos)
endwhile
let targets_len = len(targets)
let groups_len = len(s:index_to_key)
if targets_len == 0
redraw
call <SID>Message('No matches')
" Restore cursor position
call setpos('.', [0, orig_pos[0], orig_pos[1]])
" Restore original scrolloff value
execute 'setl scrolloff=' . scrolloff
" Split targets into key groups {{{
let groups = []
let i = 0
return
endif
while i < targets_len
call add(groups, targets[i : i + groups_len - 1])
" Restore cursor position
call setpos('.', [0, orig_pos[0], orig_pos[1]])
let i += groups_len
endwhile
" }}}
" Too many groups; only display the first ones {{{
if len(groups) > groups_len
call <SID>Message('Only displaying the first matches')
" Split targets into key groups {{{
let groups = []
let i = 0
let groups = groups[0 : groups_len - 1]
endif
" }}}
while i < targets_len
call add(groups, targets[i : i + groups_len - 1])
" Shade inactive source
if g:EasyMotion_shade
let shade_hl_pos = '\%' . orig_pos[0] . 'l\%'. orig_pos[1] .'c'
let i += groups_len
endwhile
" }}}
" Too many groups; only display the first ones {{{
if len(groups) > groups_len
call <SID>Message('Only displaying the first matches')
if a:direction == 1
" Backward
let shade_hl_re = '\%'. line('w0') .'l\_.*' . shade_hl_pos
else
" Forward
let shade_hl_re = shade_hl_pos . '\_.*\%'. line('w$') .'l'
endif
let groups = groups[0 : groups_len - 1]
let shade_hl_id = matchadd(g:EasyMotion_shade_hl, shade_hl_re, 0)
endif
" }}}
" Shade inactive source
if g:EasyMotion_shade
let shade_hl_pos = '\%' . orig_pos[0] . 'l\%'. orig_pos[1] .'c'
" Prompt user for target group/character
let coords = <SID>PromptUser(groups)
if a:direction == 1
" Backward
let shade_hl_re = '\%'. line('w0') .'l\_.*' . shade_hl_pos
" Remove shading
if g:EasyMotion_shade
call matchdelete(shade_hl_id)
endif
if len(coords) != 2
throw 'Cancelled'
else
" Forward
let shade_hl_re = shade_hl_pos . '\_.*\%'. line('w$') .'l'
if ! empty(visualmode)
" Store original marks
let m_a = getpos("'a")
let m_b = getpos("'b")
" Store start/end positions
call setpos("'a", [0, orig_pos[0], orig_pos[1]])
call setpos("'b", [0, coords[0], coords[1]])
" Update selection
silent exec 'normal! `a' . visualmode . '`b'
" Restore original marks
call setpos("'a", m_a)
call setpos("'b", m_b)
else
" Update cursor position
call setpos('.', [0, coords[0], coords[1]])
endif
call <SID>Message('Jumping to [' . coords[0] . ', ' . coords[1] . ']')
endif
catch /.*/
redraw
let shade_hl_id = matchadd(g:EasyMotion_shade_hl, shade_hl_re, 0)
endif
" Prompt user for target group/character
let coords = <SID>PromptUser(groups)
" Remove shading
if g:EasyMotion_shade
call matchdelete(shade_hl_id)
endif
if len(coords) != 2
" Cancelled by user
call <SID>Message('Operation cancelled')
" Show exception message
call <SID>Message(v:exception)
" Restore cursor position/selection
if ! empty(visualmode)
@ -371,36 +362,14 @@
else
call setpos('.', [0, orig_pos[0], orig_pos[1]])
endif
finally
redraw
" Restore original scrolloff value
execute 'setl scrolloff=' . scrolloff
return
else
if ! empty(visualmode)
" Store original marks
let m_a = getpos("'a")
let m_b = getpos("'b")
" Store start/end positions
call setpos("'a", [0, orig_pos[0], orig_pos[1]])
call setpos("'b", [0, coords[0], coords[1]])
" Update selection
silent exec 'normal! `a' . visualmode . '`b'
" Restore original marks
call setpos("'a", m_a)
call setpos("'b", m_b)
else
" Update cursor position
call setpos('.', [0, coords[0], coords[1]])
endif
" Restore original scrolloff value
execute 'setl scrolloff=' . scrolloff
call <SID>Message('Jumping to [' . coords[0] . ', ' . coords[1] . ']')
endif
" Restore properties
call <SID>VarReset('&scrolloff')
call <SID>VarReset('&modified')
call <SID>VarReset('&modifiable')
call <SID>VarReset('&readonly')
endtry
endfunction " }}}
" }}}