diff --git a/.vim/autoload/conque_term.vim b/.vim/autoload/conque_term.vim index f9c4b32..a0b6790 100644 --- a/.vim/autoload/conque_term.vim +++ b/.vim/autoload/conque_term.vim @@ -1,9 +1,10 @@ -" FILE: plugin/conque_term.vim {{{ +" FILE: autoload/conque_term.vim {{{ " AUTHOR: Nico Raffo -" MODIFIED: 2010-02-02 -" VERSION: 1.0, for Vim 7.0 +" WEBSITE: http://conque.googlecode.com +" MODIFIED: 2010-11-15 +" VERSION: 2.0, for Vim 7.0 " LICENSE: -" Conque - pty interaction in Vim +" Conque - Vim terminal/console emulator " Copyright (C) 2009-2010 Nico Raffo " " MIT License @@ -28,206 +29,824 @@ " }}} " ********************************************************************************************************** -" **** VIM FUNCTIONS *************************************************************************************** +" **** CROSS-TERMINAL SETTINGS ***************************************************************************** " ********************************************************************************************************** +" {{{ + +" path to this file +let s:scriptfile = expand("") +let s:scriptdir = expand(":h") . '/' +let s:scriptdirpy = expand(":h") . '/conque_term/' + +" Extra key codes +let s:input_extra = [] + +let s:term_obj = { 'idx' : 1, 'var' : '', 'is_buffer' : 1, 'active' : 1, 'buffer_name' : '' } +let s:terminals = {} + +let s:save_updatetime = &updatetime + +let s:initialized = 0 + +" }}} + +" ********************************************************************************************************** +" **** SYSTEM DETECTION ************************************************************************************ +" ********************************************************************************************************** + +" {{{ + +function! conque_term#fail(feature) " {{{ + + " create a new buffer + new + setlocal buftype=nofile + setlocal nonumber + setlocal foldcolumn=0 + setlocal wrap + setlocal noswapfile + + " missing vim features + if a:feature == 'python' + + call append('$', 'Conque ERROR: Python interface cannot be loaded') + call append('$', '') + + if !executable("python") + call append('$', 'Your version of Vim appears to be installed without the Python interface. In ') + call append('$', 'addition, you may need to install Python.') + else + call append('$', 'Your version of Vim appears to be installed without the Python interface.') + endif + + call append('$', '') + + if has('unix') == 1 + call append('$', "You are using a Unix-like operating system. Most, if not all, of the popular ") + call append('$', "Linux package managers have Python-enabled Vim available. For example ") + call append('$', "vim-gnome or vim-gtk on Ubuntu will get you everything you need.") + call append('$', "") + call append('$', "If you are compiling Vim from source, make sure you use the --enable-pythoninterp ") + call append('$', "configure option. You will also need to install Python and the Python headers.") + call append('$', "") + call append('$', "If you are using OS X, MacVim will give you Python support by default.") + else + call append('$', "You appear to be using Windows. The official Vim 7.3 installer available at ") + call append('$', "http://www.vim.org comes with the required Python interfaces. You will also ") + call append('$', "need to install Python 2.7 and/or Python 3.1, both available at http://www.python.org") + endif + + elseif a:feature == 'python_exe' + + call append('$', "Conque ERROR: Can't find Python executable") + call append('$', "") + call append('$', "Conque needs to know the full path to python.exe on Windows systems. By default, ") + call append('$', "Conque will check your system path as well as the most common installation path ") + call append('$', "C:\\PythonXX\\. To fix this error either:") + call append('$', "") + call append('$', "Set the g:ConqueTerm_PyExe option in your .vimrc. E.g.") + call append('$', " let g:ConqueTerm_PyExe = 'C:\Program Files\Python27\python.exe'") + call append('$', "") + call append('$', "Add the directory where you installed python to your system path. This isn't a bad ") + call append('$', "idea in general.") + + elseif a:feature == 'ctypes' + + call append('$', 'Conque ERROR: Python cannot load the ctypes module') + call append('$', "") + call append('$', "Conque requires the 'ctypes' python module. This has been a standard module since Python 2.5.") + call append('$', "") + call append('$', "The recommended fix is to make sure you're using the latest official GVim version 7.3, ") + call append('$', "and have at least one of the two compatible versions of Python installed, ") + call append('$', "2.7 or 3.1. You can download the GVim 7.3 installer from http://www.vim.org. You ") + call append('$', "can download the Python 2.7 or 3.1 installer from http://www.python.org") + + endif + +endfunction " }}} + +function! conque_term#dependency_check() " {{{ + + " don't recheck the second time 'round + if s:initialized == 1 + return 1 + endif + + " choose a python version and define a string unicoding function + let s:py = '' + if g:ConqueTerm_PyVersion == 3 + let s:pytest = 'python3' + else + let s:pytest = 'python' + let g:ConqueTerm_PyVersion = 2 + endif + + " first the requested version + if has(s:pytest) + if s:pytest == 'python3' + let s:py = 'py3' + else + let s:py = 'py' + endif + + " otherwise use the other version + else + let s:py_alternate = 5 - g:ConqueTerm_PyVersion + if s:py_alternate == 3 + let s:pytest = 'python3' + else + let s:pytest = 'python' + endif + if has(s:pytest) + echohl WarningMsg | echomsg "Python " . g:ConqueTerm_PyVersion . " interface is not installed, using Python " . s:py_alternate . " instead" | echohl None + let g:ConqueTerm_PyVersion = s:py_alternate + if s:pytest == 'python3' + let s:py = 'py3' + else + let s:py = 'py' + endif + endif + endif + + " test if we actually found a python version + if s:py == '' + call conque_term#fail('python') + return 0 + endif + + " quick and dirty platform declaration + if has('unix') == 1 + let s:platform = 'nix' + sil exe s:py . " CONQUE_PLATFORM = 'nix'" + else + let s:platform = 'dos' + sil exe s:py . " CONQUE_PLATFORM = 'dos'" + endif + + " if we're using Windows, make sure ctypes is available + if s:platform == 'dos' + try + sil exe s:py . " import ctypes" + catch + call conque_term#fail('ctypes') + return 0 + endtry + endif + + " if we're using Windows, make sure we can finde python executable + if s:platform == 'dos' && conque_term#find_python_exe() == '' + call conque_term#fail('python_exe') + return 0 + endif + + " check for global cursorhold/cursormove events + let o = '' + silent redir => o + silent autocmd CursorHoldI,CursorMovedI + redir END + for line in split(o, "\n") + if line =~ '^ ' || line =~ '^--' || line =~ 'matchparen' + continue + endif + echohl WarningMsg | echomsg "Warning: Global CursorHoldI and CursorMovedI autocommands may cause ConqueTerm to run slowly." | echohl None + endfor + + " if we're all good, load python files + call conque_term#load_python() + + return 1 + +endfunction " }}} + +" }}} + +" ********************************************************************************************************** +" **** WINDOWS VK CODES ************************************************************************************ +" ********************************************************************************************************** + +" Windows Virtual Key Codes {{{ +let s:windows_vk = { +\ 'VK_ADD' : 107, +\ 'VK_APPS' : 93, +\ 'VK_ATTN' : 246, +\ 'VK_BACK' : 8, +\ 'VK_BROWSER_BACK' : 166, +\ 'VK_BROWSER_FORWARD' : 167, +\ 'VK_CANCEL' : 3, +\ 'VK_CAPITAL' : 20, +\ 'VK_CLEAR' : 12, +\ 'VK_CONTROL' : 17, +\ 'VK_CONVERT' : 28, +\ 'VK_CRSEL' : 247, +\ 'VK_DECIMAL' : 110, +\ 'VK_DELETE' : 46, +\ 'VK_DIVIDE' : 111, +\ 'VK_DOWN' : 40, +\ 'VK_END' : 35, +\ 'VK_EREOF' : 249, +\ 'VK_ESCAPE' : 27, +\ 'VK_EXECUTE' : 43, +\ 'VK_EXSEL' : 248, +\ 'VK_F1' : 112, +\ 'VK_F10' : 121, +\ 'VK_F11' : 122, +\ 'VK_F12' : 123, +\ 'VK_F13' : 124, +\ 'VK_F14' : 125, +\ 'VK_F15' : 126, +\ 'VK_F16' : 127, +\ 'VK_F17' : 128, +\ 'VK_F18' : 129, +\ 'VK_F19' : 130, +\ 'VK_F2' : 113, +\ 'VK_F20' : 131, +\ 'VK_F21' : 132, +\ 'VK_F22' : 133, +\ 'VK_F23' : 134, +\ 'VK_F24' : 135, +\ 'VK_F3' : 114, +\ 'VK_F4' : 115, +\ 'VK_F5' : 116, +\ 'VK_F6' : 117, +\ 'VK_F7' : 118, +\ 'VK_F8' : 119, +\ 'VK_F9' : 120, +\ 'VK_FINAL' : 24, +\ 'VK_HANGEUL' : 21, +\ 'VK_HANGUL' : 21, +\ 'VK_HANJA' : 25, +\ 'VK_HELP' : 47, +\ 'VK_HOME' : 36, +\ 'VK_INSERT' : 45, +\ 'VK_JUNJA' : 23, +\ 'VK_KANA' : 21, +\ 'VK_KANJI' : 25, +\ 'VK_LBUTTON' : 1, +\ 'VK_LCONTROL' : 162, +\ 'VK_LEFT' : 37, +\ 'VK_LMENU' : 164, +\ 'VK_LSHIFT' : 160, +\ 'VK_LWIN' : 91, +\ 'VK_MBUTTON' : 4, +\ 'VK_MEDIA_NEXT_TRACK' : 176, +\ 'VK_MEDIA_PLAY_PAUSE' : 179, +\ 'VK_MEDIA_PREV_TRACK' : 177, +\ 'VK_MENU' : 18, +\ 'VK_MODECHANGE' : 31, +\ 'VK_MULTIPLY' : 106, +\ 'VK_NEXT' : 34, +\ 'VK_NONAME' : 252, +\ 'VK_NONCONVERT' : 29, +\ 'VK_NUMLOCK' : 144, +\ 'VK_NUMPAD0' : 96, +\ 'VK_NUMPAD1' : 97, +\ 'VK_NUMPAD2' : 98, +\ 'VK_NUMPAD3' : 99, +\ 'VK_NUMPAD4' : 100, +\ 'VK_NUMPAD5' : 101, +\ 'VK_NUMPAD6' : 102, +\ 'VK_NUMPAD7' : 103, +\ 'VK_NUMPAD8' : 104, +\ 'VK_NUMPAD9' : 105, +\ 'VK_OEM_CLEAR' : 254, +\ 'VK_PA1' : 253, +\ 'VK_PAUSE' : 19, +\ 'VK_PLAY' : 250, +\ 'VK_PRINT' : 42, +\ 'VK_PRIOR' : 33, +\ 'VK_PROCESSKEY' : 229, +\ 'VK_RBUTTON' : 2, +\ 'VK_RCONTROL' : 163, +\ 'VK_RETURN' : 13, +\ 'VK_RIGHT' : 39, +\ 'VK_RMENU' : 165, +\ 'VK_RSHIFT' : 161, +\ 'VK_RWIN' : 92, +\ 'VK_SCROLL' : 145, +\ 'VK_SELECT' : 41, +\ 'VK_SEPARATOR' : 108, +\ 'VK_SHIFT' : 16, +\ 'VK_SNAPSHOT' : 44, +\ 'VK_SPACE' : 32, +\ 'VK_SUBTRACT' : 109, +\ 'VK_TAB' : 9, +\ 'VK_UP' : 38, +\ 'VK_VOLUME_DOWN' : 174, +\ 'VK_VOLUME_MUTE' : 173, +\ 'VK_VOLUME_UP' : 175, +\ 'VK_XBUTTON1' : 5, +\ 'VK_XBUTTON2' : 6, +\ 'VK_ZOOM' : 251 +\ } +" }}} + +" ********************************************************************************************************** +" **** ACTUAL CONQUE FUNCTIONS! *************************************************************************** +" ********************************************************************************************************** + +" {{{ + " launch conque function! conque_term#open(...) "{{{ let command = get(a:000, 0, '') let hooks = get(a:000, 1, []) + let return_to_current = get(a:000, 2, 0) + let is_buffer = get(a:000, 3, 1) + + " dependency check + if conque_term#dependency_check() == 0 + return 0 + endif + + " switch to buffer if needed + if is_buffer && return_to_current + let save_sb = &switchbuf + + "use an agressive sb option + sil set switchbuf=usetab + + " current buffer name + let current_buffer = bufname("%") + endif " bare minimum validation + if s:py == '' + 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') + let l:cargs = split(command, '[^\\]\@<=\s') + let l:cargs[0] = substitute(l:cargs[0], '\\ ', ' ', 'g') if !executable(l:cargs[0]) - echohl WarningMsg | echomsg "Not an executable" | echohl None + echohl WarningMsg | echomsg "Not an executable: " . l:cargs[0] | echohl None return 0 endif endif - " set buffer window options - let g:Conque_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 + let g:ConqueTerm_Var = 'ConqueTerm_' . g:ConqueTerm_Idx + let g:ConqueTerm_BufName = substitute(command, ' ', '\\ ', 'g') . "\\ -\\ " . g:ConqueTerm_Idx + + " initialize global mappings if needed + call conque_term#init() + + " set buffer window options + if is_buffer + call conque_term#set_buffer_settings(command, hooks) + + let b:ConqueTerm_Idx = g:ConqueTerm_Idx + let b:ConqueTerm_Var = g:ConqueTerm_Var + endif + + " save handle + let t_obj = conque_term#create_terminal_object(g:ConqueTerm_Idx, is_buffer, g:ConqueTerm_BufName) + let s:terminals[g:ConqueTerm_Idx] = t_obj " 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 + if s:platform == 'nix' + execute s:py . ' ' . g:ConqueTerm_Var . ' = Conque()' + execute s:py . ' ' . g:ConqueTerm_Var . ".open('" . conque_term#python_escape(command) . "', " . l:config . ")" + else + " find python.exe and communicator + let py_exe = conque_term#python_escape(conque_term#find_python_exe()) + let py_vim = conque_term#python_escape(s:scriptdirpy . 'conque_sole_communicator.py') + if py_exe == '' + return 0 + endif + execute s:py . ' ' . g:ConqueTerm_Var . ' = ConqueSole()' + execute s:py . ' ' . g:ConqueTerm_Var . ".open('" . conque_term#python_escape(command) . "', " . l:config . ", '" . py_exe . "', '" . py_vim . "')" + + "call conque_term#init_conceal_color() + endif + catch + echohl WarningMsg | echomsg "An error occurred: " . command | echohl None + return endtry " set buffer mappings and auto commands - call conque_term#set_mappings() + if is_buffer + call conque_term#set_mappings('start') + endif - startinsert! - return 1 + " switch to buffer if needed + if is_buffer && return_to_current + " jump back to code buffer + sil exe ":sb " . current_buffer + sil exe ":set switchbuf=" . save_sb + elseif is_buffer + startinsert! + endif + + return t_obj endfunction "}}} +" open(), but no buffer +function! conque_term#subprocess(command) " {{{ + + let t_obj = conque_term#open(a:command, [], 0, 0) + if !exists('b:ConqueTerm_Var') + call conque_term#on_blur() + sil exe s:py . ' ' . g:ConqueTerm_Var . '.idle()' + endif + return t_obj + +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 - silent execute h + sil exe h endfor - silent execute "edit " . g:Conque_BufName + sil exe 'edit ++enc=utf-8 ' . g:ConqueTerm_BufName + + " showcmd gets altered by nocompatible + let sc_save = &showcmd " buffer settings + setlocal fileencoding=utf-8 " file encoding, even tho there's no file 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 + if v:version >= 703 + setlocal norelativenumber " hide relative line numbers (VIM >= 7.3) + endif 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 switchbuf=usetab " switch tabs with the command + setlocal bufhidden=hide " when buffer is no longer displayed, don't wipe it out + setlocal noreadonly " this is not actually a readonly buffer + if v:version >= 703 + setlocal conceallevel=3 + setlocal concealcursor=nic + endif setfiletype conque_term " useful - silent execute "setlocal syntax=" . g:ConqueTerm_Syntax + sil exe "setlocal syntax=" . g:ConqueTerm_Syntax + + " reset showcmd + if sc_save + set showcmd + else + set noshowcmd + endif + + " temporary global settings go in here + call conque_term#on_focus(1) endfunction " }}} " set key mappings and auto commands -function! conque_term#set_mappings() "{{{ +function! conque_term#set_mappings(action) "{{{ - " handle unexpected closing of shell, passes HUP to parent and all child processes - execute 'autocmd BufUnload python ' . b:ConqueTerm_Var . '.proc.signal(1)' - - " check for resized/scrolled buffer when entering buffer - execute 'autocmd BufEnter python ' . b:ConqueTerm_Var . '.update_window_size()' - - " set/reset updatetime on entering/exiting buffer - autocmd BufEnter set updatetime=50 - autocmd BufLeave set updatetime=1000 - - " 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 - autocmd CursorHold * call conque_term#read_all() + " 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 - " use F22 key to get more input - inoremap "\\" - inoremap "\\" - silent execute 'autocmd CursorHoldI python ' . b:ConqueTerm_Var . '.auto_read()' + " if mappings are being removed, add 'un' + let map_modifier = 'nore' + if l:action == 'stop' + let map_modifier = 'un' + endif + " }}} - " map ASCII 1-31 + " 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 ' . s:py . ' ' . b:ConqueTerm_Var . '.close()' + + " check for resized/scrolled buffer when entering buffer + execute 'autocmd ' . b:ConqueTerm_Var . ' BufEnter ' . s:py . ' ' . b:ConqueTerm_Var . '.update_window_size()' + execute 'autocmd ' . b:ConqueTerm_Var . ' VimResized ' . s:py . ' ' . b:ConqueTerm_Var . '.update_window_size()' + + " set/reset updatetime on entering/exiting buffer + execute 'autocmd ' . b:ConqueTerm_Var . ' BufEnter call conque_term#on_focus()' + execute 'autocmd ' . b:ConqueTerm_Var . ' BufLeave call conque_term#on_blur()' + + " reposition cursor when going into insert mode + execute 'autocmd ' . b:ConqueTerm_Var . ' InsertEnter ' . s:py . ' ' . b:ConqueTerm_Var . '.insert_enter()' + + " poll for more output + sil execute 'autocmd ' . b:ConqueTerm_Var . ' CursorHoldI ' . s:py . ' ' . b:ConqueTerm_Var . '.auto_read()' + endif + " }}} + + " map ASCII 1-31 {{{ for c in range(1, 31) " - if c == 27 + if c == 27 || c == 3 continue endif - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(chr(' . c . '))' + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write(chr(' . c . '))' + else + sil exe 'i' . map_modifier . 'map ' + endif endfor - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(chr(27))' - silent execute 'nnoremap :python ' . b:ConqueTerm_Var . '.write(chr(3))' + " bonus mapping: send in normal mode to terminal as well for panic interrupts + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write(chr(3))' + sil exe 'n' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write(chr(3))' + else + sil exe 'i' . map_modifier . 'map ' + sil exe 'n' . map_modifier . 'map ' + endif - " map ASCII 33-127 + " 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 :' . s:py . ' ' . 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 :' . s:py . ' ' . 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 - silent execute "inoremap :python " . b:ConqueTerm_Var . ".write(chr(124))" + if l:action == 'start' + sil exe "i" . map_modifier . "map :" . s:py . ' ' . b:ConqueTerm_Var . ".write(chr(124))" + else + sil exe "i" . map_modifier . "map " + endif continue endif - silent execute "inoremap " . nr2char(i) . " :python " . b:ConqueTerm_Var . ".write(chr(" . i . "))" + if l:action == 'start' + sil exe "i" . map_modifier . "map " . nr2char(i) . " :" . s:py . ' ' . b:ConqueTerm_Var . ".write(chr(" . i . "))" + else + sil exe "i" . map_modifier . "map " . nr2char(i) + endif endfor + " }}} - " map ASCII 128-255 + " map Latin-1 128-255 {{{ for i in range(128, 255) - silent execute "inoremap " . nr2char(i) . " :python " . b:ConqueTerm_Var . ".write('" . nr2char(i) . "')" + if l:action == 'start' + sil exe "i" . map_modifier . "map " . nr2char(i) . " :" . s:py . ' ' . b:ConqueTerm_Var . ".write_latin1(chr(" . i . "))" + else + sil exe "i" . map_modifier . "map " . nr2char(i) + endif endfor + " }}} - " Special cases - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u0008")' - "silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u0009")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u000a")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u000d")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(" ")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u001b[A")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u001b[B")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u001b[C")' - silent execute 'inoremap :python ' . b:ConqueTerm_Var . '.write(u"\u001b[D")' - - " meta characters - "for c in split(s:chars_meta, '\zs') - " silent execute 'inoremap :call conque_term#press_key("' . c . '")a' - "endfor - - " send selected text into conque - vnoremap :call conque_term#send_selected(visualmode()) - - " remap paste keys - silent execute 'nnoremap p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - silent execute 'nnoremap P :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - silent execute 'nnoremap ]p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - silent execute 'nnoremap [p :python ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' - if has('gui_running') - silent execute 'inoremap :python ' . b:ConqueTerm_Var . ".write(vim.eval('@+'))a" + " Special keys {{{ + if l:action == 'start' + if s:platform == 'nix' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x08")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write(" ")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[A")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[B")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[C")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[D")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1bOH")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1bOF")' + else + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x08")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write(" ")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_UP . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_DOWN . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_RIGHT . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_LEFT . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_DELETE . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_HOME . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_END . ')' + endif + 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 ' + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' endif + " }}} - " disable other normal mode keys which insert text - nnoremap r :echo 'Replace mode disabled in shell.' - nnoremap R :echo 'Replace mode disabled in shell.' - nnoremap c :echo 'Change mode disabled in shell.' - nnoremap C :echo 'Change mode disabled in shell.' - nnoremap s :echo 'Change mode disabled in shell.' - nnoremap S :echo 'Change mode disabled in shell.' + " keys {{{ + if g:ConqueTerm_SendFunctionKeys + if l:action == 'start' + if s:platform == 'nix' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[11~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[12~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("1b[13~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[14~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[15~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[17~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[18~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[19~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[20~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[21~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[23~")' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write("\x1b[24~")' + else + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F1 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F2 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F3 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F4 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F5 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F6 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F7 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F8 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F9 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F10 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F11 . ')' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F12 . ')' + endif + 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 ' + 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 + endif + " }}} - " help message about - "nnoremap :echo 'To send an to the terminal, press quickly in insert mode. Some programs, such as Vim, will also accept as a substitute for ' + " send selected text into conque {{{ + if l:action == 'start' + sil exe 'v' . map_modifier . 'map ' . g:ConqueTerm_SendVisKey . ' :call conque_term#send_selected(visualmode())' + endif + " }}} -endfunction "}}} + " remap paste keys {{{ + if l:action == 'start' + sil exe 'n' . map_modifier . 'map p :' . s:py . ' ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + sil exe 'n' . map_modifier . 'map P :' . s:py . ' ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + sil exe 'n' . map_modifier . 'map ]p :' . s:py . ' ' . b:ConqueTerm_Var . '.write(vim.eval("@@"))a' + sil exe 'n' . map_modifier . 'map [p :' . s:py . ' ' . 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') == 1 + if l:action == 'start' + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . ".write(vim.eval('@+'))a" + sil exe 'i' . map_modifier . 'map :' . s:py . ' ' . b:ConqueTerm_Var . ".write(vim.eval('@+'))a" + else + sil exe 'i' . map_modifier . 'map ' + sil exe 'i' . map_modifier . 'map ' + endif + endif + " }}} -" send selected text from another buffer -function! conque_term#send_selected(type) "{{{ - let reg_save = @@ + " 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 + " }}} - " yank current selection - silent execute "normal! `<" . a:type . "`>y" + " user defined mappings {{{ + for [map_from, map_to] in s:input_extra + if l:action == 'start' + sil exe 'i' . map_modifier . 'map ' . map_from . ' :' . s:py . ' ' . b:ConqueTerm_Var . ".write('" . conque_term#python_escape(map_to) . "')" + else + sil exe 'i' . map_modifier . 'map ' . map_from + endif + endfor + " }}} - let @@ = substitute(@@, '^[\r\n]*', '', '') - let @@ = substitute(@@, '[\r\n]*$', '', '') + " set conque as on or off {{{ + if l:action == 'start' + let b:conque_on = 1 + else + let b:conque_on = 0 + endif + " }}} - silent execute ":sb " . g:Conque_BufName - silent execute 'python ' . g:ConqueTerm_Var . '.paste_selection()' + " map command to toggle terminal key mappings {{{ + if a:action == 'start' + sil exe 'nnoremap ' . g:ConqueTerm_ToggleKey . ' :call conque_term#set_mappings("toggle")' + endif + " }}} - let @@ = reg_save - startinsert! -endfunction "}}} +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') +" Initialize global mappings. Should only be called once per Vim session +function! conque_term#init() " {{{ + + if s:initialized == 1 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 + augroup ConqueTerm + autocmd ConqueTerm VimLeave * call conque_term#close_all() + + " read more output when this isn't the current buffer + if g:ConqueTerm_ReadUnfocused == 1 + autocmd ConqueTerm CursorHold * call conque_term#read_all(0) + endif + + let s:initialized = 1 + +endfunction " }}} + +" read from all known conque buffers +function! conque_term#read_all(insert_mode) "{{{ + + for i in range(1, g:ConqueTerm_Idx) + try + if !s:terminals[i].active + continue + endif + + let output = s:terminals[i].read(1) + + if !s:terminals[i].is_buffer && exists('*s:terminals[i].callback') + call s:terminals[i].callback(output) + endif + catch + " probably a deleted buffer + endtry + endfor - " TODO - doesn't work " restart updatetime - "call feedkeys("\x80\xFD\x35") + if a:insert_mode + call feedkeys("\f\e", "n") + else + call feedkeys("f\e", "n") + endif + +endfunction "}}} + +" close all subprocesses +function! conque_term#close_all() "{{{ + + for i in range(1, g:ConqueTerm_Idx) + try + call s:terminals[i].close() + catch + " probably a deleted buffer + endtry + endfor + endfunction "}}} " util function to add enough \s to pass a string to python @@ -240,1139 +859,414 @@ function! conque_term#python_escape(input) "{{{ return l:cleaned endfunction "}}} +" gets called when user enters conque buffer. +" Useful for making temp changes to global config +function! conque_term#on_focus(...) " {{{ + + let startup = get(a:000, 0, 0) + + " Disable NeoComplCache. It has global hooks on CursorHold and CursorMoved :-/ + let s:NeoComplCache_WasEnabled = exists(':NeoComplCacheLock') + if s:NeoComplCache_WasEnabled == 2 + NeoComplCacheLock + endif + + if g:ConqueTerm_ReadUnfocused == 1 + autocmd! ConqueTerm CursorHoldI * + autocmd! ConqueTerm CursorHold * + endif + + " set poll interval to 50ms + set updatetime=50 + + if startup == 0 && exists('b:ConqueTerm_Var') + sil exe s:py . ' ' . g:ConqueTerm_Var . '.resume()' + endif + + " if configured, go into insert mode + if g:ConqueTerm_InsertOnEnter == 1 + startinsert! + endif + +endfunction " }}} + +" gets called when user exits conque buffer. +" Useful for resetting changes to global config +function! conque_term#on_blur() " {{{ + " re-enable NeoComplCache if needed + if exists('s:NeoComplCache_WasEnabled') && exists(':NeoComplCacheUnlock') && s:NeoComplCache_WasEnabled == 2 + NeoComplCacheUnlock + endif + + if exists('b:ConqueTerm_Var') + sil exe s:py . ' ' . b:ConqueTerm_Var . '.idle()' + endif + + " reset poll interval + if g:ConqueTerm_ReadUnfocused == 1 + set updatetime=1000 + autocmd ConqueTerm CursorHoldI * call conque_term#read_all(1) + autocmd ConqueTerm CursorHold * call conque_term#read_all(0) + elseif exists('s:save_updatetime') + exe 'set updatetime=' . s:save_updatetime + else + set updatetime=2000 + endif +endfunction " }}} + +" bell event (^G) +function! conque_term#bell() " {{{ + echohl WarningMsg | echomsg "BELL!" | echohl None +endfunction " }}} + +" }}} + +" ********************************************************************************************************** +" **** Windows only functions ****************************************************************************** +" ********************************************************************************************************** + +" {{{ + +" find python.exe in windows +function! conque_term#find_python_exe() " {{{ + + " first check configuration for custom value + if g:ConqueTerm_PyExe != '' && executable(g:ConqueTerm_PyExe) + return g:ConqueTerm_PyExe + endif + + let sys_paths = split($PATH, ';') + + " get exact python version + sil exe ':' . s:py . ' import sys, vim' + sil exe ':' . s:py . ' vim.command("let g:ConqueTerm_PyVersion = " + str(sys.version_info[0]) + str(sys.version_info[1]))' + + " ... and add to path list + call add(sys_paths, 'C:\Python' . g:ConqueTerm_PyVersion) + call reverse(sys_paths) + + " check if python.exe is in paths + for path in sys_paths + let cand = path . '\' . 'python.exe' + if executable(cand) + return cand + endif + endfor + + echohl WarningMsg | echomsg "Unable to find python.exe, see :help ConqueTerm_PythonExe for more information" | echohl None + + return '' + +endfunction " }}} + +" initialize concealed colors +function! conque_term#init_conceal_color() " {{{ + + highlight link ConqueCCBG Normal + + " foreground colors, low intensity + syn region ConqueCCF000 matchgroup=ConqueConceal start="\esf000;" end="\eef000;" concealends contains=ConqueCCBG + syn region ConqueCCF00c matchgroup=ConqueConceal start="\esf00c;" end="\eef00c;" concealends contains=ConqueCCBG + syn region ConqueCCF0c0 matchgroup=ConqueConceal start="\esf0c0;" end="\eef0c0;" concealends contains=ConqueCCBG + syn region ConqueCCF0cc matchgroup=ConqueConceal start="\esf0cc;" end="\eef0cc;" concealends contains=ConqueCCBG + syn region ConqueCCFc00 matchgroup=ConqueConceal start="\esfc00;" end="\eefc00;" concealends contains=ConqueCCBG + syn region ConqueCCFc0c matchgroup=ConqueConceal start="\esfc0c;" end="\eefc0c;" concealends contains=ConqueCCBG + syn region ConqueCCFcc0 matchgroup=ConqueConceal start="\esfcc0;" end="\eefcc0;" concealends contains=ConqueCCBG + syn region ConqueCCFccc matchgroup=ConqueConceal start="\esfccc;" end="\eefccc;" concealends contains=ConqueCCBG + + " foreground colors, high intensity + syn region ConqueCCF000 matchgroup=ConqueConceal start="\esf000;" end="\eef000;" concealends contains=ConqueCCBG + syn region ConqueCCF00f matchgroup=ConqueConceal start="\esf00f;" end="\eef00f;" concealends contains=ConqueCCBG + syn region ConqueCCF0f0 matchgroup=ConqueConceal start="\esf0f0;" end="\eef0f0;" concealends contains=ConqueCCBG + syn region ConqueCCF0ff matchgroup=ConqueConceal start="\esf0ff;" end="\eef0ff;" concealends contains=ConqueCCBG + syn region ConqueCCFf00 matchgroup=ConqueConceal start="\esff00;" end="\eeff00;" concealends contains=ConqueCCBG + syn region ConqueCCFf0f matchgroup=ConqueConceal start="\esff0f;" end="\eeff0f;" concealends contains=ConqueCCBG + syn region ConqueCCFff0 matchgroup=ConqueConceal start="\esfff0;" end="\eefff0;" concealends contains=ConqueCCBG + syn region ConqueCCFfff matchgroup=ConqueConceal start="\esffff;" end="\eeffff;" concealends contains=ConqueCCBG + + " background colors, low intensity + syn region ConqueCCB000 matchgroup=ConqueConceal start="\esb000;" end="\eeb000;" concealends + syn region ConqueCCB00c matchgroup=ConqueConceal start="\esb00c;" end="\eeb00c;" concealends + syn region ConqueCCB0c0 matchgroup=ConqueConceal start="\esb0c0;" end="\eeb0c0;" concealends + syn region ConqueCCB0cc matchgroup=ConqueConceal start="\esb0cc;" end="\eeb0cc;" concealends + syn region ConqueCCBc00 matchgroup=ConqueConceal start="\esbc00;" end="\eebc00;" concealends + syn region ConqueCCBc0c matchgroup=ConqueConceal start="\esbc0c;" end="\eebc0c;" concealends + syn region ConqueCCBcc0 matchgroup=ConqueConceal start="\esbcc0;" end="\eebcc0;" concealends + syn region ConqueCCBccc matchgroup=ConqueConceal start="\esbccc;" end="\eebccc;" concealends + + " background colors, high intensity + syn region ConqueCCB000 matchgroup=ConqueConceal start="\esb000;" end="\eeb000;" concealends + syn region ConqueCCB00f matchgroup=ConqueConceal start="\esb00f;" end="\eeb00f;" concealends + syn region ConqueCCB0f0 matchgroup=ConqueConceal start="\esb0f0;" end="\eeb0f0;" concealends + syn region ConqueCCB0ff matchgroup=ConqueConceal start="\esb0ff;" end="\eeb0ff;" concealends + syn region ConqueCCBf00 matchgroup=ConqueConceal start="\esbf00;" end="\eebf00;" concealends + syn region ConqueCCBf0f matchgroup=ConqueConceal start="\esbf0f;" end="\eebf0f;" concealends + syn region ConqueCCBff0 matchgroup=ConqueConceal start="\esbff0;" end="\eebff0;" concealends + syn region ConqueCCBfff matchgroup=ConqueConceal start="\esbfff;" end="\eebfff;" concealends + + + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + """""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" + + "highlight link ConqueCCConceal Error + + " foreground colors, low intensity + highlight ConqueCCF000 guifg=#000000 + highlight ConqueCCF00c guifg=#0000cc + highlight ConqueCCF0c0 guifg=#00cc00 + highlight ConqueCCF0cc guifg=#00cccc + highlight ConqueCCFc00 guifg=#cc0000 + highlight ConqueCCFc0c guifg=#cc00cc + highlight ConqueCCFcc0 guifg=#cccc00 + highlight ConqueCCFccc guifg=#cccccc + + " foreground colors, high intensity + highlight ConqueCCF000 guifg=#000000 + highlight ConqueCCF00f guifg=#0000ff + highlight ConqueCCF0f0 guifg=#00ff00 + highlight ConqueCCF0ff guifg=#00ffff + highlight ConqueCCFf00 guifg=#ff0000 + highlight ConqueCCFf0f guifg=#ff00ff + highlight ConqueCCFff0 guifg=#ffff00 + highlight ConqueCCFfff guifg=#ffffff + + " background colors, low intensity + highlight ConqueCCB000 guibg=#000000 + highlight ConqueCCB00c guibg=#0000cc + highlight ConqueCCB0c0 guibg=#00cc00 + highlight ConqueCCB0cc guibg=#00cccc + highlight ConqueCCBc00 guibg=#cc0000 + highlight ConqueCCBc0c guibg=#cc00cc + highlight ConqueCCBcc0 guibg=#cccc00 + highlight ConqueCCBccc guibg=#cccccc + + " background colors, high intensity + highlight ConqueCCB000 guibg=#000000 + highlight ConqueCCB00f guibg=#0000ff + highlight ConqueCCB0f0 guibg=#00ff00 + highlight ConqueCCB0ff guibg=#00ffff + highlight ConqueCCBf00 guibg=#ff0000 + highlight ConqueCCBf0f guibg=#ff00ff + highlight ConqueCCBff0 guibg=#ffff00 + highlight ConqueCCBfff guibg=#ffffff + + " background colors, low intensity + highlight link ConqueCCB000 ConqueCCBG + highlight link ConqueCCB00c ConqueCCBG + highlight link ConqueCCB0c0 ConqueCCBG + highlight link ConqueCCB0cc ConqueCCBG + highlight link ConqueCCBc00 ConqueCCBG + highlight link ConqueCCBc0c ConqueCCBG + highlight link ConqueCCBcc0 ConqueCCBG + highlight link ConqueCCBccc ConqueCCBG + + " background colors, high intensity + highlight link ConqueCCB000 ConqueCCBG + highlight link ConqueCCB00f ConqueCCBG + highlight link ConqueCCB0f0 ConqueCCBG + highlight link ConqueCCB0ff ConqueCCBG + highlight link ConqueCCBf00 ConqueCCBG + highlight link ConqueCCBf0f ConqueCCBG + highlight link ConqueCCBff0 ConqueCCBG + highlight link ConqueCCBfff ConqueCCBG + +endfunction " }}} + +" }}} + +" ********************************************************************************************************** +" **** Add-on features ************************************************************************************* +" ********************************************************************************************************** + +" 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 s:py . ' ' . g:ConqueTerm_Var . '.paste_selection()' + + " reset original values + let @@ = reg_save + sil exe 'set switchbuf=' . sb_save + + " scroll buffer left + startinsert! + normal 0zH +endfunction "}}} + +" ********************************************************************************************************** +" **** "API" functions ************************************************************************************* +" ********************************************************************************************************** + +" See doc/conque_term.txt for full documentation {{{ + +" Write to a conque terminal buffer +function! s:term_obj.write(text) dict " {{{ + + " if we're not in terminal buffer, pass flag to not position the cursor + sil exe s:py . ' ' . self.var . '.write(vim.eval("a:text"), False, False)' + +endfunction " }}} + +" same as write() but adds a newline +function! s:term_obj.writeln(text) dict " {{{ + + call self.write(a:text . "\r") + +endfunction " }}} + +" read from terminal buffer and return string +function! s:term_obj.read(...) dict " {{{ + + let read_time = get(a:000, 0, 1) + let update_buffer = get(a:000, 1, self.is_buffer) + + if update_buffer + let up_py = 'True' + else + let up_py = 'False' + endif + + " figure out if we're in the buffer we're updating + if exists('b:ConqueTerm_Var') && b:ConqueTerm_Var == self.var + let in_buffer = 1 + else + let in_buffer = 0 + endif + + let output = '' + + " read! + sil exec s:py . " conque_tmp = " . self.var . ".read(timeout = " . read_time . ", set_cursor = False, return_output = True, update_buffer = " . up_py . ")" + + " ftw! + try + let pycode = "\nif conque_tmp:\n conque_tmp = re.sub('\\\\\\\\', '\\\\\\\\\\\\\\\\', conque_tmp)\n conque_tmp = re.sub('\"', '\\\\\\\\\"', conque_tmp)\n vim.command('let output = \"' + conque_tmp + '\"')\n" + sil exec s:py . pycode + catch + " d'oh + endtry + + return output + +endfunction " }}} + +" set output callback +function! s:term_obj.set_callback(callback_func) dict " {{{ + + let s:terminals[self.idx].callback = function(a:callback_func) + +endfunction " }}} + +" close subprocess with ABORT signal +function! s:term_obj.close() dict " {{{ + + try + sil exe s:py . ' ' . self.var . '.abort()' + catch + " probably already dead + endtry + + if self.is_buffer + call conque_term#set_mappings('stop') + if exists('g:ConqueTerm_CloseOnEnd') && g:ConqueTerm_CloseOnEnd + sil exe 'bwipeout! ' . self.buffer_name + stopinsert! + endif + endif + +endfunction " }}} + +" create a new terminal object +function! conque_term#create_terminal_object(...) " {{{ + + " find conque buffer to update + let buf_num = get(a:000, 0, 0) + if buf_num > 0 + let pvar = 'ConqueTerm_' . buf_num + elseif exists('b:ConqueTerm_Var') + let pvar = b:ConqueTerm_Var + let buf_num = b:ConqueTerm_Idx + else + let pvar = g:ConqueTerm_Var + let buf_num = g:ConqueTerm_Idx + endif + + " is ther a buffer? + let is_buffer = get(a:000, 1, 1) + + " the buffer name + let bname = get(a:000, 2, '') + + let l:t_obj = copy(s:term_obj) + let l:t_obj.is_buffer = is_buffer + let l:t_obj.idx = buf_num + let l:t_obj.buffer_name = bname + let l:t_obj.var = pvar + + return l:t_obj + +endfunction " }}} + +" get an existing terminal instance +function! conque_term#get_instance(...) " {{{ + + " find conque buffer to update + let buf_num = get(a:000, 0, 0) + + if exists('s:terminals[buf_num]') + + elseif exists('b:ConqueTerm_Var') + let buf_num = b:ConqueTerm_Idx + else + let buf_num = g:ConqueTerm_Idx + endif + + return s:terminals[buf_num] + +endfunction " }}} + +" add a new default mapping +function! conque_term#imap(map_from, map_to) " {{{ + call add(s:input_extra, [a:map_from, a:map_to]) +endfunction " }}} + +" add a list of new default mappings +function! conque_term#imap_list(map_list) " {{{ + call extend(s:input_extra, a:map_list) +endfunction " }}} + +" }}} + " ********************************************************************************************************** " **** 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 - window = None - 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.window = vim.current.window - self.screen = ConqueScreen() - # }}} - - # start program and initialize this instance - def open(self, command, options): # {{{ - - # int vars - self.columns = self.window.width - self.lines = self.window.height - self.working_columns = self.window.width - self.working_lines = self.window.height - self.bottom = self.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): # {{{ - - # 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] - - 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 = self.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 self.window.width != self.columns or self.window.height != self.lines: - - # reset all window size attributes to default - self.columns = self.window.width - self.lines = self.window.height - self.working_columns = self.window.width - self.working_lines = self.window.height - self.bottom = self.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 - # }}} - - # }}} - -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 - window = 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.window = vim.current.window - - self.screen_top = 1 - self.screen_width = self.window.width - self.screen_height = self.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])) - - # XXX - Using python's version makes lots of super-fun segfaults - self.window.cursor = (real_line, real_column - 1) - #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 = self.window.width - self.screen_height = self.window.height - self.screen_top = len(self.buffer) - self.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): # {{{ - self.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 - +function! conque_term#load_python() " {{{ + + exec s:py . "file " . s:scriptdirpy . "conque_globals.py" + exec s:py . "file " . s:scriptdirpy . "conque.py" + exec s:py . "file " . s:scriptdirpy . "conque_screen.py" + exec s:py . "file " . s:scriptdirpy . "conque_subprocess.py" + if s:platform == 'dos' + exec s:py . "file " . s:scriptdirpy . "conque_win32_util.py" + exec s:py . "file " . s:scriptdirpy . "conque_sole_shared_memory.py" + exec s:py . "file " . s:scriptdirpy . "conque_sole.py" + exec s:py . "file " . s:scriptdirpy . "conque_sole_wrapper.py" + endif + +endfunction " }}} + +" vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque.py b/.vim/autoload/conque_term/conque.py new file mode 100644 index 0000000..6c7b2fc --- /dev/null +++ b/.vim/autoload/conque_term/conque.py @@ -0,0 +1,975 @@ +# FILE: autoload/conque_term/conque.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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 terminal emulator. + +The Conque does two things. First, it handles communication between Vim and +the terminal/console subprocess. For example, Vim uses the Conque.write() +method to send input, and Conque.read() to update the terminal buffer. + +Second, the Conque class handles Unix terminal escape sequence parsing. +""" + +import vim +import re +import math + + + + +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 + + # do we need to move the cursor? + cursor_set = False + + # current character set, ascii or graphics + character_set = 'ascii' + + # used for auto_read actions + read_count = 0 + + # }}} + + # 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)}) + + # send window size signal, in case LINES/COLUMNS is ignored + self.update_window_size(True) + # }}} + + # write to pty + def write(self, input, set_cursor=True, read=True): # {{{ + + # check if window size has changed + if read: + self.update_window_size() + + # write and read + self.proc.write(input) + + # read output immediately + if read: + self.read(1, set_cursor) + + # }}} + + # convert latin-1 input into utf-8 + # XXX - this is a hack, to be removed soon + def write_latin1(self, input, set_cursor=True, read=True): # {{{ + + if CONQUE_PYTHON_VERSION == 2: + try: + input_unicode = input.decode('latin-1', 'ignore') + self.write(input_unicode.encode('utf-8', 'ignore'), set_cursor, read) + except: + return + else: + self.write(input, set_cursor, read) + + # }}} + + # read from pty, and update buffer + def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True): # {{{ + output = '' + + # this may not actually work + try: + + # read from subprocess + output = self.proc.read(timeout) + # and strip null chars + output = output.replace(chr(0), '') + + if output == '': + return + + # for bufferless terminals + if not update_buffer: + return output + + + + + + 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 charset match {{{ + elif CONQUE_SEQ_REGEX_CHAR.match(s): + + if s[-1] in CONQUE_ESCAPE_CHARSET: + getattr(self, 'charset_' + CONQUE_ESCAPE_CHARSET[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) + # }}} + + # check window size + if set_cursor: + self.screen.set_cursor(self.l, self.c) + + # we need to set the cursor position + self.cursor_set = False + + vim.command('redraw') + + + + except: + + + pass + + if return_output: + if CONQUE_PYTHON_VERSION == 3: + return output + else: + return output.encode(vim.eval('&encoding'), 'replace') + # }}} + + # for polling + def auto_read(self): # {{{ + + # check subprocess status, but not every time since it's CPU expensive + if self.read_count == 10: + if not self.proc.is_alive(): + vim.command('call conque_term#get_instance().close()') + return + else: + self.read_count = 0 + self.read_count += 1 + + # read output + self.read(1) + + # reset timer + if self.c == 1: + vim.command('call feedkeys("\\", "n")') + else: + vim.command('call feedkeys("\\", "n")') + + # stop here if cursor doesn't need to be moved + if self.cursor_set: + return + + # otherwise set cursor position + try: + self.set_cursor(self.l, self.c) + except: + + + pass + self.cursor_set = True + + # }}} + + ############################################################################################### + # Plain text # {{{ + + def plain_text(self, input): + + # translate input into correct character set + if self.character_set == 'graphics': + old_input = input + input = '' + for i in range(0, len(old_input)): + chrd = ord(old_input[i]) + + + try: + if chrd > 255: + + input = input + old_input[i] + else: + input = input + unichr(CONQUE_GRAPHICS_SET[chrd]) + except: + + pass + + + 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, line=0): + + + # stop here if coloration is disabled + if not self.enable_colors: + return + + # allow custom line nr to be passed + if line: + real_line = line + else: + real_line = self.screen.get_real_line(self.l) + + # check for previous overlapping coloration + + to_del = [] + if real_line in self.color_history: + 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 real_line in self.color_history: + 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_soh(self): + pass + + def ctl_stx(self): + pass + + def ctl_bel(self): + vim.command('call conque_term#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 + + def ctl_so(self): + self.character_set = 'graphics' + + def ctl_si(self): + self.character_set = 'ascii' + + # }}} + + ############################################################################################### + # 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 val in CONQUE_FONT: + + # 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 attr in self.color_changes 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 real_line in self.color_history: + 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 + # }}} + + # }}} + + ############################################################################################### + # CHARSET functions {{{ + + def charset_us(self): + self.character_set = 'ascii' + + def charset_uk(self): + self.character_set = 'ascii' + + def charset_graphics(self): + self.character_set = 'graphics' + + # }}} + + ############################################################################################### + # Random stuff {{{ + + def set_cursor(self, line, col): + self.screen.set_cursor(line, col) + + def change_title(self, key, val): + + + if key == '0' or key == '2': + + vim.command('setlocal statusline=' + re.escape(val)) + try: + vim.command('set titlestring=' + re.escape(val)) + except: + pass + + def paste(self): + input = vim.eval('@@') + input = input.replace("\n", "\r") + self.read(50) + + def paste_selection(self): + input = vim.eval('@@') + input = input.replace("\n", "\r") + self.write(input) + + def update_window_size(self, force=False): + # resize if needed + if force or 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 insert_enter(self): + + # check window size + self.update_window_size() + + # we need to set the cursor position + self.cursor_set = False + + 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) + + def idle(self): + pass + + def resume(self): + pass + + def close(self): + self.proc.close() + + def abort(self): + self.proc.signal(1) + + # }}} + + ############################################################################################### + # 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 + # }}} + + # }}} + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_globals.py b/.vim/autoload/conque_term/conque_globals.py new file mode 100644 index 0000000..dfc3707 --- /dev/null +++ b/.vim/autoload/conque_term/conque_globals.py @@ -0,0 +1,287 @@ +# FILE: autoload/conque_term/conque_globals.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +"""Common global constants and functions for Conque.""" + +import sys +import os +import re + + + + + + + + + + + + + + + + + +# shared memory size +CONQUE_SOLE_BUFFER_LENGTH = 1000 +CONQUE_SOLE_INPUT_SIZE = 1000 +CONQUE_SOLE_STATS_SIZE = 1000 +CONQUE_SOLE_COMMANDS_SIZE = 255 +CONQUE_SOLE_RESCROLL_SIZE = 255 +CONQUE_SOLE_RESIZE_SIZE = 255 + +# interval of screen redraw +# larger number means less frequent +CONQUE_SOLE_SCREEN_REDRAW = 100 + +# interval of full buffer redraw +# larger number means less frequent +CONQUE_SOLE_BUFFER_REDRAW = 500 + +# interval of full output bucket replacement +# larger number means less frequent, 1 = every time +CONQUE_SOLE_MEM_REDRAW = 1000 + +# PYTHON VERSION +CONQUE_PYTHON_VERSION = sys.version_info[0] + + +def u(str_val, str_encoding='latin-1', errors='strict'): + """foolhardy attempt to make unicode string syntax compatible with both python 2 and 3""" + + if not str_val: + str_val = '' + + if CONQUE_PYTHON_VERSION == 3: + return str_val + + else: + return unicode(str_val, str_encoding, errors) + +# Escape sequence settings {{{ + +CONQUE_CTL = { + 1: 'soh', # start of heading + 2: 'stx', # start of text + 7: 'bel', # bell + 8: 'bs', # backspace + 9: 'tab', # tab + 10: 'nl', # new line + 13: 'cr', # carriage return + 14: 'so', # shift out + 15: 'si' # shift in +} +# 11 : 'vt', # vertical tab +# 12 : 'ff', # form feed + +# 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', + +# Character set escape sequences, with "(" +CONQUE_ESCAPE_CHARSET = { + 'A': 'uk', + 'B': 'us', + '0': 'graphics' +} + +# 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', + +CONQUE_GRAPHICS_SET = [ + 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, + 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F, + 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017, + 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F, + 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027, + 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F, + 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, + 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F, + 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047, + 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F, + 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057, + 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x00A0, + 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x00B0, 0x00B1, + 0x2591, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0xF800, + 0xF801, 0x2500, 0xF803, 0xF804, 0x251C, 0x2524, 0x2534, 0x252C, + 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F, + 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087, + 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F, + 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097, + 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F, + 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7, + 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF, + 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7, + 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF, + 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7, + 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF, + 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7, + 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF, + 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7, + 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF, + 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7, + 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF +] + +# 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(u("(\x1b\[?\??#?[0-9;]*[a-zA-Z0-9@=>]|\x1b\][0-9];.*?\x07|[\x01-\x0f]|\x1b\([AB0])"), re.UNICODE) +CONQUE_SEQ_REGEX_CTL = re.compile(u("^[\x01-\x0f]$"), re.UNICODE) +CONQUE_SEQ_REGEX_CSI = re.compile(u("^\x1b\["), re.UNICODE) +CONQUE_SEQ_REGEX_TITLE = re.compile(u("^\x1b\]"), re.UNICODE) +CONQUE_SEQ_REGEX_HASH = re.compile(u("^\x1b#"), re.UNICODE) +CONQUE_SEQ_REGEX_ESC = re.compile(u("^\x1b.$"), re.UNICODE) +CONQUE_SEQ_REGEX_CHAR = re.compile(u("^\x1b\("), re.UNICODE) + +# match table output +CONQUE_TABLE_OUTPUT = re.compile("^\s*\|\s.*\s\|\s*$|^\s*\+[=+-]+\+\s*$") + +# }}} + +# Windows subprocess config {{{ + +CONQUE_SEQ_REGEX_VK = re.compile(u("(\x1b\[\d{1,3}VK)"), re.UNICODE) + +# }}} + +CONQUE_COLOR_SEQUENCE = ( + '000', '009', '090', '099', '900', '909', '990', '999', + '000', '00f', '0f0', '0ff', 'f00', 'f0f', 'ff0', 'fff' +) + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_screen.py b/.vim/autoload/conque_term/conque_screen.py new file mode 100644 index 0000000..a1eb4ee --- /dev/null +++ b/.vim/autoload/conque_term/conque_screen.py @@ -0,0 +1,209 @@ +# FILE: autoload/conque_term/conque_screen.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +""" +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 u(self.buffer[real_line], 'utf-8') + # }}} + + def __setitem__(self, key, value): # {{{ + real_line = self.get_real_idx(key) + + if CONQUE_PYTHON_VERSION == 2: + val = value.encode('utf-8') + else: + # XXX / Vim's python3 interface doesn't accept bytes object + val = str(value) + + # if line is past end of screen, append + if real_line == len(self.buffer): + self.buffer.append(val) + else: + self.buffer[real_line] = val + # }}} + + 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.append(value, l) + + # }}} + # }}} + + ############################################################################################### + # 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') + # }}} + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_sole.py b/.vim/autoload/conque_term/conque_sole.py new file mode 100644 index 0000000..d66078e --- /dev/null +++ b/.vim/autoload/conque_term/conque_sole.py @@ -0,0 +1,459 @@ +# FILE: autoload/conque_term/conque_sole.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +import vim + + +class ConqueSole(Conque): + + window_top = None + window_bottom = None + + color_cache = {} + color_mode = None + color_conceals = {} + + buffer = None + + # counters for periodic rendering + buffer_redraw_ct = 0 + screen_redraw_ct = 0 + + # ********************************************************************************************* + # start program and initialize this instance + + def open(self, command, options={}, python_exe='', communicator_py=''): # {{{ + + # init size + self.columns = vim.current.window.width + self.lines = vim.current.window.height + self.window_top = 0 + self.window_bottom = vim.current.window.height - 1 + + # init color + self.enable_colors = options['color'] + + # open command + self.proc = ConqueSoleWrapper() + self.proc.open(command, {'TERM': options['TERM'], 'CONQUE': '1', 'LINES': self.lines, 'COLUMNS': self.columns}, python_exe, communicator_py) + + self.buffer = vim.current.buffer + + # }}} + + + # ********************************************************************************************* + # read and update screen + + def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True): # {{{ + + try: + stats = self.proc.get_stats() + + if not stats: + return + + self.buffer_redraw_ct += 1 + self.screen_redraw_ct += 1 + + update_top = 0 + update_bottom = 0 + lines = [] + + # full buffer redraw, our favorite! + if self.buffer_redraw_ct == CONQUE_SOLE_BUFFER_REDRAW: + self.buffer_redraw_ct = 0 + update_top = 0 + update_bottom = stats['top_offset'] + self.lines + (lines, attributes) = self.proc.read(update_top, update_bottom) + if return_output: + output = self.get_new_output(lines, update_top, stats) + if update_buffer: + for i in range(update_top, update_bottom + 1): + self.plain_text(i, lines[i], attributes[i], stats) + + # full screen redraw + elif stats['cursor_y'] + 1 != self.l or stats['top_offset'] != self.window_top or self.screen_redraw_ct == CONQUE_SOLE_SCREEN_REDRAW: + self.screen_redraw_ct = 0 + update_top = self.window_top + update_bottom = stats['top_offset'] + self.lines + 1 + (lines, attributes) = self.proc.read(update_top, update_bottom - update_top + 1) + if return_output: + output = self.get_new_output(lines, update_top, stats) + if update_buffer: + for i in range(update_top, update_bottom + 1): + self.plain_text(i, lines[i - update_top], attributes[i - update_top], stats) + + + # single line redraw + else: + update_top = stats['cursor_y'] + update_bottom = stats['cursor_y'] + (lines, attributes) = self.proc.read(update_top, 1) + if return_output: + output = self.get_new_output(lines, update_top, stats) + if update_buffer: + if lines[0].rstrip() != self.buffer[update_top].rstrip(): + self.plain_text(update_top, lines[0], attributes[0], stats) + + + # reset current position + self.window_top = stats['top_offset'] + self.l = stats['cursor_y'] + 1 + self.c = stats['cursor_x'] + 1 + + # reposition cursor if this seems plausible + if set_cursor: + self.set_cursor(self.l, self.c) + + if return_output: + return output + + except: + + pass + # }}} + + ######################################################################### + # Calculate the "new" output from this read. Fake but useful + + def get_new_output(self, lines, update_top, stats): # {{{ + + if not (stats['cursor_y'] + 1 > self.l or (stats['cursor_y'] + 1 == self.l and stats['cursor_x'] + 1 > self.c)): + return "" + + + + + + + try: + num_to_return = stats['cursor_y'] - self.l + 2 + + lines = lines[self.l - update_top - 1:] + + + new_output = [] + + # first line + new_output.append(lines[0][self.c - 1:].rstrip()) + + # the rest + for i in range(1, num_to_return): + new_output.append(lines[i].rstrip()) + + except: + + pass + + + + return "\n".join(new_output) + # }}} + + ######################################################################### + # update the buffer + + def plain_text(self, line_nr, text, attributes, stats): # {{{ + + + + + + self.l = line_nr + 1 + + # remove trailing whitespace + text = text.rstrip() + + # if we're using concealed text for color, then s- is weird + if self.color_mode == 'conceal': + + text = self.add_conceal_color(text, attributes, stats, line_nr) + + + # update vim buffer + if len(self.buffer) <= line_nr: + self.buffer.append(text) + else: + self.buffer[line_nr] = text + + if not self.color_mode == 'conceal': + self.do_color(attributes=attributes, stats=stats) + + # }}} + + ######################################################################### + # add conceal color + + def add_conceal_color(self, text, attributes, stats, line_nr): # {{{ + + # stop here if coloration is disabled + if not self.enable_colors: + return text + + # if no colors for this line, clear everything out + if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes): + return text + + new_text = '' + + # if text attribute is different, call add_color() + attr = None + start = 0 + self.color_conceals[line_nr] = [] + ends = [] + for i in range(0, len(attributes)): + c = ord(attributes[i]) + + if c != attr: + if attr and attr != stats['default_attribute']: + + color = self.translate_color(attr) + + new_text += chr(27) + 'sf' + color['fg_code'] + ';' + ends.append(chr(27) + 'ef' + color['fg_code'] + ';') + self.color_conceals[line_nr].append(start) + + if c > 15: + new_text += chr(27) + 'sf' + color['bg_code'] + ';' + ends.append(chr(27) + 'ef' + color['bg_code'] + ';') + self.color_conceals[line_nr].append(start) + + new_text += text[start:i] + + # close color regions + ends.reverse() + for j in range(0, len(ends)): + new_text += ends[j] + self.color_conceals[line_nr].append(i) + ends = [] + + start = i + attr = c + + + if attr and attr != stats['default_attribute']: + + color = self.translate_color(attr) + + new_text += chr(27) + 'sf' + color['fg_code'] + ';' + ends.append(chr(27) + 'ef' + color['fg_code'] + ';') + + if c > 15: + new_text += chr(27) + 'sf' + color['bg_code'] + ';' + ends.append(chr(27) + 'ef' + color['bg_code'] + ';') + + new_text += text[start:] + + # close color regions + ends.reverse() + for i in range(0, len(ends)): + new_text += ends[i] + + return new_text + + # }}} + + ######################################################################### + + def do_color(self, start=0, end=0, attributes='', stats=None): # {{{ + + # stop here if coloration is disabled + if not self.enable_colors: + return + + # if no colors for this line, clear everything out + if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes): + self.color_changes = {} + self.apply_color(1, len(attributes), self.l) + return + + # if text attribute is different, call add_color() + attr = None + start = 0 + for i in range(0, len(attributes)): + c = ord(attributes[i]) + + if c != attr: + if attr and attr != stats['default_attribute']: + self.color_changes = self.translate_color(attr) + self.apply_color(start + 1, i + 1, self.l) + start = i + attr = c + + if attr and attr != stats['default_attribute']: + self.color_changes = self.translate_color(attr) + self.apply_color(start + 1, len(attributes), self.l) + + + # }}} + + ######################################################################### + + def translate_color(self, attr): # {{{ + + # check for cached color + if attr in self.color_cache: + return self.color_cache[attr] + + + + + + + # convert attribute integer to bit string + bit_str = bin(attr) + bit_str = bit_str.replace('0b', '') + + # slice foreground and background portions of bit string + fg = bit_str[-4:].rjust(4, '0') + bg = bit_str[-8:-4].rjust(4, '0') + + # ok, first create foreground #rbg + red = int(fg[1]) * 204 + int(fg[0]) * int(fg[1]) * 51 + green = int(fg[2]) * 204 + int(fg[0]) * int(fg[2]) * 51 + blue = int(fg[3]) * 204 + int(fg[0]) * int(fg[3]) * 51 + fg_str = "#%02x%02x%02x" % (red, green, blue) + fg_code = "%02x%02x%02x" % (red, green, blue) + fg_code = fg_code[0] + fg_code[2] + fg_code[4] + + # ok, first create foreground #rbg + red = int(bg[1]) * 204 + int(bg[0]) * int(bg[1]) * 51 + green = int(bg[2]) * 204 + int(bg[0]) * int(bg[2]) * 51 + blue = int(bg[3]) * 204 + int(bg[0]) * int(bg[3]) * 51 + bg_str = "#%02x%02x%02x" % (red, green, blue) + bg_code = "%02x%02x%02x" % (red, green, blue) + bg_code = bg_code[0] + bg_code[2] + bg_code[4] + + # build value for color_changes + + color = {'guifg': fg_str, 'guibg': bg_str} + + if self.color_mode == 'conceal': + color['fg_code'] = fg_code + color['bg_code'] = bg_code + + self.color_cache[attr] = color + + return color + + # }}} + + ######################################################################### + # write virtual key code to shared memory using proprietary escape seq + + def write_vk(self, vk_code): # {{{ + + self.proc.write_vk(vk_code) + + # }}} + + # ********************************************************************************************* + # resize if needed + + def update_window_size(self): # {{{ + + 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 + + self.proc.window_resize(vim.current.window.height, vim.current.window.width) + + # }}} + + # ********************************************************************************************* + # resize if needed + + def set_cursor(self, line, column): # {{{ + + # shift cursor position to handle concealed text + if self.enable_colors and self.color_mode == 'conceal': + if line - 1 in self.color_conceals: + for c in self.color_conceals[line - 1]: + if c < column: + column += 7 + else: + break + + # figure out line + real_line = line + 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) + ')') + # }}} + + + # ********************************************************************************************* + # go into idle mode + + def idle(self): # {{{ + + self.proc.idle() + + # }}} + + # ********************************************************************************************* + # resume from idle mode + + def resume(self): # {{{ + + self.proc.resume() + + # }}} + + # ********************************************************************************************* + # end subprocess + + def close(self): + self.proc.close() + + # ********************************************************************************************* + # end subprocess forcefully + + def abort(self): + self.proc.close() + + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_sole_communicator.py b/.vim/autoload/conque_term/conque_sole_communicator.py new file mode 100644 index 0000000..5c19ff3 --- /dev/null +++ b/.vim/autoload/conque_term/conque_sole_communicator.py @@ -0,0 +1,183 @@ +# FILE: autoload/conque_term/conque_sole_communicator.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +""" +ConqueSoleCommunicator + +Script to transfer communications between python being run in Vim and a +subprocess run inside a Windows console. This is required since interactive +programs in Windows appear to require a console, and python run in Vim is +not attached to any console. So a console version of python must be initiated +for the subprocess. Communication is then done with the use of shared memory +objects. Good times! +""" + +import time +import sys + +from conque_globals import * +from conque_win32_util import * +from conque_sole_subprocess import * +from conque_sole_shared_memory import * + +############################################################## +# only run if this file was run directly + +if __name__ == '__main__': + + # attempt to catch ALL exceptions to fend of zombies + try: + + # startup and config {{{ + + # simple arg validation + + if len(sys.argv) < 5: + + exit() + + # shared memory size + CONQUE_SOLE_COMMANDS_SIZE = 255 + + # maximum time this thing reads. 0 means no limit. Only for testing. + max_loops = 0 + + # read interval, in seconds + sleep_time = 0.01 + + # idle read interval, in seconds + idle_sleep_time = 0.10 + + # are we idled? + is_idle = False + + # mem key + mem_key = sys.argv[1] + + # console width + console_width = int(sys.argv[2]) + + # console height + console_height = int(sys.argv[3]) + + # the actual subprocess to run + cmd_line = " ".join(sys.argv[4:]) + + + # width and height + options = {'LINES': console_height, 'COLUMNS': console_width} + + + + # set initial idle status + shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True) + shm_command.create('write') + + cmd = shm_command.read() + if cmd: + + if cmd['cmd'] == 'idle': + is_idle = True + shm_command.clear() + + # }}} + + ############################################################## + # Create the subprocess + + # {{{ + proc = ConqueSoleSubprocess() + res = proc.open(cmd_line, mem_key, options) + + if not res: + + exit() + + # }}} + + ############################################################## + # main loop! + + loops = 0 + + while True: + + # check for idle/resume + if is_idle or loops % 25 == 0: + + # check process health + if not proc.is_alive(): + + proc.close() + exit() + + # check for change in buffer focus + cmd = shm_command.read() + if cmd: + + if cmd['cmd'] == 'idle': + is_idle = True + shm_command.clear() + + elif cmd['cmd'] == 'resume': + is_idle = False + shm_command.clear() + + + # sleep between loops if moderation is requested + if sleep_time > 0: + if is_idle: + time.sleep(idle_sleep_time) + else: + time.sleep(sleep_time) + + # write, read, etc + proc.write() + proc.read() + + # increment loops, and exit if max has been reached + loops += 1 + if max_loops and loops >= max_loops: + + break + + ############################################################## + # all done! + + + + proc.close() + + # if an exception was thrown, croak + except: + + proc.close() + + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_sole_shared_memory.py b/.vim/autoload/conque_term/conque_sole_shared_memory.py new file mode 100644 index 0000000..32817ac --- /dev/null +++ b/.vim/autoload/conque_term/conque_sole_shared_memory.py @@ -0,0 +1,202 @@ +# FILE: autoload/conque_term/conque_sole_shared_memory.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +"""Wrapper class for shared memory between Windows python processes""" + +import mmap +import sys + +if sys.version_info[0] == 2: + CONQUE_PYTHON_VERSION = 2 +else: + CONQUE_PYTHON_VERSION = 3 + +if CONQUE_PYTHON_VERSION == 2: + import cPickle as pickle +else: + import pickle + + +class ConqueSoleSharedMemory(): + + # **************************************************************************** + # class properties + + # {{{ + + # is the data being stored not fixed length + fixed_length = False + + # fill memory with this character when clearing and fixed_length is true + fill_char = ' ' + + # serialize and unserialize data automatically + serialize = False + + # size of shared memory, in bytes / chars + mem_size = None + + # size of shared memory, in bytes / chars + mem_type = None + + # unique key, so multiple console instances are possible + mem_key = None + + # mmap instance + shm = None + + # character encoding, dammit + encoding = 'ascii' + + # pickle terminator + TERMINATOR = None + + # }}} + + # **************************************************************************** + # constructor I guess + + def __init__(self, mem_size, mem_type, mem_key, fixed_length=False, fill_char=' ', serialize=False, encoding='ascii'): # {{{ + + self.mem_size = mem_size + self.mem_type = mem_type + self.mem_key = mem_key + self.fixed_length = fixed_length + self.fill_char = fill_char + self.serialize = serialize + self.encoding = encoding + self.TERMINATOR = str(chr(0)).encode(self.encoding) + + # }}} + + # **************************************************************************** + # create memory block + + def create(self, access='write'): # {{{ + + if access == 'write': + mmap_access = mmap.ACCESS_WRITE + else: + mmap_access = mmap.ACCESS_READ + + name = "conque_%s_%s" % (self.mem_type, self.mem_key) + + self.shm = mmap.mmap(0, self.mem_size, name, mmap_access) + + if not self.shm: + return False + else: + return True + + # }}} + + # **************************************************************************** + # read data + + def read(self, chars=1, start=0): # {{{ + + # invalid reads + if self.fixed_length and (chars == 0 or start + chars > self.mem_size): + return '' + + # go to start position + self.shm.seek(start) + + if not self.fixed_length: + chars = self.shm.find(self.TERMINATOR) + + if chars == 0: + return '' + + shm_str = self.shm.read(chars) + + # return unpickled byte object + if self.serialize: + return pickle.loads(shm_str) + + # decode byes in python 3 + if CONQUE_PYTHON_VERSION == 3: + return str(shm_str, self.encoding) + + # encoding + if self.encoding != 'ascii': + shm_str = unicode(shm_str, self.encoding) + + return shm_str + + # }}} + + # **************************************************************************** + # write data + + def write(self, text, start=0): # {{{ + + # simple scenario, let pickle create bytes + if self.serialize: + if CONQUE_PYTHON_VERSION == 3: + tb = pickle.dumps(text, 0) + else: + tb = pickle.dumps(text, 0).encode(self.encoding) + + else: + tb = text.encode(self.encoding, 'replace') + + self.shm.seek(start) + + # write to memory + if self.fixed_length: + self.shm.write(tb) + else: + self.shm.write(tb + self.TERMINATOR) + + # }}} + + # **************************************************************************** + # clear + + def clear(self, start=0): # {{{ + + self.shm.seek(start) + + if self.fixed_length: + self.shm.write(str(self.fill_char * self.mem_size).encode(self.encoding)) + else: + self.shm.write(self.TERMINATOR) + + # }}} + + # **************************************************************************** + # close + + def close(self): + + self.shm.close() + + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_sole_subprocess.py b/.vim/autoload/conque_term/conque_sole_subprocess.py new file mode 100644 index 0000000..350a7df --- /dev/null +++ b/.vim/autoload/conque_term/conque_sole_subprocess.py @@ -0,0 +1,753 @@ +# FILE: autoload/conque_term/conque_sole_subprocess.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +""" ConqueSoleSubprocess {{{ + +Creates a new subprocess with it's own (hidden) console window. + +Mirrors console window text onto a block of shared memory (mmap), along with +text attribute data. Also handles translation of text input into the format +Windows console expects. + +Sample Usage: + + sh = ConqueSoleSubprocess() + sh.open("cmd.exe", "unique_str") + + shm_in = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "input", ...) + shm_out = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "output", ...) + + output = shm_out.read(...) + shm_in.write("dir\r") + output = shm_out.read(...) + +Requirements: + + * Python for Windows extensions. Available at http://sourceforge.net/projects/pywin32/ + * Must be run from process attached to an existing console. + +}}} """ + +import time +import re +import os +import ctypes + +from conque_globals import * +from conque_win32_util import * +from conque_sole_shared_memory import * + + +class ConqueSoleSubprocess(): + + # Class properties {{{ + + #window = None + handle = None + pid = None + + # input / output handles + stdin = None + stdout = None + + # size of console window + window_width = 160 + window_height = 40 + + # max lines for the console buffer + buffer_width = 160 + buffer_height = 100 + + # keep track of the buffer number at the top of the window + top = 0 + line_offset = 0 + + # buffer height is CONQUE_SOLE_BUFFER_LENGTH * output_blocks + output_blocks = 1 + + # cursor position + cursor_line = 0 + cursor_col = 0 + + # console data, array of lines + data = [] + + # console attribute data, array of array of int + attributes = [] + attribute_cache = {} + + # default attribute + default_attribute = 7 + + # shared memory objects + shm_input = None + shm_output = None + shm_attributes = None + shm_stats = None + shm_command = None + shm_rescroll = None + shm_resize = None + + # are we still a valid process? + is_alive = True + + # used for periodic execution of screen and memory redrawing + screen_redraw_ct = 0 + mem_redraw_ct = 0 + + # }}} + + # **************************************************************************** + # initialize class instance + + def __init__(self): # {{{ + + pass + + # }}} + + # **************************************************************************** + # Create proccess cmd + + def open(self, cmd, mem_key, options={}): # {{{ + + + + self.reset = True + + try: + # if we're already attached to a console, then unattach + try: + ctypes.windll.kernel32.FreeConsole() + except: + pass + + # set buffer height + self.buffer_height = CONQUE_SOLE_BUFFER_LENGTH + + if 'LINES' in options and 'COLUMNS' in options: + self.window_width = options['COLUMNS'] + self.window_height = options['LINES'] + self.buffer_width = options['COLUMNS'] + + # console window options + si = STARTUPINFO() + + # hide window + si.dwFlags |= STARTF_USESHOWWINDOW + si.wShowWindow = SW_HIDE + #si.wShowWindow = SW_MINIMIZE + + # process options + flags = NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE + + # created process info + pi = PROCESS_INFORMATION() + + + + # create the process! + res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi)) + + + + + self.pid = pi.dwProcessId + self.handle = pi.hProcess + + + + # attach ourselves to the new console + # console is not immediately available + for i in range(10): + time.sleep(1) + try: + + res = ctypes.windll.kernel32.AttachConsole(self.pid) + + + + + + + break + except: + + pass + + # get input / output handles + self.stdout = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE) + self.stdin = ctypes.windll.kernel32.GetStdHandle(STD_INPUT_HANDLE) + + # set buffer size + size = COORD(self.buffer_width, self.buffer_height) + res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size) + + + + + + + + # prev set size call needs to process + time.sleep(0.2) + + # set window size + self.set_window_size(self.window_width, self.window_height) + + # init shared memory + self.init_shared_memory(mem_key) + + # init read buffers + self.tc = ctypes.create_unicode_buffer(self.buffer_width) + self.ac = ctypes.create_unicode_buffer(self.buffer_width) + + return True + + except: + + return False + + # }}} + + # **************************************************************************** + # create shared memory objects + + def init_shared_memory(self, mem_key): # {{{ + + buf_info = self.get_buffer_info() + + + + + self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key) + self.shm_input.create('write') + self.shm_input.clear() + + self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'output', mem_key, True) + self.shm_output.create('write') + self.shm_output.clear() + + self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1') + self.shm_attributes.create('write') + self.shm_attributes.clear() + + self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True) + self.shm_stats.create('write') + self.shm_stats.clear() + + self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True) + self.shm_command.create('write') + self.shm_command.clear() + + self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True) + self.shm_resize.create('write') + self.shm_resize.clear() + + self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True) + self.shm_rescroll.create('write') + self.shm_rescroll.clear() + + return True + + # }}} + + # **************************************************************************** + # check for and process commands + + def check_commands(self): # {{{ + + cmd = self.shm_command.read() + + if cmd: + + # shut it all down + if cmd['cmd'] == 'close': + + # clear command + self.shm_command.clear() + + self.close() + return + + cmd = self.shm_resize.read() + + if cmd: + + # clear command + self.shm_resize.clear() + + # resize console + if cmd['cmd'] == 'resize': + + + + # only change buffer width if it's larger + if cmd['data']['width'] > self.buffer_width: + self.buffer_width = cmd['data']['width'] + + # always change console width and height + self.window_width = cmd['data']['width'] + self.window_height = cmd['data']['height'] + + # reset the console + buf_info = self.get_buffer_info() + self.reset_console(buf_info, add_block=False) + + # }}} + + # **************************************************************************** + # read from windows console and update output buffer + + def read(self, timeout=0): # {{{ + + # no point really + if self.screen_redraw_ct == 0 and not self.is_alive(): + stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0} + + self.shm_stats.write(stats) + return + + # check for commands + self.check_commands() + + # emulate timeout by sleeping timeout time + if timeout > 0: + read_timeout = float(timeout) / 1000 + + time.sleep(read_timeout) + + # get cursor position + buf_info = self.get_buffer_info() + curs_line = buf_info.dwCursorPosition.Y + curs_col = buf_info.dwCursorPosition.X + + # set update range + if curs_line != self.cursor_line or self.top != buf_info.srWindow.Top or self.screen_redraw_ct == CONQUE_SOLE_SCREEN_REDRAW: + self.screen_redraw_ct = 0 + + read_start = self.top + read_end = buf_info.srWindow.Bottom + 1 + else: + + read_start = curs_line + read_end = curs_line + 1 + + # vars used in for loop + coord = COORD(0, 0) + chars_read = ctypes.c_int(0) + + # read new data + for i in range(read_start, read_end): + + coord.Y = i + + res = ctypes.windll.kernel32.ReadConsoleOutputCharacterW(self.stdout, ctypes.byref(self.tc), self.buffer_width, coord, ctypes.byref(chars_read)) + ctypes.windll.kernel32.ReadConsoleOutputAttribute(self.stdout, ctypes.byref(self.ac), self.buffer_width, coord, ctypes.byref(chars_read)) + + t = self.tc.value + a = self.ac.value + + + + + # add data + if i >= len(self.data): + self.data.append(t) + self.attributes.append(a) + else: + self.data[i] = t + self.attributes[i] = a + + # write new output to shared memory + if self.mem_redraw_ct == CONQUE_SOLE_MEM_REDRAW: + self.mem_redraw_ct = 0 + + self.shm_output.write(''.join(self.data)) + self.shm_attributes.write(''.join(self.attributes)) + else: + + self.shm_output.write(text=''.join(self.data[read_start:read_end]), start=read_start * self.buffer_width) + self.shm_attributes.write(text=''.join(self.attributes[read_start:read_end]), start=read_start * self.buffer_width) + + # write cursor position to shared memory + stats = {'top_offset': buf_info.srWindow.Top, 'default_attribute': buf_info.wAttributes, 'cursor_x': curs_col, 'cursor_y': curs_line, 'is_alive': 1} + self.shm_stats.write(stats) + + + # adjust screen position + self.top = buf_info.srWindow.Top + self.cursor_line = curs_line + + # check for reset + if curs_line > buf_info.dwSize.Y - 200: + self.reset_console(buf_info) + + # increment redraw counters + self.screen_redraw_ct += 1 + self.mem_redraw_ct += 1 + + return None + + # }}} + + # **************************************************************************** + # clear the console and set cursor at home position + + def reset_console(self, buf_info, add_block=True): # {{{ + + # sometimes we just want to change the buffer width, + # in which case no need to add another block + if add_block: + self.output_blocks += 1 + + # close down old memory + self.shm_output.close() + self.shm_output = None + + self.shm_attributes.close() + self.shm_attributes = None + + # new shared memory key + mem_key = 'mk' + str(time.time()) + + # reallocate memory + self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'output', mem_key, True) + self.shm_output.create('write') + self.shm_output.clear() + + # backfill data + if len(self.data[0]) < self.buffer_width: + for i in range(0, len(self.data)): + self.data[i] = self.data[i] + ' ' * (self.buffer_width - len(self.data[i])) + self.shm_output.write(''.join(self.data)) + + self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1') + self.shm_attributes.create('write') + self.shm_attributes.clear() + + # backfill attributes + if len(self.attributes[0]) < self.buffer_width: + for i in range(0, len(self.attributes)): + self.attributes[i] = self.attributes[i] + chr(buf_info.wAttributes) * (self.buffer_width - len(self.attributes[i])) + self.shm_attributes.write(''.join(self.attributes)) + + # notify wrapper of new output block + self.shm_rescroll.write({'cmd': 'new_output', 'data': {'blocks': self.output_blocks, 'mem_key': mem_key}}) + + # set buffer size + size = COORD(X=self.buffer_width, Y=self.buffer_height * self.output_blocks) + + res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size) + + + + + + + # prev set size call needs to process + time.sleep(0.2) + + # set window size + self.set_window_size(self.window_width, self.window_height) + + # init read buffers + self.tc = ctypes.create_unicode_buffer(self.buffer_width) + self.ac = ctypes.create_unicode_buffer(self.buffer_width) + + # }}} + + # **************************************************************************** + # write text to console. this function just parses out special sequences for + # special key events and passes on the text to the plain or virtual key functions + + def write(self): # {{{ + + # get input from shared mem + text = self.shm_input.read() + + # nothing to do here + if text == '': + return + + + + # clear input queue + self.shm_input.clear() + + # split on VK codes + chunks = CONQUE_SEQ_REGEX_VK.split(text) + + # if len() is one then no vks + if len(chunks) == 1: + self.write_plain(text) + return + + + + # loop over chunks and delegate + for t in chunks: + + if t == '': + continue + + if CONQUE_SEQ_REGEX_VK.match(t): + + self.write_vk(t[2:-2]) + else: + self.write_plain(t) + + # }}} + + # **************************************************************************** + + def write_plain(self, text): # {{{ + + li = INPUT_RECORD * len(text) + list_input = li() + + for i in range(0, len(text)): + # create keyboard input + ke = KEY_EVENT_RECORD() + ke.bKeyDown = ctypes.c_byte(1) + ke.wRepeatCount = ctypes.c_short(1) + + cnum = ord(text[i]) + ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum) + ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(cnum), 0)) + + if cnum > 31: + ke.uChar.UnicodeChar = u(chr(cnum)) + elif cnum == 3: + ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, self.pid) + ke.uChar.UnicodeChar = u(chr(cnum)) + ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96) + ke.dwControlKeyState = LEFT_CTRL_PRESSED + else: + ke.uChar.UnicodeChar = u(chr(cnum)) + if cnum in CONQUE_WINDOWS_VK_INV: + ke.wVirtualKeyCode = cnum + else: + ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96) + ke.dwControlKeyState = LEFT_CTRL_PRESSED + + kc = INPUT_RECORD(KEY_EVENT) + kc.Event.KeyEvent = ke + list_input[i] = kc + + + + # write input array + events_written = ctypes.c_int() + res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, len(text), ctypes.byref(events_written)) + + + + + + + + + # }}} + + # **************************************************************************** + + def write_vk(self, vk_code): # {{{ + + + li = INPUT_RECORD * 1 + + # create keyboard input + ke = KEY_EVENT_RECORD() + ke.uChar.UnicodeChar = u(chr(0)) + ke.wVirtualKeyCode = ctypes.c_short(int(vk_code)) + ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(vk_code), 0)) + ke.bKeyDown = ctypes.c_byte(1) + ke.wRepeatCount = ctypes.c_short(1) + + # set enhanced key mode for arrow keys + if vk_code in CONQUE_WINDOWS_VK_ENHANCED: + + ke.dwControlKeyState = ENHANCED_KEY + + kc = INPUT_RECORD(KEY_EVENT) + kc.Event.KeyEvent = ke + list_input = li(kc) + + # write input array + events_written = ctypes.c_int() + res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, 1, ctypes.byref(events_written)) + + + + + + + + # }}} + + # **************************************************************************** + + def close(self): # {{{ + + # record status + self.is_alive = False + try: + stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0} + self.shm_stats.write(stats) + except: + pass + + pid_list = (ctypes.c_int * 10)() + num = ctypes.windll.kernel32.GetConsoleProcessList(pid_list, 10) + + + + current_pid = os.getpid() + + + + + + # kill subprocess pids + for pid in pid_list[0:num]: + if not pid: + break + + # kill current pid last + if pid == current_pid: + continue + try: + self.close_pid(pid) + except: + + pass + + # kill this process + try: + self.close_pid(current_pid) + except: + + pass + + def close_pid(self, pid): + + handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, 0, pid) + ctypes.windll.kernel32.TerminateProcess(handle, -1) + ctypes.windll.kernel32.CloseHandle(handle) + + # }}} + + # **************************************************************************** + # check process health + + def is_alive(self): # {{{ + + status = ctypes.windll.kernel32.WaitForSingleObject(self.handle, 1) + + if status == 0: + + self.is_alive = False + + return self.is_alive + + # }}} + + + # **************************************************************************** + # return screen data as string + + def get_screen_text(self): # {{{ + + return "\n".join(self.data) + + # }}} + + # **************************************************************************** + + def set_window_size(self, width, height): # {{{ + + + + # get current window size object + window_size = SMALL_RECT(0, 0, 0, 0) + + # buffer info has maximum window size data + buf_info = self.get_buffer_info() + + + # set top left corner + window_size.Top = 0 + window_size.Left = 0 + + # set bottom right corner + if buf_info.dwMaximumWindowSize.X < width: + + window_size.Right = buf_info.dwMaximumWindowSize.X - 1 + else: + window_size.Right = width - 1 + + if buf_info.dwMaximumWindowSize.Y < height: + + window_size.Bottom = buf_info.dwMaximumWindowSize.Y - 1 + else: + window_size.Bottom = height - 1 + + + + # set the window size! + res = ctypes.windll.kernel32.SetConsoleWindowInfo(self.stdout, ctypes.c_bool(True), ctypes.byref(window_size)) + + + + + + + # reread buffer info to get final console max lines + buf_info = self.get_buffer_info() + + self.window_width = buf_info.srWindow.Right + 1 + self.window_height = buf_info.srWindow.Bottom + 1 + + # }}} + + # **************************************************************************** + # get buffer info, used a lot + + def get_buffer_info(self): # {{{ + + buf_info = CONSOLE_SCREEN_BUFFER_INFO() + ctypes.windll.kernel32.GetConsoleScreenBufferInfo(self.stdout, ctypes.byref(buf_info)) + + return buf_info + + # }}} + + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_sole_wrapper.py b/.vim/autoload/conque_term/conque_sole_wrapper.py new file mode 100644 index 0000000..3d480c9 --- /dev/null +++ b/.vim/autoload/conque_term/conque_sole_wrapper.py @@ -0,0 +1,304 @@ +# FILE: autoload/conque_term/conque_sole_wrapper.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +""" ConqueSoleSubprocessWrapper {{{ + +Subprocess wrapper to deal with Windows insanity. Launches console based python, +which in turn launches originally requested command. Communicates with cosole +python through shared memory objects. + +}}} """ + +import ctypes +import time + + +class ConqueSoleWrapper(): + + # class properties {{{ + + shm_key = '' + + # process info + handle = None + pid = None + + # queue input in this bucket + bucket = None + + # console size + # NOTE: columns should never change after open() is called + lines = 24 + columns = 80 + + # shared memory objects + shm_input = None + shm_output = None + shm_attributes = None + shm_stats = None + shm_command = None + shm_rescroll = None + shm_resize = None + + # console python process + proc = None + + # }}} + + ######################################################################### + # unused + + def __init__(self): # {{{ + self.bucket = u('') + + # }}} + + ######################################################################### + # run communicator process which will in turn run cmd + + def open(self, cmd, options={}, python_exe='python.exe', communicator_py='conque_sole_communicator.py'): # {{{ + + self.lines = options['LINES'] + self.columns = options['COLUMNS'] + + # create a shm key + self.shm_key = 'mk' + str(time.time()) + + # python command + cmd_line = '%s "%s" %s %d %d %s' % (python_exe, communicator_py, self.shm_key, int(self.columns), int(self.lines), cmd) + + + # console window attributes + flags = NORMAL_PRIORITY_CLASS | DETACHED_PROCESS + si = STARTUPINFO() + pi = PROCESS_INFORMATION() + + # start the stupid process already + try: + res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd_line), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi)) + except: + + raise + + # handle + self.pid = pi.dwProcessId + + + + # init shared memory objects + self.init_shared_memory(self.shm_key) + + # }}} + + ######################################################################### + # read output from shared memory + + def read(self, start_line, num_lines, timeout=0): # {{{ + + # emulate timeout by sleeping timeout time + if timeout > 0: + read_timeout = float(timeout) / 1000 + + time.sleep(read_timeout) + + output = [] + attributes = [] + + # get output + for i in range(start_line, start_line + num_lines + 1): + output.append(self.shm_output.read(self.columns, i * self.columns)) + attributes.append(self.shm_attributes.read(self.columns, i * self.columns)) + + return (output, attributes) + + # }}} + + ######################################################################### + # get current cursor/scroll position + + def get_stats(self): # {{{ + + try: + rescroll = self.shm_rescroll.read() + if rescroll != '' and rescroll != None: + + + + self.shm_rescroll.clear() + + # close down old memory + self.shm_output.close() + self.shm_output = None + + self.shm_attributes.close() + self.shm_attributes = None + + # reallocate memory + + self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'output', rescroll['data']['mem_key'], True) + self.shm_output.create('read') + + self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'attributes', rescroll['data']['mem_key'], True, encoding='latin-1') + self.shm_attributes.create('read') + + stats_str = self.shm_stats.read() + if stats_str != '': + self.stats = stats_str + else: + return False + except: + + return False + + return self.stats + + # }}} + + ######################################################################### + # get process status + + def is_alive(self): # {{{ + if not self.shm_stats: + return True + + stats_str = self.shm_stats.read() + if stats_str: + return (stats_str['is_alive']) + else: + return True + # }}} + + ######################################################################### + # write input to shared memory + + def write(self, text): # {{{ + + self.bucket += u(text, 'ascii', 'replace') + + + + istr = self.shm_input.read() + + if istr == '': + + self.shm_input.write(self.bucket[:500]) + self.bucket = self.bucket[500:] + + # }}} + + ######################################################################### + # write virtual key code to shared memory using proprietary escape seq + + def write_vk(self, vk_code): # {{{ + + seq = "\x1b[" + str(vk_code) + "VK" + self.write(seq) + + # }}} + + ######################################################################### + # idle + + def idle(self): # {{{ + + + self.shm_command.write({'cmd': 'idle', 'data': {}}) + + # }}} + + ######################################################################### + # resume + + def resume(self): # {{{ + + self.shm_command.write({'cmd': 'resume', 'data': {}}) + + # }}} + + ######################################################################### + # shut it all down + + def close(self): # {{{ + + self.shm_command.write({'cmd': 'close', 'data': {}}) + time.sleep(0.2) + + # }}} + + ######################################################################### + # resize console window + + def window_resize(self, lines, columns): # {{{ + + self.lines = lines + + # we don't shrink buffer width + if columns > self.columns: + self.columns = columns + + self.shm_resize.write({'cmd': 'resize', 'data': {'width': columns, 'height': lines}}) + + # }}} + + # **************************************************************************** + # create shared memory objects + + def init_shared_memory(self, mem_key): # {{{ + + self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key) + self.shm_input.create('write') + self.shm_input.clear() + + self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'output', mem_key, True) + self.shm_output.create('write') + + self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'attributes', mem_key, True, encoding='latin-1') + self.shm_attributes.create('write') + + self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True) + self.shm_stats.create('write') + self.shm_stats.clear() + + self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True) + self.shm_command.create('write') + self.shm_command.clear() + + self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True) + self.shm_resize.create('write') + self.shm_resize.clear() + + self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True) + self.shm_rescroll.create('write') + self.shm_rescroll.clear() + + return True + + # }}} + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_subprocess.py b/.vim/autoload/conque_term/conque_subprocess.py new file mode 100644 index 0000000..db2b93c --- /dev/null +++ b/.vim/autoload/conque_term/conque_subprocess.py @@ -0,0 +1,195 @@ +# FILE: autoload/conque_term/conque_subprocess.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +""" +ConqueSubprocess + +Create and interact with a subprocess through a pty. + +Usage: + + p = ConqueSubprocess() + p.open('bash', {'TERM':'vt100'}) + output = p.read() + p.write('cd ~/vim' + "\r") + p.write('ls -lha' + "\r") + output += p.read(timeout = 500) + p.close() +""" + +if CONQUE_PLATFORM == 'nix': + import os + import signal + import pty + import tty + import select + import fcntl + import termios + import struct + + +class ConqueSubprocess: + + # process id + pid = 0 + + # stdout+stderr file descriptor + fd = None + + # constructor + def __init__(self): # {{{ + self.pid = 0 + # }}} + + # create pty + subprocess + def open(self, command, env={}): # {{{ + + # parse command + command_arr = command.split() + executable = command_arr[0] + args = command_arr + + # try to fork a new pty + try: + self.pid, self.fd = pty.fork() + + except: + + return False + + # 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 + + # replace this process with the subprocess + 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: + # read from fd until no more output + 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.decode('utf-8') + + if lines == '': + break + except: + pass + + return output + # }}} + + # I guess this one's not bad + def write(self, input): # {{{ + try: + if CONQUE_PYTHON_VERSION == 2: + os.write(self.fd, input) + else: + os.write(self.fd, bytes(input, 'utf-8')) + except: + + pass + # }}} + + # signal process + def signal(self, signum): # {{{ + try: + os.kill(self.pid, signum) + except: + pass + # }}} + + # close process + def close(self): # {{{ + self.signal(15) + # }}} + + # get process status + def is_alive(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 + + # }}} + + +# vim:foldmethod=marker diff --git a/.vim/autoload/conque_term/conque_win32_util.py b/.vim/autoload/conque_term/conque_win32_util.py new file mode 100644 index 0000000..c11bdde --- /dev/null +++ b/.vim/autoload/conque_term/conque_win32_util.py @@ -0,0 +1,473 @@ +# FILE: autoload/conque_term/conque_win32_util.py {{{ +# AUTHOR: Nico Raffo +# WEBSITE: http://conque.googlecode.com +# MODIFIED: 2010-11-15 +# VERSION: 2.0, for Vim 7.0 +# LICENSE: +# Conque - Vim terminal/console emulator +# 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. }}} + +"""Python structures used for ctypes interaction""" + +from ctypes import * + +# Constants + +# create process flag constants {{{ + +CREATE_BREAKAWAY_FROM_JOB = 0x01000000 +CREATE_DEFAULT_ERROR_MODE = 0x04000000 +CREATE_NEW_CONSOLE = 0x00000010 +CREATE_NEW_PROCESS_GROUP = 0x00000200 +CREATE_NO_WINDOW = 0x08000000 +CREATE_PROTECTED_PROCESS = 0x00040000 +CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000 +CREATE_SEPARATE_WOW_VDM = 0x00000800 +CREATE_SHARED_WOW_VDM = 0x00001000 +CREATE_SUSPENDED = 0x00000004 +CREATE_UNICODE_ENVIRONMENT = 0x00000400 + + +DETACHED_PROCESS = 0x00000008 +EXTENDED_STARTUPINFO_PRESENT = 0x00080000 +INHERIT_PARENT_AFFINITY = 0x00010000 + +# }}} + +# process priority constants {{{ + +ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000 +BELOW_NORMAL_PRIORITY_CLASS = 0x00004000 +HIGH_PRIORITY_CLASS = 0x00000080 +IDLE_PRIORITY_CLASS = 0x00000040 +NORMAL_PRIORITY_CLASS = 0x00000020 +REALTIME_PRIORITY_CLASS = 0x00000100 + +# }}} + +# startup info constants {{{ + +STARTF_FORCEONFEEDBACK = 0x00000040 +STARTF_FORCEOFFFEEDBACK = 0x00000080 +STARTF_PREVENTPINNING = 0x00002000 +STARTF_RUNFULLSCREEN = 0x00000020 +STARTF_TITLEISAPPID = 0x00001000 +STARTF_TITLEISLINKNAME = 0x00000800 +STARTF_USECOUNTCHARS = 0x00000008 +STARTF_USEFILLATTRIBUTE = 0x00000010 +STARTF_USEHOTKEY = 0x00000200 +STARTF_USEPOSITION = 0x00000004 +STARTF_USESHOWWINDOW = 0x00000001 +STARTF_USESIZE = 0x00000002 +STARTF_USESTDHANDLES = 0x00000100 + +# }}} + +# show window constants {{{ + +SW_FORCEMINIMIZE = 11 +SW_HIDE = 0 +SW_MAXIMIZE = 3 +SW_MINIMIZE = 6 +SW_RESTORE = 9 +SW_SHOW = 5 +SW_SHOWDEFAULT = 10 +SW_SHOWMAXIMIZED = 3 +SW_SHOWMINIMIZED = 2 +SW_SHOWMINNOACTIVE = 7 +SW_SHOWNA = 8 +SW_SHOWNOACTIVATE = 4 +SW_SHOWNORMAL = 1 + +# }}} + +# input event types {{{ + +FOCUS_EVENT = 0x0010 +KEY_EVENT = 0x0001 +MENU_EVENT = 0x0008 +MOUSE_EVENT = 0x0002 +WINDOW_BUFFER_SIZE_EVENT = 0x0004 + +# }}} + +# key event modifiers {{{ + +CAPSLOCK_ON = 0x0080 +ENHANCED_KEY = 0x0100 +LEFT_ALT_PRESSED = 0x0002 +LEFT_CTRL_PRESSED = 0x0008 +NUMLOCK_ON = 0x0020 +RIGHT_ALT_PRESSED = 0x0001 +RIGHT_CTRL_PRESSED = 0x0004 +SCROLLLOCK_ON = 0x0040 +SHIFT_PRESSED = 0x0010 + +# }}} + +# process access {{{ + +PROCESS_CREATE_PROCESS = 0x0080 +PROCESS_CREATE_THREAD = 0x0002 +PROCESS_DUP_HANDLE = 0x0040 +PROCESS_QUERY_INFORMATION = 0x0400 +PROCESS_QUERY_LIMITED_INFORMATION = 0x1000 +PROCESS_SET_INFORMATION = 0x0200 +PROCESS_SET_QUOTA = 0x0100 +PROCESS_SUSPEND_RESUME = 0x0800 +PROCESS_TERMINATE = 0x0001 +PROCESS_VM_OPERATION = 0x0008 +PROCESS_VM_READ = 0x0010 +PROCESS_VM_WRITE = 0x0020 + +# }}} + +# input / output handles {{{ + +STD_INPUT_HANDLE = c_ulong(-10) +STD_OUTPUT_HANDLE = c_ulong(-11) +STD_ERROR_HANDLE = c_ulong(-12) + +# }}} + +CONQUE_WINDOWS_VK = { # {{{ + 'VK_LBUTTON': 0x0001, + 'VK_RBUTTON': 0x0002, + 'VK_CANCEL': 0x0003, + 'VK_BACK': 0x0008, + 'VK_TAB': 0x0009, + 'VK_CLEAR': 0x000C, + 'VK_RETURN': 0x0D, + 'VK_SHIFT': 0x10, + 'VK_CONTROL': 0x11, + 'VK_MENU': 0x12, + 'VK_PAUSE': 0x0013, + 'VK_CAPITAL': 0x0014, + 'VK_ESCAPE': 0x001B, + 'VK_SPACE': 0x0020, + 'VK_PRIOR': 0x0021, + 'VK_NEXT': 0x0022, + 'VK_END': 0x0023, + 'VK_HOME': 0x0024, + 'VK_LEFT': 0x0025, + 'VK_UP': 0x0026, + 'VK_RIGHT': 0x0027, + 'VK_DOWN': 0x0028, + 'VK_SELECT': 0x0029, + 'VK_PRINT': 0x002A, + 'VK_EXECUTE': 0x002B, + 'VK_SNAPSHOT': 0x002C, + 'VK_INSERT': 0x002D, + 'VK_DELETE': 0x002E, + 'VK_HELP': 0x002F, + 'VK_0': 0x0030, + 'VK_1': 0x0031, + 'VK_2': 0x0032, + 'VK_3': 0x0033, + 'VK_4': 0x0034, + 'VK_5': 0x0035, + 'VK_6': 0x0036, + 'VK_7': 0x0037, + 'VK_8': 0x0038, + 'VK_9': 0x0039, + 'VK_A': 0x0041, + 'VK_B': 0x0042, + 'VK_C': 0x0043, + 'VK_D': 0x0044, + 'VK_E': 0x0045, + 'VK_F': 0x0046, + 'VK_G': 0x0047, + 'VK_H': 0x0048, + 'VK_I': 0x0049, + 'VK_J': 0x004A, + 'VK_K': 0x004B, + 'VK_L': 0x004C, + 'VK_M': 0x004D, + 'VK_N': 0x004E, + 'VK_O': 0x004F, + 'VK_P': 0x0050, + 'VK_Q': 0x0051, + 'VK_R': 0x0052, + 'VK_S': 0x0053, + 'VK_T': 0x0054, + 'VK_U': 0x0055, + 'VK_V': 0x0056, + 'VK_W': 0x0057, + 'VK_X': 0x0058, + 'VK_Y': 0x0059, + 'VK_Z': 0x005A, + 'VK_LWIN': 0x005B, + 'VK_RWIN': 0x005C, + 'VK_APPS': 0x005D, + 'VK_SLEEP': 0x005F, + 'VK_NUMPAD0': 0x0060, + 'VK_NUMPAD1': 0x0061, + 'VK_NUMPAD2': 0x0062, + 'VK_NUMPAD3': 0x0063, + 'VK_NUMPAD4': 0x0064, + 'VK_NUMPAD5': 0x0065, + 'VK_NUMPAD6': 0x0066, + 'VK_NUMPAD7': 0x0067, + 'VK_NUMPAD8': 0x0068, + 'VK_MULTIPLY': 0x006A, + 'VK_ADD': 0x006B, + 'VK_SEPARATOR': 0x006C, + 'VK_SUBTRACT': 0x006D, + 'VK_DECIMAL': 0x006E, + 'VK_DIVIDE': 0x006F, + 'VK_F1': 0x0070, + 'VK_F2': 0x0071, + 'VK_F3': 0x0072, + 'VK_F4': 0x0073, + 'VK_F5': 0x0074, + 'VK_F6': 0x0075, + 'VK_F7': 0x0076, + 'VK_F8': 0x0077, + 'VK_F9': 0x0078, + 'VK_F10': 0x0079, + 'VK_F11': 0x007A, + 'VK_F12': 0x007B, + 'VK_F13': 0x007C, + 'VK_F14': 0x007D, + 'VK_F15': 0x007E, + 'VK_F16': 0x007F, + 'VK_F17': 0x0080, + 'VK_F18': 0x0081, + 'VK_F19': 0x0082, + 'VK_F20': 0x0083, + 'VK_F21': 0x0084, + 'VK_F22': 0x0085, + 'VK_F23': 0x0086, + 'VK_F24': 0x0087, + 'VK_NUMLOCK': 0x0090, + 'VK_SCROLL': 0x0091, + 'VK_LSHIFT': 0x00A0, + 'VK_RSHIFT': 0x00A1, + 'VK_LCONTROL': 0x00A2, + 'VK_RCONTROL': 0x00A3, + 'VK_LMENU': 0x00A4, + 'VK_RMENU': 0x00A5 +} + +CONQUE_WINDOWS_VK_INV = dict([v, k] for k, v in CONQUE_WINDOWS_VK.items()) + +CONQUE_WINDOWS_VK_ENHANCED = { + str(int(CONQUE_WINDOWS_VK['VK_UP'])): 1, + str(int(CONQUE_WINDOWS_VK['VK_DOWN'])): 1, + str(int(CONQUE_WINDOWS_VK['VK_LEFT'])): 1, + str(int(CONQUE_WINDOWS_VK['VK_RIGHT'])): 1, + str(int(CONQUE_WINDOWS_VK['VK_HOME'])): 1, + str(int(CONQUE_WINDOWS_VK['VK_END'])): 1 +} + +# }}} + +# structures used for CreateProcess + +# Odd types {{{ + +LPBYTE = POINTER(c_ubyte) +LPTSTR = POINTER(c_char) + +# }}} + + +class STARTUPINFO(Structure): # {{{ + _fields_ = [("cb", c_ulong), + ("lpReserved", LPTSTR), + ("lpDesktop", LPTSTR), + ("lpTitle", LPTSTR), + ("dwX", c_ulong), + ("dwY", c_ulong), + ("dwXSize", c_ulong), + ("dwYSize", c_ulong), + ("dwXCountChars", c_ulong), + ("dwYCountChars", c_ulong), + ("dwFillAttribute", c_ulong), + ("dwFlags", c_ulong), + ("wShowWindow", c_short), + ("cbReserved2", c_short), + ("lpReserved2", LPBYTE), + ("hStdInput", c_void_p), + ("hStdOutput", c_void_p), + ("hStdError", c_void_p),] + + def to_str(self): + return '' + + # }}} + +class PROCESS_INFORMATION(Structure): # {{{ + _fields_ = [("hProcess", c_void_p), + ("hThread", c_void_p), + ("dwProcessId", c_ulong), + ("dwThreadId", c_ulong),] + + def to_str(self): + return '' + + # }}} + +class MEMORY_BASIC_INFORMATION(Structure): # {{{ + _fields_ = [("BaseAddress", c_void_p), + ("AllocationBase", c_void_p), + ("AllocationProtect", c_ulong), + ("RegionSize", c_ulong), + ("State", c_ulong), + ("Protect", c_ulong), + ("Type", c_ulong),] + + def to_str(self): + return '' + + # }}} + +class SECURITY_ATTRIBUTES(Structure): # {{{ + _fields_ = [("Length", c_ulong), + ("SecDescriptor", c_void_p), + ("InheritHandle", c_bool)] + + def to_str(self): + return '' + + # }}} + +class COORD(Structure): # {{{ + _fields_ = [("X", c_short), + ("Y", c_short)] + + def to_str(self): + return '' + + # }}} + +class SMALL_RECT(Structure): # {{{ + _fields_ = [("Left", c_short), + ("Top", c_short), + ("Right", c_short), + ("Bottom", c_short)] + + def to_str(self): + return '' + + # }}} + +class CONSOLE_SCREEN_BUFFER_INFO(Structure): # {{{ + _fields_ = [("dwSize", COORD), + ("dwCursorPosition", COORD), + ("wAttributes", c_short), + ("srWindow", SMALL_RECT), + ("dwMaximumWindowSize", COORD)] + + def to_str(self): + return '' + + # }}} + +class CHAR_UNION(Union): # {{{ + _fields_ = [("UnicodeChar", c_wchar), + ("AsciiChar", c_char)] + + def to_str(self): + return '' + + # }}} + +class CHAR_INFO(Structure): # {{{ + _fields_ = [("Char", CHAR_UNION), + ("Attributes", c_short)] + + def to_str(self): + return '' + + # }}} + +class KEY_EVENT_RECORD(Structure): # {{{ + _fields_ = [("bKeyDown", c_byte), + ("pad2", c_byte), + ('pad1', c_short), + ("wRepeatCount", c_short), + ("wVirtualKeyCode", c_short), + ("wVirtualScanCode", c_short), + ("uChar", CHAR_UNION), + ("dwControlKeyState", c_int)] + + def to_str(self): + return '' + + # }}} + +class MOUSE_EVENT_RECORD(Structure): # {{{ + _fields_ = [("dwMousePosition", COORD), + ("dwButtonState", c_int), + ("dwControlKeyState", c_int), + ("dwEventFlags", c_int)] + + def to_str(self): + return '' + + # }}} + +class WINDOW_BUFFER_SIZE_RECORD(Structure): # {{{ + _fields_ = [("dwSize", COORD)] + + def to_str(self): + return '' + + # }}} + +class MENU_EVENT_RECORD(Structure): # {{{ + _fields_ = [("dwCommandId", c_uint)] + + def to_str(self): + return '' + + # }}} + +class FOCUS_EVENT_RECORD(Structure): # {{{ + _fields_ = [("bSetFocus", c_byte)] + + def to_str(self): + return '' + # }}} + +class INPUT_UNION(Union): # {{{ + _fields_ = [("KeyEvent", KEY_EVENT_RECORD), + ("MouseEvent", MOUSE_EVENT_RECORD), + ("WindowBufferSizeEvent", WINDOW_BUFFER_SIZE_RECORD), + ("MenuEvent", MENU_EVENT_RECORD), + ("FocusEvent", FOCUS_EVENT_RECORD)] + + def to_str(self): + return '' + # }}} + +class INPUT_RECORD(Structure): # {{{ + _fields_ = [("EventType", c_short), + ("Event", INPUT_UNION)] + + def to_str(self): + return '' + # }}} + +# vim:foldmethod=marker diff --git a/.vim/bundle/ack.vim/README.md b/.vim/bundle/ack.vim/README.md index 7e0c85d..96de95e 100644 --- a/.vim/bundle/ack.vim/README.md +++ b/.vim/bundle/ack.vim/README.md @@ -12,7 +12,7 @@ The *Official Version* of this plugin is available at [vim.org](http://www.vim.o ### Ack -You have to install [ack](http://search.cpan.org/~petdance/ack/ack), of course. +You have to install [ack](http://betterthangrep.com/), of course. Install on Debian / Ubuntu with: @@ -26,6 +26,9 @@ Install on Gentoo with: sudo emerge ack +Install with Homebrew: + brew install ack + Install with MacPorts: sudo port install p5-app-ack @@ -59,7 +62,7 @@ in this window will open the file, and place the cursor on the matching line. Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use `:Ack`, `:AckAdd`, `:LAck`, and `:LAckAdd` respectively. (See `doc/ack.txt`, or install and `:h Ack` for more information.) -**From the [ack docs](http://search.cpan.org/~petdance/ack/ack)** (my favorite feature): +**From the [ack docs](http://betterthangrep.com/)** (my favorite feature): --type=TYPE, --type=noTYPE @@ -71,10 +74,20 @@ Just like where you use :grep, :grepadd, :lgrep, and :lgrepadd, you can use `:Ac See ack --help=types for a list of valid types. +### Keyboard Shortcuts ### + +In the quickfix window, you can use: + + o to open (same as enter) + go to preview file (open but maintain focus on ack.vim results) + t to open in new tab + T to open in new tab silently + q to close the quickfix window + This Vim plugin is derived (and by derived, I mean copied, essentially) from Antoine Imbert's blog post [Ack and Vim -Integration](http://blog.ant0ine.com/2007/03/ack_and_vim_integration.html) (in +Integration](http://blog.ant0ine.com/typepad/2007/03/ack-and-vim-integration.html) (in particular, the function at the bottom of the post). I added a help file that provides just enough reference to get you going. I also highly recommend you check out the docs for the Perl script 'ack', for obvious reasons: [ack - -grep-like text finder](http://search.cpan.org/~petdance/ack/ack). +grep-like text finder](http://betterthangrep.com/). diff --git a/.vim/bundle/ack.vim/doc/ack.txt b/.vim/bundle/ack.vim/doc/ack.txt index a97798b..bbe4299 100644 --- a/.vim/bundle/ack.vim/doc/ack.txt +++ b/.vim/bundle/ack.vim/doc/ack.txt @@ -11,11 +11,12 @@ This plugin is a front for the Perl module App::Ack. Ack can be used as a replacement for grep. This plugin will allow you to run ack from vim, and shows the results in a split window. -:Ack [options] {pattern} [{directory}] *:Ack* +:Ack[!] [options] {pattern} [{directory}] *:Ack* Search recursively in {directory} (which defaults to the current directory) for the {pattern}. Behaves just like the |:grep| command, but - will open the |Quickfix| window for you. + will open the |Quickfix| window for you. If [!] is not given the first + error is jumped to. :AckAdd [options] {pattern} [{directory}] *:AckAdd* @@ -47,4 +48,4 @@ with the line number of the occurrence, once for each occurrence. on a line in this window will open the file, and place the cursor on the matching line. -See http://search.cpan.org/~petdance/ack/ack for more information. +See http://betterthangrep.com/ for more information. diff --git a/.vim/bundle/ack.vim/plugin/ack.vim b/.vim/bundle/ack.vim/plugin/ack.vim index ca7c224..9367c74 100644 --- a/.vim/bundle/ack.vim/plugin/ack.vim +++ b/.vim/bundle/ack.vim/plugin/ack.vim @@ -17,6 +17,13 @@ function! s:Ack(cmd, args) redraw echo "Searching ..." + " If no pattern is provided, search for the word under the cursor + if empty(a:args) + let l:grepargs = expand("") + else + let l:grepargs = a:args + end + " Format, used to manage column jump if a:cmd =~# '-g$' let g:ackformat="%f" @@ -29,7 +36,7 @@ function! s:Ack(cmd, args) try let &grepprg=g:ackprg let &grepformat=g:ackformat - silent execute a:cmd . " " . a:args + silent execute a:cmd . " " . l:grepargs finally let &grepprg=grepprg_bak let &grepformat=grepformat_bak @@ -41,7 +48,18 @@ function! s:Ack(cmd, args) botright copen endif - exec "nnoremap q :ccl" + " TODO: Document this! + exec "nnoremap q :ccl" + exec "nnoremap t T" + exec "nnoremap T TgT" + exec "nnoremap o " + exec "nnoremap go " + + " If highlighting is on, highlight the search keyword. + if exists("g:ackhighlight") + let @/=a:args + set hlsearch + end redraw! endfunction diff --git a/.vim/bundle/command-t/ruby/command-t/Makefile b/.vim/bundle/command-t/ruby/command-t/Makefile new file mode 100644 index 0000000..381b163 --- /dev/null +++ b/.vim/bundle/command-t/ruby/command-t/Makefile @@ -0,0 +1,181 @@ + +SHELL = /bin/sh + +#### Start of system configuration section. #### + +srcdir = . +topdir = /usr/lib/ruby/1.8/x86_64-linux +hdrdir = $(topdir) +VPATH = $(srcdir):$(topdir):$(hdrdir) +exec_prefix = $(prefix) +prefix = $(DESTDIR)/usr +sharedstatedir = $(prefix)/com +mandir = $(prefix)/share/man +psdir = $(docdir) +oldincludedir = $(DESTDIR)/usr/include +localedir = $(datarootdir)/locale +bindir = $(exec_prefix)/bin +libexecdir = $(prefix)/lib/ruby1.8 +sitedir = $(DESTDIR)/usr/local/lib/site_ruby +htmldir = $(docdir) +vendorarchdir = $(vendorlibdir)/$(sitearch) +includedir = $(prefix)/include +infodir = $(prefix)/share/info +vendorlibdir = $(vendordir)/$(ruby_version) +sysconfdir = $(DESTDIR)/etc +libdir = $(exec_prefix)/lib +sbindir = $(exec_prefix)/sbin +rubylibdir = $(libdir)/ruby/$(ruby_version) +docdir = $(datarootdir)/doc/$(PACKAGE) +dvidir = $(docdir) +vendordir = $(libdir)/ruby/vendor_ruby +datarootdir = $(prefix)/share +pdfdir = $(docdir) +archdir = $(rubylibdir)/$(arch) +sitearchdir = $(sitelibdir)/$(sitearch) +datadir = $(datarootdir) +localstatedir = $(DESTDIR)/var +sitelibdir = $(sitedir)/$(ruby_version) + +CC = gcc +LIBRUBY = $(LIBRUBY_SO) +LIBRUBY_A = lib$(RUBY_SO_NAME)-static.a +LIBRUBYARG_SHARED = -l$(RUBY_SO_NAME) +LIBRUBYARG_STATIC = -l$(RUBY_SO_NAME)-static + +RUBY_EXTCONF_H = +CFLAGS = -fPIC -fno-strict-aliasing -g -g -O2 -fPIC $(cflags) +INCFLAGS = -I. -I$(topdir) -I$(hdrdir) -I$(srcdir) +DEFS = +CPPFLAGS = -DHAVE_RUBY_H $(DEFS) $(cppflags) +CXXFLAGS = $(CFLAGS) +ldflags = -L. -Wl,-Bsymbolic-functions -rdynamic -Wl,-export-dynamic +dldflags = +archflag = +DLDFLAGS = $(ldflags) $(dldflags) $(archflag) +LDSHARED = $(CC) -shared +AR = ar +EXEEXT = + +RUBY_INSTALL_NAME = ruby1.8 +RUBY_SO_NAME = ruby1.8 +arch = x86_64-linux +sitearch = x86_64-linux +ruby_version = 1.8 +ruby = /usr/bin/ruby1.8 +RUBY = $(ruby) +RM = rm -f +MAKEDIRS = mkdir -p +INSTALL = /usr/bin/install -c +INSTALL_PROG = $(INSTALL) -m 0755 +INSTALL_DATA = $(INSTALL) -m 644 +COPY = cp + +#### End of system configuration section. #### + +preload = + +libpath = . $(libdir) +LIBPATH = -L. -L$(libdir) +DEFFILE = + +CLEANFILES = mkmf.log +DISTCLEANFILES = + +extout = +extout_prefix = +target_prefix = +LOCAL_LIBS = +LIBS = $(LIBRUBYARG_SHARED) -lpthread -lrt -ldl -lcrypt -lm -lc +SRCS = ext.c match.c matcher.c +OBJS = ext.o match.o matcher.o +TARGET = ext +DLLIB = $(TARGET).so +EXTSTATIC = +STATIC_LIB = + +BINDIR = $(bindir) +RUBYCOMMONDIR = $(sitedir)$(target_prefix) +RUBYLIBDIR = $(sitelibdir)$(target_prefix) +RUBYARCHDIR = $(sitearchdir)$(target_prefix) + +TARGET_SO = $(DLLIB) +CLEANLIBS = $(TARGET).so $(TARGET).il? $(TARGET).tds $(TARGET).map +CLEANOBJS = *.o *.a *.s[ol] *.pdb *.exp *.bak + +all: $(DLLIB) +static: $(STATIC_LIB) + +clean: + @-$(RM) $(CLEANLIBS) $(CLEANOBJS) $(CLEANFILES) + +distclean: clean + @-$(RM) Makefile $(RUBY_EXTCONF_H) conftest.* mkmf.log + @-$(RM) core ruby$(EXEEXT) *~ $(DISTCLEANFILES) + +realclean: distclean +install: install-so install-rb + +install-so: $(RUBYARCHDIR) +install-so: $(RUBYARCHDIR)/$(DLLIB) +$(RUBYARCHDIR)/$(DLLIB): $(DLLIB) + $(INSTALL_PROG) $(DLLIB) $(RUBYARCHDIR) +install-rb: pre-install-rb install-rb-default +install-rb-default: pre-install-rb-default +pre-install-rb: Makefile +pre-install-rb-default: Makefile +$(RUBYARCHDIR): + $(MAKEDIRS) $@ + +site-install: site-install-so site-install-rb +site-install-so: install-so +site-install-rb: install-rb + +.SUFFIXES: .c .m .cc .cxx .cpp .C .o + +.cc.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cxx.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.cpp.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.C.o: + $(CXX) $(INCFLAGS) $(CPPFLAGS) $(CXXFLAGS) -c $< + +.c.o: + $(CC) $(INCFLAGS) $(CPPFLAGS) $(CFLAGS) -c $< + +$(DLLIB): $(OBJS) Makefile + @-$(RM) $@ + $(LDSHARED) -o $@ $(OBJS) $(LIBPATH) $(DLDFLAGS) $(LOCAL_LIBS) $(LIBS) + + + +### +# Copyright 2010 Wincent Colaiuta. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# 2. Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE +# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +# POSSIBILITY OF SUCH DAMAGE. + +CFLAGS += -std=c99 -Wall -Wextra -Wno-unused-parameter diff --git a/.vim/bundle/command-t/ruby/command-t/mkmf.log b/.vim/bundle/command-t/ruby/command-t/mkmf.log new file mode 100644 index 0000000..bf90815 --- /dev/null +++ b/.vim/bundle/command-t/ruby/command-t/mkmf.log @@ -0,0 +1,10 @@ +have_header: checking for ruby.h... -------------------- yes + +"gcc -E -I. -I/usr/lib/ruby/1.8/x86_64-linux -I. -fno-strict-aliasing -g -g -O2 -fPIC conftest.c -o conftest.i" +checked program was: +/* begin */ +1: #include +/* end */ + +-------------------- + diff --git a/.vim/bundle/nerdcommenter/doc/NERD_commenter.txt b/.vim/bundle/nerdcommenter/doc/NERD_commenter.txt index d7493b1..e340bb5 100644 --- a/.vim/bundle/nerdcommenter/doc/NERD_commenter.txt +++ b/.vim/bundle/nerdcommenter/doc/NERD_commenter.txt @@ -404,6 +404,8 @@ then the script would do a sexy comment on the last visual selection. doing visual-block comments. |'NERDCommentWholeLinesInVMode'| Changes behaviour of visual comments. |'NERDCreateDefaultMappings'| Turn the default mappings on/off. +|'NERDCustomDelimiters'| Add or override delimiters for any + filetypes. |'NERDDefaultNesting'| Tells the script to use nested comments by default. |'NERDMenuMode'| Specifies how the NERD commenter menu @@ -550,7 +552,7 @@ Note that this option does not affect the behaviour of commenting in |visual-block| mode. ------------------------------------------------------------------------------ - *'NERDCreateDefaultMappings'* + *'NERDCreateDefaultMappings'* Values: 0 or 1. Default: 1. @@ -559,6 +561,25 @@ If set to 0, none of the default mappings will be created. See also |NERDComMappings|. ------------------------------------------------------------------------------ + *'NERDCustomDelimiters'* +Values: A map (format specified below). +Default: {} + +Use this option if you have new filetypes you want the script to handle, or if +you want to override the default delimiters of a filetype. + +Example: > + let g:NERDCustomDelimiters = { + \ 'ruby': { 'left': '#', 'leftAlt': 'FOO', 'rightAlt': 'BAR' }, + \ 'grondle': { 'left': '{{', 'right': '}}' } + \ } +< + +Here we override the delimiter settings for ruby and add FOO/BAR as alternative +delimiters. We also add {{ and }} as delimiters for a new filetype called +'grondle'. + +------------------------------------------------------------------------------ *'NERDRemoveAltComs'* Values: 0 or 1. Default: 1. @@ -576,7 +597,7 @@ It will not be uncommented if the NERDRemoveAltComs is set to 0. ------------------------------------------------------------------------------ *'NERDRemoveExtraSpaces'* Values: 0 or 1. -Default: 1. +Default: 0. By default, the NERD commenter will remove spaces around comment delimiters if either: @@ -599,8 +620,6 @@ Otherwise they would become: > int bar = 10; int baz = foo + bar < -If you want the spaces to be removed only if |'NERDSpaceDelims'| is set then -set NERDRemoveExtraSpaces to 0. ------------------------------------------------------------------------------ *'NERDLPlace'* @@ -633,7 +652,7 @@ Default: 3 This option can take 4 values: "0": Turns the menu off. "1": Turns the 'comment' menu on with no menu shortcut. - "2": Turns the 'comment 'menu on with -c as the shortcut. + "2": Turns the 'comment' menu on with -c as the shortcut. "3": Turns the 'Plugin -> comment' menu on with -c as the shortcut. ------------------------------------------------------------------------------ @@ -781,6 +800,15 @@ The latest dev versions are on github ============================================================================== 8. Changelog *NERDComChangelog* +2.3.0 + - remove all filetypes which have a &commentstring in the standard vim + runtime for vim > 7.0 unless the script stores an alternate set of + delimiters + - make the script complain if the user doesnt have filetype plugins enabled + - use instead of comma to start the default mappings + - fix a couple of bugs with sexy comments - thanks to Tim Smart + - lots of refactoring + 2.2.2 - remove the NERDShutup option and the message is suppresses, this makes the plugin silently rely on &commentstring for unknown filetypes. diff --git a/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim b/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim index 982b140..4102e38 100644 --- a/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim +++ b/.vim/bundle/nerdcommenter/plugin/NERD_commenter.vim @@ -1,9 +1,9 @@ " ============================================================================ " File: NERD_commenter.vim " Description: vim global plugin that provides easy code commenting -" Maintainer: Martin Grenfell -" Version: 2.2.2 -" Last Change: 09th October, 2010 +" Maintainer: Martin Grenfell +" Version: 2.3.0 +" Last Change: 08th December, 2010 " License: This program is free software. It comes without any warranty, " to the extent permitted by applicable law. You can redistribute " it and/or modify it under the terms of the Do What The Fuck You @@ -47,7 +47,7 @@ endfunction let s:spaceStr = ' ' let s:lenSpaceStr = strlen(s:spaceStr) -" Section: variable init calls {{{2 +" Section: variable initialization {{{2 call s:InitVariable("g:NERDAllowAnyVisualDelims", 1) call s:InitVariable("g:NERDBlockComIgnoreEmpty", 0) call s:InitVariable("g:NERDCommentWholeLinesInVMode", 0) @@ -58,13 +58,15 @@ call s:InitVariable("g:NERDMenuMode", 3) call s:InitVariable("g:NERDLPlace", "[>") call s:InitVariable("g:NERDUsePlaceHolders", 1) call s:InitVariable("g:NERDRemoveAltComs", 1) -call s:InitVariable("g:NERDRemoveExtraSpaces", 1) +call s:InitVariable("g:NERDRemoveExtraSpaces", 0) call s:InitVariable("g:NERDRPlace", "<]") call s:InitVariable("g:NERDSpaceDelims", 0) -call s:InitVariable("g:NERDDelimiterRequests", 1) + +if !exists("g:NERDCustomDelimiters") + let g:NERDCustomDelimiters = {} +endif let s:NERDFileNameEscape="[]#*$%'\" ?`!&();<>\\" -"vf ;;dA:hcs"'A {j^f(lyi(k$p0f{a A }0f{a 'left':jdd^ let s:delimiterMap = { \ 'aap': { 'left': '#' }, @@ -144,7 +146,7 @@ let s:delimiterMap = { \ 'eiffel': { 'left': '--' }, \ 'elf': { 'left': "'" }, \ 'elmfilt': { 'left': '#' }, - \ 'erlang': { 'left': '%' }, + \ 'erlang': { 'left': '%', 'leftAlt': '%%' }, \ 'eruby': { 'left': '<%#', 'right': '%>', 'leftAlt': '' }, \ 'expect': { 'left': '#' }, \ 'exports': { 'left': '#' }, @@ -173,7 +175,7 @@ let s:delimiterMap = { \ 'gitrebase': { 'left': '#' }, \ 'gnuplot': { 'left': '#' }, \ 'groovy': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, - \ 'gsp': { 'left': '<%--', 'right': '--%>' }, + \ 'gsp': { 'left': '<%--', 'right': '--%>', 'leftAlt': ''}, \ 'gtkrc': { 'left': '#' }, \ 'haskell': { 'left': '{-','right': '-}', 'leftAlt': '--' }, \ 'hb': { 'left': '#' }, @@ -206,9 +208,10 @@ let s:delimiterMap = { \ 'kscript': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, \ 'lace': { 'left': '--' }, \ 'ldif': { 'left': '#' }, + \ 'less': { 'left': '/*','right': '*/' }, \ 'lilo': { 'left': '#' }, \ 'lilypond': { 'left': '%' }, - \ 'liquid': { 'left': '{%', 'right': '%}' }, + \ 'liquid': { 'left': '{% comment %}', 'right': '{% endcomment %}' }, \ 'lisp': { 'left': ';', 'leftAlt': '#|', 'rightAlt': '|#' }, \ 'llvm': { 'left': ';' }, \ 'lotos': { 'left': '(*', 'right': '*)' }, @@ -255,6 +258,7 @@ let s:delimiterMap = { \ 'occam': { 'left': '--' }, \ 'omlet': { 'left': '(*', 'right': '*)' }, \ 'omnimark': { 'left': ';' }, + \ 'ooc': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, \ 'openroad': { 'left': '//' }, \ 'opl': { 'left': "REM" }, \ 'ora': { 'left': '#' }, @@ -300,8 +304,10 @@ let s:delimiterMap = { \ 'sass': { 'left': '//', 'leftAlt': '/*' }, \ 'sather': { 'left': '--' }, \ 'scala': { 'left': '//', 'leftAlt': '/*', 'rightAlt': '*/' }, + \ 'scheme': { 'left': ';', 'leftAlt': '#|', 'rightAlt': '|#' }, \ 'scilab': { 'left': '//' }, \ 'scsh': { 'left': ';' }, + \ 'scss': { 'left': '/*','right': '*/' }, \ 'sed': { 'left': '#' }, \ 'sgmldecl': { 'left': '--', 'right': '--' }, \ 'sgmllnx': { 'left': '' }, @@ -376,12 +382,17 @@ let s:delimiterMap = { \ 'z8a': { 'left': ';' } \ } +"merge in the custom delimiters +for ft in keys(g:NERDCustomDelimiters) + let s:delimiterMap[ft] = g:NERDCustomDelimiters[ft] +endfor + " Section: Comment mapping functions, autocommands and commands {{{1 " ============================================================================ " Section: Comment enabler autocommands {{{2 " ============================================================================ -augroup commentEnablers +augroup NERDCommenter "if the user enters a buffer or reads a buffer then we gotta set up "the comment delimiters for that new filetype @@ -403,10 +414,24 @@ augroup END " set for this buffer. " function s:SetUpForNewFiletype(filetype, forceReset) + let ft = a:filetype + + "for compound filetypes, if we dont know how to handle the full filetype + "then break it down and use the first part that we know how to handle + if ft =~ '\.' && !has_key(s:delimiterMap, ft) + let filetypes = split(a:filetype, '\.') + for i in filetypes + if has_key(s:delimiterMap, i) + let ft = i + break + endif + endfor + endif + let b:NERDSexyComMarker = '' - if has_key(s:delimiterMap, a:filetype) - let b:NERDCommenterDelims = s:delimiterMap[a:filetype] + if has_key(s:delimiterMap, ft) + let b:NERDCommenterDelims = s:delimiterMap[ft] for i in ['left', 'leftAlt', 'right', 'rightAlt'] if !has_key(b:NERDCommenterDelims, i) let b:NERDCommenterDelims[i] = '' @@ -1001,6 +1026,10 @@ function! NERDComment(isVisual, type) range let oldIgnoreCase = &ignorecase set noignorecase + if !exists("g:did_load_ftplugin") || g:did_load_ftplugin != 1 + call s:NerdEcho("filetype plugins should be enabled. See :help NERDComInstallation and :help :filetype-plugin-on", 0) + endif + if a:isVisual let firstLine = line("'<") let lastLine = line("'>") @@ -2400,10 +2429,10 @@ endfunction function s:NerdEcho(msg, typeOfMsg) if a:typeOfMsg == 0 echohl WarningMsg - echo 'NERDCommenter:' . a:msg + echom 'NERDCommenter:' . a:msg echohl None elseif a:typeOfMsg == 1 - echo 'NERDCommenter:' . a:msg + echom 'NERDCommenter:' . a:msg endif endfunction diff --git a/.vim/bundle/nerdtree/doc/NERD_tree.txt b/.vim/bundle/nerdtree/doc/NERD_tree.txt index 2e2278c..cc5796a 100644 --- a/.vim/bundle/nerdtree/doc/NERD_tree.txt +++ b/.vim/bundle/nerdtree/doc/NERD_tree.txt @@ -642,6 +642,12 @@ NERD tree. These options should be set in your vimrc. |'NERDTreeWinSize'| Sets the window size when the NERD tree is opened. +|'NERDTreeMinimalUI'| Disables display of the 'Bookmarks' label and + 'Press ? for help' text. + +|'NERDTreeDirArrows'| Tells the NERD tree to use arrows instead of + + ~ chars when displaying directories. + ------------------------------------------------------------------------------ 3.2. Customisation details *NERDTreeOptionDetails* @@ -921,6 +927,30 @@ Default: 31. This option is used to change the size of the NERD tree when it is loaded. +------------------------------------------------------------------------------ + *'NERDTreeMinimalUI'* +Values: 0 or 1 +Default: 0 + +This options disables the 'Bookmarks' label 'Press ? for help' text. Use one +of the following lines to set this option: > + let NERDTreeMinimalUI=0 + let NERDTreeMinimalUI=1 +< + +------------------------------------------------------------------------------ + *'NERDTreeDirArrows'* +Values: 0 or 1 +Default: 0. + +This option is used to change the default look of directory nodes displayed in +the tree. When set to 0 it shows old-school bars (|), + and ~ chars. If set to +1 it shows right and down arrows. Use one of the follow lines to set this +option: > + let NERDTreeDirArrows=0 + let NERDTreeDirArrows=1 +< + ============================================================================== 4. The NERD tree API *NERDTreeAPI* @@ -1080,6 +1110,9 @@ The latest dev versions are on github ============================================================================== 6. Changelog *NERDTreeChangelog* +4.x.x + - Fix a bug with :NERDTreeFind and symlinks. Thanks to Vitaly Bogdanov. + 4.1.0 features: - NERDTreeFind to reveal the node for the current buffer in the tree, @@ -1214,6 +1247,7 @@ just downloaded pr0n instead. Ricky jfilip1024 Chris Chambers + Vitaly Bogdanov ============================================================================== 8. License *NERDTreeLicense* diff --git a/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim b/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim index e25b38c..953b961 100644 --- a/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim +++ b/.vim/bundle/nerdtree/nerdtree_plugin/fs_menu.vim @@ -16,8 +16,8 @@ endif let g:loaded_nerdtree_fs_menu = 1 call NERDTreeAddMenuItem({'text': '(a)dd a childnode', 'shortcut': 'a', 'callback': 'NERDTreeAddNode'}) -call NERDTreeAddMenuItem({'text': '(m)ove the curent node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) -call NERDTreeAddMenuItem({'text': '(d)elete the curent node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) +call NERDTreeAddMenuItem({'text': '(m)ove the current node', 'shortcut': 'm', 'callback': 'NERDTreeMoveNode'}) +call NERDTreeAddMenuItem({'text': '(d)elete the current node', 'shortcut': 'd', 'callback': 'NERDTreeDeleteNode'}) if g:NERDTreePath.CopyingSupported() call NERDTreeAddMenuItem({'text': '(c)copy the current node', 'shortcut': 'c', 'callback': 'NERDTreeCopyNode'}) endif diff --git a/.vim/bundle/nerdtree/plugin/NERD_tree.vim b/.vim/bundle/nerdtree/plugin/NERD_tree.vim index c5a014c..5612e81 100644 --- a/.vim/bundle/nerdtree/plugin/NERD_tree.vim +++ b/.vim/bundle/nerdtree/plugin/NERD_tree.vim @@ -51,6 +51,7 @@ call s:initVariable("g:NERDTreeAutoCenter", 1) call s:initVariable("g:NERDTreeAutoCenterThreshold", 3) call s:initVariable("g:NERDTreeCaseSensitiveSort", 0) call s:initVariable("g:NERDTreeChDirMode", 0) +call s:initVariable("g:NERDTreeMinimalUI", 0) if !exists("g:NERDTreeIgnore") let g:NERDTreeIgnore = ['\~$'] endif @@ -65,6 +66,7 @@ call s:initVariable("g:NERDTreeShowFiles", 1) call s:initVariable("g:NERDTreeShowHidden", 0) call s:initVariable("g:NERDTreeShowLineNumbers", 0) call s:initVariable("g:NERDTreeSortDirs", 1) +call s:initVariable("g:NERDTreeDirArrows", 0) if !exists("g:NERDTreeSortOrder") let g:NERDTreeSortOrder = ['\/$', '*', '\.swp$', '\.bak$', '\~$'] @@ -142,12 +144,12 @@ call s:initVariable("g:NERDTreeMapUpdirKeepOpen", "U") if s:running_windows let s:escape_chars = " `\|\"#%&,?()\*^<>" else - let s:escape_chars = " \\`\|\"#%&,?()\*^<>" + let s:escape_chars = " \\`\|\"#%&,?()\*^<>[]" endif let s:NERDTreeBufName = 'NERD_tree_' let s:tree_wid = 2 -let s:tree_markup_reg = '^[ `|]*[\-+~]' +let s:tree_markup_reg = '^[ `|]*[\-+~▾▸ ]*' let s:tree_up_dir_line = '.. (up a dir)' "the number to add to the nerd tree buffer name to make the buf name unique @@ -373,7 +375,7 @@ endfunction " FUNCTION: Bookmark.New(name, path) {{{3 " Create a new bookmark object with the given name and path object function! s:Bookmark.New(name, path) - if a:name =~ ' ' + if a:name =~# ' ' throw "NERDTree.IllegalBookmarkNameError: illegal name:" . a:name endif @@ -390,7 +392,7 @@ function! s:Bookmark.openInNewTab(options) tabnew call s:initNerdTree(self.name) else - exec "tabedit " . bookmark.path.str({'format': 'Edit'}) + exec "tabedit " . self.path.str({'format': 'Edit'}) endif if has_key(a:options, 'stayInCurrentTab') @@ -1037,7 +1039,7 @@ endfunction "gets the line number of the root node function! s:TreeFileNode.GetRootLineNum() let rootLine = 1 - while getline(rootLine) !~ '^\(/\|<\)' + while getline(rootLine) !~# '^\(/\|<\)' let rootLine = rootLine + 1 endwhile return rootLine @@ -1313,33 +1315,50 @@ function! s:TreeFileNode._renderToString(depth, drawText, vertMap, isLastChild) "get all the leading spaces and vertical tree parts for this line if a:depth > 1 for j in a:vertMap[0:-2] - if j ==# 1 - let treeParts = treeParts . '| ' - else + if g:NERDTreeDirArrows let treeParts = treeParts . ' ' + else + if j ==# 1 + let treeParts = treeParts . '| ' + else + let treeParts = treeParts . ' ' + endif endif endfor endif "get the last vertical tree part for this line which will be different "if this node is the last child of its parent - if a:isLastChild - let treeParts = treeParts . '`' - else - let treeParts = treeParts . '|' + if !g:NERDTreeDirArrows + if a:isLastChild + let treeParts = treeParts . '`' + else + let treeParts = treeParts . '|' + endif endif - "smack the appropriate dir/file symbol on the line before the file/dir "name itself if self.path.isDirectory if self.isOpen - let treeParts = treeParts . '~' + if g:NERDTreeDirArrows + let treeParts = treeParts . '▾ ' + else + let treeParts = treeParts . '~' + endif else - let treeParts = treeParts . '+' + if g:NERDTreeDirArrows + let treeParts = treeParts . '▸ ' + else + let treeParts = treeParts . '+' + endif endif else - let treeParts = treeParts . '-' + if g:NERDTreeDirArrows + let treeParts = treeParts . ' ' + else + let treeParts = treeParts . '-' + endif endif let line = treeParts . self.displayString() @@ -1602,7 +1621,7 @@ function! s:TreeDirNode._initChildren(silent) "filter out the .. and . directories "Note: we must match .. AND ../ cos sometimes the globpath returns "../ for path with strange chars (eg $) - if i !~ '\/\.\.\/\?$' && i !~ '\/\.\/\?$' + if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' "put the next file in a new node and attach it try @@ -1739,7 +1758,7 @@ function! s:TreeDirNode.refresh() "filter out the .. and . directories "Note: we must match .. AND ../ cos sometimes the globpath returns "../ for path with strange chars (eg $) - if i !~ '\/\.\.\/\?$' && i !~ '\/\.\/\?$' + if i !~# '\/\.\.\/\?$' && i !~# '\/\.\/\?$' try "create a new path and see if it exists in this nodes children @@ -1861,9 +1880,9 @@ let s:Path = {} function! s:Path.AbsolutePathFor(str) let prependCWD = 0 if s:running_windows - let prependCWD = a:str !~ '^.:\(\\\|\/\)' + let prependCWD = a:str !~# '^.:\(\\\|\/\)' else - let prependCWD = a:str !~ '^/' + let prependCWD = a:str !~# '^/' endif let toReturn = a:str @@ -1980,7 +1999,7 @@ function! s:Path.Create(fullpath) try "if it ends with a slash, assume its a dir create it - if a:fullpath =~ '\(\\\|\/\)$' + if a:fullpath =~# '\(\\\|\/\)$' "whack the trailing slash off the end if it exists let fullpath = substitute(a:fullpath, '\(\\\|\/\)$', '', '') @@ -2153,7 +2172,7 @@ endfunction function! s:Path.getSortOrderIndex() let i = 0 while i < len(g:NERDTreeSortOrder) - if self.getLastPathComponent(1) =~ g:NERDTreeSortOrder[i] + if self.getLastPathComponent(1) =~# g:NERDTreeSortOrder[i] return i endif let i = i + 1 @@ -2169,14 +2188,14 @@ function! s:Path.ignore() "filter out the user specified paths to ignore if b:NERDTreeIgnoreEnabled for i in g:NERDTreeIgnore - if lastPathComponent =~ i + if lastPathComponent =~# i return 1 endif endfor endif "dont show hidden files unless instructed to - if b:NERDTreeShowHidden ==# 0 && lastPathComponent =~ '^\.' + if b:NERDTreeShowHidden ==# 0 && lastPathComponent =~# '^\.' return 1 endif @@ -2266,7 +2285,7 @@ function! s:Path.readInfoFromDisk(fullpath) let self.isExecutable = 0 if !self.isDirectory - let self.isExecutable = getfperm(a:fullpath) =~ 'x' + let self.isExecutable = getfperm(a:fullpath) =~# 'x' endif "grab the last part of the path (minus the trailing slash) @@ -2285,7 +2304,7 @@ function! s:Path.readInfoFromDisk(fullpath) "we always wanna treat MS windows shortcuts as files for "simplicity - if hardPath !~ '\.lnk$' + if hardPath !~# '\.lnk$' let self.symLinkDest = self.symLinkDest . '/' endif @@ -2517,7 +2536,7 @@ endfunction " FUNCTION: s:completeBookmarks(A,L,P) {{{2 " completion function for the bookmark commands function! s:completeBookmarks(A,L,P) - return filter(s:Bookmark.BookmarkNames(), 'v:val =~ "^' . a:A . '"') + return filter(s:Bookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"') endfunction " FUNCTION: s:exec(cmd) {{{2 " same as :exec cmd but eventignore=all is set for the duration @@ -2530,7 +2549,7 @@ endfunction " FUNCTION: s:findAndRevealPath() {{{2 function! s:findAndRevealPath() try - let p = s:Path.New(expand("%")) + let p = s:Path.New(expand("%:p")) catch /^NERDTree.InvalidArgumentsError/ call s:echo("no file for the current buffer") return @@ -2564,7 +2583,7 @@ function! s:initNerdTree(name) let dir = a:name ==# '' ? getcwd() : a:name "hack to get an absolute path if a relative path is given - if dir =~ '^\.' + if dir =~# '^\.' let dir = getcwd() . s:Path.Slash() . dir endif let dir = resolve(dir) @@ -2645,6 +2664,9 @@ function! s:initNerdTreeInPlace(dir) setlocal nu else setlocal nonu + if v:version >= 703 + setlocal nornu + endif endif iabc @@ -2881,6 +2903,9 @@ function! s:createTreeWin() setlocal nu else setlocal nonu + if v:version >= 703 + setlocal nornu + endif endif iabc @@ -2996,12 +3021,12 @@ function! s:dumpHelp() let @h=@h."\" :OpenBookmark \n" let @h=@h."\" :ClearBookmarks []\n" let @h=@h."\" :ClearAllBookmarks\n" - else + silent! put h + elseif g:NERDTreeMinimalUI == 0 let @h="\" Press ". g:NERDTreeMapHelp ." for help\n" + silent! put h endif - silent! put h - let @h = old_h endfunction "FUNCTION: s:echo {{{2 @@ -3067,9 +3092,11 @@ function! s:getPath(ln) return b:NERDTreeRoot.path endif - " in case called from outside the tree - if line !~ '^ *[|`]' || line =~ '^$' - return {} + if !g:NERDTreeDirArrows + " in case called from outside the tree + if line !~# '^ *[|`▸▾ ]' || line =~# '^$' + return {} + endif endif if line ==# s:tree_up_dir_line @@ -3082,7 +3109,7 @@ function! s:getPath(ln) let curFile = s:stripMarkupFromLine(line, 0) let wasdir = 0 - if curFile =~ '/$' + if curFile =~# '/$' let wasdir = 1 let curFile = substitute(curFile, '/\?$', '/', "") endif @@ -3099,7 +3126,7 @@ function! s:getPath(ln) let dir = b:NERDTreeRoot.path.str({'format': 'UI'}) . dir break endif - if curLineStripped =~ '/$' + if curLineStripped =~# '/$' let lpindent = s:indentLevelFor(curLine) if lpindent < indent let indent = indent - 1 @@ -3125,7 +3152,13 @@ function! s:getTreeWinNum() endfunction "FUNCTION: s:indentLevelFor(line) {{{2 function! s:indentLevelFor(line) - return match(a:line, '[^ \-+~`|]') / s:tree_wid + let level = match(a:line, '[^ \-+~▸▾`|]') / s:tree_wid + " check if line includes arrows + if match(a:line, '[▸▾]') > -1 + " decrement level as arrow uses 3 ascii chars + let level = level - 1 + endif + return level endfunction "FUNCTION: s:isTreeOpen() {{{2 function! s:isTreeOpen() @@ -3215,16 +3248,20 @@ function! s:putCursorOnBookmarkTable() throw "NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active" endif + if g:NERDTreeMinimalUI + return cursor(1, 2) + endif + let rootNodeLine = s:TreeFileNode.GetRootLineNum() let line = 1 - while getline(line) !~ '^>-\+Bookmarks-\+$' + while getline(line) !~# '^>-\+Bookmarks-\+$' let line = line + 1 if line >= rootNodeLine throw "NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table" endif endwhile - call cursor(line, 0) + call cursor(line, 2) endfunction "FUNCTION: s:putCursorInTreeWin(){{{2 @@ -3240,8 +3277,10 @@ endfunction "FUNCTION: s:renderBookmarks {{{2 function! s:renderBookmarks() - call setline(line(".")+1, ">----------Bookmarks----------") - call cursor(line(".")+1, col(".")) + if g:NERDTreeMinimalUI == 0 + call setline(line(".")+1, ">----------Bookmarks----------") + call cursor(line(".")+1, col(".")) + endif for i in s:Bookmark.Bookmarks() call setline(line(".")+1, i.str()) @@ -3268,16 +3307,20 @@ function! s:renderView() call s:dumpHelp() "delete the blank line before the help and add one after it - call setline(line(".")+1, "") - call cursor(line(".")+1, col(".")) + if g:NERDTreeMinimalUI == 0 + call setline(line(".")+1, "") + call cursor(line(".")+1, col(".")) + endif if b:NERDTreeShowBookmarks call s:renderBookmarks() endif "add the 'up a dir' line - call setline(line(".")+1, s:tree_up_dir_line) - call cursor(line(".")+1, col(".")) + if !g:NERDTreeMinimalUI + call setline(line(".")+1, s:tree_up_dir_line) + call cursor(line(".")+1, col(".")) + endif "draw the header line let header = b:NERDTreeRoot.path.str({'format': 'UI', 'truncateTo': winwidth(0)}) @@ -3365,91 +3408,91 @@ function! s:setupStatusline() endfunction "FUNCTION: s:setupSyntaxHighlighting() {{{2 function! s:setupSyntaxHighlighting() - "treeFlags are syntax items that should be invisible, but give clues as to + "NERDTreeFlags are syntax items that should be invisible, but give clues as to "how things should be highlighted - syn match treeFlag #\~# - syn match treeFlag #\[RO\]# + syn match NERDTreeFlag #\~# + syn match NERDTreeFlag #\[RO\]# "highlighting for the .. (up dir) line at the top of the tree - execute "syn match treeUp #". s:tree_up_dir_line ."#" + execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line ."#" "highlighting for the ~/+ symbols for the directory nodes - syn match treeClosable #\~\<# - syn match treeClosable #\~\.# - syn match treeOpenable #+\<# - syn match treeOpenable #+\.#he=e-1 + syn match NERDTreeClosable #\~\<# + syn match NERDTreeClosable #\~\.# + syn match NERDTreeOpenable #+\<# + syn match NERDTreeOpenable #+\.#he=e-1 "highlighting for the tree structural parts - syn match treePart #|# - syn match treePart #`# - syn match treePartFile #[|`]-#hs=s+1 contains=treePart + syn match NERDTreePart #|# + syn match NERDTreePart #`# + syn match NERDTreePartFile #[|`]-#hs=s+1 contains=NERDTreePart "quickhelp syntax elements - syn match treeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 - syn match treeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 - syn match treeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=treeFlag - syn match treeToggleOn #".*(on)#hs=e-2,he=e-1 contains=treeHelpKey - syn match treeToggleOff #".*(off)#hs=e-3,he=e-1 contains=treeHelpKey - syn match treeHelpCommand #" :.\{-}\>#hs=s+3 - syn match treeHelp #^".*# contains=treeHelpKey,treeHelpTitle,treeFlag,treeToggleOff,treeToggleOn,treeHelpCommand + syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#hs=s+2,he=e-1 + syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#hs=s+2,he=e-1 + syn match NERDTreeHelpTitle #" .*\~#hs=s+2,he=e-1 contains=NERDTreeFlag + syn match NERDTreeToggleOn #".*(on)#hs=e-2,he=e-1 contains=NERDTreeHelpKey + syn match NERDTreeToggleOff #".*(off)#hs=e-3,he=e-1 contains=NERDTreeHelpKey + syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 + syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeFlag,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand "highlighting for readonly files - syn match treeRO #.*\[RO\]#hs=s+2 contains=treeFlag,treeBookmark,treePart,treePartFile + syn match NERDTreeRO #.*\[RO\]#hs=s+2 contains=NERDTreeFlag,NERDTreeBookmark,NERDTreePart,NERDTreePartFile "highlighting for sym links - syn match treeLink #[^-| `].* -> # contains=treeBookmark,treeOpenable,treeClosable,treeDirSlash + syn match NERDTreeLink #[^-| `].* -> # contains=NERDTreeBookmark,NERDTreeOpenable,NERDTreeClosable,NERDTreeDirSlash "highlighing for directory nodes and file nodes - syn match treeDirSlash #/# - syn match treeDir #[^-| `].*/# contains=treeLink,treeDirSlash,treeOpenable,treeClosable - syn match treeExecFile #[|`]-.*\*\($\| \)# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark - syn match treeFile #|-.*# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark,treeExecFile - syn match treeFile #`-.*# contains=treeLink,treePart,treeRO,treePartFile,treeBookmark,treeExecFile - syn match treeCWD #^/.*$# + syn match NERDTreeDirSlash #/# + syn match NERDTreeDir #[^-| `].*/# contains=NERDTreeLink,NERDTreeDirSlash,NERDTreeOpenable,NERDTreeClosable + syn match NERDTreeExecFile #[|` ].*\*\($\| \)# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark + syn match NERDTreeFile #|-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile + syn match NERDTreeFile #`-.*# contains=NERDTreeLink,NERDTreePart,NERDTreeRO,NERDTreePartFile,NERDTreeBookmark,NERDTreeExecFile + syn match NERDTreeCWD #^/.*$# "highlighting for bookmarks - syn match treeBookmark # {.*}#hs=s+1 + syn match NERDTreeBookmark # {.*}#hs=s+1 "highlighting for the bookmarks table - syn match treeBookmarksLeader #^># - syn match treeBookmarksHeader #^>-\+Bookmarks-\+$# contains=treeBookmarksLeader - syn match treeBookmarkName #^>.\{-} #he=e-1 contains=treeBookmarksLeader - syn match treeBookmark #^>.*$# contains=treeBookmarksLeader,treeBookmarkName,treeBookmarksHeader + syn match NERDTreeBookmarksLeader #^># + syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmarksLeader + syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader + syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader if g:NERDChristmasTree - hi def link treePart Special - hi def link treePartFile Type - hi def link treeFile Normal - hi def link treeExecFile Title - hi def link treeDirSlash Identifier - hi def link treeClosable Type + hi def link NERDTreePart Special + hi def link NERDTreePartFile Type + hi def link NERDTreeFile Normal + hi def link NERDTreeExecFile Title + hi def link NERDTreeDirSlash Identifier + hi def link NERDTreeClosable Type else - hi def link treePart Normal - hi def link treePartFile Normal - hi def link treeFile Normal - hi def link treeClosable Title + hi def link NERDTreePart Normal + hi def link NERDTreePartFile Normal + hi def link NERDTreeFile Normal + hi def link NERDTreeClosable Title endif - hi def link treeBookmarksHeader statement - hi def link treeBookmarksLeader ignore - hi def link treeBookmarkName Identifier - hi def link treeBookmark normal + hi def link NERDTreeBookmarksHeader statement + hi def link NERDTreeBookmarksLeader ignore + hi def link NERDTreeBookmarkName Identifier + hi def link NERDTreeBookmark normal - hi def link treeHelp String - hi def link treeHelpKey Identifier - hi def link treeHelpCommand Identifier - hi def link treeHelpTitle Macro - hi def link treeToggleOn Question - hi def link treeToggleOff WarningMsg + hi def link NERDTreeHelp String + hi def link NERDTreeHelpKey Identifier + hi def link NERDTreeHelpCommand Identifier + hi def link NERDTreeHelpTitle Macro + hi def link NERDTreeToggleOn Question + hi def link NERDTreeToggleOff WarningMsg - hi def link treeDir Directory - hi def link treeUp Directory - hi def link treeCWD Statement - hi def link treeLink Macro - hi def link treeOpenable Title - hi def link treeFlag ignore - hi def link treeRO WarningMsg - hi def link treeBookmark Statement + hi def link NERDTreeDir Directory + hi def link NERDTreeUp Directory + hi def link NERDTreeCWD Statement + hi def link NERDTreeLink Macro + hi def link NERDTreeOpenable Title + hi def link NERDTreeFlag ignore + hi def link NERDTreeRO WarningMsg + hi def link NERDTreeBookmark Statement hi def link NERDTreeCurrentNode Search endfunction @@ -3476,7 +3519,7 @@ function! s:stripMarkupFromLine(line, removeLeadingSpaces) let line = substitute (line, '*\ze\($\| \)', "","") let wasdir = 0 - if line =~ '/$' + if line =~# '/$' let wasdir = 1 endif let line = substitute (line,' -> .*',"","") " remove link to @@ -3634,14 +3677,14 @@ function! s:checkForActivate() "if they clicked a dir, check if they clicked on the + or ~ sign "beside it if currentNode.path.isDirectory - if startToCur =~ s:tree_markup_reg . '$' && char =~ '[+~]' + if startToCur =~# s:tree_markup_reg . '$' && char =~# '[+~]' call s:activateNode(0) return endif endif if (g:NERDTreeMouseMode ==# 2 && currentNode.path.isDirectory) || g:NERDTreeMouseMode ==# 3 - if char !~ s:tree_markup_reg && startToCur !~ '\/$' + if char !~# s:tree_markup_reg && startToCur !~# '\/$' call s:activateNode(0) return endif @@ -4041,7 +4084,7 @@ endfunction "re-rendered function! s:upDir(keepState) let cwd = b:NERDTreeRoot.path.str({'format': 'UI'}) - if cwd ==# "/" || cwd =~ '^[^/]..$' + if cwd ==# "/" || cwd =~# '^[^/]..$' call s:echo("already at top dir") else if !a:keepState diff --git a/.vim/bundle/vim-coffee-script/ftdetect/eco.vim b/.vim/bundle/vim-coffee-script/ftdetect/eco.vim new file mode 100644 index 0000000..b420649 --- /dev/null +++ b/.vim/bundle/vim-coffee-script/ftdetect/eco.vim @@ -0,0 +1 @@ +autocmd BufNewFile,BufRead *.eco set filetype=eco diff --git a/.vim/bundle/vim-coffee-script/ftplugin/coffee.vim b/.vim/bundle/vim-coffee-script/ftplugin/coffee.vim index 4e53c17..85cdd87 100644 --- a/.vim/bundle/vim-coffee-script/ftplugin/coffee.vim +++ b/.vim/bundle/vim-coffee-script/ftplugin/coffee.vim @@ -12,3 +12,8 @@ let b:did_ftplugin = 1 setlocal formatoptions-=t formatoptions+=croql setlocal comments=s:###,m:\ ,e:###,:# setlocal commentstring=#\ %s + +" Compile the current file on write. +if exists("coffee_compile_on_save") + autocmd BufWritePost,FileWritePost *.coffee silent !coffee -c & +endif diff --git a/.vim/bundle/vim-coffee-script/indent/coffee.vim b/.vim/bundle/vim-coffee-script/indent/coffee.vim index 796ad04..9f942d4 100644 --- a/.vim/bundle/vim-coffee-script/indent/coffee.vim +++ b/.vim/bundle/vim-coffee-script/indent/coffee.vim @@ -11,30 +11,30 @@ let b:did_indent = 1 setlocal autoindent setlocal indentexpr=GetCoffeeIndent(v:lnum) -" Make sure GetCoffeeIndent is run when these are typed so they can be outdented -setlocal indentkeys+=0],0),=else,=when,=catch,=finally +" Make sure GetCoffeeIndent is run when these are typed so they can be +" indented or outdented. +setlocal indentkeys+=0],0),0.,=else,=when,=catch,=finally -" Only define the function once +" Only define the function once. if exists("*GetCoffeeIndent") finish endif -" Join a list of regexps as branches +" Join a list of regexps as branches. function! s:RegexpJoin(regexps) return join(a:regexps, '\|') endfunction -" Create a regexp group from a list of regexps +" Create a regexp group from a list of regexps. function! s:RegexpGroup(...) return '\%(' . s:RegexpJoin(a:000) . '\)' endfunction -" Outdent certain keywords and brackets +" Outdent certain keywords and brackets. let s:outdent = '^' -\ . s:RegexpGroup('else', 'when', 'catch', 'finally', -\ ']', '}', ')') +\ . s:RegexpGroup('else', 'when', 'catch', 'finally', ']', '}', ')') -" Indent after certain keywords +" Indent after certain keywords. let s:indent_after_keywords = '^' \ . s:RegexpGroup('if', 'unless', 'else', 'for', \ 'while', 'until', 'loop', 'switch', @@ -42,23 +42,28 @@ let s:indent_after_keywords = '^' \ 'class') \ . '\>' -" Indent after brackets, functions, and assignments -let s:indent_after_literals = s:RegexpGroup('\[', '{', '(', '->', '=>', -\ ':', '=') +" Indent after brackets, functions, and assignments. +let s:indent_after_literals = s:RegexpGroup('\[', '{', '(', '->', '=>', ':', '=') \ . '$' -" Combine the two regexps above +" Combine the two regexps above. let s:indent_after = s:RegexpJoin([s:indent_after_keywords, \ s:indent_after_literals]) -" Indent after certain keywords used in multi-line assignments +" Indent after operators at the end of lines. +let s:continuations = s:RegexpGroup('-\@', '=\@', '-\@' -" Outdent after certain keywords +" Outdent after certain keywords. let s:outdent_after = '^' \ . s:RegexpGroup('return', 'break', 'continue', 'throw') \ . '\>' @@ -68,37 +73,55 @@ let s:outdent_after = '^' let s:dont_outdent_after = '\<' . s:RegexpGroup('if', 'unless') . '\>' " Check for a single-line statement (e.g., 'if a then b'), which doesn't need an -" indent afterwards +" indent afterwards. function! s:IsSingleLineStatement(line) - " The 'then' keyword is usually a good hint + " The 'then' keyword is usually a good hint. return a:line =~ '\' endfunction " Check for a single-line 'else' statement (e.g., 'else return a' but -" not 'else if a'), which doesn't need an indent afterwards +" not 'else if a'), which doesn't need an indent afterwards. function! s:IsSingleLineElse(line) " Check if the line actually starts with 'else', then if the line contains " anything other than 'else', then finally if the line is actually an 'else' - " statement rather than an 'else if' statement - return a:line =~ '^else\>' && a:line !~ '^else$' && a:line !~ '^else if\>' + " statement rather than an 'else if' or 'else unless' statement. + return a:line =~ '^else\>' + \ && a:line !~ '^else$' + \ && a:line !~ '^else if\>' + \ && a:line !~ '^else unless\>' endfunction -" Check if a 'when' statement is the first in a 'switch' block by searching the +" Check if a 'when' statement is the first in a switch block by searching the " previous line for the 'switch' keyword. The first 'when' shouldn't be -" outdented +" outdented. function! s:IsFirstWhen(curline, prevline) return a:curline =~ '^when\>' && a:prevline =~ '\' endfunction " Check for a multi-line assignment like -" a: if b -" c -" else -" d +" a = if b +" c +" else +" d function! s:IsMultiLineAssignment(line) return a:line =~ s:assignment_keywords endfunction +" Check if a line is a comment. +function! s:IsComment(line) + return a:line =~ '^#' +endfunction + +" Check if a line is a dot-access. +function! s:IsDotAccess(line) + return a:line =~ '^\.' +endfunction + +" Check if a line is a continuation. +function! s:IsContinuation(line) + return a:line =~ s:continuations +endfunction + function! s:ShouldOutdent(curline, prevline) return !s:IsSingleLineStatement(a:prevline) \ && !s:IsFirstWhen(a:curline, a:prevline) @@ -106,11 +129,21 @@ function! s:ShouldOutdent(curline, prevline) \ && a:curline =~ s:outdent endfunction -function! s:ShouldIndentAfter(prevline) +function! s:ShouldIndent(curline, prevline) + return !s:IsDotAccess(a:prevline) && s:IsDotAccess(a:curline) +endfunction + +function! s:ShouldIndentAfter(prevline, prevprevline) return !s:IsSingleLineStatement(a:prevline) \ && !s:IsSingleLineElse(a:prevline) + \ && !s:IsComment(a:prevline) + \ \ && (a:prevline =~ s:indent_after - \ || s:IsMultiLineAssignment(a:prevline)) + \ || s:IsMultiLineAssignment(a:prevline) + \ + \ || (s:IsContinuation(a:prevline) + \ && !s:IsContinuation(a:prevprevline) + \ && a:prevprevline !~ s:indent_after_literals)) endfunction function! s:ShouldOutdentAfter(prevline) @@ -119,21 +152,36 @@ function! s:ShouldOutdentAfter(prevline) \ && a:prevline =~ s:outdent_after endfunction -function! GetCoffeeIndent(curlinenum) - " Find a non-blank line above the current line - let prevlinenum = prevnonblank(a:curlinenum - 1) +" Get the nearest previous non-blank line. +function! s:GetPrevLineNum(linenum) + return prevnonblank(a:linenum - 1) +endfunction - " No indenting is needed at the start of a file +" Get the contents of a line without leading whitespace. +function! s:GetTrimmedLine(linenum, indent) + return substitute(getline(a:linenum)[a:indent : -1], '\s\+$', '', '') +endfunction + +function! GetCoffeeIndent(curlinenum) + let prevlinenum = s:GetPrevLineNum(a:curlinenum) + let prevprevlinenum = s:GetPrevLineNum(prevlinenum) + + " No indenting is needed at the start of a file. if prevlinenum == 0 return 0 endif let curindent = indent(a:curlinenum) let previndent = indent(prevlinenum) + let prevprevindent = indent(prevprevlinenum) - " Strip off leading whitespace - let curline = getline(a:curlinenum)[curindent : -1] - let prevline = getline(prevlinenum)[previndent : -1] + let curline = s:GetTrimmedLine(a:curlinenum, curindent) + let prevline = s:GetTrimmedLine(prevlinenum, previndent) + let prevprevline = s:GetTrimmedLine(prevprevlinenum, prevprevindent) + + if s:ShouldIndent(curline, prevline) + return previndent + &shiftwidth + endif if s:ShouldOutdent(curline, prevline) " Is the line already outdented? @@ -144,7 +192,7 @@ function! GetCoffeeIndent(curlinenum) endif endif - if s:ShouldIndentAfter(prevline) + if s:ShouldIndentAfter(prevline, prevprevline) return previndent + &shiftwidth endif diff --git a/.vim/bundle/vim-coffee-script/readme.md b/.vim/bundle/vim-coffee-script/readme.md index a38224b..fa6dd12 100644 --- a/.vim/bundle/vim-coffee-script/readme.md +++ b/.vim/bundle/vim-coffee-script/readme.md @@ -1,5 +1,5 @@ This project adds [CoffeeScript] support to the vim editor. Currently, it -supports [almost][todo] all of CoffeeScript 0.9.2's syntax and indentation style. +supports [almost][todo] all of CoffeeScript's syntax and indentation style. ![Screenshot][screenshot] @@ -23,7 +23,7 @@ supports [almost][todo] all of CoffeeScript 0.9.2's syntax and indentation style > so you actually need to "filetype off" before "filetype plugin indent on" > to force reloading. -[pathogen]: http://vim.org/scripts/script.php?script_id=2332 +[pathogen]: http://www.vim.org/scripts/script.php?script_id=2332 2. Create, and change into, the `~/.vim/bundle/` directory: @@ -50,12 +50,19 @@ extension or a `Cakefile` will load all the CoffeeScript stuff. $ git pull -Everything will then be brought up to date! +Everything will then be brought up to date. ### Customizing -Some of the possibly unwanted syntax highlighting elements can be disabled -in the following ways. +#### Compile the current file on write/save + +If you are using the NodeJS version of CofeeScript, with the `coffee` command +in your `$PATH`, you can enable auto-compiling on file write/save like so: + + let coffee_compile_on_save = 1 + +This will compile the CoffeeScript to JavaScript. For example, +`/Users/brian/ZOMG.coffee` will compile to `/Users/brian/ZOMG.js`. #### Disable trailing whitespace error highlighting diff --git a/.vim/bundle/vim-coffee-script/syntax/coffee.vim b/.vim/bundle/vim-coffee-script/syntax/coffee.vim index ea8606a..8e5c741 100644 --- a/.vim/bundle/vim-coffee-script/syntax/coffee.vim +++ b/.vim/bundle/vim-coffee-script/syntax/coffee.vim @@ -13,11 +13,15 @@ endif let b:current_syntax = "coffee" +" Highlight long strings. syntax sync minlines=100 -" CoffeeScript allows dollar signs in identifiers +" CoffeeScript allows dollar signs in identifiers. setlocal isident+=$ +" These are 'matches' rather than 'keywords' because vim's highlighting priority +" for keywords (the highest) causes them to be wrongly highlighted when used as +" dot-properties. syntax match coffeeStatement /\<\%(return\|break\|continue\|throw\)\>/ highlight default link coffeeStatement Statement @@ -33,7 +37,7 @@ highlight default link coffeeException Exception syntax match coffeeOperator /\<\%(instanceof\|typeof\|delete\)\>/ highlight default link coffeeOperator Operator -syntax match coffeeKeyword /\<\%(new\|in\|of\|by\|where\|and\|or\|not\|is\|isnt\|class\|extends\|super\|all\)\>/ +syntax match coffeeKeyword /\<\%(new\|in\|of\|by\|and\|or\|not\|is\|isnt\|class\|extends\|super\|own\|do\)\>/ highlight default link coffeeKeyword Keyword syntax match coffeeBoolean /\<\%(\%(true\|on\|yes\|false\|off\|no\)\)\>/ @@ -42,50 +46,74 @@ highlight default link coffeeBoolean Boolean syntax match coffeeGlobal /\<\%(null\|undefined\)\>/ highlight default link coffeeGlobal Type +" Keywords reserved by the language syntax cluster coffeeReserved contains=coffeeStatement,coffeeRepeat, \ coffeeConditional,coffeeException, \ coffeeOperator,coffeeKeyword, \ coffeeBoolean,coffeeGlobal -syntax match coffeeAssignmentMod /\%(\s\+\zs\%(and\|or\)\|\W\{,3}\)\ze=/ contained -highlight default link coffeeAssignmentMod SpecialChar - -syntax match coffeeAssignmentChar /:\|=/ contained -highlight default link coffeeAssignmentChar SpecialChar - syntax match coffeeVar /\<\%(this\|prototype\|arguments\)\>/ -" Matches @-variables like @abc +" Matches @-variables like @abc. syntax match coffeeVar /@\%(\I\i*\)\?/ highlight default link coffeeVar Type " Matches class-like names that start with a capital letter, like Array or -" Object +" Object. syntax match coffeeObject /\<\u\w*\>/ highlight default link coffeeObject Structure -" Matches constant-like names in SCREAMING_CAPS +" Matches constant-like names in SCREAMING_CAPS. syntax match coffeeConstant /\<\u[A-Z0-9_]\+\>/ highlight default link coffeeConstant Constant -syntax match coffeePrototype /::/ -highlight default link coffeePrototype SpecialChar - -syntax region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=@coffeeInterpString -syntax region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/ contains=@coffeeSimpleString -highlight default link coffeeString String - " What can make up a variable name syntax cluster coffeeIdentifier contains=coffeeVar,coffeeObject,coffeeConstant, \ coffeePrototype -syntax match coffeeAssignment /@\?\I\%(\i\|::\|\.\|\[.\+\]\|([^)]*)\)*\s*\%(::\@!\|\%(and\|or\|\|&&\|||\|?\|+\|-\|\/\|\*\|%\|<<\|>>\|>>>\|&\||\|\^\)==\@!>\@!\)/ -\ contains=@coffeeIdentifier,coffeeAssignmentMod, -\ coffeeAssignmentChar,coffeeBrackets, -\ coffeeParens -syntax match coffeeAssignment /\%("\|'\)[^'"]\+\%("\|'\)\s*:/ contains=coffeeString, -\ coffeeAssignmentChar -syntax match coffeeAssignment /\d*\%(\.\d\+\)\?\s*:/ contains=coffeeNumber,coffeeAssignmentChar -highlight default link coffeeAssignment Identifier +syntax region coffeeString start=/"/ skip=/\\\\\|\\"/ end=/"/ contains=@coffeeInterpString +syntax region coffeeString start=/'/ skip=/\\\\\|\\'/ end=/'/ contains=@coffeeSimpleString +highlight default link coffeeString String + +syntax region coffeeAssignString start=/"/ skip=/\\\\\|\\"/ end=/"/ contained contains=@coffeeSimpleString +syntax region coffeeAssignString start=/'/ skip=/\\\\\|\\'/ end=/'/ contained contains=@coffeeSimpleString +highlight default link coffeeAssignString String + +" Matches numbers like -10, -10e8, -10E8, 10, 10e8, 10E8. +syntax match coffeeNumber /\i\@/ +highlight default link coffeeNumber Number + +" Matches floating-point numbers like -10.42e8, 10.42e-8. +syntax match coffeeFloat /\i\@>\|>>>\|&\||\|\^\)\?=\@\@!/ contained +highlight default link coffeeAssignSymbols SpecialChar + +syntax match coffeeAssignBrackets /\[.\+\]/ contained contains=TOP,coffeeAssign + +syntax match coffeeAssign /\%(++\|--\)\s*\%(@\|@\?\I\)\%(\i\|::\|\.\|?\|\[.\+\]\)*/ +\ contains=@coffeeIdentifier,coffeeAssignSymbols,coffeeAssignBrackets +syntax match coffeeAssign /\%(@\|@\?\I\)\%(\i\|::\|\.\|?\|\[.\+\]\)*\%(++\|--\|\s*\%(and\|or\|&&\|||\|?\|+\|-\|\/\|\*\|%\|<<\|>>\|>>>\|&\||\|\^\)\?=\@\@!\)/ +\ contains=@coffeeIdentifier,coffeeAssignSymbols,coffeeAssignBrackets + +" Displays an error for reserved words. +if !exists("coffee_no_reserved_words_error") + syntax match coffeeReservedError /\<\%(case\|default\|function\|var\|void\|with\|const\|let\|enum\|export\|import\|native\|__hasProp\|__extends\|__slice\|__bind\|__indexOf\)\>/ + highlight default link coffeeReservedError Error +endif + +syntax match coffeeAssign /@\?\I\i*\s*:\@\|=>/ highlight default link coffeeFunction Function @@ -97,65 +125,51 @@ syntax match coffeeComment /#.*/ contains=@Spell,coffeeTodo syntax match coffeeComment /####\@!\_.\{-}###/ contains=@Spell,coffeeTodo highlight default link coffeeComment Comment -syntax region coffeeEmbed start=/`/ end=/`/ +syntax region coffeeHereComment start=/#/ end=/\ze\/\/\// end=/$/ contained contains=@Spell,coffeeTodo +highlight default link coffeeHereComment coffeeComment + +syntax region coffeeEmbed start=/`/ skip=/\\\\\|\\`/ end=/`/ highlight default link coffeeEmbed Special -" Matches numbers like -10, -10e8, -10E8, 10, 10e8, 10E8 -syntax match coffeeNumber /\<-\?\d\+\%([eE][+-]\?\d\+\)\?\>/ -" Matches hex numbers like 0xfff, 0x000 -syntax match coffeeNumber /\<0[xX]\x\+\>/ -highlight default link coffeeNumber Number - -" Matches floating-point numbers like -10.42e8, 10.42e-8 -syntax match coffeeFloat /-\?\d*\.\@/ contains=@coffeeTop containedin=ALLBUT,@ecoRegions keepend +syn region ecoExpression matchgroup=ecoDelimiter start=/<%[=\-]/ end=/%>/ contains=@coffeeTop containedin=ALLBUT,@ecoRegions keepend +syn region ecoComment matchgroup=ecoComment start=/<%#/ end=/%>/ contains=@coffeeTodo,@Spell containedin=ALLBUT,@ecoRegions keepend + +" eco features not in coffeescript proper +syn keyword ecoEnd end containedin=@ecoRegions +syn match ecoIndentColon /\s+\w+:/ containedin=@ecoRegions + +" Define the default highlighting. + +hi def link ecoDelimiter Delimiter +hi def link ecoComment Comment +hi def link ecoEnd coffeeConditional +hi def link ecoIndentColon None + +let b:current_syntax = 'eco' + +" vim: nowrap sw=2 sts=2 ts=8: diff --git a/.vim/bundle/vim-coffee-script/thanks.md b/.vim/bundle/vim-coffee-script/thanks.md new file mode 100644 index 0000000..e9fdc5a --- /dev/null +++ b/.vim/bundle/vim-coffee-script/thanks.md @@ -0,0 +1,22 @@ +Thanks to the following contributors: + + Brian Egan (3): + Adding compile functionality to the ftplugin. Must be enabled in .vimrc + Updating the readme with compilation instructions + Updating bad header in readme to make instructions easier to read + + Chris Hoffman (3): + Add new keywoards from, to, and do + Highlight the - in negative integers + Add here regex highlighting, increase fold level for here docs + + Jay Adkisson: + Support for eco templates + + Karl Guertin (1): + Cakefiles are coffeescript + + Simon Lipp (1): + Trailing spaces are not error on lines containing only spaces + +And thanks to anyone who files or has filed a bug report. diff --git a/.vim/bundle/vim-coffee-script/todo.md b/.vim/bundle/vim-coffee-script/todo.md index 0f32a35..f45f2b6 100644 --- a/.vim/bundle/vim-coffee-script/todo.md +++ b/.vim/bundle/vim-coffee-script/todo.md @@ -6,14 +6,6 @@ {a, b} = c └──┴─ these should be highlighted as identifiers -- Assignments inside brackets (sounds simple enough): - - a[b -= c] = d - - this should still be highlighted correctly: - - a[b[c]] = d - - Smart, lookback outdenting for cases like: a = { @@ -22,14 +14,13 @@ } └─ bracket should be put here -- Should indent if the previous line ends, or the current line starts, with one - of these: +- Fix assignments with brackets in these cases: - + - * / % | & , . is isnt and or && || + a[b] = c[d] + a[b -= c] = d -- Support `else unless` in indentation: + and still highlight these correctly: - unless a - b - else unless c - d + a[b] = c + a[b[c]] = d + a[b[c] -= d] = e diff --git a/.vim/bundle/vim-fugitive/.gitignore b/.vim/bundle/vim-fugitive/.gitignore new file mode 100644 index 0000000..0a56e3f --- /dev/null +++ b/.vim/bundle/vim-fugitive/.gitignore @@ -0,0 +1 @@ +/doc/tags diff --git a/.vim/bundle/vim-fugitive/README.markdown b/.vim/bundle/vim-fugitive/README.markdown new file mode 100644 index 0000000..1d58026 --- /dev/null +++ b/.vim/bundle/vim-fugitive/README.markdown @@ -0,0 +1,70 @@ +fugitive.vim +============ + +I'm not going to lie to you; fugitive.vim may very well be the best +Git wrapper of all time. Check out these features: + +View any blob, tree, commit, or tag in the repository with `:Gedit` (and +`:Gsplit`, `:Gvsplit`, `:Gtabedit`, ...). Edit a file in the index and +write to it to stage the changes. Use `:Gdiff` to bring up the staged +version of the file side by side with the working tree version and use +Vim's diff handling capabilities to stage a subset of the file's +changes. + +Bring up the output of `git status` with `:Gstatus`. Press `-` to +`add`/`reset` a file's changes, or `p` to `add`/`reset` `--patch` that +mofo. And guess what `:Gcommit` does! + +`:Gblame` brings up an interactive vertical split with `git blame` +output. Press enter on a line to reblame the file as it stood in that +commit, or `o` to open that commit in a split. When you're done, use +`:Gedit` in the historic buffer to go back to the work tree version. + +`:Gmove` does a `git mv` on a file and simultaneously renames the +buffer. `:Gremove` does a `git rm` on a file and simultaneously deletes +the buffer. + +Use `:Ggrep` to search the work tree (or any arbitrary commit) with +`git grep`, skipping over that which is not tracked in the repository. +`:Glog` loads all previous revisions of a file into the quickfix list so +you can iterate over them and watch the file evolve! + +`:Gread` is a variant of `git checkout -- filename` that operates on the +buffer rather than the filename. This means you can use `u` to undo it +and you never get any warnings about the file changing outside Vim. +`:Gwrite` writes to both the work tree and index versions of a file, +making it like `git add` when called from a work tree file and like +`git checkout` when called from the index or a blob in history. + +Use `:Gbrowse` to open the current file on GitHub, with optional line +range (try it in visual mode!). If your current repository isn't on +GitHub, `git instaweb` will be spun up instead. + +Add `%{fugitive#statusline()}` to `'statusline'` to get an indicator +with the current branch in (surprise!) your statusline. + +Oh, and of course there's `:Git` for running any arbitrary command. + +Like fugitive.vim? Follow the repository on +[GitHub](http://github.com/tpope/vim-fugitive) and vote for it on +[vim.org](http://www.vim.org/scripts/script.php?script_id=2975). + +FAQ +--- + +> I installed the plugin and started Vim. Why don't any of the commands +> exist? + +Fugitive cares about the current file, not the current working +directory. Edit a file from the repository. + +> I opened a new tab. Why don't any of the commands exist? + +Fugitive cares about the current file, not the current working +directory. Edit a file from the repository. + +> I changed the current working directory. Why do all the commands use +> the old directory? + +Fugitive cares about the current file, not the current working +directory. Edit a file from the repository. diff --git a/.vim/bundle/vim-fugitive/doc/fugitive.txt b/.vim/bundle/vim-fugitive/doc/fugitive.txt new file mode 100644 index 0000000..39f3dd2 --- /dev/null +++ b/.vim/bundle/vim-fugitive/doc/fugitive.txt @@ -0,0 +1,255 @@ +*fugitive.txt* A Git wrapper so awesome, it should be illegal + +Author: Tim Pope *fugitive-author* +License: Same terms as Vim itself (see |license|) + +This plugin is only available if 'compatible' is not set. + +INTRODUCTION *fugitive* + +Install in ~/.vim, or in ~\vimfiles if you're on Windows and feeling lucky. +Vim 7.2 is recommended as it ships with syntax highlighting for many Git file +types. + +If you're in a hurry to get started, here are some things to try: + +In any file in your repository, run |:Gedit| HEAD. Press to jump to the +current branch. Press again to jump to the top most commit. Keep using + to explore parent commits, trees, and blobs. Use C in a tree or blob to +get back to the commit. + +Edit a file in the work tree and make some changes. Use |:Gdiff| to open up +the indexed version. Use |do| and |dp| on various hunks to bring the files in +sync, or use |:Gread| to pull in all changes. Write the indexed version to +stage the file. + +Run |:Gstatus| to check your repository's status. Use "-" to stage and reset +files and "p" to add/reset --patch them. Invoke |:Gcommit| to commit your +changes. + +Run |:Gblame| in a work tree file to see a blame in a vertical split. Press + on any line to reopen and reblame that file as it stood in that commit. +Press o or O on any line to inspect that commit in a split or a tab. + +Run |:Ggrep| to search the work tree or history. Run |:Gmove| to rename a +file. Run |:Gremove| to delete a file. + +COMMANDS *fugitive-commands* + +These commands are local to the buffers in which they work (generally, buffers +that are part of Git repositories). + + *fugitive-:Git* +:Git [args] Run an arbitrary git command. Similar to :!git [args] + but chdir to the repository tree first. + + *fugitive-:Gcd* +:Gcd [directory] |:cd| relative to the repository. + + *fugitive-:Glcd* +:Glcd [directory] |:lcd| relative to the repository. + + *fugitive-:Gstatus* +:Gstatus Bring up the output of git-status in the preview + window. In addition to standard motions, you can + use and to jump from filename to + filename. Press D to |:Gdiff| the file on the cursor + line, or ds to |:Gsdiff|. Press - to stage or unstage + the file on the cursor line. Press p to do so on a + per hunk basis (--patch). Press C to invoke + |:Gcommit|. + + *fugitive-:Gcommit* +:Gcommit [args] A wrapper around git-commit. If there is nothing + to commit, |:Gstatus| is called instead. Unless the + arguments given would skip the invocation of an editor + (e.g., -m), a split window will be used to obtain a + commit message. Write and close that window (:wq or + |:Gwrite|) to finish the commit. Unlike when running + the actual git-commit command, it is possible (but + unadvisable) to muck with the index with commands like + git-add and git-reset while a commit message is + pending. + + *fugitive-:Ggrep* +:Ggrep [args] |:grep| with git-grep as 'grepprg'. + + *fugitive-:Glog* +:Glog [args] Load all previous revisions of the current file into + the quickfix list. Additional git-log arguments can + be given (for example, --reverse). If "--" appears as + an argument, no file specific filtering is done, and + commits are loaded into the quickfix list. + + *fugitive-:Gedit* *fugitive-:Ge* +:Gedit [revision] |:edit| a |fugitive-revision|. + + *fugitive-:Gsplit* +:Gsplit [revision] |:split| a |fugitive-revision|. + + *fugitive-:Gvsplit* +:Gvsplit [revision] |:vsplit| a |fugitive-revision|. + + *fugitive-:Gtabedit* +:Gtabedit [revision] |:tabedit| a |fugitive-revision| + + *fugitive-:Gpedit* +:Gpedit [revision] |:pedit| a |fugitive-revision| + + *fugitive-:Gread* +:Gread [revision] Empty the buffer and |:read| a |fugitive-revision|. + When the argument is omitted, this is similar to + git-checkout on a work tree file or git-add on a stage + file, but without writing anything to disk. + +:{range}Gread [revision] + |:read| in a |fugitive-revision| after {range}. + + *fugitive-:Gwrite* +:Gwrite Write to the current file's path and stage the results. + When run in a work tree file, it is effectively git + add. Elsewhere, it is effectively git-checkout. A + great deal of effort is expended to behave sensibly + when the work tree or index version of the file is + open in another buffer. + +:Gwrite {path} You can give |:Gwrite| an explicit path of where in + the work tree to write. You can also give a path like + :0:foo.txt or even :0 to write to just that stage in + the index. + + *fugitive-:Gwq* +:Gwq [path] Like |:Gwrite| followed by |:quit| if the write + succeeded. + +:Gwq! [path] Like |:Gwrite|! followed by |:quit|! if the write + succeeded. + + *fugitive-:Gdiff* +:Gdiff [revision] Perform a |vimdiff| against the current file in the + given revision. With no argument, the version in the + index is used (which means a three-way diff during a + merge conflict, making it a git-mergetool + alternative). The newer of the two files is placed + to the right. Use |do| and |dp| and write to the + index file to simulate "git add --patch". + + *fugitive-:Gsdiff* +:Gsdiff [revision] Like |:Gdiff|, but split horizontally. + + *fugitive-:Gvdiff* +:Gvdiff [revision] Identical to |:Gdiff|. For symmetry with |:Gsdiff|. + + *fugitive-:Gmove* +:Gmove {destination} Wrapper around git-mv that renames the buffer + afterward. The destination is relative to the current + directory except when started with a /, in which case + it is relative to the work tree. Add a ! to pass -f. + + *fugitive-:Gremove* +:Gremove Wrapper around git-rm that deletes the buffer + afterward. When invoked in an index file, --cached is + passed. Add a ! to pass -f and forcefully discard the + buffer. + + *fugitive-:Gblame* +:Gblame [flags] Run git-blame on the file and open the results in a + scroll bound vertical split. Press enter on a line to + reblame the file as it was in that commit. You can + give any of ltwfsMC as flags and they will be passed + along to git-blame. + +:[range]Gblame [flags] Run git-blame on the given range. + + *fugitive-:Gbrowse* +:[range]Gbrowse If the remote for the current branch is on GitHub, + open the current file, blob, tree, commit, or tag + (with git-web--browse) on GitHub. Otherwise, open the + current file, blob, tree, commit, or tag in + git-instaweb (if you have issues, verify you can run + "git instaweb" from a terminal). If a range is given, + it is appropriately appended to the URL as an anchor. + +:[range]Gbrowse! Like :Gbrowse, but put the URL on the clipboard rather + than opening it. + +:[range]Gbrowse {revision} + Like :Gbrowse, but for a given |fugitive-revision|. A + useful value here is -, which ties the URL to the + latest commit rather than a volatile branch. + +:[range]Gbrowse [...]@{remote} + Force using the given remote rather than the remote + for the current branch. The remote is used to + determine which GitHub repository to link to. + +MAPPINGS *fugitive-mappings* + +These maps are available in Git objects. + + *fugitive-* + Jump to the revision under the cursor. + + *fugitive-o* +o Jump to the revision under the cursor in a new split. + + *fugitive-O* +O Jump to the revision under the cursor in a new tab. + + *fugitive-~* +~ Go to the current file in the [count]th first + ancestor. + + *fugitive-P* +P Go to the current file in the [count]th parent. + + *fugitive-C* +C Go to the commit containing the current file. + + *fugitive-a* +a Show the current tag, commit, or tree in an alternate + format. + +SPECIFYING REVISIONS *fugitive-revision* + +Fugitive revisions are similar to Git revisions as defined in the "SPECIFYING +REVISIONS" section in the git-rev-parse man page. For commands that accept an +optional revision, the default is the file in the index for work tree files +and the work tree file for everything else. Example revisions follow. + +Revision Meaning ~ +HEAD .git/HEAD +master .git/refs/heads/master +HEAD^{} The commit referenced by HEAD +HEAD^ The parent of the commit referenced by HEAD +HEAD: The tree referenced by HEAD +/HEAD The file named HEAD in the work tree +Makefile The file named Makefile in the work tree +HEAD^:Makefile The file named Makefile in the parent of HEAD +:Makefile The file named Makefile in the index (writable) +- The current file in HEAD +^ The current file in the previous commit +~3 The current file 3 commits ago +: .git/index (Same as |:Gstatus|) +:0 The current file in the index +:1 The current file's common ancestor during a conflict +:2 The current file in the target branch during a conflict +:3 The current file in the merged branch during a conflict +:/foo The most recent commit with "foo" in the message + +STATUSLINE *fugitive-statusline* + + *fugitive#statusline()* +Add %{fugitive#statusline()} to your statusline to get an indicator including +the current branch and the currently edited file's commit. If you don't have +a statusline, this one matches the default when 'ruler' is set: +> + set statusline=%<%f\ %h%m%r%{fugitive#statusline()}%=%-14.(%l,%c%V%)\ %P +< +ABOUT *fugitive-about* + +Grab the latest version or report a bug on GitHub: + +http://github.com/tpope/vim-fugitive + + vim:tw=78:et:ft=help:norl: diff --git a/.vim/bundle/vim-fugitive/plugin/fugitive.vim b/.vim/bundle/vim-fugitive/plugin/fugitive.vim new file mode 100644 index 0000000..74a4e6f --- /dev/null +++ b/.vim/bundle/vim-fugitive/plugin/fugitive.vim @@ -0,0 +1,2016 @@ +" fugitive.vim - A Git wrapper so awesome, it should be illegal +" Maintainer: Tim Pope +" Version: 1.1 +" GetLatestVimScripts: 2975 1 :AutoInstall: fugitive.vim + +if exists('g:loaded_fugitive') || &cp + finish +endif +let g:loaded_fugitive = 1 + +if !exists('g:fugitive_git_executable') + let g:fugitive_git_executable = 'git' +endif + +" Utility {{{1 + +function! s:function(name) abort + return function(substitute(a:name,'^s:',matchstr(expand(''), '\d\+_'),'')) +endfunction + +function! s:sub(str,pat,rep) abort + return substitute(a:str,'\v\C'.a:pat,a:rep,'') +endfunction + +function! s:gsub(str,pat,rep) abort + return substitute(a:str,'\v\C'.a:pat,a:rep,'g') +endfunction + +function! s:shellesc(arg) abort + if a:arg =~ '^[A-Za-z0-9_/.-]\+$' + return a:arg + elseif &shell =~# 'cmd' && a:arg !~# '"' + return '"'.a:arg.'"' + else + return shellescape(a:arg) + endif +endfunction + +function! s:fnameescape(file) abort + if exists('*fnameescape') + return fnameescape(a:file) + else + return escape(a:file," \t\n*?[{`$\\%#'\"|!<") + endif +endfunction + +function! s:throw(string) abort + let v:errmsg = 'fugitive: '.a:string + throw v:errmsg +endfunction + +function! s:warn(str) + echohl WarningMsg + echomsg a:str + echohl None + let v:warningmsg = a:str +endfunction + +function! s:shellslash(path) + if exists('+shellslash') && !&shellslash + return s:gsub(a:path,'\\','/') + else + return a:path + endif +endfunction + +function! s:add_methods(namespace, method_names) abort + for name in a:method_names + let s:{a:namespace}_prototype[name] = s:function('s:'.a:namespace.'_'.name) + endfor +endfunction + +let s:commands = [] +function! s:command(definition) abort + let s:commands += [a:definition] +endfunction + +function! s:define_commands() + for command in s:commands + exe 'command! -buffer '.command + endfor +endfunction + +function! s:compatibility_check() + if exists('b:git_dir') && exists('*GitBranchInfoCheckGitDir') && !exists('g:fugitive_did_compatibility_warning') + let g:fugitive_did_compatibility_warning = 1 + call s:warn("See http://github.com/tpope/vim-fugitive/issues#issue/1 for why you should remove git-branch-info.vim") + endif +endfunction + +augroup fugitive_utility + autocmd! + autocmd User Fugitive call s:define_commands() + autocmd VimEnter * call s:compatibility_check() +augroup END + +let s:abstract_prototype = {} + +" }}}1 +" Initialization {{{1 + +function! s:ExtractGitDir(path) abort + let path = s:shellslash(a:path) + if path =~? '^fugitive://.*//' + return matchstr(path,'fugitive://\zs.\{-\}\ze//') + endif + let fn = fnamemodify(path,':s?[\/]$??') + let ofn = "" + let nfn = fn + while fn != ofn + if isdirectory(fn . '/.git') + return s:sub(simplify(fnamemodify(fn . '/.git',':p')),'\W$','') + elseif fn =~ '\.git$' && filereadable(fn . '/HEAD') + return s:sub(simplify(fnamemodify(fn,':p')),'\W$','') + endif + let ofn = fn + let fn = fnamemodify(ofn,':h') + endwhile + return '' +endfunction + +function! s:Detect(path) + if exists('b:git_dir') && b:git_dir ==# '' + unlet b:git_dir + endif + if !exists('b:git_dir') + let dir = s:ExtractGitDir(a:path) + if dir != '' + let b:git_dir = dir + endif + endif + if exists('b:git_dir') + silent doautocmd User Fugitive + cnoremap fugitive#buffer().rev() + let buffer = fugitive#buffer() + if expand('%:p') =~# '//' + call buffer.setvar('&path',s:sub(buffer.getvar('&path'),'^\.%(,|$)','')) + endif + if b:git_dir !~# ',' && stridx(buffer.getvar('&tags'),b:git_dir.'/tags') == -1 + if &filetype != '' + call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/'.&filetype.'.tags') + endif + call buffer.setvar('&tags',buffer.getvar('&tags').','.b:git_dir.'/tags') + endif + endif +endfunction + +augroup fugitive + autocmd! + autocmd BufNewFile,BufReadPost * call s:Detect(expand(':p')) + autocmd FileType netrw call s:Detect(expand(':p')) + autocmd VimEnter * if expand('')==''|call s:Detect(getcwd())|endif + autocmd BufWinLeave * execute getwinvar(+winnr(), 'fugitive_restore') +augroup END + +" }}}1 +" Repository {{{1 + +let s:repo_prototype = {} +let s:repos = {} + +function! s:repo(...) abort + let dir = a:0 ? a:1 : (exists('b:git_dir') && b:git_dir !=# '' ? b:git_dir : s:ExtractGitDir(expand('%:p'))) + if dir !=# '' + if has_key(s:repos,dir) + let repo = get(s:repos,dir) + else + let repo = {'git_dir': dir} + let s:repos[dir] = repo + endif + return extend(extend(repo,s:repo_prototype,'keep'),s:abstract_prototype,'keep') + endif + call s:throw('not a git repository: '.expand('%:p')) +endfunction + +function! s:repo_dir(...) dict abort + return join([self.git_dir]+a:000,'/') +endfunction + +function! s:repo_tree(...) dict abort + if !self.bare() + let dir = fnamemodify(self.git_dir,':h') + return join([dir]+a:000,'/') + endif + call s:throw('no work tree') +endfunction + +function! s:repo_bare() dict abort + return self.dir() !~# '/\.git$' +endfunction + +function! s:repo_translate(spec) dict abort + if a:spec ==# '.' || a:spec ==# '/.' + return self.bare() ? self.dir() : self.tree() + elseif a:spec =~# '^/' + return fnamemodify(self.dir(),':h').a:spec + elseif a:spec =~# '^:[0-3]:' + return 'fugitive://'.self.dir().'//'.a:spec[1].'/'.a:spec[3:-1] + elseif a:spec ==# ':' + if $GIT_INDEX_FILE =~# '/[^/]*index[^/]*\.lock$' && fnamemodify($GIT_INDEX_FILE,':p')[0:strlen(s:repo().dir())] ==# s:repo().dir('') && filereadable($GIT_INDEX_FILE) + return fnamemodify($GIT_INDEX_FILE,':p') + else + return self.dir('index') + endif + elseif a:spec =~# '^:/' + let ref = self.rev_parse(matchstr(a:spec,'.[^:]*')) + return 'fugitive://'.self.dir().'//'.ref + elseif a:spec =~# '^:' + return 'fugitive://'.self.dir().'//0/'.a:spec[1:-1] + elseif a:spec =~# 'HEAD\|^refs/' && a:spec !~ ':' && filereadable(self.dir(a:spec)) + return self.dir(a:spec) + elseif filereadable(s:repo().dir('refs/'.a:spec)) + return self.dir('refs/'.a:spec) + elseif filereadable(s:repo().dir('refs/tags/'.a:spec)) + return self.dir('refs/tags/'.a:spec) + elseif filereadable(s:repo().dir('refs/heads/'.a:spec)) + return self.dir('refs/heads/'.a:spec) + elseif filereadable(s:repo().dir('refs/remotes/'.a:spec)) + return self.dir('refs/remotes/'.a:spec) + elseif filereadable(s:repo().dir('refs/remotes/'.a:spec.'/HEAD')) + return self.dir('refs/remotes/'.a:spec,'/HEAD') + else + try + let ref = self.rev_parse(matchstr(a:spec,'[^:]*')) + let path = s:sub(matchstr(a:spec,':.*'),'^:','/') + return 'fugitive://'.self.dir().'//'.ref.path + catch /^fugitive:/ + return self.tree(a:spec) + endtry + endif +endfunction + +call s:add_methods('repo',['dir','tree','bare','translate']) + +function! s:repo_git_command(...) dict abort + let git = g:fugitive_git_executable . ' --git-dir='.s:shellesc(self.git_dir) + return git.join(map(copy(a:000),'" ".s:shellesc(v:val)'),'') +endfunction + +function! s:repo_git_chomp(...) dict abort + return s:sub(system(call(self.git_command,a:000,self)),'\n$','') +endfunction + +function! s:repo_git_chomp_in_tree(...) dict abort + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd.'`=s:repo().tree()`' + return call(s:repo().git_chomp, a:000, s:repo()) + finally + execute cd.'`=dir`' + endtry +endfunction + +function! s:repo_rev_parse(rev) dict abort + let hash = self.git_chomp('rev-parse','--verify',a:rev) + if hash =~ '\<\x\{40\}$' + return matchstr(hash,'\<\x\{40\}$') + endif + call s:throw('rev-parse '.a:rev.': '.hash) +endfunction + +call s:add_methods('repo',['git_command','git_chomp','git_chomp_in_tree','rev_parse']) + +function! s:repo_dirglob(base) dict abort + let base = s:sub(a:base,'^/','') + let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*/')),"\n") + call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]') + return matches +endfunction + +function! s:repo_superglob(base) dict abort + if a:base =~# '^/' || a:base !~# ':' + let results = [] + if a:base !~# '^/' + let heads = ["HEAD","ORIG_HEAD","FETCH_HEAD","MERGE_HEAD"] + let heads += sort(split(s:repo().git_chomp("rev-parse","--symbolic","--branches","--tags","--remotes"),"\n")) + call filter(heads,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base') + let results += heads + endif + if !self.bare() + let base = s:sub(a:base,'^/','') + let matches = split(glob(self.tree(s:gsub(base,'/','*&').'*')),"\n") + call map(matches,'s:shellslash(v:val)') + call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val') + call map(matches,'v:val[ strlen(self.tree())+(a:base !~ "^/") : -1 ]') + let results += matches + endif + return results + + elseif a:base =~# '^:' + let entries = split(self.git_chomp('ls-files','--stage'),"\n") + call map(entries,'s:sub(v:val,".*(\\d)\\t(.*)",":\\1:\\2")') + if a:base !~# '^:[0-3]\%(:\|$\)' + call filter(entries,'v:val[1] == "0"') + call map(entries,'v:val[2:-1]') + endif + call filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base') + return entries + + else + let tree = matchstr(a:base,'.*[:/]') + let entries = split(self.git_chomp('ls-tree',tree),"\n") + call map(entries,'s:sub(v:val,"^04.*\\zs$","/")') + call map(entries,'tree.s:sub(v:val,".*\t","")') + return filter(entries,'v:val[ 0 : strlen(a:base)-1 ] ==# a:base') + endif +endfunction + +call s:add_methods('repo',['dirglob','superglob']) + +function! s:repo_keywordprg() dict abort + let args = ' --git-dir='.escape(self.dir(),"\\\"' ").' show' + if has('gui_running') && !has('win32') + return g:fugitive_git_executable . ' --no-pager' . args + else + return g:fugitive_git_executable . args + endif +endfunction + +call s:add_methods('repo',['keywordprg']) + +" }}}1 +" Buffer {{{1 + +let s:buffer_prototype = {} + +function! s:buffer(...) abort + let buffer = {'#': bufnr(a:0 ? a:1 : '%')} + call extend(extend(buffer,s:buffer_prototype,'keep'),s:abstract_prototype,'keep') + if buffer.getvar('git_dir') !=# '' + return buffer + endif + call s:throw('not a git repository: '.expand('%:p')) +endfunction + +function! fugitive#buffer(...) abort + return s:buffer(a:0 ? a:1 : '%') +endfunction + +function! s:buffer_getvar(var) dict abort + return getbufvar(self['#'],a:var) +endfunction + +function! s:buffer_setvar(var,value) dict abort + return setbufvar(self['#'],a:var,a:value) +endfunction + +function! s:buffer_getline(lnum) dict abort + return getbufline(self['#'],a:lnum)[0] +endfunction + +function! s:buffer_repo() dict abort + return s:repo(self.getvar('git_dir')) +endfunction + +function! s:buffer_type(...) dict abort + if self.getvar('fugitive_type') != '' + let type = self.getvar('fugitive_type') + elseif fnamemodify(self.spec(),':p') =~# '.\git/refs/\|\.git/\w*HEAD$' + let type = 'head' + elseif self.getline(1) =~ '^tree \x\{40\}$' && self.getline(2) == '' + let type = 'tree' + elseif self.getline(1) =~ '^\d\{6\} \w\{4\} \x\{40\}\>\t' + let type = 'tree' + elseif self.getline(1) =~ '^\d\{6\} \x\{40\}\> \d\t' + let type = 'index' + elseif isdirectory(self.spec()) + let type = 'directory' + elseif self.spec() == '' + let type = 'null' + elseif filereadable(self.spec()) + let type = 'file' + else + let type = '' + endif + if a:0 + return !empty(filter(copy(a:000),'v:val ==# type')) + else + return type + endif +endfunction + +if has('win32') + + function! s:buffer_spec() dict abort + let bufname = bufname(self['#']) + let retval = '' + for i in split(bufname,'[^:]\zs\\') + let retval = fnamemodify((retval==''?'':retval.'\').i,':.') + endfor + return s:shellslash(fnamemodify(retval,':p')) + endfunction + +else + + function! s:buffer_spec() dict abort + let bufname = bufname(self['#']) + return s:shellslash(bufname == '' ? '' : fnamemodify(bufname,':p')) + endfunction + +endif + +function! s:buffer_name() dict abort + return self.spec() +endfunction + +function! s:buffer_commit() dict abort + return matchstr(self.spec(),'^fugitive://.\{-\}//\zs\w*') +endfunction + +function! s:buffer_path(...) dict abort + let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*') + if rev != '' + let rev = s:sub(rev,'\w*','') + else + let rev = self.spec()[strlen(self.repo().tree()) : -1] + endif + return s:sub(s:sub(rev,'.\zs/$',''),'^/',a:0 ? a:1 : '') +endfunction + +function! s:buffer_rev() dict abort + let rev = matchstr(self.spec(),'^fugitive://.\{-\}//\zs.*') + if rev =~ '^\x/' + return ':'.rev[0].':'.rev[2:-1] + elseif rev =~ '.' + return s:sub(rev,'/',':') + elseif self.spec() =~ '\.git/index$' + return ':' + elseif self.spec() =~ '\.git/refs/\|\.git/.*HEAD$' + return self.spec()[strlen(self.repo().dir())+1 : -1] + else + return self.path() + endif +endfunction + +function! s:buffer_sha1() dict abort + if self.spec() =~ '^fugitive://' || self.spec() =~ '\.git/refs/\|\.git/.*HEAD$' + return self.repo().rev_parse(self.rev()) + else + return '' + endif +endfunction + +function! s:buffer_expand(rev) dict abort + if a:rev =~# '^:[0-3]$' + let file = a:rev.self.path(':') + elseif a:rev =~# '^[-:]/$' + let file = '/'.self.path() + elseif a:rev =~# '^-' + let file = 'HEAD^{}'.a:rev[1:-1].self.path(':') + elseif a:rev =~# '^@{' + let file = 'HEAD'.a:rev.self.path(':') + elseif a:rev =~# '^[~^]' + let commit = s:sub(self.commit(),'^\d=$','HEAD') + let file = commit.a:rev.self.path(':') + else + let file = a:rev + endif + return s:sub(s:sub(file,'\%$',self.path()),'\.\@<=/$','') +endfunction + +function! s:buffer_containing_commit() dict abort + if self.commit() =~# '^\d$' + return ':' + elseif self.commit() =~# '.' + return self.commit() + else + return 'HEAD' + endif +endfunction + +call s:add_methods('buffer',['getvar','setvar','getline','repo','type','spec','name','commit','path','rev','sha1','expand','containing_commit']) + +" }}}1 +" Git {{{1 + +call s:command("-bang -nargs=? -complete=customlist,s:GitComplete Git :execute s:Git(0,)") + +function! s:ExecuteInTree(cmd) abort + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd.'`=s:repo().tree()`' + execute a:cmd + finally + execute cd.'`=dir`' + endtry +endfunction + +function! s:Git(bang,cmd) abort + let git = s:repo().git_command() + if has('gui_running') && !has('win32') + let git .= ' --no-pager' + endif + let cmd = matchstr(a:cmd,'\v\C.{-}%($|\\@ `=s:repo().bare() ? s:repo().dir() : s:repo().tree()`") +call s:command("-bar -bang -nargs=? -complete=customlist,s:DirComplete Glcd :lcd `=s:repo().bare() ? s:repo().dir() : s:repo().tree()`") + +" }}}1 +" Gstatus {{{1 + +call s:command("-bar Gstatus :execute s:Status()") + +function! s:Status() abort + try + Gpedit : + wincmd P + nnoremap q :bdelete + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry + return '' +endfunction + +function! fugitive#reload_status() abort + let mytab = tabpagenr() + for tab in [mytab] + range(1,tabpagenr('$')) + for winnr in range(1,tabpagewinnr(tab,'$')) + if getbufvar(tabpagebuflist(tab)[winnr-1],'fugitive_type') ==# 'index' + execute 'tabnext '.tab + if winnr != winnr() + execute winnr.'wincmd w' + let restorewinnr = 1 + endif + try + if !&modified + call s:BufReadIndex() + endif + finally + if exists('restorewinnr') + wincmd p + endif + execute 'tabnext '.mytab + endtry + endif + endfor + endfor +endfunction + +function! s:StageDiff(...) abort + let cmd = a:0 ? a:1 : 'Gdiff' + let section = getline(search('^# .*:$','bnW')) + let line = getline('.') + let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$') + if filename ==# '' && section == '# Changes to be committed:' + return 'Git diff --cached' + elseif filename ==# '' + return 'Git diff' + elseif line =~# '^#\trenamed:' && filename =~ ' -> ' + let [old, new] = split(filename,' -> ') + execute 'Gedit '.s:fnameescape(':0:'.new) + return cmd.' HEAD:'.s:fnameescape(old) + elseif section == '# Changes to be committed:' + execute 'Gedit '.s:fnameescape(':0:'.filename) + return cmd.' -' + else + execute 'Gedit '.s:fnameescape('/'.filename) + return cmd + endif +endfunction + +function! s:StageToggle(lnum1,lnum2) abort + try + let output = '' + for lnum in range(a:lnum1,a:lnum2) + let line = getline(lnum) + if getline('.') == '# Changes to be committed:' + return 'Gcommit' + endif + let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$') + if filename ==# '' + continue + endif + if !exists('first_filename') + let first_filename = filename + endif + execute lnum + let section = getline(search('^# .*:$','bnW')) + if line =~# '^#\trenamed:' && filename =~ ' -> ' + let cmd = ['mv','--'] + reverse(split(filename,' -> ')) + let filename = cmd[-1] + elseif section =~? ' to be ' + let cmd = ['reset','-q','--',filename] + elseif line =~# '^#\tdeleted:' + let cmd = ['rm','--',filename] + else + let cmd = ['add','--',filename] + endif + let output .= call(s:repo().git_chomp_in_tree,cmd,s:repo())."\n" + endfor + if exists('first_filename') + let jump = first_filename + let f = matchstr(getline(a:lnum1-1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*') + if f !=# '' | let jump = f | endif + let f = matchstr(getline(a:lnum2+1),'^#\t\%([[:alpha:] ]\+: *\)\=\zs.*') + if f !=# '' | let jump = f | endif + silent! edit! + 1 + redraw + call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.jump.'\%( (new commits)\)\=\$','W') + endif + echo s:sub(s:gsub(output,'\n+','\n'),'\n$','') + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry + return 'checktime' +endfunction + +function! s:StagePatch(lnum1,lnum2) abort + let add = [] + let reset = [] + + for lnum in range(a:lnum1,a:lnum2) + let line = getline(lnum) + if line == '# Changes to be committed:' + return 'Git reset --patch' + elseif line == '# Changed but not updated:' + return 'Git add --patch' + endif + let filename = matchstr(line,'^#\t\%([[:alpha:] ]\+: *\)\=\zs.\{-\}\ze\%( (new commits)\)\=$') + if filename ==# '' + continue + endif + if !exists('first_filename') + let first_filename = filename + endif + execute lnum + let section = getline(search('^# .*:$','bnW')) + if line =~# '^#\trenamed:' && filename =~ ' -> ' + let reset += [split(filename,' -> ')[1]] + elseif section =~? ' to be ' + let reset += [filename] + elseif line !~# '^#\tdeleted:' + let add += [filename] + endif + endfor + try + if !empty(add) + execute "Git add --patch -- ".join(map(add,'s:shellesc(v:val)')) + endif + if !empty(reset) + execute "Git reset --patch -- ".join(map(add,'s:shellesc(v:val)')) + endif + if exists('first_filename') + silent! edit! + 1 + redraw + call search('^#\t\%([[:alpha:] ]\+: *\)\=\V'.first_filename.'\%( (new commits)\)\=\$','W') + endif + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry + return 'checktime' +endfunction + +" }}}1 +" Gcommit {{{1 + +call s:command("-nargs=? -complete=customlist,s:CommitComplete Gcommit :execute s:Commit()") + +function! s:Commit(args) abort + let old_type = s:buffer().type() + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + let msgfile = s:repo().dir('COMMIT_EDITMSG') + let outfile = tempname() + let errorfile = tempname() + try + execute cd.'`=s:repo().tree()`' + let command = '' + if &shell =~# 'cmd' + let old_editor = $GIT_EDITOR + let $GIT_EDITOR = 'false' + elseif &shell !~# 'csh' + let command = 'GIT_EDITOR=false ' + endif + let command .= s:repo().git_command('commit').' '.a:args + if &shell =~# 'csh' + silent execute '!setenv GIT_EDITOR false; ('.command.' > '.outfile.') >& '.errorfile + elseif a:args =~# '\%(^\| \)--interactive\>' + execute '!'.command.' 2> '.errorfile + else + silent execute '!'.command.' > '.outfile.' 2> '.errorfile + endif + if !v:shell_error + if filereadable(outfile) + for line in readfile(outfile) + echo line + endfor + endif + return '' + else + let errors = readfile(errorfile) + let error = get(errors,-2,get(errors,-1,'!')) + if error =~# "'false'\\.$" + let args = a:args + let args = s:gsub(args,'%(%(^| )-- )@' + let args = '--cleanup=strip '.args + endif + if bufname('%') == '' && line('$') == 1 && getline(1) == '' && !&mod + edit `=msgfile` + else + split `=msgfile` + endif + if old_type ==# 'index' + bdelete # + endif + let b:fugitive_commit_arguments = args + setlocal bufhidden=delete filetype=gitcommit + return '1' + elseif error ==# '!' + return s:Status() + else + call s:throw(error) + endif + endif + catch /^fugitive:/ + return 'echoerr v:errmsg' + finally + if exists('old_editor') + let $GIT_EDITOR = old_editor + endif + call delete(outfile) + call delete(errorfile) + execute cd.'`=dir`' + call fugitive#reload_status() + endtry +endfunction + +function! s:CommitComplete(A,L,P) abort + if a:A =~ '^-' || type(a:A) == type(0) " a:A is 0 on :Gcommit - + let args = ['-C', '-F', '-a', '-c', '-e', '-i', '-m', '-n', '-o', '-q', '-s', '-t', '-u', '-v', '--all', '--allow-empty', '--amend', '--author=', '--cleanup=', '--dry-run', '--edit', '--file=', '--include', '--interactive', '--message=', '--no-verify', '--only', '--quiet', '--reedit-message=', '--reuse-message=', '--signoff', '--template=', '--untracked-files', '--verbose'] + return filter(args,'v:val[0 : strlen(a:A)-1] ==# a:A') + else + return s:repo().superglob(a:A) + endif +endfunction + +function! s:FinishCommit() + let args = getbufvar(+expand(''),'fugitive_commit_arguments') + if !empty(args) + call setbufvar(+expand(''),'fugitive_commit_arguments','') + return s:Commit(args) + endif + return '' +endfunction + +augroup fugitive_commit + autocmd! + autocmd VimLeavePre,BufDelete *.git/COMMIT_EDITMSG execute s:sub(s:FinishCommit(), '^echoerr (.*)', 'echohl ErrorMsg|echo \1|echohl NONE') +augroup END + +" }}}1 +" Ggrep, Glog {{{1 + +if !exists('g:fugitive_summary_format') + let g:fugitive_summary_format = '%s' +endif + +call s:command("-bang -nargs=? -complete=customlist,s:EditComplete Ggrep :execute s:Grep(0,)") +call s:command("-bar -bang -nargs=* -complete=customlist,s:EditComplete Glog :execute s:Log('grep',)") + +function! s:Grep(bang,arg) abort + let grepprg = &grepprg + let grepformat = &grepformat + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd.'`=s:repo().tree()`' + let &grepprg = s:repo().git_command('--no-pager', 'grep', '-n') + let &grepformat = '%f:%l:%m' + exe 'grep! '.escape(matchstr(a:arg,'\v\C.{-}%($|[''" ]\@=\|)@='),'|') + let list = getqflist() + for entry in list + if bufname(entry.bufnr) =~ ':' + let entry.filename = s:repo().translate(bufname(entry.bufnr)) + unlet! entry.bufnr + elseif a:arg =~# '\%(^\| \)--cached\>' + let entry.filename = s:repo().translate(':0:'.bufname(entry.bufnr)) + unlet! entry.bufnr + endif + endfor + call setqflist(list,'r') + if !a:bang && !empty(list) + return 'cfirst'.matchstr(a:arg,'\v\C[''" ]\zs\|.*') + else + return matchstr(a:arg,'\v\C[''" ]\|\zs.*') + endif + finally + let &grepprg = grepprg + let &grepformat = grepformat + execute cd.'`=dir`' + endtry +endfunction + +function! s:Log(cmd,...) + let path = s:buffer().path('/') + if path =~# '^/\.git\%(/\|$\)' || index(a:000,'--') != -1 + let path = '' + endif + let cmd = ['--no-pager', 'log', '--no-color'] + let cmd += [escape('--pretty=format:fugitive://'.s:repo().dir().'//%H'.path.'::'.g:fugitive_summary_format,'%')] + if empty(filter(a:000[0 : index(a:000,'--')],'v:val !~# "^-"')) + if s:buffer().commit() =~# '\x\{40\}' + let cmd += [s:buffer().commit()] + elseif s:buffer().path() =~# '^\.git/refs/\|^\.git/.*HEAD$' + let cmd += [s:buffer().path()[5:-1]] + endif + end + let cmd += map(copy(a:000),'s:sub(v:val,"^\\%(%(:\\w)*)","\\=fnamemodify(s:buffer().path(),submatch(1))")') + if path =~# '/.' + let cmd += ['--',path[1:-1]] + endif + let grepformat = &grepformat + let grepprg = &grepprg + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd.'`=s:repo().tree()`' + let &grepprg = call(s:repo().git_command,cmd,s:repo()) + let &grepformat = '%f::%m' + exe a:cmd + finally + let &grepformat = grepformat + let &grepprg = grepprg + execute cd.'`=dir`' + endtry +endfunction + +" }}}1 +" Gedit, Gpedit, Gsplit, Gvsplit, Gtabedit, Gread {{{1 + +function! s:Edit(cmd,...) abort + if a:0 && a:1 == '' + return '' + elseif a:0 + let file = s:buffer().expand(a:1) + elseif s:buffer().commit() ==# '' && s:buffer().path('/') !~# '^/.git\>' + let file = s:buffer().path(':') + else + let file = s:buffer().path('/') + endif + try + let file = s:repo().translate(file) + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry + if a:cmd ==# 'read' + return 'silent %delete_|read '.s:fnameescape(file).'|silent 1delete_|diffupdate|'.line('.') + else + if &previewwindow && getbufvar('','fugitive_type') ==# 'index' + wincmd p + endif + return a:cmd.' '.s:fnameescape(file) + endif +endfunction + +function! s:EditComplete(A,L,P) abort + return s:repo().superglob(a:A) +endfunction + +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Ge :execute s:Edit('edit',)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gedit :execute s:Edit('edit',)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gpedit :execute s:Edit('pedit',)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gsplit :execute s:Edit('split',)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gvsplit :execute s:Edit('vsplit',)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gtabedit :execute s:Edit('tabedit',)") +call s:command("-bar -bang -nargs=? -count -complete=customlist,s:EditComplete Gread :execute s:Edit((! && ? '' : ).'read',)") + +" }}}1 +" Gwrite, Gwq {{{1 + +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwrite :execute s:Write(0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gw :execute s:Write(0,)") +call s:command("-bar -bang -nargs=? -complete=customlist,s:EditComplete Gwq :execute s:Wq(0,)") + +function! s:Write(force,...) abort + if exists('b:fugitive_commit_arguments') + return 'write|bdelete' + elseif expand('%:t') == 'COMMIT_EDITMSG' && $GIT_INDEX_FILE != '' + return 'wq' + elseif s:buffer().type() == 'index' + return 'Gcommit' + endif + let mytab = tabpagenr() + let mybufnr = bufnr('') + let path = a:0 ? a:1 : s:buffer().path() + if path =~# '^:\d\>' + return 'write'.(a:force ? '! ' : ' ').s:fnameescape(s:repo().translate(s:buffer().expand(path))) + endif + let always_permitted = (s:buffer().path() ==# path && s:buffer().commit() =~# '^0\=$') + if !always_permitted && !a:force && s:repo().git_chomp_in_tree('diff','--name-status','HEAD','--',path) . s:repo().git_chomp_in_tree('ls-files','--others','--',path) !=# '' + let v:errmsg = 'fugitive: file has uncommitted changes (use ! to override)' + return 'echoerr v:errmsg' + endif + let file = s:repo().translate(path) + let treebufnr = 0 + for nr in range(1,bufnr('$')) + if fnamemodify(bufname(nr),':p') ==# file + let treebufnr = nr + endif + endfor + + if treebufnr > 0 && treebufnr != bufnr('') + let temp = tempname() + silent execute '%write '.temp + for tab in [mytab] + range(1,tabpagenr('$')) + for winnr in range(1,tabpagewinnr(tab,'$')) + if tabpagebuflist(tab)[winnr-1] == treebufnr + execute 'tabnext '.tab + if winnr != winnr() + execute winnr.'wincmd w' + let restorewinnr = 1 + endif + try + let lnum = line('.') + let last = line('$') + silent execute '$read '.temp + silent execute '1,'.last.'delete_' + silent write! + silent execute lnum + let did = 1 + finally + if exists('restorewinnr') + wincmd p + endif + execute 'tabnext '.mytab + endtry + endif + endfor + endfor + if !exists('did') + call writefile(readfile(temp,'b'),file,'b') + endif + else + execute 'write! '.s:fnameescape(s:repo().translate(path)) + endif + + if a:force + let error = s:repo().git_chomp_in_tree('add', '--force', file) + else + let error = s:repo().git_chomp_in_tree('add', file) + endif + if v:shell_error + let v:errmsg = 'fugitive: '.error + return 'echoerr v:errmsg' + endif + if s:buffer().path() ==# path && s:buffer().commit() =~# '^\d$' + set nomodified + endif + + let one = s:repo().translate(':1:'.path) + let two = s:repo().translate(':2:'.path) + let three = s:repo().translate(':3:'.path) + for nr in range(1,bufnr('$')) + if bufloaded(nr) && !getbufvar(nr,'&modified') && (bufname(nr) == one || bufname(nr) == two || bufname(nr) == three) + execute nr.'bdelete' + endif + endfor + + unlet! restorewinnr + let zero = s:repo().translate(':0:'.path) + for tab in range(1,tabpagenr('$')) + for winnr in range(1,tabpagewinnr(tab,'$')) + let bufnr = tabpagebuflist(tab)[winnr-1] + let bufname = bufname(bufnr) + if bufname ==# zero && bufnr != mybufnr + execute 'tabnext '.tab + if winnr != winnr() + execute winnr.'wincmd w' + let restorewinnr = 1 + endif + try + let lnum = line('.') + let last = line('$') + silent $read `=file` + silent execute '1,'.last.'delete_' + silent execute lnum + set nomodified + diffupdate + finally + if exists('restorewinnr') + wincmd p + endif + execute 'tabnext '.mytab + endtry + break + endif + endfor + endfor + call fugitive#reload_status() + return 'checktime' +endfunction + +function! s:Wq(force,...) abort + let bang = a:force ? '!' : '' + if exists('b:fugitive_commit_arguments') + return 'wq'.bang + endif + let result = call(s:function('s:Write'),[a:force]+a:000) + if result =~# '^\%(write\|wq\|echoerr\)' + return s:sub(result,'^write','wq') + else + return result.'|quit'.bang + endif +endfunction + +" }}}1 +" Gdiff {{{1 + +call s:command("-bang -bar -nargs=? -complete=customlist,s:EditComplete Gdiff :execute s:Diff(0,)") +call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gvdiff :execute s:Diff(0,)") +call s:command("-bar -nargs=? -complete=customlist,s:EditComplete Gsdiff :execute s:Diff(1,)") + +augroup fugitive_diff + autocmd! + autocmd BufWinLeave * if s:diff_window_count() == 2 && &diff && getbufvar(+expand(''), 'git_dir') !=# '' | call s:diff_off_all(getbufvar(+expand(''), 'git_dir')) | endif + autocmd BufWinEnter * if s:diff_window_count() == 1 && &diff && getbufvar(+expand(''), 'git_dir') !=# '' | diffoff | endif +augroup END + +function! s:diff_window_count() + let c = 0 + for nr in range(1,winnr('$')) + let c += getwinvar(nr,'&diff') + endfor + return c +endfunction + +function! s:diff_off_all(dir) + for nr in range(1,winnr('$')) + if getwinvar(nr,'&diff') + if nr != winnr() + execute nr.'wincmd w' + let restorewinnr = 1 + endif + if exists('b:git_dir') && b:git_dir ==# a:dir + diffoff + endif + if exists('restorewinnr') + wincmd p + endif + endif + endfor +endfunction + +function! s:buffer_compare_age(commit) dict abort + let scores = {':0': 1, ':1': 2, ':2': 3, ':': 4, ':3': 5} + let my_score = get(scores,':'.self.commit(),0) + let their_score = get(scores,':'.a:commit,0) + if my_score || their_score + return my_score < their_score ? -1 : my_score != their_score + elseif self.commit() ==# a:commit + return 0 + endif + let base = self.repo().git_chomp('merge-base',self.commit(),a:commit) + if base ==# self.commit() + return -1 + elseif base ==# a:commit + return 1 + endif + let my_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',self.commit()) + let their_time = +self.repo().git_chomp('log','--max-count=1','--pretty=format:%at',a:commit) + return my_time < their_time ? -1 : my_time != their_time +endfunction + +call s:add_methods('buffer',['compare_age']) + +function! s:Diff(bang,...) abort + let split = a:bang ? 'split' : 'vsplit' + if exists(':DiffGitCached') + return 'DiffGitCached' + elseif (!a:0 || a:1 == ':') && s:buffer().commit() =~# '^[0-1]\=$' && s:repo().git_chomp_in_tree('ls-files', '--unmerged', '--', s:buffer().path()) !=# '' + execute 'leftabove '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':2''))`' + diffthis + wincmd p + execute 'rightbelow '.split.' `=fugitive#buffer().repo().translate(s:buffer().expand('':3''))`' + diffthis + wincmd p + diffthis + return '' + elseif a:0 + if a:1 ==# '' + return '' + elseif a:1 ==# '/' + let file = s:buffer().path('/') + elseif a:1 ==# ':' + let file = s:buffer().path(':0:') + elseif a:1 =~# '^:/.' + try + let file = s:repo().rev_parse(a:1).s:buffer().path(':') + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry + else + let file = s:buffer().expand(a:1) + endif + if file !~# ':' && file !~# '^/' && s:repo().git_chomp('cat-file','-t',file) =~# '^\%(tag\|commit\)$' + let file = file.s:buffer().path(':') + endif + else + let file = s:buffer().path(s:buffer().commit() == '' ? ':0:' : '/') + endif + try + let spec = s:repo().translate(file) + let commit = matchstr(spec,'\C[^:/]//\zs\x\+') + if s:buffer().compare_age(commit) < 0 + execute 'rightbelow '.split.' `=spec`' + else + execute 'leftabove '.split.' `=spec`' + endif + diffthis + wincmd p + diffthis + return '' + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +" }}}1 +" Gmove, Gremove {{{1 + +function! s:Move(force,destination) + if a:destination =~# '^/' + let destination = a:destination[1:-1] + else + let destination = fnamemodify(s:sub(a:destination,'[%#]%(:\w)*','\=expand(submatch(0))'),':p') + if destination[0:strlen(s:repo().tree())] ==# s:repo().tree('') + let destination = destination[strlen(s:repo().tree('')):-1] + endif + endif + if isdirectory(s:buffer().name()) + " Work around Vim parser idiosyncrasy + let b = s:buffer() + call b.setvar('&swapfile',0) + endif + let message = call(s:repo().git_chomp_in_tree,['mv']+(a:force ? ['-f'] : [])+['--', s:buffer().path(), destination], s:repo()) + if v:shell_error + let v:errmsg = 'fugitive: '.message + return 'echoerr v:errmsg' + endif + let destination = s:repo().tree(destination) + if isdirectory(destination) + let destination = fnamemodify(s:sub(destination,'/$','').'/'.expand('%:t'),':.') + endif + call fugitive#reload_status() + if s:buffer().commit() == '' + if isdirectory(destination) + return 'edit '.s:fnameescape(destination) + else + return 'saveas! '.s:fnameescape(destination) + endif + else + return 'file '.s:fnameescape(s:repo().translate(':0:'.destination) + endif +endfunction + +function! s:MoveComplete(A,L,P) + if a:A =~ '^/' + return s:repo().superglob(a:A) + else + let matches = split(glob(a:A.'*'),"\n") + call map(matches,'v:val !~ "/$" && isdirectory(v:val) ? v:val."/" : v:val') + return matches + endif +endfunction + +function! s:Remove(force) + if s:buffer().commit() ==# '' + let cmd = ['rm'] + elseif s:buffer().commit() ==# '0' + let cmd = ['rm','--cached'] + else + let v:errmsg = 'fugitive: rm not supported here' + return 'echoerr v:errmsg' + endif + if a:force + let cmd += ['--force'] + endif + let message = call(s:repo().git_chomp_in_tree,cmd+['--',s:buffer().path()],s:repo()) + if v:shell_error + let v:errmsg = 'fugitive: '.s:sub(message,'error:.*\zs\n\(.*-f.*',' (add ! to force)') + return 'echoerr '.string(v:errmsg) + else + call fugitive#reload_status() + return 'bdelete'.(a:force ? '!' : '') + endif +endfunction + +augroup fugitive_remove + autocmd! + autocmd User Fugitive if s:buffer().commit() =~# '^0\=$' | + \ exe "command! -buffer -bar -bang -nargs=1 -complete=customlist,s:MoveComplete Gmove :execute s:Move(0,)" | + \ exe "command! -buffer -bar -bang Gremove :execute s:Remove(0)" | + \ endif +augroup END + +" }}}1 +" Gblame {{{1 + +augroup fugitive_blame + autocmd! + autocmd BufReadPost *.fugitiveblame setfiletype fugitiveblame + autocmd FileType fugitiveblame setlocal nomodeline | if exists('b:git_dir') | let &l:keywordprg = s:repo().keywordprg() | endif + autocmd Syntax fugitiveblame call s:BlameSyntax() + autocmd User Fugitive if s:buffer().type('file', 'blob') | exe "command! -buffer -bar -bang -range=0 -nargs=* Gblame :execute s:Blame(0,,,,[])" | endif +augroup END + +function! s:Blame(bang,line1,line2,count,args) abort + try + if s:buffer().path() == '' + call s:throw('file or blob required') + endif + if filter(copy(a:args),'v:val !~# "^\\%(--root\|--show-name\\|-\\=\\%([ltwfs]\\|[MC]\\d*\\)\\+\\)$"') != [] + call s:throw('unsupported option') + endif + call map(a:args,'s:sub(v:val,"^\\ze[^-]","-")') + let git_dir = s:repo().dir() + let cmd = ['--no-pager', 'blame', '--show-number'] + a:args + if s:buffer().commit() =~# '\D\|..' + let cmd += [s:buffer().commit()] + else + let cmd += ['--contents', '-'] + endif + let basecmd = call(s:repo().git_command,cmd+['--',s:buffer().path()],s:repo()) + try + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + if !s:repo().bare() + let dir = getcwd() + execute cd.'`=s:repo().tree()`' + endif + if a:count + execute 'write !'.substitute(basecmd,' blame ',' blame -L '.a:line1.','.a:line2.' ','g') + else + let error = tempname() + let temp = error.'.fugitiveblame' + if &shell =~# 'csh' + silent! execute '%write !('.basecmd.' > '.temp.') >& '.error + else + silent! execute '%write !'.basecmd.' > '.temp.' 2> '.error + endif + if exists('l:dir') + execute cd.'`=dir`' + unlet dir + endif + if v:shell_error + call s:throw(join(readfile(error),"\n")) + endif + let bufnr = bufnr('') + let restore = 'call setwinvar(bufwinnr('.bufnr.'),"&scrollbind",0)' + if &l:wrap + let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&wrap",1)' + endif + if &l:foldenable + let restore .= '|call setwinvar(bufwinnr('.bufnr.'),"&foldenable",1)' + endif + let winnr = winnr() + windo set noscrollbind + exe winnr.'wincmd w' + setlocal scrollbind nowrap nofoldenable + let top = line('w0') + &scrolloff + let current = line('.') + exe 'leftabove vsplit '.temp + let b:git_dir = git_dir + let b:fugitive_type = 'blame' + let b:fugitive_blamed_bufnr = bufnr + let w:fugitive_restore = restore + let b:fugitive_blame_arguments = join(a:args,' ') + call s:Detect(expand('%:p')) + execute top + normal! zt + execute current + execute "vertical resize ".(match(getline('.'),'\s\+\d\+)')+1) + setlocal nomodified nomodifiable bufhidden=delete nonumber scrollbind nowrap foldcolumn=0 nofoldenable filetype=fugitiveblame + nnoremap q :bdelete + nnoremap :exe BlameJump('') + nnoremap P :exe BlameJump('^'.v:count1) + nnoremap ~ :exe BlameJump('~'.v:count1) + nnoremap o :exe Edit((&splitbelow ? "botright" : "topleft")." split", matchstr(getline('.'),'\x\+')) + nnoremap O :exe Edit("tabedit", matchstr(getline('.'),'\x\+')) + syncbind + endif + finally + if exists('l:dir') + execute cd.'`=dir`' + endif + endtry + return '' + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +function! s:BlameJump(suffix) abort + let commit = matchstr(getline('.'),'^\^\=\zs\x\+') + if commit =~# '^0\+$' + let commit = ':0' + endif + let lnum = matchstr(getline('.'),'\d\+\ze\s\+[([:digit:]]') + let path = matchstr(getline('.'),'^\^\=\zs\x\+\s\+\zs.\{-\}\ze\s*\d\+ ') + if path ==# '' + let path = s:buffer(b:fugitive_blamed_bufnr).path() + endif + let args = b:fugitive_blame_arguments + let offset = line('.') - line('w0') + let bufnr = bufnr('%') + let winnr = bufwinnr(b:fugitive_blamed_bufnr) + if winnr > 0 + exe winnr.'wincmd w' + endif + execute s:Edit('edit',commit.a:suffix.':'.path) + if winnr > 0 + exe bufnr.'bdelete' + endif + execute 'Gblame '.args + execute lnum + let delta = line('.') - line('w0') - offset + if delta > 0 + execute 'norm! 'delta."\" + elseif delta < 0 + execute 'norm! '(-delta)."\" + endif + syncbind + return '' +endfunction + +function! s:BlameSyntax() abort + let b:current_syntax = 'fugitiveblame' + syn match FugitiveblameBoundary "^\^" + syn match FugitiveblameBlank "^\s\+\s\@=" nextgroup=FugitiveblameAnnotation,fugitiveblameOriginalFile,FugitiveblameOriginalLineNumber skipwhite + syn match FugitiveblameHash "\%(^\^\=\)\@<=\x\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite + syn match FugitiveblameUncommitted "\%(^\^\=\)\@<=0\{7,40\}\>" nextgroup=FugitiveblameAnnotation,FugitiveblameOriginalLineNumber,fugitiveblameOriginalFile skipwhite + syn region FugitiveblameAnnotation matchgroup=FugitiveblameDelimiter start="(" end="\%( \d\+\)\@<=)" contained keepend oneline + syn match FugitiveblameTime "[0-9:/+-][0-9:/+ -]*[0-9:/+-]\%( \+\d\+)\)\@=" contained containedin=FugitiveblameAnnotation + syn match FugitiveblameLineNumber " \@<=\d\+)\@=" contained containedin=FugitiveblameAnnotation + syn match FugitiveblameOriginalFile " \%(\f\+\D\@<=\|\D\@=\f\+\)\%(\%(\s\+\d\+\)\=\s\%((\|\s*\d\+)\)\)\@=" contained nextgroup=FugitiveblameOriginalLineNumber,FugitiveblameAnnotation skipwhite + syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s(\)\@=" contained nextgroup=FugitiveblameAnnotation skipwhite + syn match FugitiveblameOriginalLineNumber " \@<=\d\+\%(\s\+\d\+)\)\@=" contained nextgroup=FugitiveblameShort skipwhite + syn match FugitiveblameShort "\d\+)" contained contains=FugitiveblameLineNumber + syn match FugitiveblameNotCommittedYet "(\@<=Not Committed Yet\>" contained containedin=FugitiveblameAnnotation + hi def link FugitiveblameBoundary Keyword + hi def link FugitiveblameHash Identifier + hi def link FugitiveblameUncommitted Function + hi def link FugitiveblameTime PreProc + hi def link FugitiveblameLineNumber Number + hi def link FugitiveblameOriginalFile String + hi def link FugitiveblameOriginalLineNumber Float + hi def link FugitiveblameShort FugitiveblameDelimiter + hi def link FugitiveblameDelimiter Delimiter + hi def link FugitiveblameNotCommittedYet Comment +endfunction + +" }}}1 +" Gbrowse {{{1 + +call s:command("-bar -bang -count=0 -nargs=? -complete=customlist,s:EditComplete Gbrowse :execute s:Browse(0,,,)") + +function! s:Browse(bang,line1,count,...) abort + try + let rev = a:0 ? substitute(a:1,'@[[:alnum:]_-]*\%(://.\{-\}\)\=$','','') : '' + if rev ==# '' + let expanded = s:buffer().rev() + elseif rev ==# ':' + let expanded = s:buffer().path('/') + else + let expanded = s:buffer().expand(rev) + endif + let full = s:repo().translate(expanded) + let commit = '' + if full =~# '^fugitive://' + let commit = matchstr(full,'://.*//\zs\w\+') + let path = matchstr(full,'://.*//\w\+\zs/.*') + if commit =~ '..' + let type = s:repo().git_chomp('cat-file','-t',commit.s:sub(path,'^/',':')) + else + let type = 'blob' + endif + let path = path[1:-1] + elseif s:repo().bare() + let path = '.git/' . full[strlen(s:repo().dir())+1:-1] + let type = '' + else + let path = full[strlen(s:repo().tree())+1:-1] + if path =~# '^\.git/' + let type = '' + elseif isdirectory(full) + let type = 'tree' + else + let type = 'blob' + endif + endif + if path =~# '^\.git/.*HEAD' && filereadable(s:repo().dir(path[5:-1])) + let body = readfile(s:repo().dir(path[5:-1]))[0] + if body =~# '^\x\{40\}$' + let commit = body + let type = 'commit' + let path = '' + elseif body =~# '^ref: refs/' + let path = '.git/' . matchstr(body,'ref: \zs.*') + endif + endif + + if a:0 && a:1 =~# '@[[:alnum:]_-]*\%(://.\{-\}\)\=$' + let remote = matchstr(a:1,'@\zs[[:alnum:]_-]\+\%(://.\{-\}\)\=$') + elseif path =~# '^\.git/refs/remotes/.' + let remote = matchstr(path,'^\.git/refs/remotes/\zs[^/]\+') + else + let remote = 'origin' + let branch = matchstr(rev,'^[[:alnum:]/._-]\+\ze[:^~@]') + if branch ==# '' && path =~# '^\.git/refs/\w\+/' + let branch = s:sub(path,'^\.git/refs/\w+/','') + endif + if filereadable(s:repo().dir('refs/remotes/'.branch)) + let remote = matchstr(branch,'[^/]\+') + let rev = rev[strlen(remote)+1:-1] + else + if branch ==# '' + let branch = matchstr(s:repo().head_ref(),'\\)' + return root . '/admin' + elseif path =~# '^\.git\>' + return root + endif + if a:rev =~# '^[[:alnum:]._-]\+:' + let commit = matchstr(a:rev,'^[^:]*') + elseif a:commit =~# '^\d\=$' + let local = matchstr(a:repo.head_ref(),'\' + return root + endif + let url = root + if a:commit =~# '^\x\{40\}$' + if a:type ==# 'commit' + let url .= ';a=commit' + endif + let url .= ';h=' . a:repo.rev_parse(a:commit . (a:path == '' ? '' : ':' . a:path)) + else + if a:type ==# 'blob' + let tmp = tempname() + silent execute 'write !'.a:repo.git_command('hash-object','-w','--stdin').' > '.tmp + let url .= ';h=' . readfile(tmp)[0] + else + try + let url .= ';h=' . a:repo.rev_parse((a:commit == '' ? 'HEAD' : ':' . a:commit) . ':' . a:path) + catch /^fugitive:/ + call s:throw('fugitive: cannot browse uncommitted file') + endtry + endif + let root .= ';hb=' . matchstr(a:repo.head_ref(),'[^ ]\+$') + endif + if a:path !=# '' + let url .= ';f=' . a:path + endif + if a:0 && a:1 + let url .= '#l' . a:1 + endif + return url +endfunction + +" }}}1 +" File access {{{1 + +function! s:ReplaceCmd(cmd,...) abort + let fn = bufname('') + let tmp = tempname() + let aw = &autowrite + let prefix = '' + try + if a:0 && a:1 != '' + if &shell =~# 'cmd' + let old_index = $GIT_INDEX_FILE + let $GIT_INDEX_FILE = a:1 + elseif &shell =~# 'csh' + let prefix = 'setenv GIT_INDEX_FILE '.s:shellesc(a:1).'; ' + else + let prefix = 'GIT_INDEX_FILE='.s:shellesc(a:1).' ' + endif + endif + set noautowrite + silent exe '!'.escape(prefix.a:cmd,'%#').' > '.tmp + finally + let &autowrite = aw + if exists('old_index') + let $GIT_INDEX_FILE = old_index + endif + endtry + silent exe 'keepalt file '.tmp + silent edit! + silent exe 'keepalt file '.s:fnameescape(fn) + call delete(tmp) + silent exe 'doau BufReadPost '.s:fnameescape(fn) +endfunction + +function! s:BufReadIndex() + if !exists('b:fugitive_display_format') + let b:fugitive_display_format = filereadable(expand('%').'.lock') + endif + let b:fugitive_display_format = b:fugitive_display_format % 2 + let b:fugitive_type = 'index' + try + let b:git_dir = s:repo().dir() + setlocal noro ma + if fnamemodify($GIT_INDEX_FILE !=# '' ? $GIT_INDEX_FILE : b:git_dir . '/index', ':p') ==# expand('%:p') + let index = '' + else + let index = expand('%:p') + endif + if b:fugitive_display_format + call s:ReplaceCmd(s:repo().git_command('ls-files','--stage'),index) + set ft=git nospell + else + let cd = exists('*haslocaldir') && haslocaldir() ? 'lcd ' : 'cd ' + let dir = getcwd() + try + execute cd.'`=s:repo().tree()`' + call s:ReplaceCmd(s:repo().git_command('status'),index) + finally + execute cd.'`=dir`' + endtry + set ft=gitcommit + endif + setlocal ro noma nomod nomodeline bufhidden=delete + nnoremap a :let b:fugitive_display_format += 1exe BufReadIndex() + nnoremap i :let b:fugitive_display_format -= 1exe BufReadIndex() + nnoremap D :execute StageDiff() + nnoremap dd :execute StageDiff() + nnoremap dh :execute StageDiff('Gsdiff') + nnoremap ds :execute StageDiff('Gsdiff') + nnoremap dv :execute StageDiff() + nnoremap - :execute StageToggle(line('.'),line('.')+v:count1-1) + xnoremap - :execute StageToggle(line("'<"),line("'>")) + nnoremap p :execute StagePatch(line('.'),line('.')+v:count1-1) + xnoremap p :execute StagePatch(line("'<"),line("'>")) + nnoremap :call search('^#\t.*','W'). + nnoremap :call search('^#\t.*','Wbe'). + call s:JumpInit() + nunmap P + nunmap ~ + nnoremap C :Gcommit + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +function! s:FileRead() + try + let repo = s:repo(s:ExtractGitDir(expand(''))) + let path = s:sub(s:sub(matchstr(expand(''),'fugitive://.\{-\}//\zs.*'),'/',':'),'^\d:',':&') + let hash = repo.rev_parse(path) + if path =~ '^:' + let type = 'blob' + else + let type = repo.git_chomp('cat-file','-t',hash) + endif + " TODO: use count, if possible + return "read !".escape(repo.git_command('cat-file',type,hash),'%#\') + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +function! s:BufReadIndexFile() + try + let b:fugitive_type = 'blob' + let b:git_dir = s:repo().dir() + call s:ReplaceCmd(s:repo().git_command('cat-file','blob',s:buffer().sha1())) + return '' + catch /^fugitive: rev-parse/ + silent exe 'doau BufNewFile '.s:fnameescape(bufname('')) + return '' + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +function! s:BufWriteIndexFile() + let tmp = tempname() + try + let path = matchstr(expand(''),'//\d/\zs.*') + let stage = matchstr(expand(''),'//\zs\d') + silent execute 'write !'.s:repo().git_command('hash-object','-w','--stdin').' > '.tmp + let sha1 = readfile(tmp)[0] + let old_mode = matchstr(s:repo().git_chomp('ls-files','--stage',path),'^\d\+') + if old_mode == '' + let old_mode = executable(s:repo().tree(path)) ? '100755' : '100644' + endif + let info = old_mode.' '.sha1.' '.stage."\t".path + call writefile([info],tmp) + if has('win32') + let error = system('type '.tmp.'|'.s:repo().git_command('update-index','--index-info')) + else + let error = system(s:repo().git_command('update-index','--index-info').' < '.tmp) + endif + if v:shell_error == 0 + setlocal nomodified + silent execute 'doautocmd BufWritePost '.s:fnameescape(expand('%:p')) + call fugitive#reload_status() + return '' + else + return 'echoerr '.string('fugitive: '.error) + endif + finally + call delete(tmp) + endtry +endfunction + +function! s:BufReadObject() + try + setlocal noro ma + let b:git_dir = s:repo().dir() + let hash = s:buffer().sha1() + if !exists("b:fugitive_type") + let b:fugitive_type = s:repo().git_chomp('cat-file','-t',hash) + endif + if b:fugitive_type !~# '^\%(tag\|commit\|tree\|blob\)$' + return "echoerr 'fugitive: unrecognized git type'" + endif + let firstline = getline('.') + if !exists('b:fugitive_display_format') && b:fugitive_type != 'blob' + let b:fugitive_display_format = +getbufvar('#','fugitive_display_format') + endif + + let pos = getpos('.') + silent %delete + setlocal endofline + + if b:fugitive_type == 'tree' + let b:fugitive_display_format = b:fugitive_display_format % 2 + if b:fugitive_display_format + call s:ReplaceCmd(s:repo().git_command('ls-tree',hash)) + else + call s:ReplaceCmd(s:repo().git_command('show',hash)) + endif + elseif b:fugitive_type == 'tag' + let b:fugitive_display_format = b:fugitive_display_format % 2 + if b:fugitive_display_format + call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash)) + else + call s:ReplaceCmd(s:repo().git_command('cat-file','-p',hash)) + endif + elseif b:fugitive_type == 'commit' + let b:fugitive_display_format = b:fugitive_display_format % 2 + if b:fugitive_display_format + call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash)) + else + call s:ReplaceCmd(s:repo().git_command('show','--pretty=format:tree %T%nparent %P%nauthor %an <%ae> %ad%ncommitter %cn <%ce> %cd%nencoding %e%n%n%s%n%n%b',hash)) + call search('^parent ') + if getline('.') ==# 'parent ' + silent delete_ + else + silent s/\%(^parent\)\@\)\=$','W',line('.')+3) + silent delete_ + end + 1 + endif + elseif b:fugitive_type ==# 'blob' + call s:ReplaceCmd(s:repo().git_command('cat-file',b:fugitive_type,hash)) + endif + call setpos('.',pos) + setlocal ro noma nomod nomodeline + if b:fugitive_type !=# 'blob' + set filetype=git + nnoremap a :let b:fugitive_display_format += v:count1exe BufReadObject() + nnoremap i :let b:fugitive_display_format -= v:count1exe BufReadObject() + else + call s:JumpInit() + endif + + return '' + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +augroup fugitive_files + autocmd! + autocmd BufReadCmd *.git/index exe s:BufReadIndex() + autocmd BufReadCmd *.git/*index*.lock exe s:BufReadIndex() + autocmd FileReadCmd fugitive://**//[0-3]/** exe s:FileRead() + autocmd BufReadCmd fugitive://**//[0-3]/** exe s:BufReadIndexFile() + autocmd BufWriteCmd fugitive://**//[0-3]/** exe s:BufWriteIndexFile() + autocmd BufReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:BufReadObject() + autocmd FileReadCmd fugitive://**//[0-9a-f][0-9a-f]* exe s:FileRead() + autocmd FileType git call s:JumpInit() +augroup END + +" }}}1 +" Go to file {{{1 + +function! s:JumpInit() abort + nnoremap :exe GF("edit") + if !&modifiable + nnoremap o :exe GF("split") + nnoremap O :exe GF("tabedit") + nnoremap P :exe Edit('edit',buffer().commit().'^'.v:count1.buffer().path(':')) + nnoremap ~ :exe Edit('edit',buffer().commit().'~'.v:count1.buffer().path(':')) + nnoremap C :exe Edit('edit',buffer().containing_commit()) + nnoremap cc :exe Edit('edit',buffer().containing_commit()) + nnoremap co :exe Edit('split',buffer().containing_commit()) + nnoremap cO :exe Edit('tabedit',buffer().containing_commit()) + nnoremap cp :exe Edit('pedit',buffer().containing_commit()) + endif +endfunction + +function! s:GF(mode) abort + try + let buffer = s:buffer() + let myhash = buffer.sha1() + + if buffer.type('tree') + let showtree = (getline(1) =~# '^tree ' && getline(2) == "") + if showtree && line('.') == 1 + return "" + elseif showtree && line('.') > 2 + return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(getline('.'),'/$','')) + elseif getline('.') =~# '^\d\{6\} \l\{3,8\} \x\{40\}\t' + return s:Edit(a:mode,buffer.commit().':'.s:buffer().path().(buffer.path() =~# '^$\|/$' ? '' : '/').s:sub(matchstr(getline('.'),'\t\zs.*'),'/$','')) + endif + + elseif buffer.type('blob') + let ref = expand("") + try + let sha1 = buffer.repo().rev_parse(ref) + catch /^fugitive:/ + endtry + if exists('sha1') + return s:Edit(a:mode,ref) + endif + + else + + " Index + if getline('.') =~# '^\d\{6\} \x\{40\} \d\t' + let ref = matchstr(getline('.'),'\x\{40\}') + let file = ':'.s:sub(matchstr(getline('.'),'\d\t.*'),'\t',':') + return s:Edit(a:mode,file) + + elseif getline('.') =~# '^#\trenamed:.* -> ' + let file = '/'.matchstr(getline('.'),' -> \zs.*') + return s:Edit(a:mode,file) + elseif getline('.') =~# '^#\t[[:alpha:] ]\+: *.' + let file = '/'.matchstr(getline('.'),': *\zs.\{-\}\ze\%( (new commits)\)\=$') + return s:Edit(a:mode,file) + elseif getline('.') =~# '^#\t.' + let file = '/'.matchstr(getline('.'),'#\t\zs.*') + return s:Edit(a:mode,file) + elseif getline('.') =~# ': needs merge$' + let file = '/'.matchstr(getline('.'),'.*\ze: needs merge$') + return s:Edit(a:mode,file).'|Gdiff' + + elseif getline('.') ==# '# Not currently on any branch.' + return s:Edit(a:mode,'HEAD') + elseif getline('.') =~# '^# On branch ' + let file = 'refs/heads/'.getline('.')[12:] + return s:Edit(a:mode,file) + elseif getline('.') =~# "^# Your branch .*'" + let file = matchstr(getline('.'),"'\\zs\\S\\+\\ze'") + return s:Edit(a:mode,file) + endif + + let showtree = (getline(1) =~# '^tree ' && getline(2) == "") + + if getline('.') =~# '^ref: ' + let ref = strpart(getline('.'),5) + + elseif getline('.') =~# '^parent \x\{40\}\>' + let ref = matchstr(getline('.'),'\x\{40\}') + let line = line('.') + let parent = 0 + while getline(line) =~# '^parent ' + let parent += 1 + let line -= 1 + endwhile + return s:Edit(a:mode,ref) + + elseif getline('.') =~ '^tree \x\{40\}$' + let ref = matchstr(getline('.'),'\x\{40\}') + if s:repo().rev_parse(myhash.':') == ref + let ref = myhash.':' + endif + return s:Edit(a:mode,ref) + + elseif getline('.') =~# '^object \x\{40\}$' && getline(line('.')+1) =~ '^type \%(commit\|tree\|blob\)$' + let ref = matchstr(getline('.'),'\x\{40\}') + let type = matchstr(getline(line('.')+1),'type \zs.*') + + elseif getline('.') =~# '^\l\{3,8\} '.myhash.'$' + return '' + + elseif getline('.') =~# '^\l\{3,8\} \x\{40\}\>' + let ref = matchstr(getline('.'),'\x\{40\}') + echoerr "warning: unknown context ".matchstr(getline('.'),'^\l*') + + elseif getline('.') =~# '^[+-]\{3\} [ab/]' + let ref = getline('.')[4:] + + elseif getline('.') =~# '^rename from ' + let ref = 'a/'.getline('.')[12:] + elseif getline('.') =~# '^rename to ' + let ref = 'b/'.getline('.')[10:] + + elseif getline('.') =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)' + let dref = matchstr(getline('.'),'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)') + let ref = matchstr(getline('.'),'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)') + let dcmd = 'Gdiff' + + elseif getline('.') =~# '^index ' && getline(line('.')-1) =~# '^diff --git \%(a/.*\|/dev/null\) \%(b/.*\|/dev/null\)' + let line = getline(line('.')-1) + let dref = matchstr(line,'\Cdiff --git \zs\%(a/.*\|/dev/null\)\ze \%(b/.*\|/dev/null\)') + let ref = matchstr(line,'\Cdiff --git \%(a/.*\|/dev/null\) \zs\%(b/.*\|/dev/null\)') + let dcmd = 'Gdiff!' + + elseif line('$') == 1 && getline('.') =~ '^\x\{40\}$' + let ref = getline('.') + else + let ref = '' + endif + + if myhash ==# '' + let ref = s:sub(ref,'^a/','HEAD:') + let ref = s:sub(ref,'^b/',':0:') + if exists('dref') + let dref = s:sub(dref,'^a/','HEAD:') + endif + else + let ref = s:sub(ref,'^a/',myhash.'^:') + let ref = s:sub(ref,'^b/',myhash.':') + if exists('dref') + let dref = s:sub(dref,'^a/',myhash.'^:') + endif + endif + + if ref ==# '/dev/null' + " Empty blob + let ref = 'e69de29bb2d1d6434b8b29ae775ad8c2e48c5391' + endif + + if exists('dref') + return s:Edit(a:mode,ref) . '|'.dcmd.' '.s:fnameescape(dref) + elseif ref != "" + return s:Edit(a:mode,ref) + endif + + endif + return '' + catch /^fugitive:/ + return 'echoerr v:errmsg' + endtry +endfunction + +" }}}1 +" Statusline {{{1 + +function! s:repo_head_ref() dict abort + return readfile(s:repo().dir('HEAD'))[0] +endfunction + +call s:add_methods('repo',['head_ref']) + +function! fugitive#statusline(...) + if !exists('b:git_dir') + return '' + endif + let status = '' + if s:buffer().commit() != '' + let status .= ':' . s:buffer().commit()[0:7] + endif + let head = s:repo().head_ref() + if head =~# '^ref: ' + let status .= s:sub(head,'^ref: %(refs/%(heads/|remotes/|tags/)=)=','(').')' + elseif head =~# '^\x\{40\}$' + let status .= '('.head[0:7].')' + endif + if &statusline =~# '%[MRHWY]' && &statusline !~# '%[mrhwy]' + return ',GIT'.status + else + return '[Git'.status.']' + endif +endfunction + +function! s:repo_config(conf) dict abort + return matchstr(system(s:repo().git_command('config').' '.a:conf),"[^\r\n]*") +endfun + +function! s:repo_user() dict abort + let username = s:repo().config('user.name') + let useremail = s:repo().config('user.email') + return username.' <'.useremail.'>' +endfun + +call s:add_methods('repo',['config', 'user']) + +" }}}1 + +" vim:set ft=vim ts=8 sw=2 sts=2: diff --git a/.vim/bundle/vim-unimpaired/doc/unimpaired.txt b/.vim/bundle/vim-unimpaired/doc/unimpaired.txt index 84f39b7..0ff651c 100644 --- a/.vim/bundle/vim-unimpaired/doc/unimpaired.txt +++ b/.vim/bundle/vim-unimpaired/doc/unimpaired.txt @@ -94,8 +94,6 @@ Mnenomic: encoding always comes before decoding; "[" always comes before "]". TODO *unimpaired-todo* -Descend into and ascend from directories with |[o| and |]o|. - Avoid munging null characters when encoding and decoding. vim:tw=78:et:ft=help:norl: diff --git a/.vim/bundle/vim-unimpaired/plugin/unimpaired.vim b/.vim/bundle/vim-unimpaired/plugin/unimpaired.vim index 46577a6..21c8ba8 100644 --- a/.vim/bundle/vim-unimpaired/plugin/unimpaired.vim +++ b/.vim/bundle/vim-unimpaired/plugin/unimpaired.vim @@ -34,9 +34,9 @@ function! s:entries(path) let path = substitute(a:path,'[\\/]$','','') let files = split(glob(path."/.*"),"\n") let files += split(glob(path."/*"),"\n") - call filter(files,'v:val !=# "." && v:val !=# ".."') - call filter(files,'v:val[-4:-1] !=# ".swp" && v:val[-1:-1] !=# "~"') call map(files,'substitute(v:val,"[\\/]$","","")') + call filter(files,'v:val !~# "[\\\\/]\\.\\.\\=$"') + call filter(files,'v:val[-4:-1] !=# ".swp" && v:val[-1:-1] !=# "~"') return files endfunction @@ -219,7 +219,7 @@ endfunction function! s:Transform(algorithm,type) let sel_save = &selection let cb_save = &clipboard - set selection=inclusive clipboard-=unnamed + set selection=inclusive clipboard-=unnamed clipboard-=unnamedplus let reg_save = @@ if a:type =~ '^\d\+$' silent exe 'norm! ^v'.a:type.'$hy' diff --git a/.vim/doc/conque_term.txt b/.vim/doc/conque_term.txt index ff8ca54..4213d32 100644 --- a/.vim/doc/conque_term.txt +++ b/.vim/doc/conque_term.txt @@ -1,68 +1,430 @@ -*ConqueTerm* Plugin to run a shell in a buffer +*ConqueTerm* Plugin to run a shell inside a Vim buffer -The ConqueTerm plugin will convert a buffer into a terminal emulator, allowing -you to run a shell or shell application in the buffer. +The ConqueTerm plugin will turn a Vim buffer into a terminal emulator, allowing +you to run and interact with a shell or shell application inside the buffer. - *conque_term-usage* + 1. Installation |conque-term-installation| + 2. Usage |conque-term-usage| + 3. Config Options |conque-term-options| + 4. VimScript API |conque-term-api| + 5. Misc |conque-term-misc| -Type :ConqueTerm to launch an application in the current buffer. E.g. +============================================================================== - :ConqueTerm bash - :ConqueTerm mysql -h localhost -u joe_lunchbox Menu - :ConqueTerm man top +1. Installation *conque-term-installation* +Conque is designed for both Unix and Windows operating systems, however the +requirements are slightly different. Please check section below corresponding +to your installed OS. + +1.1 Requirements for Unix *conque-term-requirements* + + * [G]Vim 7.0+ with +python and/or +python3 + * Python 2.3+ and/or 3.x + * Unix-like OS: Linux, OS X, Solaris, Cygwin, etc + +The most common stumbling block is getting a version of Vim which has the +python interface enabled. Most all software package managers will have a copy +of Vim with Python support, so that is often the easiest way to get it. If +you're compiling Vim from source, be sure to use the --enable-pythoninterp +option, or --enable-python3interp for Python 3. On OS X the best option is +MacVim, which installs with Python support by default. + +1.2 Requirements for Windows *conque-term-windows* + + * [G]Vim 7.3 with +python and/or +python3 + * Python 2.7 and/or 3.1 + * Modern Windows OS (XP or later) + +Conque only officially supports the latest GVim 7.3 Windows installer +available at www.vim.org. If you are currently using Vim 7.2 or earlier you +will need to upgrade to 7.3 for Windows support. The Windows installer already +has the +python/+python3 interface built in. + +The official 7.3 release of Vim for Windows only works with Python versions +2.7 and/or 3.1. You can download and install Python from their website +http://www.python.org/download + +If you are compiling Vim + Python from source on Windows, the requirements +become only Vim 7.3+ and Python 2.7+. + + +1.3 Installation *conque-term-installation-instructions* + +Download the latest vimball from http://conque.googlecode.com + +Open the .vba file with Vim and run the following commands: +> + :so % + :q +< +That's it! The :ConqueTerm command will be available the next time you start +Vim. You can delete the .vba file when you've verified Conque was successfully +installed. + +============================================================================== + +2. Usage *conque-term-usage* + +Type :ConqueTerm to launch an application in the current buffer. Eg: +> + :ConqueTerm bash + :ConqueTerm mysql -h localhost -u joe_lunchbox Menu + :ConqueTerm Powershell.exe +< Use :ConqueTermSplit or :ConqueTermVSplit to open Conque in a new horizontal -or vertical buffer. +or vertical buffer. Use :ConqueTermTab to open Conque in a new tab. -Keys pressed in insert mode will be sent to the shell, along with output from -the 'p' command in normal mode. +In insert mode you can interact with the shell as you would expect in a +normal terminal. All key presses will be sent to the terminal, including +control characters. See |conque-term-special-keys| for more information, +particularly regarding the key. -Press the key twice to send a single to the shell. Pressing this -key once will leave insert mode like normal. - -Press in any buffer to send a visual selection to the shell. +In normal mode you can use Vim commands to browse your terminal output and +scroll back through the history. Most all Vim functionality will work, such +as searching, yanking or highlighting text. - *conque_term-settings* +2.1 Special keys *conque-term-special-keys* -Set the following in your .vimrc (default values shown) +There are several keys which can be configured to have special behavior with +Conque. -" Enable colors. Setting this to 0 will make your terminal faster. -let g:ConqueTerm_Color = 1 +Send text to Conque *conque-term-F9* -" Set your terminal type. I strong recommend leaving this as vt100, -" however more features may be enabled with xterm. -let g:ConqueTerm_TERM = 'vt100' +If you want to send some text from a file you are editing in another buffer +to be run in Conque, select the desired text visually then press the +key. If you have multiple Conque buffers, the text will be sent to the most +recently created buffer. Alternatively you can yank the text, switch to your +terminal, then paste it with the normal 'p' key. This feature can be +configured to use a different key with the |ConqueTerm_SendVisKey| option. -" Set buffer syntax. Conque has highlighting for MySQL, but not much else. -let g:ConqueTerm_Syntax = 'conque' +Toggle terminal input mode *conque-term-F8* -" Continue updating shell when it's not the current, focused buffer -let g:ConqueTerm_ReadUnfocused = 1 +If you want to use insert mode to edit the terminal screen, press . You +will now be able to edit the terminal output freely without your cursor +jumping the the active prompt line. This may be useful if you want to reformat +terminal output for readability. + +While the terminal is paused new output will not be displayed on the screen +until you press again to resume. + +You can configure Conque to use a different key with the |ConqueTerm_ToggleKey| +option. + +Sending the key press *conque-term-Esc* + +By default if you press the key in a Conque buffer you will leave insert +mode. But what if you want the key press to be sent to your terminal? There +are two options. By default, pressing twice will send one key +press to the terminal, while pressing it once will leave insert mode. + +Alternatively you can use the |ConqueTerm_EscKey| option to choose a +different key for leaving insert mode. If a custom key is set, then all +key presses will be sent to the terminal. - *conque_term-requirements* +============================================================================== -The following minimum requirements are needed to run Conque. Conque will not -run on Windows without a Cygwin-like environment. +3. Options *conque-term-options* - - Vim 7.1 - - Python 2.3 - - Supported operating systems: *nix, Mac, or Cygwin +You can set the following options in your .vimrc (default values shown) -Tested on: - - Vim 7.2 / Python 2.6 / Ubuntu 9.10 (Gnome & GTK) - - Vim 7.2 / Python 2.6 / FreeBSD 8.0 (GTK) - - Vim 7.1 / Python 2.6 / FreeBSD 8.0 (GTK) - x Vim 7.0 / Python 2.6 / FreeBSD 8.0 (GTK) - * feedkeys() doesn't restart updatetime - - Vim 7.2 / Python 2.4 / OpenSolaris 2009.06 (Gnome) - - Vim 7.2 / Python 2.4 / CentOS 5.3 (no GUI) - - Vim 7.1 / Python 2.3 / RHEL 4 (no GUI) - - Vim 7.2 / Python 2.5 / Cygwin (Windows Vista 64b) - - MacVim 7.2 / Python 2.3 / OS X 10.6.2 - *conque_term-bugs* +3.1 Insert mode when entering buffer *ConqueTerm_InsertOnEnter* + +If set to 1 then you will automatically go into insert mode when you enter the +buffer. This diverges from normal Vim behavior. If 0 you will still be in +normal mode. +> + let g:ConqueTerm_InsertOnEnter = 0 +< +3.2 Enable in insert mode *ConqueTerm_CWInsert* + +If set to 1 then you can leave the Conque buffer using the commands +while you're still in insert mode. If set to 0 then the character will +be sent to the terminal. If both this option and ConqueTerm_InsertOnEnter are +set you can go in and out of the terminal buffer while never leaving insert +mode. +> + let g:ConqueTerm_CWInsert = 0 +< +3.3 Use a custom key for leaving insert mode *ConqueTerm_EscKey* + +If a custom key is set, then all key presses will be sent to the +terminal and you must use this custom key to leave insert mode. If left to the +default value of '' then you must press it twice to send the escape +character to the terminal, while pressing it once will leave insert mode. + +Note: You cannot use a key which is internally coded with the escape +character. This includes the keys and often the and keys. +Picking a control key, such as will be your best bet. +> + let g:ConqueTerm_EscKey = '' +< +3.4 Send selected text to Conque *ConqueTerm_SendVisKey* + +Use this key to send the currently selected text to the most recently created +Conque buffer. +> + let g:ConqueTerm_SendVisKey = '' +< +3.5 Toggle terminal input mode *ConqueTerm_ToggleKey* + +Press this key to pause terminal input and output display. You will then be +able to edit the terminal screen as if it were a normal text buffer. Press +this key again to resume terminal mode. +> + let g:ConqueTerm_ToggleKey = '' +< +3.6 Enable or disable colors *ConqueTerm_Color* + +Set to 1 to enable colors, 0 to disable. Syntax highlighting in Vim can be +slow if your terminal is color intensive. Disabling color can make the +terminal render significantly faster. +> + let g:ConqueTerm_Color = 1 +< +3.7 Choose your terminal type, Unix ONLY *ConqueTerm_TERM* + +Use this option to tell Conque what type of terminal it should identify itself +as. Conque officially uses the more limited VT100 terminal type for +developement and testing, although it supports some more advanced features +such as colors and title strings. + +You can change this setting to a more advanced type, namely 'xterm', but your +results may vary depending on which programs you're running. +> + let g:ConqueTerm_TERM = 'vt100' +< +3.8 Choose Vim syntax type *ConqueTerm_Syntax* + +Set the buffer syntax. The default 'conque' has highlighting for MySQL, but +not much else. +> + let g:ConqueTerm_Syntax = 'conque' +< +3.9 Keep updating terminal buffer *ConqueTerm_ReadUnfocused* + +If set to 1 then your Conque buffers will continue to update after you've +switched to another buffer. + +Note: Conque buffers may continue to update, but they will not scroll down as +new lines are added beyond the bottom of the visible buffer area. This is a +limitation of the Vim scripting language for which I haven't found a +workaround. +> + let g:ConqueTerm_ReadUnfocused = 1 +< +3.10 Regex for highlighting your prompt *ConqueTerm_PromptRegex* + +Use this regular expression for sytax highlighting your terminal prompt. Your +terminal will generally run faster if you use Vim highlighting instead of +terminal colors for your prompt. You can also use it to do more advanced +syntax highlighting for the prompt line. +> + let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$' +< +3.11 Close buffer when program exits *ConqueTerm_CloseOnEnd* + +If you want your terminal buffer to be closed and permanently deleted when the +program running inside of it exits, set this option to 1. Otherwise the buffer +will become a simple text buffer after the program exits, and you can edit the +program output in insert mode. +> + let g:ConqueTerm_CloseOnEnd = 0 +< +3.12 Python version *ConqueTerm_PyVersion* + +Conque will work with either Python 2.x or 3.x, assuming the interfaces have +been installed. By default it will try to use Python 2 first, then will try +Python 3. If you want Conque to use Python 3, set this variable to 3. + +Note: even if you set this to 3, if you don't have the python3 interface +Conque will fall back to using Python 2. +> + let g:ConqueTerm_PyVersion = 2 +< +3.13 Python executable, Windows ONLY *ConqueTerm_PyExe* + +The Windows version of Conque needs to know the path to the python.exe +executable for the version of Python Conque is using. If you installed Python +in the default location, or added the Python directory to your system path, +Conque should be able to find python.exe without you changing this variable. + +For example, you might set this to 'C:\Program Files\Python27\python.exe' +> + let g:ConqueTerm_PyExe = '' +< +3.14 Function Keys *ConqueTerm_SendFunctionKeys* + +By default, function keys (the F1-F12 row at the top of your keyboard) are not +passed to the terminal. Set this option to 1 to send these key events. + +Note: Unless you configured |ConqueTerm_SendVisKey| and |ConqueTerm_ToggleKey| +to use different keys, and will not be sent to the terminal even if +you set this option to 1. +> + let g:ConqueTerm_SendFunctionKeys = 0 +< + +============================================================================== + +4. VimScript API (Beta) *conque-term-api* + +The Conque scripting API allows you to create and interact with Conque +terminals with the VimScript language. This API is still in beta stage. + +4.1 conque_term#open({command}, [buf_opts], [remain]) *conque-term-open* + +The open() function will create a new terminal buffer and start your command. + +The {command} must be an executable, either an absolute path or relative to +your system path. + +You can pass in a list of vim commands [buf_opts] which will be executed after +the new buffer is created but before the command is started. These are +typically commands to alter the size, position or configuration of the buffer +window. + +Note: If you don't pass in a command such as 'split', the terminal will open +in the current buffer. + +If you don't want the new terminal buffer to become the new active buffer, set + [remain] to 1. Only works if you create a split screen using [options]. + +Returns a Conque terminal object. + +Examples: +> + let my_terminal = conque_term#open('/bin/bash') + let my_terminal = conque_term#open('ipython', ['split', 'resize 20'], 1) +< +4.2 conque_term#subprocess({command}) *conque-term-subprocess* + +Starts a new subprocess with your {command}, but no terminal buffer is ever +created. This may be useful if you need asynchronous interaction with a +subprocess, but want to handle the output on your own. + +Returns a Conque terminal object. + +Example: +> + let my_subprocess = conque_term#subprocess('tail -f /var/log/foo.log') +< +4.3 conque_term#get_instance( [terminal_number] ) *conque-term-get-instance* + +Use the get_instance() function to retrieve an existing terminal object. The +terminal could have been created either with the user command :ConqueTerm or +with an API call to conque_term#open() or subprocess(). + +Use the optional [terminal_number] to retrieve a specific terminal instance. +Otherwise if the current buffer is a Conque terminal, it will be returned, +else the most recently created terminal. The terminal number is what you see +at the end of a terminal buffer name, e.g. "bash - 2". + +Returns a Conque terminal object. + +Example: +> + nnoremap :call conque_term#get_instance().writeln('clear') +< +4.4 CONQUE_OBJECT.write(text) *conque-term-write* + +Once you have a terminal object from open(), subprocess() or get_instance() +you can send text input to it with the write() method. + +No return value. + +Examples: +> + call my_terminal.write("whoami\n") + call my_terminal.write("\") +< +4.5 CONQUE_OBJECT.writeln(text) *conque-term-writeln* + +The same as write() except adds a \n character to the end if your input. + +Examples: +> + call my_subprocess.writeln('make') +< +4.6 CONQUE_OBJECT.read( [timeout], [update_buffer] ) *conque-term-read* + +Read new output from a Conque terminal subprocess. New output will be returned +as a string, and the terminal buffer will also be updated by default. + +If you are reading immediately after calling the write() method, you may want +to wait [timeout] milliseconds for output to be ready. + +If you want to prevent the output from being displayed in the terminal buffer, +set [update_buffer] to 0. This option has no effect if the terminal was +created with the subprocess() function, since there never is a buffer to +update. + +Returns output string. + +Note: The terminal buffer will not automatically scroll down if the new output +extends beyond the bottom of the visible buffer. Vim doesn't allow "unfocused" +buffers to be scrolled at the current version, although hopefully this will +change. + +Examples: +> + call my_terminal.writeln('whoami') + let output = my_terminal.read(500) + call my_terminal.writeln('ls -lha') + let output = my_terminal.read(1000, 1) +< +4.7 CONQUE_OBJECT.set_callback( {funcname} ) *conque-term-set-callback* + +Register a callback function for this subprocess instance. This function will +automatically be called whenever new output is available. Only practical with +subprocess() objects. + +Conque checkes for new subprocess output once a second when Vim is idle. If +new output is found your function will be called. + +Pass in the callback function name {funcname} as a string. + +No return value. + +Note: this method requires the g:ConqueTerm_ReadUnfocused option to be set. + +Note: this method is experimental, results may vary. + +Example: +> + let sp = conque_term#subprocess('tail -f /home/joe/log/error_log') + + function! MyErrorAlert(output) + echo a:output + endfunction + + call sp.set_callback('MyErrorAlert') +< +4.8 CONQUE_OBJECT.close() *conque-term-close* + +Kill your terminal subprocess. Sends the ABORT signal. You probably want to +close your subprocess in a more graceful manner with the write() method, but +this can be used when needed. Does not close the terminal buffer, if it +exists. + +This method will be called on all existing Conque subprocesses when Vim exits. + +Example: +> + let term = conque_term#open('ping google.com', ['belowright split']) + call term.read(5000) + call term.close() +< + +============================================================================== + +5. Misc *conque-term-misc* + + +5.1 Known bugs *conque-term-bugs* The following are known limitations: @@ -74,38 +436,22 @@ The following are known limitations: exception. Pressing x or instead of works in most cases. - *conque_term-todo* - - Fix pasting from named registers - - Polling unfucused conque buffers (Top explodes when window resizes) - - Enable graphics character set - - Consider supporting xterm escapes - - Improve color logic - - Find a solution to UTF-8 input (See InsertCharPre in Vim todo.txt) - - Find an alternative to updatetime polling (See Vim todo.txt) - - Find a graceful solution to Meta key input - - Windows support - (See PyConsole http://www.vim.org/scripts/script.php?script_id=1974) - - Always: look for performance improvements - - - *conque_term-contribute* +5.2 Contribute *conque-term-contribute* The two contributions most in need are improvements to Vim itself. I currently -use hacks to simulate a key press event and repeating CursorHold event. The -Vim todo.txt document lists proposed improvements to give users this behavior -without hacks. Having a key press event should allow Conque to work with multi- -byte input. If you are a Vim developer, please consider prioritizing these two -items: +use hacks to capture key press input from the user, and to poll the terminal +for more output. The Vim todo.txt document lists proposed improvements to give +users this behavior without hacks. Having a key press event should allow +Conque to work with multi- byte input. If you are a Vim developer, please +consider prioritizing these two items: - todo.txt (Autocommands, line ~3137) 8 Add an event like CursorHold that is triggered repeatedly, not just once after typing something. - - todo.txt (Autocommands, proposed event list, line ~3189) - InsertCharPre - user typed character Insert mode, before inserting the - char. Pattern is matched with text before the cursor. Set v:char to the - character, can be changed. (not triggered when 'paste' is set). + +5.3 Feedback *conque-term-feedback* Bugs, suggestions and patches are all welcome. @@ -113,44 +459,4 @@ For more information visit http://conque.googlecode.com Check out the latest from svn at http://conque.googlecode.com/svn/trunk/ - *conque_term-changelog* - - - 1.0 / 2010-02- - * Complete python rewrite - * Add support for ncurses based applications - * Add continuous polling, instead of using - * Improve speed - * Improve syntax highlighting - - - 0.6 / 2009-12-18 - * Fix GVim errors with non-english locale - * No functional changes - - - 0.5 / 2009-12-02 - * Various performance enhancements and bugfixes. - * Rewritten escape sequence processing - - - 0.4 / 2009-10-30 - * Improved history and tab completion - * Fix escape sequence formatting and improve highlighting - * Send selected text to shell from any buffer - * Add special handling of "vi" and "man" commands - * Improve error handling - * Add key mappings for - * Various bugfixes - - - 0.3 / 2009-10-13 - * Apply escape sequence coloring to output, e.g. ls --color - * Clean up syntax files for portability - * Fix several Vim 7.1 bugs - * Bugfixes for multiple shell buffers - * Add experimental shell folding option - - - 0.2 / 2009-10-01 - * Rewritten subprocess management module in python instead of c - * Added support for OS X, partial support for Windows - * Improved tab completion - - - 0.1 / 2009-09-03 - * Initial release - + vim:tw=78:ts=8:ft=help:norl: diff --git a/.vim/doc/tags b/.vim/doc/tags index 47fa067..5832a54 100644 --- a/.vim/doc/tags +++ b/.vim/doc/tags @@ -56,6 +56,20 @@ :VCSUpdate vcscommand.txt /*:VCSUpdate* :VCSVimDiff vcscommand.txt /*:VCSVimDiff* ConqueTerm conque_term.txt /*ConqueTerm* +ConqueTerm_CWInsert conque_term.txt /*ConqueTerm_CWInsert* +ConqueTerm_CloseOnEnd conque_term.txt /*ConqueTerm_CloseOnEnd* +ConqueTerm_Color conque_term.txt /*ConqueTerm_Color* +ConqueTerm_EscKey conque_term.txt /*ConqueTerm_EscKey* +ConqueTerm_InsertOnEnter conque_term.txt /*ConqueTerm_InsertOnEnter* +ConqueTerm_PromptRegex conque_term.txt /*ConqueTerm_PromptRegex* +ConqueTerm_PyExe conque_term.txt /*ConqueTerm_PyExe* +ConqueTerm_PyVersion conque_term.txt /*ConqueTerm_PyVersion* +ConqueTerm_ReadUnfocused conque_term.txt /*ConqueTerm_ReadUnfocused* +ConqueTerm_SendFunctionKeys conque_term.txt /*ConqueTerm_SendFunctionKeys* +ConqueTerm_SendVisKey conque_term.txt /*ConqueTerm_SendVisKey* +ConqueTerm_Syntax conque_term.txt /*ConqueTerm_Syntax* +ConqueTerm_TERM conque_term.txt /*ConqueTerm_TERM* +ConqueTerm_ToggleKey conque_term.txt /*ConqueTerm_ToggleKey* ExtractSnips() snipMate.txt /*ExtractSnips()* ExtractSnipsFile() snipMate.txt /*ExtractSnipsFile()* Filename() snipMate.txt /*Filename()* @@ -172,13 +186,29 @@ cocoa-license cocoa.txt /*cocoa-license* cocoa-mappings cocoa.txt /*cocoa-mappings* cocoa-suggested-plugins cocoa.txt /*cocoa-suggested-plugins* cocoa.txt cocoa.txt /*cocoa.txt* -conque_term-bugs conque_term.txt /*conque_term-bugs* -conque_term-changelog conque_term.txt /*conque_term-changelog* -conque_term-contribute conque_term.txt /*conque_term-contribute* -conque_term-requirements conque_term.txt /*conque_term-requirements* -conque_term-settings conque_term.txt /*conque_term-settings* -conque_term-todo conque_term.txt /*conque_term-todo* -conque_term-usage conque_term.txt /*conque_term-usage* +conque-term-Esc conque_term.txt /*conque-term-Esc* +conque-term-F8 conque_term.txt /*conque-term-F8* +conque-term-F9 conque_term.txt /*conque-term-F9* +conque-term-api conque_term.txt /*conque-term-api* +conque-term-bugs conque_term.txt /*conque-term-bugs* +conque-term-close conque_term.txt /*conque-term-close* +conque-term-contribute conque_term.txt /*conque-term-contribute* +conque-term-feedback conque_term.txt /*conque-term-feedback* +conque-term-get-instance conque_term.txt /*conque-term-get-instance* +conque-term-installation conque_term.txt /*conque-term-installation* +conque-term-installation-instructions conque_term.txt /*conque-term-installation-instructions* +conque-term-misc conque_term.txt /*conque-term-misc* +conque-term-open conque_term.txt /*conque-term-open* +conque-term-options conque_term.txt /*conque-term-options* +conque-term-read conque_term.txt /*conque-term-read* +conque-term-requirements conque_term.txt /*conque-term-requirements* +conque-term-set-callback conque_term.txt /*conque-term-set-callback* +conque-term-special-keys conque_term.txt /*conque-term-special-keys* +conque-term-subprocess conque_term.txt /*conque-term-subprocess* +conque-term-usage conque_term.txt /*conque-term-usage* +conque-term-windows conque_term.txt /*conque-term-windows* +conque-term-write conque_term.txt /*conque-term-write* +conque-term-writeln conque_term.txt /*conque-term-writeln* cs surround.txt /*cs* cvscommand-changes vcscommand.txt /*cvscommand-changes* drawit DrawIt.txt /*drawit* diff --git a/.vim/filetype.vim b/.vim/filetype.vim index 6a1b5ff..0d0b969 100644 --- a/.vim/filetype.vim +++ b/.vim/filetype.vim @@ -35,6 +35,8 @@ augroup python autocmd FileType python set softtabstop=4 autocmd FileType python set shiftwidth=4 autocmd FileType python set expandtab + autocmd FileType python set nosmartindent + augroup END augroup javascript autocmd FileType javascript set ts=4 diff --git a/.vim/indent/python.vim b/.vim/indent/python.vim new file mode 100644 index 0000000..32c773c --- /dev/null +++ b/.vim/indent/python.vim @@ -0,0 +1,196 @@ +" Python indent file +" Language: Python +" Maintainer: Eric Mc Sween +" Original Author: David Bustos +" Last Change: 2004 Jun 07 + +" Only load this indent file when no other was loaded. +if exists("b:did_indent") + finish +endif +let b:did_indent = 1 + +setlocal expandtab +setlocal nolisp +setlocal autoindent +setlocal indentexpr=GetPythonIndent(v:lnum) +setlocal indentkeys=!^F,o,O,<:>,0),0],0},=elif,=except + +let s:maxoff = 50 + +" Find backwards the closest open parenthesis/bracket/brace. +function! s:SearchParensPair() + let line = line('.') + let col = col('.') + + " Skip strings and comments and don't look too far + let skip = "line('.') < " . (line - s:maxoff) . " ? dummy :" . + \ 'synIDattr(synID(line("."), col("."), 0), "name") =~? ' . + \ '"string\\|comment"' + + " Search for parentheses + call cursor(line, col) + let parlnum = searchpair('(', '', ')', 'bW', skip) + let parcol = col('.') + + " Search for brackets + call cursor(line, col) + let par2lnum = searchpair('\[', '', '\]', 'bW', skip) + let par2col = col('.') + + " Search for braces + call cursor(line, col) + let par3lnum = searchpair('{', '', '}', 'bW', skip) + let par3col = col('.') + + " Get the closest match + if par2lnum > parlnum || (par2lnum == parlnum && par2col > parcol) + let parlnum = par2lnum + let parcol = par2col + endif + if par3lnum > parlnum || (par3lnum == parlnum && par3col > parcol) + let parlnum = par3lnum + let parcol = par3col + endif + + " Put the cursor on the match + if parlnum > 0 + call cursor(parlnum, parcol) + endif + return parlnum +endfunction + +" Find the start of a multi-line statement +function! s:StatementStart(lnum) + let lnum = a:lnum + while 1 + if getline(lnum - 1) =~ '\\$' + let lnum = lnum - 1 + else + call cursor(lnum, 1) + let maybe_lnum = s:SearchParensPair() + if maybe_lnum < 1 + return lnum + else + let lnum = maybe_lnum + endif + endif + endwhile +endfunction + +" Find the block starter that matches the current line +function! s:BlockStarter(lnum, block_start_re) + let lnum = a:lnum + let maxindent = 10000 " whatever + while lnum > 1 + let lnum = prevnonblank(lnum - 1) + if indent(lnum) < maxindent + if getline(lnum) =~ a:block_start_re + return lnum + else + let maxindent = indent(lnum) + " It's not worth going further if we reached the top level + if maxindent == 0 + return -1 + endif + endif + endif + endwhile + return -1 +endfunction + +function! GetPythonIndent(lnum) + + " First line has indent 0 + if a:lnum == 1 + return 0 + endif + + " If we can find an open parenthesis/bracket/brace, line up with it. + call cursor(a:lnum, 1) + let parlnum = s:SearchParensPair() + if parlnum > 0 + let parcol = col('.') + let closing_paren = match(getline(a:lnum), '^\s*[])}]') != -1 + if match(getline(parlnum), '[([{]\s*$', parcol - 1) != -1 + if closing_paren + return indent(parlnum) + else + return indent(parlnum) + &shiftwidth + endif + else + if closing_paren + return parcol - 1 + else + return parcol + endif + endif + endif + + " Examine this line + let thisline = getline(a:lnum) + let thisindent = indent(a:lnum) + + " If the line starts with 'elif' or 'else', line up with 'if' or 'elif' + if thisline =~ '^\s*\(elif\|else\)\>' + let bslnum = s:BlockStarter(a:lnum, '^\s*\(if\|elif\)\>') + if bslnum > 0 + return indent(bslnum) + else + return -1 + endif + endif + + " If the line starts with 'except' or 'finally', line up with 'try' + " or 'except' + if thisline =~ '^\s*\(except\|finally\)\>' + let bslnum = s:BlockStarter(a:lnum, '^\s*\(try\|except\)\>') + if bslnum > 0 + return indent(bslnum) + else + return -1 + endif + endif + + " Examine previous line + let plnum = a:lnum - 1 + let pline = getline(plnum) + let sslnum = s:StatementStart(plnum) + + " If the previous line is blank, keep the same indentation + if pline =~ '^\s*$' + return -1 + endif + + " If this line is explicitly joined, try to find an indentation that looks + " good. + if pline =~ '\\$' + let compound_statement = '^\s*\(if\|while\|for\s.*\sin\|except\)\s*' + let maybe_indent = matchend(getline(sslnum), compound_statement) + if maybe_indent != -1 + return maybe_indent + else + return indent(sslnum) + &sw * 2 + endif + endif + + " If the previous line ended with a colon, indent relative to + " statement start. + if pline =~ ':\s*$' + return indent(sslnum) + &sw + endif + + " If the previous line was a stop-execution statement or a pass + if getline(sslnum) =~ '^\s*\(break\|continue\|raise\|return\|pass\)\>' + " See if the user has already dedented + if indent(a:lnum) > indent(sslnum) - &sw + " If not, recommend one dedent + return indent(sslnum) - &sw + endif + " Otherwise, trust the user + return -1 + endif + + " In all other cases, line up with the start of the previous statement. + return indent(sslnum) +endfunction diff --git a/.vim/plugin/ShowFunc.vim b/.vim/plugin/ShowFunc.vim new file mode 100644 index 0000000..a540892 --- /dev/null +++ b/.vim/plugin/ShowFunc.vim @@ -0,0 +1,566 @@ +" ------------------------------------------------------------------------------ +" Filename: ShowFunc.vim {{{ +" VimScript: #397 +" +" Maintainer: Dave Vehrs +" Last Modified: 28 Mar 2006 03:58:12 PM by Dave V +" +" Copyright: (C) 2002,2003,2004,2005,2006 Dave Vehrs +" +" This program is free software; you can redistribute it and/or +" modify it under the terms of the GNU General Public License as +" published by the Free Software Foundation; either version 2 of +" the License, or (at your option) any later version. +" +" This program is distributed in the hope that it will be useful, +" but WITHOUT ANY WARRANTY; without even the implied warranty of +" MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +" GNU General Public License for more details. +" +" You should have received a copy of the GNU General Public +" License along with this program; if not, write to the Free +" Software Foundation, Inc., 59 Temple Place, Suite 330, +" Boston, MA 02111-1307 USA _OR_ download at copy at +" http://www.gnu.org/licenses/licenses.html#TOCGPL +" +" Description: This script creates a hyper link list of all the functions, +" subroutines, classes, macros or procedures in a single file or +" all currently open windows and displays them in a dynamically +" sized cwindow. +" History: This script inspired by an idea posted by Flemming Madsen, in +" vimtip#79. +" +" WARNING: It may write the file as a side effect. +" Requires: Vim 6.0 or newer. +" Exuberant ctags (http://ctags.sourceforge.net/). +" Install: Put this file in the vim plugins directory (~/.vim/plugin) +" to load it automatically, or load it manually with +" :so ShowFunc.vim. +" +" Additional notes at end of file...}}} +" ------------------------------------------------------------------------------ +" Configuration: {{{ + +" Test for and if necessary configure all default settings. If you would like +" to change any setting, just add let g:variablename = "new-value" to your +" .vimrc. +" For Example, to change the location of the ctags binary, add this: +" let g:showfuncctagsbin = "/bin/ctags" +" OR +" let g:showfuncctagsbin = "c:\\gnu\\ctags\\ctags.exe" + +" Default ScanType Options: buffers | Scan all open buffers. +" current | Scan only the current buffer. +" windows | Scan all open windows. +if !exists("g:ShowFuncScanType") + let g:ShowFuncScanType = "buffers" +endif + +" Default SortType Options: yes | Display output sorted alphabetically. +" no | Display output in file order. +" foldcase | Display output sorted alphabetically, +" | disregarding case. +if !exists("g:ShowFuncSortType") + let g:ShowFuncSortType = "foldcase" +endif + +" You can limited the filetypes that are supported by listing them seperated +" by "^@". +" let g:CtagsSupportedFileTypes = "c^@python^@perl^@" + +" ----- +" Sometimes you'll get more results than you want and you can filter the +" output. + +" To find out what languages ctags supports: +" ctags --list-languages +" To find out what tags are supported for each language, execute: +" ctags --list-kinds= +" For example: +" ctags --list-kinds=vim +" a autocommand groups +" f function definitions +" v variable definitions + +" Now, we can set ctags to just search for functions like so: +" let g:ShowFunc_vim_Kinds = "f" +" To search for functions and autocommand groups: +" let g:ShowFunc_vim_Kinds = "af" +" let g:ShowFunc_vim_Kinds = "-a+f-v" +" To search for everything but variables: +" let g:ShowFunc_vim_Kinds = "-v" +let g:ShowFunc_vim_Kinds = "-v" +let g:ShowFunc_php_Kinds = "-v" + +" To set filters for other languages, simply set a global variable for them +" by replacing the _vim_ with the vim filetype (same as ctags for all +" languages but c++, then use cpp). +" let g:ShowFunc_cpp_Kinds = "-v" + +" }}} +" ------------------------------------------------------------------------------ +" Exit if already loaded. {{{ + +if ( exists("loaded_showfunc") || &cp ) | finish | endif +let g:loaded_showfunc=1 + +" Enable filetype detection +filetype on + +" }}} +" ------------------------------------------------------------------------------ +" AutoCommands: {{{ + +augroup showfunc_autocmd + autocmd! + autocmd BufEnter * call LastWindow() +augroup end + +" }}} +" ------------------------------------------------------------------------------ +" Functions: {{{ + +" Rotate through available scan types. +function! ChangeScanType() + if g:ShowFuncScanType == "buffers" | let g:ShowFuncScanType = "windows" + elseif g:ShowFuncScanType == "windows" | let g:ShowFuncScanType = "current" + elseif g:ShowFuncScanType == "current" | let g:ShowFuncScanType = "buffers" + endif + call ShowFuncOpen() +endfunction + +" Rotate through available sort types. +function! ChangeSortType() + if g:ShowFuncSortType == "no" | let g:ShowFuncSortType = "yes" + elseif g:ShowFuncSortType == "yes" | let g:ShowFuncSortType = "foldcase" + elseif g:ShowFuncSortType == "foldcase" | let g:ShowFuncSortType = "no" + endif + call ShowFuncOpen() +endfunction + +" Ctags binary tests +function! s:CtagsTest(path) + " if the location of the ctags executable is not already configured, then + " attempt to find it.... + if a:path == "unk" + let l:test_paths = "/usr/local/bin/ctags /usr/bin/ctags" . + \ " C:\\gnu\\ctags\\ctags.exe " + let l:rpath = "fail" + while l:test_paths != '' + let l:pathcut = strpart(l:test_paths,0,stridx(l:test_paths,' ')) + if executable(l:pathcut) + let l:rpath = s:CtagsVersionTest(l:pathcut) + if l:rpath != "fail" + break + endif + endif + let l:test_paths = strpart(l:test_paths,stridx(l:test_paths,' ') + 1) + endwhile + if l:rpath == "fail" + if !has("gui_running") || has("win32") + echo "ShowFunc Error: Ctags binary not found.\n". + \ "Please set g:showfuncctagsbin in your .vimrc.\n" + endif + endif + else + " Else test the variable to see that it is actually an executable. + if executable(a:path) + let l:rpath = s:CtagsVersionTest(a:path) + else + if ( !has("gui_running") || has("win32") ) + echo "ShowFunc Error: Ctags binary not found.\n". + \ "Your g:showfuncctagsbin may be set incorrectly.\n" + endif + let g:loaded_showfunc = 0 + let l:rpath = "fail" + endif + endif + return l:rpath +endfunction + +" Test to be sure we have Exuberant Ctags. +function! s:CtagsVersionTest(path) + " Test Ctags for correct ctags project.. + let l:test_str = strtrans(system(a:path . " -x --version")) + let ctagsvertest = strpart(l:test_str,0,15) + if ctagsvertest != "Exuberant Ctags" + if ( !has("gui_running") || has("win32") ) + echo "ShowFunc Error: Incorrect Version of Ctags.\n". + \ "Download the correct version from http://ctags.sourceforge.net" + endif + let g:loaded_showfunc = 0 + let l:rpath = "fail" + else + let l:rpath = a:path + " Set Ctags version variables. + let g:CtagsMajorVersion = strpart(l:test_str,(stridx(l:test_str,"s ")+2), + \ (stridx(l:test_str,".")-(stridx(l:test_str,"s ")+2)) ) + let l:test_str2 = strpart(l:test_str,(stridx(l:test_str,".")+1)) + if ((stridx(l:test_str2,".") < stridx(l:test_str2,",")) && (stridx(l:test_str2,".") >= 0)) + let g:CtagsSubVersion = strpart(l:test_str2, + \ (stridx(l:test_str2,".")+1),(stridx(l:test_str2,",")-(stridx(l:test_str2,".")+1))) + + let g:CtagsMinorVersion = strpart(l:test_str2,0, + \ (stridx(l:test_str2,"."))) + else + let g:CtagsMinorVersion = strpart(l:test_str2,0, + \ (stridx(l:test_str2,","))) + let g:CtagsSubVersion = "0" + endif + " Test for correct versions. + if g:CtagsMajorVersion < 5 + echo "Exuberant Ctags needs to be upgraded for ShowFunc to work." + echo "Please visit http://ctags.sourceforge,net." + let l:rpath = "fail" + elseif g:CtagsMinorVersion <= 4 + echo "Exuberant Ctags should be upgraded, some features of the" + echo "ShowFunc script may not work." + echo "Please visit http://ctags.sourceforge,net." + endif + " Define default supported file types list for Ctags versions 5.5 and newer. + if (!exists("g:CtagsSupportedFileTypes") && g:CtagsMajorVersion == 5 && + \ g:CtagsMinorVersion >= 5) + let g:CtagsSupportedFileTypes = strtrans(system(l:rpath . + \ " -x --list-languages")) + endif + endif + return l:rpath +endfunction + + " Display a simple help window. +function! DisplayHelp() + echo "ShowFunc Help: \n". + \ " c Close \n". + \ " r Refresh \n". + \ " s Change Scan Sort \n". + \ " t Change Scan Type \n" +endfunction + +" Watch for last window and if its a CWindow, then close (vimtip#536). +function! LastWindow() + if ( &buftype == "quickfix" ) + if winbufnr(2) == -1 + quit! + endif + endif +endfunction + +" Determine the best window height for the new cwindow and open it. +function! s:OpenCWin() + let l:mod_total = 0 + let l:win_count = 1 + " Determine correct window height + windo let l:win_count = l:win_count + 1 + if l:win_count <= 2 | let l:win_count = 4 | endif + windo let l:mod_total = l:mod_total + winheight(0)/l:win_count | + \ execute 'resize +'.l:mod_total + " Open cwindow + execute 'belowright copen '.l:mod_total + let l:cwin_filelen = line("$") + " Test for short output lists. + if l:cwin_filelen < winheight(0) + cclose + " And adjust cwindow height accordingly. + execute 'belowright copen '.l:cwin_filelen + endif + if v:version >= 700 + setlocal statusline=ShowFunc.vim\ Tag\ List + endif + " Set cwindow specific key mappings. + nnoremap c :cclose + nnoremap h :call DisplayHelp() + nnoremap r :call ShowFuncOpen() + nnoremap s :call ChangeSortType() + nnoremap t :call ChangeScanType() + set nobuflisted + return +endfunction + +" Set Folds by filename. +function! s:ShowFuncFolds() + let l:test_line = getline(v:lnum) + let l:test_filename = strpart(l:test_line,0,stridx(l:test_line,'|')) + if g:FoldFileName == '' + let g:FoldFileName = l:test_filename + return ">1" + elseif g:FoldFileName == l:test_filename + return "=" + else + let g:FoldFileName = l:test_filename + return ">1" + endif +endfunction + +" Set FoldText to filename and tag count. +function! ShowFuncFoldText() + let l:line = "" + let l:textwidth = &textwidth - 20 + let l:line = getline(v:foldstart) + let l:line = strpart(l:line,0,stridx(l:line,'|')) + if strlen(l:line) < l:textwidth + let l:count = 59 - strlen(l:subline) + while strlen(l:line) < l:textwidth + let l:line = l:line." " + endwhile + endif + let l:tag_count = v:foldend - v:foldstart + 1 + if l:tag_count <= 9 + return v:folddashes."+ File: ".l:line." Tags: ". l:tag_count." " + elseif l:tag_count <= 99 + return v:folddashes."+ File: ".l:line." Tags: ". l:tag_count." " + elseif l:tag_count <= 999 + return v:folddashes."+ File: ".l:line." Tags: ". l:tag_count." " + else + return v:folddashes."+ File: ".l:line." Tags: ". l:tag_count." " + endif +endfunction + +" Set ctags options to call. +function! s:SetGrepPrg(sort) + if g:CtagsMinorVersion < 5 + if ( &filetype == "asm" || &filetype == "asp" || &filetype == "awk" || + \ &filetype == "beta" || &filetype == "c" || &filetype == "cobol" || + \ &filetype == "eiffel" || &filetype == "fortran" || &filetype == "java" || + \ &filetype == "lisp" || &filetype == "lua" || &filetype == "make" || + \ &filetype == "pascal" || &filetype == "perl" || &filetype == "php" || + \ &filetype == "python" || &filetype == "rexx" || &filetype == "ruby" || + \ &filetype == "scheme" || &filetype == "sh" || &filetype == "slang" || + \ &filetype == "sql" || &filetype == "tcl" || &filetype == "vera" || + \ &filetype == "verilog" || &filetype == "vim" || &filetype == "yacc" ) + let l:grep_return = g:showfuncctagsbin .' -x --language-force=' . &filetype . + \ ' --sort=' . a:sort + elseif &filetype == "cpp" + let l:grep_return = g:showfuncctagsbin .' -x --language-force=c++ --sort=' . + \ a:sort + else + return "fail" + endif + else + if &filetype == "cpp" | let l:cfiletype = "c++" + else | let l:cfiletype = &filetype | endif + let l:filetest = s:TestFileType(l:cfiletype) + if l:filetest != "false" + if exists("g:ShowFunc_{&filetype}_Kinds") + let l:grep_return = g:showfuncctagsbin . ' -x --language-force=' . + \ l:cfiletype . ' --' . l:cfiletype . '-kinds=' . + \ g:ShowFunc_{&filetype}_Kinds . ' --sort=' . a:sort + else + let l:grep_return = g:showfuncctagsbin . ' -x --language-force=' . + \ l:cfiletype . ' --sort=' . a:sort + endif + else | let l:grep_return = "fail" | endif + endif + return l:grep_return +endfunction + +function! ShowFuncOpen() + set lazyredraw + " Close any existing cwindows. + cclose + if &lines >= 8 + let l:count = 0 + let l:gf_s = &grepformat + let l:gp_s = &grepprg + set grepformat&vim + set grepprg&vim + let &grepformat = '%*\k%*\s%t%*\k%*\s%l%*\s%f\ %m' + if ( g:ShowFuncScanType == "buffers" ) + " Scan all open buffers. + let l:currbuf = bufnr("%") + bufdo! let &grepprg = s:SetGrepPrg(g:ShowFuncSortType) | + \ if &grepprg != "fail" | if &readonly == 0 | update | endif | + \ if l:count == 0 | silent! grep! % | let l:count = l:count + 1 | + \ else | silent! grepadd! % | endif | endif + execute 'buffer '.l:currbuf + elseif g:ShowFuncScanType == "windows" + " Scan all open windows. + windo let &grepprg = s:SetGrepPrg(g:ShowFuncSortType) | + \ if &grepprg != "fail" | if &readonly == 0 | update | endif | + \ if l:count == 0 | silent! grep! %| let l:count = l:count + 1 | + \ else | silent! grepadd! % | endif | endif + elseif g:ShowFuncScanType == "current" + " Scan current buffer only. + let &grepprg = s:SetGrepPrg(g:ShowFuncSortType) + if &grepprg != "fail" + if &readonly == 0 | update | endif + silent! grep! % + else + echohl WarningMsg + echo "ShowFunc Error: Unknown FileType" + echohl none + endif + endif + let &grepformat = l:gf_s + let &grepprg = l:gp_s + execute s:OpenCWin() + if ( g:ShowFuncScanType == "buffers" || g:ShowFuncScanType == "windows" ) + " Do folding. + let g:FoldFileName = '' + setlocal foldexpr=s:ShowFuncFolds() + setlocal foldmethod=expr + setlocal foldtext=ShowFuncFoldText() + endif + else + echohl WarningMsg + echo "ShowFunc Error: Window too small.\n" + echohl none + endif + set nolazyredraw + redraw! +endfunction + +" Test for supported filetype. +function! s:TestFileType(type) + let l:supportedfiles = g:CtagsSupportedFileTypes + while l:supportedfiles != "^@" && l:supportedfiles != "" + let l:sfcut = strpart(l:supportedfiles,0,stridx(l:supportedfiles,"^@")) + if l:sfcut ==? a:type + return "true" + endif + let l:supportedfiles = strpart(l:supportedfiles, + \ stridx(l:supportedfiles,'^@')+2) + endwhile + return "false" +endfunction +" }}} +" ------------------------------------------------------------------------------ +" Test Environment: {{{ +" Test Ctags Binary to be sure its the correct version. +if exists("g:showfuncctagsbin") + let g:showfuncctagsbin = s:CtagsTest(g:showfuncctagsbin) +endif +if (!exists("g:showfuncctagsbin") || g:showfuncctagsbin == "fail") + let g:showfuncctagsbin = s:CtagsTest("unk") +endif + +" If a suitable ctags binary cannot be found, remove autocommands, clear +" functions and exit script. +if g:showfuncctagsbin == "fail" + echo "ShowFunc exting. (Cleaning up functions)" + let g:loaded_showfunc = 0 + augroup! showfunc_autocmd + delfunction ChangeScanType + delfunction ChangeSortType + delfunction s:CtagsTest + delfunction s:CtagsVersionTest + delfunction DisplayHelp + delfunction LastWindow + delfunction s:OpenCWin + delfunction s:ShowFuncFolds + delfunction s:ShowFuncFoldText + delfunction s:SetGrepPrg + delfunction ShowFuncOpen + delfunction s:TestFileType + finish +endif + +" }}} +" ------------------------------------------------------------------------------ +" Key Mappings: {{{ +" To change the main key mapping, add this to your .vimrc file: +" map ShowFunc + +if ( !hasmapto('ShowFunc') && (maparg('') == '') ) + map ShowFunc + map! ShowFunc +elseif !hasmapto('ShowFunc') + if ( !has("gui_running") || has("win32") ) + echo "ShowFunc Error: No Key mapped.\n". + \ " is taken and a replacement was not assigned." + endif + let g:loaded_showfunc = 0 + finish +endif +noremap ShowFunc :call ShowFuncOpen() +noremap! ShowFunc :call ShowFuncOpen() + +" Note: Cwindow specific key mappings can be found in the OpenCWin function. }}} +" ------------------------------------------------------------------------------ +" Known Issues: {{{ +" 1. Error messages that occur as gvim is loading (on Linux) do not display in +" GUI windows. When called from a menu or icon, it appears that gvim is hung +" (it appears in the ps listings but no window appears). To avoid this I +" have disabled the display of errors during gvim loading and the ShowFunc +" script simply exits. +" }}} +" ------------------------------------------------------------------------------ +" Feature Wishlist: {{{ +" 1. If scan is set to "current", make cwindow update on buffer change (except +" to the cwindow) +" 2. Window size ratios should remain the same as ShowFunc opens and closes. +" 3. Patch vim to allow for setlocal statusline. +" 4. Expand error format format so that the tag type is grabbed by grep. +" }}} +" ------------------------------------------------------------------------------ +" Notes: {{{ +" 1. Best veiwed with AutoFold.vim (vimscript#925) and ShowFunc.vim +" (vimscript#397). +" }}} +" ------------------------------------------------------------------------------ +" Version History: {{{ +" 1.0 08-24-2002 Initial Release. +" 1.1 08-26-2002 Patches to Fortran (thanks to Ajit Thakkar), Pascal, +" and Python support. +" 1.1.1 08-26-2002 Fixed copy&paste errors. ooops. +" 1.1.2 08-27-2002 Removed the Python patch. +" 1.1.3 08-31-2002 Fixed Fortran and Pascal patches, Thanks to Ajit Thakkar, +" and Engelbert Gruber. +" 1.2 09-22-2002 Fixed redraw bug so that it works with the Winmanager +" (vimscript#95) and Bufexplorer (vimscript#42) scripts. +" 1.2.1 10-17-2002 Added unknown filetype handling. Added status messages +" ('ShowFunc:'). Fixed key-mappings. +" 1.3Beta 11-16-2002 Beta: Multiple file handling. Restructured script. +" 1.3Beta2 11-20-2002 Beta: Fixed Multiple file cwindow refresh issue (grep +" vs. grepadd). +" 1.3Beta3 11-29-2002 Beta: Split SetFileType into two ( SetGrepFormat, and +" SetGrepPrg ). Set &...&vim to insure proper '\ multiline +" translation. Added keymapping testing to protect against +" conflicting with existing user configurations and to make +" it easy to remap when necessary. Thanks to Luc Hermitte +" 1.3 12-01-2002 Fixed buffer display issue (Thanks to vimtip#133). Fixed +" window height test for TestWinH and OpenCWin. Changed +" MultiWin (scans all open windows) to MultiBuf (scans all +" open buffers). Basic multiple file handling is complete. +" 1.4 12-21-2002 Changed user interface. Eliminated multiple key-mappings. +" Pressing F1 runs the default scan, and opens the cwindow. +" Scan sort and type can be changed by pressing the s and t +" keys respectively. Unifed scan types into one function +" (ShowFuncOpen) and bought back the all open windows scan. +" 1.4.1 01-19-2003 Fixed multi-window scan display issue. Improved dynamic +" cwindow sizing. Added basic help dialog. +" 1.4.2 03-13-2003 Rewrote the SetGrepFormat and SetGrepPrg functions. Added +" support for all tags for all languages that Exburent +" Ctags (ver. 5.4) supports. +" 1.4.3 03-15-2003 Automatically fold output on filename for multiple file +" scans (all buffers or windows). +" 1.4.4 03-17-2003 Improved error handling. Improved SetFoldText(). +" 1.4.5 03-22-2003 More error handling improvements, including tests for the +" correct version of ctags, and keymap assignment. I want +" to thank Mark Thomas for his assistance in finding and +" fixing a bug in the ctags executable detection on Windows. +" 1.5 09-21-2003 Created a more generic grep format so that explicit type +" definitions are no longer necessary (eliminating the +" SetGrepFormat function). Modified the SetGrepPrg function +" to detect Ctags versions earlier than 5.5. Supportted +" filetypes for Ctags versions 5.4 are statically +" assigned. +" With Ctags versions 5.5 (and later) supported filetypes +" are detected dynamically (including those defined by +" regular expressions (--regex-). +" 1.5.1 09-25-2003 Bug Fixes. +" 1.5.2 10-06-2003 Improved Exuberant Ctags version checking. +" 1.5.3 10-15-2004 Fixed ShowFuncFoldText. +" 1.5.4 01-13-2005 Script cleanup. Added MyLastWindow function (when +" closing windows, tests last window to see if its a +" Cwindow, if it is then close vim session). +" 1.5.5 07-20-2005 Patches from two Windows users (David Rennalls and Bill +" McCarthy). Fixes in cleanup, documentaion, and autocmds. +" 1.5.6 02-28-2006 First Vim 7 patches. Added setlocal statusline support +" to update the cwindow name. +" 1.5.7 03-27-2006 Per request by Diederik Van der Boor, added ability to +" filter the variables kinds that ctags outputs (ver 5.5 +" or newer). +" +" }}} +" ------------------------------------------------------------------------------ +" vim:tw=80:ts=2:sw=2: diff --git a/.vim/plugin/conque_term.vim b/.vim/plugin/conque_term.vim index 42dad68..2ed9e73 100644 --- a/.vim/plugin/conque_term.vim +++ b/.vim/plugin/conque_term.vim @@ -1,9 +1,10 @@ " FILE: plugin/conque_term.vim {{{ " AUTHOR: Nico Raffo -" MODIFIED: 2010-02-02 -" VERSION: 1.0, for Vim 7.0 +" WEBSITE: http://conque.googlecode.com +" MODIFIED: 2010-11-15 +" VERSION: 2.0, for Vim 7.0 " LICENSE: -" Conque - pty interaction in Vim +" Conque - Vim terminal/console emulator " Copyright (C) 2009-2010 Nico Raffo " " MIT License @@ -37,7 +38,37 @@ endif " **** CONFIG ********************************************************************************************** " ********************************************************************************************************** -" Enable color {{{ +" {{{ + +" automatically go into insert mode when entering buffer {{{ +if !exists('g:ConqueTerm_InsertOnEnter') + let g:ConqueTerm_InsertOnEnter = 0 +endif " }}} + +" Allow user to use keys to switch window in insert mode. {{{ +if !exists('g:ConqueTerm_CWInsert') + let g:ConqueTerm_CWInsert = 0 +endif " }}} + +" Choose key mapping to leave insert mode {{{ +" If you choose something other than '', then will be sent to terminal +" Using a different key will usually fix Alt/Meta key issues +if !exists('g:ConqueTerm_EscKey') + let g:ConqueTerm_EscKey = '' +endif " }}} + +" Use this key to send selected text to conque. {{{ +if !exists('g:ConqueTerm_SendVisKey') + let g:ConqueTerm_SendVisKey = '' +endif " }}} + +" Use this key to toggle terminal key mappings. {{{ +if !exists('g:ConqueTerm_ToggleKey') + let g:ConqueTerm_ToggleKey = '' +endif " }}} + +" Enable color. {{{ +" If your apps use a lot of color it will slow down the shell. if !exists('g:ConqueTerm_Color') let g:ConqueTerm_Color = 1 endif " }}} @@ -52,9 +83,9 @@ if !exists('g:ConqueTerm_Syntax') let g:ConqueTerm_Syntax = 'conque_term' endif " }}} -" Read when unfocused {{{ +" Keep on updating the shell window after you've switched to another buffer {{{ if !exists('g:ConqueTerm_ReadUnfocused') - let g:ConqueTerm_ReadUnfocused = 1 + let g:ConqueTerm_ReadUnfocused = 0 endif " }}} " Use this regular expression to highlight prompt {{{ @@ -62,19 +93,47 @@ if !exists('g:ConqueTerm_PromptRegex') let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$' endif " }}} +" Choose which Python version to attempt to load first {{{ +" Valid values are 2, 3 or 0 (no preference) +if !exists('g:ConqueTerm_PyVersion') + let g:ConqueTerm_PyVersion = 2 +endif " }}} + +" Path to python.exe. (Windows only) {{{ +" By default, Conque will check C:\PythonNN\python.exe then will search system path +" If you have installed Python in an unusual location and it's not in your path, fill in the full path below +" E.g. 'C:\Program Files\Python\Python27\python.exe' +if !exists('g:ConqueTerm_PyExe') + let g:ConqueTerm_PyExe = '' +endif " }}} + +" Automatically close buffer when program exits {{{ +if !exists('g:ConqueTerm_CloseOnEnd') + let g:ConqueTerm_CloseOnEnd = 0 +endif " }}} + +" Send function key presses to terminal {{{ +if !exists('g:ConqueTerm_SendFunctionKeys') + let g:ConqueTerm_SendFunctionKeys = 0 +endif " }}} + +" }}} + " ********************************************************************************************************** " **** Startup ********************************************************************************************* " ********************************************************************************************************** " Startup {{{ -setlocal encoding=utf-8 let g:ConqueTerm_Loaded = 1 -let g:ConqueTerm_Idx = 1 +let g:ConqueTerm_Idx = 0 +let g:ConqueTerm_Version = 200 command! -nargs=+ -complete=shellcmd ConqueTerm call conque_term#open() -command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(, ['split']) -command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(, ['vsplit']) +command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(, ['belowright split']) +command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(, ['belowright vsplit']) +command! -nargs=+ -complete=shellcmd ConqueTermTab call conque_term#open(, ['tabnew']) " }}} +" vim:foldmethod=marker diff --git a/.vim/syntax/conque_term.vim b/.vim/syntax/conque_term.vim index aabb017..927cbd5 100644 --- a/.vim/syntax/conque_term.vim +++ b/.vim/syntax/conque_term.vim @@ -1,23 +1,56 @@ +" FILE: syntax/conque_term.vim {{{ +" AUTHOR: Nico Raffo +" WEBSITE: http://conque.googlecode.com +" MODIFIED: 2010-11-15 +" VERSION: 2.0, for Vim 7.0 +" LICENSE: +" Conque - Vim terminal/console emulator +" 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. +" }}} + " ******************************************************************************************************************* " MySQL ************************************************************************************************************* " ******************************************************************************************************************* +" TODO Move these to syntax which is only executed for mysql +"syn match MySQLTableBodyG "^\s*\w\+:\(.\+\)\=$" contains=MySQLTableHeadG,MySQLNullG,MySQLBool,MySQLNumberG,MySQLStorageClass oneline skipwhite skipnl +"syn match MySQLTableHeadG "^\s*\w\+:" contains=MySQLTableColon skipwhite contained +"syn match MySQLTableColon ":" contained + syn match MySQLTableHead "^ *|.*| *$" nextgroup=MySQLTableDivide contains=MySQLTableBar oneline skipwhite skipnl syn match MySQLTableBody "^ *|.*| *$" nextgroup=MySQLTableBody,MySQLTableEnd contains=MySQLTableBar,MySQLNull,MySQLBool,MySQLNumber,MySQLStorageClass oneline skipwhite skipnl syn match MySQLTableEnd "^ *+[+=-]\++ *$" oneline syn match MySQLTableDivide "^ *+[+=-]\++ *$" nextgroup=MySQLTableBody oneline skipwhite skipnl syn match MySQLTableStart "^ *+[+=-]\++ *$" nextgroup=MySQLTableHead oneline skipwhite skipnl -syn match MySQLTableBar "|" contained -syn match MySQLNull " NULL " contained -syn match MySQLBool " YES " contained -syn match MySQLBool " NO " contained +syn match MySQLNull " NULL " contained contains=MySQLTableBar syn match MySQLStorageClass " PRI " contained syn match MySQLStorageClass " MUL " contained syn match MySQLStorageClass " UNI " contained syn match MySQLStorageClass " CURRENT_TIMESTAMP " contained syn match MySQLStorageClass " auto_increment " contained -syn match MySQLNumber " \d\+ " contained +syn match MySQLTableBar "|" contained +syn match MySQLNumber "|\? *\d\+\(\.\d\+\)\? *|" contained contains=MySQLTableBar syn match MySQLQueryStat "^\d\+ rows\? in set.*" oneline syn match MySQLPromptLine "^.\?mysql> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline syn match MySQLPromptLine "^ -> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline @@ -25,12 +58,13 @@ syn match MySQLPrompt "^.\?mysql>" contained oneline syn match MySQLPrompt "^ ->" contained oneline syn case ignore syn keyword MySQLKeyword select count max sum avg date show table tables status like as from left right outer inner join contained -syn keyword MySQLKeyword where group by having limit offset order desc asc show contained +syn keyword MySQLKeyword where group by having limit offset order desc asc show contained and interval is null on syn case match syn region MySQLString start=+'+ end=+'+ skip=+\\'+ contained oneline syn region MySQLString start=+"+ end=+"+ skip=+\\"+ contained oneline syn region MySQLString start=+`+ end=+`+ skip=+\\`+ contained oneline + hi def link MySQLPrompt Identifier hi def link MySQLTableHead Title hi def link MySQLTableBody Normal @@ -64,9 +98,11 @@ endif " ******************************************************************************************************************* " Typical Prompt -silent execute "syn match ConquePromptLine '" . g:ConqueTerm_PromptRegex . ".*$' contains=ConquePrompt,ConqueString oneline" -silent execute "syn match ConquePrompt '" . g:ConqueTerm_PromptRegex . "' contained oneline" -hi def link ConquePrompt Identifier +if g:ConqueTerm_PromptRegex != '' + silent execute "syn match ConquePromptLine '" . g:ConqueTerm_PromptRegex . ".*$' contains=ConquePrompt,ConqueString oneline" + silent execute "syn match ConquePrompt '" . g:ConqueTerm_PromptRegex . "' contained oneline" + hi def link ConquePrompt Identifier +endif " Strings syn region ConqueString start=+'+ end=+'+ skip=+\\'+ contained oneline