From aa8d1ef8a6cf58b6f98621c375d95331eed10a29 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Thu, 9 Jan 2014 10:30:51 +0900 Subject: [PATCH 1/7] Fix allows_repeat variable for SelectLines is global --- autoload/EasyMotion.vim | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/autoload/EasyMotion.vim b/autoload/EasyMotion.vim index 1ef7048..8d589e1 100644 --- a/autoload/EasyMotion.vim +++ b/autoload/EasyMotion.vim @@ -906,8 +906,11 @@ function! s:PromptUser(groups, allows_repeat, fixed_column) "{{{ endif " }}} " -- Repeat EasyMotion ------------------- {{{ - if a:allows_repeat && char == '.' - return g:EasyMotion_old_target + if a:allows_repeat && + \ char == '.' && + \ exists('s:old_target_coord') + " For SelectLines + return s:old_target_coord endif "}}} " -- Check if the input char is valid ---- {{{ if ! has_key(a:groups, char) @@ -1078,7 +1081,7 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ " -- Prompt user for target group/character {{{ let coords = s:PromptUser(groups, allows_repeat, fixed_column) - let g:EasyMotion_old_target = coords + let s:old_target_coord = coords "}}} " -- Update selection -------------------- {{{ From 29a46ae157f0d863a3e8c94f30e719a15f3458dd Mon Sep 17 00:00:00 2001 From: haya14busa Date: Thu, 9 Jan 2014 13:45:32 +0900 Subject: [PATCH 2/7] Modify and Add missing within line motion Mofify: use s:line_flag and search_stopline Add : Missing f,F,t,T motion within line And some refactoring about init & reset functions --- autoload/EasyMotion.vim | 153 +++++++++++++++++++++++----------------- plugin/EasyMotion.vim | 4 ++ 2 files changed, 91 insertions(+), 66 deletions(-) diff --git a/autoload/EasyMotion.vim b/autoload/EasyMotion.vim index 8d589e1..a0f963c 100644 --- a/autoload/EasyMotion.vim +++ b/autoload/EasyMotion.vim @@ -7,13 +7,43 @@ let s:save_cpo = &cpo set cpo&vim " }}} -" == Reset {{{ -function! EasyMotion#reset() - " Reset Migemo Dictionary +" == Init {{{ +function! EasyMotion#init() + " Init Migemo Dictionary let s:migemo_dicts = {} + let s:line_flag = 0 + " Anywhere regular expression: {{{ + let re = '\v' . + \ '(<.|^$)' . '|' . + \ '(.>|^$)' . '|' . + \ '(\l)\zs(\u)' . '|' . + \ '(_\zs.)' . '|' . + \ '(#\zs.)' + " 1. word + " 2. end of word + " 3. CamelCase + " 4. after '_' hoge_foo + " 5. after '#' hoge#foo + let g:EasyMotion_re_anywhere = get(g:, 'EasyMotion_re_anywhere', re) + + + " Anywhere regular expression within line: + let re = '\v' . + \ '(<.|^$)' . '|' . + \ '(.>|^$)' . '|' . + \ '(\l)\zs(\u)' . '|' . + \ '(_\zs.)' . '|' . + \ '(#\zs.)' + let g:EasyMotion_re_line_anywhere = get(g:, 'EasyMotion_re_line_anywhere', re) + "}}} + + return "" +endfunction "}}} +" == Reset {{{ +function! EasyMotion#reset() + let s:line_flag = 0 return "" endfunction "}}} - " == Motion functions {{{ " -- Find Motion ------------------------- function! EasyMotion#F(visualmode, direction) " {{{ @@ -88,23 +118,6 @@ function! EasyMotion#Search(visualmode, direction) " {{{ endfunction " }}} " -- JumpToAnywhere Motion --------------- function! EasyMotion#JumpToAnywhere(visualmode, direction) " {{{ - if !exists('g:EasyMotion_re_anywhere') - " Anywhere regular expression: {{{ - let re = '\v' . - \ '(<.|^$)' . '|' . - \ '(.>|^$)' . '|' . - \ '(\l)\zs(\u)' . '|' . - \ '(_\zs.)' . '|' . - \ '(#\zs.)' - " 1. word - " 2. end of word - " 3. CamelCase - " 4. after '_' hoge_foo - " 5. after '#' hoge#foo - "}}} - let g:EasyMotion_re_anywhere = get(g:, 'EasyMotion_re_anywhere', re) - endif - " call s:EasyMotion( g:EasyMotion_re_anywhere, a:direction, a:visualmode ? visualmode() : '', '') endfunction " }}} " -- Line Motion ------------------------- @@ -119,53 +132,52 @@ function! EasyMotion#SL(visualmode, direction) " {{{ if a:visualmode call s:before_visual() endif - let re = '\%' . line('.') . 'l' . re + let s:line_flag = 1 + call s:EasyMotion(re, a:direction, a:visualmode ? visualmode() : '', mode(1)) +endfunction " }}} +function! EasyMotion#TL(visualmode, direction) " {{{ + let char = s:GetSearchChar(a:visualmode) + + if empty(char) + return + endif + + let re = s:findMotion(char) + + if a:direction == 1 + " backward + let re = re . '\zs.' + else + " forward + let re = '.\ze' . re + endif + + if a:visualmode + call s:before_visual() + endif + let s:line_flag = 1 call s:EasyMotion(re, a:direction, a:visualmode ? visualmode() : '', mode(1)) endfunction " }}} function! EasyMotion#WBL(visualmode, direction) " {{{ - if a:visualmode - call s:before_visual() - endif - call s:EasyMotion('\%'.line('.').'l'.'\(\<.\|^$\)', a:direction, a:visualmode ? visualmode() : '', '') + let s:line_flag = 1 + " call s:EasyMotion('\%'.line('.').'l'.'\(\<.\|^$\)', a:direction, a:visualmode ? visualmode() : '', '') + call s:EasyMotion('\(\<.\|^$\)', a:direction, a:visualmode ? visualmode() : '', '') endfunction " }}} function! EasyMotion#EL(visualmode, direction) " {{{ if a:visualmode call s:before_visual() endif - call s:EasyMotion('\%'.line('.').'l'.'\(.\>\|^$\)', a:direction, a:visualmode ? visualmode() : '', mode(1)) + let s:line_flag = 1 + call s:EasyMotion('\(.\>\|^$\)', a:direction, a:visualmode ? visualmode() : '', mode(1)) endfunction " }}} function! EasyMotion#LineAnywhere(visualmode, direction) " {{{ - - if ! exists('s:re_line_flag') "{{{ - " Load once! - " Anywhere regular expression: - let re = '\v' . - \ '(<.|^$)' . '|' . - \ '(.>|^$)' . '|' . - \ '(\l)\zs(\u)' . '|' . - \ '(_\zs.)' . '|' . - \ '(#\zs.)' - let re_lineanywhere = get(g:, 'EasyMotion_re_line_anywhere', re) - - if match(re_lineanywhere, '\\v') < 0 - let s:re_line_flag = '\%' - let bracket_before = '\(' - let bracket_after = '\)' - else - let re_lineanywhere = substitute(re_lineanywhere,'\\v','','') - let s:re_line_flag = '\v%' - let bracket_before = '(' - let bracket_after = ')' - endif - let s:re_line_after = 'l' . bracket_before . re_lineanywhere . bracket_after - endif "}}} - if a:visualmode call s:before_visual() endif - let re = s:re_line_flag . line('.') . s:re_line_after + let s:line_flag = 1 + let re = g:EasyMotion_re_line_anywhere call s:EasyMotion(re, a:direction, a:visualmode ? visualmode() : '', '') endfunction " }}} " -- Special Motion ---------------------- @@ -953,6 +965,10 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ let search_direction = (a:direction >= 1 ? 'b' : '') let search_stopline = line(a:direction >= 1 ? 'w0' : 'w$') let search_at_cursor = fixed_column ? 'c' : '' + + if s:line_flag == 1 + let search_stopline = line('.') + endif "}}} " Handle visual mode {{{ @@ -1008,8 +1024,13 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ keepjumps call cursor(orig_pos[0], orig_pos[1]) endif let targets2 = [] + if s:line_flag == 0 + let search_stopline = line('w$') + else + let search_stopline = line('.') + endif while 1 - let pos = searchpos(a:regexp, '', line('w$')) + let pos = searchpos(a:regexp, '', search_stopline) " Reached end of search range if pos == [0, 0] break @@ -1024,31 +1045,30 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ call add(targets2, pos) endwhile " Merge match target dict"{{{ - let t1 = 0 - let t2 = 0 + let t1 = 0 " backward + let t2 = 0 " forward let targets3 = [] while t1 < len(targets) || t2 < len(targets2) - if t1 < len(targets) - call add(targets3, targets[t1]) - let t1 += 1 - endif + " Forward -> Backward -> F -> B -> ... if t2 < len(targets2) call add(targets3, targets2[t2]) let t2 += 1 endif + if t1 < len(targets) + call add(targets3, targets[t1]) + let t1 += 1 + endif endwhile let targets = targets3 "}}} endif "}}} - " Handle no match"{{{ 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')) @@ -1130,7 +1150,8 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ let s:EasyMotion_cancelled = 1 finally " -- Restore properties ------------------ {{{ - call s:RestoreValue() + call s:RestoreValue() + call EasyMotion#reset() " }}} " -- Remove shading ---------------------- {{{ if g:EasyMotion_do_shade && exists('shade_hl_id') && (!fixed_column) @@ -1143,9 +1164,9 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ endtry endfunction " }}} "}}} - -" == Call Reset {{{ -call EasyMotion#reset() +"}}} +" == Call init {{{ +call EasyMotion#init() "}}} " == Restore 'cpoptions' {{{ let &cpo = s:save_cpo diff --git a/plugin/EasyMotion.vim b/plugin/EasyMotion.vim index b316e72..c370103 100644 --- a/plugin/EasyMotion.vim +++ b/plugin/EasyMotion.vim @@ -130,6 +130,10 @@ set cpo&vim \ , 'lineanywhere' : { 'name': 'LineAnywhere' , 'dir': 2 } \ \ , 'sl' : { 'name': 'SL' , 'dir': 2 } + \ , 'fl' : { 'name': 'SL' , 'dir': 0 } + \ , 'Fl' : { 'name': 'SL' , 'dir': 1 } + \ , 'tl' : { 'name': 'TL' , 'dir': 0 } + \ , 'Tl' : { 'name': 'TL' , 'dir': 1 } \ , 'wl' : { 'name': 'WBL' , 'dir': 0 } \ , 'bl' : { 'name': 'WBL' , 'dir': 1 } \ , 'bd-wl' : { 'name': 'WBL' , 'dir': 2 } From b03263760bbf89a3118d7619c9fbf40c64b24250 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Thu, 9 Jan 2014 13:52:07 +0900 Subject: [PATCH 3/7] Implement repeat last motion! Description: Repeat last motion(use same regexp) Mapping: (easymotion-repeat) FIXME: dir arguments is redundant --- autoload/EasyMotion.vim | 25 +++++++++++++++++++++++++ plugin/EasyMotion.vim | 2 ++ 2 files changed, 27 insertions(+) diff --git a/autoload/EasyMotion.vim b/autoload/EasyMotion.vim index a0f963c..ea31be4 100644 --- a/autoload/EasyMotion.vim +++ b/autoload/EasyMotion.vim @@ -302,6 +302,19 @@ function! EasyMotion#UserMapping(re, mapping, direction) " {{{ silent exec "onoremap ".a:mapping." :call EasyMotion#User('".a:re."', 0, ".a:direction.")" silent exec "vnoremap ".a:mapping." :call EasyMotion#User('".a:re."', 0,".a:direction.")" endfunction " }}} +" -- Repeat Motion ----------------------- +function! EasyMotion#Repeat(visualmode, direction) " {{{ + " Repeat previous motion with previous targets + if ! exists('s:old') + call s:Message("Previous targets doesn't exist") + return + endif + let re = s:old.regexp + let direction = s:old.direction + let s:line_flag = s:old.line_flag + + call s:EasyMotion(re, direction, a:visualmode ? visualmode() : '', mode(1)) +endfunction " }}} " }}} " == Helper functions {{{ @@ -955,6 +968,18 @@ function! s:EasyMotion(regexp, direction, visualmode, mode, ...) " {{{ let orig_pos = [line('.'), col('.')] let targets = [] + " Store Regular Expression + let s:old = { + \ 'regexp': a:regexp, + \ 'direction': a:direction, + \ } + if s:line_flag == 1 + let s:old['line_flag'] = 1 + else + let s:old['line_flag'] = 0 + endif + + try " -- Reset properties -------------------- {{{ " Save original value and set new value diff --git a/plugin/EasyMotion.vim b/plugin/EasyMotion.vim index c370103..9d70790 100644 --- a/plugin/EasyMotion.vim +++ b/plugin/EasyMotion.vim @@ -140,6 +140,8 @@ set cpo&vim \ , 'el' : { 'name': 'EL' , 'dir': 0 } \ , 'gel' : { 'name': 'EL' , 'dir': 1 } \ , 'bd-el' : { 'name': 'EL' , 'dir': 2 } + \ + \ , 'repeat' : { 'name': 'Repeat' , 'dir': 0 } \ }, 0) " Prepare but don't map by default. " }}} " }}} From 0f4a6438b1c944b12efec685a1dfe326591788c7 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Thu, 9 Jan 2014 13:52:48 +0900 Subject: [PATCH 4/7] Implement jump first match with Enter option Variable: g:EasyMotion_enter_jump_first Default: 0 (Off) Enable: let g:EasyMotion_enter_jump_first = 1 --- autoload/EasyMotion.vim | 3 +++ plugin/EasyMotion.vim | 1 + 2 files changed, 4 insertions(+) diff --git a/autoload/EasyMotion.vim b/autoload/EasyMotion.vim index ea31be4..82bd7b2 100644 --- a/autoload/EasyMotion.vim +++ b/autoload/EasyMotion.vim @@ -890,6 +890,9 @@ function! s:PromptUser(groups, allows_repeat, fixed_column) "{{{ if g:EasyMotion_use_upper == 1 && match(g:EasyMotion_keys, '\l') == -1 let char = toupper(char) endif + if char ==# ' ' && g:EasyMotion_enter_jump_first == 1 + let char = g:EasyMotion_keys[0] + endif " }}} finally " Restore original lines diff --git a/plugin/EasyMotion.vim b/plugin/EasyMotion.vim index 9d70790..e1933f0 100644 --- a/plugin/EasyMotion.vim +++ b/plugin/EasyMotion.vim @@ -28,6 +28,7 @@ set cpo&vim \ , 'skipfoldedline' : 1 \ , 'use_migemo' : 0 \ , 'use_upper' : 0 + \ , 'enter_jump_first' : 0 \ \ , 'hl_group_target' : 'EasyMotionTarget' \ , 'hl2_first_group_target' : 'EasyMotionTarget2First' From 65d4d41d66bd6eefee8a49831fefff0054685ab1 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Fri, 10 Jan 2014 16:47:35 +0900 Subject: [PATCH 5/7] Update doc Add description for missing line motion --- doc/easymotion.txt | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/doc/easymotion.txt b/doc/easymotion.txt index 9010482..16fe61b 100644 --- a/doc/easymotion.txt +++ b/doc/easymotion.txt @@ -153,6 +153,10 @@ EasyMotion table *easymotion-plug-table* Within Line Motion | ----------------------------------|--------------------------------- (easymotion-sl) | See |(easymotion-sl)| + (easymotion-fl) | See |(easymotion-fl)| + (easymotion-Fl) | See |(easymotion-Fl)| + (easymotion-tl) | See |(easymotion-tl)| + (easymotion-Tl) | See |(easymotion-Tl)| (easymotion-wl) | See |(easymotion-wl)| (easymotion-bl) | See |(easymotion-bl)| (easymotion-bd-wl) | See |(easymotion-bd-wl)| @@ -221,6 +225,22 @@ Within line motion *easymotion-within-line* This function is same as |(easymoion-s)|, except range is within current cursor line. +(easymotion-fl) *(easymotion-fl)* + This function is same as |(easymoion-f)|, except range + is within current cursor line. + +(easymotion-Fl) *(easymotion-Fl)* + This function is same as |(easymoion-F)|, except range + is within current cursor line. + +(easymotion-tl) *(easymotion-tl)* + This function is same as |(easymoion-t)|, except range + is within current cursor line. + +(easymotion-Tl) *(easymotion-Tl)* + This function is same as |(easymoion-T)|, except range + is within current cursor line. + (easymotion-wl) *(easymotion-wl)* This function is same as |(easymoion-w)|, except range is within current cursor line. From daf0362674da444b1870599f254f729514b1c291 Mon Sep 17 00:00:00 2001 From: haya14busa Date: Fri, 10 Jan 2014 17:03:08 +0900 Subject: [PATCH 6/7] Update doc Add description for repeat motion Some Cosmetic changes --- doc/easymotion.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/doc/easymotion.txt b/doc/easymotion.txt index 16fe61b..c6e9ac1 100644 --- a/doc/easymotion.txt +++ b/doc/easymotion.txt @@ -150,6 +150,8 @@ EasyMotion table *easymotion-plug-table* (easymotion-bd-jk) | See |(easymotion-bd-jk)| (easymotion-bd-n) | See |(easymotion-bd-n)| (easymotion-jumptoanywhere) | See |(easymotion-jumptoanywhere)| + (easymotion-repeat) | See |(easymotion-repeat)| + | Within Line Motion | ----------------------------------|--------------------------------- (easymotion-sl) | See |(easymotion-sl)| @@ -178,6 +180,8 @@ EasyMotion table *easymotion-plug-table* These mappings are not mapped by Default. +Bidirection ~ + (easymotion-bd-w) *(easymotion-bd-w)* Beginning of word forward and backward. See |w| & |b|. Note: bd is short for bidirectional @@ -197,6 +201,8 @@ These mappings are not mapped by Default. (easymotion-bd-n) *(easymotion-bd-n)* Jump to latest "/" or "?" forward. See |n| & |N|. +Jump To Anywhere ~ + (easymotion-jumptoanywhere) *(easymotion-jumptoanywhere)* JumpToAnywhere motion! Default: Beginning and End of word, Camelcase, after '_', @@ -219,7 +225,17 @@ These mappings are not mapped by Default. \ '(<.|.$)' . '|' . \ '(\l)\zs(\u)' . '|' . < -Within line motion *easymotion-within-line* +Repeat ~ + +(easymotion-repeat) *(easymotion-repeat)* + Repeat last motion! + + Repeat last motion type including input target character. + Nothing will happen when previous motion doesn't exist. + + +Within line motion ~ + *easymotion-within-line* (easymotion-sl) *(easymotion-sl)* This function is same as |(easymoion-s)|, except range From 50b858cd3d3a9c60e464305458fdcced2e4a94ec Mon Sep 17 00:00:00 2001 From: haya14busa Date: Fri, 10 Jan 2014 17:13:52 +0900 Subject: [PATCH 7/7] Update doc Add description for Easymotion_enter_jump_first --- doc/easymotion.txt | 32 ++++++++++++++++++++++++-------- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/doc/easymotion.txt b/doc/easymotion.txt index c6e9ac1..9af952f 100644 --- a/doc/easymotion.txt +++ b/doc/easymotion.txt @@ -1,4 +1,4 @@ -*easymotion.txt* Version 2.0 Last change:23 Dec 2013. +*easymotion.txt* Version 2.0 Last change:10 Jan 2014. ______ __ ___ __ _ @@ -29,13 +29,14 @@ CONTENTS *easymotion-contents* 4.7 EasyMotion_smartsign ........... |EasyMotion_smartsign| 4.8 EasyMotion_use_migemo .......... |EasyMotion_use_migemo| 4.9 EasyMotion_use_upper .......... |EasyMotion_use_upper| - 4.10 Custom highlighting ............ |easymotion-custom-hl| - 4.11 Custom mappings ................ |easymotion-custom-mappings| - 4.11.1 Leader key ............... |easymotion-leader-key| - 4.11.2 Custom keys .............. |easymotion-custom-keys| - 4.12 Easymotion special functions ... |easymotion-special-mappings| - 4.12.1 Select Line .............. |easymotion-select-line| - 4.12.2 Select Phrase ............ |easymotion-select-phrase| + 4.10 Custom highlighting ........... |easymotion-custom-hl| + 4.11 Custom mappings ............... |easymotion-custom-mappings| + 4.11.1 Leader key .............. |easymotion-leader-key| + 4.11.2 Custom keys ............. |easymotion-custom-keys| + 4.12 Easymotion special functions .. |easymotion-special-mappings| + 4.12.1 Select Line ............. |easymotion-select-line| + 4.12.2 Select Phrase ........... |easymotion-select-phrase| + 4.13 EasyMotion_enter_jump_first ... |EasyMotion_enter_jump_first| 5. License ............................ |easymotion-license| 6. Known bugs ......................... |easymotion-known-bugs| 7. Contributing ....................... |easymotion-contributing| @@ -713,6 +714,21 @@ or map it by yourself(Recommend) Note: special phrase function when d & y is a little bit different. So you should map them individually, don't define omap only. +------------------------------------------------------------------------------ +4.13 Jump to first match by Enter *EasyMotion_enter_jump_first* + *g:EasyMotion_enter_jump_first* + +Type Enter key and jump to first match (first letter of |g:EasyMotion_keys| ). + +Set this option to 1 if you want to enable this feature. + +Example: +> + let g:EasyMotion_enter_jump_first = 1 +< +Default: 0 + + ============================================================================== 5. License *easymotion-license*