Browse files

EasyMotion 更新:合并 abudden 的 autoload 提升补丁

  • Loading branch information...
1 parent 7e3567d commit 16e5efa4a0dae04f6b993db747aae22e6a34accd @lilydjwg committed Mar 16, 2013
Showing with 614 additions and 21 deletions.
  1. +28 −15 autoload/EasyMotion.vim
  2. +518 −0 autoload/EasyMotion/EasyMotion.vim
  3. +62 −0 autoload/EasyMotion/Init.vim
  4. +6 −6 plugin/EasyMotion.vim
View
43 autoload/EasyMotion.vim
@@ -146,18 +146,15 @@
endfunction " }}}
function! s:GetChar() " {{{
let char = getchar()
-
- if char == 27
- " Escape key pressed
+ if char == 27 " Escape key pressed
redraw
-
- call s:Message('Cancelled')
-
- return ''
+ throw("Cancelled")
endif
-
return nr2char(char)
endfunction " }}}
+ function! s:GetTwoCharKeyCombo() " {{{
+ return s:GetChar() . s:GetChar()
+ endfunction " }}}
function! s:GetSearchChar(visualmode) " {{{
call s:Prompt('Search for character')
@@ -175,6 +172,21 @@
return char
endfunction " }}}
+ function! s:GenerateTwoKeyCombos() " {{{
+ let usable_keys = split(g:EasyMotion_keys, '\zs')
+
+ let difficult_to_type_combos = {'fv':1,'fg':1,'hj':1,'nj':1,'mj':1,'ft':1,'fr':1,'fb':1,'fc':1,'de':1,'sw':1,'sx':1,'aq':1,'az':1}
+
+ let two_key_combos = []
+ for key1 in usable_keys
+ for key2 in usable_keys
+ if !has_key(difficult_to_type_combos, key1 . key2) && !has_key(difficult_to_type_combos, key2 . key1)
+ let two_key_combos += [key1 . key2]
+ end
+ endfor
+ endfor
+ return two_key_combos
+ endfunction " }}}
" }}}
" Grouping algorithms {{{
let s:grouping_algorithms = {
@@ -380,7 +392,7 @@
" This has to be done in order to match the correct
" column; \%c matches the byte column and not display
" column.
- let target_char_len = strlen(matchstr(lines[line_num]['marker'], '\%' . col_num . 'c.'))
+ let target_char_len = strlen(matchstr(lines[line_num]['marker'], '\%' . col_num . 'c..'))
let target_key_len = strlen(target_key)
" Solve multibyte issues by matching the byte column
@@ -389,14 +401,14 @@
if strlen(lines[line_num]['marker']) > 0
" Substitute marker character if line length > 0
- let lines[line_num]['marker'] = substitute(lines[line_num]['marker'], '\%' . col_num . 'c.', target_key, '')
+ let lines[line_num]['marker'] = substitute(lines[line_num]['marker'], '\%' . col_num . 'c..', target_key, '')
else
" Set the line to the marker character if the line is empty
let lines[line_num]['marker'] = target_key
endif
" Add highlighting coordinates
- call add(hl_coords, '\%' . line_num . 'l\%' . col_num . 'c')
+ call add(hl_coords, '\%' . line_num . 'l\%' . col_num . 'c..')
" Add marker/target lenght difference for multibyte
" compensation
@@ -417,8 +429,7 @@
" Get target character {{{
call s:Prompt('Target key')
-
- let char = s:GetChar()
+ let char = s:GetTwoCharKeyCombo()
" }}}
finally
" Restore original lines
@@ -494,11 +505,13 @@
" }}}
let GroupingFn = function('s:GroupingAlgorithm' . s:grouping_algorithms[g:EasyMotion_grouping])
- let groups = GroupingFn(targets, split(g:EasyMotion_keys, '\zs'))
+
+ " Take available keys and generate all possible two key combos
+ let groups = GroupingFn(targets, s:GenerateTwoKeyCombos())
" Shade inactive source {{{
if g:EasyMotion_do_shade
- let shade_hl_pos = '\%' . orig_pos[0] . 'l\%'. orig_pos[1] .'c'
+ let shade_hl_pos = '\%' . orig_pos[0] . 'l\%'. orig_pos[1] .'c..'
if a:direction == 1
" Backward
View
518 autoload/EasyMotion/EasyMotion.vim
@@ -0,0 +1,518 @@
+" EasyMotion - Vim motions on speed!
+"
+" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
+" Source repository: https://github.com/Lokaltog/vim-easymotion
+
+" Motion functions {{{
+ function! EasyMotion#EasyMotion#F(visualmode, direction) " {{{
+ let char = s:GetSearchChar(a:visualmode)
+
+ if empty(char)
+ return
+ endif
+
+ let re = '\C' . escape(char, '.$^~')
+
+ call s:EasyMotion(re, a:direction, a:visualmode ? visualmode() : '', mode(1))
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#T(visualmode, direction) " {{{
+ let char = s:GetSearchChar(a:visualmode)
+
+ if empty(char)
+ return
+ endif
+
+ if a:direction == 1
+ let re = '\C' . escape(char, '.$^~') . '\zs.'
+ else
+ let re = '\C.' . escape(char, '.$^~')
+ endif
+
+ call s:EasyMotion(re, a:direction, a:visualmode ? visualmode() : '', mode(1))
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#WB(visualmode, direction) " {{{
+ call s:EasyMotion('\(\<.\|^$\)', a:direction, a:visualmode ? visualmode() : '', '')
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#WBW(visualmode, direction) " {{{
+ call s:EasyMotion('\(\(^\|\s\)\@<=\S\|^$\)', a:direction, a:visualmode ? visualmode() : '', '')
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#E(visualmode, direction) " {{{
+ call s:EasyMotion('\(.\>\|^$\)', a:direction, a:visualmode ? visualmode() : '', mode(1))
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#EW(visualmode, direction) " {{{
+ call s:EasyMotion('\(\S\(\s\|$\)\|^$\)', a:direction, a:visualmode ? visualmode() : '', mode(1))
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#JK(visualmode, direction) " {{{
+ call s:EasyMotion('^\(\w\|\s*\zs\|$\)', a:direction, a:visualmode ? visualmode() : '', '')
+ endfunction " }}}
+ function! EasyMotion#EasyMotion#Search(visualmode, direction) " {{{
+ call s:EasyMotion(@/, a:direction, a:visualmode ? visualmode() : '', '')
+ endfunction " }}}
+" }}}
+" Helper functions {{{
+ function! s:Message(message) " {{{
+ echo 'EasyMotion: ' . a:message
+ endfunction " }}}
+ function! s:Prompt(message) " {{{
+ echohl Question
+ echo a:message . ': '
+ echohl None
+ endfunction " }}}
+ function! s:VarReset(var, ...) " {{{
+ if ! exists('s:var_reset')
+ let s:var_reset = {}
+ endif
+
+ let buf = bufname("")
+
+ if a:0 == 0 && has_key(s:var_reset, a:var)
+ " Reset var to original value
+ call setbufvar(buf, a:var, s:var_reset[a:var])
+ elseif a:0 == 1
+ let new_value = a:0 == 1 ? a:1 : ''
+
+ " Store original value
+ let s:var_reset[a:var] = getbufvar(buf, a:var)
+
+ " Set new var value
+ call setbufvar(buf, a:var, new_value)
+ endif
+ endfunction " }}}
+ function! s:SetLines(lines, key) " {{{
+ try
+ " Try to join changes with previous undo block
+ undojoin
+ catch
+ endtry
+
+ for [line_num, line] in a:lines
+ call setline(line_num, line[a:key])
+ endfor
+ endfunction " }}}
+ function! s:GetChar() " {{{
+ let char = getchar()
+
+ if char == 27
+ " Escape key pressed
+ redraw
+
+ call s:Message('Cancelled')
+
+ return ''
+ endif
+
+ return nr2char(char)
+ endfunction " }}}
+ function! s:GetSearchChar(visualmode) " {{{
+ call s:Prompt('Search for character')
+
+ let char = s:GetChar()
+
+ " Check that we have an input char
+ if empty(char)
+ " Restore selection
+ if ! empty(a:visualmode)
+ silent exec 'normal! gv'
+ endif
+
+ return ''
+ endif
+
+ return char
+ endfunction " }}}
+" }}}
+" Grouping algorithms {{{
+ let s:grouping_algorithms = {
+ \ 1: 'SCTree'
+ \ , 2: 'Original'
+ \ }
+ " Single-key/closest target priority tree {{{
+ " This algorithm tries to assign one-key jumps to all the targets closest to the cursor.
+ " It works recursively and will work correctly with as few keys as two.
+ function! s:GroupingAlgorithmSCTree(targets, keys)
+ " Prepare variables for working
+ let targets_len = len(a:targets)
+ let keys_len = len(a:keys)
+
+ let groups = {}
+
+ let keys = reverse(copy(a:keys))
+
+ " Semi-recursively count targets {{{
+ " We need to know exactly how many child nodes (targets) this branch will have
+ " in order to pass the correct amount of targets to the recursive function.
+
+ " Prepare sorted target count list {{{
+ " This is horrible, I know. But dicts aren't sorted in vim, so we need to
+ " work around that. That is done by having one sorted list with key counts,
+ " and a dict which connects the key with the keys_count list.
+
+ let keys_count = []
+ let keys_count_keys = {}
+
+ let i = 0
+ for key in keys
+ call add(keys_count, 0)
+
+ let keys_count_keys[key] = i
+
+ let i += 1
+ endfor
+ " }}}
+
+ let targets_left = targets_len
+ let level = 0
+ let i = 0
+
+ while targets_left > 0
+ " Calculate the amount of child nodes based on the current level
+ let childs_len = (level == 0 ? 1 : (keys_len - 1) )
+
+ for key in keys
+ " Add child node count to the keys_count array
+ let keys_count[keys_count_keys[key]] += childs_len
+
+ " Subtract the child node count
+ let targets_left -= childs_len
+
+ if targets_left <= 0
+ " Subtract the targets left if we added too many too
+ " many child nodes to the key count
+ let keys_count[keys_count_keys[key]] += targets_left
+
+ break
+ endif
+
+ let i += 1
+ endfor
+
+ let level += 1
+ endwhile
+ " }}}
+ " Create group tree {{{
+ let i = 0
+ let key = 0
+
+ call reverse(keys_count)
+
+ for key_count in keys_count
+ if key_count > 1
+ " We need to create a subgroup
+ " Recurse one level deeper
+ let groups[a:keys[key]] = s:GroupingAlgorithmSCTree(a:targets[i : i + key_count - 1], a:keys)
+ elseif key_count == 1
+ " Assign single target key
+ let groups[a:keys[key]] = a:targets[i]
+ else
+ " No target
+ continue
+ endif
+
+ let key += 1
+ let i += key_count
+ endfor
+ " }}}
+
+ " Finally!
+ return groups
+ endfunction
+ " }}}
+ " Original {{{
+ function! s:GroupingAlgorithmOriginal(targets, keys)
+ " Split targets into groups (1 level)
+ let targets_len = len(a:targets)
+ let keys_len = len(a:keys)
+
+ let groups = {}
+
+ let i = 0
+ let root_group = 0
+ try
+ while root_group < targets_len
+ let groups[a:keys[root_group]] = {}
+
+ for key in a:keys
+ let groups[a:keys[root_group]][key] = a:targets[i]
+
+ let i += 1
+ endfor
+
+ let root_group += 1
+ endwhile
+ catch | endtry
+
+ " Flatten the group array
+ if len(groups) == 1
+ let groups = groups[a:keys[0]]
+ endif
+
+ return groups
+ endfunction
+ " }}}
+ " Coord/key dictionary creation {{{
+ function! s:CreateCoordKeyDict(groups, ...)
+ " Dict structure:
+ " 1,2 : a
+ " 2,3 : b
+ let sort_list = []
+ let coord_keys = {}
+ let group_key = a:0 == 1 ? a:1 : ''
+
+ for [key, item] in items(a:groups)
+ let key = ( ! empty(group_key) ? group_key : key)
+
+ if type(item) == 3
+ " Destination coords
+
+ " The key needs to be zero-padded in order to
+ " sort correctly
+ let dict_key = printf('%05d,%05d', item[0], item[1])
+ let coord_keys[dict_key] = key
+
+ " We need a sorting list to loop correctly in
+ " PromptUser, dicts are unsorted
+ call add(sort_list, dict_key)
+ else
+ " Item is a dict (has children)
+ let coord_key_dict = s:CreateCoordKeyDict(item, key)
+
+ " Make sure to extend both the sort list and the
+ " coord key dict
+ call extend(sort_list, coord_key_dict[0])
+ call extend(coord_keys, coord_key_dict[1])
+ endif
+
+ unlet item
+ endfor
+
+ return [sort_list, coord_keys]
+ endfunction
+ " }}}
+" }}}
+" Core functions {{{
+ function! s:PromptUser(groups) "{{{
+ " If only one possible match, jump directly to it {{{
+ let group_values = values(a:groups)
+
+ if len(group_values) == 1
+ redraw
+
+ return group_values[0]
+ endif
+ " }}}
+ " Prepare marker lines {{{
+ let lines = {}
+ let hl_coords = []
+ let coord_key_dict = s:CreateCoordKeyDict(a:groups)
+
+ for dict_key in sort(coord_key_dict[0])
+ let target_key = coord_key_dict[1][dict_key]
+ let [line_num, col_num] = split(dict_key, ',')
+
+ let line_num = str2nr(line_num)
+ let col_num = str2nr(col_num)
+
+ " Add original line and marker line
+ if ! has_key(lines, line_num)
+ let current_line = getline(line_num)
+
+ let lines[line_num] = { 'orig': current_line, 'marker': current_line, 'mb_compensation': 0 }
+ endif
+
+ " Compensate for byte difference between marker
+ " character and target character
+ "
+ " This has to be done in order to match the correct
+ " column; \%c matches the byte column and not display
+ " column.
+ let target_char_len = strlen(matchstr(lines[line_num]['marker'], '\%' . col_num . 'c.'))
+ let target_key_len = strlen(target_key)
+
+ " Solve multibyte issues by matching the byte column
+ " number instead of the visual column
+ let col_num -= lines[line_num]['mb_compensation']
+
+ if strlen(lines[line_num]['marker']) > 0
+ " Substitute marker character if line length > 0
+ let lines[line_num]['marker'] = substitute(lines[line_num]['marker'], '\%' . col_num . 'c.', target_key, '')
+ else
+ " Set the line to the marker character if the line is empty
+ let lines[line_num]['marker'] = target_key
+ endif
+
+ " Add highlighting coordinates
+ call add(hl_coords, '\%' . line_num . 'l\%' . col_num . 'c')
+
+ " Add marker/target lenght difference for multibyte
+ " compensation
+ let lines[line_num]['mb_compensation'] += (target_char_len - target_key_len)
+ endfor
+
+ let lines_items = items(lines)
+ " }}}
+ " Highlight targets {{{
+ let target_hl_id = matchadd(g:EasyMotion_hl_group_target, join(hl_coords, '\|'), 1)
+ " }}}
+
+ try
+ " Set lines with markers
+ call s:SetLines(lines_items, 'marker')
+
+ redraw
+
+ " Get target character {{{
+ call s:Prompt('Target key')
+
+ let char = s:GetChar()
+ " }}}
+ finally
+ " Restore original lines
+ call s:SetLines(lines_items, 'orig')
+
+ " Un-highlight targets {{{
+ if exists('target_hl_id')
+ call matchdelete(target_hl_id)
+ endif
+ " }}}
+
+ redraw
+ endtry
+
+ " Check if we have an input char {{{
+ if empty(char)
+ throw 'Cancelled'
+ endif
+ " }}}
+ " Check if the input char is valid {{{
+ if ! has_key(a:groups, char)
+ throw 'Invalid target'
+ endif
+ " }}}
+
+ let target = a:groups[char]
+
+ if type(target) == 3
+ " Return target coordinates
+ return target
+ else
+ " Prompt for new target character
+ return s:PromptUser(target)
+ endif
+ endfunction "}}}
+ function! s:EasyMotion(regexp, direction, visualmode, mode) " {{{
+ let orig_pos = [line('.'), col('.')]
+ let targets = []
+
+ try
+ " Reset properties {{{
+ call s:VarReset('&scrolloff', 0)
+ call s:VarReset('&modified', 0)
+ call s:VarReset('&modifiable', 1)
+ call s:VarReset('&readonly', 0)
+ call s:VarReset('&spell', 0)
+ call s:VarReset('&virtualedit', '')
+ " }}}
+ " Find motion targets {{{
+ let search_direction = (a:direction == 1 ? 'b' : '')
+ let search_stopline = line(a:direction == 1 ? 'w0' : 'w$')
+
+ while 1
+ let pos = searchpos(a:regexp, search_direction, search_stopline)
+
+ " 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)
+ if targets_len == 0
+ throw 'No matches'
+ endif
+ " }}}
+
+ let GroupingFn = function('s:GroupingAlgorithm' . s:grouping_algorithms[g:EasyMotion_grouping])
+ let groups = GroupingFn(targets, split(g:EasyMotion_keys, '\zs'))
+
+ " Shade inactive source {{{
+ if g:EasyMotion_do_shade
+ let shade_hl_pos = '\%' . orig_pos[0] . 'l\%'. orig_pos[1] .'c'
+
+ 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 shade_hl_id = matchadd(g:EasyMotion_hl_group_shade, shade_hl_re, 0)
+ endif
+ " }}}
+
+ " Prompt user for target group/character
+ let coords = s:PromptUser(groups)
+
+ " Update selection {{{
+ if ! empty(a:visualmode)
+ keepjumps call cursor(orig_pos[0], orig_pos[1])
+
+ exec 'normal! ' . a:visualmode
+ endif
+ " }}}
+ " Handle operator-pending mode {{{
+ if a:mode == 'no'
+ " This mode requires that we eat one more
+ " character to the right if we're using
+ " a forward motion
+ if a:direction != 1
+ let coords[1] += 1
+ endif
+ endif
+ " }}}
+
+ " Update cursor position
+ call cursor(orig_pos[0], orig_pos[1])
+ mark '
+ call cursor(coords[0], coords[1])
+
+ call s:Message('Jumping to [' . coords[0] . ', ' . coords[1] . ']')
+ catch
+ redraw
+
+ " Show exception message
+ call s:Message(v:exception)
+
+ " Restore original cursor position/selection {{{
+ if ! empty(a:visualmode)
+ silent exec 'normal! gv'
+ else
+ keepjumps call cursor(orig_pos[0], orig_pos[1])
+ endif
+ " }}}
+ finally
+ " Restore properties {{{
+ call s:VarReset('&scrolloff')
+ call s:VarReset('&modified')
+ call s:VarReset('&modifiable')
+ call s:VarReset('&readonly')
+ call s:VarReset('&spell')
+ call s:VarReset('&virtualedit')
+ " }}}
+ " Remove shading {{{
+ if g:EasyMotion_do_shade && exists('shade_hl_id')
+ call matchdelete(shade_hl_id)
+ endif
+ " }}}
+ endtry
+ endfunction " }}}
+" }}}
+
+" vim: fdm=marker:noet:ts=4:sw=4:sts=4
View
62 autoload/EasyMotion/Init.vim
@@ -0,0 +1,62 @@
+" EasyMotion - Vim motions on speed!
+"
+" Author: Kim Silkebækken <kim.silkebaekken+vim@gmail.com>
+" Source repository: https://github.com/Lokaltog/vim-easymotion
+
+" Default configuration functions {{{
+ function! EasyMotion#Init#InitOptions(options) " {{{
+ for [key, value] in items(a:options)
+ if ! exists('g:EasyMotion_' . key)
+ exec 'let g:EasyMotion_' . key . ' = ' . string(value)
+ endif
+ endfor
+ endfunction " }}}
+ function! EasyMotion#Init#InitHL(group, colors) " {{{
+ let group_default = a:group . 'Default'
+
+ " Prepare highlighting variables
+ let guihl = printf('guibg=%s guifg=%s gui=%s', a:colors.gui[0], a:colors.gui[1], a:colors.gui[2])
+ if !exists('g:CSApprox_loaded')
+ let ctermhl = &t_Co == 256
+ \ ? printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm256[0], a:colors.cterm256[1], a:colors.cterm256[2])
+ \ : printf('ctermbg=%s ctermfg=%s cterm=%s', a:colors.cterm[0], a:colors.cterm[1], a:colors.cterm[2])
+ else
+ let ctermhl = ''
+ endif
+
+ " Create default highlighting group
+ execute printf('hi default %s %s %s', group_default, guihl, ctermhl)
+
+ " Check if the hl group exists
+ if hlexists(a:group)
+ redir => hlstatus | exec 'silent hi ' . a:group | redir END
+
+ " Return if the group isn't cleared
+ if hlstatus !~ 'cleared'
+ return
+ endif
+ endif
+
+ " No colors are defined for this group, link to defaults
+ execute printf('hi default link %s %s', a:group, group_default)
+ endfunction " }}}
+ function! EasyMotion#Init#InitMappings(motions) "{{{
+ for motion in keys(a:motions)
+ call EasyMotion#Init#InitOptions({ 'mapping_' . motion : g:EasyMotion_leader_key . motion })
+ endfor
+
+ if g:EasyMotion_do_mapping
+ for [motion, fn] in items(a:motions)
+ if empty(g:EasyMotion_mapping_{motion})
+ continue
+ endif
+
+ silent exec 'nnoremap <silent> ' . g:EasyMotion_mapping_{motion} . ' :call EasyMotion#EasyMotion#' . fn.name . '(0, ' . fn.dir . ')<CR>'
+ silent exec 'onoremap <silent> ' . g:EasyMotion_mapping_{motion} . ' :call EasyMotion#EasyMotion#' . fn.name . '(0, ' . fn.dir . ')<CR>'
+ silent exec 'vnoremap <silent> ' . g:EasyMotion_mapping_{motion} . ' :<C-U>call EasyMotion#EasyMotion#' . fn.name . '(1, ' . fn.dir . ')<CR>'
+ endfor
+ endif
+ endfunction "}}}
+" }}}
+
+" vim: fdm=marker:noet:ts=4:sw=4:sts=4
View
12 plugin/EasyMotion.vim
@@ -12,7 +12,7 @@
" }}}
" Default configuration {{{
" Default options {{{
- call EasyMotion#InitOptions({
+ call EasyMotion#Init#InitOptions({
\ 'leader_key' : '<Leader><Leader>'
\ , 'keys' : 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
\ , 'do_shade' : 1
@@ -36,20 +36,20 @@
\ , 'cterm' : ['NONE', 'grey' , 'NONE']
\ }
- call EasyMotion#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
- call EasyMotion#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
+ call EasyMotion#Init#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
+ call EasyMotion#Init#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
" Reset highlighting after loading a new color scheme {{{
augroup EasyMotionInitHL
autocmd!
- autocmd ColorScheme * call EasyMotion#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
- autocmd ColorScheme * call EasyMotion#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
+ autocmd ColorScheme * call EasyMotion#Init#InitHL(g:EasyMotion_hl_group_target, s:target_hl_defaults)
+ autocmd ColorScheme * call EasyMotion#Init#InitHL(g:EasyMotion_hl_group_shade, s:shade_hl_defaults)
augroup end
" }}}
" }}}
" Default key mapping {{{
- call EasyMotion#InitMappings({
+ call EasyMotion#Init#InitMappings({
\ 'f' : { 'name': 'F' , 'dir': 0 }
\ , 'F' : { 'name': 'F' , 'dir': 1 }
\ , 't' : { 'name': 'T' , 'dir': 0 }

0 comments on commit 16e5efa

Please sign in to comment.