├── autoload ├── vital │ ├── vimconsole.vital │ ├── _vimconsole │ │ └── Bitwise.vim │ └── _vimconsole.vim ├── vital.vim ├── quickrun │ └── outputter │ │ └── vimconsole.vim ├── vimconsole │ ├── async.vim │ └── enc.vim └── vimconsole.vim ├── doc ├── .gitignore └── vimconsole.txt ├── README.md ├── plugin └── vimconsole.vim └── LICENSE.txt /autoload/vital/vimconsole.vital: -------------------------------------------------------------------------------- 1 | vimconsole 2 | 8da44ea 3 | 4 | Bitwise 5 | -------------------------------------------------------------------------------- /doc/.gitignore: -------------------------------------------------------------------------------- 1 | 2 | tags 3 | 4 | # vim: set ft=gitignore fdm=manual ff=unix : 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | # vim-vimconsole 3 | 4 | This is Immediate Window for Vim script. 5 | It is like Google Chrome Developer Console. 6 | 7 | # LICENSE 8 | 9 | Distributed under MIT License. See LICENSE.txt 10 | 11 | -------------------------------------------------------------------------------- /autoload/vital.vim: -------------------------------------------------------------------------------- 1 | function! vital#of(name) 2 | let files = globpath(&runtimepath, 'autoload/vital/' . a:name . '.vital') 3 | let file = split(files, "\n") 4 | if empty(file) 5 | throw 'vital: version file not found: ' . a:name 6 | endif 7 | let ver = readfile(file[0], 'b') 8 | if empty(ver) 9 | throw 'vital: invalid version file: ' . a:name 10 | endif 11 | return vital#_{substitute(ver[0], '\W', '', 'g')}#new() 12 | endfunction 13 | -------------------------------------------------------------------------------- /plugin/vimconsole.vim: -------------------------------------------------------------------------------- 1 | 2 | scriptencoding utf-8 3 | 4 | if exists("g:loaded_vimconsole") 5 | finish 6 | endif 7 | let g:loaded_vimconsole = 1 8 | 9 | let s:save_cpo = &cpo 10 | set cpo&vim 11 | 12 | let g:vimconsole#startinsert = get(g:, 'vimconsole#startinsert', 0) 13 | let g:vimconsole#auto_redraw = get(g:,'vimconsole#auto_redraw',0) 14 | let g:vimconsole#enable_quoted_string = get(g:,'vimconsole#enable_quoted_string', 1) 15 | let g:vimconsole#eval_function_name = get(g:,'vimconsole#eval_function_name','eval') 16 | let g:vimconsole#height = get(g:,'vimconsole#height', '&lines / 2') 17 | let g:vimconsole#hooks = get(g:,'vimconsole#hooks',{}) 18 | let g:vimconsole#no_default_key_mappings = get(g:,'vimconsole#no_default_key_mappings', 0) 19 | let g:vimconsole#session_type = get(g:,'vimconsole#session_type', 't:') 20 | let g:vimconsole#split_rule = get(g:,'vimconsole#split_rule', 'bottom') 21 | let g:vimconsole#width = get(g:,'vimconsole#width', '&columns / 2') 22 | 23 | call vimconsole#define_commands() 24 | 25 | let &cpo = s:save_cpo 26 | finish 27 | 28 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | LICENSE 3 | ======= 4 | 5 | |vimconsole.vim| is distributed under MIT license. 6 | 7 | Copyright (c) 2014 rbtnn 8 | 9 | Permission is hereby granted, free of charge, to any person obtaining 10 | a copy of this software and associated documentation files (the 11 | "Software"), to deal in the Software without restriction, including 12 | without limitation the rights to use, copy, modify, merge, publish, 13 | distribute, sublicense, and/or sell copies of the Software, and to 14 | permit persons to whom the Software is furnished to do so, subject to 15 | the following conditions: 16 | 17 | The above copyright notice and this permission notice shall be included 18 | in all copies or substantial portions of the Software. 19 | 20 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 21 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 22 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 23 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 24 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 25 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 26 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 27 | -------------------------------------------------------------------------------- /autoload/quickrun/outputter/vimconsole.vim: -------------------------------------------------------------------------------- 1 | 2 | let s:save_cpo = &cpo 3 | set cpo&vim 4 | 5 | let s:outputter = { 6 | \ 'config': { 7 | \ 'height': g:vimconsole#height, 8 | \ 'width': g:vimconsole#width, 9 | \ 'split_rule': g:vimconsole#split_rule, 10 | \ 'enable_quoted_string': g:vimconsole#enable_quoted_string, 11 | \ } 12 | \ } 13 | 14 | let s:caches = {} 15 | 16 | function! s:outputter.init(session) 17 | let s:caches['height'] = g:vimconsole#height 18 | let s:caches['width'] = g:vimconsole#width 19 | let s:caches['split_rule'] = g:vimconsole#split_rule 20 | let s:caches['enable_quoted_string'] = g:vimconsole#enable_quoted_string 21 | endfunction 22 | 23 | function! s:outputter.start(session) 24 | endfunction 25 | 26 | function! s:outputter.output(data, session) 27 | call vimconsole#log(a:data) 28 | endfunction 29 | 30 | function! s:outputter.sweep() 31 | let g:vimconsole#height = s:caches['height'] 32 | let g:vimconsole#width = s:caches['width'] 33 | let g:vimconsole#split_rule = s:caches['split_rule'] 34 | let g:vimconsole#enable_quoted_string = s:caches['enable_quoted_string'] 35 | endfunction 36 | 37 | function! s:outputter.finish(session) 38 | let g:vimconsole#height = self.config.height 39 | let g:vimconsole#width = self.config.width 40 | let g:vimconsole#split_rule = self.config.split_rule 41 | let g:vimconsole#enable_quoted_string = self.config.enable_quoted_string 42 | 43 | call vimconsole#winopen('!') 44 | endfunction 45 | 46 | function! quickrun#outputter#vimconsole#new() 47 | return deepcopy(s:outputter) 48 | endfunction 49 | 50 | let &cpo = s:save_cpo 51 | unlet s:save_cpo 52 | 53 | -------------------------------------------------------------------------------- /autoload/vimconsole/async.vim: -------------------------------------------------------------------------------- 1 | 2 | scriptencoding utf-8 3 | 4 | function! s:receive_vimproc_result(key) 5 | let session = vimconsole#async#session(a:key).session 6 | let vimproc = session._vimproc 7 | 8 | try 9 | if !has_key(session, 'stop') 10 | if !vimproc.stdout.eof 11 | call session.outputter(vimproc.stdout.read(), 'stdout') 12 | endif 13 | if !vimproc.stderr.eof 14 | call session.outputter(vimproc.stderr.read(), 'stderr') 15 | endif 16 | 17 | if !(vimproc.stdout.eof && vimproc.stderr.eof) 18 | call feedkeys(mode() ==# 'i' ? "\\" : "g\", 'n') 19 | return 0 20 | endif 21 | endif 22 | catch 23 | call session.outputter(('async vimproc: ' . v:throwpoint . "\n" . v:exception), '_') 24 | endtry 25 | 26 | call vimproc.stdout.close() 27 | call vimproc.stderr.close() 28 | call vimproc.waitpid() 29 | call session.finalizer(get(vimproc, 'status', 1)) 30 | call session.sweep(get(vimproc, 'status', 1)) 31 | return 1 32 | endfunction 33 | function! s:async_system(commands, ...) 34 | let session = get(a:000, 0, {}) 35 | 36 | let session.input = get(session,'input', '') 37 | let session.key = get(session,'key', fnamemodify(tempname(), ':t:r')) 38 | let session.runner_id = get(session,'runner_id', 'plugin-async-runner-vimproc-' . session.key) 39 | let session.config = get(session,'config',{}) 40 | let session.config.updatetime = get(session.config,'updatetime',0) 41 | let session.config.sleep = get(session.config,'sleep',50) 42 | 43 | call vimconsole#async#session(session.key, session) 44 | 45 | execute 'augroup ' . session.runner_id 46 | execute 'augroup END' 47 | 48 | let vimproc = vimproc#pgroup_open(join(a:commands, ' && ')) 49 | call vimproc.stdin.write(session.input) 50 | call vimproc.stdin.close() 51 | 52 | let session._vimproc = vimproc 53 | 54 | if ! has_key(session,'initializer') 55 | let session['initializer'] = function('vimconsole#async#default_initializer') 56 | endif 57 | 58 | if ! has_key(session,'outputter') 59 | let session['outputter'] = function('vimconsole#async#default_outputter') 60 | endif 61 | 62 | if ! has_key(session, 'finalizer') 63 | let session['finalizer'] = function('vimconsole#async#default_finalizer') 64 | endif 65 | 66 | function! session.sweep(vimproc_status) 67 | if has_key(self, '_autocmd') 68 | execute 'autocmd! ' . self.runner_id 69 | endif 70 | if has_key(self, '_updatetime') 71 | let &updatetime = self._updatetime 72 | endif 73 | execute 'augroup! ' . self.runner_id 74 | endfunction 75 | 76 | if session.config.sleep 77 | execute 'sleep' session.config.sleep . 'm' 78 | endif 79 | 80 | call session.initializer() 81 | if s:receive_vimproc_result(session.key) 82 | return 83 | endif 84 | 85 | execute 'augroup ' . session.runner_id 86 | execute ' autocmd! CursorHold,CursorHoldI * call s:receive_vimproc_result(' . string(session.key) . ')' 87 | execute 'augroup END' 88 | 89 | let session._autocmd = 1 90 | if session.config.updatetime 91 | let session._updatetime = &updatetime 92 | let &updatetime = session.config.updatetime 93 | endif 94 | endfunction 95 | 96 | function! vimconsole#async#default_outputter(...) dict 97 | let data = get(a:000, 0, '') 98 | let type = get(a:000, 1, '') 99 | if type is 'stdout' 100 | call vimconsole#log(join(vimconsole#enc#iconv(data), "\n")) 101 | elseif type is 'stderr' 102 | call vimconsole#log(join(vimconsole#enc#iconv(data), "\n")) 103 | endif 104 | endfunction 105 | function! vimconsole#async#default_finalizer(vimproc_status) dict 106 | call vimconsole#log(printf('[vimconsole] async session end: %s', self.key)) 107 | endfunction 108 | function! vimconsole#async#default_initializer() dict 109 | call vimconsole#log(printf('[vimconsole] async session begin: %s', self.key)) 110 | endfunction 111 | 112 | function! vimconsole#async#stop() 113 | let s:async_sessions = get(s:,'async_sessions',{}) 114 | for key in keys(s:async_sessions) 115 | let session = vimconsole#async#session(key).session 116 | let session['stop'] = 1 117 | endfor 118 | endfunction 119 | function! vimconsole#async#session(key,...) 120 | let s:async_sessions = get(s:,'async_sessions',{}) 121 | if 0 < a:0 122 | let s:async_sessions[ a:key ] = a:1 123 | else 124 | let s:async_sessions[ a:key ] = get(s:async_sessions,a:key,{}) 125 | endif 126 | return { 'key' : a:key, 'session' : s:async_sessions[ a:key ] } 127 | endfunction 128 | function! vimconsole#async#system(input_str, ...) 129 | try 130 | call vimproc#version() 131 | call s:async_system([(a:input_str)], { 132 | \ 'initializer' : 0 < a:0 ? a:1 : function('vimconsole#async#default_initializer'), 133 | \ 'outputter' : 1 < a:0 ? a:2 : function('vimconsole#async#default_outputter'), 134 | \ 'finalizer' : 2 < a:0 ? a:3 : function('vimconsole#async#default_finalizer'), 135 | \ }) 136 | catch '.*' 137 | endtry 138 | return [] 139 | endfunction 140 | function! vimconsole#async#system_with_vim(input_str, ...) 141 | let return_value = [] 142 | 143 | if 1 < winnr('$') 144 | call vimconsole#winclose() 145 | endif 146 | if -1 isnot match(a:input_str, '^\s*pwd\s*$') 147 | let return_value += [getcwd()] 148 | elseif -1 isnot match(a:input_str, '^\s*l\?cd .*$') 149 | let str = matchstr(a:input_str, '^\s*l\?cd .*$') 150 | silent execute str 151 | let return_value += [getcwd()] 152 | elseif -1 isnot match(a:input_str, '^\s*vim .*$') 153 | let path = matchstr(a:input_str, '^\s*vim \zs.*$') 154 | if filereadable(expand(path)) 155 | silent execute printf('edit %s', path) 156 | endif 157 | elseif -1 isnot match(a:input_str, '^\s*:.*$') 158 | let cmd = matchstr(a:input_str, '^\s*:\zs.*$') 159 | redir => output 160 | silent! execute cmd 161 | redir END 162 | let return_value += split(output, "\n") 163 | elseif isdirectory(expand(a:input_str)) 164 | silent execute 'lcd ' . a:input_str 165 | let return_value += [getcwd()] 166 | elseif filereadable(expand(a:input_str)) 167 | silent execute printf('edit %s', a:input_str) 168 | else 169 | call vimconsole#async#system(a:input_str) 170 | endif 171 | call vimconsole#winopen() 172 | 173 | return return_value 174 | endfunction 175 | 176 | -------------------------------------------------------------------------------- /autoload/vimconsole/enc.vim: -------------------------------------------------------------------------------- 1 | 2 | scriptencoding utf-8 3 | 4 | let s:V = vital#of('vimconsole') 5 | let s:Bitwise = s:V.import('Bitwise') 6 | 7 | function! s:char2binary(c) 8 | " echo s:char2binary('c') 9 | " [0,1,1,0 ,0,0,1,1] 10 | let bits = [0,0,0,0 ,0,0,0,0] 11 | if len(a:c) == 1 12 | let n = 1 13 | for i in range(7,0,-1) 14 | let bits[i] = s:Bitwise.and(char2nr(a:c),n) != 0 15 | let n = n * 2 16 | endfor 17 | else 18 | endif 19 | return bits 20 | endfunction 21 | function! s:count_1_prefixed(bits) 22 | " echo s:count_1_prefixed([1,1,0,0 ,0,0,1,1]) 23 | " 2 24 | let c = 0 25 | for b in a:bits 26 | if b == 0 27 | break 28 | else 29 | let c = c + 1 30 | endif 31 | endfor 32 | return c 33 | endfunction 34 | 35 | function! vimconsole#enc#utf_8(line) 36 | " http://tools.ietf.org/html/rfc3629 37 | 38 | let cs = a:line 39 | let i = 0 40 | while i < len(cs) 41 | let bits = s:char2binary(cs[i]) 42 | let c = s:count_1_prefixed(bits) 43 | 44 | " 1 byte utf-8 char. this is asci char. 45 | if c == 0 46 | let i = i + 1 47 | 48 | " 2~4 byte utf-8 char. 49 | elseif 2 <= c && c <= 4 50 | let i = i + 1 51 | " consume b10... 52 | for _ in range(1,c-1) "{{{ 53 | let bits = s:char2binary(cs[i]) 54 | let c = s:count_1_prefixed(bits) 55 | if c == 1 56 | " ok 57 | else 58 | " not utf-8 59 | return 0 60 | endif 61 | let i = i + 1 62 | endfor "}}} 63 | else 64 | " not utf-8 65 | return 0 66 | endif 67 | endwhile 68 | return 1 69 | endfunction 70 | function! vimconsole#enc#euc_jp(line) 71 | " http://charset.7jp.net/euc.html 72 | 73 | let cs = a:line 74 | let i = 0 75 | while i < len(cs) 76 | if 0x00 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x7f 77 | let i = i + 1 78 | elseif 0xa1 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xfe 79 | let i = i + 1 80 | if 0xa1 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xfe 81 | let i = i + 1 82 | else 83 | return 0 84 | endif 85 | elseif 0x8e == char2nr(cs[i]) 86 | let i = i + 1 87 | if 0xa1 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xdf 88 | let i = i + 1 89 | else 90 | return 0 91 | endif 92 | else 93 | return 0 94 | endif 95 | endwhile 96 | return 1 97 | endfunction 98 | function! vimconsole#enc#shift_jis(line) 99 | " http://charset.7jp.net/sjis.html 100 | 101 | let cs = a:line 102 | let i = 0 103 | while i < len(cs) 104 | if 0x00 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x7f 105 | let i = i + 1 106 | elseif 0xa1 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xdf 107 | let i = i + 1 108 | 109 | elseif (0x81 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x9f) 110 | \ || (0xe0 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xef) 111 | let i = i + 1 112 | if (0x40 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x7e) 113 | \ || (0x80 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xfc) 114 | let i = i + 1 115 | else 116 | return 0 117 | endif 118 | elseif 0x8e == char2nr(cs[i]) 119 | let i = i + 1 120 | if 0xa1 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xdf 121 | let i = i + 1 122 | else 123 | return 0 124 | endif 125 | else 126 | return 0 127 | endif 128 | endwhile 129 | return 1 130 | endfunction 131 | function! vimconsole#enc#iso_2022_jp(line) 132 | " http://charset.7jp.net/jis.html 133 | " 134 | " MODE_A : "ASCIIの開始" 135 | " MODE_B : "漢字の開始(旧JIS漢字 JIS C 6226-1978)" 136 | " MODE_C : "漢字の開始 (新JIS漢字 JIS X 0208-1983)" 137 | " MODE_D : "漢字の開始 (JIS X 0208-1990)" 138 | " MODE_E : "JISローマ字の開始" 139 | " MODE_F : "半角カタカナの開始" 140 | 141 | let cs = a:line 142 | let mode = "MODE_A" 143 | let i = 0 144 | while i < len(cs) 145 | if 0x1b == char2nr(cs[i]) && 0x24 == char2nr(cs[i+1]) && 0x40 == char2nr(cs[i+2]) 146 | let i = i + 3 147 | let mode = "MODE_B" 148 | elseif 0x1b == char2nr(cs[i]) && 0x24 == char2nr(cs[i+1]) && 0x42 == char2nr(cs[i+2]) 149 | let i = i + 3 150 | let mode = "MODE_C" 151 | elseif 0x1b == char2nr(cs[i]) && 0x26 == char2nr(cs[i+1]) && 0x40 == char2nr(cs[i+2]) 152 | \ && 0x1b == char2nr(cs[i+3]) && 0x24 == char2nr(cs[i+4]) && 0x42 == char2nr(cs[i+5]) 153 | let i = i + 6 154 | let mode = "MODE_D" 155 | elseif 0x1b == char2nr(cs[i]) && 0x28 == char2nr(cs[i+1]) && 0x42 == char2nr(cs[i+2]) 156 | let i = i + 3 157 | let mode = "MODE_A" 158 | "elseif 0x1b == char2nr(cs[i]) && 0x28 == char2nr(cs[i+1]) && 0x4a == char2nr(cs[i+2]) 159 | " let i = i + 3 160 | " let mode = "MODE_E" 161 | elseif 0x1b == char2nr(cs[i]) && 0x28 == char2nr(cs[i+1]) && 0x49 == char2nr(cs[i+2]) 162 | let i = i + 3 163 | let mode = "MODE_F" 164 | 165 | elseif mode =~ "MODE_A" 166 | if 0x00 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x7f 167 | let i = i + 1 168 | else 169 | return 0 170 | endif 171 | elseif mode =~ "MODE_F" 172 | if (0x21 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x5f) 173 | \ || (0xa1 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0xdf) 174 | let i = i + 1 175 | else 176 | return 0 177 | endif 178 | elseif mode =~ "MODE_B" 179 | \ || mode =~ "MODE_C" 180 | \ || mode =~ "MODE_D" 181 | if (0x21 <= char2nr(cs[i]) && char2nr(cs[i]) <= 0x7e) 182 | \ && (0x21 <= char2nr(cs[i+1]) && char2nr(cs[i+1]) <= 0x7e) 183 | let i = i + 2 184 | else 185 | return 0 186 | endif 187 | else 188 | return 0 189 | endif 190 | endwhile 191 | return 1 192 | endfunction 193 | function! vimconsole#enc#of(str) 194 | if vimconsole#enc#iso_2022_jp(a:str) 195 | return "iso-2022-jp" 196 | elseif vimconsole#enc#utf_8(a:str) 197 | return "utf-8" 198 | elseif vimconsole#enc#euc_jp(a:str) 199 | return "euc-jp" 200 | elseif vimconsole#enc#shift_jis(a:str) 201 | return "shift_jis" 202 | else 203 | echo "Unknown charcode of " . a:str 204 | return "" 205 | endif 206 | endfunction 207 | function! vimconsole#enc#iconv(lines,...) 208 | let to_encode = a:0 > 0 ? a:1 : &encoding 209 | let lines = type(a:lines) == type([]) ? copy(a:lines) : [(a:lines)] 210 | let encoded_lines = map(lines,'iconv(v:val,vimconsole#enc#of(v:val),to_encode)') 211 | let lines_str = join(encoded_lines,"\n") 212 | let lines_str = substitute(lines_str,"\r\n","\r","g") 213 | let lines_str = substitute(lines_str,"\n","\r","g") 214 | return split(lines_str,"\r") 215 | endfunction 216 | 217 | 218 | -------------------------------------------------------------------------------- /autoload/vital/_vimconsole/Bitwise.vim: -------------------------------------------------------------------------------- 1 | " bitwise operators 2 | " moved from github.com/ynkdir/vim-funlib 3 | 4 | let s:save_cpo = &cpo 5 | set cpo&vim 6 | 7 | " compare as unsigned int 8 | function! s:compare(a, b) 9 | if (a:a >= 0 && a:b >= 0) || (a:a < 0 && a:b < 0) 10 | return a:a < a:b ? -1 : a:a > a:b ? 1 : 0 11 | else 12 | return a:a < 0 ? 1 : -1 13 | endif 14 | endfunction 15 | 16 | function! s:lshift(a, n) 17 | return a:a * s:pow2[s:and(a:n, 0x1F)] 18 | endfunction 19 | 20 | function! s:rshift(a, n) 21 | let n = s:and(a:n, 0x1F) 22 | return n == 0 ? a:a : 23 | \ a:a < 0 ? (a:a - 0x80000000) / s:pow2[n] + 0x40000000 / s:pow2[n - 1] 24 | \ : a:a / s:pow2[n] 25 | endfunction 26 | 27 | let s:pow2 = [ 28 | \ 0x1, 0x2, 0x4, 0x8, 29 | \ 0x10, 0x20, 0x40, 0x80, 30 | \ 0x100, 0x200, 0x400, 0x800, 31 | \ 0x1000, 0x2000, 0x4000, 0x8000, 32 | \ 0x10000, 0x20000, 0x40000, 0x80000, 33 | \ 0x100000, 0x200000, 0x400000, 0x800000, 34 | \ 0x1000000, 0x2000000, 0x4000000, 0x8000000, 35 | \ 0x10000000, 0x20000000, 0x40000000, 0x80000000, 36 | \ ] 37 | 38 | if exists('*and') 39 | function! s:_vital_loaded(V) dict 40 | for op in ['and', 'or', 'xor', 'invert'] 41 | let self[op] = function(op) 42 | let s:[op] = self[op] 43 | endfor 44 | endfunction 45 | finish 46 | endif 47 | 48 | 49 | function! s:invert(a) 50 | return -a:a - 1 51 | endfunction 52 | 53 | function! s:and(a, b) 54 | let a = a:a < 0 ? a:a - 0x80000000 : a:a 55 | let b = a:b < 0 ? a:b - 0x80000000 : a:b 56 | let r = 0 57 | let n = 1 58 | while a && b 59 | let r += s:and[a % 0x10][b % 0x10] * n 60 | let a = a / 0x10 61 | let b = b / 0x10 62 | let n = n * 0x10 63 | endwhile 64 | if (a:a < 0) && (a:b < 0) 65 | let r += 0x80000000 66 | endif 67 | return r 68 | endfunction 69 | 70 | function! s:or(a, b) 71 | let a = a:a < 0 ? a:a - 0x80000000 : a:a 72 | let b = a:b < 0 ? a:b - 0x80000000 : a:b 73 | let r = 0 74 | let n = 1 75 | while a || b 76 | let r += s:or[a % 0x10][b % 0x10] * n 77 | let a = a / 0x10 78 | let b = b / 0x10 79 | let n = n * 0x10 80 | endwhile 81 | if (a:a < 0) || (a:b < 0) 82 | let r += 0x80000000 83 | endif 84 | return r 85 | endfunction 86 | 87 | function! s:xor(a, b) 88 | let a = a:a < 0 ? a:a - 0x80000000 : a:a 89 | let b = a:b < 0 ? a:b - 0x80000000 : a:b 90 | let r = 0 91 | let n = 1 92 | while a || b 93 | let r += s:xor[a % 0x10][b % 0x10] * n 94 | let a = a / 0x10 95 | let b = b / 0x10 96 | let n = n * 0x10 97 | endwhile 98 | if (a:a < 0) != (a:b < 0) 99 | let r += 0x80000000 100 | endif 101 | return r 102 | endfunction 103 | 104 | let s:and = [ 105 | \ [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0], 106 | \ [0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1], 107 | \ [0x0, 0x0, 0x2, 0x2, 0x0, 0x0, 0x2, 0x2, 0x0, 0x0, 0x2, 0x2, 0x0, 0x0, 0x2, 0x2], 108 | \ [0x0, 0x1, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3], 109 | \ [0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4], 110 | \ [0x0, 0x1, 0x0, 0x1, 0x4, 0x5, 0x4, 0x5, 0x0, 0x1, 0x0, 0x1, 0x4, 0x5, 0x4, 0x5], 111 | \ [0x0, 0x0, 0x2, 0x2, 0x4, 0x4, 0x6, 0x6, 0x0, 0x0, 0x2, 0x2, 0x4, 0x4, 0x6, 0x6], 112 | \ [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7], 113 | \ [0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8, 0x8], 114 | \ [0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x0, 0x1, 0x8, 0x9, 0x8, 0x9, 0x8, 0x9, 0x8, 0x9], 115 | \ [0x0, 0x0, 0x2, 0x2, 0x0, 0x0, 0x2, 0x2, 0x8, 0x8, 0xA, 0xA, 0x8, 0x8, 0xA, 0xA], 116 | \ [0x0, 0x1, 0x2, 0x3, 0x0, 0x1, 0x2, 0x3, 0x8, 0x9, 0xA, 0xB, 0x8, 0x9, 0xA, 0xB], 117 | \ [0x0, 0x0, 0x0, 0x0, 0x4, 0x4, 0x4, 0x4, 0x8, 0x8, 0x8, 0x8, 0xC, 0xC, 0xC, 0xC], 118 | \ [0x0, 0x1, 0x0, 0x1, 0x4, 0x5, 0x4, 0x5, 0x8, 0x9, 0x8, 0x9, 0xC, 0xD, 0xC, 0xD], 119 | \ [0x0, 0x0, 0x2, 0x2, 0x4, 0x4, 0x6, 0x6, 0x8, 0x8, 0xA, 0xA, 0xC, 0xC, 0xE, 0xE], 120 | \ [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF] 121 | \ ] 122 | 123 | let s:or = [ 124 | \ [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF], 125 | \ [0x1, 0x1, 0x3, 0x3, 0x5, 0x5, 0x7, 0x7, 0x9, 0x9, 0xB, 0xB, 0xD, 0xD, 0xF, 0xF], 126 | \ [0x2, 0x3, 0x2, 0x3, 0x6, 0x7, 0x6, 0x7, 0xA, 0xB, 0xA, 0xB, 0xE, 0xF, 0xE, 0xF], 127 | \ [0x3, 0x3, 0x3, 0x3, 0x7, 0x7, 0x7, 0x7, 0xB, 0xB, 0xB, 0xB, 0xF, 0xF, 0xF, 0xF], 128 | \ [0x4, 0x5, 0x6, 0x7, 0x4, 0x5, 0x6, 0x7, 0xC, 0xD, 0xE, 0xF, 0xC, 0xD, 0xE, 0xF], 129 | \ [0x5, 0x5, 0x7, 0x7, 0x5, 0x5, 0x7, 0x7, 0xD, 0xD, 0xF, 0xF, 0xD, 0xD, 0xF, 0xF], 130 | \ [0x6, 0x7, 0x6, 0x7, 0x6, 0x7, 0x6, 0x7, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF], 131 | \ [0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0x7, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF], 132 | \ [0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF], 133 | \ [0x9, 0x9, 0xB, 0xB, 0xD, 0xD, 0xF, 0xF, 0x9, 0x9, 0xB, 0xB, 0xD, 0xD, 0xF, 0xF], 134 | \ [0xA, 0xB, 0xA, 0xB, 0xE, 0xF, 0xE, 0xF, 0xA, 0xB, 0xA, 0xB, 0xE, 0xF, 0xE, 0xF], 135 | \ [0xB, 0xB, 0xB, 0xB, 0xF, 0xF, 0xF, 0xF, 0xB, 0xB, 0xB, 0xB, 0xF, 0xF, 0xF, 0xF], 136 | \ [0xC, 0xD, 0xE, 0xF, 0xC, 0xD, 0xE, 0xF, 0xC, 0xD, 0xE, 0xF, 0xC, 0xD, 0xE, 0xF], 137 | \ [0xD, 0xD, 0xF, 0xF, 0xD, 0xD, 0xF, 0xF, 0xD, 0xD, 0xF, 0xF, 0xD, 0xD, 0xF, 0xF], 138 | \ [0xE, 0xF, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF, 0xE, 0xF], 139 | \ [0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF] 140 | \ ] 141 | 142 | let s:xor = [ 143 | \ [0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7, 0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF], 144 | \ [0x1, 0x0, 0x3, 0x2, 0x5, 0x4, 0x7, 0x6, 0x9, 0x8, 0xB, 0xA, 0xD, 0xC, 0xF, 0xE], 145 | \ [0x2, 0x3, 0x0, 0x1, 0x6, 0x7, 0x4, 0x5, 0xA, 0xB, 0x8, 0x9, 0xE, 0xF, 0xC, 0xD], 146 | \ [0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4, 0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC], 147 | \ [0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3, 0xC, 0xD, 0xE, 0xF, 0x8, 0x9, 0xA, 0xB], 148 | \ [0x5, 0x4, 0x7, 0x6, 0x1, 0x0, 0x3, 0x2, 0xD, 0xC, 0xF, 0xE, 0x9, 0x8, 0xB, 0xA], 149 | \ [0x6, 0x7, 0x4, 0x5, 0x2, 0x3, 0x0, 0x1, 0xE, 0xF, 0xC, 0xD, 0xA, 0xB, 0x8, 0x9], 150 | \ [0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0, 0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8], 151 | \ [0x8, 0x9, 0xA, 0xB, 0xC, 0xD, 0xE, 0xF, 0x0, 0x1, 0x2, 0x3, 0x4, 0x5, 0x6, 0x7], 152 | \ [0x9, 0x8, 0xB, 0xA, 0xD, 0xC, 0xF, 0xE, 0x1, 0x0, 0x3, 0x2, 0x5, 0x4, 0x7, 0x6], 153 | \ [0xA, 0xB, 0x8, 0x9, 0xE, 0xF, 0xC, 0xD, 0x2, 0x3, 0x0, 0x1, 0x6, 0x7, 0x4, 0x5], 154 | \ [0xB, 0xA, 0x9, 0x8, 0xF, 0xE, 0xD, 0xC, 0x3, 0x2, 0x1, 0x0, 0x7, 0x6, 0x5, 0x4], 155 | \ [0xC, 0xD, 0xE, 0xF, 0x8, 0x9, 0xA, 0xB, 0x4, 0x5, 0x6, 0x7, 0x0, 0x1, 0x2, 0x3], 156 | \ [0xD, 0xC, 0xF, 0xE, 0x9, 0x8, 0xB, 0xA, 0x5, 0x4, 0x7, 0x6, 0x1, 0x0, 0x3, 0x2], 157 | \ [0xE, 0xF, 0xC, 0xD, 0xA, 0xB, 0x8, 0x9, 0x6, 0x7, 0x4, 0x5, 0x2, 0x3, 0x0, 0x1], 158 | \ [0xF, 0xE, 0xD, 0xC, 0xB, 0xA, 0x9, 0x8, 0x7, 0x6, 0x5, 0x4, 0x3, 0x2, 0x1, 0x0] 159 | \ ] 160 | 161 | let &cpo = s:save_cpo 162 | unlet s:save_cpo 163 | 164 | " vim:set et ts=2 sts=2 sw=2 tw=0: 165 | -------------------------------------------------------------------------------- /autoload/vital/_vimconsole.vim: -------------------------------------------------------------------------------- 1 | let s:self_version = expand(':t:r') 2 | 3 | " Note: The extra argument to globpath() was added in Patch 7.2.051. 4 | let s:globpath_third_arg = v:version > 702 || v:version == 702 && has('patch51') 5 | 6 | let s:loaded = {} 7 | 8 | function! s:import(name, ...) 9 | let target = {} 10 | let functions = [] 11 | for a in a:000 12 | if type(a) == type({}) 13 | let target = a 14 | elseif type(a) == type([]) 15 | let functions = a 16 | endif 17 | unlet a 18 | endfor 19 | let module = s:_import(a:name) 20 | if empty(functions) 21 | call extend(target, module, 'keep') 22 | else 23 | for f in functions 24 | if has_key(module, f) && !has_key(target, f) 25 | let target[f] = module[f] 26 | endif 27 | endfor 28 | endif 29 | return target 30 | endfunction 31 | 32 | function! s:load(...) dict 33 | for arg in a:000 34 | let [name; as] = type(arg) == type([]) ? arg[: 1] : [arg, arg] 35 | let target = split(join(as, ''), '\W\+') 36 | let dict = self 37 | while 1 <= len(target) 38 | let ns = remove(target, 0) 39 | if !has_key(dict, ns) 40 | let dict[ns] = {} 41 | endif 42 | if type(dict[ns]) == type({}) 43 | let dict = dict[ns] 44 | else 45 | unlet dict 46 | break 47 | endif 48 | endwhile 49 | 50 | if exists('dict') 51 | call extend(dict, s:_import(name)) 52 | endif 53 | unlet arg 54 | endfor 55 | return self 56 | endfunction 57 | 58 | function! s:unload() 59 | let s:loaded = {} 60 | endfunction 61 | 62 | function! s:exists(name) 63 | return s:_get_module_path(a:name) !=# '' 64 | endfunction 65 | 66 | function! s:search(pattern) 67 | let target = substitute(a:pattern, '\.', '/', 'g') 68 | let tailpath = printf('autoload/vital/%s/%s.vim', s:self_version, target) 69 | 70 | let paths = s:_runtime_files(tailpath) 71 | let modules = sort(map(paths, 's:_file2module(v:val)')) 72 | return s:_uniq(modules) 73 | endfunction 74 | 75 | function! s:expand_modules(entry, all) 76 | if type(a:entry) == type([]) 77 | let candidates = s:_concat(map(copy(a:entry), 's:search(v:val)')) 78 | if empty(candidates) 79 | throw printf('vital: Any of module %s is not found', string(a:entry)) 80 | endif 81 | if eval(join(map(copy(candidates), 'has_key(a:all, v:val)'), '+')) 82 | let modules = [] 83 | else 84 | let modules = [candidates[0]] 85 | endif 86 | else 87 | let modules = s:search(a:entry) 88 | if empty(modules) 89 | throw printf('vital: Module %s is not found', a:entry) 90 | endif 91 | endif 92 | call filter(modules, '!has_key(a:all, v:val)') 93 | for module in modules 94 | let a:all[module] = 1 95 | endfor 96 | return modules 97 | endfunction 98 | 99 | function! s:_import(name) 100 | if type(a:name) == type(0) 101 | return s:_build_module(a:name) 102 | endif 103 | let path = s:_get_module_path(a:name) 104 | if path ==# '' 105 | throw 'vital: module not found: ' . a:name 106 | endif 107 | let sid = get(s:_scripts(), path, 0) 108 | if !sid 109 | try 110 | execute 'source' fnameescape(path) 111 | catch /^Vim\%((\a\+)\)\?:E484/ 112 | throw 'vital: module not found: ' . a:name 113 | catch /^Vim\%((\a\+)\)\?:E127/ 114 | " Ignore. 115 | endtry 116 | 117 | let sid = s:_scripts()[path] 118 | endif 119 | return s:_build_module(sid) 120 | endfunction 121 | 122 | function! s:_get_module_path(name) 123 | if s:_is_absolute_path(a:name) && filereadable(a:name) 124 | return s:_unify_path(a:name) 125 | endif 126 | if a:name ==# '' 127 | let tailpath = printf('autoload/vital/%s.vim', s:self_version) 128 | elseif a:name =~# '\v^\u\w*%(\.\u\w*)*$' 129 | let target = substitute(a:name, '\W\+', '/', 'g') 130 | let tailpath = printf('autoload/vital/%s/%s.vim', s:self_version, target) 131 | else 132 | throw 'vital: Invalid module name: ' . a:name 133 | endif 134 | 135 | let paths = s:_runtime_files(tailpath) 136 | call filter(paths, 'filereadable(v:val)') 137 | let path = get(paths, 0, '') 138 | return path !=# '' ? s:_unify_path(path) : '' 139 | endfunction 140 | 141 | function! s:_scripts() 142 | let scripts = {} 143 | for line in filter(split(s:_redir('scriptnames'), "\n"), 144 | \ 'stridx(v:val, s:self_version) > 0') 145 | let list = matchlist(line, '^\s*\(\d\+\):\s\+\(.\+\)\s*$') 146 | if !empty(list) 147 | let scripts[s:_unify_path(list[2])] = list[1] - 0 148 | endif 149 | endfor 150 | return scripts 151 | endfunction 152 | 153 | function! s:_file2module(file) 154 | let filename = fnamemodify(a:file, ':p:gs?[\\/]\+?/?') 155 | let tail = matchstr(filename, 'autoload/vital/_\w\+/\zs.*\ze\.vim$') 156 | return join(split(tail, '[\\/]\+'), '.') 157 | endfunction 158 | 159 | if filereadable(expand(':r') . '.VIM') 160 | function! s:_unify_path(path) 161 | " Note: On windows, vim can't expand path names from 8.3 formats. 162 | " So if getting full path via and $HOME was set as 8.3 format, 163 | " vital load duplicated scripts. Below's :~ avoid this issue. 164 | return tolower(fnamemodify(resolve(fnamemodify( 165 | \ a:path, ':p')), ':~:gs?[\\/]\+?/?')) 166 | endfunction 167 | else 168 | function! s:_unify_path(path) 169 | return resolve(fnamemodify(a:path, ':p:gs?[\\/]\+?/?')) 170 | endfunction 171 | endif 172 | 173 | if s:globpath_third_arg 174 | function! s:_runtime_files(path) 175 | return split(globpath(&runtimepath, a:path, 1), "\n") 176 | endfunction 177 | else 178 | function! s:_runtime_files(path) 179 | return split(globpath(&runtimepath, a:path), "\n") 180 | endfunction 181 | endif 182 | 183 | " Copy from System.Filepath 184 | if has('win16') || has('win32') || has('win64') 185 | function! s:_is_absolute_path(path) 186 | return a:path =~? '^[a-z]:[/\\]' 187 | endfunction 188 | else 189 | function! s:_is_absolute_path(path) 190 | return a:path[0] ==# '/' 191 | endfunction 192 | endif 193 | 194 | function! s:_build_module(sid) 195 | if has_key(s:loaded, a:sid) 196 | return copy(s:loaded[a:sid]) 197 | endif 198 | let functions = s:_get_functions(a:sid) 199 | 200 | let prefix = '' . a:sid . '_' 201 | let module = {} 202 | for func in functions 203 | let module[func] = function(prefix . func) 204 | endfor 205 | if has_key(module, '_vital_loaded') 206 | let V = vital#{s:self_version}#new() 207 | if has_key(module, '_vital_depends') 208 | let all = {} 209 | let modules = 210 | \ s:_concat(map(module._vital_depends(), 211 | \ 's:expand_modules(v:val, all)')) 212 | call call(V.load, modules, V) 213 | endif 214 | try 215 | call module._vital_loaded(V) 216 | catch 217 | " FIXME: Show an error message for debug. 218 | endtry 219 | endif 220 | if !get(g:, 'vital_debug', 0) 221 | call filter(module, 'v:key =~# "^\\a"') 222 | endif 223 | let s:loaded[a:sid] = module 224 | return copy(module) 225 | endfunction 226 | 227 | if exists('+regexpengine') 228 | function! s:_get_functions(sid) 229 | let funcs = s:_redir(printf("function /\\%%#=2^\%d_", a:sid)) 230 | let map_pat = '' . a:sid . '_\zs\w\+' 231 | return map(split(funcs, "\n"), 'matchstr(v:val, map_pat)') 232 | endfunction 233 | else 234 | function! s:_get_functions(sid) 235 | let prefix = '' . a:sid . '_' 236 | let funcs = s:_redir('function') 237 | let filter_pat = '^\s*function ' . prefix 238 | let map_pat = prefix . '\zs\w\+' 239 | return map(filter(split(funcs, "\n"), 240 | \ 'stridx(v:val, prefix) > 0 && v:val =~# filter_pat'), 241 | \ 'matchstr(v:val, map_pat)') 242 | endfunction 243 | endif 244 | 245 | if exists('*uniq') 246 | function! s:_uniq(list) 247 | return uniq(a:list) 248 | endfunction 249 | else 250 | function! s:_uniq(list) 251 | let i = len(a:list) - 1 252 | while 0 < i 253 | if a:list[i] ==# a:list[i - 1] 254 | call remove(a:list, i) 255 | let i -= 2 256 | else 257 | let i -= 1 258 | endif 259 | endwhile 260 | return a:list 261 | endfunction 262 | endif 263 | 264 | function! s:_concat(lists) 265 | let result_list = [] 266 | for list in a:lists 267 | let result_list += list 268 | endfor 269 | return result_list 270 | endfunction 271 | 272 | function! s:_redir(cmd) 273 | let [save_verbose, save_verbosefile] = [&verbose, &verbosefile] 274 | set verbose=0 verbosefile= 275 | redir => res 276 | silent! execute a:cmd 277 | redir END 278 | let [&verbose, &verbosefile] = [save_verbose, save_verbosefile] 279 | return res 280 | endfunction 281 | 282 | function! vital#{s:self_version}#new() 283 | return s:_import('') 284 | endfunction 285 | -------------------------------------------------------------------------------- /doc/vimconsole.txt: -------------------------------------------------------------------------------- 1 | *vimconsole.txt* This is immediate-window for Vim script. 2 | 3 | Author : rbtnn 4 | LICENSE: MIT license (see LICENSE.txt) 5 | 6 | CONTENTS *vimconsole-contents* 7 | 8 | Variables |vimconsole-variables| 9 | Commands |vimconsole-commands| 10 | Functions |vimconsole-functions| 11 | Key Mappings |vimconsole-key-mappings| 12 | FAQ |vimconsole-faq| 13 | 14 | 15 | ============================================================================== 16 | 17 | This is Immediate Window for Vim script. 18 | It is like Google Chrome Developer Console. 19 | 20 | This use |PrettyPrint()| if install https://github.com/thinca/vim-prettyprint. 21 | 22 | 23 | ============================================================================== 24 | VARIABLES *vimconsole-variables* 25 | 26 | 27 | * g:vimconsole#split_rule *g:vimconsole#split_rule* 28 | 29 | Split position rule. This can have one of following values. 30 | default: 'bottom' 31 | 32 | 'top', 'bottom', 'right', 'left' 33 | 34 | 35 | * g:vimconsole#width *g:vimconsole#width* 36 | 37 | Use it as VimConsole's window width if the type is Number. 38 | Use it evaluated as VimConsole's window width if the type is String. 39 | default: '&columns / 2' 40 | 41 | 42 | * g:vimconsole#height *g:vimconsole#height* 43 | 44 | Use it as VimConsole's window height if the type is Number. 45 | Use it evaluated as VimConsole's window height if the type is String. 46 | default: '&lines / 2' 47 | 48 | 49 | * g:vimconsole#auto_redraw *g:vimconsole#auto_redraw* 50 | 51 | When print to VimConsole, call |vimconsole#redraw()|automatically. 52 | default: 0 53 | 54 | 55 | * g:vimconsole#enable_quoted_string *g:vimconsole#enable_quoted_string* 56 | 57 | Print a string with single-quote, if its type is string. 58 | default: 1 59 | 60 | 61 | * g:vimconsole#hooks *g:vimconsole#looks* 62 | 63 | This value is `{}`. This can have following keys. 64 | Calling a hook function, does not call any hook function. 65 | 66 | 67 | on_logged: This is a function reference. 68 | If g:vimconsole#hooks has this key, call this after logging by 69 | a logging function (vimconsole#log, vimconsole#warn,... ,etc.). 70 | 71 | Example: 72 | > 73 | function! g:vimconsole#hooks.on_logged(context) 74 | " `a:context`'s value is such as `{ 'tag' : 'vimconsole#assert' }`. 75 | call vimconsole#log(a:context.tag) 76 | endfunction 77 | < 78 | 79 | on_pre_redraw: This is a function reference. 80 | If g:vimconsole#hooks has this key, 81 | call this before redrawing VimConsole. 82 | 83 | Example: 84 | > 85 | function! g:vimconsole#hooks.on_pre_redraw(context) 86 | " `a:context`'s value is such as `{ 'tag' : 'vimconsole#redraw' }`. 87 | call vimconsole#log(a:context.tag) 88 | endfunction 89 | < 90 | 91 | on_post_redraw: This is a function reference. 92 | If g:vimconsole#hooks has this key, 93 | call this after redrawing VimConsole. 94 | 95 | Example: 96 | > 97 | function! g:vimconsole#hooks.on_post_redraw(context) 98 | " `a:context`'s value is such as `{ 'tag' : 'vimconsole#redraw' }`. 99 | call vimconsole#log(a:context.tag) 100 | endfunction 101 | < 102 | 103 | * g:vimconsole#eval_function_name *g:vimconsole#eval_function_name* 104 | 105 | This value is a function name. 106 | (signature: string -> string or string -> [string]) 107 | It is used for evaluate a character string from prompt. 108 | default: 'eval' 109 | 110 | Example: 111 | > 112 | " Use like a shell. 113 | let g:vimconsole#eval_function_name = 'vimproc#system' 114 | 115 | " VimConsole>ls 116 | " README.md autoload doc plugin vimconsole.png 117 | < 118 | 119 | 120 | * g:vimconsole#no_default_key_mappings *g:vimconsole#no_default_key_mappings* 121 | 122 | Does not set default key mappings. 123 | 124 | 125 | * g:vimconsole#session_type *g:vimconsole#session_type* 126 | 127 | This value is a session-type of vimconsole.vim. 128 | session-type is one of values(`'t:'`,`'g:'`). 129 | default: `'t:'` 130 | 131 | 132 | * g:vimconsole#startinsert *g:vimconsole#startinsert* 133 | 134 | This value is to start Insert mode on VimConsole. 135 | 136 | 137 | ============================================================================== 138 | COMMANDS *vimconsole-commands* 139 | 140 | * :VimConsoleLog {obj} *VimConsoleLog* 141 | 142 | Print to VimConsole. 143 | Same as `vimconsole#log({obj},...)`. 144 | 145 | 146 | * :VimConsoleOpen[!] *VimConsoleOpen* 147 | 148 | Open VimConsole if it is closed. 149 | Do nothing when VimConsole is opened (don't call vimconsole#redraw). 150 | If with bang, force call vimconsole#redraw. 151 | 152 | 153 | * :VimConsoleClose *VimConsoleClose* 154 | 155 | Close VimConsole. 156 | 157 | 158 | * :VimConsoleToggle *VimConsoleToggle* 159 | 160 | Toggle VimConsole. 161 | 162 | 163 | * :VimConsoleClear *VimConsoleClear* 164 | 165 | Clear logs of VimConsole. 166 | 167 | 168 | * :VimConsoleRedraw[!] *VimConsoleRedraw* 169 | 170 | Redraw VimConsole. 171 | If with bang, call vimconsole#clear before to redraw. 172 | 173 | 174 | ============================================================================== 175 | FUNCTIONS *vimconsole-functions* 176 | 177 | * vimconsole#assert(expr,obj,...) *vimconsole#assert()* 178 | 179 | It is like javascript's `console.assert({expr},{obj},...)`. 180 | This behavior is printf({obj}, ...) to VimConsole if `0 < a:0`. 181 | 182 | 183 | * vimconsole#log(obj,...) *vimconsole#log()* 184 | 185 | It is like javascript's `console.log({obj},...)`. 186 | This behavior is printf({obj}, ...) to VimConsole if `0 < a:0`. 187 | 188 | 189 | * vimconsole#winopen([{bang}]) *vimconsole#winopen()* 190 | 191 | Same as |VimConsoleOpen|. 192 | 193 | 194 | * vimconsole#winclose() *vimconsole#winclose()* 195 | 196 | Same as |VimConsoleClose|. 197 | 198 | 199 | * vimconsole#wintoggle() *vimconsole#wintoggle()* 200 | 201 | Same as |VimConsoleToggle|. 202 | 203 | 204 | * vimconsole#clear() *vimconsole#clear()* 205 | 206 | Same as |VimConsoleClear|. 207 | 208 | 209 | * vimconsole#redraw([{bang}]) *vimconsole#redraw()* 210 | 211 | Same as |VimConsoleRedraw|. 212 | 213 | 214 | * vimconsole#is_open() *vimconsole#is_open()* 215 | 216 | 1 is returned if VimConsole is opened. 217 | 0 is returned if VimConsole is closed. 218 | 219 | 220 | ------------------------------------------------------------------------------ 221 | KEY MAPPINGS *vimconsole-key-mappings* 222 | 223 | (vimconsole_close) *(vimconsole_close)* 224 | 225 | Same as |VimConsoleClose|. 226 | 227 | 228 | (vimconsole_clear) *(vimconsole_clear)* 229 | 230 | Same as |VimConsoleClear|. 231 | 232 | 233 | (vimconsole_redraw) *(vimconsole_redraw)* 234 | 235 | Same as |VimConsoleRedraw|. 236 | 237 | 238 | (vimconsole_next_prompt) *(vimconsole_next_prompt)* 239 | 240 | Move to next prompt from cursor. 241 | 242 | 243 | (vimconsole_previous_prompt) *(vimconsole_previous_prompt)* 244 | 245 | Move to previous prompt from cursor. 246 | 247 | 248 | ============================================================================== 249 | FAQ *vimconsole-faq* 250 | 251 | Q: I want to fix highlight and syntax when reload `.vimrc`. 252 | 253 | A: You can use below setting in `.vimrc`. 254 | > 255 | if vimconsole#is_open() 256 | call vimconsole#winopen('!') 257 | endif 258 | < 259 | 260 | Q: I want to scroll until the end of logs automatically. 261 | 262 | A: You can use below setting in `.vimrc`. 263 | > 264 | let g:vimconsole#hooks = {} 265 | function! g:vimconsole#hooks.on_post_redraw(context) 266 | normal G$l 267 | endfunction 268 | < 269 | 270 | 271 | ============================================================================== 272 | vim:tw=78:ts=8:ft=help:norl:noet:fen:fdl=0: 273 | -------------------------------------------------------------------------------- /autoload/vimconsole.vim: -------------------------------------------------------------------------------- 1 | 2 | let s:TYPE_STRING = type('') 3 | let s:TYPE_PROMPT = 8 4 | 5 | let s:PROMPT_STRING = 'VimConsole>' 6 | let s:PROMPT_STRING_PATTERN = '^' . s:PROMPT_STRING 7 | let s:FILETYPE = 'vimconsole' 8 | 9 | augroup vimconsole 10 | autocmd! 11 | autocmd TextChanged * :call text_changed() 12 | augroup END 13 | 14 | function! s:text_changed() 15 | if &filetype is# s:FILETYPE 16 | let lines = vimconsole#buflines() 17 | 18 | let curr_session = s:session() 19 | 20 | let m = matchlist(getline(len(lines)), s:PROMPT_STRING_PATTERN . '\(.*\)$') 21 | let curr_session['input_str'] = empty(m) ? '' : m[1] 22 | 23 | let save_line = getline(".") 24 | let save_cursor = getpos(".") 25 | let joined_lines = join(lines, "\n") 26 | silent % delete _ 27 | silent put=joined_lines 28 | silent 1 delete _ 29 | call setpos('.', save_cursor) 30 | call setline('.', save_line) 31 | 32 | let m = matchlist(getline(len(lines)), s:PROMPT_STRING_PATTERN . '\(.*\)$') 33 | if empty(m) 34 | call setline('$', s:PROMPT_STRING) 35 | endif 36 | endif 37 | endfunction 38 | function! s:session() 39 | if g:vimconsole#session_type is# 't:' 40 | let t:vimconsole = get(t:,'vimconsole',{}) 41 | return t:vimconsole 42 | elseif g:vimconsole#session_type is# 'g:' 43 | let g:vimconsole = get(g:,'vimconsole',{}) 44 | return g:vimconsole 45 | else 46 | let t:vimconsole = get(t:,'vimconsole',{}) 47 | return t:vimconsole 48 | endif 49 | endfunction 50 | function! s:object(...) 51 | let curr_session = s:session() 52 | 53 | let message_queue = deepcopy(get(curr_session,'message_queue',[])) 54 | if !empty(message_queue) 55 | let curr_session.message_queue = [] 56 | for x in message_queue 57 | call s:add_log(s:TYPE_STRING,type(x),x,[]) 58 | endfor 59 | endif 60 | 61 | if 0 < a:0 62 | let curr_session.objs = get(curr_session,'objs',[]) + [ a:1 ] 63 | endif 64 | return get(curr_session,'objs',[]) 65 | endfunction 66 | function! s:is_vimconsole_window(bufnr) 67 | return ( getbufvar(a:bufnr,'&filetype') ==# s:FILETYPE ) && ( getbufvar(a:bufnr,'vimconsole') ) 68 | endfunction 69 | function! s:hook_events(hook_type,context) 70 | let curr_session = s:session() 71 | try 72 | if ! get(curr_session,'is_hooking',0) 73 | let curr_session.is_hooking = 1 74 | if has_key(g:vimconsole#hooks,a:hook_type) 75 | call g:vimconsole#hooks[(a:hook_type)](a:context) 76 | endif 77 | if -1 != index(['on_logged'],a:hook_type) 78 | if g:vimconsole#auto_redraw 79 | call vimconsole#redraw() 80 | endif 81 | endif 82 | endif 83 | finally 84 | let curr_session.is_hooking = 0 85 | endtry 86 | endfunction 87 | function! s:add_log(true_type,false_type,value,list) 88 | if 0 < len(a:list) 89 | call s:object({ 'type' : a:true_type, 'value' : call('printf',[(a:value)]+a:list) }) 90 | else 91 | call s:object({ 'type' : a:false_type, 'value' : deepcopy(a:value) }) 92 | endif 93 | endfunction 94 | function! s:object2lines(obj) 95 | let lines = [] 96 | 97 | if type(function('tr')) == a:obj.type 98 | redir => hoge 99 | try 100 | execute 'function ' . matchstr(string(a:obj.value),"function('\\zs.*\\ze')") 101 | catch /.*/ 102 | echo string(a:obj.value) 103 | endtry 104 | redir END 105 | let lines += split(hoge,"\n") 106 | elseif type({}) == a:obj.type 107 | try 108 | let lines += split(PrettyPrint(a:obj.value),"\n") 109 | catch 110 | let lines += [ '{' ] 111 | for key in keys(a:obj.value) 112 | let lines += [ ' ' . printf("'%s' : %s", key, string(a:obj.value[key])) . ',' ] 113 | endfor 114 | let lines += [ '}' ] 115 | endtry 116 | elseif type([]) == a:obj.type 117 | try 118 | let lines += split(PrettyPrint(a:obj.value),"\n") 119 | catch 120 | let lines += [ '[' ] 121 | for e in a:obj.value 122 | let lines += [ ' ' . string(e) . ',' ] 123 | unlet e 124 | endfor 125 | let lines += [ ']' ] 126 | endtry 127 | elseif type(0.0) == a:obj.type 128 | let lines += [ string(a:obj.value) ] 129 | elseif type(0) == a:obj.type 130 | let lines += [ string(a:obj.value) ] 131 | elseif s:TYPE_PROMPT == a:obj.type 132 | let lines += [ a:obj.value ] 133 | elseif type('') == a:obj.type 134 | if g:vimconsole#enable_quoted_string 135 | let lines += map(split(a:obj.value,"\n"),'string(v:val)') 136 | else 137 | let lines += split(a:obj.value,"\n") 138 | endif 139 | else 140 | let lines += map(split(a:obj.value,"\n"),'string(v:val)') 141 | endif 142 | 143 | return lines 144 | endfunction 145 | function! s:vimconsole_initialize() 146 | execute printf('edit vimconsole@%s', fnamemodify(tempname(), ':t:r')) 147 | let b:vimconsole = 1 148 | setlocal buftype=nofile 149 | setlocal nobuflisted 150 | setlocal noswapfile 151 | setlocal bufhidden=hide 152 | setlocal nospell 153 | setlocal foldmethod=manual 154 | execute 'setlocal filetype=' . s:FILETYPE 155 | 156 | nnoremap (vimconsole_close) :VimConsoleClose 157 | nnoremap (vimconsole_clear) :VimConsoleClear 158 | nnoremap (vimconsole_redraw) :VimConsoleRedraw 159 | nnoremap (vimconsole_next_prompt) :call key_c_n() 160 | nnoremap (vimconsole_previous_prompt) :call key_c_p() 161 | 162 | inoremap key_i_bs() 163 | inoremap key_i_del() 164 | inoremap :call key_cr() 165 | nnoremap :call key_cr() 166 | if ! g:vimconsole#no_default_key_mappings 167 | nmap (vimconsole_previous_prompt) 168 | nmap (vimconsole_next_prompt) 169 | endif 170 | 171 | call clearmatches() 172 | call matchadd('Title', s:PROMPT_STRING_PATTERN) 173 | call matchadd('Comment', '^\[vimconsole].*$') 174 | 175 | call vimconsole#redraw() 176 | endfunction 177 | 178 | function! s:key_cr() 179 | if s:is_vimconsole_window(bufnr('%')) 180 | let m = matchlist(getline('.'), s:PROMPT_STRING_PATTERN . '\(.*\)$') 181 | if ! empty(m) 182 | let input_str = m[1] 183 | if line('.') is line('$') 184 | let curr_session = s:session() 185 | let curr_session['input_str'] = '' 186 | endif 187 | call vimconsole#execute_on_prompt(input_str) 188 | endif 189 | endif 190 | endfunction 191 | function! s:key_c_n() 192 | normal 0 193 | call search(s:PROMPT_STRING_PATTERN, 'w') 194 | normal 0f> 195 | endfunction 196 | function! s:key_c_p() 197 | normal 0 198 | call search(s:PROMPT_STRING_PATTERN, 'bw') 199 | normal 0f> 200 | endfunction 201 | function! s:key_i_bs() 202 | if &l:filetype is# s:FILETYPE 203 | if len(s:PROMPT_STRING) < (getpos('.')[2] + getpos('.')[3] - 1) 204 | return "\" 205 | else 206 | return '' 207 | endif 208 | endif 209 | endfunction 210 | function! s:key_i_del() 211 | if &l:filetype is# s:FILETYPE 212 | if len(s:PROMPT_STRING) < (getpos('.')[2] + getpos('.')[3] - 1) 213 | return "\" 214 | else 215 | return '' 216 | endif 217 | endif 218 | endfunction 219 | 220 | function! vimconsole#execute_on_prompt(input) 221 | if ! empty(a:input) 222 | call s:add_log(s:TYPE_PROMPT, s:TYPE_PROMPT, (s:PROMPT_STRING . a:input), []) 223 | 224 | let is_vimcon = s:is_vimconsole_window(winbufnr(0)) 225 | 226 | if is_vimcon 227 | for winnr in range(1, winnr('$')) 228 | if winbufnr(winnr) == bufnr('#') 229 | execute winnr . "wincmd w" 230 | endif 231 | endfor 232 | endif 233 | 234 | try 235 | let F = function(g:vimconsole#eval_function_name) 236 | let output = F(a:input) 237 | for line in type(output) is type([]) ? output : [output] 238 | call vimconsole#log(line) 239 | endfor 240 | catch 241 | call vimconsole#log(join([ v:exception, v:throwpoint ], "\n")) 242 | endtry 243 | 244 | if is_vimcon 245 | for winnr in range(1, winnr('$')) 246 | if s:is_vimconsole_window(winbufnr(winnr)) 247 | execute winnr . "wincmd w" 248 | call vimconsole#bufenter() 249 | break 250 | endif 251 | endfor 252 | endif 253 | endif 254 | endfunction 255 | function! vimconsole#save_session(path) 256 | let path = expand(a:path == "" ? '~/.vimconsole_session' : a:path) 257 | silent! call writefile([ 258 | \ printf("%s\t%s", 'g:vimconsole', string(get(g:, 'vimconsole', {}))), 259 | \ printf("%s\t%s", 't:vimconsole', string(get(t:, 'vimconsole', {}))), 260 | \ printf("%s\t%s", 'g:vimconsole#auto_redraw', string(g:vimconsole#auto_redraw)), 261 | \ printf("%s\t%s", 'g:vimconsole#enable_quoted_string', string(g:vimconsole#enable_quoted_string)), 262 | \ printf("%s\t%s", 'g:vimconsole#eval_function_name', string(g:vimconsole#eval_function_name)), 263 | \ printf("%s\t%s", 'g:vimconsole#height', string(g:vimconsole#height)), 264 | \ printf("%s\t%s", 'g:vimconsole#no_default_key_mappings', string(g:vimconsole#no_default_key_mappings)), 265 | \ printf("%s\t%s", 'g:vimconsole#session_type', string(g:vimconsole#session_type)), 266 | \ printf("%s\t%s", 'g:vimconsole#split_rule', string(g:vimconsole#split_rule)), 267 | \ printf("%s\t%s", 'g:vimconsole#width', string(g:vimconsole#width)), 268 | \ ], path) 269 | endfunction 270 | function! vimconsole#load_session(path) 271 | let path = expand(a:path == "" ? '~/.vimconsole_session' : a:path) 272 | if filereadable(path) 273 | for line in readfile(path) 274 | let m = matchlist(line, '^\([^\t]*\)\t\(.*\)$') 275 | if !empty(m) 276 | if m[1] == 'g:vimconsole' 277 | let g:vimconsole = eval(m[2]) 278 | elseif m[1] == 't:vimconsole' 279 | let t:vimconsole = eval(m[2]) 280 | elseif m[1] == 'g:vimconsole#auto_redraw' 281 | let g:vimconsole#auto_redraw = eval(m[2]) 282 | elseif m[1] == 'g:vimconsole#enable_quoted_string' 283 | let g:vimconsole#enable_quoted_string = eval(m[2]) 284 | elseif m[1] == 'g:vimconsole#eval_function_name' 285 | let g:vimconsole#eval_function_name = eval(m[2]) 286 | elseif m[1] == 'g:vimconsole#height' 287 | let g:vimconsole#height = eval(m[2]) 288 | elseif m[1] == 'g:vimconsole#no_default_key_mappings' 289 | let g:vimconsole#no_default_key_mappings = eval(m[2]) 290 | elseif m[1] == 'g:vimconsole#session_type' 291 | let g:vimconsole#session_type = eval(m[2]) 292 | elseif m[1] == 'g:vimconsole#split_rule' 293 | let g:vimconsole#split_rule = eval(m[2]) 294 | elseif m[1] == 'g:vimconsole#width' 295 | let g:vimconsole#width = eval(m[2]) 296 | endif 297 | endif 298 | endfor 299 | endif 300 | endfunction 301 | function! vimconsole#clear() 302 | let curr_session = s:session() 303 | let curr_session.objs = [] 304 | call vimconsole#redraw() 305 | endfunction 306 | function! vimconsole#assert(expr,obj,...) 307 | if ! a:expr 308 | call s:add_log(s:TYPE_STRING,type(a:obj),a:obj,a:000) 309 | endif 310 | call s:hook_events('on_logged',{ 'tag' : 'vimconsole#assert' }) 311 | endfunction 312 | function! vimconsole#log(obj,...) 313 | call s:add_log(s:TYPE_STRING,type(a:obj),a:obj,a:000) 314 | call s:hook_events('on_logged',{ 'tag' : 'vimconsole#log' }) 315 | endfunction 316 | function! vimconsole#wintoggle() 317 | let close_flag = 0 318 | for winnr in range(1,winnr('$')) 319 | let bufnr = winbufnr(winnr) 320 | if s:is_vimconsole_window(bufnr) 321 | execute winnr . "wincmd w" 322 | close 323 | let close_flag = 1 324 | endif 325 | endfor 326 | if ! close_flag 327 | call vimconsole#winopen() 328 | endif 329 | endfunction 330 | function! vimconsole#is_open() 331 | for winnr in range(1,winnr('$')) 332 | let bufnr = winbufnr(winnr) 333 | if s:is_vimconsole_window(bufnr) 334 | return 1 335 | endif 336 | endfor 337 | return 0 338 | endfunction 339 | function! vimconsole#winclose() 340 | for winnr in range(1,winnr('$')) 341 | let bufnr = winbufnr(winnr) 342 | if s:is_vimconsole_window(bufnr) 343 | execute winnr . "wincmd w" 344 | close 345 | endif 346 | endfor 347 | endfunction 348 | function! vimconsole#buflines() 349 | let rtn = [] 350 | let reserved_lines_len = len(rtn) 351 | let start = reserved_lines_len 352 | for obj in s:object() 353 | let lines = s:object2lines(obj) 354 | let obj.start = start + 1 355 | let obj.last = start + len(lines) 356 | let rtn += lines 357 | let start = obj.last 358 | endfor 359 | let curr_session = s:session() 360 | let rtn += [ s:PROMPT_STRING . get(curr_session,'input_str','') ] 361 | return rtn 362 | endfunction 363 | function! vimconsole#redraw(...) 364 | let bang = 0 < a:0 ? ( a:1 ==# '!' ) : 0 365 | let curr_winnr = winnr() 366 | for winnr in range(1,winnr('$')) 367 | let bufnr = winbufnr(winnr) 368 | if s:is_vimconsole_window(bufnr) 369 | if bang 370 | call vimconsole#clear() 371 | endif 372 | execute winnr . "wincmd w" 373 | 374 | call s:hook_events('on_pre_redraw',{ 'tag' : 'vimconsole#redraw' }) 375 | 376 | let lines = join(vimconsole#buflines(), "\n") 377 | silent % delete _ 378 | silent put=lines 379 | silent 1 delete _ 380 | 381 | call s:hook_events('on_post_redraw',{ 'tag' : 'vimconsole#redraw' }) 382 | endif 383 | endfor 384 | execute curr_winnr . "wincmd w" 385 | endfunction 386 | function! vimconsole#bufenter() 387 | call vimconsole#redraw() 388 | endfunction 389 | function! vimconsole#define_commands() 390 | command! -nargs=0 -bar -bang VimConsoleOpen :call vimconsole#winopen() 391 | command! -nargs=0 -bar -bang VimConsoleRedraw :call vimconsole#redraw() 392 | command! -nargs=0 -bar VimConsoleClose :call vimconsole#winclose() 393 | command! -nargs=0 -bar VimConsoleClear :call vimconsole#clear() 394 | command! -nargs=0 -bar VimConsoleToggle :call vimconsole#wintoggle() 395 | command! -nargs=1 -complete=expression VimConsoleLog :call vimconsole#log() 396 | command! -nargs=? -complete=file -bar VimConsoleSaveSession :call vimconsole#save_session() 397 | command! -nargs=? -complete=file -bar VimConsoleLoadSession :call vimconsole#load_session() 398 | endfunction 399 | function! vimconsole#winopen(...) 400 | let bang = 0 < a:0 ? ( a:1 ==# '!' ) : 0 401 | let curr_winnr = winnr() 402 | if vimconsole#is_open() 403 | if bang 404 | call vimconsole#winclose() 405 | else 406 | return 0 407 | endif 408 | endif 409 | new 410 | let width = type(g:vimconsole#width) is type(0) ? g:vimconsole#width : eval(g:vimconsole#width) 411 | let height = type(g:vimconsole#height) is type(0) ? g:vimconsole#height : eval(g:vimconsole#height) 412 | if g:vimconsole#split_rule is# 'top' 413 | execute "wincmd K" 414 | execute 'resize ' . height 415 | elseif g:vimconsole#split_rule is# 'left' 416 | execute "wincmd H" 417 | execute 'vertical resize ' . width 418 | elseif g:vimconsole#split_rule is# 'right' 419 | execute "wincmd L" 420 | execute 'vertical resize ' . width 421 | else 422 | " defalut: bottom 423 | execute "wincmd J" 424 | execute 'resize ' . height 425 | endif 426 | call s:vimconsole_initialize() 427 | if g:vimconsole#startinsert 428 | startinsert! 429 | else 430 | execute curr_winnr . "wincmd w" 431 | endif 432 | endfunction 433 | function! vimconsole#tabopen() 434 | tabnew 435 | call s:vimconsole_initialize() 436 | if g:vimconsole#startinsert 437 | startinsert! 438 | endif 439 | endfunction 440 | 441 | " vim: set ts=2 sts=2 sw=2 ft=vim ff=unix : 442 | --------------------------------------------------------------------------------