From: Ben Beltran Date: Wed, 5 Jun 2013 15:50:57 +0000 (-0500) Subject: Aand that's all the plugins. X-Git-Url: https://git.r.bdr.sh/rbdr/dotfiles/commitdiff_plain/fe337504f2fb3ded76326b1e3d4d02787a27d853 Aand that's all the plugins. --- diff --git a/.gitmodules b/.gitmodules index b572e5b..d9ba288 100644 --- a/.gitmodules +++ b/.gitmodules @@ -43,3 +43,48 @@ [submodule "vim/bundle/vim-endwise"] path = vim/bundle/vim-endwise url = git://github.com/tpope/vim-endwise.git +[submodule "vim/bundle/vim-fugitive"] + path = vim/bundle/vim-fugitive + url = git://github.com/tpope/vim-fugitive.git +[submodule "vim/bundle/gist-vim"] + path = vim/bundle/gist-vim + url = https://github.com/mattn/gist-vim +[submodule "vim/bundle/vim-indent-object"] + path = vim/bundle/vim-indent-object + url = git://github.com/michaeljsmith/vim-indent-object.git +[submodule "vim/bundle/vim-rails"] + path = vim/bundle/vim-rails + url = git://github.com/tpope/vim-rails.git +[submodule "vim/bundle/searchfold.vim"] + path = vim/bundle/searchfold.vim + url = git://github.com/vim-scripts/searchfold.vim.git +[submodule "vim/bundle/vim-snipmate"] + path = vim/bundle/vim-snipmate + url = git://github.com/garbas/vim-snipmate.git +[submodule "vim/bundle/tlib_vim"] + path = vim/bundle/tlib_vim + url = git://github.com/tomtom/tlib_vim.git +[submodule "vim/bundle/vim-addon-mw-utils"] + path = vim/bundle/vim-addon-mw-utils + url = git://github.com/MarcWeber/vim-addon-mw-utils.git +[submodule "vim/bundle/supertab"] + path = vim/bundle/supertab + url = https://github.com/ervandew/supertab +[submodule "vim/bundle/vim-surround"] + path = vim/bundle/vim-surround + url = git://github.com/tpope/vim-surround.git +[submodule "vim/bundle/syntastic"] + path = vim/bundle/syntastic + url = git://github.com/scrooloose/syntastic.git +[submodule "vim/bundle/tagbar"] + path = vim/bundle/tagbar + url = git://github.com/majutsushi/tagbar.git +[submodule "vim/bundle/taglist"] + path = vim/bundle/taglist + url = git://github.com/vim-scripts/taglist.vim.git +[submodule "vim/bundle/vim-unimpaired"] + path = vim/bundle/vim-unimpaired + url = git://github.com/tpope/vim-unimpaired.git +[submodule "vim/bundle/vim-showmarks"] + path = vim/bundle/vim-showmarks + url = git://github.com/vimez/vim-showmarks.git diff --git a/vim/after/plugin/snipMate.vim b/vim/after/plugin/snipMate.vim deleted file mode 100644 index bdbe199..0000000 --- a/vim/after/plugin/snipMate.vim +++ /dev/null @@ -1,40 +0,0 @@ -" These are the mappings for snipMate.vim. Putting it here ensures that it -" will be mapped after other plugins such as supertab.vim. -if !exists('loaded_snips') || exists('s:did_snips_mappings') - finish -endif -let s:did_snips_mappings = 1 - -" This is put here in the 'after' directory in order for snipMate to override -" other plugin mappings (e.g., supertab). -" -" You can safely adjust these mappings to your preferences (as explained in -" :help snipMate-remap). -ino =TriggerSnippet() -snor i=TriggerSnippet() -ino =BackwardsSnippet() -snor i=BackwardsSnippet() -ino =ShowAvailableSnips() - -" The default mappings for these are annoying & sometimes break snipMate. -" You can change them back if you want, I've put them here for convenience. -snor b -snor a -snor bi -snor ' b' -snor ` b` -snor % b% -snor U bU -snor ^ b^ -snor \ b\ -snor b - -" By default load snippets in snippets_dir -if empty(snippets_dir) - finish -endif - -call GetSnippets(snippets_dir, '_') " Get global snippets - -au FileType * if &ft != 'help' | call GetSnippets(snippets_dir, &ft) | endif -" vim:noet:sw=4:ts=4:ft=vim diff --git a/vim/autoload/conque_term.vim b/vim/autoload/conque_term.vim deleted file mode 100644 index 2780c7d..0000000 --- a/vim/autoload/conque_term.vim +++ /dev/null @@ -1,1590 +0,0 @@ -" FILE: plugin/conque_term.vim {{{ -" -" AUTHOR: Nico Raffo -" MODIFIED: 2010-05-27 -" VERSION: 1.1, for Vim 7.0 -" LICENSE: -" Conque - pty interaction in Vim -" Copyright (C) 2009-2010 Nico Raffo -" -" MIT License -" -" Permission is hereby granted, free of charge, to any person obtaining a copy -" of this software and associated documentation files (the "Software"), to deal -" in the Software without restriction, including without limitation the rights -" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -" copies of the Software, and to permit persons to whom the Software is -" furnished to do so, subject to the following conditions: -" -" The above copyright notice and this permission notice shall be included in -" all copies or substantial portions of the Software. -" -" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -" THE SOFTWARE. -" }}} - - -" ********************************************************************************************************** -" **** VIM FUNCTIONS *************************************************************************************** -" ********************************************************************************************************** - -" launch conque -function! conque_term#open(...) "{{{ - let command = get(a:000, 0, '') - let hooks = get(a:000, 1, []) - - " bare minimum validation - if has('python') != 1 - echohl WarningMsg | echomsg "Conque requires the Python interface to be installed" | echohl None - return 0 - endif - if empty(command) - echohl WarningMsg | echomsg "No command found" | echohl None - return 0 - else - let l:cargs = split(command, '\s') - if !executable(l:cargs[0]) - echohl WarningMsg | echomsg "Not an executable: " . l:cargs[0] | echohl None - return 0 - endif - endif - - " set buffer window options - let g:ConqueTerm_BufName = substitute(command, ' ', '\\ ', 'g') . "\\ -\\ " . g:ConqueTerm_Idx - call conque_term#set_buffer_settings(command, hooks) - let b:ConqueTerm_Var = 'ConqueTerm_' . g:ConqueTerm_Idx - let g:ConqueTerm_Var = 'ConqueTerm_' . g:ConqueTerm_Idx - let g:ConqueTerm_Idx += 1 - - " open command - try - let l:config = '{"color":' . string(g:ConqueTerm_Color) . ',"TERM":"' . g:ConqueTerm_TERM . '"}' - execute 'python ' . b:ConqueTerm_Var . ' = Conque()' - execute "python " . b:ConqueTerm_Var . ".open('" . conque_term#python_escape(command) . "', " . l:config . ")" - catch - echohl WarningMsg | echomsg "Unable to open command: " . command | echohl None - return 0 - endtry - - " set buffer mappings and auto commands - call conque_term#set_mappings('start') - - startinsert! - return 1 -endfunction "}}} - -" set buffer options -function! conque_term#set_buffer_settings(command, pre_hooks) "{{{ - - " optional hooks to execute, e.g. 'split' - for h in a:pre_hooks - sil exe h - endfor - sil exe "edit " . g:ConqueTerm_BufName - - " buffer settings - setlocal nocompatible " conque won't work in compatible mode - setlocal nopaste " conque won't work in paste mode - setlocal buftype=nofile " this buffer is not a file, you can't save it - setlocal nonumber " hide line numbers - setlocal foldcolumn=0 " reasonable left margin - setlocal nowrap " default to no wrap (esp with MySQL) - setlocal noswapfile " don't bother creating a .swp file - setlocal updatetime=50 " trigger cursorhold event after 50ms / XXX - global - setlocal scrolloff=0 " don't use buffer lines. it makes the 'clear' command not work as expected - setlocal sidescrolloff=0 " don't use buffer lines. it makes the 'clear' command not work as expected - setlocal sidescroll=1 " don't use buffer lines. it makes the 'clear' command not work as expected - setlocal foldmethod=manual " don't fold on {{{}}} and stuff - setlocal bufhidden=hide " when buffer is no longer displayed, don't wipe it out - setfiletype conque_term " useful - sil exe "setlocal syntax=" . g:ConqueTerm_Syntax - -endfunction " }}} - -" set key mappings and auto commands -function! conque_term#set_mappings(action) "{{{ - - " set action - if a:action == 'toggle' - if exists('b:conque_on') && b:conque_on == 1 - let l:action = 'stop' - echohl WarningMsg | echomsg "Terminal is paused" | echohl None - else - let l:action = 'start' - echohl WarningMsg | echomsg "Terminal is resumed" | echohl None - endif - else - let l:action = a:action - endif - - " if mappings are being removed, add 'un' - let map_modifier = 'nore' - if l:action == 'stop' - let map_modifier = 'un' - endif - - " remove all auto commands - if l:action == 'stop' - execute 'autocmd! ' . b:ConqueTerm_Var - - else - execute 'augroup ' . b:ConqueTerm_Var - - " handle unexpected closing of shell, passes HUP to parent and all child processes - execute 'autocmd ' . b:ConqueTerm_Var . ' BufUnload python ' . b:ConqueTerm_Var . '.proc.signal(1)' - - " check for resized/scrolled buffer when entering buffer - execute 'autocmd ' . b:ConqueTerm_Var . ' BufEnter python ' . b:ConqueTerm_Var . '.update_window_size()' - execute 'autocmd ' . b:ConqueTerm_Var . ' VimResized python ' . b:ConqueTerm_Var . '.update_window_size()' - - " set/reset updatetime on entering/exiting buffer - autocmd BufEnter set updatetime=50 - autocmd BufLeave set updatetime=2000 - - " check for resized/scrolled buffer when entering insert mode - " XXX - messed up since we enter insert mode at each updatetime - "execute 'autocmd InsertEnter python ' . b:ConqueTerm_Var . '.screen.align()' - - " read more output when this isn't the current buffer - if g:ConqueTerm_ReadUnfocused == 1 - execute 'autocmd ' . b:ConqueTerm_Var . ' CursorHold * call conque_term#read_all()' - endif - - " poll for more output - sil execute 'autocmd ' . b:ConqueTerm_Var . ' CursorHoldI python ' . b:ConqueTerm_Var . '.auto_read()' - endif - - " use F22 key to get more input - if l:action == 'start' - sil exe 'i' . map_modifier . 'map "\\"' - sil exe 'i' . map_modifier . 'map "\\"' - else - sil exe 'i' . map_modifier . 'map ' - sil exe 'i' . map_modifier . 'map ' - endif - - " map ASCII 1-31 - for c in range(1, 31) - " - if c == 27 - continue - endif - if l:action == 'start' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(' . c . '))' - else - sil exe 'i' . map_modifier . 'map ' - endif - endfor - if l:action == 'start' - sil exe 'n' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(3))' - else - sil exe 'n' . map_modifier . 'map ' - endif - - " leave insert mode - if !exists('g:ConqueTerm_EscKey') || g:ConqueTerm_EscKey == '' - " use to send to terminal - if l:action == 'start' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(27))' - else - sil exe 'i' . map_modifier . 'map ' - endif - else - " use to send to terminal - if l:action == 'start' - sil exe 'i' . map_modifier . 'map ' . g:ConqueTerm_EscKey . ' ' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(chr(27))' - else - sil exe 'i' . map_modifier . 'map ' . g:ConqueTerm_EscKey - sil exe 'i' . map_modifier . 'map ' - endif - endif - - " Map in insert mode - if exists('g:ConqueTerm_CWInsert') && g:ConqueTerm_CWInsert == 1 - inoremap j j - inoremap k k - inoremap h h - inoremap l l - inoremap w w - endif - - " map ASCII 33-127 - for i in range(33, 127) - " - if i == 124 - if l:action == 'start' - sil exe "i" . map_modifier . "map :python " . b:ConqueTerm_Var . ".write(chr(124))" - else - sil exe "i" . map_modifier . "map " - endif - continue - endif - if l:action == 'start' - sil exe "i" . map_modifier . "map " . nr2char(i) . " :python " . b:ConqueTerm_Var . ".write(chr(" . i . "))" - else - sil exe "i" . map_modifier . "map " . nr2char(i) - endif - endfor - - " map ASCII 128-255 - for i in range(128, 255) - if l:action == 'start' - sil exe "i" . map_modifier . "map " . nr2char(i) . " :python " . b:ConqueTerm_Var . ".write('" . nr2char(i) . "')" - else - sil exe "i" . map_modifier . "map " . nr2char(i) - endif - endfor - - " Special cases - if l:action == 'start' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u0008")' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(" ")' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[A")' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[B")' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[C")' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . '.write(u"\u001b[D")' - else - sil exe 'i' . map_modifier . 'map ' - sil exe 'i' . map_modifier . 'map ' - sil exe 'i' . map_modifier . 'map ' - sil exe 'i' . map_modifier . 'map ' - sil exe 'i' . map_modifier . 'map ' - sil exe 'i' . map_modifier . 'map ' - endif - - " send selected text into conque - if l:action == 'start' - sil exe 'v' . map_modifier . 'map :call conque_term#send_selected(visualmode())' - else - sil exe 'v' . map_modifier . 'map ' - endif - - " remap paste keys - if l:action == 'start' - sil exe 'n' . map_modifier . 'map p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - sil exe 'n' . map_modifier . 'map P :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - sil exe 'n' . map_modifier . 'map ]p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - sil exe 'n' . map_modifier . 'map [p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - else - sil exe 'n' . map_modifier . 'map p' - sil exe 'n' . map_modifier . 'map P' - sil exe 'n' . map_modifier . 'map ]p' - sil exe 'n' . map_modifier . 'map [p' - endif - if has('gui_running') - if l:action == 'start' - sil exe 'i' . map_modifier . 'map :python ' . b:ConqueTerm_Var . ".write(vim.eval('@+'))a" - else - sil exe 'i' . map_modifier . 'map ' - endif - endif - - " disable other normal mode keys which insert text - if l:action == 'start' - sil exe 'n' . map_modifier . 'map r :echo "Replace mode disabled in shell."' - sil exe 'n' . map_modifier . 'map R :echo "Replace mode disabled in shell."' - sil exe 'n' . map_modifier . 'map c :echo "Change mode disabled in shell."' - sil exe 'n' . map_modifier . 'map C :echo "Change mode disabled in shell."' - sil exe 'n' . map_modifier . 'map s :echo "Change mode disabled in shell."' - sil exe 'n' . map_modifier . 'map S :echo "Change mode disabled in shell."' - else - sil exe 'n' . map_modifier . 'map r' - sil exe 'n' . map_modifier . 'map R' - sil exe 'n' . map_modifier . 'map c' - sil exe 'n' . map_modifier . 'map C' - sil exe 'n' . map_modifier . 'map s' - sil exe 'n' . map_modifier . 'map S' - endif - - " set conque as on or off - if l:action == 'start' - let b:conque_on = 1 - else - let b:conque_on = 0 - endif - - " map command to start stop the shell - if a:action == 'start' - nnoremap :call conque_term#set_mappings('toggle') - endif - -endfunction " }}} - - -" send selected text from another buffer -function! conque_term#send_selected(type) "{{{ - let reg_save = @@ - - " save user's sb settings - let sb_save = &switchbuf - set switchbuf=usetab - - " yank current selection - sil exe "normal! `<" . a:type . "`>y" - - " format yanked text - let @@ = substitute(@@, '^[\r\n]*', '', '') - let @@ = substitute(@@, '[\r\n]*$', '', '') - - " execute yanked text - sil exe ":sb " . g:ConqueTerm_BufName - sil exe 'python ' . g:ConqueTerm_Var . '.paste_selection()' - - " reset original values - let @@ = reg_save - sil exe 'set switchbuf=' . sb_save - - " scroll buffer left - startinsert! - normal 0zH -endfunction "}}} - -" read from all known conque buffers -function! conque_term#read_all() "{{{ - " don't run this if we're in a conque buffer - if exists('b:ConqueTerm_Var') - return - endif - - try - for i in range(1, g:ConqueTerm_Idx - 1) - execute 'python ConqueTerm_' . string(i) . '.read(1)' - endfor - catch - " probably a deleted buffer - endtry - - " restart updatetime - call feedkeys("f\e") -endfunction "}}} - -" util function to add enough \s to pass a string to python -function! conque_term#python_escape(input) "{{{ - let l:cleaned = a:input - let l:cleaned = substitute(l:cleaned, '\\', '\\\\', 'g') - let l:cleaned = substitute(l:cleaned, '\n', '\\n', 'g') - let l:cleaned = substitute(l:cleaned, '\r', '\\r', 'g') - let l:cleaned = substitute(l:cleaned, "'", "\\\\'", 'g') - return l:cleaned -endfunction "}}} - -" ********************************************************************************************************** -" **** PYTHON ********************************************************************************************** -" ********************************************************************************************************** - -if has('python') - -python << EOF - -import vim, re, time, math - -# CONFIG CONSTANTS {{{ - -CONQUE_CTL = { - 7:'bel', # bell - 8:'bs', # backspace - 9:'tab', # tab - 10:'nl', # new line - 13:'cr' # carriage return -} -# 11 : 'vt', # vertical tab -# 12 : 'ff', # form feed -# 14 : 'so', # shift out -# 15 : 'si' # shift in - -# Escape sequences -CONQUE_ESCAPE = { - 'm':'font', - 'J':'clear_screen', - 'K':'clear_line', - '@':'add_spaces', - 'A':'cursor_up', - 'B':'cursor_down', - 'C':'cursor_right', - 'D':'cursor_left', - 'G':'cursor_to_column', - 'H':'cursor', - 'P':'delete_chars', - 'f':'cursor', - 'g':'tab_clear', - 'r':'set_coords', - 'h':'set', - 'l':'reset' -} -# 'L':'insert_lines', -# 'M':'delete_lines', -# 'd':'cusor_vpos', - -# Alternate escape sequences, no [ -CONQUE_ESCAPE_PLAIN = { - 'D':'scroll_up', - 'E':'next_line', - 'H':'set_tab', - 'M':'scroll_down' -} -# 'N':'single_shift_2', -# 'O':'single_shift_3', -# '=':'alternate_keypad', -# '>':'numeric_keypad', -# '7':'save_cursor', -# '8':'restore_cursor', - -# Uber alternate escape sequences, with # or ? -CONQUE_ESCAPE_QUESTION = { - '1h':'new_line_mode', - '3h':'132_cols', - '4h':'smooth_scrolling', - '5h':'reverse_video', - '6h':'relative_origin', - '7h':'set_auto_wrap', - '8h':'set_auto_repeat', - '9h':'set_interlacing_mode', - '1l':'set_cursor_key', - '2l':'set_vt52', - '3l':'80_cols', - '4l':'set_jump_scrolling', - '5l':'normal_video', - '6l':'absolute_origin', - '7l':'reset_auto_wrap', - '8l':'reset_auto_repeat', - '9l':'reset_interlacing_mode' -} - -CONQUE_ESCAPE_HASH = { - '8':'screen_alignment_test' -} -# '3':'double_height_top', -# '4':'double_height_bottom', -# '5':'single_height_single_width', -# '6':'single_height_double_width', - -# Font codes {{{ -CONQUE_FONT = { - 0: {'description':'Normal (default)', 'attributes': {'cterm':'NONE','ctermfg':'NONE','ctermbg':'NONE','gui':'NONE','guifg':'NONE','guibg':'NONE'}, 'normal':True}, - 1: {'description':'Bold', 'attributes': {'cterm':'BOLD','gui':'BOLD'}, 'normal':False}, - 4: {'description':'Underlined', 'attributes': {'cterm':'UNDERLINE','gui':'UNDERLINE'}, 'normal':False}, - 5: {'description':'Blink (appears as Bold)', 'attributes': {'cterm':'BOLD','gui':'BOLD'}, 'normal':False}, - 7: {'description':'Inverse', 'attributes': {'cterm':'REVERSE','gui':'REVERSE'}, 'normal':False}, - 8: {'description':'Invisible (hidden)', 'attributes': {'ctermfg':'0','ctermbg':'0','guifg':'#000000','guibg':'#000000'}, 'normal':False}, - 22: {'description':'Normal (neither bold nor faint)', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, - 24: {'description':'Not underlined', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, - 25: {'description':'Steady (not blinking)', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, - 27: {'description':'Positive (not inverse)', 'attributes': {'cterm':'NONE','gui':'NONE'}, 'normal':True}, - 28: {'description':'Visible (not hidden)', 'attributes': {'ctermfg':'NONE','ctermbg':'NONE','guifg':'NONE','guibg':'NONE'}, 'normal':True}, - 30: {'description':'Set foreground color to Black', 'attributes': {'ctermfg':'16','guifg':'#000000'}, 'normal':False}, - 31: {'description':'Set foreground color to Red', 'attributes': {'ctermfg':'1','guifg':'#ff0000'}, 'normal':False}, - 32: {'description':'Set foreground color to Green', 'attributes': {'ctermfg':'2','guifg':'#00ff00'}, 'normal':False}, - 33: {'description':'Set foreground color to Yellow', 'attributes': {'ctermfg':'3','guifg':'#ffff00'}, 'normal':False}, - 34: {'description':'Set foreground color to Blue', 'attributes': {'ctermfg':'4','guifg':'#0000ff'}, 'normal':False}, - 35: {'description':'Set foreground color to Magenta', 'attributes': {'ctermfg':'5','guifg':'#990099'}, 'normal':False}, - 36: {'description':'Set foreground color to Cyan', 'attributes': {'ctermfg':'6','guifg':'#009999'}, 'normal':False}, - 37: {'description':'Set foreground color to White', 'attributes': {'ctermfg':'7','guifg':'#ffffff'}, 'normal':False}, - 39: {'description':'Set foreground color to default (original)', 'attributes': {'ctermfg':'NONE','guifg':'NONE'}, 'normal':True}, - 40: {'description':'Set background color to Black', 'attributes': {'ctermbg':'16','guibg':'#000000'}, 'normal':False}, - 41: {'description':'Set background color to Red', 'attributes': {'ctermbg':'1','guibg':'#ff0000'}, 'normal':False}, - 42: {'description':'Set background color to Green', 'attributes': {'ctermbg':'2','guibg':'#00ff00'}, 'normal':False}, - 43: {'description':'Set background color to Yellow', 'attributes': {'ctermbg':'3','guibg':'#ffff00'}, 'normal':False}, - 44: {'description':'Set background color to Blue', 'attributes': {'ctermbg':'4','guibg':'#0000ff'}, 'normal':False}, - 45: {'description':'Set background color to Magenta', 'attributes': {'ctermbg':'5','guibg':'#990099'}, 'normal':False}, - 46: {'description':'Set background color to Cyan', 'attributes': {'ctermbg':'6','guibg':'#009999'}, 'normal':False}, - 47: {'description':'Set background color to White', 'attributes': {'ctermbg':'7','guibg':'#ffffff'}, 'normal':False}, - 49: {'description':'Set background color to default (original).', 'attributes': {'ctermbg':'NONE','guibg':'NONE'}, 'normal':True}, - 90: {'description':'Set foreground color to Black', 'attributes': {'ctermfg':'8','guifg':'#000000'}, 'normal':False}, - 91: {'description':'Set foreground color to Red', 'attributes': {'ctermfg':'9','guifg':'#ff0000'}, 'normal':False}, - 92: {'description':'Set foreground color to Green', 'attributes': {'ctermfg':'10','guifg':'#00ff00'}, 'normal':False}, - 93: {'description':'Set foreground color to Yellow', 'attributes': {'ctermfg':'11','guifg':'#ffff00'}, 'normal':False}, - 94: {'description':'Set foreground color to Blue', 'attributes': {'ctermfg':'12','guifg':'#0000ff'}, 'normal':False}, - 95: {'description':'Set foreground color to Magenta', 'attributes': {'ctermfg':'13','guifg':'#990099'}, 'normal':False}, - 96: {'description':'Set foreground color to Cyan', 'attributes': {'ctermfg':'14','guifg':'#009999'}, 'normal':False}, - 97: {'description':'Set foreground color to White', 'attributes': {'ctermfg':'15','guifg':'#ffffff'}, 'normal':False}, - 100: {'description':'Set background color to Black', 'attributes': {'ctermbg':'8','guibg':'#000000'}, 'normal':False}, - 101: {'description':'Set background color to Red', 'attributes': {'ctermbg':'9','guibg':'#ff0000'}, 'normal':False}, - 102: {'description':'Set background color to Green', 'attributes': {'ctermbg':'10','guibg':'#00ff00'}, 'normal':False}, - 103: {'description':'Set background color to Yellow', 'attributes': {'ctermbg':'11','guibg':'#ffff00'}, 'normal':False}, - 104: {'description':'Set background color to Blue', 'attributes': {'ctermbg':'12','guibg':'#0000ff'}, 'normal':False}, - 105: {'description':'Set background color to Magenta', 'attributes': {'ctermbg':'13','guibg':'#990099'}, 'normal':False}, - 106: {'description':'Set background color to Cyan', 'attributes': {'ctermbg':'14','guibg':'#009999'}, 'normal':False}, - 107: {'description':'Set background color to White', 'attributes': {'ctermbg':'15','guibg':'#ffffff'}, 'normal':False} -} -# }}} - -# regular expression matching (almost) all control sequences -CONQUE_SEQ_REGEX = re.compile(ur"(\u001b\[?\??#?[0-9;]*[a-zA-Z@]|\u001b\][0-9];.*?\u0007|[\u0007-\u000f])", re.UNICODE) -CONQUE_SEQ_REGEX_CTL = re.compile(ur"^[\u0007-\u000f]$", re.UNICODE) -CONQUE_SEQ_REGEX_CSI = re.compile(ur"^\u001b\[", re.UNICODE) -CONQUE_SEQ_REGEX_TITLE = re.compile(ur"^\u001b\]", re.UNICODE) -CONQUE_SEQ_REGEX_HASH = re.compile(ur"^\u001b#", re.UNICODE) -CONQUE_SEQ_REGEX_ESC = re.compile(ur"^\u001b", re.UNICODE) - -# match table output -CONQUE_TABLE_OUTPUT = re.compile("^\s*\|\s.*\s\|\s*$|^\s*\+[=+-]+\+\s*$") - -# }}} - -################################################################################################### -class Conque: - - # CLASS PROPERTIES {{{ - - # screen object - screen = None - - # subprocess object - proc = None - - # terminal dimensions and scrolling region - columns = 80 # same as $COLUMNS - lines = 24 # same as $LINES - working_columns = 80 # can be changed by CSI ? 3 l/h - working_lines = 24 # can be changed by CSI r - - # top/bottom of the scroll region - top = 1 # relative to top of screen - bottom = 24 # relative to top of screen - - # cursor position - l = 1 # current cursor line - c = 1 # current cursor column - - # autowrap mode - autowrap = True - - # absolute coordinate mode - absolute_coords = True - - # tabstop positions - tabstops = [] - - # enable colors - enable_colors = True - - # color changes - color_changes = {} - - # color history - color_history = {} - - # don't wrap table output - unwrap_tables = True - - # wrap CUF/CUB around line breaks - wrap_cursor = False - - # }}} - - # constructor - def __init__(self): # {{{ - self.screen = ConqueScreen() - # }}} - - # start program and initialize this instance - def open(self, command, options): # {{{ - - # int vars - self.columns = vim.current.window.width - self.lines = vim.current.window.height - self.working_columns = vim.current.window.width - self.working_lines = vim.current.window.height - self.bottom = vim.current.window.height - - # init color - self.enable_colors = options['color'] - - # init tabstops - self.init_tabstops() - - # open command - self.proc = ConqueSubprocess() - self.proc.open(command, { 'TERM' : options['TERM'], 'CONQUE' : '1', 'LINES' : str(self.lines), 'COLUMNS' : str(self.columns)}) - # }}} - - # write to pty - def write(self, input): # {{{ - - - # check if window size has changed - self.update_window_size() - - # write and read - self.proc.write(input) - self.read(1) - # }}} - - # read from pty, and update buffer - def read(self, timeout = 1): # {{{ - # read from subprocess - output = self.proc.read(timeout) - # and strip null chars - output = output.replace(chr(0), '') - - if output == '': - return - - - - - - chunks = CONQUE_SEQ_REGEX.split(output) - - - - - - # don't go through all the csi regex if length is one (no matches) - if len(chunks) == 1: - - self.plain_text(chunks[0]) - - else: - for s in chunks: - if s == '': - continue - - - - - - - # Check for control character match {{{ - if CONQUE_SEQ_REGEX_CTL.match(s[0]): - - nr = ord(s[0]) - if nr in CONQUE_CTL: - getattr(self, 'ctl_' + CONQUE_CTL[nr])() - else: - - pass - # }}} - - # check for escape sequence match {{{ - elif CONQUE_SEQ_REGEX_CSI.match(s): - - if s[-1] in CONQUE_ESCAPE: - csi = self.parse_csi(s[2:]) - - getattr(self, 'csi_' + CONQUE_ESCAPE[s[-1]])(csi) - else: - - pass - # }}} - - # check for title match {{{ - elif CONQUE_SEQ_REGEX_TITLE.match(s): - - self.change_title(s[2], s[4:-1]) - # }}} - - # check for hash match {{{ - elif CONQUE_SEQ_REGEX_HASH.match(s): - - if s[-1] in CONQUE_ESCAPE_HASH: - getattr(self, 'hash_' + CONQUE_ESCAPE_HASH[s[-1]])() - else: - - pass - # }}} - - # check for other escape match {{{ - elif CONQUE_SEQ_REGEX_ESC.match(s): - - if s[-1] in CONQUE_ESCAPE_PLAIN: - getattr(self, 'esc_' + CONQUE_ESCAPE_PLAIN[s[-1]])() - else: - - pass - # }}} - - # else process plain text {{{ - else: - self.plain_text(s) - # }}} - - # set cursor position - self.screen.set_cursor(self.l, self.c) - - vim.command('redraw') - - - # }}} - - # for polling - def auto_read(self): # {{{ - self.read(1) - if self.c == 1: - vim.command('call feedkeys("\", "t")') - else: - vim.command('call feedkeys("\", "t")') - self.screen.set_cursor(self.l, self.c) - # }}} - - ############################################################################################### - # Plain text # {{{ - - def plain_text(self, input): - - current_line = self.screen[self.l] - - if len(current_line) < self.working_columns: - current_line = current_line + ' ' * (self.c - len(current_line)) - - # if line is wider than screen - if self.c + len(input) - 1 > self.working_columns: - # Table formatting hack - if self.unwrap_tables and CONQUE_TABLE_OUTPUT.match(input): - self.screen[self.l] = current_line[ : self.c - 1] + input + current_line[ self.c + len(input) - 1 : ] - self.apply_color(self.c, self.c + len(input)) - self.c += len(input) - return - - diff = self.c + len(input) - self.working_columns - 1 - # if autowrap is enabled - if self.autowrap: - self.screen[self.l] = current_line[ : self.c - 1] + input[ : -1 * diff ] - self.apply_color(self.c, self.working_columns) - self.ctl_nl() - self.ctl_cr() - remaining = input[ -1 * diff : ] - - self.plain_text(remaining) - else: - self.screen[self.l] = current_line[ : self.c - 1] + input[ : -1 * diff - 1 ] + input[-1] - self.apply_color(self.c, self.working_columns) - self.c = self.working_columns - - # no autowrap - else: - self.screen[self.l] = current_line[ : self.c - 1] + input + current_line[ self.c + len(input) - 1 : ] - self.apply_color(self.c, self.c + len(input)) - self.c += len(input) - - def apply_color(self, start, end): - - - # stop here if coloration is disabled - if not self.enable_colors: - return - - real_line = self.screen.get_real_line(self.l) - - # check for previous overlapping coloration - - to_del = [] - if self.color_history.has_key(real_line): - for i in range(len(self.color_history[real_line])): - syn = self.color_history[real_line][i] - - if syn['start'] >= start and syn['start'] < end: - - vim.command('syn clear ' + syn['name']) - to_del.append(i) - # outside - if syn['end'] > end: - - self.exec_highlight(real_line, end, syn['end'], syn['highlight']) - elif syn['end'] > start and syn['end'] <= end: - - vim.command('syn clear ' + syn['name']) - to_del.append(i) - # outside - if syn['start'] < start: - - self.exec_highlight(real_line, syn['start'], start, syn['highlight']) - - if len(to_del) > 0: - to_del.reverse() - for di in to_del: - del self.color_history[real_line][di] - - # if there are no new colors - if len(self.color_changes) == 0: - return - - highlight = '' - for attr in self.color_changes.keys(): - highlight = highlight + ' ' + attr + '=' + self.color_changes[attr] - - # execute the highlight - self.exec_highlight(real_line, start, end, highlight) - - def exec_highlight(self, real_line, start, end, highlight): - unique_key = str(self.proc.pid) - - syntax_name = 'EscapeSequenceAt_' + unique_key + '_' + str(self.l) + '_' + str(start) + '_' + str(len(self.color_history) + 1) - syntax_options = ' contains=ALLBUT,ConqueString,MySQLString,MySQLKeyword oneline' - syntax_region = 'syntax match ' + syntax_name + ' /\%' + str(real_line) + 'l\%>' + str(start - 1) + 'c.*\%<' + str(end + 1) + 'c/' + syntax_options - syntax_highlight = 'highlight ' + syntax_name + highlight - - vim.command(syntax_region) - vim.command(syntax_highlight) - - # add syntax name to history - if not self.color_history.has_key(real_line): - self.color_history[real_line] = [] - - self.color_history[real_line].append({'name':syntax_name, 'start':start, 'end':end, 'highlight':highlight}) - - # }}} - - ############################################################################################### - # Control functions {{{ - - def ctl_nl(self): - # if we're in a scrolling region, scroll instead of moving cursor down - if self.lines != self.working_lines and self.l == self.bottom: - del self.screen[self.top] - self.screen.insert(self.bottom, '') - elif self.l == self.bottom: - self.screen.append('') - else: - self.l += 1 - - self.color_changes = {} - - def ctl_cr(self): - self.c = 1 - - self.color_changes = {} - - def ctl_bs(self): - if self.c > 1: - self.c += -1 - - def ctl_bel(self): - print 'BELL' - - def ctl_tab(self): - # default tabstop location - ts = self.working_columns - - # check set tabstops - for i in range(self.c, len(self.tabstops)): - if self.tabstops[i]: - ts = i + 1 - break - - - - self.c = ts - - # }}} - - ############################################################################################### - # CSI functions {{{ - - def csi_font(self, csi): # {{{ - if not self.enable_colors: - return - - # defaults to 0 - if len(csi['vals']) == 0: - csi['vals'] = [0] - - # 256 xterm color foreground - if len(csi['vals']) == 3 and csi['vals'][0] == 38 and csi['vals'][1] == 5: - self.color_changes['ctermfg'] = str(csi['vals'][2]) - self.color_changes['guifg'] = '#' + self.xterm_to_rgb(csi['vals'][2]) - - # 256 xterm color background - elif len(csi['vals']) == 3 and csi['vals'][0] == 48 and csi['vals'][1] == 5: - self.color_changes['ctermbg'] = str(csi['vals'][2]) - self.color_changes['guibg'] = '#' + self.xterm_to_rgb(csi['vals'][2]) - - # 16 colors - else: - for val in csi['vals']: - if CONQUE_FONT.has_key(val): - - # ignore starting normal colors - if CONQUE_FONT[val]['normal'] and len(self.color_changes) == 0: - - continue - # clear color changes - elif CONQUE_FONT[val]['normal']: - - self.color_changes = {} - # save these color attributes for next plain_text() call - else: - - for attr in CONQUE_FONT[val]['attributes'].keys(): - if self.color_changes.has_key(attr) and (attr == 'cterm' or attr == 'gui'): - self.color_changes[attr] += ',' + CONQUE_FONT[val]['attributes'][attr] - else: - self.color_changes[attr] = CONQUE_FONT[val]['attributes'][attr] - # }}} - - def csi_clear_line(self, csi): # {{{ - - - # this escape defaults to 0 - if len(csi['vals']) == 0: - csi['val'] = 0 - - - - - # 0 means cursor right - if csi['val'] == 0: - self.screen[self.l] = self.screen[self.l][0 : self.c - 1] - - # 1 means cursor left - elif csi['val'] == 1: - self.screen[self.l] = ' ' * (self.c) + self.screen[self.l][self.c : ] - - # clear entire line - elif csi['val'] == 2: - self.screen[self.l] = '' - - # clear colors - if csi['val'] == 2 or (csi['val'] == 0 and self.c == 1): - real_line = self.screen.get_real_line(self.l) - if self.color_history.has_key(real_line): - for syn in self.color_history[real_line]: - vim.command('syn clear ' + syn['name']) - - - - # }}} - - def csi_cursor_right(self, csi): # {{{ - # we use 1 even if escape explicitly specifies 0 - if csi['val'] == 0: - csi['val'] = 1 - - - - - if self.wrap_cursor and self.c + csi['val'] > self.working_columns: - self.l += int(math.floor( (self.c + csi['val']) / self.working_columns )) - self.c = (self.c + csi['val']) % self.working_columns - return - - self.c = self.bound(self.c + csi['val'], 1, self.working_columns) - # }}} - - def csi_cursor_left(self, csi): # {{{ - # we use 1 even if escape explicitly specifies 0 - if csi['val'] == 0: - csi['val'] = 1 - - if self.wrap_cursor and csi['val'] >= self.c: - self.l += int(math.floor( (self.c - csi['val']) / self.working_columns )) - self.c = self.working_columns - (csi['val'] - self.c) % self.working_columns - return - - self.c = self.bound(self.c - csi['val'], 1, self.working_columns) - # }}} - - def csi_cursor_to_column(self, csi): # {{{ - self.c = self.bound(csi['val'], 1, self.working_columns) - # }}} - - def csi_cursor_up(self, csi): # {{{ - self.l = self.bound(self.l - csi['val'], self.top, self.bottom) - - self.color_changes = {} - # }}} - - def csi_cursor_down(self, csi): # {{{ - self.l = self.bound(self.l + csi['val'], self.top, self.bottom) - - self.color_changes = {} - # }}} - - def csi_clear_screen(self, csi): # {{{ - # default to 0 - if len(csi['vals']) == 0: - csi['val'] = 0 - - # 2 == clear entire screen - if csi['val'] == 2: - self.l = 1 - self.c = 1 - self.screen.clear() - - # 0 == clear down - elif csi['val'] == 0: - for l in range(self.bound(self.l + 1, 1, self.lines), self.lines + 1): - self.screen[l] = '' - - # clear end of current line - self.csi_clear_line(self.parse_csi('K')) - - # 1 == clear up - elif csi['val'] == 1: - for l in range(1, self.bound(self.l, 1, self.lines + 1)): - self.screen[l] = '' - - # clear beginning of current line - self.csi_clear_line(self.parse_csi('1K')) - - # clear coloration - if csi['val'] == 2 or csi['val'] == 0: - real_line = self.screen.get_real_line(self.l) - for line in self.color_history.keys(): - if line >= real_line: - for syn in self.color_history[line]: - vim.command('syn clear ' + syn['name']) - - self.color_changes = {} - # }}} - - def csi_delete_chars(self, csi): # {{{ - self.screen[self.l] = self.screen[self.l][ : self.c ] + self.screen[self.l][ self.c + csi['val'] : ] - # }}} - - def csi_add_spaces(self, csi): # {{{ - self.screen[self.l] = self.screen[self.l][ : self.c - 1] + ' ' * csi['val'] + self.screen[self.l][self.c : ] - # }}} - - def csi_cursor(self, csi): # {{{ - if len(csi['vals']) == 2: - new_line = csi['vals'][0] - new_col = csi['vals'][1] - else: - new_line = 1 - new_col = 1 - - if self.absolute_coords: - self.l = self.bound(new_line, 1, self.lines) - else: - self.l = self.bound(self.top + new_line - 1, self.top, self.bottom) - - self.c = self.bound(new_col, 1, self.working_columns) - if self.c > len(self.screen[self.l]): - self.screen[self.l] = self.screen[self.l] + ' ' * (self.c - len(self.screen[self.l])) - - # }}} - - def csi_set_coords(self, csi): # {{{ - if len(csi['vals']) == 2: - new_start = csi['vals'][0] - new_end = csi['vals'][1] - else: - new_start = 1 - new_end = vim.current.window.height - - self.top = new_start - self.bottom = new_end - self.working_lines = new_end - new_start + 1 - - # if cursor is outside scrolling region, reset it - if self.l < self.top: - self.l = self.top - elif self.l > self.bottom: - self.l = self.bottom - - self.color_changes = {} - # }}} - - def csi_tab_clear(self, csi): # {{{ - # this escape defaults to 0 - if len(csi['vals']) == 0: - csi['val'] = 0 - - - - if csi['val'] == 0: - self.tabstops[self.c - 1] = False - elif csi['val'] == 3: - for i in range(0, self.columns + 1): - self.tabstops[i] = False - # }}} - - def csi_set(self, csi): # {{{ - # 132 cols - if csi['val'] == 3: - self.csi_clear_screen(self.parse_csi('2J')) - self.working_columns = 132 - - # relative_origin - elif csi['val'] == 6: - self.absolute_coords = False - - # set auto wrap - elif csi['val'] == 7: - self.autowrap = True - - - self.color_changes = {} - # }}} - - def csi_reset(self, csi): # {{{ - # 80 cols - if csi['val'] == 3: - self.csi_clear_screen(self.parse_csi('2J')) - self.working_columns = 80 - - # absolute origin - elif csi['val'] == 6: - self.absolute_coords = True - - # reset auto wrap - elif csi['val'] == 7: - self.autowrap = False - - - self.color_changes = {} - # }}} - - # }}} - - ############################################################################################### - # ESC functions {{{ - - def esc_scroll_up(self): # {{{ - self.ctl_nl() - - self.color_changes = {} - # }}} - - def esc_next_line(self): # {{{ - self.ctl_nl() - self.c = 1 - # }}} - - def esc_set_tab(self): # {{{ - - if self.c <= len(self.tabstops): - self.tabstops[self.c - 1] = True - # }}} - - def esc_scroll_down(self): # {{{ - if self.l == self.top: - del self.screen[self.bottom] - self.screen.insert(self.top, '') - else: - self.l += -1 - - self.color_changes = {} - # }}} - - # }}} - - ############################################################################################### - # HASH functions {{{ - - def hash_screen_alignment_test(self): # {{{ - self.csi_clear_screen(self.parse_csi('2J')) - self.working_lines = self.lines - for l in range(1, self.lines + 1): - self.screen[l] = 'E' * self.working_columns - # }}} - - # }}} - - ############################################################################################### - # Random stuff {{{ - - def change_title(self, key, val): - - - if key == '0' or key == '2': - - vim.command('setlocal statusline=' + re.escape(val)) - - def paste(self): - self.write(vim.eval('@@')) - self.read(50) - - def paste_selection(self): - self.write(vim.eval('@@')) - - def update_window_size(self): - # resize if needed - if vim.current.window.width != self.columns or vim.current.window.height != self.lines: - - # reset all window size attributes to default - self.columns = vim.current.window.width - self.lines = vim.current.window.height - self.working_columns = vim.current.window.width - self.working_lines = vim.current.window.height - self.bottom = vim.current.window.height - - # reset screen object attributes - self.l = self.screen.reset_size(self.l) - - # reset tabstops - self.init_tabstops() - - - - # signal process that screen size has changed - self.proc.window_resize(self.lines, self.columns) - - def init_tabstops(self): - for i in range(0, self.columns + 1): - if i % 8 == 0: - self.tabstops.append(True) - else: - self.tabstops.append(False) - - # }}} - - ############################################################################################### - # Utility {{{ - - def parse_csi(self, s): # {{{ - attr = { 'key' : s[-1], 'flag' : '', 'val' : 1, 'vals' : [] } - - if len(s) == 1: - return attr - - full = s[0:-1] - - if full[0] == '?': - full = full[1:] - attr['flag'] = '?' - - if full != '': - vals = full.split(';') - for val in vals: - - val = re.sub("\D", "", val) - - if val != '': - attr['vals'].append(int(val)) - - if len(attr['vals']) == 1: - attr['val'] = int(attr['vals'][0]) - - return attr - # }}} - - def bound(self, val, min, max): # {{{ - if val > max: - return max - - if val < min: - return min - - return val - # }}} - - def xterm_to_rgb(self, color_code): # {{{ - if color_code < 16: - ascii_colors = ['000000', 'CD0000', '00CD00', 'CDCD00', '0000EE', 'CD00CD', '00CDCD', 'E5E5E5', - '7F7F7F', 'FF0000', '00FF00', 'FFFF00', '5C5CFF', 'FF00FF', '00FFFF', 'FFFFFF'] - return ascii_colors[color_code] - - elif color_code < 232: - cc = int(color_code) - 16 - - p1 = "%02x" % (math.floor(cc / 36) * (255/5)) - p2 = "%02x" % (math.floor((cc % 36) / 6) * (255/5)) - p3 = "%02x" % (math.floor(cc % 6) * (255/5)) - - return p1 + p2 + p3 - else: - grey_tone = "%02x" % math.floor((255/24) * (color_code - 232)) - return grey_tone + grey_tone + grey_tone - # }}} - - # }}} - - -import os, signal, pty, tty, select, fcntl, termios, struct - -################################################################################################### -class ConqueSubprocess: - - # process id - pid = 0 - - # stdout+stderr file descriptor - fd = None - - # constructor - def __init__(self): # {{{ - self.pid = 0 - # }}} - - # create the pty or whatever (whatever == windows) - def open(self, command, env = {}): # {{{ - command_arr = command.split() - executable = command_arr[0] - args = command_arr - - try: - self.pid, self.fd = pty.fork() - - except: - pass - - - # child proc, replace with command after altering terminal attributes - if self.pid == 0: - - # set requested environment variables - for k in env.keys(): - os.environ[k] = env[k] - - # set some attributes - try: - attrs = tty.tcgetattr(1) - attrs[0] = attrs[0] ^ tty.IGNBRK - attrs[0] = attrs[0] | tty.BRKINT | tty.IXANY | tty.IMAXBEL - attrs[2] = attrs[2] | tty.HUPCL - attrs[3] = attrs[3] | tty.ICANON | tty.ECHO | tty.ISIG | tty.ECHOKE - attrs[6][tty.VMIN] = 1 - attrs[6][tty.VTIME] = 0 - tty.tcsetattr(1, tty.TCSANOW, attrs) - except: - pass - - os.execvp(executable, args) - - # else master, do nothing - else: - pass - - # }}} - - # read from pty - # XXX - select.poll() doesn't work in OS X!!!!!!! - def read(self, timeout = 1): # {{{ - - output = '' - read_timeout = float(timeout) / 1000 - - try: - # what, no do/while? - while 1: - s_read, s_write, s_error = select.select( [ self.fd ], [], [], read_timeout) - - lines = '' - for s_fd in s_read: - try: - lines = os.read( self.fd, 32 ) - except: - pass - output = output + lines - - if lines == '': - break - except: - pass - - return output - # }}} - - # I guess this one's not bad - def write(self, input): # {{{ - try: - os.write(self.fd, input) - except: - pass - # }}} - - # signal process - def signal(self, signum): # {{{ - try: - os.kill(self.pid, signum) - except: - pass - # }}} - - # get process status - def get_status(self): #{{{ - - p_status = True - - try: - if os.waitpid( self.pid, os.WNOHANG )[0]: - p_status = False - except: - p_status = False - - return p_status - - # }}} - - # update window size in kernel, then send SIGWINCH to fg process - def window_resize(self, lines, columns): # {{{ - try: - fcntl.ioctl(self.fd, termios.TIOCSWINSZ, struct.pack("HHHH", lines, columns, 0, 0)) - os.kill(self.pid, signal.SIGWINCH) - except: - pass - - # }}} - - -################################################################################################### -# ConqueScreen is an extention of the vim.current.buffer object -# It restricts the working indices of the buffer object to the scroll region which pty is expecting -# It also uses 1-based indexes, to match escape sequence commands -# -# E.g.: -# s = ConqueScreen() -# ... -# s[5] = 'Set 5th line in terminal to this line' -# s.append('Add new line to terminal') -# s[5] = 'Since previous append() command scrolled the terminal down, this is a different line than first cb[5] call' -# - -import vim - -class ConqueScreen(object): - - # CLASS PROPERTIES {{{ - - # the buffer - buffer = None - - # screen and scrolling regions - screen_top = 1 - - # screen width - screen_width = 80 - screen_height = 80 - - # }}} - - def __init__(self): # {{{ - self.buffer = vim.current.buffer - - self.screen_top = 1 - self.screen_width = vim.current.window.width - self.screen_height = vim.current.window.height - # }}} - - ############################################################################################### - # List overload {{{ - def __len__(self): # {{{ - return len(self.buffer) - # }}} - - def __getitem__(self, key): # {{{ - real_line = self.get_real_idx(key) - - # if line is past buffer end, add lines to buffer - if real_line >= len(self.buffer): - for i in range(len(self.buffer), real_line + 1): - self.append(' ' * self.screen_width) - - return self.buffer[ real_line ] - # }}} - - def __setitem__(self, key, value): # {{{ - real_line = self.get_real_idx(key) - - # if line is past end of screen, append - if real_line == len(self.buffer): - self.buffer.append(value) - else: - self.buffer[ real_line ] = value - # }}} - - def __delitem__(self, key): # {{{ - del self.buffer[ self.screen_top + key - 2 ] - # }}} - - def append(self, value): # {{{ - if len(self.buffer) > self.screen_top + self.screen_height - 1: - self.buffer[len(self.buffer) - 1] = value - else: - self.buffer.append(value) - - if len(self.buffer) > self.screen_top + self.screen_height - 1: - self.screen_top += 1 - if vim.current.buffer.number == self.buffer.number: - vim.command('normal G') - # }}} - - def insert(self, line, value): # {{{ - - l = self.screen_top + line - 2 - self.buffer[l:l] = [ value ] - - # }}} - # }}} - - ############################################################################################### - # Util {{{ - def get_top(self): # {{{ - return self.screen_top - # }}} - - def get_real_idx(self, line): # {{{ - return (self.screen_top + line - 2) - # }}} - - def get_real_line(self, line): # {{{ - return (self.screen_top + line - 1) - # }}} - - def set_screen_width(self, width): # {{{ - self.screen_width = width - # }}} - - # }}} - - ############################################################################################### - def clear(self): # {{{ - self.buffer.append(' ') - vim.command('normal Gzt') - self.screen_top = len(self.buffer) - # }}} - - def set_cursor(self, line, column): # {{{ - # figure out line - real_line = self.screen_top + line - 1 - if real_line > len(self.buffer): - for l in range(len(self.buffer) - 1, real_line): - self.buffer.append('') - - # figure out column - real_column = column - if len(self.buffer[real_line - 1]) < real_column: - self.buffer[real_line - 1] = self.buffer[real_line - 1] + ' ' * (real_column - len(self.buffer[real_line - 1])) - - # python version is occasionally grumpy - try: - vim.current.window.cursor = (real_line, real_column - 1) - except: - vim.command('call cursor(' + str(real_line) + ', ' + str(real_column) + ')') - # }}} - - def reset_size(self, line): # {{{ - - - - - # save cursor line number - real_line = self.screen_top + line - - # reset screen size - self.screen_width = vim.current.window.width - self.screen_height = vim.current.window.height - self.screen_top = len(self.buffer) - vim.current.window.height + 1 - if self.screen_top < 1: - self.screen_top = 1 - - - # align bottom of buffer to bottom of screen - vim.command('normal ' + str(self.screen_height) + 'kG') - - # return new relative line number - return (real_line - self.screen_top) - # }}} - - def scroll_to_bottom(self): # {{{ - vim.current.window.cursor = (len(self.buffer) - 1, 1) - # }}} - - def align(self): # {{{ - # align bottom of buffer to bottom of screen - vim.command('normal ' + str(self.screen_height) + 'kG') - # }}} - - -EOF - -endif - diff --git a/vim/autoload/rails.vim b/vim/autoload/rails.vim deleted file mode 100644 index ca36075..0000000 --- a/vim/autoload/rails.vim +++ /dev/null @@ -1,4560 +0,0 @@ -" autoload/rails.vim -" Author: Tim Pope - -" Install this file as autoload/rails.vim. - -if exists('g:autoloaded_rails') || &cp - finish -endif -let g:autoloaded_rails = '4.4' - -let s:cpo_save = &cpo -set cpo&vim - -" Utility Functions {{{1 - -let s:app_prototype = {} -let s:file_prototype = {} -let s:buffer_prototype = {} -let s:readable_prototype = {} - -function! s:add_methods(namespace, method_names) - for name in a:method_names - let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name) - endfor -endfunction - -function! s:function(name) - return function(substitute(a:name,'^s:',matchstr(expand(''), '\d\+_'),'')) -endfunction - -function! s:sub(str,pat,rep) - return substitute(a:str,'\v\C'.a:pat,a:rep,'') -endfunction - -function! s:gsub(str,pat,rep) - return substitute(a:str,'\v\C'.a:pat,a:rep,'g') -endfunction - -function! s:startswith(string,prefix) - return strpart(a:string, 0, strlen(a:prefix)) ==# a:prefix -endfunction - -function! s:compact(ary) - return s:sub(s:sub(s:gsub(a:ary,'\n\n+','\n'),'\n$',''),'^\n','') -endfunction - -function! s:uniq(list) - let seen = {} - let i = 0 - while i < len(a:list) - if has_key(seen,a:list[i]) - call remove(a:list, i) - else - let seen[a:list[i]] = 1 - let i += 1 - endif - endwhile - return a:list -endfunction - -function! s:scrub(collection,item) - " Removes item from a newline separated collection - let col = "\n" . a:collection - let idx = stridx(col,"\n".a:item."\n") - let cnt = 0 - while idx != -1 && cnt < 100 - let col = strpart(col,0,idx).strpart(col,idx+strlen(a:item)+1) - let idx = stridx(col,"\n".a:item."\n") - let cnt += 1 - endwhile - return strpart(col,1) -endfunction - -function! s:escarg(p) - return s:gsub(a:p,'[ !%#]','\\&') -endfunction - -function! s:esccmd(p) - return s:gsub(a:p,'[!%#]','\\&') -endfunction - -function! s:rquote(str) - " Imperfect but adequate for Ruby arguments - if a:str =~ '^[A-Za-z0-9_/.:-]\+$' - return a:str - elseif &shell =~? 'cmd' - return '"'.s:gsub(s:gsub(a:str,'\','\\'),'"','\\"').'"' - else - return "'".s:gsub(s:gsub(a:str,'\','\\'),"'","'\\\\''")."'" - endif -endfunction - -function! s:sname() - return fnamemodify(s:file,':t:r') -endfunction - -function! s:pop_command() - if exists("s:command_stack") && len(s:command_stack) > 0 - exe remove(s:command_stack,-1) - endif -endfunction - -function! s:push_chdir(...) - if !exists("s:command_stack") | let s:command_stack = [] | endif - if exists("b:rails_root") && (a:0 ? getcwd() !=# rails#app().path() : !s:startswith(getcwd(), rails#app().path())) - let chdir = exists("*haslocaldir") && haslocaldir() ? "lchdir " : "chdir " - call add(s:command_stack,chdir.s:escarg(getcwd())) - exe chdir.s:escarg(rails#app().path()) - else - call add(s:command_stack,"") - endif -endfunction - -function! s:app_path(...) dict - return join([self.root]+a:000,'/') -endfunction - -function! s:app_has_file(file) dict - return filereadable(self.path(a:file)) -endfunction - -function! s:app_find_file(name, ...) dict abort - let trim = strlen(self.path())+1 - if a:0 - let path = s:pathjoin(map(s:pathsplit(a:1),'self.path(v:val)')) - else - let path = s:pathjoin([self.path()]) - endif - let suffixesadd = s:pathjoin(get(a:000,1,&suffixesadd)) - let default = get(a:000,2,'') - let oldsuffixesadd = &l:suffixesadd - try - let &suffixesadd = suffixesadd - " Versions before 7.1.256 returned directories from findfile - if type(default) == type(0) && (v:version < 702 || default == -1) - let all = findfile(a:name,path,-1) - if v:version < 702 - call filter(all,'!isdirectory(v:val)') - endif - call map(all,'s:gsub(strpart(fnamemodify(v:val,":p"),trim),"\\\\","/")') - return default < 0 ? all : get(all,default-1,'') - elseif type(default) == type(0) - let found = findfile(a:name,path,default) - else - let i = 1 - let found = findfile(a:name,path) - while v:version < 702 && found != "" && isdirectory(found) - let i += 1 - let found = findfile(a:name,path,i) - endwhile - endif - return found == "" ? default : s:gsub(strpart(fnamemodify(found,':p'),trim),'\\','/') - finally - let &l:suffixesadd = oldsuffixesadd - endtry -endfunction - -call s:add_methods('app',['path','has_file','find_file']) - -" Split a path into a list. From pathogen.vim -function! s:pathsplit(path) abort - if type(a:path) == type([]) | return copy(a:path) | endif - let split = split(a:path,'\\\@' - if matchstr(self.getline(a:lnum+1),'^'.spc) && !matchstr(self.getline(a:lnum+1),'^'.spc.endpat) && matchstr(cline,endpat) - return a:lnum - endif - let endl = a:lnum - while endl <= self.line_count() - let endl += 1 - if self.getline(endl) =~ '^'.spc.endpat - return endl - elseif self.getline(endl) =~ '^=begin\>' - while self.getline(endl) !~ '^=end\>' && endl <= self.line_count() - let endl += 1 - endwhile - let endl += 1 - elseif self.getline(endl) !~ '^'.spc && self.getline(endl) !~ '^\s*\%(#.*\)\=$' - return 0 - endif - endwhile - return 0 -endfunction - -function! s:endof(lnum) - return rails#buffer().end_of(a:lnum) -endfunction - -function! s:readable_last_opening_line(start,pattern,limit) dict abort - let line = a:start - while line > a:limit && self.getline(line) !~ a:pattern - let line -= 1 - endwhile - let lend = self.end_of(line) - if line > a:limit && (lend < 0 || lend >= a:start) - return line - else - return -1 - endif -endfunction - -function! s:lastopeningline(pattern,limit,start) - return rails#buffer().last_opening_line(a:start,a:pattern,a:limit) -endfunction - -function! s:readable_define_pattern() dict abort - if self.name() =~ '\.yml$' - return '^\%(\h\k*:\)\@=' - endif - let define = '^\s*def\s\+\(self\.\)\=' - if self.name() =~# '\.rake$' - let define .= "\\\|^\\s*\\%(task\\\|file\\)\\s\\+[:'\"]" - endif - if self.name() =~# '/schema\.rb$' - let define .= "\\\|^\\s*create_table\\s\\+[:'\"]" - endif - if self.type_name('test') - let define .= '\|^\s*test\s*[''"]' - endif - return define -endfunction - -function! s:readable_last_method_line(start) dict abort - return self.last_opening_line(a:start,self.define_pattern(),0) -endfunction - -function! s:lastmethodline(start) - return rails#buffer().last_method_line(a:start) -endfunction - -function! s:readable_last_method(start) dict abort - let lnum = self.last_method_line(a:start) - let line = self.getline(lnum) - if line =~# '^\s*test\s*\([''"]\).*\1' - let string = matchstr(line,'^\s*\w\+\s*\([''"]\)\zs.*\ze\1') - return 'test_'.s:gsub(string,' +','_') - elseif lnum - return s:sub(matchstr(line,'\%('.self.define_pattern().'\)\zs\h\%(\k\|[:.]\)*[?!=]\='),':$','') - else - return "" - endif -endfunction - -function! s:lastmethod(...) - return rails#buffer().last_method(a:0 ? a:1 : line(".")) -endfunction - -function! s:readable_last_format(start) dict abort - if self.type_name('view') - let format = fnamemodify(self.path(),':r:e') - if format == '' - return get({'rhtml': 'html', 'rxml': 'xml', 'rjs': 'js', 'haml': 'html'},fnamemodify(self.path(),':e'),'') - else - return format - endif - endif - let rline = self.last_opening_line(a:start,'\C^\s*\%(mail\>.*\|respond_to\)\s*\%(\.*\|respond_to\)\s*\%(\ rline - let match = matchstr(self.getline(line),'\C^\s*'.variable.'\s*\.\s*\zs\h\k*') - if match != '' - return match - endif - let line -= 1 - endwhile - endif - return "" -endfunction - -function! s:lastformat(start) - return rails#buffer().last_format(a:start) -endfunction - -function! s:format(...) - let format = rails#buffer().last_format(a:0 > 1 ? a:2 : line(".")) - return format ==# '' && a:0 ? a:1 : format -endfunction - -call s:add_methods('readable',['end_of','last_opening_line','last_method_line','last_method','last_format','define_pattern']) - -let s:view_types = split('rhtml,erb,rxml,builder,rjs,mab,liquid,haml,dryml,mn,slim',',') - -function! s:viewspattern() - return '\%('.join(s:view_types,'\|').'\)' -endfunction - -function! s:controller(...) - return rails#buffer().controller_name(a:0 ? a:1 : 0) -endfunction - -function! s:readable_controller_name(...) dict abort - let f = self.name() - if has_key(self,'getvar') && self.getvar('rails_controller') != '' - return self.getvar('rails_controller') - elseif f =~ '\ get(self,last_lines_ftime,0) - let self.last_lines = readfile(self.path()) - let self.last_lines_ftime = ftime - endif - return get(self,'last_lines',[]) -endfunction - -function! s:file_getline(lnum,...) dict abort - if a:0 - return self.lines[lnum-1 : a:1-1] - else - return self.lines[lnum-1] - endif -endfunction - -function! s:buffer_lines() dict abort - return self.getline(1,'$') -endfunction - -function! s:buffer_getline(...) dict abort - if a:0 == 1 - return get(call('getbufline',[self.number()]+a:000),0,'') - else - return call('getbufline',[self.number()]+a:000) - endif -endfunction - -function! s:readable_line_count() dict abort - return len(self.lines()) -endfunction - -function! s:environment() - if exists('$RAILS_ENV') - return $RAILS_ENV - else - return "development" - endif -endfunction - -function! s:Complete_environments(...) - return s:completion_filter(rails#app().environments(),a:0 ? a:1 : "") -endfunction - -function! s:warn(str) - echohl WarningMsg - echomsg a:str - echohl None - " Sometimes required to flush output - echo "" - let v:warningmsg = a:str -endfunction - -function! s:error(str) - echohl ErrorMsg - echomsg a:str - echohl None - let v:errmsg = a:str -endfunction - -function! s:debug(str) - if exists("g:rails_debug") && g:rails_debug - echohl Debug - echomsg a:str - echohl None - endif -endfunction - -function! s:buffer_getvar(varname) dict abort - return getbufvar(self.number(),a:varname) -endfunction - -function! s:buffer_setvar(varname, val) dict abort - return setbufvar(self.number(),a:varname,a:val) -endfunction - -call s:add_methods('buffer',['getvar','setvar']) - -" }}}1 -" "Public" Interface {{{1 - -" RailsRoot() is the only official public function - -function! rails#underscore(str) - let str = s:gsub(a:str,'::','/') - let str = s:gsub(str,'(\u+)(\u\l)','\1_\2') - let str = s:gsub(str,'(\l|\d)(\u)','\1_\2') - let str = tolower(str) - return str -endfunction - -function! rails#camelize(str) - let str = s:gsub(a:str,'/(.=)','::\u\1') - let str = s:gsub(str,'%([_-]|<)(.)','\u\1') - return str -endfunction - -function! rails#singularize(word) - " Probably not worth it to be as comprehensive as Rails but we can - " still hit the common cases. - let word = a:word - if word =~? '\.js$' || word == '' - return word - endif - let word = s:sub(word,'eople$','ersons') - let word = s:sub(word,'%([Mm]ov|[aeio])@ 0 && getbufvar(nr,'rails_file_type') != '' - return getbufvar(nr,'rails_file_type') - elseif f =~ '_controller\.rb$' || f =~ '\' - let r = "controller-api" - else - let r = "controller" - endif - elseif f =~ '_api\.rb' - let r = "api" - elseif f =~ '\') - if class == "ActiveResource::Base" - let class = "ares" - let r = "model-ares" - elseif class == 'ActionMailer::Base' - let r = "mailer" - elseif class != '' - let class = tolower(s:gsub(class,'[^A-Z]','')) - let r = "model-".class - elseif f =~ '_mailer\.rb$' - let r = "mailer" - elseif top =~ '\<\%(validates_\w\+_of\|set_\%(table_name\|primary_key\)\|has_one\|has_many\|belongs_to\)\>' - let r = "model-arb" - else - let r = "model" - endif - elseif f =~ '\.*\.' - let r = "view-layout-" . e - elseif f =~ '\<\%(app/views\|components\)/.*/_\k\+\.\k\+\%(\.\k\+\)\=$' - let r = "view-partial-" . e - elseif f =~ '\.*\.' || f =~ '\' - if e == "yml" - let r = "fixtures-yaml" - else - let r = "fixtures" . (e == "" ? "" : "-" . e) - endif - elseif f =~ '\' - let r = "db-migration" - elseif f=~ '\.*\.rb$' - let r = "config-routes" - elseif f =~ '\' - let cmd = 'script/rails '.a:cmd - else - let cmd = 'script/'.a:cmd - endif - return self.ruby_shell_command(cmd) -endfunction - -function! s:app_background_script_command(cmd) dict abort - let cmd = s:esccmd(self.script_shell_command(a:cmd)) - if has_key(self,'options') && has_key(self.options,'gnu_screen') - let screen = self.options.gnu_screen - else - let screen = g:rails_gnu_screen - endif - if has("gui_win32") - if &shellcmdflag == "-c" && ($PATH . &shell) =~? 'cygwin' - silent exe "!cygstart -d ".s:rquote(self.path())." ruby ".a:cmd - else - exe "!start ".cmd - endif - elseif exists("$STY") && !has("gui_running") && screen && executable("screen") - silent exe "!screen -ln -fn -t ".s:sub(s:sub(a:cmd,'\s.*',''),'^%(script|-rcommand)/','rails-').' '.cmd - elseif exists("$TMUX") && !has("gui_running") && screen && executable("tmux") - silent exe '!tmux new-window -d -n "'.s:sub(s:sub(a:cmd,'\s.*',''),'^%(script|-rcommand)/','rails-').'" "'.cmd.'"' - else - exe "!".cmd - endif - return v:shell_error -endfunction - -function! s:app_execute_script_command(cmd) dict abort - exe '!'.s:esccmd(self.script_shell_command(a:cmd)) - return v:shell_error -endfunction - -function! s:app_lightweight_ruby_eval(ruby,...) dict abort - let def = a:0 ? a:1 : "" - if !executable("ruby") - return def - endif - let args = '-e '.s:rquote('begin; require %{rubygems}; rescue LoadError; end; begin; require %{active_support}; rescue LoadError; end; '.a:ruby) - let cmd = self.ruby_shell_command(args) - " If the shell is messed up, this command could cause an error message - silent! let results = system(cmd) - return v:shell_error == 0 ? results : def -endfunction - -function! s:app_eval(ruby,...) dict abort - let def = a:0 ? a:1 : "" - if !executable("ruby") - return def - endif - let args = "-r./config/boot -r ".s:rquote(self.path("config/environment"))." -e ".s:rquote(a:ruby) - let cmd = self.ruby_shell_command(args) - " If the shell is messed up, this command could cause an error message - silent! let results = system(cmd) - return v:shell_error == 0 ? results : def -endfunction - -call s:add_methods('app', ['ruby_shell_command','script_shell_command','execute_script_command','background_script_command','lightweight_ruby_eval','eval']) - -" }}}1 -" Commands {{{1 - -function! s:prephelp() - let fn = fnamemodify(s:file,':h:h').'/doc/' - if filereadable(fn.'rails.txt') - if !filereadable(fn.'tags') || getftime(fn.'tags') <= getftime(fn.'rails.txt') - silent! helptags `=fn` - endif - endif -endfunction - -function! RailsHelpCommand(...) - call s:prephelp() - let topic = a:0 ? a:1 : "" - if topic == "" || topic == "-" - return "help rails" - elseif topic =~ '^g:' - return "help ".topic - elseif topic =~ '^-' - return "help rails".topic - else - return "help rails-".topic - endif -endfunction - -function! s:BufCommands() - call s:BufFinderCommands() - call s:BufNavCommands() - call s:BufScriptWrappers() - command! -buffer -bar -nargs=? -bang -count -complete=customlist,s:Complete_rake Rake :call s:Rake(0,! && ? -1 : ,) - command! -buffer -bar -nargs=? -bang -range -complete=customlist,s:Complete_preview Rpreview :call s:Preview(0,,) - command! -buffer -bar -nargs=? -bang -complete=customlist,s:Complete_environments Rlog :call s:Log(0,) - command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_set Rset :call s:Set(0,) - command! -buffer -bar -nargs=0 Rtags :call rails#app().tags_command() - " Embedding all this logic directly into the command makes the error - " messages more concise. - command! -buffer -bar -nargs=? -bang Rdoc : - \ if 0 || =~ "^\\([:'-]\\|g:\\)" | - \ exe RailsHelpCommand() | - \ else | call s:Doc(0,) | endif - command! -buffer -bar -nargs=0 -bang Rrefresh :if 0|unlet! g:autoloaded_rails|source `=s:file`|endif|call s:Refresh(0) - if exists(":NERDTree") - command! -buffer -bar -nargs=? -complete=customlist,s:Complete_cd Rtree :NERDTree `=rails#app().path()` - endif - if exists("g:loaded_dbext") - command! -buffer -bar -nargs=? -complete=customlist,s:Complete_environments Rdbext :call s:BufDatabase(2,)|let b:dbext_buffer_defaulted = 1 - endif - let ext = expand("%:e") - if ext =~ s:viewspattern() - " TODO: complete controller names with trailing slashes here - command! -buffer -bar -bang -nargs=? -range -complete=customlist,s:controllerList Rextract :,call s:Extract(0,) - endif - if RailsFilePath() =~ '\0) - endif -endfunction - -function! s:Doc(bang, string) - if a:string != "" - if exists("g:rails_search_url") - let query = substitute(a:string,'[^A-Za-z0-9_.~-]','\="%".printf("%02X",char2nr(submatch(0)))','g') - let url = printf(g:rails_search_url, query) - else - return s:error("specify a g:rails_search_url with %s for a query placeholder") - endif - elseif isdirectory(rails#app().path("doc/api/classes")) - let url = rails#app().path("/doc/api/index.html") - elseif s:getpidfor("0.0.0.0","8808") > 0 - let url = "http://localhost:8808" - else - let url = "http://api.rubyonrails.org" - endif - call s:initOpenURL() - if exists(":OpenURL") - exe "OpenURL ".s:escarg(url) - else - return s:error("No :OpenURL command found") - endif -endfunction - -function! s:Log(bang,arg) - if a:arg == "" - let lf = "log/".s:environment().".log" - else - let lf = "log/".a:arg.".log" - endif - let size = getfsize(rails#app().path(lf)) - if size >= 1048576 - call s:warn("Log file is ".((size+512)/1024)."KB. Consider :Rake log:clear") - endif - if a:bang - exe "cgetfile ".lf - clast - else - if exists(":Tail") - Tail `=rails#app().path(lf)` - else - pedit `=rails#app().path(lf)` - endif - endif -endfunction - -function! rails#new_app_command(bang,...) - if a:0 == 0 - let msg = "rails.vim ".g:autoloaded_rails - if a:bang && exists('b:rails_root') && rails#buffer().type_name() == '' - echo msg." (Rails)" - elseif a:bang && exists('b:rails_root') - echo msg." (Rails-".rails#buffer().type_name().")" - elseif a:bang - echo msg - else - !rails - endif - return - endif - let args = map(copy(a:000),'expand(v:val)') - if a:bang - let args = ['--force'] + args - endif - exe '!rails '.join(map(copy(args),'s:rquote(v:val)'),' ') - for dir in args - if dir !~# '^-' && filereadable(dir.'/'.g:rails_default_file) - edit `=dir.'/'.g:rails_default_file` - return - endif - endfor -endfunction - -function! s:app_tags_command() dict - if exists("g:Tlist_Ctags_Cmd") - let cmd = g:Tlist_Ctags_Cmd - elseif executable("exuberant-ctags") - let cmd = "exuberant-ctags" - elseif executable("ctags-exuberant") - let cmd = "ctags-exuberant" - elseif executable("ctags") - let cmd = "ctags" - elseif executable("ctags.exe") - let cmd = "ctags.exe" - else - return s:error("ctags not found") - endif - exe '!'.cmd.' -f '.s:escarg(self.path("tmp/tags")).' -R --langmap="ruby:+.rake.builder.rjs" '.g:rails_ctags_arguments.' '.s:escarg(self.path()) -endfunction - -call s:add_methods('app',['tags_command']) - -function! s:Refresh(bang) - if exists("g:rubycomplete_rails") && g:rubycomplete_rails && has("ruby") && exists('g:rubycomplete_completions') - silent! ruby ActiveRecord::Base.reset_subclasses if defined?(ActiveRecord) - silent! ruby if defined?(ActiveSupport::Dependencies); ActiveSupport::Dependencies.clear; elsif defined?(Dependencies); Dependencies.clear; end - if a:bang - silent! ruby ActiveRecord::Base.clear_reloadable_connections! if defined?(ActiveRecord) - endif - endif - call rails#app().cache.clear() - silent doautocmd User BufLeaveRails - if a:bang - for key in keys(s:apps) - if type(s:apps[key]) == type({}) - call s:apps[key].cache.clear() - endif - call extend(s:apps[key],filter(copy(s:app_prototype),'type(v:val) == type(function("tr"))'),'force') - endfor - endif - let i = 1 - let max = bufnr('$') - while i <= max - let rr = getbufvar(i,"rails_root") - if rr != "" - call setbufvar(i,"rails_refresh",1) - endif - let i += 1 - endwhile - silent doautocmd User BufEnterRails -endfunction - -function! s:RefreshBuffer() - if exists("b:rails_refresh") && b:rails_refresh - let oldroot = b:rails_root - unlet! b:rails_root - let b:rails_refresh = 0 - call RailsBufInit(oldroot) - unlet! b:rails_refresh - endif -endfunction - -" }}}1 -" Rake {{{1 - -function! s:app_rake_tasks() dict - if self.cache.needs('rake_tasks') - call s:push_chdir() - try - let lines = split(system("rake -T"),"\n") - finally - call s:pop_command() - endtry - if v:shell_error != 0 - return [] - endif - call map(lines,'matchstr(v:val,"^rake\\s\\+\\zs\\S*")') - call filter(lines,'v:val != ""') - call self.cache.set('rake_tasks',lines) - endif - return self.cache.get('rake_tasks') -endfunction - -call s:add_methods('app', ['rake_tasks']) - -let s:efm_backtrace='%D(in\ %f),' - \.'%\\s%#from\ %f:%l:%m,' - \.'%\\s%#from\ %f:%l:,' - \.'%\\s#{RAILS_ROOT}/%f:%l:\ %#%m,' - \.'%\\s%##\ %f:%l:%m,' - \.'%\\s%##\ %f:%l,' - \.'%\\s%#[%f:%l:\ %#%m,' - \.'%\\s%#%f:%l:\ %#%m,' - \.'%\\s%#%f:%l:,' - \.'%m\ [%f:%l]:' - -function! s:makewithruby(arg,bang,...) - let old_make = &makeprg - try - let &l:makeprg = rails#app().ruby_shell_command(a:arg) - exe 'make'.(a:bang ? '!' : '') - if !a:bang - cwindow - endif - finally - let &l:makeprg = old_make - endtry -endfunction - -function! s:Rake(bang,lnum,arg) - let self = rails#app() - let lnum = a:lnum < 0 ? 0 : a:lnum - let old_makeprg = &l:makeprg - let old_errorformat = &l:errorformat - try - if exists('b:bundler_root') && b:bundler_root ==# rails#app().path() - let &l:makeprg = 'bundle exec rake' - else - let &l:makeprg = 'rake' - endif - let &l:errorformat = s:efm_backtrace - let arg = a:arg - if &filetype == "ruby" && arg == '' && g:rails_modelines - let mnum = s:lastmethodline(lnum) - let str = getline(mnum)."\n".getline(mnum+1)."\n".getline(mnum+2)."\n" - let pat = '\s\+\zs.\{-\}\ze\%(\n\|\s\s\|#{\@!\|$\)' - let mat = matchstr(str,'#\s*rake'.pat) - let mat = s:sub(mat,'\s+$','') - if mat != "" - let arg = mat - endif - endif - if arg == '' - let opt = s:getopt('task','bl') - if opt != '' - let arg = opt - else - let arg = rails#buffer().default_rake_task(lnum) - endif - endif - if !has_key(self,'options') | let self.options = {} | endif - if arg == '-' - let arg = get(self.options,'last_rake_task','') - endif - let self.options['last_rake_task'] = arg - let withrubyargs = '-r ./config/boot -r '.s:rquote(self.path('config/environment')).' -e "puts \%((in \#{Dir.getwd}))" ' - if arg =~# '^notes\>' - let &l:errorformat = '%-P%f:,\ \ *\ [%*[\ ]%l]\ [%t%*[^]]] %m,\ \ *\ [%*[\ ]%l] %m,%-Q' - " %D to chdir is apparently incompatible with %P multiline messages - call s:push_chdir(1) - exe 'make! '.arg - call s:pop_command() - if !a:bang - cwindow - endif - elseif arg =~# '^\%(stats\|routes\|secret\|time:zones\|db:\%(charset\|collation\|fixtures:identify\>.*\|migrate:status\|version\)\)\%([: ]\|$\)' - let &l:errorformat = '%D(in\ %f),%+G%.%#' - exe 'make! '.arg - if !a:bang - copen - endif - elseif arg =~ '^preview\>' - exe (lnum == 0 ? '' : lnum).'R'.s:gsub(arg,':','/') - elseif arg =~ '^runner:' - let arg = s:sub(arg,'^runner:','') - let root = matchstr(arg,'%\%(:\w\)*') - let file = expand(root).matchstr(arg,'%\%(:\w\)*\zs.*') - if file =~ '#.*$' - let extra = " -- -n ".matchstr(file,'#\zs.*') - let file = s:sub(file,'#.*','') - else - let extra = '' - endif - if self.has_file(file) || self.has_file(file.'.rb') - call s:makewithruby(withrubyargs.'-r"'.file.'"'.extra,a:bang,file !~# '_\%(spec\|test\)\%(\.rb\)\=$') - else - call s:makewithruby(withrubyargs.'-e '.s:esccmd(s:rquote(arg)),a:bang) - endif - elseif arg == 'run' || arg == 'runner' - call s:makewithruby(withrubyargs.'-r"'.RailsFilePath().'"',a:bang,RailsFilePath() !~# '_\%(spec\|test\)\%(\.rb\)\=$') - elseif arg =~ '^run:' - let arg = s:sub(arg,'^run:','') - let arg = s:sub(arg,'^\%:h',expand('%:h')) - let arg = s:sub(arg,'^%(\%|$|#@=)',expand('%')) - let arg = s:sub(arg,'#(\w+[?!=]=)$',' -- -n\1') - call s:makewithruby(withrubyargs.'-r'.arg,a:bang,arg !~# '_\%(spec\|test\)\.rb$') - else - exe 'make! '.arg - if !a:bang - cwindow - endif - endif - finally - let &l:errorformat = old_errorformat - let &l:makeprg = old_makeprg - endtry -endfunction - -function! s:readable_default_rake_task(lnum) dict abort - let app = self.app() - let lnum = a:lnum < 0 ? 0 : a:lnum - if self.getvar('&buftype') == 'quickfix' - return '-' - elseif self.getline(lnum) =~# '# rake ' - return matchstr(self.getline(lnum),'\C# rake \zs.*') - elseif self.getline(self.last_method_line(lnum)-1) =~# '# rake ' - return matchstr(self.getline(self.last_method_line(lnum)-1),'\C# rake \zs.*') - elseif self.getline(self.last_method_line(lnum)) =~# '# rake ' - return matchstr(self.getline(self.last_method_line(lnum)),'\C# rake \zs.*') - elseif self.getline(1) =~# '# rake ' && !lnum - return matchstr(self.getline(1),'\C# rake \zs.*') - elseif self.type_name('config-routes') - return 'routes' - elseif self.type_name('fixtures-yaml') && lnum - return "db:fixtures:identify LABEL=".self.last_method(lnum) - elseif self.type_name('fixtures') && lnum == 0 - return "db:fixtures:load FIXTURES=".s:sub(fnamemodify(self.name(),':r'),'^.{-}/fixtures/','') - elseif self.type_name('task') - let mnum = self.last_method_line(lnum) - let line = getline(mnum) - " We can't grab the namespace so only run tasks at the start of the line - if line =~# '^\%(task\|file\)\>' - return self.last_method(a:lnum) - else - return matchstr(self.getline(1),'\C# rake \zs.*') - endif - elseif self.type_name('spec') - if self.name() =~# '\ 0 - return 'spec SPEC="'.self.path().'":'.lnum - else - return 'spec SPEC="'.self.path().'"' - endif - elseif self.type_name('test') - let meth = self.last_method(lnum) - if meth =~ '^test_' - let call = " -n".meth."" - else - let call = "" - endif - if self.type_name('test-unit','test-functional','test-integration') - return s:sub(s:gsub(self.type_name(),'-',':'),'unit$|functional$','&s').' TEST="'.self.path().'"'.s:sub(call,'^ ',' TESTOPTS=') - elseif self.name() =~# '\ 0 - return 'cucumber FEATURE="'.self.path().'":'.lnum - else - return 'cucumber FEATURE="'.self.path().'"' - endif - elseif self.type_name('cucumber') - return 'cucumber' - else - return '' - endif -endfunction - -function! s:Complete_rake(A,L,P) - return s:completion_filter(rails#app().rake_tasks(),a:A) -endfunction - -call s:add_methods('readable',['default_rake_task']) - -" }}}1 -" Preview {{{1 - -function! s:initOpenURL() - if !exists(":OpenURL") - if has("gui_mac") || has("gui_macvim") || exists("$SECURITYSESSIONID") - command -bar -nargs=1 OpenURL :!open - elseif has("gui_win32") - command -bar -nargs=1 OpenURL :!start cmd /cstart /b - elseif executable("sensible-browser") - command -bar -nargs=1 OpenURL :!sensible-browser - endif - endif -endfunction - -function! s:scanlineforuris(line) - let url = matchstr(a:line,"\\v\\C%(%(GET|PUT|POST|DELETE)\\s+|\\w+://[^/]*)/[^ \n\r\t<>\"]*[^] .,;\n\r\t<>\":]") - if url =~ '\C^\u\+\s\+' - let method = matchstr(url,'^\u\+') - let url = matchstr(url,'\s\+\zs.*') - if method !=? "GET" - let url .= (url =~ '?' ? '&' : '?') . '_method='.tolower(method) - endif - endif - if url != "" - return [url] - else - return [] - endif -endfunction - -function! s:readable_preview_urls(lnum) dict abort - let urls = [] - let start = self.last_method_line(a:lnum) - 1 - while start > 0 && self.getline(start) =~ '^\s*\%(\%(-\=\|<%\)#.*\)\=$' - let urls = s:scanlineforuris(self.getline(start)) + urls - let start -= 1 - endwhile - let start = 1 - while start < self.line_count() && self.getline(start) =~ '^\s*\%(\%(-\=\|<%\)#.*\)\=$' - let urls += s:scanlineforuris(self.getline(start)) - let start += 1 - endwhile - if has_key(self,'getvar') && self.getvar('rails_preview') != '' - let url += [self.getvar('rails_preview')] - end - if self.name() =~ '^public/stylesheets/sass/' - let urls = urls + [s:sub(s:sub(self.name(),'^public/stylesheets/sass/','/stylesheets/'),'\.s[ac]ss$','.css')] - elseif self.name() =~ '^public/' - let urls = urls + [s:sub(self.name(),'^public','')] - elseif self.name() =~ '^app/assets/stylesheets/' - let urls = urls + ['/assets/application.css'] - elseif self.name() =~ '^app/assets/javascripts/' - let urls = urls + ['/assets/application.js'] - elseif self.name() =~ '^app/stylesheets/' - let urls = urls + [s:sub(s:sub(self.name(),'^app/stylesheets/','/stylesheets/'),'\.less$','.css')] - elseif self.name() =~ '^app/scripts/' - let urls = urls + [s:sub(s:sub(self.name(),'^app/scripts/','/javascripts/'),'\.coffee$','.js')] - elseif self.controller_name() != '' && self.controller_name() != 'application' - if self.type_name('controller') && self.last_method(a:lnum) != '' - let urls += ['/'.self.controller_name().'/'.self.last_method(a:lnum).'/'] - elseif self.type_name('controller','view-layout','view-partial') - let urls += ['/'.self.controller_name().'/'] - elseif self.type_name('view') - let urls += ['/'.s:controller().'/'.fnamemodify(self.name(),':t:r:r').'/'] - endif - endif - return urls -endfunction - -call s:add_methods('readable',['preview_urls']) - -function! s:Preview(bang,lnum,arg) - let root = s:getopt("root_url") - if root == '' - let root = s:getopt("url") - endif - let root = s:sub(root,'/$','') - if a:arg =~ '://' - let uri = a:arg - elseif a:arg != '' - let uri = root.'/'.s:sub(a:arg,'^/','') - else - let uri = get(rails#buffer().preview_urls(a:lnum),0,'') - let uri = root.'/'.s:sub(s:sub(uri,'^/',''),'/$','') - endif - call s:initOpenURL() - if exists(':OpenURL') && !a:bang - exe 'OpenURL '.uri - else - " Work around bug where URLs ending in / get handled as FTP - let url = uri.(uri =~ '/$' ? '?' : '') - silent exe 'pedit '.url - wincmd w - if &filetype == '' - if uri =~ '\.css$' - setlocal filetype=css - elseif uri =~ '\.js$' - setlocal filetype=javascript - elseif getline(1) =~ '^\s*<' - setlocal filetype=xhtml - endif - endif - call RailsBufInit(rails#app().path()) - map q :bwipe - wincmd p - if !a:bang - call s:warn("Define a :OpenURL command to use a browser") - endif - endif -endfunction - -function! s:Complete_preview(A,L,P) - return rails#buffer().preview_urls(a:L =~ '^\d' ? matchstr(a:L,'^\d\+') : line('.')) -endfunction - -" }}}1 -" Script Wrappers {{{1 - -function! s:BufScriptWrappers() - command! -buffer -bar -nargs=* -complete=customlist,s:Complete_script Rscript :call rails#app().script_command(0,) - command! -buffer -bar -nargs=* -complete=customlist,s:Complete_generate Rgenerate :call rails#app().generate_command(0,) - command! -buffer -bar -nargs=* -complete=customlist,s:Complete_destroy Rdestroy :call rails#app().destroy_command(0,) - command! -buffer -bar -nargs=? -bang -complete=customlist,s:Complete_server Rserver :call rails#app().server_command(0,) - command! -buffer -bang -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rrunner :call rails#app().runner_command(0 ? -2 : (==?:-1),) - command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rp :call rails#app().runner_command(==?:-1,'p begin '..' end') - command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Rpp :call rails#app().runner_command(==?:-1,'require %{pp}; pp begin '..' end') - command! -buffer -nargs=1 -range=0 -complete=customlist,s:Complete_ruby Ry :call rails#app().runner_command(==?:-1,'y begin '..' end') -endfunction - -function! s:app_generators() dict - if self.cache.needs('generators') - let generators = self.relglob("vendor/plugins/","*/generators/*") - let generators += self.relglob("","lib/generators/*") - call filter(generators,'v:val =~ "/$"') - let generators += split(glob(expand("~/.rails/generators")."/*"),"\n") - call map(generators,'s:sub(v:val,"^.*[\\\\/]generators[\\\\/]\\ze.","")') - call map(generators,'s:sub(v:val,"[\\\\/]$","")') - call self.cache.set('generators',generators) - endif - return sort(split(g:rails_generators,"\n") + self.cache.get('generators')) -endfunction - -function! s:app_script_command(bang,...) dict - let str = "" - let cmd = a:0 ? a:1 : "console" - let c = 2 - while c <= a:0 - let str .= " " . s:rquote(a:{c}) - let c += 1 - endwhile - if cmd ==# "plugin" - call self.cache.clear('generators') - endif - if a:bang || cmd =~# 'console' - return self.background_script_command(cmd.str) - else - return self.execute_script_command(cmd.str) - endif -endfunction - -function! s:app_runner_command(count,args) dict - if a:count == -2 - return self.script_command(a:bang,"runner",a:args) - else - let str = self.ruby_shell_command('-r./config/boot -e "require '."'commands/runner'".'" '.s:rquote(a:args)) - let res = s:sub(system(str),'\n$','') - if a:count < 0 - echo res - else - exe a:count.'put =res' - endif - endif -endfunction - -function! s:getpidfor(bind,port) - if has("win32") || has("win64") - let netstat = system("netstat -anop tcp") - let pid = matchstr(netstat,'\<'.a:bind.':'.a:port.'\>.\{-\}LISTENING\s\+\zs\d\+') - elseif executable('lsof') - let pid = system("lsof -i 4tcp@".a:bind.':'.a:port."|grep LISTEN|awk '{print $2}'") - let pid = s:sub(pid,'\n','') - else - let pid = "" - endif - return pid -endfunction - -function! s:app_server_command(bang,arg) dict - let port = matchstr(a:arg,'\%(-p\|--port=\=\)\s*\zs\d\+') - if port == '' - let port = "3000" - endif - " TODO: Extract bind argument - let bind = "0.0.0.0" - if a:bang && executable("ruby") - let pid = s:getpidfor(bind,port) - if pid =~ '^\d\+$' - echo "Killing server with pid ".pid - if !has("win32") - call system("ruby -e 'Process.kill(:TERM,".pid.")'") - sleep 100m - endif - call system("ruby -e 'Process.kill(9,".pid.")'") - sleep 100m - endif - if a:arg == "-" - return - endif - endif - if has_key(self,'options') && has_key(self.options,'gnu_screen') - let screen = self.options.gnu_screen - else - let screen = g:rails_gnu_screen - endif - if has("win32") || has("win64") || (exists("$STY") && !has("gui_running") && screen && executable("screen")) || (exists("$TMUX") && !has("gui_running") && screen && executable("tmux")) - call self.background_script_command('server '.a:arg) - else - " --daemon would be more descriptive but lighttpd does not support it - call self.execute_script_command('server '.a:arg." -d") - endif - call s:setopt('a:root_url','http://'.(bind=='0.0.0.0'?'localhost': bind).':'.port.'/') -endfunction - -function! s:app_destroy_command(bang,...) dict - if a:0 == 0 - return self.execute_script_command('destroy') - elseif a:0 == 1 - return self.execute_script_command('destroy '.s:rquote(a:1)) - endif - let str = "" - let c = 1 - while c <= a:0 - let str .= " " . s:rquote(a:{c}) - let c += 1 - endwhile - call self.execute_script_command('destroy'.str) - call self.cache.clear('user_classes') -endfunction - -function! s:app_generate_command(bang,...) dict - if a:0 == 0 - return self.execute_script_command('generate') - elseif a:0 == 1 - return self.execute_script_command('generate '.s:rquote(a:1)) - endif - let cmd = join(map(copy(a:000),'s:rquote(v:val)'),' ') - if cmd !~ '-p\>' && cmd !~ '--pretend\>' - let execstr = self.script_shell_command('generate '.cmd.' -p -f') - let res = system(execstr) - let g:res = res - let junk = '\%(\e\[[0-9;]*m\)\=' - let file = matchstr(res,junk.'\s\+\%(create\|force\)'.junk.'\s\+\zs\f\+\.rb\ze\n') - if file == "" - let file = matchstr(res,junk.'\s\+\%(identical\)'.junk.'\s\+\zs\f\+\.rb\ze\n') - endif - else - let file = "" - endif - if !self.execute_script_command('generate '.cmd) && file != '' - call self.cache.clear('user_classes') - call self.cache.clear('features') - if file =~ '^db/migrate/\d\d\d\d' - let file = get(self.relglob('',s:sub(file,'\d+','[0-9]*[0-9]')),-1,file) - endif - edit `=self.path(file)` - endif -endfunction - -call s:add_methods('app', ['generators','script_command','runner_command','server_command','destroy_command','generate_command']) - -function! s:Complete_script(ArgLead,CmdLine,P) - let cmd = s:sub(a:CmdLine,'^\u\w*\s+','') - if cmd !~ '^[ A-Za-z0-9_=:-]*$' - return [] - elseif cmd =~# '^\w*$' - return s:completion_filter(rails#app().relglob("script/","**/*"),a:ArgLead) - elseif cmd =~# '^\%(plugin\)\s\+'.a:ArgLead.'$' - return s:completion_filter(["discover","list","install","update","remove","source","unsource","sources"],a:ArgLead) - elseif cmd =~# '\%(plugin\)\s\+\%(install\|remove\)\s\+'.a:ArgLead.'$' || cmd =~ '\%(generate\|destroy\)\s\+plugin\s\+'.a:ArgLead.'$' - return s:pluginList(a:ArgLead,a:CmdLine,a:P) - elseif cmd =~# '^\%(generate\|destroy\)\s\+'.a:ArgLead.'$' - return s:completion_filter(rails#app().generators(),a:ArgLead) - elseif cmd =~# '^\%(generate\|destroy\)\s\+\w\+\s\+'.a:ArgLead.'$' - let target = matchstr(cmd,'^\w\+\s\+\%(\w\+:\)\=\zs\w\+\ze\s\+') - if target =~# '^\w*controller$' - return filter(s:controllerList(a:ArgLead,"",""),'v:val !=# "application"') - elseif target ==# 'generator' - return s:completion_filter(map(rails#app().relglob('lib/generators/','*'),'s:sub(v:val,"/$","")')) - elseif target ==# 'helper' - return s:helperList(a:ArgLead,"","") - elseif target ==# 'integration_test' || target ==# 'integration_spec' || target ==# 'feature' - return s:integrationtestList(a:ArgLead,"","") - elseif target ==# 'metal' - return s:metalList(a:ArgLead,"","") - elseif target ==# 'migration' || target ==# 'session_migration' - return s:migrationList(a:ArgLead,"","") - elseif target =~# '^\w*\%(model\|resource\)$' || target =~# '\w*scaffold\%(_controller\)\=$' || target ==# 'mailer' - return s:modelList(a:ArgLead,"","") - elseif target ==# 'observer' - let observers = s:observerList("","","") - let models = s:modelList("","","") - if cmd =~# '^destroy\>' - let models = [] - endif - call filter(models,'index(observers,v:val) < 0') - return s:completion_filter(observers + models,a:ArgLead) - else - return [] - endif - elseif cmd =~# '^\%(generate\|destroy\)\s\+scaffold\s\+\w\+\s\+'.a:ArgLead.'$' - return filter(s:controllerList(a:ArgLead,"",""),'v:val !=# "application"') - return s:completion_filter(rails#app().environments()) - elseif cmd =~# '^\%(console\)\s\+\(--\=\w\+\s\+\)\='.a:ArgLead."$" - return s:completion_filter(rails#app().environments()+["-s","--sandbox"],a:ArgLead) - elseif cmd =~# '^\%(server\)\s\+.*-e\s\+'.a:ArgLead."$" - return s:completion_filter(rails#app().environments(),a:ArgLead) - elseif cmd =~# '^\%(server\)\s\+' - if a:ArgLead =~# '^--environment=' - return s:completion_filter(map(copy(rails#app().environments()),'"--environment=".v:val'),a:ArgLead) - else - return filter(["-p","-b","-e","-m","-d","-u","-c","-h","--port=","--binding=","--environment=","--mime-types=","--daemon","--debugger","--charset=","--help"],'s:startswith(v:val,a:ArgLead)') - endif - endif - return "" -endfunction - -function! s:CustomComplete(A,L,P,cmd) - let L = "Rscript ".a:cmd." ".s:sub(a:L,'^\h\w*\s+','') - let P = a:P - strlen(a:L) + strlen(L) - return s:Complete_script(a:A,L,P) -endfunction - -function! s:Complete_server(A,L,P) - return s:CustomComplete(a:A,a:L,a:P,"server") -endfunction - -function! s:Complete_console(A,L,P) - return s:CustomComplete(a:A,a:L,a:P,"console") -endfunction - -function! s:Complete_generate(A,L,P) - return s:CustomComplete(a:A,a:L,a:P,"generate") -endfunction - -function! s:Complete_destroy(A,L,P) - return s:CustomComplete(a:A,a:L,a:P,"destroy") -endfunction - -function! s:Complete_ruby(A,L,P) - return s:completion_filter(rails#app().user_classes()+["ActiveRecord::Base"],a:A) -endfunction - -" }}}1 -" Navigation {{{1 - -function! s:BufNavCommands() - command! -buffer -bar -nargs=? -complete=customlist,s:Complete_cd Rcd :cd `=rails#app().path()` - command! -buffer -bar -nargs=? -complete=customlist,s:Complete_cd Rlcd :lcd `=rails#app().path()` - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find Rfind :call s:warn( 'Rfind has been deprecated in favor of :1R or :find' )|call s:Find(,'' ,) - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find REfind :call s:warn('REfind has been deprecated in favor of :1RE or :find')|call s:Find(,'E',) - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find RSfind :call s:warn('RSfind has been deprecated in favor of :1RS or :find')|call s:Find(,'S',) - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find RVfind :call s:warn('RVfind has been deprecated in favor of :1RV or :find')|call s:Find(,'V',) - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find RTfind :call s:warn('RTfind has been deprecated in favor of :1RT or :find')|call s:Find(,'T',) - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find Rsfind :call s:warn('Rsfind has been deprecated in favor of :1RS or :sfind')|RSfind - command! -buffer -bar -nargs=* -count=1 -complete=customlist,s:Complete_find Rtabfind :call s:warn('Rtabfind has been deprecated in favor of :1RT or :tabfind')|RTfind - command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit Redit :call s:warn( 'Redit has been deprecated in favor of :R')|call s:Edit(,'' ,) - command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit REedit :call s:warn('REedit has been deprecated in favor of :RE')|call s:Edit(,'E',) - command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit RSedit :call s:warn('RSedit has been deprecated in favor of :RS')|call s:Edit(,'S',) - command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit RVedit :call s:warn('RVedit has been deprecated in favor of :RV')|call s:Edit(,'V',) - command! -buffer -bar -nargs=* -bang -complete=customlist,s:Complete_edit RTedit :call s:warn('RTedit has been deprecated in favor of :RT')|call s:Edit(,'T',) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_edit RDedit :call s:warn('RDedit has been deprecated in favor of :RD')|call s:Edit(,'D',) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related A :call s:Alternate('', ,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AE :call s:Alternate('E',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AS :call s:Alternate('S',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AV :call s:Alternate('V',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AT :call s:Alternate('T',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AD :call s:Alternate('D',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related AN :call s:Related('' ,,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related R :call s:Related('' ,,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RE :call s:Related('E',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RS :call s:Related('S',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RV :call s:Related('V',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RT :call s:Related('T',,,,) - command! -buffer -bar -nargs=* -range=0 -complete=customlist,s:Complete_related RD :call s:Related('D',,,,) -endfunction - -function! s:djump(def) - let def = s:sub(a:def,'^[#:]','') - if def =~ '^\d\+$' - exe def - elseif def =~ '^!' - if expand('%') !~ '://' && !isdirectory(expand('%:p:h')) - call mkdir(expand('%:p:h'),'p') - endif - elseif def != '' - let ext = matchstr(def,'\.\zs.*') - let def = matchstr(def,'[^.]*') - let v:errmsg = '' - silent! exe "djump ".def - if ext != '' && (v:errmsg == '' || v:errmsg =~ '^E387') - let rpat = '\C^\s*\%(mail\>.*\|respond_to\)\s*\%(\ 0 - let variable = matchstr(getline(rline),rpat) - let success = search('\C^\s*'.variable.'\s*\.\s*\zs'.ext.'\>','',end) - if !success - silent! exe "djump ".def - endif - endif - endif - endif -endfunction - -function! s:Find(count,cmd,...) - let str = "" - if a:0 - let i = 1 - while i < a:0 - let str .= s:escarg(a:{i}) . " " - let i += 1 - endwhile - let file = a:{i} - let tail = matchstr(file,'[#!].*$\|:\d*\%(:in\>.*\)\=$') - if tail != "" - let file = s:sub(file,'[#!].*$|:\d*%(:in>.*)=$','') - endif - if file != "" - let file = s:RailsIncludefind(file) - endif - else - let file = s:RailsFind() - let tail = "" - endif - call s:findedit((a:count==1?'' : a:count).a:cmd,file.tail,str) -endfunction - -function! s:Edit(count,cmd,...) - if a:0 - let str = "" - let i = 1 - while i < a:0 - let str .= "`=a:".i."` " - let i += 1 - endwhile - let file = a:{i} - call s:findedit(s:editcmdfor(a:cmd),file,str) - else - exe s:editcmdfor(a:cmd) - endif -endfunction - -function! s:fuzzyglob(arg) - return s:gsub(s:gsub(a:arg,'[^/.]','[&]*'),'%(/|^)\.@!|\.','&*') -endfunction - -function! s:Complete_find(ArgLead, CmdLine, CursorPos) - let paths = s:pathsplit(&l:path) - let seen = {} - for path in paths - if s:startswith(path,rails#app().path()) && path !~ '[][*]' - let path = path[strlen(rails#app().path()) + 1 : ] - for file in rails#app().relglob(path == '' ? '' : path.'/',s:fuzzyglob(rails#underscore(a:ArgLead)), a:ArgLead =~# '\u' ? '.rb' : '') - let seen[file] = 1 - endfor - endif - endfor - return s:autocamelize(sort(keys(seen)),a:ArgLead) -endfunction - -function! s:Complete_edit(ArgLead, CmdLine, CursorPos) - return s:completion_filter(rails#app().relglob("",s:fuzzyglob(a:ArgLead)),a:ArgLead) -endfunction - -function! s:Complete_cd(ArgLead, CmdLine, CursorPos) - let all = rails#app().relglob("",a:ArgLead."*") - call filter(all,'v:val =~ "/$"') - return filter(all,'s:startswith(v:val,a:ArgLead)') -endfunction - -function! RailsIncludeexpr() - " Is this foolproof? - if mode() =~ '[iR]' || expand("") != v:fname - return s:RailsIncludefind(v:fname) - else - return s:RailsIncludefind(v:fname,1) - endif -endfunction - -function! s:linepeak() - let line = getline(line(".")) - let line = s:sub(line,'^(.{'.col(".").'}).*','\1') - let line = s:sub(line,'([:"'."'".']|\%[qQ]=[[({<])=\f*$','') - return line -endfunction - -function! s:matchcursor(pat) - let line = getline(".") - let lastend = 0 - while lastend >= 0 - let beg = match(line,'\C'.a:pat,lastend) - let end = matchend(line,'\C'.a:pat,lastend) - if beg < col(".") && end >= col(".") - return matchstr(line,'\C'.a:pat,lastend) - endif - let lastend = end - endwhile - return "" -endfunction - -function! s:findit(pat,repl) - let res = s:matchcursor(a:pat) - if res != "" - return substitute(res,'\C'.a:pat,a:repl,'') - else - return "" - endif -endfunction - -function! s:findamethod(func,repl) - return s:findit('\s*\<\%('.a:func.'\)\s*(\=\s*[@:'."'".'"]\(\f\+\)\>.\=',a:repl) -endfunction - -function! s:findasymbol(sym,repl) - return s:findit('\s*\%(:\%('.a:sym.'\)\s*=>\|\<'.a:sym.':\)\s*(\=\s*[@:'."'".'"]\(\f\+\)\>.\=',a:repl) -endfunction - -function! s:findfromview(func,repl) - " ( ) ( ) ( \1 ) ( ) - return s:findit('\s*\%(<%\)\==\=\s*\<\%('.a:func.'\)\s*(\=\s*[@:'."'".'"]\(\f\+\)\>['."'".'"]\=\s*\%(%>\s*\)\=',a:repl) -endfunction - -function! s:RailsFind() - if filereadable(expand("")) - return expand("") - endif - - " UGH - let buffer = rails#buffer() - let format = s:format('html') - - let res = s:findit('\v\s*.=',expand('%:h').'/\1') - if res != ""|return res.(fnamemodify(res,':e') == '' ? '.rb' : '')|endif - - let res = s:findit('\v['."'".'"]=',expand('%:h').'\1') - if res != ""|return res|endif - - let res = rails#underscore(s:findit('\v\s*<%(include|extend)\(=\s*<([[:alnum:]_:]+)>','\1')) - if res != ""|return res.".rb"|endif - - let res = s:findamethod('require','\1') - if res != ""|return res.(fnamemodify(res,':e') == '' ? '.rb' : '')|endif - - let res = s:findamethod('belongs_to\|has_one\|composed_of\|validates_associated\|scaffold','app/models/\1.rb') - if res != ""|return res|endif - - let res = rails#singularize(s:findamethod('has_many\|has_and_belongs_to_many','app/models/\1')) - if res != ""|return res.".rb"|endif - - let res = rails#singularize(s:findamethod('create_table\|change_table\|drop_table\|add_column\|rename_column\|remove_column\|add_index','app/models/\1')) - if res != ""|return res.".rb"|endif - - let res = rails#singularize(s:findasymbol('through','app/models/\1')) - if res != ""|return res.".rb"|endif - - let res = s:findamethod('fixtures','fixtures/\1') - if res != "" - return RailsFilePath() =~ '\\|\\|,\s*to:\)\s*','app/controllers/\1') - if res =~ '#'|return s:sub(res,'#','_controller.rb#')|endif - - let res = s:findamethod('layout','\=s:findlayout(submatch(1))') - if res != ""|return res|endif - - let res = s:findasymbol('layout','\=s:findlayout(submatch(1))') - if res != ""|return res|endif - - let res = s:findamethod('helper','app/helpers/\1_helper.rb') - if res != ""|return res|endif - - let res = s:findasymbol('controller','app/controllers/\1_controller.rb') - if res != ""|return res|endif - - let res = s:findasymbol('action','\1') - if res != ""|return res|endif - - let res = s:findasymbol('template','app/views/\1') - if res != ""|return res|endif - - let res = s:sub(s:sub(s:findasymbol('partial','\1'),'^/',''),'[^/]+$','_&') - if res != ""|return res."\n".s:findview(res)|endif - - let res = s:sub(s:sub(s:findfromview('render\s*(\=\s*\%(:partial\s\+=>\|partial:\)\s*','\1'),'^/',''),'[^/]+$','_&') - if res != ""|return res."\n".s:findview(res)|endif - - let res = s:findamethod('render\>\s*\%(:\%(template\|action\)\s\+=>\|template:\|action:\)\s*','\1.'.format.'\n\1') - if res != ""|return res|endif - - let res = s:sub(s:findfromview('render','\1'),'^/','') - if buffer.type_name('view') | let res = s:sub(res,'[^/]+$','_&') | endif - if res != ""|return res."\n".s:findview(res)|endif - - let res = s:findamethod('redirect_to\s*(\=\s*\%\(:action\s\+=>\|\','/application') - if res != '' && fnamemodify(res, ':e') == '' " Append the default extension iff the filename doesn't already contains an extension - let res .= '.js' - end - if res != ""|return res|endif - - if buffer.type_name('controller') - let contr = s:controller() - let view = s:findit('\s*\(\=','/\1') - let res = s:findview(contr.'/'.view) - if res != ""|return res|endif - endif - - let old_isfname = &isfname - try - set isfname=@,48-57,/,-,_,:,# - " TODO: grab visual selection in visual mode - let cfile = expand("") - finally - let &isfname = old_isfname - endtry - let res = s:RailsIncludefind(cfile,1) - return res -endfunction - -function! s:app_named_route_file(route) dict - call self.route_names() - if self.cache.has("named_routes") && has_key(self.cache.get("named_routes"),a:route) - return self.cache.get("named_routes")[a:route] - endif - return "" -endfunction - -function! s:app_route_names() dict - if self.cache.needs("named_routes") - let exec = "ActionController::Routing::Routes.named_routes.each {|n,r| puts %{#{n} app/controllers/#{r.requirements[:controller]}_controller.rb##{r.requirements[:action]}}}" - let string = self.eval(exec) - let routes = {} - for line in split(string,"\n") - let route = split(line," ") - let name = route[0] - let routes[name] = route[1] - endfor - call self.cache.set("named_routes",routes) - endif - - return keys(self.cache.get("named_routes")) -endfunction - -call s:add_methods('app', ['route_names','named_route_file']) - -function! RailsNamedRoutes() - return rails#app().route_names() -endfunction - -function! s:RailsIncludefind(str,...) - if a:str ==# "ApplicationController" - return "application_controller.rb\napp/controllers/application.rb" - elseif a:str ==# "Test::Unit::TestCase" - return "test/unit/testcase.rb" - endif - let str = a:str - if a:0 == 1 - " Get the text before the filename under the cursor. - " We'll cheat and peak at this in a bit - let line = s:linepeak() - let line = s:sub(line,'([:"'."'".']|\%[qQ]=[[({<])=\f*$','') - else - let line = "" - endif - let str = s:sub(str,'^\s*','') - let str = s:sub(str,'\s*$','') - let str = s:sub(str,'^:=[:@]','') - let str = s:sub(str,':0x\x+$','') " For # style output - let str = s:gsub(str,"[\"']",'') - if line =~# '\<\(require\|load\)\s*(\s*$' - return str - elseif str =~# '^\l\w*#\w\+$' - return 'app/controllers/'.s:sub(str,'#','_controller.rb#') - endif - let str = rails#underscore(str) - let fpat = '\(\s*\%("\f*"\|:\f*\|'."'\\f*'".'\)\s*,\s*\)*' - if a:str =~# '\u' - " Classes should always be in .rb files - let str .= '.rb' - elseif line =~# ':partial\s*=>\s*' - let str = s:sub(str,'[^/]+$','_&') - let str = s:findview(str) - elseif line =~# '\\s*' - let str = s:findview(s:sub(str,'^/=','layouts/')) - elseif line =~# ':controller\s*=>\s*' - let str = 'app/controllers/'.str.'_controller.rb' - elseif line =~# '\\s*$' && rails#buffer().type_name('config-routes')) - if line !~# ':as\s*=>\s*$' - let str = s:sub(str,'_%(path|url)$','') - let str = s:sub(str,'^hash_for_','') - endif - let file = rails#app().named_route_file(str) - if file == "" - let str = s:sub(str,'^formatted_','') - if str =~# '^\%(new\|edit\)_' - let str = 'app/controllers/'.s:sub(rails#pluralize(str),'^(new|edit)_(.*)','\2_controller.rb#\1') - elseif str ==# rails#singularize(str) - " If the word can't be singularized, it's probably a link to the show - " method. We should verify by checking for an argument, but that's - " difficult the way things here are currently structured. - let str = 'app/controllers/'.rails#pluralize(str).'_controller.rb#show' - else - let str = 'app/controllers/'.str.'_controller.rb#index' - endif - else - let str = file - endif - elseif str !~ '/' - " If we made it this far, we'll risk making it singular. - let str = rails#singularize(str) - let str = s:sub(str,'_id$','') - endif - if str =~ '^/' && !filereadable(str) - let str = s:sub(str,'^/','') - endif - if str =~# '^lib/' && !filereadable(str) - let str = s:sub(str,'^lib/','') - endif - return str -endfunction - -" }}}1 -" File Finders {{{1 - -function! s:addfilecmds(type) - let l = s:sub(a:type,'^.','\l&') - let cmds = 'ESVTD ' - let cmd = '' - while cmds != '' - let cplt = " -complete=customlist,".s:sid.l."List" - exe "command! -buffer -bar ".(cmd == 'D' ? '-range=0 ' : '')."-nargs=*".cplt." R".cmd.l." :call s:".l.'Edit("'.(cmd == 'D' ? '' : '').cmd.'",)' - let cmd = strpart(cmds,0,1) - let cmds = strpart(cmds,1) - endwhile -endfunction - -function! s:BufFinderCommands() - command! -buffer -bar -nargs=+ Rnavcommand :call s:Navcommand(0,) - call s:addfilecmds("metal") - call s:addfilecmds("model") - call s:addfilecmds("view") - call s:addfilecmds("controller") - call s:addfilecmds("mailer") - call s:addfilecmds("migration") - call s:addfilecmds("observer") - call s:addfilecmds("helper") - call s:addfilecmds("layout") - call s:addfilecmds("fixtures") - call s:addfilecmds("locale") - if rails#app().has('test') || rails#app().has('spec') - call s:addfilecmds("unittest") - call s:addfilecmds("functionaltest") - endif - if rails#app().has('test') || rails#app().has('spec') || rails#app().has('cucumber') - call s:addfilecmds("integrationtest") - endif - if rails#app().has('spec') - call s:addfilecmds("spec") - endif - call s:addfilecmds("stylesheet") - call s:addfilecmds("javascript") - call s:addfilecmds("plugin") - call s:addfilecmds("task") - call s:addfilecmds("lib") - call s:addfilecmds("environment") - call s:addfilecmds("initializer") -endfunction - -function! s:completion_filter(results,A) - let results = sort(type(a:results) == type("") ? split(a:results,"\n") : copy(a:results)) - call filter(results,'v:val !~# "\\~$"') - let filtered = filter(copy(results),'s:startswith(v:val,a:A)') - if !empty(filtered) | return filtered | endif - let regex = s:gsub(a:A,'[^/]','[&].*') - let filtered = filter(copy(results),'v:val =~# "^".regex') - if !empty(filtered) | return filtered | endif - let regex = s:gsub(a:A,'.','[&].*') - let filtered = filter(copy(results),'v:val =~# regex') - return filtered -endfunction - -function! s:autocamelize(files,test) - if a:test =~# '^\u' - return s:completion_filter(map(copy(a:files),'rails#camelize(v:val)'),a:test) - else - return s:completion_filter(a:files,a:test) - endif -endfunction - -function! s:app_relglob(path,glob,...) dict - if exists("+shellslash") && ! &shellslash - let old_ss = &shellslash - let &shellslash = 1 - endif - let path = a:path - if path !~ '^/' && path !~ '^\w:' - let path = self.path(path) - endif - let suffix = a:0 ? a:1 : '' - let full_paths = split(glob(path.a:glob.suffix),"\n") - let relative_paths = [] - for entry in full_paths - if suffix == '' && isdirectory(entry) && entry !~ '/$' - let entry .= '/' - endif - let relative_paths += [entry[strlen(path) : -strlen(suffix)-1]] - endfor - if exists("old_ss") - let &shellslash = old_ss - endif - return relative_paths -endfunction - -call s:add_methods('app', ['relglob']) - -function! s:relglob(...) - return join(call(rails#app().relglob,a:000,rails#app()),"\n") -endfunction - -function! s:helperList(A,L,P) - return s:autocamelize(rails#app().relglob("app/helpers/","**/*","_helper.rb"),a:A) -endfunction - -function! s:controllerList(A,L,P) - let con = rails#app().relglob("app/controllers/","**/*",".rb") - call map(con,'s:sub(v:val,"_controller$","")') - return s:autocamelize(con,a:A) -endfunction - -function! s:mailerList(A,L,P) - return s:autocamelize(rails#app().relglob("app/mailers/","**/*",".rb"),a:A) -endfunction - -function! s:viewList(A,L,P) - let c = s:controller(1) - let top = rails#app().relglob("app/views/",s:fuzzyglob(a:A)) - call filter(top,'v:val !~# "\\~$"') - if c != '' && a:A !~ '/' - let local = rails#app().relglob("app/views/".c."/","*.*[^~]") - return s:completion_filter(local+top,a:A) - endif - return s:completion_filter(top,a:A) -endfunction - -function! s:layoutList(A,L,P) - return s:completion_filter(rails#app().relglob("app/views/layouts/","*"),a:A) -endfunction - -function! s:stylesheetList(A,L,P) - let list = rails#app().relglob('app/assets/stylesheets/','**/*.*','') - call map(list,'s:sub(v:val,"\\..*$","")') - let list += rails#app().relglob('public/stylesheets/','**/*','.css') - if rails#app().has('sass') - call extend(list,rails#app().relglob('public/stylesheets/sass/','**/*','.s?ss')) - call s:uniq(list) - endif - return s:completion_filter(list,a:A) -endfunction - -function! s:javascriptList(A,L,P) - let list = rails#app().relglob('app/assets/javascripts/','**/*.*','') - call map(list,'s:sub(v:val,"\\..*$","")') - let list += rails#app().relglob("public/javascripts/","**/*",".js") - return s:completion_filter(list,a:A) -endfunction - -function! s:metalList(A,L,P) - return s:autocamelize(rails#app().relglob("app/metal/","**/*",".rb"),a:A) -endfunction - -function! s:modelList(A,L,P) - let models = rails#app().relglob("app/models/","**/*",".rb") - call filter(models,'v:val !~# "_observer$"') - return s:autocamelize(models,a:A) -endfunction - -function! s:observerList(A,L,P) - return s:autocamelize(rails#app().relglob("app/models/","**/*","_observer.rb"),a:A) -endfunction - -function! s:fixturesList(A,L,P) - return s:completion_filter(rails#app().relglob("test/fixtures/","**/*")+rails#app().relglob("spec/fixtures/","**/*"),a:A) -endfunction - -function! s:localeList(A,L,P) - return s:completion_filter(rails#app().relglob("config/locales/","**/*"),a:A) -endfunction - -function! s:migrationList(A,L,P) - if a:A =~ '^\d' - let migrations = rails#app().relglob("db/migrate/",a:A."[0-9_]*",".rb") - return map(migrations,'matchstr(v:val,"^[0-9]*")') - else - let migrations = rails#app().relglob("db/migrate/","[0-9]*[0-9]_*",".rb") - call map(migrations,'s:sub(v:val,"^[0-9]*_","")') - return s:autocamelize(migrations,a:A) - endif -endfunction - -function! s:unittestList(A,L,P) - let found = [] - if rails#app().has('test') - let found += rails#app().relglob("test/unit/","**/*","_test.rb") - endif - if rails#app().has('spec') - let found += rails#app().relglob("spec/models/","**/*","_spec.rb") - endif - return s:autocamelize(found,a:A) -endfunction - -function! s:functionaltestList(A,L,P) - let found = [] - if rails#app().has('test') - let found += rails#app().relglob("test/functional/","**/*","_test.rb") - endif - if rails#app().has('spec') - let found += rails#app().relglob("spec/controllers/","**/*","_spec.rb") - let found += rails#app().relglob("spec/mailers/","**/*","_spec.rb") - endif - return s:autocamelize(found,a:A) -endfunction - -function! s:integrationtestList(A,L,P) - if a:A =~# '^\u' - return s:autocamelize(rails#app().relglob("test/integration/","**/*","_test.rb"),a:A) - endif - let found = [] - if rails#app().has('test') - let found += rails#app().relglob("test/integration/","**/*","_test.rb") - endif - if rails#app().has('spec') - let found += rails#app().relglob("spec/requests/","**/*","_spec.rb") - let found += rails#app().relglob("spec/integration/","**/*","_spec.rb") - endif - if rails#app().has('cucumber') - let found += rails#app().relglob("features/","**/*",".feature") - endif - return s:completion_filter(found,a:A) -endfunction - -function! s:specList(A,L,P) - return s:completion_filter(rails#app().relglob("spec/","**/*","_spec.rb"),a:A) -endfunction - -function! s:pluginList(A,L,P) - if a:A =~ '/' - return s:completion_filter(rails#app().relglob('vendor/plugins/',matchstr(a:A,'.\{-\}/').'**/*'),a:A) - else - return s:completion_filter(rails#app().relglob('vendor/plugins/',"*","/init.rb"),a:A) - endif -endfunction - -" Task files, not actual rake tasks -function! s:taskList(A,L,P) - let all = rails#app().relglob("lib/tasks/","**/*",".rake") - if RailsFilePath() =~ '\','".name."',\"".prefix."\",".string(suffix).",".string(filter).",".string(default).",)" - let cmd = strpart(cmds,0,1) - let cmds = strpart(cmds,1) - endwhile -endfunction - -function! s:CommandList(A,L,P) - let cmd = matchstr(a:L,'\CR[A-Z]\=\w\+') - exe cmd." &" - let lp = s:last_prefix . "\n" - let res = [] - while lp != "" - let p = matchstr(lp,'.\{-\}\ze\n') - let lp = s:sub(lp,'.{-}\n','') - let res += rails#app().relglob(p,s:last_filter,s:last_suffix) - endwhile - if s:last_camelize - return s:autocamelize(res,a:A) - else - return s:completion_filter(res,a:A) - endif -endfunction - -function! s:CommandEdit(cmd,name,prefix,suffix,filter,default,...) - if a:0 && a:1 == "&" - let s:last_prefix = a:prefix - let s:last_suffix = a:suffix - let s:last_filter = a:filter - let s:last_camelize = (a:suffix =~# '\.rb$') - else - if a:default == "both()" - if s:model() != "" - let default = s:model() - else - let default = s:controller() - endif - elseif a:default == "model()" - let default = s:model(1) - elseif a:default == "controller()" - let default = s:controller(1) - else - let default = a:default - endif - call s:EditSimpleRb(a:cmd,a:name,a:0 ? a:1 : default,a:prefix,a:suffix) - endif -endfunction - -function! s:EditSimpleRb(cmd,name,target,prefix,suffix,...) - let cmd = s:findcmdfor(a:cmd) - if a:target == "" - " Good idea to emulate error numbers like this? - return s:error("E471: Argument required") - endif - let f = a:0 ? a:target : rails#underscore(a:target) - let jump = matchstr(f,'[#!].*\|:\d*\%(:in\)\=$') - let f = s:sub(f,'[#!].*|:\d*%(:in)=$','') - if jump =~ '^!' - let cmd = s:editcmdfor(cmd) - endif - if f == '.' - let f = s:sub(f,'\.$','') - else - let f .= a:suffix.jump - endif - let f = s:gsub(a:prefix,'\n',f.'\n').f - return s:findedit(cmd,f) -endfunction - -function! s:app_migration(file) dict - let arg = a:file - if arg =~ '^0$\|^0\=[#:]' - let suffix = s:sub(arg,'^0*','') - if self.has_file('db/schema.rb') - return 'db/schema.rb'.suffix - elseif self.has_file('db/'.s:environment().'_structure.sql') - return 'db/'.s:environment().'_structure.sql'.suffix - else - return 'db/schema.rb'.suffix - endif - elseif arg =~ '^\d$' - let glob = '00'.arg.'_*.rb' - elseif arg =~ '^\d\d$' - let glob = '0'.arg.'_*.rb' - elseif arg =~ '^\d\d\d$' - let glob = ''.arg.'_*.rb' - elseif arg == '' - let glob = '*.rb' - else - let glob = '*'.rails#underscore(arg).'*rb' - endif - let files = split(glob(self.path('db/migrate/').glob),"\n") - if arg == '' - return get(files,-1,'') - endif - call map(files,'strpart(v:val,1+strlen(self.path()))') - let keep = get(files,0,'') - if glob =~# '^\*.*\*rb' - let pattern = glob[1:-4] - call filter(files,'v:val =~# ''db/migrate/\d\+_''.pattern.''\.rb''') - let keep = get(files,0,keep) - endif - return keep -endfunction - -call s:add_methods('app', ['migration']) - -function! s:migrationEdit(cmd,...) - let cmd = s:findcmdfor(a:cmd) - let arg = a:0 ? a:1 : '' - let migr = arg == "." ? "db/migrate" : rails#app().migration(arg) - if migr != '' - call s:findedit(cmd,migr) - else - return s:error("Migration not found".(arg=='' ? '' : ': '.arg)) - endif -endfunction - -function! s:fixturesEdit(cmd,...) - if a:0 - let c = rails#underscore(a:1) - else - let c = rails#pluralize(s:model(1)) - endif - if c == "" - return s:error("E471: Argument required") - endif - let e = fnamemodify(c,':e') - let e = e == '' ? e : '.'.e - let c = fnamemodify(c,':r') - let file = get(rails#app().test_suites(),0,'test').'/fixtures/'.c.e - if file =~ '\.\w\+$' && rails#app().find_file(c.e,["test/fixtures","spec/fixtures"]) ==# '' - call s:edit(a:cmd,file) - else - call s:findedit(a:cmd,rails#app().find_file(c.e,["test/fixtures","spec/fixtures"],[".yml",".csv"],file)) - endif -endfunction - -function! s:localeEdit(cmd,...) - let c = a:0 ? a:1 : rails#app().default_locale() - if c =~# '\.' - call s:edit(a:cmd,rails#app().find_file(c,'config/locales',[],'config/locales/'.c)) - else - call s:findedit(a:cmd,rails#app().find_file(c,'config/locales',['.yml','.rb'],'config/locales/'.c)) - endif -endfunction - -function! s:metalEdit(cmd,...) - if a:0 - call s:EditSimpleRb(a:cmd,"metal",a:1,"app/metal/",".rb") - else - call s:EditSimpleRb(a:cmd,"metal",'config/boot',"",".rb") - endif -endfunction - -function! s:modelEdit(cmd,...) - call s:EditSimpleRb(a:cmd,"model",a:0? a:1 : s:model(1),"app/models/",".rb") -endfunction - -function! s:observerEdit(cmd,...) - call s:EditSimpleRb(a:cmd,"observer",a:0? a:1 : s:model(1),"app/models/","_observer.rb") -endfunction - -function! s:viewEdit(cmd,...) - if a:0 && a:1 =~ '^[^!#:]' - let view = matchstr(a:1,'[^!#:]*') - elseif rails#buffer().type_name('controller','mailer') - let view = s:lastmethod(line('.')) - else - let view = '' - endif - if view == '' - return s:error("No view name given") - elseif view == '.' - return s:edit(a:cmd,'app/views') - elseif view !~ '/' && s:controller(1) != '' - let view = s:controller(1) . '/' . view - endif - if view !~ '/' - return s:error("Cannot find view without controller") - endif - let file = "app/views/".view - let found = s:findview(view) - if found != '' - let dir = fnamemodify(rails#app().path(found),':h') - if !isdirectory(dir) - if a:0 && a:1 =~ '!' - call mkdir(dir,'p') - else - return s:error('No such directory') - endif - endif - call s:edit(a:cmd,found) - elseif file =~ '\.\w\+$' - call s:findedit(a:cmd,file) - else - let format = s:format(rails#buffer().type_name('mailer') ? 'text' : 'html') - if glob(rails#app().path(file.'.'.format).'.*[^~]') != '' - let file .= '.' . format - endif - call s:findedit(a:cmd,file) - endif -endfunction - -function! s:findview(name) - let self = rails#buffer() - let name = a:name - let pre = 'app/views/' - if name !~# '/' - let controller = self.controller_name(1) - if controller != '' - let name = controller.'/'.name - endif - endif - if name =~# '\.\w\+\.\w\+$' || name =~# '\.'.s:viewspattern().'$' - return pre.name - else - for format in ['.'.s:format('html'), ''] - for type in s:view_types - if self.app().has_file(pre.name.format.'.'.type) - return pre.name.format.'.'.type - endif - endfor - endfor - endif - return '' -endfunction - -function! s:findlayout(name) - return s:findview("layouts/".(a:name == '' ? 'application' : a:name)) -endfunction - -function! s:layoutEdit(cmd,...) - if a:0 - return s:viewEdit(a:cmd,"layouts/".a:1) - endif - let file = s:findlayout(s:controller(1)) - if file == "" - let file = s:findlayout("application") - endif - if file == "" - let file = "app/views/layouts/application.html.erb" - endif - call s:edit(a:cmd,s:sub(file,'^/','')) -endfunction - -function! s:controllerEdit(cmd,...) - let suffix = '.rb' - if a:0 == 0 - let controller = s:controller(1) - if rails#buffer().type_name() =~# '^view\%(-layout\|-partial\)\@!' - let suffix .= '#'.expand('%:t:r') - endif - else - let controller = a:1 - endif - if rails#app().has_file("app/controllers/".controller."_controller.rb") || !rails#app().has_file("app/controllers/".controller.".rb") - let suffix = "_controller".suffix - endif - return s:EditSimpleRb(a:cmd,"controller",controller,"app/controllers/",suffix) -endfunction - -function! s:mailerEdit(cmd,...) - return s:EditSimpleRb(a:cmd,"mailer",a:0? a:1 : s:controller(1),"app/mailers/\napp/models/",".rb") -endfunction - -function! s:helperEdit(cmd,...) - return s:EditSimpleRb(a:cmd,"helper",a:0? a:1 : s:controller(1),"app/helpers/","_helper.rb") -endfunction - -function! s:stylesheetEdit(cmd,...) - let name = a:0 ? a:1 : s:controller(1) - if rails#app().has('sass') && rails#app().has_file('public/stylesheets/sass/'.name.'.sass') - return s:EditSimpleRb(a:cmd,"stylesheet",name,"public/stylesheets/sass/",".sass",1) - elseif rails#app().has('sass') && rails#app().has_file('public/stylesheets/sass/'.name.'.scss') - return s:EditSimpleRb(a:cmd,"stylesheet",name,"public/stylesheets/sass/",".scss",1) - elseif rails#app().has('lesscss') && rails#app().has_file('app/stylesheets/'.name.'.less') - return s:EditSimpleRb(a:cmd,"stylesheet",name,"app/stylesheets/",".less",1) - else - let types = rails#app().relglob('app/assets/stylesheets/'.name,'.*','') - if !empty(types) - return s:EditSimpleRb(a:cmd,'stylesheet',name,'app/assets/stylesheets/',types[0],1) - else - return s:EditSimpleRb(a:cmd,'stylesheet',name,'public/stylesheets/','.css',1) - endif - endif -endfunction - -function! s:javascriptEdit(cmd,...) - let name = a:0 ? a:1 : s:controller(1) - if rails#app().has('coffee') && rails#app().has_file('app/scripts/'.name.'.coffee') - return s:EditSimpleRb(a:cmd,'javascript',name,'app/scripts/','.coffee',1) - elseif rails#app().has('coffee') && rails#app().has_file('app/scripts/'.name.'.js') - return s:EditSimpleRb(a:cmd,'javascript',name,'app/scripts/','.js',1) - else - let types = rails#app().relglob('app/assets/javascripts/'.name,'.*','') - if !empty(types) - return s:EditSimpleRb(a:cmd,'javascript',name,'app/assets/javascripts/',types[0],1) - else - return s:EditSimpleRb(a:cmd,'javascript',name,'public/javascripts/','.js',1) - endif - endif -endfunction - -function! s:unittestEdit(cmd,...) - let f = rails#underscore(a:0 ? matchstr(a:1,'[^!#:]*') : s:model(1)) - let jump = a:0 ? matchstr(a:1,'[!#:].*') : '' - if jump =~ '!' - let cmd = s:editcmdfor(a:cmd) - else - let cmd = s:findcmdfor(a:cmd) - endif - let mapping = {'test': ['test/unit/','_test.rb'], 'spec': ['spec/models/','_spec.rb']} - let tests = map(filter(rails#app().test_suites(),'has_key(mapping,v:val)'),'get(mapping,v:val)') - if empty(tests) - let tests = [mapping['test']] - endif - for [prefix, suffix] in tests - if !a:0 && rails#buffer().type_name('model-aro') && f != '' && f !~# '_observer$' - if rails#app().has_file(prefix.f.'_observer'.suffix) - return s:findedit(cmd,prefix.f.'_observer'.suffix.jump) - endif - endif - endfor - for [prefix, suffix] in tests - if rails#app().has_file(prefix.f.suffix) - return s:findedit(cmd,prefix.f.suffix.jump) - endif - endfor - return s:EditSimpleRb(a:cmd,"unittest",f.jump,tests[0][0],tests[0][1],1) -endfunction - -function! s:functionaltestEdit(cmd,...) - let f = rails#underscore(a:0 ? matchstr(a:1,'[^!#:]*') : s:controller(1)) - let jump = a:0 ? matchstr(a:1,'[!#:].*') : '' - if jump =~ '!' - let cmd = s:editcmdfor(a:cmd) - else - let cmd = s:findcmdfor(a:cmd) - endif - let mapping = {'test': [['test/functional/'],['_test.rb','_controller_test.rb']], 'spec': [['spec/controllers/','spec/mailers/'],['_spec.rb','_controller_spec.rb']]} - let tests = map(filter(rails#app().test_suites(),'has_key(mapping,v:val)'),'get(mapping,v:val)') - if empty(tests) - let tests = [mapping[tests]] - endif - for [prefixes, suffixes] in tests - for prefix in prefixes - for suffix in suffixes - if rails#app().has_file(prefix.f.suffix) - return s:findedit(cmd,prefix.f.suffix.jump) - endif - endfor - endfor - endfor - return s:EditSimpleRb(a:cmd,"functionaltest",f.jump,tests[0][0][0],tests[0][1][0],1) -endfunction - -function! s:integrationtestEdit(cmd,...) - if !a:0 - return s:EditSimpleRb(a:cmd,"integrationtest","test/test_helper\nfeatures/support/env\nspec/spec_helper","",".rb") - endif - let f = rails#underscore(matchstr(a:1,'[^!#:]*')) - let jump = matchstr(a:1,'[!#:].*') - if jump =~ '!' - let cmd = s:editcmdfor(a:cmd) - else - let cmd = s:findcmdfor(a:cmd) - endif - let tests = [['test/integration/','_test.rb'], [ 'spec/requests/','_spec.rb'], [ 'spec/integration/','_spec.rb'], [ 'features/','.feature']] - call filter(tests, 'isdirectory(rails#app().path(v:val[0]))') - if empty(tests) - let tests = [['test/integration/','_test.rb']] - endif - for [prefix, suffix] in tests - if rails#app().has_file(prefix.f.suffix) - return s:findedit(cmd,prefix.f.suffix.jump) - elseif rails#app().has_file(prefix.rails#underscore(f).suffix) - return s:findedit(cmd,prefix.rails#underscore(f).suffix.jump) - endif - endfor - return s:EditSimpleRb(a:cmd,"integrationtest",f.jump,tests[0][0],tests[0][1],1) -endfunction - -function! s:specEdit(cmd,...) - if a:0 - return s:EditSimpleRb(a:cmd,"spec",a:1,"spec/","_spec.rb") - else - call s:EditSimpleRb(a:cmd,"spec","spec_helper","spec/",".rb") - endif -endfunction - -function! s:pluginEdit(cmd,...) - let cmd = s:findcmdfor(a:cmd) - let plugin = "" - let extra = "" - if RailsFilePath() =~ '\','split') - let cmd = s:sub(cmd,'find>','edit') - return cmd -endfunction - -function! s:try(cmd) abort - if !exists(":try") - " I've seen at least one weird setup without :try - exe a:cmd - else - try - exe a:cmd - catch - call s:error(s:sub(v:exception,'^.{-}:\zeE','')) - return 0 - endtry - endif - return 1 -endfunction - -function! s:findedit(cmd,files,...) abort - let cmd = s:findcmdfor(a:cmd) - let files = type(a:files) == type([]) ? copy(a:files) : split(a:files,"\n") - if len(files) == 1 - let file = files[0] - else - let file = get(filter(copy(files),'rails#app().has_file(s:sub(v:val,"#.*|:\\d*$",""))'),0,get(files,0,'')) - endif - if file =~ '[#!]\|:\d*\%(:in\)\=$' - let djump = matchstr(file,'!.*\|#\zs.*\|:\zs\d*\ze\%(:in\)\=$') - let file = s:sub(file,'[#!].*|:\d*%(:in)=$','') - else - let djump = '' - endif - if file == '' - let testcmd = "edit" - elseif isdirectory(rails#app().path(file)) - let arg = file == "." ? rails#app().path() : rails#app().path(file) - let testcmd = s:editcmdfor(cmd).' '.(a:0 ? a:1 . ' ' : '').s:escarg(arg) - exe testcmd - return - elseif rails#app().path() =~ '://' || cmd =~ 'edit' || cmd =~ 'split' - if file !~ '^/' && file !~ '^\w:' && file !~ '://' - let file = s:escarg(rails#app().path(file)) - endif - let testcmd = s:editcmdfor(cmd).' '.(a:0 ? a:1 . ' ' : '').file - else - let testcmd = cmd.' '.(a:0 ? a:1 . ' ' : '').file - endif - if s:try(testcmd) - call s:djump(djump) - endif -endfunction - -function! s:edit(cmd,file,...) - let cmd = s:editcmdfor(a:cmd) - let cmd .= ' '.(a:0 ? a:1 . ' ' : '') - let file = a:file - if file !~ '^/' && file !~ '^\w:' && file !~ '://' - exe cmd."`=fnamemodify(rails#app().path(file),':.')`" - else - exe cmd.file - endif -endfunction - -function! s:Alternate(cmd,line1,line2,count,...) - if a:0 - if a:count && a:cmd !~# 'D' - return call('s:Find',[1,a:line1.a:cmd]+a:000) - elseif a:count - return call('s:Edit',[1,a:line1.a:cmd]+a:000) - else - return call('s:Edit',[1,a:cmd]+a:000) - endif - else - let file = s:getopt(a:count ? 'related' : 'alternate', 'bl') - if file == '' - let file = rails#buffer().related(a:count) - endif - if file != '' - call s:findedit(a:cmd,file) - else - call s:warn("No alternate file is defined") - endif - endif -endfunction - -function! s:Related(cmd,line1,line2,count,...) - if a:count == 0 && a:0 == 0 - return s:Alternate(a:cmd,a:line1,a:line1,a:line1) - else - return call('s:Alternate',[a:cmd,a:line1,a:line2,a:count]+a:000) - endif -endfunction - -function! s:Complete_related(A,L,P) - if a:L =~# '^[[:alpha:]]' - return s:Complete_edit(a:A,a:L,a:P) - else - return s:Complete_find(a:A,a:L,a:P) - endif -endfunction - -function! s:readable_related(...) dict abort - let f = self.name() - if a:0 && a:1 - let lastmethod = self.last_method(a:1) - if self.type_name('controller','mailer') && lastmethod != "" - let root = s:sub(s:sub(s:sub(f,'/application%(_controller)=\.rb$','/shared_controller.rb'),'/%(controllers|models|mailers)/','/views/'),'%(_controller)=\.rb$','/'.lastmethod) - let format = self.last_format(a:1) - if format == '' - let format = self.type_name('mailer') ? 'text' : 'html' - endif - if glob(self.app().path().'/'.root.'.'.format.'.*[^~]') != '' - return root . '.' . format - else - return root - endif - elseif f =~ '\ me') - let migration = "db/migrate/".get(candidates,0,migrations[0]).".rb" - endif - return migration . (exists('l:lastmethod') && lastmethod != '' ? '#'.lastmethod : '') - elseif f =~ '\??').'/layout.'.fnamemodify(f,':e') - else - let dest = f - endif - return s:sub(s:sub(dest,' 1 - return s:error("Incorrect number of arguments") - endif - if a:1 =~ '[^a-z0-9_/.]' - return s:error("Invalid partial name") - endif - let rails_root = rails#app().path() - let ext = expand("%:e") - let file = s:sub(a:1,'%(/|^)\zs_\ze[^/]*$','') - let first = a:firstline - let last = a:lastline - let range = first.",".last - if rails#buffer().type_name('view-layout') - if RailsFilePath() =~ '\' - let curdir = 'app/views/shared' - if file !~ '/' - let file = "shared/" .file - endif - else - let curdir = s:sub(RailsFilePath(),'.*]+)'.erub2.'\s*$' - let collection = s:sub(getline(first-1),'^'.fspaces.erub1.'for\s+(\k+)\s+in\s+([^ >]+)'.erub2.'\s*$','\1>\2') - elseif getline(first-1) =~ '\v^'.fspaces.erub1.'([^ %>]+)\.each\s+do\s+\|\s*(\k+)\s*\|'.erub2.'\s*$' - let collection = s:sub(getline(first-1),'^'.fspaces.erub1.'([^ %>]+)\.each\s+do\s+\|\s*(\k+)\s*\|'.erub2.'\s*$','\2>\1') - endif - if collection != '' - let var = matchstr(collection,'^\k\+') - let collection = s:sub(collection,'^\k+\>','') - let first -= 1 - let last += 1 - endif - else - let fspaces = spaces - endif - let renderstr = "render :partial => '".fnamemodify(file,":r:r")."'" - if collection != "" - let renderstr .= ", :collection => ".collection - elseif "@".name != var - let renderstr .= ", :object => ".var - endif - if ext =~? '^\%(rhtml\|erb\|dryml\)$' - let renderstr = "<%= ".renderstr." %>" - elseif ext == "rxml" || ext == "builder" - let renderstr = "xml << ".s:sub(renderstr,"render ","render(").")" - elseif ext == "rjs" - let renderstr = "page << ".s:sub(renderstr,"render ","render(").")" - elseif ext == "haml" - let renderstr = "= ".renderstr - elseif ext == "mn" - let renderstr = "_".renderstr - endif - let buf = @@ - silent exe range."yank" - let partial = @@ - let @@ = buf - let old_ai = &ai - try - let &ai = 0 - silent exe "norm! :".first.",".last."change\".fspaces.renderstr."\.\" - finally - let &ai = old_ai - endtry - if renderstr =~ '<%' - norm ^6w - else - norm ^5w - endif - let ft = &ft - let shortout = fnamemodify(out,':.') - silent split `=shortout` - silent %delete - let &ft = ft - let @@ = partial - silent put - 0delete - let @@ = buf - if spaces != "" - silent! exe '%substitute/^'.spaces.'//' - endif - silent! exe '%substitute?\%(\w\|[@:"'."'".'-]\)\@?'.name.'?g' - 1 -endfunction - -" }}}1 -" Migration Inversion {{{1 - -function! s:mkeep(str) - " Things to keep (like comments) from a migration statement - return matchstr(a:str,' #[^{].*') -endfunction - -function! s:mextargs(str,num) - if a:str =~ '^\s*\w\+\s*(' - return s:sub(matchstr(a:str,'^\s*\w\+\s*\zs(\%([^,)]\+[,)]\)\{,'.a:num.'\}'),',$',')') - else - return s:sub(s:sub(matchstr(a:str,'\w\+\>\zs\s*\%([^,){ ]*[, ]*\)\{,'.a:num.'\}'),'[, ]*$',''),'^\s+',' ') - endif -endfunction - -function! s:migspc(line) - return matchstr(a:line,'^\s*') -endfunction - -function! s:invertrange(beg,end) - let str = "" - let lnum = a:beg - while lnum <= a:end - let line = getline(lnum) - let add = "" - if line == '' - let add = ' ' - elseif line =~ '^\s*\(#[^{].*\)\=$' - let add = line - elseif line =~ '\' - let add = s:migspc(line)."drop_table".s:mextargs(line,1).s:mkeep(line) - let lnum = s:endof(lnum) - elseif line =~ '\' - let add = s:sub(line,'\s*\(=\s*([^,){ ]*).*','create_table \1 do |t|'."\n".matchstr(line,'^\s*').'end').s:mkeep(line) - elseif line =~ '\' - let add = s:migspc(line).'remove_column'.s:mextargs(line,2).s:mkeep(line) - elseif line =~ '\' - let add = s:sub(line,'','add_column') - elseif line =~ '\' - let add = s:migspc(line).'remove_index'.s:mextargs(line,1) - let mat = matchstr(line,':name\s*=>\s*\zs[^ ,)]*') - if mat != '' - let add = s:sub(add,'\)=$',', :name => '.mat.'&') - else - let mat = matchstr(line,'\[^,]*,\s*\zs\%(\[[^]]*\]\|[:"'."'".']\w*["'."'".']\=\)') - if mat != '' - let add = s:sub(add,'\)=$',', :column => '.mat.'&') - endif - endif - let add .= s:mkeep(line) - elseif line =~ '\' - let add = s:sub(s:sub(line,'\s*','') - elseif line =~ '\' - let add = s:sub(line,'' - let add = s:migspc(line).'change_column'.s:mextargs(line,2).s:mkeep(line) - elseif line =~ '\' - let add = s:migspc(line).'change_column_default'.s:mextargs(line,2).s:mkeep(line) - elseif line =~ '\.update_all(\(["'."'".']\).*\1)$' || line =~ '\.update_all \(["'."'".']\).*\1$' - " .update_all('a = b') => .update_all('b = a') - let pre = matchstr(line,'^.*\.update_all[( ][}'."'".'"]') - let post = matchstr(line,'["'."'".'])\=$') - let mat = strpart(line,strlen(pre),strlen(line)-strlen(pre)-strlen(post)) - let mat = s:gsub(','.mat.',','%(,\s*)@<=([^ ,=]{-})(\s*\=\s*)([^,=]{-})%(\s*,)@=','\3\2\1') - let add = pre.s:sub(s:sub(mat,'^,',''),',$','').post - elseif line =~ '^s\*\%(if\|unless\|while\|until\|for\)\>' - let lnum = s:endof(lnum) - endif - if lnum == 0 - return -1 - endif - if add == "" - let add = s:sub(line,'^\s*\zs.*','raise ActiveRecord::IrreversibleMigration') - elseif add == " " - let add = "" - endif - let str = add."\n".str - let lnum += 1 - endwhile - let str = s:gsub(str,'(\s*raise ActiveRecord::IrreversibleMigration\n)+','\1') - return str -endfunction - -function! s:Invert(bang) - let err = "Could not parse method" - let src = "up" - let dst = "down" - let beg = search('\%('.&l:define.'\).*'.src.'\>',"w") - let end = s:endof(beg) - if beg + 1 == end - let src = "down" - let dst = "up" - let beg = search('\%('.&l:define.'\).*'.src.'\>',"w") - let end = s:endof(beg) - endif - if !beg || !end - return s:error(err) - endif - let str = s:invertrange(beg+1,end-1) - if str == -1 - return s:error(err) - endif - let beg = search('\%('.&l:define.'\).*'.dst.'\>',"w") - let end = s:endof(beg) - if !beg || !end - return s:error(err) - endif - if foldclosed(beg) > 0 - exe beg."foldopen!" - endif - if beg + 1 < end - exe (beg+1).",".(end-1)."delete _" - endif - if str != '' - exe beg.'put =str' - exe 1+beg - endif -endfunction - -" }}}1 -" Cache {{{1 - -let s:cache_prototype = {'dict': {}} - -function! s:cache_clear(...) dict - if a:0 == 0 - let self.dict = {} - elseif has_key(self,'dict') && has_key(self.dict,a:1) - unlet! self.dict[a:1] - endif -endfunction - -function! rails#cache_clear(...) - if exists('b:rails_root') - return call(rails#app().cache.clear,a:000,rails#app().cache) - endif -endfunction - -function! s:cache_get(...) dict - if a:0 == 1 - return self.dict[a:1] - else - return self.dict - endif -endfunction - -function! s:cache_has(key) dict - return has_key(self.dict,a:key) -endfunction - -function! s:cache_needs(key) dict - return !has_key(self.dict,a:key) -endfunction - -function! s:cache_set(key,value) dict - let self.dict[a:key] = a:value -endfunction - -call s:add_methods('cache', ['clear','needs','has','get','set']) - -let s:app_prototype.cache = s:cache_prototype - -" }}}1 -" Syntax {{{1 - -function! s:resetomnicomplete() - if exists("+completefunc") && &completefunc == 'syntaxcomplete#Complete' - if exists("g:loaded_syntax_completion") - " Ugly but necessary, until we have our own completion - unlet g:loaded_syntax_completion - silent! delfunction syntaxcomplete#Complete - endif - endif -endfunction - -function! s:helpermethods() - return "" - \."action_name atom_feed audio_path audio_tag auto_discovery_link_tag " - \."button_tag button_to button_to_function " - \."cache capture cdata_section check_box check_box_tag collection_select concat content_for content_tag content_tag_for controller controller_name controller_path convert_to_model cookies csrf_meta_tag csrf_meta_tags current_cycle cycle " - \."date_select datetime_select debug distance_of_time_in_words distance_of_time_in_words_to_now div_for dom_class dom_id " - \."email_field email_field_tag escape_javascript escape_once excerpt " - \."favicon_link_tag field_set_tag fields_for file_field file_field_tag flash form_for form_tag " - \."grouped_collection_select grouped_options_for_select " - \."headers hidden_field hidden_field_tag highlight " - \."image_alt image_path image_submit_tag image_tag " - \."j javascript_cdata_section javascript_include_tag javascript_path javascript_tag " - \."l label label_tag link_to link_to_function link_to_if link_to_unless link_to_unless_current localize logger " - \."mail_to " - \."number_field number_field_tag number_to_currency number_to_human number_to_human_size number_to_percentage number_to_phone number_with_delimiter number_with_precision " - \."option_groups_from_collection_for_select options_for_select options_from_collection_for_select " - \."params password_field password_field_tag path_to_audio path_to_image path_to_javascript path_to_stylesheet path_to_video phone_field phone_field_tag pluralize provide " - \."radio_button radio_button_tag range_field range_field_tag raw render request request_forgery_protection_token reset_cycle response " - \."safe_concat safe_join sanitize sanitize_css search_field search_field_tag select select_date select_datetime select_day select_hour select_minute select_month select_second select_tag select_time select_year session simple_format strip_links strip_tags stylesheet_link_tag stylesheet_path submit_tag " - \."t tag telephone_field telephone_field_tag text_area text_area_tag text_field text_field_tag time_ago_in_words time_select time_tag time_zone_options_for_select time_zone_select translate truncate " - \."url_field url_field_tag url_for url_options " - \."video_path video_tag " - \."word_wrap" -endfunction - -function! s:app_user_classes() dict - if self.cache.needs("user_classes") - let controllers = self.relglob("app/controllers/","**/*",".rb") - call map(controllers,'v:val == "application" ? v:val."_controller" : v:val') - let classes = - \ self.relglob("app/models/","**/*",".rb") + - \ controllers + - \ self.relglob("app/helpers/","**/*",".rb") + - \ self.relglob("lib/","**/*",".rb") - call map(classes,'rails#camelize(v:val)') - call self.cache.set("user_classes",classes) - endif - return self.cache.get('user_classes') -endfunction - -function! s:app_user_assertions() dict - if self.cache.needs("user_assertions") - if self.has_file("test/test_helper.rb") - let assertions = map(filter(s:readfile(self.path("test/test_helper.rb")),'v:val =~ "^ def assert_"'),'matchstr(v:val,"^ def \\zsassert_\\w\\+")') - else - let assertions = [] - endif - call self.cache.set("user_assertions",assertions) - endif - return self.cache.get('user_assertions') -endfunction - -call s:add_methods('app', ['user_classes','user_assertions']) - -function! s:BufSyntax() - if (!exists("g:rails_syntax") || g:rails_syntax) - let buffer = rails#buffer() - let s:javascript_functions = "$ $$ $A $F $H $R $w jQuery" - let classes = s:gsub(join(rails#app().user_classes(),' '),'::',' ') - if &syntax == 'ruby' - if classes != '' - exe "syn keyword rubyRailsUserClass ".classes." containedin=rubyClassDeclaration,rubyModuleDeclaration,rubyClass,rubyModule" - endif - if buffer.type_name() == '' - syn keyword rubyRailsMethod params request response session headers cookies flash - endif - if buffer.type_name('api') - syn keyword rubyRailsAPIMethod api_method inflect_names - endif - if buffer.type_name() ==# 'model' || buffer.type_name('model-arb') - syn keyword rubyRailsARMethod default_scope named_scope scope serialize - syn keyword rubyRailsARAssociationMethod belongs_to has_one has_many has_and_belongs_to_many composed_of accepts_nested_attributes_for - syn keyword rubyRailsARCallbackMethod before_create before_destroy before_save before_update before_validation before_validation_on_create before_validation_on_update - syn keyword rubyRailsARCallbackMethod after_create after_destroy after_save after_update after_validation after_validation_on_create after_validation_on_update - syn keyword rubyRailsARCallbackMethod around_create around_destroy around_save around_update - syn keyword rubyRailsARCallbackMethod after_commit after_find after_initialize after_rollback after_touch - syn keyword rubyRailsARClassMethod attr_accessible attr_protected attr_readonly establish_connection set_inheritance_column set_locking_column set_primary_key set_sequence_name set_table_name - syn keyword rubyRailsARValidationMethod validate validates validate_on_create validate_on_update validates_acceptance_of validates_associated validates_confirmation_of validates_each validates_exclusion_of validates_format_of validates_inclusion_of validates_length_of validates_numericality_of validates_presence_of validates_size_of validates_uniqueness_of - syn keyword rubyRailsMethod logger - endif - if buffer.type_name('model-aro') - syn keyword rubyRailsARMethod observe - endif - if buffer.type_name('mailer') - syn keyword rubyRailsMethod logger url_for polymorphic_path polymorphic_url - syn keyword rubyRailsRenderMethod mail render - syn keyword rubyRailsControllerMethod attachments default helper helper_attr helper_method - endif - if buffer.type_name('helper','view') - syn keyword rubyRailsViewMethod polymorphic_path polymorphic_url - exe "syn keyword rubyRailsHelperMethod ".s:gsub(s:helpermethods(),'<%(content_for|select)\s+','') - syn match rubyRailsHelperMethod '\\%(\s*{\|\s*do\>\|\s*(\=\s*&\)\@!' - syn match rubyRailsHelperMethod '\<\%(content_for?\=\|current_page?\)' - syn match rubyRailsViewMethod '\.\@' - if buffer.type_name('view-partial') - syn keyword rubyRailsMethod local_assigns - endif - elseif buffer.type_name('controller') - syn keyword rubyRailsMethod params request response session headers cookies flash - syn keyword rubyRailsRenderMethod render - syn keyword rubyRailsMethod logger polymorphic_path polymorphic_url - syn keyword rubyRailsControllerMethod helper helper_attr helper_method filter layout url_for serialize exempt_from_layout filter_parameter_logging hide_action cache_sweeper protect_from_forgery caches_page cache_page caches_action expire_page expire_action rescue_from - syn keyword rubyRailsRenderMethod head redirect_to render_to_string respond_with - syn match rubyRailsRenderMethod '\?\@!' - syn keyword rubyRailsFilterMethod before_filter append_before_filter prepend_before_filter after_filter append_after_filter prepend_after_filter around_filter append_around_filter prepend_around_filter skip_before_filter skip_after_filter - syn keyword rubyRailsFilterMethod verify - endif - if buffer.type_name('db-migration','db-schema') - syn keyword rubyRailsMigrationMethod create_table change_table drop_table rename_table add_column rename_column change_column change_column_default remove_column add_index remove_index rename_index execute - endif - if buffer.type_name('test') - if !empty(rails#app().user_assertions()) - exe "syn keyword rubyRailsUserMethod ".join(rails#app().user_assertions()) - endif - syn keyword rubyRailsTestMethod add_assertion assert assert_block assert_equal assert_in_delta assert_instance_of assert_kind_of assert_match assert_nil assert_no_match assert_not_equal assert_not_nil assert_not_same assert_nothing_raised assert_nothing_thrown assert_operator assert_raise assert_respond_to assert_same assert_send assert_throws assert_recognizes assert_generates assert_routing flunk fixtures fixture_path use_transactional_fixtures use_instantiated_fixtures assert_difference assert_no_difference assert_valid - syn keyword rubyRailsTestMethod test setup teardown - if !buffer.type_name('test-unit') - syn match rubyRailsTestControllerMethod '\.\@' - syn keyword rubyRailsTestControllerMethod get_via_redirect post_via_redirect put_via_redirect delete_via_redirect request_via_redirect - syn keyword rubyRailsTestControllerMethod assert_response assert_redirected_to assert_template assert_recognizes assert_generates assert_routing assert_dom_equal assert_dom_not_equal assert_select assert_select_rjs assert_select_encoded assert_select_email assert_tag assert_no_tag - endif - elseif buffer.type_name('spec') - syn keyword rubyRailsTestMethod describe context it its specify shared_examples_for it_should_behave_like before after around subject fixtures controller_name helper_name - syn match rubyRailsTestMethod '\!\=' - syn keyword rubyRailsTestMethod violated pending expect double mock mock_model stub_model - syn match rubyRailsTestMethod '\.\@!\@!' - if !buffer.type_name('spec-model') - syn match rubyRailsTestControllerMethod '\.\@' - syn keyword rubyRailsTestControllerMethod integrate_views - syn keyword rubyRailsMethod params request response session flash - syn keyword rubyRailsMethod polymorphic_path polymorphic_url - endif - endif - if buffer.type_name('task') - syn match rubyRailsRakeMethod '^\s*\zs\%(task\|file\|namespace\|desc\|before\|after\|on\)\>\%(\s*=\)\@!' - endif - if buffer.type_name('model-awss') - syn keyword rubyRailsMethod member - endif - if buffer.type_name('config-routes') - syn match rubyRailsMethod '\.\zs\%(connect\|named_route\)\>' - syn keyword rubyRailsMethod match get put post delete redirect root resource resources collection member nested scope namespace controller constraints - endif - syn keyword rubyRailsMethod debugger - syn keyword rubyRailsMethod alias_attribute alias_method_chain attr_accessor_with_default attr_internal attr_internal_accessor attr_internal_reader attr_internal_writer delegate mattr_accessor mattr_reader mattr_writer superclass_delegating_accessor superclass_delegating_reader superclass_delegating_writer - syn keyword rubyRailsMethod cattr_accessor cattr_reader cattr_writer class_inheritable_accessor class_inheritable_array class_inheritable_array_writer class_inheritable_hash class_inheritable_hash_writer class_inheritable_option class_inheritable_reader class_inheritable_writer inheritable_attributes read_inheritable_attribute reset_inheritable_attributes write_inheritable_array write_inheritable_attribute write_inheritable_hash - syn keyword rubyRailsInclude require_dependency - - syn region rubyString matchgroup=rubyStringDelimiter start=+\%(:order\s*=>\s*\)\@<="+ skip=+\\\\\|\\"+ end=+"+ contains=@rubyStringSpecial,railsOrderSpecial - syn region rubyString matchgroup=rubyStringDelimiter start=+\%(:order\s*=>\s*\)\@<='+ skip=+\\\\\|\\'+ end=+'+ contains=@rubyStringSpecial,railsOrderSpecial - syn match railsOrderSpecial +\c\<\%(DE\|A\)SC\>+ contained - syn region rubyString matchgroup=rubyStringDelimiter start=+\%(:conditions\s*=>\s*\[\s*\)\@<="+ skip=+\\\\\|\\"+ end=+"+ contains=@rubyStringSpecial,railsConditionsSpecial - syn region rubyString matchgroup=rubyStringDelimiter start=+\%(:conditions\s*=>\s*\[\s*\)\@<='+ skip=+\\\\\|\\'+ end=+'+ contains=@rubyStringSpecial,railsConditionsSpecial - syn match railsConditionsSpecial +?\|:\h\w*+ contained - syn cluster rubyNotTop add=railsOrderSpecial,railsConditionsSpecial - - " XHTML highlighting inside %Q<> - unlet! b:current_syntax - let removenorend = !exists("g:html_no_rendering") - let g:html_no_rendering = 1 - syn include @htmlTop syntax/xhtml.vim - if removenorend - unlet! g:html_no_rendering - endif - let b:current_syntax = "ruby" - " Restore syn sync, as best we can - if !exists("g:ruby_minlines") - let g:ruby_minlines = 50 - endif - syn sync fromstart - exe "syn sync minlines=" . g:ruby_minlines - syn case match - syn region rubyString matchgroup=rubyStringDelimiter start=+%Q\=<+ end=+>+ contains=@htmlTop,@rubyStringSpecial - syn cluster htmlArgCluster add=@rubyStringSpecial - syn cluster htmlPreProc add=@rubyStringSpecial - - elseif &syntax =~# '^eruby\>' || &syntax == 'haml' - syn case match - if classes != '' - exe 'syn keyword '.&syntax.'RailsUserClass '.classes.' contained containedin=@'.&syntax.'RailsRegions' - endif - if &syntax == 'haml' - exe 'syn cluster hamlRailsRegions contains=hamlRubyCodeIncluded,hamlRubyCode,hamlRubyHash,@hamlEmbeddedRuby,rubyInterpolation' - else - exe 'syn cluster erubyRailsRegions contains=erubyOneLiner,erubyBlock,erubyExpression,rubyInterpolation' - endif - exe 'syn keyword '.&syntax.'RailsHelperMethod '.s:gsub(s:helpermethods(),'<%(content_for|select)\s+','').' contained containedin=@'.&syntax.'RailsRegions' - exe 'syn match '.&syntax.'RailsHelperMethod "\\%(\s*{\|\s*do\>\|\s*(\=\s*&\)\@!" contained containedin=@'.&syntax.'RailsRegions' - exe 'syn match '.&syntax.'RailsHelperMethod "\<\%(content_for?\=\|current_page?\)" contained containedin=@'.&syntax.'RailsRegions' - exe 'syn keyword '.&syntax.'RailsMethod debugger polymorphic_path polymorphic_url contained containedin=@'.&syntax.'RailsRegions' - exe 'syn match '.&syntax.'RailsViewMethod "\.\@" contained containedin=@'.&syntax.'RailsRegions' - if buffer.type_name('view-partial') - exe 'syn keyword '.&syntax.'RailsMethod local_assigns contained containedin=@'.&syntax.'RailsRegions' - endif - exe 'syn keyword '.&syntax.'RailsRenderMethod render contained containedin=@'.&syntax.'RailsRegions' - exe 'syn case match' - set isk+=$ - exe 'syn keyword javascriptRailsFunction contained '.s:javascript_functions - exe 'syn cluster htmlJavaScript add=javascriptRailsFunction' - elseif &syntax == "yaml" - syn case match - " Modeled after syntax/eruby.vim - unlet! b:current_syntax - let g:main_syntax = 'eruby' - syn include @rubyTop syntax/ruby.vim - unlet g:main_syntax - syn cluster yamlRailsRegions contains=yamlRailsOneLiner,yamlRailsBlock,yamlRailsExpression - syn region yamlRailsOneLiner matchgroup=yamlRailsDelimiter start="^%%\@!" end="$" contains=@rubyRailsTop containedin=ALLBUT,@yamlRailsRegions,yamlRailsComment keepend oneline - syn region yamlRailsBlock matchgroup=yamlRailsDelimiter start="<%%\@!" end="%>" contains=@rubyTop containedin=ALLBUT,@yamlRailsRegions,yamlRailsComment - syn region yamlRailsExpression matchgroup=yamlRailsDelimiter start="<%=" end="%>" contains=@rubyTop containedin=ALLBUT,@yamlRailsRegions,yamlRailsComment - syn region yamlRailsComment matchgroup=yamlRailsDelimiter start="<%#" end="%>" contains=rubyTodo,@Spell containedin=ALLBUT,@yamlRailsRegions,yamlRailsComment keepend - syn match yamlRailsMethod '\.\@' contained containedin=@yamlRailsRegions - if classes != '' - exe "syn keyword yamlRailsUserClass ".classes." contained containedin=@yamlRailsRegions" - endif - let b:current_syntax = "yaml" - elseif &syntax == "html" - syn case match - set isk+=$ - exe "syn keyword javascriptRailsFunction contained ".s:javascript_functions - syn cluster htmlJavaScript add=javascriptRailsFunction - elseif &syntax == "javascript" || &syntax == "coffee" - " The syntax file included with Vim incorrectly sets syn case ignore. - syn case match - set isk+=$ - exe "syn keyword javascriptRailsFunction ".s:javascript_functions - - endif - endif - call s:HiDefaults() -endfunction - -function! s:HiDefaults() - hi def link rubyRailsAPIMethod rubyRailsMethod - hi def link rubyRailsARAssociationMethod rubyRailsARMethod - hi def link rubyRailsARCallbackMethod rubyRailsARMethod - hi def link rubyRailsARClassMethod rubyRailsARMethod - hi def link rubyRailsARValidationMethod rubyRailsARMethod - hi def link rubyRailsARMethod rubyRailsMethod - hi def link rubyRailsRenderMethod rubyRailsMethod - hi def link rubyRailsHelperMethod rubyRailsMethod - hi def link rubyRailsViewMethod rubyRailsMethod - hi def link rubyRailsMigrationMethod rubyRailsMethod - hi def link rubyRailsControllerMethod rubyRailsMethod - hi def link rubyRailsFilterMethod rubyRailsMethod - hi def link rubyRailsTestControllerMethod rubyRailsTestMethod - hi def link rubyRailsTestMethod rubyRailsMethod - hi def link rubyRailsRakeMethod rubyRailsMethod - hi def link rubyRailsMethod railsMethod - hi def link rubyRailsInclude rubyInclude - hi def link rubyRailsUserClass railsUserClass - hi def link rubyRailsUserMethod railsUserMethod - hi def link erubyRailsHelperMethod erubyRailsMethod - hi def link erubyRailsViewMethod erubyRailsMethod - hi def link erubyRailsRenderMethod erubyRailsMethod - hi def link erubyRailsMethod railsMethod - hi def link erubyRailsUserMethod railsUserMethod - hi def link erubyRailsUserClass railsUserClass - hi def link hamlRailsHelperMethod hamlRailsMethod - hi def link hamlRailsViewMethod hamlRailsMethod - hi def link hamlRailsRenderMethod hamlRailsMethod - hi def link hamlRailsMethod railsMethod - hi def link hamlRailsUserMethod railsUserMethod - hi def link hamlRailsUserClass railsUserClass - hi def link railsUserMethod railsMethod - hi def link yamlRailsDelimiter Delimiter - hi def link yamlRailsMethod railsMethod - hi def link yamlRailsComment Comment - hi def link yamlRailsUserClass railsUserClass - hi def link yamlRailsUserMethod railsUserMethod - hi def link javascriptRailsFunction railsMethod - hi def link railsUserClass railsClass - hi def link railsMethod Function - hi def link railsClass Type - hi def link railsOrderSpecial railsStringSpecial - hi def link railsConditionsSpecial railsStringSpecial - hi def link railsStringSpecial Identifier -endfunction - -function! rails#log_syntax() - if has('conceal') - syn match railslogEscape '\e\[[0-9;]*m' conceal - syn match railslogEscapeMN '\e\[[0-9;]*m' conceal nextgroup=railslogModelNum,railslogEscapeMN skipwhite contained - syn match railslogEscapeSQL '\e\[[0-9;]*m' conceal nextgroup=railslogSQL,railslogEscapeSQL skipwhite contained - else - syn match railslogEscape '\e\[[0-9;]*m' - syn match railslogEscapeMN '\e\[[0-9;]*m' nextgroup=railslogModelNum,railslogEscapeMN skipwhite contained - syn match railslogEscapeSQL '\e\[[0-9;]*m' nextgroup=railslogSQL,railslogEscapeSQL skipwhite contained - endif - syn match railslogRender '\%(^\s*\%(\e\[[0-9;]*m\)\=\)\@<=\%(Processing\|Rendering\|Rendered\|Redirected\|Completed\)\>' - syn match railslogComment '^\s*# .*' - syn match railslogModel '\%(^\s*\%(\e\[[0-9;]*m\)\=\)\@<=\u\%(\w\|:\)* \%(Load\%( Including Associations\| IDs For Limited Eager Loading\)\=\|Columns\|Count\|Create\|Update\|Destroy\|Delete all\)\>' skipwhite nextgroup=railslogModelNum,railslogEscapeMN - syn match railslogModel '\%(^\s*\%(\e\[[0-9;]*m\)\=\)\@<=SQL\>' skipwhite nextgroup=railslogModelNum,railslogEscapeMN - syn region railslogModelNum start='(' end=')' contains=railslogNumber contained skipwhite nextgroup=railslogSQL,railslogEscapeSQL - syn match railslogSQL '\u[^\e]*' contained - " Destroy generates multiline SQL, ugh - syn match railslogSQL '\%(^ \%(\e\[[0-9;]*m\)\=\)\@<=\%(FROM\|WHERE\|ON\|AND\|OR\|ORDER\) .*$' - syn match railslogNumber '\<\d\+\>%' - syn match railslogNumber '[ (]\@<=\<\d\+\.\d\+\>\.\@!' - syn region railslogString start='"' skip='\\"' end='"' oneline contained - syn region railslogHash start='{' end='}' oneline contains=railslogHash,railslogString - syn match railslogIP '\<\d\{1,3\}\%(\.\d\{1,3}\)\{3\}\>' - syn match railslogTimestamp '\<\d\d\d\d-\d\d-\d\d \d\d:\d\d:\d\d\>' - syn match railslogSessionID '\<\x\{32\}\>' - syn match railslogIdentifier '^\s*\%(Session ID\|Parameters\)\ze:' - syn match railslogSuccess '\<2\d\d \u[A-Za-z0-9 ]*\>' - syn match railslogRedirect '\<3\d\d \u[A-Za-z0-9 ]*\>' - syn match railslogError '\<[45]\d\d \u[A-Za-z0-9 ]*\>' - syn match railslogError '^DEPRECATION WARNING\>' - syn keyword railslogHTTP OPTIONS GET HEAD POST PUT DELETE TRACE CONNECT - syn region railslogStackTrace start=":\d\+:in `\w\+'$" end="^\s*$" keepend fold - hi def link railslogEscapeMN railslogEscape - hi def link railslogEscapeSQL railslogEscape - hi def link railslogEscape Ignore - hi def link railslogComment Comment - hi def link railslogRender Keyword - hi def link railslogModel Type - hi def link railslogSQL PreProc - hi def link railslogNumber Number - hi def link railslogString String - hi def link railslogSessionID Constant - hi def link railslogIdentifier Identifier - hi def link railslogRedirect railslogSuccess - hi def link railslogSuccess Special - hi def link railslogError Error - hi def link railslogHTTP Special -endfunction - -" }}}1 -" Mappings {{{1 - -function! s:BufMappings() - nnoremap RailsFind :call Find(v:count1,'E') - nnoremap RailsSplitFind :call Find(v:count1,'S') - nnoremap RailsVSplitFind :call Find(v:count1,'V') - nnoremap RailsTabFind :call Find(v:count1,'T') - if g:rails_mappings - if !hasmapto("RailsFind") - nmap gf RailsFind - endif - if !hasmapto("RailsSplitFind") - nmap f RailsSplitFind - endif - if !hasmapto("RailsTabFind") - nmap gf RailsTabFind - endif - if exists("$CREAM") - imap RailsFind - imap RailsAlternate - imap RailsRelated - endif - endif - " SelectBuf you're a dirty hack - let v:errmsg = "" -endfunction - -" }}}1 -" Database {{{1 - -function! s:extractdbvar(str,arg) - return matchstr("\n".a:str."\n",'\n'.a:arg.'=\zs.\{-\}\ze\n') -endfunction - -function! s:app_dbext_settings(environment) dict - if self.cache.needs('dbext_settings') - call self.cache.set('dbext_settings',{}) - endif - let cache = self.cache.get('dbext_settings') - if !has_key(cache,a:environment) - let dict = {} - if self.has_file("config/database.yml") - let cmdb = 'require %{yaml}; File.open(%q{'.self.path().'/config/database.yml}) {|f| y = YAML::load(f); e = y[%{' - let cmde = '}]; i=0; e=y[e] while e.respond_to?(:to_str) && (i+=1)<16; e.each{|k,v|puts k.to_s+%{=}+v.to_s}}' - let out = self.lightweight_ruby_eval(cmdb.a:environment.cmde) - let adapter = s:extractdbvar(out,'adapter') - let adapter = get({'mysql2': 'mysql', 'postgresql': 'pgsql', 'sqlite3': 'sqlite', 'sqlserver': 'sqlsrv', 'sybase': 'asa', 'oracle': 'ora'},adapter,adapter) - let dict['type'] = toupper(adapter) - let dict['user'] = s:extractdbvar(out,'username') - let dict['passwd'] = s:extractdbvar(out,'password') - if dict['passwd'] == '' && adapter == 'mysql' - " Hack to override password from .my.cnf - let dict['extra'] = ' --password=' - else - let dict['extra'] = '' - endif - let dict['dbname'] = s:extractdbvar(out,'database') - if dict['dbname'] == '' - let dict['dbname'] = s:extractdbvar(out,'dbfile') - endif - if dict['dbname'] != '' && dict['dbname'] !~ '^:' && adapter =~? '^sqlite' - let dict['dbname'] = self.path(dict['dbname']) - endif - let dict['profile'] = '' - if adapter == 'ora' - let dict['srvname'] = s:extractdbvar(out,'database') - else - let dict['srvname'] = s:extractdbvar(out,'host') - endif - let dict['host'] = s:extractdbvar(out,'host') - let dict['port'] = s:extractdbvar(out,'port') - let dict['dsnname'] = s:extractdbvar(out,'dsn') - if dict['host'] =~? '^\cDBI:' - if dict['host'] =~? '\c\' - let dict['integratedlogin'] = 1 - endif - let dict['host'] = matchstr(dict['host'],'\c\<\%(Server\|Data Source\)\s*=\s*\zs[^;]*') - endif - call filter(dict,'v:val != ""') - endif - let cache[a:environment] = dict - endif - return cache[a:environment] -endfunction - -function! s:BufDatabase(...) - if exists("s:lock_database") || !exists('g:loaded_dbext') || !exists('b:rails_root') - return - endif - let self = rails#app() - let s:lock_database = 1 - if (a:0 && a:1 > 1) - call self.cache.clear('dbext_settings') - endif - if (a:0 > 1 && a:2 != '') - let env = a:2 - else - let env = s:environment() - endif - if (!self.cache.has('dbext_settings') || !has_key(self.cache.get('dbext_settings'),env)) && (a:0 ? a:1 : 0) <= 0 - unlet! s:lock_database - return - endif - let dict = self.dbext_settings(env) - for key in ['type', 'profile', 'bin', 'user', 'passwd', 'dbname', 'srvname', 'host', 'port', 'dsnname', 'extra', 'integratedlogin'] - let b:dbext_{key} = get(dict,key,'') - endfor - if b:dbext_type == 'PGSQL' - let $PGPASSWORD = b:dbext_passwd - elseif exists('$PGPASSWORD') - let $PGPASSWORD = '' - endif - unlet! s:lock_database -endfunction - -call s:add_methods('app', ['dbext_settings']) - -" }}}1 -" Abbreviations {{{1 - -function! s:selectiveexpand(pat,good,default,...) - if a:0 > 0 - let nd = a:1 - else - let nd = "" - endif - let c = nr2char(getchar(0)) - let good = a:good - if c == "" " ^] - return s:sub(good.(a:0 ? " ".a:1 : ''),'\s+$','') - elseif c == "\t" - return good.(a:0 ? " ".a:1 : '') - elseif c =~ a:pat - return good.c.(a:0 ? a:1 : '') - else - return a:default.c - endif -endfunction - -function! s:TheCWord() - let l = s:linepeak() - if l =~ '\<\%(find\|first\|last\|all\|paginate\)\>' - return s:selectiveexpand('..',':conditions => ',':c') - elseif l =~ '\\s*' - return s:selectiveexpand('..',':collection => ',':c') - elseif l =~ '\<\%(url_for\|link_to\|form_tag\)\>' || l =~ ':url\s*=>\s*{\s*' - return s:selectiveexpand('..',':controller => ',':c') - else - return s:selectiveexpand('..',':conditions => ',':c') - endif -endfunction - -function! s:AddSelectiveExpand(abbr,pat,expn,...) - let expn = s:gsub(s:gsub(a:expn ,'[\"|]','\\&'),'\<','\\') - let expn2 = s:gsub(s:gsub(a:0 ? a:1 : '','[\"|]','\\&'),'\<','\\') - if a:0 - exe "inoreabbrev ".a:abbr." =selectiveexpand(".string(a:pat).",\"".expn."\",".string(a:abbr).",\"".expn2."\")" - else - exe "inoreabbrev ".a:abbr." =selectiveexpand(".string(a:pat).",\"".expn."\",".string(a:abbr).")" - endif -endfunction - -function! s:AddTabExpand(abbr,expn) - call s:AddSelectiveExpand(a:abbr,'..',a:expn) -endfunction - -function! s:AddBracketExpand(abbr,expn) - call s:AddSelectiveExpand(a:abbr,'[[.]',a:expn) -endfunction - -function! s:AddColonExpand(abbr,expn) - call s:AddSelectiveExpand(a:abbr,'[:.]',a:expn) -endfunction - -function! s:AddParenExpand(abbr,expn,...) - if a:0 - call s:AddSelectiveExpand(a:abbr,'(',a:expn,a:1) - else - call s:AddSelectiveExpand(a:abbr,'(',a:expn,'') - endif -endfunction - -function! s:BufAbbreviations() - command! -buffer -bar -nargs=* -bang Rabbrev :call s:Abbrev(0,) - " Some of these were cherry picked from the TextMate snippets - if g:rails_abbreviations - let buffer = rails#buffer() - " Limit to the right filetypes. But error on the liberal side - if buffer.type_name('controller','view','helper','test-functional','test-integration') - Rabbrev pa[ params - Rabbrev rq[ request - Rabbrev rs[ response - Rabbrev se[ session - Rabbrev hd[ headers - Rabbrev coo[ cookies - Rabbrev fl[ flash - Rabbrev rr( render - Rabbrev ra( render :action\ =>\ - Rabbrev rc( render :controller\ =>\ - Rabbrev rf( render :file\ =>\ - Rabbrev ri( render :inline\ =>\ - Rabbrev rj( render :json\ =>\ - Rabbrev rl( render :layout\ =>\ - Rabbrev rp( render :partial\ =>\ - Rabbrev rt( render :text\ =>\ - Rabbrev rx( render :xml\ =>\ - endif - if buffer.type_name('view','helper') - Rabbrev dotiw distance_of_time_in_words - Rabbrev taiw time_ago_in_words - endif - if buffer.type_name('controller') - Rabbrev re( redirect_to - Rabbrev rea( redirect_to :action\ =>\ - Rabbrev rec( redirect_to :controller\ =>\ - Rabbrev rst( respond_to - endif - if buffer.type_name() ==# 'model' || buffer.type_name('model-arb') - Rabbrev bt( belongs_to - Rabbrev ho( has_one - Rabbrev hm( has_many - Rabbrev habtm( has_and_belongs_to_many - Rabbrev co( composed_of - Rabbrev va( validates_associated - Rabbrev vb( validates_acceptance_of - Rabbrev vc( validates_confirmation_of - Rabbrev ve( validates_exclusion_of - Rabbrev vf( validates_format_of - Rabbrev vi( validates_inclusion_of - Rabbrev vl( validates_length_of - Rabbrev vn( validates_numericality_of - Rabbrev vp( validates_presence_of - Rabbrev vu( validates_uniqueness_of - endif - if buffer.type_name('db-migration','db-schema') - Rabbrev mac( add_column - Rabbrev mrnc( rename_column - Rabbrev mrc( remove_column - Rabbrev mct( create_table - Rabbrev mcht( change_table - Rabbrev mrnt( rename_table - Rabbrev mdt( drop_table - Rabbrev mcc( t.column - endif - if buffer.type_name('test') - Rabbrev ase( assert_equal - Rabbrev asko( assert_kind_of - Rabbrev asnn( assert_not_nil - Rabbrev asr( assert_raise - Rabbrev asre( assert_response - Rabbrev art( assert_redirected_to - endif - Rabbrev :a :action\ =>\ - " hax - Rabbrev :c :co________\ =>\ - inoreabbrev :c =TheCWord() - Rabbrev :i :id\ =>\ - Rabbrev :o :object\ =>\ - Rabbrev :p :partial\ =>\ - Rabbrev logd( logger.debug - Rabbrev logi( logger.info - Rabbrev logw( logger.warn - Rabbrev loge( logger.error - Rabbrev logf( logger.fatal - Rabbrev fi( find - Rabbrev AR:: ActiveRecord - Rabbrev AV:: ActionView - Rabbrev AC:: ActionController - Rabbrev AD:: ActionDispatch - Rabbrev AS:: ActiveSupport - Rabbrev AM:: ActionMailer - Rabbrev AO:: ActiveModel - Rabbrev AE:: ActiveResource - endif -endfunction - -function! s:Abbrev(bang,...) abort - if !exists("b:rails_abbreviations") - let b:rails_abbreviations = {} - endif - if a:0 > 3 || (a:bang && (a:0 != 1)) - return s:error("Rabbrev: invalid arguments") - endif - if a:0 == 0 - for key in sort(keys(b:rails_abbreviations)) - echo key . join(b:rails_abbreviations[key],"\t") - endfor - return - endif - let lhs = a:1 - let root = s:sub(lhs,'%(::|\(|\[)$','') - if a:bang - if has_key(b:rails_abbreviations,root) - call remove(b:rails_abbreviations,root) - endif - exe "iunabbrev ".root - return - endif - if a:0 > 3 || a:0 < 2 - return s:error("Rabbrev: invalid arguments") - endif - let rhs = a:2 - if has_key(b:rails_abbreviations,root) - call remove(b:rails_abbreviations,root) - endif - if lhs =~ '($' - let b:rails_abbreviations[root] = ["(", rhs . (a:0 > 2 ? "\t".a:3 : "")] - if a:0 > 2 - call s:AddParenExpand(root,rhs,a:3) - else - call s:AddParenExpand(root,rhs) - endif - return - endif - if a:0 > 2 - return s:error("Rabbrev: invalid arguments") - endif - if lhs =~ ':$' - call s:AddColonExpand(root,rhs) - elseif lhs =~ '\[$' - call s:AddBracketExpand(root,rhs) - elseif lhs =~ '\w$' - call s:AddTabExpand(lhs,rhs) - else - return s:error("Rabbrev: unimplemented") - endif - let b:rails_abbreviations[root] = [matchstr(lhs,'\W*$'),rhs] -endfunction - -" }}}1 -" Settings {{{1 - -function! s:Set(bang,...) - let c = 1 - let defscope = '' - for arg in a:000 - if arg =~? '^<[abgl]\=>$' - let defscope = (matchstr(arg,'<\zs.*\ze>')) - elseif arg !~ '=' - if defscope != '' && arg !~ '^\w:' - let arg = defscope.':'.opt - endif - let val = s:getopt(arg) - if val == '' && !has_key(s:opts(),arg) - call s:error("No such rails.vim option: ".arg) - else - echo arg."=".val - endif - else - let opt = matchstr(arg,'[^=]*') - let val = s:sub(arg,'^[^=]*\=','') - if defscope != '' && opt !~ '^\w:' - let opt = defscope.':'.opt - endif - call s:setopt(opt,val) - endif - endfor -endfunction - -function! s:getopt(opt,...) - let app = rails#app() - let opt = a:opt - if a:0 - let scope = a:1 - elseif opt =~ '^[abgl]:' - let scope = tolower(matchstr(opt,'^\w')) - let opt = s:sub(opt,'^\w:','') - else - let scope = 'abgl' - endif - let lnum = a:0 > 1 ? a:2 : line('.') - if scope =~ 'l' && &filetype != 'ruby' - let scope = s:sub(scope,'l','b') - endif - if scope =~ 'l' - call s:LocalModelines(lnum) - endif - let var = s:sname().'_'.opt - let lastmethod = s:lastmethod(lnum) - if lastmethod == '' | let lastmethod = ' ' | endif - " Get buffer option - if scope =~ 'l' && exists('b:_'.var) && has_key(b:_{var},lastmethod) - return b:_{var}[lastmethod] - elseif exists('b:'.var) && (scope =~ 'b' || (scope =~ 'l' && lastmethod == ' ')) - return b:{var} - elseif scope =~ 'a' && has_key(app,'options') && has_key(app.options,opt) - return app.options[opt] - elseif scope =~ 'g' && exists("g:".s:sname()."_".opt) - return g:{var} - else - return "" - endif -endfunction - -function! s:setopt(opt,val) - let app = rails#app() - if a:opt =~? '[abgl]:' - let scope = matchstr(a:opt,'^\w') - let opt = s:sub(a:opt,'^\w:','') - else - let scope = '' - let opt = a:opt - endif - let defscope = get(s:opts(),opt,'a') - if scope == '' - let scope = defscope - endif - if &filetype != 'ruby' && (scope ==# 'B' || scope ==# 'l') - let scope = 'b' - endif - let var = s:sname().'_'.opt - if opt =~ '\W' - return s:error("Invalid option ".a:opt) - elseif scope ==# 'B' && defscope == 'l' - if !exists('b:_'.var) | let b:_{var} = {} | endif - let b:_{var}[' '] = a:val - elseif scope =~? 'b' - let b:{var} = a:val - elseif scope =~? 'a' - if !has_key(app,'options') | let app.options = {} | endif - let app.options[opt] = a:val - elseif scope =~? 'g' - let g:{var} = a:val - elseif scope =~? 'l' - if !exists('b:_'.var) | let b:_{var} = {} | endif - let lastmethod = s:lastmethod(lnum) - let b:_{var}[lastmethod == '' ? ' ' : lastmethod] = a:val - else - return s:error("Invalid scope for ".a:opt) - endif -endfunction - -function! s:opts() - return {'alternate': 'b', 'controller': 'b', 'gnu_screen': 'a', 'model': 'b', 'preview': 'l', 'task': 'b', 'related': 'l', 'root_url': 'a'} -endfunction - -function! s:Complete_set(A,L,P) - if a:A =~ '=' - let opt = matchstr(a:A,'[^=]*') - return [opt."=".s:getopt(opt)] - else - let extra = matchstr(a:A,'^[abgl]:') - return filter(sort(map(keys(s:opts()),'extra.v:val')),'s:startswith(v:val,a:A)') - endif - return [] -endfunction - -function! s:BufModelines() - if !g:rails_modelines - return - endif - let lines = getline("$")."\n".getline(line("$")-1)."\n".getline(1)."\n".getline(2)."\n".getline(3)."\n" - let pat = '\s\+\zs.\{-\}\ze\%(\n\|\s\s\|#{\@!\|%>\|-->\|$\)' - let cnt = 1 - let mat = matchstr(lines,'\C\ ".mat - endif - let mat = matchstr(lines,'\C\ ".mat - endif - let mat = matchstr(lines,'\C\ 0 - if !exists("g:RAILS_HISTORY") - let g:RAILS_HISTORY = "" - endif - let path = a:path - let g:RAILS_HISTORY = s:scrub(g:RAILS_HISTORY,path) - if has("win32") - let g:RAILS_HISTORY = s:scrub(g:RAILS_HISTORY,s:gsub(path,'\\','/')) - endif - let path = fnamemodify(path,':p:~:h') - let g:RAILS_HISTORY = s:scrub(g:RAILS_HISTORY,path) - if has("win32") - let g:RAILS_HISTORY = s:scrub(g:RAILS_HISTORY,s:gsub(path,'\\','/')) - endif - let g:RAILS_HISTORY = path."\n".g:RAILS_HISTORY - let g:RAILS_HISTORY = s:sub(g:RAILS_HISTORY,'%(.{-}\n){,'.g:rails_history_size.'}\zs.*','') - endif - call app.source_callback("config/syntax.vim") - if expand('%:t') =~ '\.yml\.example$' - setlocal filetype=yaml - elseif expand('%:e') =~ '^\%(rjs\|rxml\|builder\)$' - setlocal filetype=ruby - elseif firsttime - " Activate custom syntax - let &syntax = &syntax - endif - if expand('%:e') == 'log' - nnoremap R :checktime - nnoremap G :checktime$ - nnoremap q :bwipe - setlocal modifiable filetype=railslog noswapfile autoread foldmethod=syntax - if exists('+concealcursor') - setlocal concealcursor=nc conceallevel=2 - else - silent %s/\%(\e\[[0-9;]*m\|\r$\)//ge - endif - setlocal readonly nomodifiable - $ - endif - call s:BufSettings() - call s:BufCommands() - call s:BufAbbreviations() - " snippetsEmu.vim - if exists('g:loaded_snippet') - silent! runtime! ftplugin/rails_snippets.vim - " filetype snippets need to come last for higher priority - exe "silent! runtime! ftplugin/".&filetype."_snippets.vim" - endif - let t = rails#buffer().type_name() - let t = "-".t - let f = '/'.RailsFilePath() - if f =~ '[ !#$%\,]' - let f = '' - endif - runtime! macros/rails.vim - silent doautocmd User Rails - if t != '-' - exe "silent doautocmd User Rails".s:gsub(t,'-','.') - endif - if f != '' - exe "silent doautocmd User Rails".f - endif - call app.source_callback("config/rails.vim") - call s:BufModelines() - call s:BufMappings() - return b:rails_root -endfunction - -function! s:SetBasePath() - let self = rails#buffer() - if self.app().path() =~ '://' - return - endif - let transformed_path = s:pathsplit(s:pathjoin([self.app().path()]))[0] - let add_dot = self.getvar('&path') =~# '^\.\%(,\|$\)' - let old_path = s:pathsplit(s:sub(self.getvar('&path'),'^\.%(,|$)','')) - call filter(old_path,'!s:startswith(v:val,transformed_path)') - - let path = ['app', 'app/models', 'app/controllers', 'app/helpers', 'config', 'lib', 'app/views'] - if self.controller_name() != '' - let path += ['app/views/'.self.controller_name(), 'public'] - endif - if self.app().has('test') - let path += ['test', 'test/unit', 'test/functional', 'test/integration'] - endif - if self.app().has('spec') - let path += ['spec', 'spec/models', 'spec/controllers', 'spec/helpers', 'spec/views', 'spec/lib', 'spec/requests', 'spec/integration'] - endif - let path += ['app/*', 'vendor', 'vendor/plugins/*/lib', 'vendor/plugins/*/test', 'vendor/rails/*/lib', 'vendor/rails/*/test'] - call map(path,'self.app().path(v:val)') - call self.setvar('&path',(add_dot ? '.,' : '').s:pathjoin([self.app().path()],path,old_path)) -endfunction - -function! s:BufSettings() - if !exists('b:rails_root') - return '' - endif - let self = rails#buffer() - call s:SetBasePath() - let rp = s:gsub(self.app().path(),'[ ,]','\\&') - if stridx(&tags,rp.'/tmp/tags') == -1 - let &l:tags = rp . '/tmp/tags,' . &tags . ',' . rp . '/tags' - endif - if has("gui_win32") || has("gui_running") - let code = '*.rb;*.rake;Rakefile' - let templates = '*.'.join(s:view_types,';*.') - let fixtures = '*.yml;*.csv' - let statics = '*.html;*.css;*.js;*.xml;*.xsd;*.sql;.htaccess;README;README_FOR_APP' - let b:browsefilter = "" - \."All Rails Files\t".code.';'.templates.';'.fixtures.';'.statics."\n" - \."Source Code (*.rb, *.rake)\t".code."\n" - \."Templates (*.rhtml, *.rxml, *.rjs)\t".templates."\n" - \."Fixtures (*.yml, *.csv)\t".fixtures."\n" - \."Static Files (*.html, *.css, *.js)\t".statics."\n" - \."All Files (*.*)\t*.*\n" - endif - call self.setvar('&includeexpr','RailsIncludeexpr()') - call self.setvar('&suffixesadd', ".rb,.".join(s:view_types,',.')) - let ft = self.getvar('&filetype') - if ft =~ '^\%(e\=ruby\|[yh]aml\|coffee\|css\|s[ac]ss\|lesscss\)$' - call self.setvar('&shiftwidth',2) - call self.setvar('&softtabstop',2) - call self.setvar('&expandtab',1) - if exists('+completefunc') && self.getvar('&completefunc') == '' - call self.setvar('&completefunc','syntaxcomplete#Complete') - endif - endif - if ft == 'ruby' - call self.setvar('&define',self.define_pattern()) - " This really belongs in after/ftplugin/ruby.vim but we'll be nice - if exists('g:loaded_surround') && self.getvar('surround_101') == '' - call self.setvar('surround_5', "\r\nend") - call self.setvar('surround_69', "\1expr: \1\rend") - call self.setvar('surround_101', "\r\nend") - endif - elseif ft == 'yaml' || fnamemodify(self.name(),':e') == 'yml' - call self.setvar('&define',self.define_pattern()) - elseif ft =~# '^eruby\>' - if exists("g:loaded_allml") - call self.setvar('allml_stylesheet_link_tag', "<%= stylesheet_link_tag '\r' %>") - call self.setvar('allml_javascript_include_tag', "<%= javascript_include_tag '\r' %>") - call self.setvar('allml_doctype_index', 10) - endif - if exists("g:loaded_ragtag") - call self.setvar('ragtag_stylesheet_link_tag', "<%= stylesheet_link_tag '\r' %>") - call self.setvar('ragtag_javascript_include_tag', "<%= javascript_include_tag '\r' %>") - call self.setvar('ragtag_doctype_index', 10) - endif - elseif ft == 'haml' - if exists("g:loaded_allml") - call self.setvar('allml_stylesheet_link_tag', "= stylesheet_link_tag '\r'") - call self.setvar('allml_javascript_include_tag', "= javascript_include_tag '\r'") - call self.setvar('allml_doctype_index', 10) - endif - if exists("g:loaded_ragtag") - call self.setvar('ragtag_stylesheet_link_tag', "= stylesheet_link_tag '\r'") - call self.setvar('ragtag_javascript_include_tag', "= javascript_include_tag '\r'") - call self.setvar('ragtag_doctype_index', 10) - endif - endif - if ft =~# '^eruby\>' || ft ==# 'yaml' - " surround.vim - if exists("g:loaded_surround") - " The idea behind the || part here is that one can normally define the - " surrounding to omit the hyphen (since standard ERuby does not use it) - " but have it added in Rails ERuby files. Unfortunately, this makes it - " difficult if you really don't want a hyphen in Rails ERuby files. If - " this is your desire, you will need to accomplish it via a rails.vim - " autocommand. - if self.getvar('surround_45') == '' || self.getvar('surround_45') == "<% \r %>" " - - call self.setvar('surround_45', "<% \r -%>") - endif - if self.getvar('surround_61') == '' " = - call self.setvar('surround_61', "<%= \r %>") - endif - if self.getvar("surround_35") == '' " # - call self.setvar('surround_35', "<%# \r %>") - endif - if self.getvar('surround_101') == '' || self.getvar('surround_101')== "<% \r %>\n<% end %>" "e - call self.setvar('surround_5', "<% \r -%>\n<% end -%>") - call self.setvar('surround_69', "<% \1expr: \1 -%>\r<% end -%>") - call self.setvar('surround_101', "<% \r -%>\n<% end -%>") - endif - endif - endif -endfunction - -" }}}1 -" Autocommands {{{1 - -augroup railsPluginAuto - autocmd! - autocmd User BufEnterRails call s:RefreshBuffer() - autocmd User BufEnterRails call s:resetomnicomplete() - autocmd User BufEnterRails call s:BufDatabase(-1) - autocmd User dbextPreConnection call s:BufDatabase(1) - autocmd BufWritePost */config/database.yml call rails#cache_clear("dbext_settings") - autocmd BufWritePost */test/test_helper.rb call rails#cache_clear("user_assertions") - autocmd BufWritePost */config/routes.rb call rails#cache_clear("named_routes") - autocmd BufWritePost */config/environment.rb call rails#cache_clear("default_locale") - autocmd BufWritePost */config/environments/*.rb call rails#cache_clear("environments") - autocmd BufWritePost */tasks/**.rake call rails#cache_clear("rake_tasks") - autocmd BufWritePost */generators/** call rails#cache_clear("generators") - autocmd FileType * if exists("b:rails_root") | call s:BufSettings() | endif - autocmd Syntax ruby,eruby,yaml,haml,javascript,coffee,railslog if exists("b:rails_root") | call s:BufSyntax() | endif - autocmd QuickFixCmdPre *make* call s:push_chdir() - autocmd QuickFixCmdPost *make* call s:pop_command() -augroup END - -" }}}1 -" Initialization {{{1 - -map xx xx -let s:sid = s:sub(maparg("xx"),'xx$','') -unmap xx -let s:file = expand(':p') - -if !exists('s:apps') - let s:apps = {} -endif - -" }}}1 - -let &cpo = s:cpo_save - -" vim:set sw=2 sts=2: diff --git a/vim/autoload/snipMate.vim b/vim/autoload/snipMate.vim deleted file mode 100644 index 0ad5a58..0000000 --- a/vim/autoload/snipMate.vim +++ /dev/null @@ -1,435 +0,0 @@ -fun! Filename(...) - let filename = expand('%:t:r') - if filename == '' | return a:0 == 2 ? a:2 : '' | endif - return !a:0 || a:1 == '' ? filename : substitute(a:1, '$1', filename, 'g') -endf - -fun s:RemoveSnippet() - unl! g:snipPos s:curPos s:snipLen s:endCol s:endLine s:prevLen - \ s:lastBuf s:oldWord - if exists('s:update') - unl s:startCol s:origWordLen s:update - if exists('s:oldVars') | unl s:oldVars s:oldEndCol | endif - endif - aug! snipMateAutocmds -endf - -fun snipMate#expandSnip(snip, col) - let lnum = line('.') | let col = a:col - - let snippet = s:ProcessSnippet(a:snip) - " Avoid error if eval evaluates to nothing - if snippet == '' | return '' | endif - - " Expand snippet onto current position with the tab stops removed - let snipLines = split(substitute(snippet, '$\d\+\|${\d\+.\{-}}', '', 'g'), "\n", 1) - - let line = getline(lnum) - let afterCursor = strpart(line, col - 1) - " Keep text after the cursor - if afterCursor != "\t" && afterCursor != ' ' - let line = strpart(line, 0, col - 1) - let snipLines[-1] .= afterCursor - else - let afterCursor = '' - " For some reason the cursor needs to move one right after this - if line != '' && col == 1 && &ve != 'all' && &ve != 'onemore' - let col += 1 - endif - endif - - call setline(lnum, line.snipLines[0]) - - " Autoindent snippet according to previous indentation - let indent = matchend(line, '^.\{-}\ze\(\S\|$\)') + 1 - call append(lnum, map(snipLines[1:], "'".strpart(line, 0, indent - 1)."'.v:val")) - - " Open any folds snippet expands into - if &fen | sil! exe lnum.','.(lnum + len(snipLines) - 1).'foldopen' | endif - - let [g:snipPos, s:snipLen] = s:BuildTabStops(snippet, lnum, col - indent, indent) - - if s:snipLen - aug snipMateAutocmds - au CursorMovedI * call s:UpdateChangedSnip(0) - au InsertEnter * call s:UpdateChangedSnip(1) - aug END - let s:lastBuf = bufnr(0) " Only expand snippet while in current buffer - let s:curPos = 0 - let s:endCol = g:snipPos[s:curPos][1] - let s:endLine = g:snipPos[s:curPos][0] - - call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1]) - let s:prevLen = [line('$'), col('$')] - if g:snipPos[s:curPos][2] != -1 | return s:SelectWord() | endif - else - unl g:snipPos s:snipLen - " Place cursor at end of snippet if no tab stop is given - let newlines = len(snipLines) - 1 - call cursor(lnum + newlines, indent + len(snipLines[-1]) - len(afterCursor) - \ + (newlines ? 0: col - 1)) - endif - return '' -endf - -" Prepare snippet to be processed by s:BuildTabStops -fun s:ProcessSnippet(snip) - let snippet = a:snip - " Evaluate eval (`...`) expressions. - " Backquotes prefixed with a backslash "\" are ignored. - " Using a loop here instead of a regex fixes a bug with nested "\=". - if stridx(snippet, '`') != -1 - while match(snippet, '\(^\|[^\\]\)`.\{-}[^\\]`') != -1 - let snippet = substitute(snippet, '\(^\|[^\\]\)\zs`.\{-}[^\\]`\ze', - \ substitute(eval(matchstr(snippet, '\(^\|[^\\]\)`\zs.\{-}[^\\]\ze`')), - \ "\n\\%$", '', ''), '') - endw - let snippet = substitute(snippet, "\r", "\n", 'g') - let snippet = substitute(snippet, '\\`', '`', 'g') - endif - - " Place all text after a colon in a tab stop after the tab stop - " (e.g. "${#:foo}" becomes "${:foo}foo"). - " This helps tell the position of the tab stops later. - let snippet = substitute(snippet, '${\d\+:\(.\{-}\)}', '&\1', 'g') - - " Update the a:snip so that all the $# become the text after - " the colon in their associated ${#}. - " (e.g. "${1:foo}" turns all "$1"'s into "foo") - let i = 1 - while stridx(snippet, '${'.i) != -1 - let s = matchstr(snippet, '${'.i.':\zs.\{-}\ze}') - if s != '' - let snippet = substitute(snippet, '$'.i, s.'&', 'g') - endif - let i += 1 - endw - - if &et " Expand tabs to spaces if 'expandtab' is set. - return substitute(snippet, '\t', repeat(' ', &sts ? &sts : &sw), 'g') - endif - return snippet -endf - -" Counts occurences of haystack in needle -fun s:Count(haystack, needle) - let counter = 0 - let index = stridx(a:haystack, a:needle) - while index != -1 - let index = stridx(a:haystack, a:needle, index+1) - let counter += 1 - endw - return counter -endf - -" Builds a list of a list of each tab stop in the snippet containing: -" 1.) The tab stop's line number. -" 2.) The tab stop's column number -" (by getting the length of the string between the last "\n" and the -" tab stop). -" 3.) The length of the text after the colon for the current tab stop -" (e.g. "${1:foo}" would return 3). If there is no text, -1 is returned. -" 4.) If the "${#:}" construct is given, another list containing all -" the matches of "$#", to be replaced with the placeholder. This list is -" composed the same way as the parent; the first item is the line number, -" and the second is the column. -fun s:BuildTabStops(snip, lnum, col, indent) - let snipPos = [] - let i = 1 - let withoutVars = substitute(a:snip, '$\d\+', '', 'g') - while stridx(a:snip, '${'.i) != -1 - let beforeTabStop = matchstr(withoutVars, '^.*\ze${'.i.'\D') - let withoutOthers = substitute(withoutVars, '${\('.i.'\D\)\@!\d\+.\{-}}', '', 'g') - - let j = i - 1 - call add(snipPos, [0, 0, -1]) - let snipPos[j][0] = a:lnum + s:Count(beforeTabStop, "\n") - let snipPos[j][1] = a:indent + len(matchstr(withoutOthers, '.*\(\n\|^\)\zs.*\ze${'.i.'\D')) - if snipPos[j][0] == a:lnum | let snipPos[j][1] += a:col | endif - - " Get all $# matches in another list, if ${#:name} is given - if stridx(withoutVars, '${'.i.':') != -1 - let snipPos[j][2] = len(matchstr(withoutVars, '${'.i.':\zs.\{-}\ze}')) - let dots = repeat('.', snipPos[j][2]) - call add(snipPos[j], []) - let withoutOthers = substitute(a:snip, '${\d\+.\{-}}\|$'.i.'\@!\d\+', '', 'g') - while match(withoutOthers, '$'.i.'\(\D\|$\)') != -1 - let beforeMark = matchstr(withoutOthers, '^.\{-}\ze'.dots.'$'.i.'\(\D\|$\)') - call add(snipPos[j][3], [0, 0]) - let snipPos[j][3][-1][0] = a:lnum + s:Count(beforeMark, "\n") - let snipPos[j][3][-1][1] = a:indent + (snipPos[j][3][-1][0] > a:lnum - \ ? len(matchstr(beforeMark, '.*\n\zs.*')) - \ : a:col + len(beforeMark)) - let withoutOthers = substitute(withoutOthers, '$'.i.'\ze\(\D\|$\)', '', '') - endw - endif - let i += 1 - endw - return [snipPos, i - 1] -endf - -fun snipMate#jumpTabStop(backwards) - let leftPlaceholder = exists('s:origWordLen') - \ && s:origWordLen != g:snipPos[s:curPos][2] - if leftPlaceholder && exists('s:oldEndCol') - let startPlaceholder = s:oldEndCol + 1 - endif - - if exists('s:update') - call s:UpdatePlaceholderTabStops() - else - call s:UpdateTabStops() - endif - - " Don't reselect placeholder if it has been modified - if leftPlaceholder && g:snipPos[s:curPos][2] != -1 - if exists('startPlaceholder') - let g:snipPos[s:curPos][1] = startPlaceholder - else - let g:snipPos[s:curPos][1] = col('.') - let g:snipPos[s:curPos][2] = 0 - endif - endif - - let s:curPos += a:backwards ? -1 : 1 - " Loop over the snippet when going backwards from the beginning - if s:curPos < 0 | let s:curPos = s:snipLen - 1 | endif - - if s:curPos == s:snipLen - let sMode = s:endCol == g:snipPos[s:curPos-1][1]+g:snipPos[s:curPos-1][2] - call s:RemoveSnippet() - return sMode ? "\" : TriggerSnippet() - endif - - call cursor(g:snipPos[s:curPos][0], g:snipPos[s:curPos][1]) - - let s:endLine = g:snipPos[s:curPos][0] - let s:endCol = g:snipPos[s:curPos][1] - let s:prevLen = [line('$'), col('$')] - - return g:snipPos[s:curPos][2] == -1 ? '' : s:SelectWord() -endf - -fun s:UpdatePlaceholderTabStops() - let changeLen = s:origWordLen - g:snipPos[s:curPos][2] - unl s:startCol s:origWordLen s:update - if !exists('s:oldVars') | return | endif - " Update tab stops in snippet if text has been added via "$#" - " (e.g., in "${1:foo}bar$1${2}"). - if changeLen != 0 - let curLine = line('.') - - for pos in g:snipPos - if pos == g:snipPos[s:curPos] | continue | endif - let changed = pos[0] == curLine && pos[1] > s:oldEndCol - let changedVars = 0 - let endPlaceholder = pos[2] - 1 + pos[1] - " Subtract changeLen from each tab stop that was after any of - " the current tab stop's placeholders. - for [lnum, col] in s:oldVars - if lnum > pos[0] | break | endif - if pos[0] == lnum - if pos[1] > col || (pos[2] == -1 && pos[1] == col) - let changed += 1 - elseif col < endPlaceholder - let changedVars += 1 - endif - endif - endfor - let pos[1] -= changeLen * changed - let pos[2] -= changeLen * changedVars " Parse variables within placeholders - " e.g., "${1:foo} ${2:$1bar}" - - if pos[2] == -1 | continue | endif - " Do the same to any placeholders in the other tab stops. - for nPos in pos[3] - let changed = nPos[0] == curLine && nPos[1] > s:oldEndCol - for [lnum, col] in s:oldVars - if lnum > nPos[0] | break | endif - if nPos[0] == lnum && nPos[1] > col - let changed += 1 - endif - endfor - let nPos[1] -= changeLen * changed - endfor - endfor - endif - unl s:endCol s:oldVars s:oldEndCol -endf - -fun s:UpdateTabStops() - let changeLine = s:endLine - g:snipPos[s:curPos][0] - let changeCol = s:endCol - g:snipPos[s:curPos][1] - if exists('s:origWordLen') - let changeCol -= s:origWordLen - unl s:origWordLen - endif - let lnum = g:snipPos[s:curPos][0] - let col = g:snipPos[s:curPos][1] - " Update the line number of all proceeding tab stops if has - " been inserted. - if changeLine != 0 - let changeLine -= 1 - for pos in g:snipPos - if pos[0] >= lnum - if pos[0] == lnum | let pos[1] += changeCol | endif - let pos[0] += changeLine - endif - if pos[2] == -1 | continue | endif - for nPos in pos[3] - if nPos[0] >= lnum - if nPos[0] == lnum | let nPos[1] += changeCol | endif - let nPos[0] += changeLine - endif - endfor - endfor - elseif changeCol != 0 - " Update the column of all proceeding tab stops if text has - " been inserted/deleted in the current line. - for pos in g:snipPos - if pos[1] >= col && pos[0] == lnum - let pos[1] += changeCol - endif - if pos[2] == -1 | continue | endif - for nPos in pos[3] - if nPos[0] > lnum | break | endif - if nPos[0] == lnum && nPos[1] >= col - let nPos[1] += changeCol - endif - endfor - endfor - endif -endf - -fun s:SelectWord() - let s:origWordLen = g:snipPos[s:curPos][2] - let s:oldWord = strpart(getline('.'), g:snipPos[s:curPos][1] - 1, - \ s:origWordLen) - let s:prevLen[1] -= s:origWordLen - if !empty(g:snipPos[s:curPos][3]) - let s:update = 1 - let s:endCol = -1 - let s:startCol = g:snipPos[s:curPos][1] - 1 - endif - if !s:origWordLen | return '' | endif - let l = col('.') != 1 ? 'l' : '' - if &sel == 'exclusive' - return "\".l.'v'.s:origWordLen."l\" - endif - return s:origWordLen == 1 ? "\".l.'gh' - \ : "\".l.'v'.(s:origWordLen - 1)."l\" -endf - -" This updates the snippet as you type when text needs to be inserted -" into multiple places (e.g. in "${1:default text}foo$1bar$1", -" "default text" would be highlighted, and if the user types something, -" UpdateChangedSnip() would be called so that the text after "foo" & "bar" -" are updated accordingly) -" -" It also automatically quits the snippet if the cursor is moved out of it -" while in insert mode. -fun s:UpdateChangedSnip(entering) - if exists('g:snipPos') && bufnr(0) != s:lastBuf - call s:RemoveSnippet() - elseif exists('s:update') " If modifying a placeholder - if !exists('s:oldVars') && s:curPos + 1 < s:snipLen - " Save the old snippet & word length before it's updated - " s:startCol must be saved too, in case text is added - " before the snippet (e.g. in "foo$1${2}bar${1:foo}"). - let s:oldEndCol = s:startCol - let s:oldVars = deepcopy(g:snipPos[s:curPos][3]) - endif - let col = col('.') - 1 - - if s:endCol != -1 - let changeLen = col('$') - s:prevLen[1] - let s:endCol += changeLen - else " When being updated the first time, after leaving select mode - if a:entering | return | endif - let s:endCol = col - 1 - endif - - " If the cursor moves outside the snippet, quit it - if line('.') != g:snipPos[s:curPos][0] || col < s:startCol || - \ col - 1 > s:endCol - unl! s:startCol s:origWordLen s:oldVars s:update - return s:RemoveSnippet() - endif - - call s:UpdateVars() - let s:prevLen[1] = col('$') - elseif exists('g:snipPos') - if !a:entering && g:snipPos[s:curPos][2] != -1 - let g:snipPos[s:curPos][2] = -2 - endif - - let col = col('.') - let lnum = line('.') - let changeLine = line('$') - s:prevLen[0] - - if lnum == s:endLine - let s:endCol += col('$') - s:prevLen[1] - let s:prevLen = [line('$'), col('$')] - endif - if changeLine != 0 - let s:endLine += changeLine - let s:endCol = col - endif - - " Delete snippet if cursor moves out of it in insert mode - if (lnum == s:endLine && (col > s:endCol || col < g:snipPos[s:curPos][1])) - \ || lnum > s:endLine || lnum < g:snipPos[s:curPos][0] - call s:RemoveSnippet() - endif - endif -endf - -" This updates the variables in a snippet when a placeholder has been edited. -" (e.g., each "$1" in "${1:foo} $1bar $1bar") -fun s:UpdateVars() - let newWordLen = s:endCol - s:startCol + 1 - let newWord = strpart(getline('.'), s:startCol, newWordLen) - if newWord == s:oldWord || empty(g:snipPos[s:curPos][3]) - return - endif - - let changeLen = g:snipPos[s:curPos][2] - newWordLen - let curLine = line('.') - let startCol = col('.') - let oldStartSnip = s:startCol - let updateTabStops = changeLen != 0 - let i = 0 - - for [lnum, col] in g:snipPos[s:curPos][3] - if updateTabStops - let start = s:startCol - if lnum == curLine && col <= start - let s:startCol -= changeLen - let s:endCol -= changeLen - endif - for nPos in g:snipPos[s:curPos][3][(i):] - " This list is in ascending order, so quit if we've gone too far. - if nPos[0] > lnum | break | endif - if nPos[0] == lnum && nPos[1] > col - let nPos[1] -= changeLen - endif - endfor - if lnum == curLine && col > start - let col -= changeLen - let g:snipPos[s:curPos][3][i][1] = col - endif - let i += 1 - endif - - " "Very nomagic" is used here to allow special characters. - call setline(lnum, substitute(getline(lnum), '\%'.col.'c\V'. - \ escape(s:oldWord, '\'), escape(newWord, '\&'), '')) - endfor - if oldStartSnip != s:startCol - call cursor(0, startCol + s:startCol - oldStartSnip) - endif - - let s:oldWord = newWord - let g:snipPos[s:curPos][2] = newWordLen -endf -" vim:noet:sw=4:ts=4:ft=vim diff --git a/vim/autoload/syntastic.vim b/vim/autoload/syntastic.vim deleted file mode 100644 index a477736..0000000 --- a/vim/autoload/syntastic.vim +++ /dev/null @@ -1,24 +0,0 @@ - -function! syntastic#ErrorBalloonExpr() - if !exists('b:syntastic_balloons') | return '' | endif - return get(b:syntastic_balloons, v:beval_lnum, '') -endfunction - -function! syntastic#HighlightErrors(errors, termfunc, ...) - call clearmatches() - let forcecb = a:0 && a:1 - for item in a:errors - let group = item['type'] == 'E' ? 'SpellBad' : 'SpellCap' - if item['col'] && !forcecb - let lastcol = col([item['lnum'], '$']) - let lcol = min([lastcol, item['col']]) - call matchadd(group, '\%'.item['lnum'].'l\%'.lcol.'c') - else - let term = a:termfunc(item) - if len(term) > 0 - call matchadd(group, '\%' . item['lnum'] . 'l' . term) - endif - endif - endfor -endfunction - diff --git a/vim/autoload/syntastic/c.vim b/vim/autoload/syntastic/c.vim deleted file mode 100644 index c7232df..0000000 --- a/vim/autoload/syntastic/c.vim +++ /dev/null @@ -1,171 +0,0 @@ -if exists("g:loaded_syntastic_c_autoload") - finish -endif -let g:loaded_syntastic_c_autoload = 1 - -let s:save_cpo = &cpo -set cpo&vim - -" initialize c/cpp syntax checker handlers -function! s:Init() - let s:handlers = [] - let s:cflags = {} - - call s:RegHandler('gtk', 'syntastic#c#CheckPKG', - \ ['gtk', 'gtk+-2.0', 'gtk+', 'glib-2.0', 'glib']) - call s:RegHandler('glib', 'syntastic#c#CheckPKG', - \ ['glib', 'glib-2.0', 'glib']) - call s:RegHandler('glade', 'syntastic#c#CheckPKG', - \ ['glade', 'libglade-2.0', 'libglade']) - call s:RegHandler('libsoup', 'syntastic#c#CheckPKG', - \ ['libsoup', 'libsoup-2.4', 'libsoup-2.2']) - call s:RegHandler('webkit', 'syntastic#c#CheckPKG', - \ ['webkit', 'webkit-1.0']) - call s:RegHandler('cairo', 'syntastic#c#CheckPKG', - \ ['cairo', 'cairo']) - call s:RegHandler('pango', 'syntastic#c#CheckPKG', - \ ['pango', 'pango']) - call s:RegHandler('libxml', 'syntastic#c#CheckPKG', - \ ['libxml', 'libxml-2.0', 'libxml']) - call s:RegHandler('freetype', 'syntastic#c#CheckPKG', - \ ['freetype', 'freetype2', 'freetype']) - call s:RegHandler('SDL', 'syntastic#c#CheckPKG', - \ ['sdl', 'sdl']) - call s:RegHandler('opengl', 'syntastic#c#CheckPKG', - \ ['opengl', 'gl']) - call s:RegHandler('ruby', 'syntastic#c#CheckRuby', []) - call s:RegHandler('Python\.h', 'syntastic#c#CheckPython', []) - call s:RegHandler('php\.h', 'syntastic#c#CheckPhp', []) -endfunction - -" search the first 100 lines for include statements that are -" given in the handlers dictionary -function! syntastic#c#SearchHeaders() - let includes = '' - let files = [] - let found = [] - let lines = filter(getline(1, 100), 'v:val =~# "#\s*include"') - - " search current buffer - for line in lines - let file = matchstr(line, '"\zs\S\+\ze"') - if file != '' - call add(files, file) - continue - endif - for handler in s:handlers - if line =~# handler["regex"] - let includes .= call(handler["func"], handler["args"]) - call add(found, handler["regex"]) - break - endif - endfor - endfor - - " search included headers - for hfile in files - if hfile != '' - let filename = expand('%:p:h') . ((has('win32') || has('win64')) ? - \ '\' : '/') . hfile - try - let lines = readfile(filename, '', 100) - catch /E484/ - continue - endtry - let lines = filter(lines, 'v:val =~# "#\s*include"') - for handler in s:handlers - if index(found, handler["regex"]) != -1 - continue - endif - for line in lines - if line =~# handler["regex"] - let includes .= call(handler["func"], handler["args"]) - call add(found, handler["regex"]) - break - endif - endfor - endfor - endif - endfor - - return includes -endfunction - -" try to find library with 'pkg-config' -" search possible libraries from first to last given -" argument until one is found -function! syntastic#c#CheckPKG(name, ...) - if executable('pkg-config') - if !has_key(s:cflags, a:name) - for i in range(a:0) - let l:cflags = system('pkg-config --cflags '.a:000[i]) - " since we cannot necessarily trust the pkg-config exit code - " we have to check for an error output as well - if v:shell_error == 0 && l:cflags !~? 'not found' - let l:cflags = ' '.substitute(l:cflags, "\n", '', '') - let s:cflags[a:name] = l:cflags - return l:cflags - endif - endfor - else - return s:cflags[a:name] - endif - endif - return '' -endfunction - -" try to find PHP includes with 'php-config' -function! syntastic#c#CheckPhp() - if executable('php-config') - if !exists('s:php_flags') - let s:php_flags = system('php-config --includes') - let s:php_flags = ' ' . substitute(s:php_flags, "\n", '', '') - endif - return s:php_flags - endif - return '' -endfunction - -" try to find the ruby headers with 'rbconfig' -function! syntastic#c#CheckRuby() - if executable('ruby') - if !exists('s:ruby_flags') - let s:ruby_flags = system('ruby -r rbconfig -e ' - \ . '''puts Config::CONFIG["archdir"]''') - let s:ruby_flags = substitute(s:ruby_flags, "\n", '', '') - let s:ruby_flags = ' -I' . s:ruby_flags - endif - return s:ruby_flags - endif - return '' -endfunction - -" try to find the python headers with distutils -function! syntastic#c#CheckPython() - if executable('python') - if !exists('s:python_flags') - let s:python_flags = system('python -c ''from distutils import ' - \ . 'sysconfig; import sys; sys.stdout.write(sysconfig.get_python_inc())''') - let s:python_flags = substitute(s:python_flags, "\n", '', '') - let s:python_flags = ' -I' . s:python_flags - endif - return s:python_flags - endif - return '' -endfunction - -" return a handler dictionary object -function! s:RegHandler(regex, function, args) - let handler = {} - let handler["regex"] = a:regex - let handler["func"] = function(a:function) - let handler["args"] = a:args - call add(s:handlers, handler) -endfunction - -call s:Init() - -let &cpo = s:save_cpo -unlet s:save_cpo - -" vim: set et sts=4 sw=4: diff --git a/vim/autoload/tagbar.vim b/vim/autoload/tagbar.vim deleted file mode 100644 index 48ad320..0000000 --- a/vim/autoload/tagbar.vim +++ /dev/null @@ -1,3099 +0,0 @@ -" ============================================================================ -" File: tagbar.vim -" Description: List the current file's tags in a sidebar, ordered by class etc -" Author: Jan Larres -" Licence: Vim licence -" Website: http://majutsushi.github.com/tagbar/ -" Version: 2.3 -" Note: This plugin was heavily inspired by the 'Taglist' plugin by -" Yegappan Lakshmanan and uses a small amount of code from it. -" -" Original taglist copyright notice: -" Permission is hereby granted to use and distribute this code, -" with or without modifications, provided that this copyright -" notice is copied with it. Like anything else that's free, -" taglist.vim is provided *as is* and comes with no warranty of -" any kind, either expressed or implied. In no event will the -" copyright holder be liable for any damamges resulting from the -" use of this software. -" ============================================================================ - -scriptencoding utf-8 - -" Initialization {{{1 - -" Basic init {{{2 - -if !exists('g:tagbar_ctags_bin') - if executable('ctags-exuberant') - let g:tagbar_ctags_bin = 'ctags-exuberant' - elseif executable('exuberant-ctags') - let g:tagbar_ctags_bin = 'exuberant-ctags' - elseif executable('exctags') - let g:tagbar_ctags_bin = 'exctags' - elseif has('macunix') && executable('/usr/local/bin/ctags') - " Homebrew default location - let g:tagbar_ctags_bin = '/usr/local/bin/ctags' - elseif has('macunix') && executable('/opt/local/bin/ctags') - " Macports default location - let g:tagbar_ctags_bin = '/opt/local/bin/ctags' - elseif executable('ctags') - let g:tagbar_ctags_bin = 'ctags' - elseif executable('ctags.exe') - let g:tagbar_ctags_bin = 'ctags.exe' - elseif executable('tags') - let g:tagbar_ctags_bin = 'tags' - else - echomsg 'Tagbar: Exuberant ctags not found, skipping plugin' - finish - endif -else - " reset 'wildignore' temporarily in case *.exe is included in it - let wildignore_save = &wildignore - set wildignore& - - let g:tagbar_ctags_bin = expand(g:tagbar_ctags_bin) - - let &wildignore = wildignore_save - - if !executable(g:tagbar_ctags_bin) - echomsg 'Tagbar: Exuberant ctags not found in specified place,' - \ 'skipping plugin' - finish - endif -endif - -redir => s:ftype_out -silent filetype -redir END -if s:ftype_out !~# 'detection:ON' - echomsg 'Tagbar: Filetype detection is turned off, skipping plugin' - unlet s:ftype_out - finish -endif -unlet s:ftype_out - -let s:icon_closed = g:tagbar_iconchars[0] -let s:icon_open = g:tagbar_iconchars[1] - -let s:type_init_done = 0 -let s:autocommands_done = 0 -let s:checked_ctags = 0 -let s:window_expanded = 0 - -let s:access_symbols = { - \ 'public' : '+', - \ 'protected' : '#', - \ 'private' : '-' -\ } - -let g:loaded_tagbar = 1 - -let s:last_highlight_tline = 0 -let s:debug = 0 -let s:debug_file = '' - -" s:Init() {{{2 -function! s:Init() - if !s:type_init_done - call s:InitTypes() - endif - - if !s:checked_ctags - if !s:CheckForExCtags() - return - endif - endif -endfunction - -" s:InitTypes() {{{2 -function! s:InitTypes() - call s:LogDebugMessage('Initializing types') - - let s:known_types = {} - - " Ant {{{3 - let type_ant = {} - let type_ant.ctagstype = 'ant' - let type_ant.kinds = [ - \ {'short' : 'p', 'long' : 'projects', 'fold' : 0}, - \ {'short' : 't', 'long' : 'targets', 'fold' : 0} - \ ] - let s:known_types.ant = type_ant - " Asm {{{3 - let type_asm = {} - let type_asm.ctagstype = 'asm' - let type_asm.kinds = [ - \ {'short' : 'm', 'long' : 'macros', 'fold' : 0}, - \ {'short' : 't', 'long' : 'types', 'fold' : 0}, - \ {'short' : 'd', 'long' : 'defines', 'fold' : 0}, - \ {'short' : 'l', 'long' : 'labels', 'fold' : 0} - \ ] - let s:known_types.asm = type_asm - " ASP {{{3 - let type_aspvbs = {} - let type_aspvbs.ctagstype = 'asp' - let type_aspvbs.kinds = [ - \ {'short' : 'd', 'long' : 'constants', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0} - \ ] - let s:known_types.aspvbs = type_aspvbs - " Awk {{{3 - let type_awk = {} - let type_awk.ctagstype = 'awk' - let type_awk.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let s:known_types.awk = type_awk - " Basic {{{3 - let type_basic = {} - let type_basic.ctagstype = 'basic' - let type_basic.kinds = [ - \ {'short' : 'c', 'long' : 'constants', 'fold' : 0}, - \ {'short' : 'g', 'long' : 'enumerations', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'l', 'long' : 'labels', 'fold' : 0}, - \ {'short' : 't', 'long' : 'types', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0} - \ ] - let s:known_types.basic = type_basic - " BETA {{{3 - let type_beta = {} - let type_beta.ctagstype = 'beta' - let type_beta.kinds = [ - \ {'short' : 'f', 'long' : 'fragments', 'fold' : 0}, - \ {'short' : 's', 'long' : 'slots', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'patterns', 'fold' : 0} - \ ] - let s:known_types.beta = type_beta - " C {{{3 - let type_c = {} - let type_c.ctagstype = 'c' - let type_c.kinds = [ - \ {'short' : 'd', 'long' : 'macros', 'fold' : 1}, - \ {'short' : 'p', 'long' : 'prototypes', 'fold' : 1}, - \ {'short' : 'g', 'long' : 'enums', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0}, - \ {'short' : 't', 'long' : 'typedefs', 'fold' : 0}, - \ {'short' : 's', 'long' : 'structs', 'fold' : 0}, - \ {'short' : 'u', 'long' : 'unions', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'members', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let type_c.sro = '::' - let type_c.kind2scope = { - \ 'g' : 'enum', - \ 's' : 'struct', - \ 'u' : 'union' - \ } - let type_c.scope2kind = { - \ 'enum' : 'g', - \ 'struct' : 's', - \ 'union' : 'u' - \ } - let s:known_types.c = type_c - " C++ {{{3 - let type_cpp = {} - let type_cpp.ctagstype = 'c++' - let type_cpp.kinds = [ - \ {'short' : 'd', 'long' : 'macros', 'fold' : 1}, - \ {'short' : 'p', 'long' : 'prototypes', 'fold' : 1}, - \ {'short' : 'g', 'long' : 'enums', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0}, - \ {'short' : 't', 'long' : 'typedefs', 'fold' : 0}, - \ {'short' : 'n', 'long' : 'namespaces', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 's', 'long' : 'structs', 'fold' : 0}, - \ {'short' : 'u', 'long' : 'unions', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'members', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0} - \ ] - let type_cpp.sro = '::' - let type_cpp.kind2scope = { - \ 'g' : 'enum', - \ 'n' : 'namespace', - \ 'c' : 'class', - \ 's' : 'struct', - \ 'u' : 'union' - \ } - let type_cpp.scope2kind = { - \ 'enum' : 'g', - \ 'namespace' : 'n', - \ 'class' : 'c', - \ 'struct' : 's', - \ 'union' : 'u' - \ } - let s:known_types.cpp = type_cpp - " C# {{{3 - let type_cs = {} - let type_cs.ctagstype = 'c#' - let type_cs.kinds = [ - \ {'short' : 'd', 'long' : 'macros', 'fold' : 1}, - \ {'short' : 'f', 'long' : 'fields', 'fold' : 0}, - \ {'short' : 'g', 'long' : 'enums', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0}, - \ {'short' : 't', 'long' : 'typedefs', 'fold' : 0}, - \ {'short' : 'n', 'long' : 'namespaces', 'fold' : 0}, - \ {'short' : 'i', 'long' : 'interfaces', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 's', 'long' : 'structs', 'fold' : 0}, - \ {'short' : 'E', 'long' : 'events', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'methods', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'properties', 'fold' : 0} - \ ] - let type_cs.sro = '.' - let type_cs.kind2scope = { - \ 'n' : 'namespace', - \ 'i' : 'interface', - \ 'c' : 'class', - \ 's' : 'struct', - \ 'g' : 'enum' - \ } - let type_cs.scope2kind = { - \ 'namespace' : 'n', - \ 'interface' : 'i', - \ 'class' : 'c', - \ 'struct' : 's', - \ 'enum' : 'g' - \ } - let s:known_types.cs = type_cs - " COBOL {{{3 - let type_cobol = {} - let type_cobol.ctagstype = 'cobol' - let type_cobol.kinds = [ - \ {'short' : 'd', 'long' : 'data items', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'file descriptions', 'fold' : 0}, - \ {'short' : 'g', 'long' : 'group items', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'paragraphs', 'fold' : 0}, - \ {'short' : 'P', 'long' : 'program ids', 'fold' : 0}, - \ {'short' : 's', 'long' : 'sections', 'fold' : 0} - \ ] - let s:known_types.cobol = type_cobol - " DOS Batch {{{3 - let type_dosbatch = {} - let type_dosbatch.ctagstype = 'dosbatch' - let type_dosbatch.kinds = [ - \ {'short' : 'l', 'long' : 'labels', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0} - \ ] - let s:known_types.dosbatch = type_dosbatch - " Eiffel {{{3 - let type_eiffel = {} - let type_eiffel.ctagstype = 'eiffel' - let type_eiffel.kinds = [ - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'features', 'fold' : 0} - \ ] - let type_eiffel.sro = '.' " Not sure, is nesting even possible? - let type_eiffel.kind2scope = { - \ 'c' : 'class', - \ 'f' : 'feature' - \ } - let type_eiffel.scope2kind = { - \ 'class' : 'c', - \ 'feature' : 'f' - \ } - let s:known_types.eiffel = type_eiffel - " Erlang {{{3 - let type_erlang = {} - let type_erlang.ctagstype = 'erlang' - let type_erlang.kinds = [ - \ {'short' : 'm', 'long' : 'modules', 'fold' : 0}, - \ {'short' : 'd', 'long' : 'macro definitions', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'r', 'long' : 'record definitions', 'fold' : 0} - \ ] - let type_erlang.sro = '.' " Not sure, is nesting even possible? - let type_erlang.kind2scope = { - \ 'm' : 'module' - \ } - let type_erlang.scope2kind = { - \ 'module' : 'm' - \ } - let s:known_types.erlang = type_erlang - " Flex {{{3 - " Vim doesn't support Flex out of the box, this is based on rough - " guesses and probably requires - " http://www.vim.org/scripts/script.php?script_id=2909 - " Improvements welcome! - let type_mxml = {} - let type_mxml.ctagstype = 'flex' - let type_mxml.kinds = [ - \ {'short' : 'v', 'long' : 'global variables', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'methods', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'properties', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'x', 'long' : 'mxtags', 'fold' : 0} - \ ] - let type_mxml.sro = '.' - let type_mxml.kind2scope = { - \ 'c' : 'class' - \ } - let type_mxml.scope2kind = { - \ 'class' : 'c' - \ } - let s:known_types.mxml = type_mxml - " Fortran {{{3 - let type_fortran = {} - let type_fortran.ctagstype = 'fortran' - let type_fortran.kinds = [ - \ {'short' : 'm', 'long' : 'modules', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'programs', 'fold' : 0}, - \ {'short' : 'k', 'long' : 'components', 'fold' : 0}, - \ {'short' : 't', 'long' : 'derived types and structures', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'common blocks', 'fold' : 0}, - \ {'short' : 'b', 'long' : 'block data', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'entry points', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0}, - \ {'short' : 'l', 'long' : 'labels', 'fold' : 0}, - \ {'short' : 'n', 'long' : 'namelists', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0} - \ ] - let type_fortran.sro = '.' " Not sure, is nesting even possible? - let type_fortran.kind2scope = { - \ 'm' : 'module', - \ 'p' : 'program', - \ 'f' : 'function', - \ 's' : 'subroutine' - \ } - let type_fortran.scope2kind = { - \ 'module' : 'm', - \ 'program' : 'p', - \ 'function' : 'f', - \ 'subroutine' : 's' - \ } - let s:known_types.fortran = type_fortran - " HTML {{{3 - let type_html = {} - let type_html.ctagstype = 'html' - let type_html.kinds = [ - \ {'short' : 'f', 'long' : 'JavaScript funtions', 'fold' : 0}, - \ {'short' : 'a', 'long' : 'named anchors', 'fold' : 0} - \ ] - let s:known_types.html = type_html - " Java {{{3 - let type_java = {} - let type_java.ctagstype = 'java' - let type_java.kinds = [ - \ {'short' : 'p', 'long' : 'packages', 'fold' : 1}, - \ {'short' : 'f', 'long' : 'fields', 'fold' : 0}, - \ {'short' : 'g', 'long' : 'enum types', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'enum constants', 'fold' : 0}, - \ {'short' : 'i', 'long' : 'interfaces', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'methods', 'fold' : 0} - \ ] - let type_java.sro = '.' - let type_java.kind2scope = { - \ 'g' : 'enum', - \ 'i' : 'interface', - \ 'c' : 'class' - \ } - let type_java.scope2kind = { - \ 'enum' : 'g', - \ 'interface' : 'i', - \ 'class' : 'c' - \ } - let s:known_types.java = type_java - " JavaScript {{{3 - " JavaScript is weird -- it does have scopes, but ctags doesn't seem to - " properly generate the information for them, instead it simply uses the - " complete name. So ctags has to be fixed before I can do anything here. - " Alternatively jsctags/doctorjs will be used if available. - let type_javascript = {} - let type_javascript.ctagstype = 'javascript' - let jsctags = s:CheckFTCtags('jsctags', 'javascript') - if jsctags != '' - let type_javascript.kinds = [ - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let type_javascript.sro = '.' - let type_javascript.kind2scope = { - \ 'v' : 'namespace', - \ 'f' : 'namespace' - \ } - let type_javascript.scope2kind = { - \ 'namespace' : 'v' - \ } - let type_javascript.ctagsbin = jsctags - let type_javascript.ctagsargs = '-f -' - else - let type_javascript.kinds = [ - \ {'short' : 'v', 'long' : 'global variables', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'properties', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'methods', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - endif - let s:known_types.javascript = type_javascript - " Lisp {{{3 - let type_lisp = {} - let type_lisp.ctagstype = 'lisp' - let type_lisp.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let s:known_types.lisp = type_lisp - " Lua {{{3 - let type_lua = {} - let type_lua.ctagstype = 'lua' - let type_lua.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let s:known_types.lua = type_lua - " Make {{{3 - let type_make = {} - let type_make.ctagstype = 'make' - let type_make.kinds = [ - \ {'short' : 'm', 'long' : 'macros', 'fold' : 0} - \ ] - let s:known_types.make = type_make - " Matlab {{{3 - let type_matlab = {} - let type_matlab.ctagstype = 'matlab' - let type_matlab.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let s:known_types.matlab = type_matlab - " Ocaml {{{3 - let type_ocaml = {} - let type_ocaml.ctagstype = 'ocaml' - let type_ocaml.kinds = [ - \ {'short' : 'M', 'long' : 'modules or functors', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'global variables', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'C', 'long' : 'constructors', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'methods', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'exceptions', 'fold' : 0}, - \ {'short' : 't', 'long' : 'type names', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'r', 'long' : 'structure fields', 'fold' : 0} - \ ] - let type_ocaml.sro = '.' " Not sure, is nesting even possible? - let type_ocaml.kind2scope = { - \ 'M' : 'Module', - \ 'c' : 'class', - \ 't' : 'type' - \ } - let type_ocaml.scope2kind = { - \ 'Module' : 'M', - \ 'class' : 'c', - \ 'type' : 't' - \ } - let s:known_types.ocaml = type_ocaml - " Pascal {{{3 - let type_pascal = {} - let type_pascal.ctagstype = 'pascal' - let type_pascal.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0} - \ ] - let s:known_types.pascal = type_pascal - " Perl {{{3 - let type_perl = {} - let type_perl.ctagstype = 'perl' - let type_perl.kinds = [ - \ {'short' : 'p', 'long' : 'packages', 'fold' : 1}, - \ {'short' : 'c', 'long' : 'constants', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'formats', 'fold' : 0}, - \ {'short' : 'l', 'long' : 'labels', 'fold' : 0}, - \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0} - \ ] - let s:known_types.perl = type_perl - " PHP {{{3 - let type_php = {} - let type_php.ctagstype = 'php' - let type_php.kinds = [ - \ {'short' : 'i', 'long' : 'interfaces', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'd', 'long' : 'constant definitions', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0}, - \ {'short' : 'j', 'long' : 'javascript functions', 'fold' : 0} - \ ] - let s:known_types.php = type_php - " Python {{{3 - let type_python = {} - let type_python.ctagstype = 'python' - let type_python.kinds = [ - \ {'short' : 'i', 'long' : 'imports', 'fold' : 1}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'members', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0} - \ ] - let type_python.sro = '.' - let type_python.kind2scope = { - \ 'c' : 'class', - \ 'f' : 'function', - \ 'm' : 'function' - \ } - let type_python.scope2kind = { - \ 'class' : 'c', - \ 'function' : 'f' - \ } - let s:known_types.python = type_python - " REXX {{{3 - let type_rexx = {} - let type_rexx.ctagstype = 'rexx' - let type_rexx.kinds = [ - \ {'short' : 's', 'long' : 'subroutines', 'fold' : 0} - \ ] - let s:known_types.rexx = type_rexx - " Ruby {{{3 - let type_ruby = {} - let type_ruby.ctagstype = 'ruby' - let type_ruby.kinds = [ - \ {'short' : 'm', 'long' : 'modules', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'methods', 'fold' : 0}, - \ {'short' : 'F', 'long' : 'singleton methods', 'fold' : 0} - \ ] - let type_ruby.sro = '.' - let type_ruby.kind2scope = { - \ 'c' : 'class', - \ 'm' : 'class' - \ } - let type_ruby.scope2kind = { - \ 'class' : 'c' - \ } - let s:known_types.ruby = type_ruby - " Scheme {{{3 - let type_scheme = {} - let type_scheme.ctagstype = 'scheme' - let type_scheme.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 's', 'long' : 'sets', 'fold' : 0} - \ ] - let s:known_types.scheme = type_scheme - " Shell script {{{3 - let type_sh = {} - let type_sh.ctagstype = 'sh' - let type_sh.kinds = [ - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let s:known_types.sh = type_sh - let s:known_types.csh = type_sh - let s:known_types.zsh = type_sh - " SLang {{{3 - let type_slang = {} - let type_slang.ctagstype = 'slang' - let type_slang.kinds = [ - \ {'short' : 'n', 'long' : 'namespaces', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0} - \ ] - let s:known_types.slang = type_slang - " SML {{{3 - let type_sml = {} - let type_sml.ctagstype = 'sml' - let type_sml.kinds = [ - \ {'short' : 'e', 'long' : 'exception declarations', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'function definitions', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'functor definitions', 'fold' : 0}, - \ {'short' : 's', 'long' : 'signature declarations', 'fold' : 0}, - \ {'short' : 'r', 'long' : 'structure declarations', 'fold' : 0}, - \ {'short' : 't', 'long' : 'type definitions', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'value bindings', 'fold' : 0} - \ ] - let s:known_types.sml = type_sml - " SQL {{{3 - " The SQL ctags parser seems to be buggy for me, so this just uses the - " normal kinds even though scopes should be available. Improvements - " welcome! - let type_sql = {} - let type_sql.ctagstype = 'sql' - let type_sql.kinds = [ - \ {'short' : 'P', 'long' : 'packages', 'fold' : 1}, - \ {'short' : 'c', 'long' : 'cursors', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'F', 'long' : 'record fields', 'fold' : 0}, - \ {'short' : 'L', 'long' : 'block label', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0}, - \ {'short' : 's', 'long' : 'subtypes', 'fold' : 0}, - \ {'short' : 't', 'long' : 'tables', 'fold' : 0}, - \ {'short' : 'T', 'long' : 'triggers', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0}, - \ {'short' : 'i', 'long' : 'indexes', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'events', 'fold' : 0}, - \ {'short' : 'U', 'long' : 'publications', 'fold' : 0}, - \ {'short' : 'R', 'long' : 'services', 'fold' : 0}, - \ {'short' : 'D', 'long' : 'domains', 'fold' : 0}, - \ {'short' : 'V', 'long' : 'views', 'fold' : 0}, - \ {'short' : 'n', 'long' : 'synonyms', 'fold' : 0}, - \ {'short' : 'x', 'long' : 'MobiLink Table Scripts', 'fold' : 0}, - \ {'short' : 'y', 'long' : 'MobiLink Conn Scripts', 'fold' : 0} - \ ] - let s:known_types.sql = type_sql - " Tcl {{{3 - let type_tcl = {} - let type_tcl.ctagstype = 'tcl' - let type_tcl.kinds = [ - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'methods', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0} - \ ] - let s:known_types.tcl = type_tcl - " LaTeX {{{3 - let type_tex = {} - let type_tex.ctagstype = 'tex' - let type_tex.kinds = [ - \ {'short' : 'p', 'long' : 'parts', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'chapters', 'fold' : 0}, - \ {'short' : 's', 'long' : 'sections', 'fold' : 0}, - \ {'short' : 'u', 'long' : 'subsections', 'fold' : 0}, - \ {'short' : 'b', 'long' : 'subsubsections', 'fold' : 0}, - \ {'short' : 'P', 'long' : 'paragraphs', 'fold' : 0}, - \ {'short' : 'G', 'long' : 'subparagraphs', 'fold' : 0} - \ ] - let s:known_types.tex = type_tex - " Vera {{{3 - " Why are variables 'virtual'? - let type_vera = {} - let type_vera.ctagstype = 'vera' - let type_vera.kinds = [ - \ {'short' : 'd', 'long' : 'macros', 'fold' : 1}, - \ {'short' : 'g', 'long' : 'enums', 'fold' : 0}, - \ {'short' : 'T', 'long' : 'typedefs', 'fold' : 0}, - \ {'short' : 'c', 'long' : 'classes', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'enumerators', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'members', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 't', 'long' : 'tasks', 'fold' : 0}, - \ {'short' : 'v', 'long' : 'variables', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'programs', 'fold' : 0} - \ ] - let type_vera.sro = '.' " Nesting doesn't seem to be possible - let type_vera.kind2scope = { - \ 'g' : 'enum', - \ 'c' : 'class', - \ 'v' : 'virtual' - \ } - let type_vera.scope2kind = { - \ 'enum' : 'g', - \ 'class' : 'c', - \ 'virtual' : 'v' - \ } - let s:known_types.vera = type_vera - " Verilog {{{3 - let type_verilog = {} - let type_verilog.ctagstype = 'verilog' - let type_verilog.kinds = [ - \ {'short' : 'c', 'long' : 'constants', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'events', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'modules', 'fold' : 0}, - \ {'short' : 'n', 'long' : 'net data types', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'ports', 'fold' : 0}, - \ {'short' : 'r', 'long' : 'register data types', 'fold' : 0}, - \ {'short' : 't', 'long' : 'tasks', 'fold' : 0} - \ ] - let s:known_types.verilog = type_verilog - " VHDL {{{3 - " The VHDL ctags parser unfortunately doesn't generate proper scopes - let type_vhdl = {} - let type_vhdl.ctagstype = 'vhdl' - let type_vhdl.kinds = [ - \ {'short' : 'P', 'long' : 'packages', 'fold' : 1}, - \ {'short' : 'c', 'long' : 'constants', 'fold' : 0}, - \ {'short' : 't', 'long' : 'types', 'fold' : 0}, - \ {'short' : 'T', 'long' : 'subtypes', 'fold' : 0}, - \ {'short' : 'r', 'long' : 'records', 'fold' : 0}, - \ {'short' : 'e', 'long' : 'entities', 'fold' : 0}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'p', 'long' : 'procedures', 'fold' : 0} - \ ] - let s:known_types.vhdl = type_vhdl - " Vim {{{3 - let type_vim = {} - let type_vim.ctagstype = 'vim' - let type_vim.kinds = [ - \ {'short' : 'v', 'long' : 'variables', 'fold' : 1}, - \ {'short' : 'f', 'long' : 'functions', 'fold' : 0}, - \ {'short' : 'a', 'long' : 'autocommand groups', 'fold' : 1}, - \ {'short' : 'c', 'long' : 'commands', 'fold' : 0}, - \ {'short' : 'm', 'long' : 'maps', 'fold' : 1} - \ ] - let s:known_types.vim = type_vim - " YACC {{{3 - let type_yacc = {} - let type_yacc.ctagstype = 'yacc' - let type_yacc.kinds = [ - \ {'short' : 'l', 'long' : 'labels', 'fold' : 0} - \ ] - let s:known_types.yacc = type_yacc - " }}}3 - - let user_defs = s:GetUserTypeDefs() - for [key, value] in items(user_defs) - if !has_key(s:known_types, key) || - \ (has_key(value, 'replace') && value.replace) - let s:known_types[key] = value - else - call extend(s:known_types[key], value) - endif - endfor - - " Create a dictionary of the kind order for fast - " access in sorting functions - for type in values(s:known_types) - let i = 0 - let type.kinddict = {} - for kind in type.kinds - let type.kinddict[kind.short] = i - let i += 1 - endfor - endfor - - let s:type_init_done = 1 -endfunction - -" s:GetUserTypeDefs() {{{2 -function! s:GetUserTypeDefs() - call s:LogDebugMessage('Initializing user types') - - redir => defs - silent execute 'let g:' - redir END - - let deflist = split(defs, '\n') - call map(deflist, 'substitute(v:val, ''^\S\+\zs.*'', "", "")') - call filter(deflist, 'v:val =~ "^tagbar_type_"') - - let defdict = {} - for defstr in deflist - let type = substitute(defstr, '^tagbar_type_', '', '') - execute 'let defdict["' . type . '"] = g:' . defstr - endfor - - " If the user only specified one of kind2scope and scope2kind use it to - " generate the other one - " Also, transform the 'kind' definitions into dictionary format - for def in values(defdict) - if has_key(def, 'kinds') - let kinds = def.kinds - let def.kinds = [] - for kind in kinds - let kindlist = split(kind, ':') - let kinddict = {'short' : kindlist[0], 'long' : kindlist[1]} - if len(kindlist) == 3 - let kinddict.fold = kindlist[2] - else - let kinddict.fold = 0 - endif - call add(def.kinds, kinddict) - endfor - endif - - if has_key(def, 'kind2scope') && !has_key(def, 'scope2kind') - let def.scope2kind = {} - for [key, value] in items(def.kind2scope) - let def.scope2kind[value] = key - endfor - elseif has_key(def, 'scope2kind') && !has_key(def, 'kind2scope') - let def.kind2scope = {} - for [key, value] in items(def.scope2kind) - let def.kind2scope[value] = key - endfor - endif - endfor - - return defdict -endfunction - -" s:RestoreSession() {{{2 -" Properly restore Tagbar after a session got loaded -function! s:RestoreSession() - call s:LogDebugMessage('Restoring session') - - let tagbarwinnr = bufwinnr('__Tagbar__') - if tagbarwinnr == -1 - " Tagbar wasn't open in the saved session, nothing to do - return - else - let in_tagbar = 1 - if winnr() != tagbarwinnr - execute tagbarwinnr . 'wincmd w' - let in_tagbar = 0 - endif - endif - - call s:Init() - - call s:InitWindow(g:tagbar_autoclose) - - " Leave the Tagbar window and come back so the update event gets triggered - wincmd p - execute tagbarwinnr . 'wincmd w' - - if !in_tagbar - wincmd p - endif -endfunction - -" s:MapKeys() {{{2 -function! s:MapKeys() - call s:LogDebugMessage('Mapping keys') - - nnoremap