Skip to content

Instantly share code, notes, and snippets.

@AndrewRadev
Created July 1, 2012 16:10
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save AndrewRadev/3028833 to your computer and use it in GitHub Desktop.
Save AndrewRadev/3028833 to your computer and use it in GitHub Desktop.
My ftplugin/eruby.vim file
" This file is supposed to be saved as "~/.vim/ftplugin/eruby.vim". If desired, parts of it can be
" picked and saved into separate files in the same directory as long as they start with "eruby_",
" for example "~/.vim/ftplugin/eruby_surroundings.vim".
" Surround mappings. The character defines the mapping. Most of these are meant for use in visual
" mode to add a wrapping, although they can probably be used otherwise as well.
"
" These ones let you wrap a piece of text on a line with erb <% %> markers. The last one is
" particularly useful for adding translations in the place of hardcoded strings.
"
let b:surround_{char2nr('-')} = "<% \r %>"
let b:surround_{char2nr('=')} = "<%= \r %>"
let b:surround_{char2nr('t')} = "<%=t '\r' %>"
" These ones operate on larger blocks and add if-clauses, loops and blocks. Most of them I don't
" use very often (how often do you write a while loop in erb?). The ones that have \1 and \2
" markers in them use an "advanced" customization option in surround.vim that makes Vim ask for
" the contents of the "\1" and "\2" placeholders (:help surround-customizing)
"
" Example:
" Given the following HTML:
"
" <div class="foo">bar</div>
"
" After marking the line in visual mode and typing se, you get two input prompts asking for:
"
" collection: things
" item: thingie
"
" Which results into:
"
" <% things.each do |thingie| %>
" <div class="foo">bar</div>
" <% end %>
"
let b:surround_{char2nr('i')} = "<% if \1<% if: \1 %> \r <% end %>"
let b:surround_{char2nr('u')} = "<% unless \1<% unless: \1 %> \r <% end %>"
let b:surround_{char2nr('w')} = "<% while \1<% while: \1 do %> \r <% end %>"
let b:surround_{char2nr('e')} = "<% \1<% collection: \1.each do |\2item: \2| %> \r <% end %>"
let b:surround_{char2nr('d')} = "<% do %> \r <% end %>"
" This one allows executing cs": to change strings into symbols. Should actually be in
" ftplugin/ruby.vim.
"
" "foo" -> :foo
" 'bar' -> :bar
"
" The reverse doesn't seem to be possible, since the ":" is not a surrounding anymore.
let b:surround_{char2nr(':')} = ":\r"
" This one lets you mark something in a string and turn it into an interpolation with s# in visual
" mode. Also should be in ftplugin/ruby.vim.
"
" "Hi, my name is name" -> "Hi, my name is #{name}"
"
let b:surround_{char2nr('#')} = "#{\r}"
" This one is hard to explain and fairly useless for erb files, so ignore.
RunCommand !erb % <args>
" The "=" text object is one I use to deal with <% %> surroundings. Given the following eruby
" code:
"
" <h2><%= some.heading %></h2>
"
" Typing ci= while within the <% %> tags results into this:
"
" <h2><%= %></h2>
"
" With the cursor in insert mode within the tags. Typing da= would result into just this:
"
" <h2></h2>
"
" And so on. This is a standard text object, so it can be used with the usual v, d, c, y actions
" (:help text-objects). Note that it's not a complete text object, because it doesn't handle
" counts or multiline erb tags.
"
onoremap <buffer> a= :<c-u>call <SID>ErbTextObject('a')<cr>
xnoremap <buffer> a= :<c-u>call <SID>ErbTextObject('a')<cr>
onoremap <buffer> i= :<c-u>call <SID>ErbTextObject('i')<cr>
xnoremap <buffer> i= :<c-u>call <SID>ErbTextObject('i')<cr>
function! s:ErbTextObject(mode)
if search('<%.*\%#.*%>', 'n') <= 0
return
endif
if a:mode == 'i'
let [start_flags, end_flags] = ['be', '']
else " a:mode == 'a'
let [start_flags, end_flags] = ['b', 'e']
endif
call search('<%=\?\s*.', start_flags, line('.'))
let start = col('.') - 1
call search('.\s*-\?%>', end_flags, line('.'))
let end = col('.') - 1
let interval = end - start
if start == 0
exe 'normal! 0v'.interval.'l'
else
exe 'normal! 0'.start.'lv'.interval.'l'
endif
endfunction
" This can be used to toggle between <%= and <% tags. The reason it uses - as a mapping is because
" I use that key as a general-purpose "toggle switch" for various little things in different
" filetypes.
"
" <%= foo %> <-> <% foo %>
"
nnoremap <buffer> - :call <SID>ToggleOutput()<cr>
function! s:ToggleOutput()
let saved_cursor = getpos('.')
let line = getline('.')
if line =~ '<%='
s/<%=/<%/
elseif line =~ '<%[^=]'
s/<%/<%=/
endif
call setpos('.', saved_cursor)
endfunction
" This is used later on in ftplugin/ruby.vim
let b:erb_loaded = 1
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment