Skip to content

Commit

Permalink
Add support for defining cycles for use in a specific filetype, impro…
Browse files Browse the repository at this point in the history
…ve documentation.
  • Loading branch information
zef committed Mar 10, 2012
1 parent cc394e6 commit 818a886
Show file tree
Hide file tree
Showing 2 changed files with 88 additions and 36 deletions.
31 changes: 25 additions & 6 deletions doc/cycle.txt
Original file line number Diff line number Diff line change
@@ -1,17 +1,36 @@
*cycle.txt* Quickly toggle between related words.

ABOUT *cycle*
ABOUT *cycle*

Cycle.vim allows you to toggle between pairs or lists of related words. The
default mappings are the same as those with which you can increment and decrement
a number under the cursor — <C-A> and <C-X>, respectively.

default mappings are the same as those with which you can increment and
decrement a number under the cursor — <C-A> and <C-X>, respectively.

CUSTOMIZATION

You can add your own word groups: >
call AddCycleGroup(['one', 'two', 'three'])
You can add your own word groups:
>
call AddCycleGroup(['one', 'two', 'three'])
<
To deal with conflicts, Cycle.vim also supports adding groups that are specific
to a certain filetype:
>
call AddCycleGroup('ruby', ['class', 'module'])
call AddCycleGroup('python', ['else', 'elif'])
<
When multiple groups define the same word, groups belonging to specific
filetypes will be used instead of global groups. This is useful in the cases
above, since in HTML we would want 'class' to cycle with 'id' and Python uses
'elif' while some other languages use 'elsif'.

Providing a list of filetypes is also supported:
>
call AddCycleGroup(['ruby', 'eruby', 'perl'], ['else', 'elsif'])
<
However, if there are no conflicting cases it is preferable to define all
cycle groups in the global namespace, using filetype-specific groups only in
case of conflict. Instead of specifying multiple languages we define that
group in the global space and override it only for python.

vim:tw=78:ts=8:ft=help:norl:

93 changes: 63 additions & 30 deletions plugin/cycle.vim
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@
" endif
" let g:loaded_cycle = 1

let s:options = [
let s:options = {}

let s:options['global'] = [
\ ['==', '!='],
\ ['+=', '-='],
\ ['&&', '||'],
Expand All @@ -16,8 +18,18 @@ let s:options = [
\ ['first', 'last'],
\]

" CSS/Sass/JavaScript/HTML
let s:options = s:options + [
" ruby/eruby
let s:options['global'] = s:options['global'] + [
\ ['else', 'elsif'],
\ ['include', 'require'],
\ ['Time', 'Date'],
\ ['present', 'blank'],
\ ['while', 'until'],
\]

" css/sass/javascript/html
let s:options['global'] = s:options['global'] + [
\ ['class', 'id'],
\ ['px', '%', 'em'],
\ ['left', 'right'],
\ ['top', 'bottom'],
Expand All @@ -27,36 +39,70 @@ let s:options = s:options + [
\ ['div', 'p', 'span'],
\ ['h1', 'h2', 'h3'],
\ ['png', 'jpg', 'gif'],
\ ['linear', 'radial'],
\ ['show', 'hide'],
\ ['mouseover', 'mouseout'],
\ ['mouseenter', 'mouseleave'],
\]

" Takes one or two arguments:
"
" group
" - or -
" filetype(s), group
function! AddCycleGroup(filetypes_or_group, ...)
if a:0
let group = a:1
" type(['list']) == 3
" type('string') == 1
if type(a:filetypes_or_group) == 1
let filetypes = [a:filetypes_or_group]
else
let filetypes = a:filetypes_or_group
end
else
let group = a:filetypes_or_group
let filetypes = ['global']
endif

function! AddCycleGroup(group)
call add(s:options, a:group)
endfunction
for type in filetypes
if !has_key(s:options, type)
let s:options[type] = []
endif

call add(s:options[type], group)
endfor
endfunction

function! s:Cycle(word, direction)
let groups = filter(copy(s:options), "index(v:val, a:word) >= 0")
let matches = []
let filetype = &ft

if has_key(s:options, filetype)
let matches = filter(copy(s:options[filetype]), "index(v:val, a:word) >= 0")
endif

" echo(string(groups))
if empty(matches)
let matches = filter(copy(s:options['global']), "index(v:val, a:word) >= 0")
endif

if empty(groups)
if empty(matches)
" if exists("g:loaded_speeddating")
" echo 'speed dating!'
" else
" echo 'no speed dating'
" endif

if a:direction == 1
exe "norm! \<C-A>"
else
exe "norm! \<C-X>"
endif
else
" Currently doesn't account for more than one group
let group = groups[0]
" Currently doesn't account for existence of more than one group
let group = matches[0]
let index = index(group, a:word) + a:direction

let max_index = (len(group) - 1)

if index > max_index
Expand All @@ -68,28 +114,15 @@ function! s:Cycle(word, direction)

endfunction

" Need to implement system to include things like this based on filetype
" Ruby (or Rails)
call AddCycleGroup(['else', 'elsif'])
call AddCycleGroup(['include', 'require'])
call AddCycleGroup(['class', 'module'])
call AddCycleGroup(['Time', 'Date'])
call AddCycleGroup(['present', 'blank'])

" js/jQuery
call AddCycleGroup(['show', 'hide'])
call AddCycleGroup(['mouseover', 'mouseout'])
call AddCycleGroup(['mouseenter', 'mouseleave'])
" language specific overrides:
call AddCycleGroup('ruby', ['class', 'module'])
call AddCycleGroup('python', ['else', 'elif'])

nnoremap <silent> <Plug>CycleNext :<C-U>call <SID>Cycle(expand("<cword>"), 1)<CR>
nnoremap <silent> <Plug>CycleNext :<C-U>call <SID>Cycle(expand("<cword>"), 1)<CR>
nnoremap <silent> <Plug>CyclePrevious :<C-U>call <SID>Cycle(expand("<cword>"), -1)<CR>
" vnoremap <silent> <Plug>CycleNext :<C-U>call <SID>incrementvisual(v:count1)<CR>
" vnoremap <silent> <Plug>CyclePrevious :<C-U>call <SID>incrementvisual(-v:count1)<CR>
if !exists("g:cycle_no_mappings") || !g:cycle_no_mappings
nmap <C-A> <Plug>CycleNext
nmap <C-X> <Plug>CyclePrevious
" xmap <C-A> <Plug>CycleNext
" xmap <C-X> <Plug>CyclePrevious
endif

0 comments on commit 818a886

Please sign in to comment.