· 8 years ago · Mar 20, 2018, 01:24 PM
1" Vimball Archiver by Charles E. Campbell
2UseVimball
3finish
4autoload/conque_gdb.vim [[[1
5607
6
7" dependency
8if !exists('g:plugin_conque_gdb_loaded')
9 runtime! plugin/conque_gdb.vim
10endif
11
12if exists('g:autoload_conque_gdb_loaded') || g:ConqueGdb_Disable
13 finish
14endif
15
16let g:autoload_conque_gdb_loaded = 1
17
18" Path to gdb python scripts
19let s:SCRIPT_DIR = expand("<sfile>:h") . '/conque_gdb/'
20
21" Conque term terminal object
22let s:gdb = {'idx': 1, 'active': 0, 'buffer_number': -1}
23
24" Buffer number of the current source file, opened by gdb
25let s:src_buf = -1
26
27" Window number of the current source file, opened by gdb
28let s:src_bufwin = -1
29
30" True if the terminal being opened currently is a gdb terminal
31let s:is_gdb_startup = 0
32
33" Name of the sign showing up when a break point has been reached
34let s:SIGN_POINTER = 'conque_gdb_sign_pointer'
35
36" Sign name of enabled break points
37let s:SIGN_ENABLED = 'conque_gdb_break_enabled'
38
39" Sign name of disabled break points
40let s:SIGN_DISABLED = 'conque_gdb_break_disabled'
41
42" Start pointer sign from this value
43let s:SIGN_POINTER_VAL = 15605
44
45" Current id of the break point pointer sign
46let s:sign_pointer_id = s:SIGN_POINTER_VAL
47
48" Name of the file containing the sign which will be removed next
49let s:sign_file = ''
50
51" Line number of current sign
52let s:sign_line = -1
53
54" List of buffers opened by ConqueGdb
55let s:opened_buffers = {}
56
57" OS platform ('unix') or ('win')
58let s:platform = ''
59
60" Python version
61let s:py = ''
62
63" How to execute gdb
64let s:gdb_command = ''
65
66" true if gdb supports python
67let g:conque_gdb_gdb_py_support = 0
68
69" Which python object to use for terminal emulating ('ConqueGdb()') for Unix
70" and ('ConqueSoleGdb()') for Windows
71let s:term_object = ''
72
73" Original path to the GDB executable
74let s:orig_gdb_path = g:ConqueGdb_GdbExe
75
76" Define the current gdb break point sign
77sil exe 'sign define ' . s:SIGN_POINTER . ' linehl=Search'
78
79" Define sign for enabled break points
80sil exe 'sign define ' . s:SIGN_ENABLED . ' text=>> texthl=ErrorMsg'
81
82" Define sign for disabled break points
83sil exe 'sign define ' . s:SIGN_DISABLED . ' text=>> texthl=WarningMsg'
84
85" How to escape file names before passing them to python.
86function! s:escape_to_py_file(fname)
87 let l:fname = a:fname
88 let l:fname = substitute(l:fname, '\\', '\\\\\\\\', 'g')
89 let l:fname = substitute(l:fname, '"', '\\"', 'g')
90 return l:fname
91endfunction
92
93" Attempt to escape file names before opening them for edit/view
94function! s:escape_to_shell_file(fname)
95 if s:platform != 'win'
96 let l:fname = substitute(a:fname, '\\', '\\\\', 'g')
97 let l:fname = substitute(l:fname, '"', '\\"', 'g')
98 let l:fname = substitute(l:fname, '`', '\\`', 'g')
99 let l:fname = substitute(l:fname, ' ', '\\ ', 'g')
100 let l:fname = substitute(l:fname, '*', '\\*', 'g')
101 let l:fname = substitute(l:fname, '#', '\\#', 'g')
102 let l:fname = substitute(l:fname, '{', '\\{', 'g')
103 let l:fname = substitute(l:fname, '}', '\\}', 'g')
104 let l:fname = substitute(l:fname, '[', '\\[', 'g')
105 let l:fname = substitute(l:fname, ']', '\\]', 'g')
106 else
107 let l:fname = a:fname
108 endif
109 return l:fname
110endfunction
111
112" Python substitutes the "'" character with "\n" before calling vim functions.
113" Use this function to substitute it back again!
114function! s:file_from_python(fname)
115 return substitute(a:fname, "\n", "'", 'g')
116endfunction
117
118" Place a break point sign indicating there is a gdb break point at
119" file a:fname, line number a:lineno.
120" a:enabled == 0 if the break point should be marked as disabled.
121function! conque_gdb#set_breakpoint_sign(id, fname, lineno, enabled)
122 let l:fname = s:file_from_python(a:fname)
123
124 let l:bufname = bufname(l:fname)
125 if l:bufname == ""
126 return
127 endif
128
129 if a:enabled == 'y'
130 let l:name = s:SIGN_ENABLED
131 else
132 let l:name = s:SIGN_DISABLED
133 endif
134 try
135 sil exe 'sign place ' . a:id . ' line=' . a:lineno . ' name=' . l:name . ' buffer=' . bufnr(l:bufname)
136 catch
137 endtry
138endfunction
139
140" Remove the break point sign with id a:id in file a:fname.
141function! conque_gdb#remove_breakpoint_sign(id, fname)
142 let l:fname = s:file_from_python(a:fname)
143
144 let l:bufname = bufname(l:fname)
145 if l:bufname == ""
146 return
147 endif
148
149 try
150 sil exe 'sign unplace ' . a:id . ' buffer=' . bufnr(l:bufname)
151 catch
152 endtry
153endfunction
154
155" Place sign indication a break point has been hit and the execution has
156" stopped in file a:fname, line number a:lineno.
157function! s:set_pointer(id, fname, lineno)
158 let l:bufname = bufname(a:fname)
159 if l:bufname == ""
160 return
161 endif
162 try
163 sil exe 'sign place ' . a:id . ' line=' . a:lineno . ' name=' . s:SIGN_POINTER . ' buffer=' . bufnr(l:bufname)
164 catch
165 echohl WarningMsg | echomsg 'ConqueGdb: Unable to place sign in source file ' . a:fname | echohl None
166 endtry
167endfunction
168
169" Remove previous sign that indicated where the execution was stopped.
170function! conque_gdb#remove_prev_pointer()
171 if s:sign_file != ''
172 let l:bufname = bufname(s:sign_file)
173 if l:bufname == ""
174 return
175 endif
176
177 try
178 sil exe 'sign unplace ' . s:sign_pointer_id . ' buffer=' . bufnr(l:bufname)
179 catch
180 endtry
181
182 let s:sign_file = ''
183 endif
184endfunction
185
186" Set a new sign in file a:fname at line number a:lineno.
187" And remove the previous sign
188function! conque_gdb#update_pointer(fname, lineno)
189 let l:next_pointer_id = s:sign_pointer_id % 2 + s:SIGN_POINTER_VAL
190 if a:fname != ''
191 call s:set_pointer(l:next_pointer_id, a:fname, a:lineno)
192 endif
193 call conque_gdb#remove_prev_pointer()
194 let s:sign_pointer_id = l:next_pointer_id
195 let s:sign_file = a:fname
196 let s:sign_line = a:lineno
197endfunction
198
199function! s:buf_update()
200 if s:platform != 'win'
201 if col(".") == col("$")
202 call feedkeys("\<Right>")
203 else
204 call feedkeys("\<Right>\<Left>")
205 endif
206 endif
207endfunction
208
209" Remove a written buffer from the list of buffers ConqueGdb has opened
210function! s:src_buf_written()
211 try
212 sil autocmd! conque_gdb_src_write_augroup BufWritePre <buffer>
213 if has_key(s:opened_buffers, bufnr("%"))
214 call remove(s:opened_buffers, bufnr("%"))
215 endif
216 catch
217 endtry
218endfunction
219
220" Open file a:fname at line number a:lineno.
221" a:perm specifies how to open the file
222" read only ('r') or read-write ('w').
223function! s:open_file(fname, lineno, perm)
224 let l:fbufname = bufname(a:fname)
225 if l:fbufname == "" || !bufloaded(bufnr(l:fbufname))
226 let l:opened_by_gdb = 1
227 else
228 let l:opened_by_gdb = 0
229 endif
230
231 if bufexists(a:fname)
232 let l:method = 'buffer ' . bufnr(bufname(a:fname))
233 elseif a:perm == 'w'
234 let l:method = 'edit ' . a:fname
235 else
236 let l:method = 'view ' . a:fname
237 endif
238
239 if bufwinnr(s:src_buf) == bufwinnr(s:gdb.buffer_number)
240 if !l:opened_by_gdb && bufwinnr(l:fbufname) != -1
241 sil noautocmd wincmd p
242 sil exe 'noautocmd ' . bufwinnr(l:fbufname) . 'wincmd w'
243 else
244 sil exe 'noautocmd ' . get(g:conque_gdb_src_splits, g:ConqueGdb_SrcSplit, g:conque_gdb_default_split)
245 endif
246 elseif bufwinnr(s:src_buf) == -1
247 sil exe get(g:conque_gdb_src_splits, g:ConqueGdb_SrcSplit, g:conque_gdb_default_split)
248 elseif winbufnr(s:src_bufwin) == s:src_buf
249 sil noautocmd wincmd p
250 sil exe 'noautocmd ' . s:src_bufwin . 'wincmd w'
251 else
252 sil noautocmd wincmd p
253 sil exe 'noautocmd ' . bufwinnr(s:src_buf) . 'wincmd w'
254 endif
255
256 sil exe 'noautocmd ' . l:method
257
258 let s:src_buf = bufnr("%")
259 let s:src_bufwin = winnr()
260
261 if l:opened_by_gdb
262 let s:opened_buffers[s:src_buf] = 1
263 augroup conque_gdb_src_write_augroup
264 autocmd conque_gdb_src_write_augroup BufWritePre <buffer> call s:src_buf_written()
265 augroup END
266 if g:conque_gdb_gdb_py_support
267 sil exe s:py . ' ' . s:gdb.var . '.place_file_breakpoints("' . s:escape_to_py_file(expand('%:p')) . '")'
268 endif
269 endif
270
271 " For some reason vim doesn't always detect the file type.
272 " So we do it manually here if we have opened the file.
273 if l:opened_by_gdb
274 sil filetype detect
275 else
276 sil exe 'set filetype=' . &filetype
277 endif
278endfunction
279
280" Move the gdb break point sign to file a:fname, line number a:lineno
281" The "\n" character is interpreted as "'".
282function! conque_gdb#breakpoint(fname, lineno)
283 let l:fname_py = s:file_from_python(a:fname)
284 let l:lineno = a:lineno
285
286 if filewritable(l:fname_py)
287 let l:perm = 'w'
288 elseif filereadable(l:fname_py)
289 let l:perm = 'r'
290 else
291 let l:perm = ''
292 endif
293
294 let l:fname = s:escape_to_shell_file(l:fname_py)
295
296 if l:perm != ''
297 let l:last_win = winnr()
298 let l:last_buf = bufnr("%")
299 call s:open_file(l:fname, l:lineno, l:perm)
300
301 sil noautocmd wincmd p
302 sil exe 'noautocmd ' . s:src_bufwin . 'wincmd w'
303 sil exe ':' . a:lineno
304 sil normal! zz
305
306 call conque_gdb#update_pointer(l:fname_py, l:lineno)
307 call s:buf_update()
308
309 if l:last_buf != winbufnr(l:last_win)
310 let l:last = bufwinnr(l:last_buf)
311 if l:last != -1
312 let l:last_win = l:last
313 endif
314 endif
315 sil noautocmd wincmd p
316 sil exe 'noautocmd ' . l:last_win . ' wincmd w'
317 else
318 " Gdb should detect that the file can't be opened. This should not happen.
319 echohl WarningMsg | echomsg 'ConqueGdb: Unable to open file ' . a:fname | echohl None
320 let l:fname = ''
321 let l:lineno = 0
322 endif
323endfunction
324
325" Get command to execute gdb on Unix
326function! s:get_unix_gdb()
327 if g:ConqueGdb_GdbExe != ''
328 let l:gdb_exe = g:ConqueGdb_GdbExe
329 else
330 let l:gdb_exe = 'gdb'
331 endif
332 if !executable(l:gdb_exe)
333 return ''
334 endif
335
336 let pyresp = "'PYYES'"
337 sil let l:gdb_py_support = system(l:gdb_exe . ' -q -batch -ex "python print(' . pyresp . ')"')
338 if l:gdb_py_support =~ ".*PYYES\n.*"
339 " Gdb has python support
340 let g:conque_gdb_gdb_py_support = 1
341 return l:gdb_exe . ' -f -x ' . s:SCRIPT_DIR . 'conque_gdb_gdb.py'
342 else
343 " No python pupport
344 let g:conque_gdb_gdb_py_support = 0
345 return l:gdb_exe . ' -f'
346 endif
347endfunction
348
349" Get command to execute gdb on Windows
350function! s:get_win_gdb()
351 let g:conque_gdb_gdb_py_support = 0
352
353 if g:ConqueGdb_GdbExe != ''
354 if executable(g:ConqueGdb_GdbExe)
355 return g:ConqueGdb_GdbExe
356 else
357 return ''
358 endif
359 endif
360
361 let sys_paths = split($PATH, ';')
362
363 " Try to add path to MinGW gdb.exe
364 call add(sys_paths, 'C:\MinGW\bin')
365 call reverse(sys_paths)
366
367 " check if gdb.exe is in paths
368 for path in sys_paths
369 let cand = path . '\gdb.exe'
370 if executable(cand)
371 return cand . ' -f'
372 endif
373 endfor
374
375 return ''
376endfunction
377
378" Return command to execute gdb
379function! s:get_gdb_command()
380 if s:platform != 'win'
381 return s:get_unix_gdb()
382 endif
383 return s:get_win_gdb()
384endfunction
385
386" Open a new gdb terminal.
387" If a gdb terminal is already running then open this and do not open a new one.
388function! conque_gdb#open(...)
389 let s:src_buf = bufnr("%")
390 let l:start_cmds = get(a:000, 1, [])
391
392 if bufloaded(s:gdb.buffer_number) && s:gdb.active
393 echohl WarningMsg | echomsg "GDB already running" | echohl None
394
395 if bufwinnr(s:gdb.buffer_number) == -1
396 " Open the existing gdb buffer with the start commands
397 for c in l:start_cmds
398 sil exe c
399 endfor
400 sil exe 'buffer ' . s:gdb.buffer_number
401 else
402 " Move cursor to the visible gdb window
403 sil exe bufwinnr(s:gdb.buffer_number) . 'wincmd w'
404 endif
405
406 if g:ConqueTerm_InsertOnEnter == 1
407 startinsert!
408 endif
409 else
410 " Find out if gdb was found on the system
411 if s:gdb_command == ''
412 echohl WarningMsg
413 echomsg "ConqueGdb: Unable to find gdb executable, see :help ConqueGdb_GdbExe and :help ConqueGdbExe for more information."
414 echohl None
415 return
416 endif
417
418 " Find out which gdb command script gdb should execute on startup.
419 sil let l:enable_confirm = system(s:gdb_command . ' -q -batch -ex "show confirm"')
420 if l:enable_confirm =~ '.*\s\+[Oo][Nn]\W.*'
421 let l:extra = ' -x ' . s:SCRIPT_DIR . 'gdbinit_confirm.gdb '
422 else
423 let l:extra = ' -x ' . s:SCRIPT_DIR . 'gdbinit_no_confirm.gdb '
424 endif
425
426 " Don't let user use the TUI feature. It does not work with ConqueGdb.
427 let l:user_args = get(a:000, 0, '')
428 if l:user_args =~ '\(.*\s\+\|^\)-\+tui\($\|\s\+.*\)'
429 echohl WarningMsg
430 echomsg 'ConqueGdb: GDB Text User Interface (--tui) is not supported'
431 echohl None
432 return
433 endif
434
435 let l:gdb_cmd = s:gdb_command . l:extra . l:user_args
436 let s:is_gdb_startup = 1
437 try
438 let s:gdb = conque_term#open(l:gdb_cmd, l:start_cmds, get(a:000, 2, 0), get(a:000, 3, 1), s:term_object)
439 sil exe 'file ConqueGDB\#' . s:gdb.idx
440 catch
441 endtry
442 let s:is_gdb_startup = 0
443 endif
444 let s:src_bufwin = winnr("#")
445endfunction
446
447" Send a command to the gdb subprocess.
448function! conque_gdb#command(cmd)
449 if !(bufloaded(s:gdb.buffer_number) && s:gdb.active)
450 echohl WarningMsg | echomsg "GDB is not running" | echohl None
451 return
452 endif
453
454 if bufwinnr(s:gdb.buffer_number) == -1
455 let s:src_buf = bufnr("%")
456 let s:src_bufwin = winnr()
457 sil exe 'noautocmd ' . get(g:conque_gdb_src_splits, g:ConqueGdb_SrcSplit, g:conque_gdb_default_split)
458 sil exe 'noautocmd wincmd w'
459 sil exe 'noautocmd buffer ' . s:gdb.buffer_number
460 sil exe 'noautocmd wincmd p'
461 endif
462
463 let l:win = winnr()
464 let l:buf_win = bufwinnr(s:gdb.buffer_number)
465 if l:win != l:buf_win
466 sil noautocmd wincmd p
467 sil exe 'noautocmd ' . l:buf_win . 'wincmd w'
468 let l:go_back = 1
469 else
470 let l:go_back = 0
471 endif
472
473 if g:ConqueGdb_SaveHistory
474 let l:cmd_prefix = ''
475 else
476 let l:cmd_prefix = 'server '
477 endif
478 call s:gdb.writeln(l:cmd_prefix . a:cmd)
479
480 if s:platform == 'win'
481 exe 'sleep ' . g:ConqueGdb_ReadTimeout . 'ms'
482 endif
483 call s:gdb.read(g:ConqueGdb_ReadTimeout)
484
485 if l:go_back
486 sil noautocmd wincmd p
487 sil exe 'noautocmd ' . l:win . 'wincmd w'
488 endif
489endfunction
490
491" print word under cursor.
492" Only supported on Unix where gdb supports the python API.
493function! conque_gdb#print_word(cword)
494 if a:cword != ''
495 call conque_gdb#command("print " . a:cword)
496 endif
497endfunction
498
499" Set/Clear break point in file a:fullfile, line a:line
500" Note that this is only supported on Unix where gdb has support for the
501" python API.
502function! conque_gdb#toggle_breakpoint(fullfile, line)
503 let l:command = "clear "
504 if bufloaded(s:gdb.buffer_number) || s:gdb.active
505 sil exe s:py . ' ' . s:gdb.var . '.vim_toggle_breakpoint("' . s:escape_to_py_file(a:fullfile) .'","'. a:line .'")'
506 endif
507 call conque_gdb#command(l:command . a:fullfile . ':' . a:line)
508endfunction
509
510" Restore state of script to indicate gdb has terminated
511function! s:restore()
512 try
513 autocmd! conque_gdb_augroup
514 call conque_gdb#remove_prev_pointer()
515 if g:conque_gdb_gdb_py_support
516 sil exe s:py . ' ' . s:gdb.var . '.remove_all_signs()'
517 endif
518 catch
519 endtry
520 let s:src_buf = -1
521 let s:src_bufwin = -1
522 let s:sign_file = ''
523 let s:sign_line = -1
524endfunction
525
526" Delete buffers opened by ConqueGdb
527function! conque_gdb#delete_opened_buffers()
528 for buf in keys(s:opened_buffers)
529 try
530 sil exe 'bdelete ' . buf
531 catch
532 endtry
533 endfor
534 let s:opened_buffers = {}
535endfunction
536
537" Called on BufWinEnter to find out when the user opens a new buffer in the
538" source window. Use this window for source code when break points are hit.
539function! s:buf_win_enter()
540 if winnr() == s:src_bufwin
541 if bufwinnr(s:src_buf) != -1
542 let s:src_bufwin = bufwinnr(s:src_buf)
543 else
544 let s:src_buf = bufnr("%")
545 endif
546 endif
547endfunction
548
549" Called on BufReadPost.
550" Place sign indicating where there are break points in the newly opened file
551" if necessary. Maybe the sign indicating where the execution has stopped
552" should be placed in this file also.
553function! s:buf_read_post()
554 let l:sign_bufname = bufname(s:sign_file)
555 if l:sign_bufname != "" && bufnr(l:sign_bufname) == bufnr("%")
556 call conque_gdb#update_pointer(s:sign_file, s:sign_line)
557 endif
558 if g:conque_gdb_gdb_py_support
559 sil exe s:py . ' ' . s:gdb.var . '.place_file_breakpoints("' . s:escape_to_py_file(expand('%:p')) . '")'
560 endif
561endfunction
562
563" Called after new conque terminals start up
564function! conque_gdb#after_startup(term)
565 if s:is_gdb_startup
566 " The gdb terminal has started up
567 augroup conque_gdb_augroup
568 autocmd!
569 autocmd conque_gdb_augroup BufUnload <buffer> call s:restore()
570 autocmd conque_gdb_augroup BufWinEnter * call s:buf_win_enter()
571 autocmd conque_gdb_augroup BufReadPost * call s:buf_read_post()
572 augroup END
573 endif
574endfunction
575
576" Called when the programs inside conque terminals terminate
577function! conque_gdb#after_close(term)
578 if a:term.idx == s:gdb.idx
579 call s:restore()
580 endif
581endfunction
582
583" Function to load the python files and setup the script.
584" This must be done before calling any other function in this script.
585function! conque_gdb#load_python()
586 if conque_term#dependency_check(0)
587 let s:py = conque_term#get_py()
588 if has('unix')
589 let s:platform = 'unix'
590 let s:term_object = 'ConqueGdb()'
591 exe s:py . "file " . s:SCRIPT_DIR . "conque_gdb.py"
592 else
593 let s:platform = 'win'
594 let s:term_object = 'ConqueSoleGdb()'
595 exe s:py . "file " . s:SCRIPT_DIR . "conque_sole_gdb.py"
596 endif
597 endif
598 let s:gdb_command = s:get_gdb_command()
599endfunction
600
601" Change path to GDB executable at runtime.
602function! conque_gdb#change_gdb_exe(gdb_path)
603 if a:gdb_path == ""
604 let g:ConqueGdb_GdbExe = s:orig_gdb_path
605 else
606 let g:ConqueGdb_GdbExe = a:gdb_path
607 endif
608 let s:gdb_command = s:get_gdb_command()
609endfunction
610
611call conque_term#register_function('after_startup', 'conque_gdb#after_startup')
612call conque_term#register_function('after_close', 'conque_gdb#after_close')
613autoload/conque_term.vim [[[1
6141656
615" FILE: autoload/conque_term.vim {{{
616" AUTHOR: Nico Raffo <nicoraffo@gmail.com>
617" WEBSITE: http://conque.googlecode.com
618" MODIFIED: 2011-09-12
619" VERSION: 2.3, for Vim 7.0
620" LICENSE:
621" Conque - Vim terminal/console emulator
622" Copyright (C) 2009-2011 Nico Raffo
623"
624" MIT License
625"
626" Permission is hereby granted, free of charge, to any person obtaining a copy
627" of this software and associated documentation files (the "Software"), to deal
628" in the Software without restriction, including without limitation the rights
629" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
630" copies of the Software, and to permit persons to whom the Software is
631" furnished to do so, subject to the following conditions:
632"
633" The above copyright notice and this permission notice shall be included in
634" all copies or substantial portions of the Software.
635"
636" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
637" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
638" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
639" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
640" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
641" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
642" THE SOFTWARE.
643" }}}
644
645" **********************************************************************************************************
646" **** GLOBAL INITIALIZATION *******************************************************************************
647" **********************************************************************************************************
648
649" {{{
650
651" Don't source twice
652if exists('g:ConqueTerm_TermLoaded')
653 finish
654endif
655let g:ConqueTerm_TermLoaded = 1
656
657" load plugin file if it hasn't already been loaded (e.g. conque_term#foo() is used in .vimrc)
658if !exists('g:ConqueTerm_Loaded')
659 runtime! plugin/conque_term.vim
660endif
661
662" path to conque install directories
663let s:scriptdir = expand("<sfile>:h") . '/'
664let s:scriptdirpy = expand("<sfile>:h") . '/conque_term/'
665
666" global list of terminal instances
667let s:term_obj = {'idx': 1, 'var': '', 'is_buffer': 1, 'active': 1, 'buffer_name': '', 'buffer_number' : -1, 'command': ''}
668let g:ConqueTerm_Terminals = {}
669
670" global lists of registered functions
671let s:hooks = { 'after_startup': [], 'buffer_enter': [], 'buffer_leave': [], 'after_keymap': [], 'after_close': [] }
672
673" Number of currently opened terminals
674let s:term_count = 0
675
676" required for session support
677if g:ConqueTerm_SessionSupport == 1
678 set sessionoptions+=globals
679 try
680 sil! let s:saved_terminals = eval(g:ConqueTerm_TerminalsString)
681 catch
682 let s:saved_terminals = {}
683 endtry
684endif
685
686" more session support
687let g:ConqueTerm_TerminalsString = ''
688
689" init terminal counter
690let g:ConqueTerm_Idx = 0
691
692" to save the users &updatetime. This is not a constant
693let s:save_updatetime = &updatetime
694
695" if nonzero restore the &updatetime when all terminals are closed
696let s:reset_updatetime = 1
697
698" have we called the init() function yet?
699let s:initialized = 0
700
701" }}}
702
703" **********************************************************************************************************
704" **** SYSTEM DETECTION ************************************************************************************
705" **********************************************************************************************************
706
707" {{{
708
709" Display various error messages
710function! conque_term#fail(feature) " {{{
711
712 " create a new buffer
713 new
714 setlocal buftype=nofile
715 setlocal nonumber
716 setlocal foldcolumn=0
717 setlocal wrap
718 setlocal noswapfile
719
720 " missing vim features
721 if a:feature == 'python'
722
723 call append('$', 'Conque ERROR: Python interface cannot be loaded')
724 call append('$', '')
725
726 if !executable("python")
727 call append('$', 'Your version of Vim appears to be installed without the Python interface. In ')
728 call append('$', 'addition, you may need to install Python.')
729 else
730 call append('$', 'Your version of Vim appears to be installed without the Python interface.')
731 endif
732
733 call append('$', '')
734
735 if has('unix') == 1
736 call append('$', "You are using a Unix-like operating system. Most, if not all, of the popular ")
737 call append('$', "Linux package managers have Python-enabled Vim available. For example ")
738 call append('$', "vim-gnome or vim-gtk on Ubuntu will get you everything you need.")
739 call append('$', "")
740 call append('$', "If you are compiling Vim from source, make sure you use the --enable-pythoninterp ")
741 call append('$', "configure option. You will also need to install Python and the Python headers.")
742 call append('$', "")
743 call append('$', "If you are using OS X, MacVim will give you Python support by default.")
744 else
745 call append('$', "You appear to be using Windows. The official Vim 7.3 installer available at ")
746 call append('$', "http://www.vim.org comes with the required Python interfaces. You will also ")
747 call append('$', "need to install Python 2.7 and/or Python 3.1, both available at http://www.python.org")
748 endif
749
750 elseif a:feature == 'python_exe'
751
752 call append('$', "Conque ERROR: Can't find Python executable")
753 call append('$', "")
754 call append('$', "Conque needs to know the full path to python.exe on Windows systems. By default, ")
755 call append('$', "Conque will check your system path as well as the most common installation path ")
756 call append('$', "C:\\PythonXX\\python.exe. To fix this error either:")
757 call append('$', "")
758 call append('$', "Set the g:ConqueTerm_PyExe option in your .vimrc. E.g.")
759 call append('$', " let g:ConqueTerm_PyExe = 'C:\Program Files\Python27\python.exe'")
760 call append('$', "")
761 call append('$', "Add the directory where you installed python to your system path. This isn't a bad ")
762 call append('$', "idea in general.")
763
764 elseif a:feature == 'ctypes'
765
766 call append('$', 'Conque ERROR: Python cannot load the ctypes module')
767 call append('$', "")
768 call append('$', "Conque requires the 'ctypes' python module. This has been a standard module since Python 2.5.")
769 call append('$', "")
770 call append('$', "The recommended fix is to make sure you're using the latest official GVim version 7.3, ")
771 call append('$', "and have at least one of the two compatible versions of Python installed, ")
772 call append('$', "2.7 or 3.1. You can download the GVim 7.3 installer from http://www.vim.org. You ")
773 call append('$', "can download the Python 2.7 or 3.1 installer from http://www.python.org")
774
775 endif
776
777endfunction " }}}
778
779" Go through various system checks before attempting to launch conque
780function! conque_term#dependency_check(...) " {{{
781 let show_messages = get(a:000, 0, 1)
782
783 " don't recheck the second time 'round
784 if s:initialized == 1
785 return 1
786 endif
787
788 " choose a python version
789 let s:py = ''
790 if g:ConqueTerm_PyVersion == 3
791 let pytest = 'python3'
792 else
793 let pytest = 'python'
794 let g:ConqueTerm_PyVersion = 2
795 endif
796
797 " first test the requested version
798 if has(pytest)
799 if pytest == 'python3'
800 let s:py = 'py3'
801 else
802 let s:py = 'py'
803 endif
804
805 " otherwise use the other version
806 else
807 let py_alternate = 5 - g:ConqueTerm_PyVersion
808 if py_alternate == 3
809 let pytest = 'python3'
810 else
811 let pytest = 'python'
812 endif
813 if has(pytest)
814 if show_messages
815 echohl WarningMsg | echomsg "Python " . g:ConqueTerm_PyVersion . " interface is not installed, using Python " . py_alternate . " instead" | echohl None
816 endif
817 let g:ConqueTerm_PyVersion = py_alternate
818 if pytest == 'python3'
819 let s:py = 'py3'
820 else
821 let s:py = 'py'
822 endif
823 endif
824 endif
825
826 " test if we actually found a python version
827 if s:py == ''
828 if show_messages
829 call conque_term#fail('python')
830 endif
831 return 0
832 endif
833
834 " quick and dirty platform declaration
835 if has('unix') == 1
836 let s:platform = 'unix'
837 sil exe s:py . " CONQUE_PLATFORM = 'unix'"
838 else
839 let s:platform = 'windows'
840 sil exe s:py . " CONQUE_PLATFORM = 'windows'"
841 endif
842
843 " if we're using Windows, make sure ctypes is available
844 if s:platform == 'windows'
845 try
846 sil exe s:py . " import ctypes"
847 catch
848 if show_messages
849 call conque_term#fail('ctypes')
850 endif
851 return 0
852 endtry
853 endif
854
855 " if we're using Windows, make sure we can finde python executable
856 if s:platform == 'windows' && conque_term#find_python_exe() == ''
857 if show_messages
858 call conque_term#fail('python_exe')
859 endif
860 return 0
861 endif
862
863 " check for global cursorhold/cursormove events
864 let o = ''
865 silent redir => o
866 silent autocmd CursorHoldI,CursorMovedI
867 redir END
868 for line in split(o, "\n")
869 if line =~ '^ ' || line =~ '^--' || line =~ 'matchparen'
870 continue
871 endif
872 if g:ConqueTerm_StartMessages && show_messages
873 echohl WarningMsg | echomsg "Warning: Global CursorHoldI and CursorMovedI autocommands may cause ConqueTerm to run slowly." | echohl None
874 endif
875 endfor
876
877 " check for compatible mode
878 if &compatible == 1 && show_messages
879 echohl WarningMsg | echomsg "Warning: Conque may not function normally in 'compatible' mode." | echohl None
880 endif
881
882 " check for fast mode
883 if g:ConqueTerm_FastMode
884 sil exe s:py . " CONQUE_FAST_MODE = True"
885 else
886 sil exe s:py . " CONQUE_FAST_MODE = False"
887 endif
888
889 " if we're all good, load python files
890 call conque_term#load_python()
891
892 return 1
893
894endfunction " }}}
895
896" }}}
897
898" **********************************************************************************************************
899" **** STARTUP MESSAGES ************************************************************************************
900" **********************************************************************************************************
901
902" {{{
903"if g:ConqueTerm_StartMessages
904" let msg_file = s:scriptdirpy . 'version.vim'
905" let msg_show = 1
906" let msg_ct = 1
907"
908" " we can write to conque term directory
909" if filewritable(s:scriptdirpy) == 2
910"
911" if filewritable(msg_file)
912"
913" " read current message file
914" try
915" silent execute "source " . msg_file
916" if exists('g:ConqueTerm_MsgCt') && exists('g:ConqueTerm_MsgVer')
917" if g:ConqueTerm_MsgVer == g:ConqueTerm_Version && g:ConqueTerm_MsgCt > 2
918" let msg_show = 0
919" else
920" let msg_ct = g:ConqueTerm_MsgCt + 1
921" endif
922" endif
923" catch
924" endtry
925" endif
926"
927" " update message file
928" if msg_show
929" let file_contents = ['let g:ConqueTerm_MsgCt = ' . msg_ct, 'let g:ConqueTerm_MsgVer = ' . g:ConqueTerm_Version]
930" call writefile(file_contents, msg_file)
931" endif
932" endif
933"
934" " save our final decision
935" let g:ConqueTerm_StartMessages = msg_show
936"endif
937" }}}
938
939" **********************************************************************************************************
940" **** WINDOWS VK CODES ************************************************************************************
941" **********************************************************************************************************
942
943" Windows Virtual Key Codes {{{
944let s:windows_vk = {
945\ 'VK_ADD' : 107,
946\ 'VK_APPS' : 93,
947\ 'VK_ATTN' : 246,
948\ 'VK_BACK' : 8,
949\ 'VK_BROWSER_BACK' : 166,
950\ 'VK_BROWSER_FORWARD' : 167,
951\ 'VK_CANCEL' : 3,
952\ 'VK_CAPITAL' : 20,
953\ 'VK_CLEAR' : 12,
954\ 'VK_CONTROL' : 17,
955\ 'VK_CONVERT' : 28,
956\ 'VK_CRSEL' : 247,
957\ 'VK_DECIMAL' : 110,
958\ 'VK_DELETE' : 46,
959\ 'VK_DIVIDE' : 111,
960\ 'VK_DOWN' : 40,
961\ 'VK_DOWN_CTL' : '40;1024',
962\ 'VK_END' : 35,
963\ 'VK_EREOF' : 249,
964\ 'VK_ESCAPE' : 27,
965\ 'VK_EXECUTE' : 43,
966\ 'VK_EXSEL' : 248,
967\ 'VK_F1' : 112,
968\ 'VK_F10' : 121,
969\ 'VK_F11' : 122,
970\ 'VK_F12' : 123,
971\ 'VK_F13' : 124,
972\ 'VK_F14' : 125,
973\ 'VK_F15' : 126,
974\ 'VK_F16' : 127,
975\ 'VK_F17' : 128,
976\ 'VK_F18' : 129,
977\ 'VK_F19' : 130,
978\ 'VK_F2' : 113,
979\ 'VK_F20' : 131,
980\ 'VK_F21' : 132,
981\ 'VK_F22' : 133,
982\ 'VK_F23' : 134,
983\ 'VK_F24' : 135,
984\ 'VK_F3' : 114,
985\ 'VK_F4' : 115,
986\ 'VK_F5' : 116,
987\ 'VK_F6' : 117,
988\ 'VK_F7' : 118,
989\ 'VK_F8' : 119,
990\ 'VK_F9' : 120,
991\ 'VK_FINAL' : 24,
992\ 'VK_HANGEUL' : 21,
993\ 'VK_HANGUL' : 21,
994\ 'VK_HANJA' : 25,
995\ 'VK_HELP' : 47,
996\ 'VK_HOME' : 36,
997\ 'VK_INSERT' : 45,
998\ 'VK_JUNJA' : 23,
999\ 'VK_KANA' : 21,
1000\ 'VK_KANJI' : 25,
1001\ 'VK_LBUTTON' : 1,
1002\ 'VK_LCONTROL' : 162,
1003\ 'VK_LEFT' : 37,
1004\ 'VK_LEFT_CTL' : '37;1024',
1005\ 'VK_LMENU' : 164,
1006\ 'VK_LSHIFT' : 160,
1007\ 'VK_LWIN' : 91,
1008\ 'VK_MBUTTON' : 4,
1009\ 'VK_MEDIA_NEXT_TRACK' : 176,
1010\ 'VK_MEDIA_PLAY_PAUSE' : 179,
1011\ 'VK_MEDIA_PREV_TRACK' : 177,
1012\ 'VK_MENU' : 18,
1013\ 'VK_MODECHANGE' : 31,
1014\ 'VK_MULTIPLY' : 106,
1015\ 'VK_NEXT' : 34,
1016\ 'VK_NONAME' : 252,
1017\ 'VK_NONCONVERT' : 29,
1018\ 'VK_NUMLOCK' : 144,
1019\ 'VK_NUMPAD0' : 96,
1020\ 'VK_NUMPAD1' : 97,
1021\ 'VK_NUMPAD2' : 98,
1022\ 'VK_NUMPAD3' : 99,
1023\ 'VK_NUMPAD4' : 100,
1024\ 'VK_NUMPAD5' : 101,
1025\ 'VK_NUMPAD6' : 102,
1026\ 'VK_NUMPAD7' : 103,
1027\ 'VK_NUMPAD8' : 104,
1028\ 'VK_NUMPAD9' : 105,
1029\ 'VK_OEM_CLEAR' : 254,
1030\ 'VK_PA1' : 253,
1031\ 'VK_PAUSE' : 19,
1032\ 'VK_PLAY' : 250,
1033\ 'VK_PRINT' : 42,
1034\ 'VK_PRIOR' : 33,
1035\ 'VK_PROCESSKEY' : 229,
1036\ 'VK_RBUTTON' : 2,
1037\ 'VK_RCONTROL' : 163,
1038\ 'VK_RETURN' : 13,
1039\ 'VK_RIGHT' : 39,
1040\ 'VK_RIGHT_CTL' : '39;1024',
1041\ 'VK_RMENU' : 165,
1042\ 'VK_RSHIFT' : 161,
1043\ 'VK_RWIN' : 92,
1044\ 'VK_SCROLL' : 145,
1045\ 'VK_SELECT' : 41,
1046\ 'VK_SEPARATOR' : 108,
1047\ 'VK_SHIFT' : 16,
1048\ 'VK_SNAPSHOT' : 44,
1049\ 'VK_SPACE' : 32,
1050\ 'VK_SUBTRACT' : 109,
1051\ 'VK_TAB' : 9,
1052\ 'VK_UP' : 38,
1053\ 'VK_UP_CTL' : '38;1024',
1054\ 'VK_VOLUME_DOWN' : 174,
1055\ 'VK_VOLUME_MUTE' : 173,
1056\ 'VK_VOLUME_UP' : 175,
1057\ 'VK_XBUTTON1' : 5,
1058\ 'VK_XBUTTON2' : 6,
1059\ 'VK_ZOOM' : 251
1060\ }
1061" }}}
1062
1063" **********************************************************************************************************
1064" **** ACTUAL CONQUE FUNCTIONS! ***************************************************************************
1065" **********************************************************************************************************
1066
1067" {{{
1068
1069" launch conque
1070function! conque_term#open(...) "{{{
1071 let command = get(a:000, 0, '')
1072 let vim_startup_commands = get(a:000, 1, [])
1073 let return_to_current = get(a:000, 2, 0)
1074 let is_buffer = get(a:000, 3, 1)
1075
1076 if has('unix')
1077 let term_type = get(a:000, 4, 'Conque()')
1078 else
1079 let term_type = get(a:000, 4, 'ConqueSole()')
1080 endif
1081
1082 " dependency check
1083 if !conque_term#dependency_check()
1084 return 0
1085 endif
1086
1087 " switch to buffer if needed
1088 if is_buffer && return_to_current
1089 let save_sb = &switchbuf
1090 sil set switchbuf=usetab
1091 let current_buffer = bufname("%")
1092 endif
1093
1094 " bare minimum validation
1095 if s:py == ''
1096 echohl WarningMsg | echomsg "Conque requires the Python interface to be installed. See :help ConqueTerm for more information." | echohl None
1097 return 0
1098 endif
1099 if empty(command)
1100 echohl WarningMsg | echomsg "Invalid usage: no program path given. Use :ConqueTerm YOUR PROGRAM, e.g. :ConqueTerm ipython" | echohl None
1101 return 0
1102 else
1103 let cmd_args = split(command, '[^\\]\@<=\s')
1104 let cmd_args[0] = substitute(cmd_args[0], '\\ ', ' ', 'g')
1105 if !executable(cmd_args[0])
1106 echohl WarningMsg | echomsg "Not an executable: " . cmd_args[0] | echohl None
1107 return 0
1108 endif
1109 endif
1110
1111 " initialize global identifiers
1112 let g:ConqueTerm_Idx += 1
1113 let g:ConqueTerm_Var = 'ConqueTerm_' . g:ConqueTerm_Idx
1114 let g:ConqueTerm_BufName = substitute(command, ' ', '\\ ', 'g') . "\\ -\\ " . g:ConqueTerm_Idx
1115
1116 " initialize global mappings if needed
1117 call conque_term#init()
1118
1119 " set Vim buffer window options
1120 if is_buffer
1121 call conque_term#set_buffer_settings(command, vim_startup_commands)
1122
1123 let b:ConqueTerm_Idx = g:ConqueTerm_Idx
1124 let b:ConqueTerm_Var = g:ConqueTerm_Var
1125 endif
1126
1127 " save terminal instance
1128 let t_obj = conque_term#create_terminal_object(g:ConqueTerm_Idx, is_buffer, g:ConqueTerm_BufName, command)
1129 let g:ConqueTerm_Terminals[g:ConqueTerm_Idx] = t_obj
1130
1131 " required for session support
1132 let g:ConqueTerm_TerminalsString = string(g:ConqueTerm_Terminals)
1133
1134 " open command
1135 try
1136 let options = {}
1137 let options["TERM"] = g:ConqueTerm_TERM
1138 let options["CODE_PAGE"] = g:ConqueTerm_CodePage
1139 let options["color"] = g:ConqueTerm_Color
1140 let options["offset"] = 0 " g:ConqueTerm_StartMessages * 10
1141
1142 if s:platform == 'unix'
1143 " Initialize conque terminal object
1144 sil execute s:py . ' ' . g:ConqueTerm_Var . ' = ' . term_type
1145 sil execute s:py . ' ' . g:ConqueTerm_Var . ".open()"
1146 else
1147 " find python.exe and communicator
1148 let py_exe = conque_term#find_python_exe()
1149 let py_vim = s:scriptdirpy . 'conque_sole_communicator.py'
1150 sil execute s:py . ' ' . g:ConqueTerm_Var . ' = ' . term_type
1151 sil execute s:py . ' ' . g:ConqueTerm_Var . ".open()"
1152
1153 if g:ConqueTerm_ColorMode == 'conceal'
1154 call conque_term#init_conceal_color()
1155 endif
1156 endif
1157 catch
1158 echohl WarningMsg | echomsg "An error occurred: " . command | echohl None
1159 return 0
1160 endtry
1161
1162 " set key mappings and auto commands
1163 if is_buffer
1164 call conque_term#set_mappings('start')
1165 endif
1166
1167 if s:term_count == 0
1168 let s:save_updatetime = &updatetime
1169 endif
1170 let s:term_count = s:term_count + 1
1171
1172 " call user defined functions
1173 call conque_term#call_hooks('after_startup', t_obj)
1174
1175 " switch to buffer if needed
1176 if is_buffer && return_to_current
1177 sil exe ":sb " . current_buffer
1178 sil exe ":set switchbuf=" . save_sb
1179 elseif is_buffer
1180 startinsert!
1181 endif
1182
1183 return t_obj
1184
1185endfunction "}}}
1186
1187" open(), but no buffer
1188function! conque_term#subprocess(command) " {{{
1189
1190 let t_obj = conque_term#open(a:command, [], 0, 0)
1191 if !exists('b:ConqueTerm_Var')
1192 call conque_term#on_blur(0)
1193 sil exe s:py . ' ' . g:ConqueTerm_Var . '.idle()'
1194 endif
1195 return t_obj
1196
1197endfunction " }}}
1198
1199" set buffer options
1200function! conque_term#set_buffer_settings(command, vim_startup_commands) "{{{
1201
1202 " optional hooks to execute, e.g. 'split'
1203 for h in a:vim_startup_commands
1204 sil exe h
1205 endfor
1206 sil exe 'edit ++enc=utf-8 ' . g:ConqueTerm_BufName
1207
1208 " buffer settings
1209 setlocal fileencoding=utf-8 " file encoding, even tho there's no file
1210 setlocal nopaste " conque won't work in paste mode
1211 setlocal buftype=nofile " this buffer is not a file, you can't save it
1212 setlocal nonumber " hide line numbers
1213 if v:version >= 703
1214 setlocal norelativenumber " hide relative line numbers (VIM >= 7.3)
1215 endif
1216 setlocal foldcolumn=0 " reasonable left margin
1217 setlocal nowrap " default to no wrap (esp with MySQL)
1218 setlocal noswapfile " don't bother creating a .swp file
1219 setlocal scrolloff=0 " don't use buffer lines. it makes the 'clear' command not work as expected
1220 setlocal sidescrolloff=0 " don't use buffer lines. it makes the 'clear' command not work as expected
1221 setlocal sidescroll=1 " don't use buffer lines. it makes the 'clear' command not work as expected
1222 setlocal foldmethod=manual " don't fold on {{{}}} and stuff
1223 setlocal bufhidden=hide " when buffer is no longer displayed, don't wipe it out
1224 setlocal noreadonly " this is not actually a readonly buffer
1225 if v:version >= 703
1226 setlocal conceallevel=3
1227 setlocal concealcursor=nic
1228 endif
1229 if g:ConqueTerm_ReadUnfocused
1230 set cpoptions+=I " Don't remove autoindent when moving cursor up and down
1231 endif
1232 setfiletype conque_term " useful
1233 sil exe "setlocal syntax=" . g:ConqueTerm_Syntax
1234
1235 " temporary global settings go in here
1236 call conque_term#on_focus(1)
1237
1238endfunction " }}}
1239
1240" send normal character key press to terminal
1241function! conque_term#key_press() "{{{
1242 sil exe s:py . ' ' . b:ConqueTerm_Var . ".write_buffered_ord(" . char2nr(v:char) . ")"
1243 sil let v:char = ''
1244endfunction " }}}
1245
1246
1247
1248" set key mappings and auto commands
1249function! conque_term#set_mappings(action) "{{{
1250
1251 " set action {{{
1252 if a:action == 'toggle'
1253 if exists('b:conque_on') && b:conque_on == 1
1254 let l:action = 'stop'
1255 echohl WarningMsg | echomsg "Terminal is paused" | echohl None
1256 else
1257 let l:action = 'start'
1258 echohl WarningMsg | echomsg "Terminal is resumed" | echohl None
1259 endif
1260 else
1261 let l:action = a:action
1262 endif
1263
1264 " if mappings are being removed, add 'un'
1265 let map_modifier = 'nore'
1266 if l:action == 'stop'
1267 let map_modifier = 'un'
1268 endif
1269 " }}}
1270
1271 " auto commands {{{
1272 if l:action == 'stop'
1273 sil exe 'autocmd! ' . b:ConqueTerm_Var
1274
1275 else
1276 sil exe 'augroup ' . b:ConqueTerm_Var
1277
1278 " handle unexpected closing of shell, passes HUP to parent and all child processes
1279 sil exe 'autocmd ' . b:ConqueTerm_Var . ' BufDelete <buffer> call g:ConqueTerm_Terminals[' . b:ConqueTerm_Idx . '].close()'
1280 sil exe 'autocmd ' . b:ConqueTerm_Var . ' BufUnload <buffer> call g:ConqueTerm_Terminals[' . b:ConqueTerm_Idx . '].close()'
1281
1282 " check for resized/scrolled buffer when entering buffer
1283 sil exe 'autocmd ' . b:ConqueTerm_Var . ' BufEnter <buffer> ' . s:py . ' ' . b:ConqueTerm_Var . '.update_window_size()'
1284 sil exe 'autocmd ' . b:ConqueTerm_Var . ' VimResized ' . s:py . ' ' . b:ConqueTerm_Var . '.update_window_size()'
1285
1286 sil exe 'autocmd ' . b:ConqueTerm_Var . ' BufEnter <buffer> call conque_term#on_focus()'
1287 sil exe 'autocmd ' . b:ConqueTerm_Var . ' BufLeave <buffer> call conque_term#on_blur(1)'
1288
1289 " reposition cursor when going into insert mode
1290 sil exe 'autocmd ' . b:ConqueTerm_Var . ' InsertEnter <buffer> ' . s:py . ' ' . b:ConqueTerm_Var . '.insert_enter()'
1291 sil exe 'autocmd ' . b:ConqueTerm_Var . ' InsertEnter <buffer> call s:insert_enter()'
1292 sil exe 'autocmd ' . b:ConqueTerm_Var . ' InsertLeave <buffer> call s:insert_leave()'
1293
1294 " How to poll for more output
1295 if g:ConqueTerm_ReadUnfocused
1296 sil exe 'autocmd ' . b:ConqueTerm_Var . ' CursorHoldI <buffer> call conque_term#read_all(1)'
1297 sil exe 'autocmd ' . b:ConqueTerm_Var . ' CursorHold <buffer> call conque_term#read_all(0)'
1298 else
1299 sil exe 'autocmd ' . b:ConqueTerm_Var . ' CursorHoldI <buffer> ' . s:py . ' ' . b:ConqueTerm_Var . '.auto_read()'
1300 endif
1301 endif
1302 " }}}
1303
1304 " map ASCII 1-31 {{{
1305 for c in range(1, 31)
1306 " <Esc>
1307 if c == 27 || c == 3
1308 continue
1309 endif
1310 if l:action == 'start'
1311 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-' . nr2char(64 + c) . '> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(' . c . ')<CR>'
1312 else
1313 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-' . nr2char(64 + c) . '>'
1314 endif
1315 endfor
1316
1317 if exists('g:ConqueTerm_Interrupt')
1318 " Use user defined key binding to send interrupt to terminal in normal and insert mode
1319 if l:action == 'start'
1320 sil exe 'i' . map_modifier . 'map <silent> <buffer> ' . g:ConqueTerm_Interrupt . ' <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(3)<CR>'
1321 sil exe 'n' . map_modifier . 'map <silent> <buffer> ' . g:ConqueTerm_Interrupt . ' <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(3)<CR>'
1322 else
1323 sil exe 'i' . map_modifier . 'map <silent> <buffer> ' . g:ConqueTerm_Interrupt
1324 sil exe 'n' . map_modifier . 'map <silent> <buffer> ' . g:ConqueTerm_Interrupt
1325 endif
1326 else
1327 " Use default key binding to send interrupt to terminal in normal and insert mode
1328 if l:action == 'start'
1329 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-c> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(3)<CR>'
1330 sil exe 'n' . map_modifier . 'map <silent> <buffer> <C-c> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(3)<CR>'
1331 else
1332 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-c>'
1333 sil exe 'n' . map_modifier . 'map <silent> <buffer> <C-c>'
1334 endif
1335 endif
1336
1337 " leave insert mode
1338 if !exists('g:ConqueTerm_EscKey') || g:ConqueTerm_EscKey =~ '<[Ee][Ss][Cc]>'
1339 " use <Esc><Esc> to send <Esc> to terminal
1340 if l:action == 'start'
1341 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Esc><Esc> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(27)<CR>'
1342 else
1343 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Esc><Esc>'
1344 endif
1345 else
1346 " use <Esc> to send <Esc> to terminal
1347 if l:action == 'start'
1348 sil exe 'i' . map_modifier . 'map <silent> <buffer> ' . g:ConqueTerm_EscKey . ' <Esc>'
1349 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Esc> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_ord(27)<CR>'
1350 else
1351 sil exe 'i' . map_modifier . 'map <silent> <buffer> ' . g:ConqueTerm_EscKey
1352 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Esc>'
1353 endif
1354 endif
1355
1356 " Map <C-w> in insert mode
1357 if exists('g:ConqueTerm_CWInsert') && g:ConqueTerm_CWInsert == 1
1358 inoremap <silent> <buffer> <C-w> <Esc><C-w>
1359 endif
1360 " }}}
1361
1362 " map 33 and beyond {{{
1363 if exists('##InsertCharPre') && g:ConqueTerm_InsertCharPre == 1
1364 if l:action == 'start'
1365 autocmd InsertCharPre <buffer> call conque_term#key_press()
1366 else
1367 autocmd! InsertCharPre <buffer>
1368 endif
1369 else
1370 for i in range(33, 127)
1371 " <Bar>
1372 if i == 124
1373 if l:action == 'start'
1374 sil exe "i" . map_modifier . "map <silent> <buffer> <Bar> <C-o>:" . s:py . ' ' . b:ConqueTerm_Var . ".write_ord(124)<CR>"
1375 else
1376 sil exe "i" . map_modifier . "map <silent> <buffer> <Bar>"
1377 endif
1378 continue
1379 endif
1380 if l:action == 'start'
1381 sil exe "i" . map_modifier . "map <silent> <buffer> " . nr2char(i) . " <C-o>:" . s:py . ' ' . b:ConqueTerm_Var . ".write_ord(" . i . ")<CR>"
1382 else
1383 sil exe "i" . map_modifier . "map <silent> <buffer> " . nr2char(i)
1384 endif
1385 endfor
1386 endif
1387 " }}}
1388
1389 " Special keys {{{
1390 if l:action == 'start'
1391 if s:platform == 'unix'
1392 sil exe 'i' . map_modifier . 'map <silent> <buffer> <BS> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x08"))<CR>'
1393 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Space> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u(" "))<CR>'
1394 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-BS> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x08"))<CR>'
1395 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Space> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u(" "))<CR>'
1396
1397 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Up> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[A"))<CR>'
1398 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Down> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[B"))<CR>'
1399 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Right> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[C"))<CR>'
1400 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Left> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[D"))<CR>'
1401
1402 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Up> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[A"))<CR>'
1403 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Down> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[B"))<CR>'
1404 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Right> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[C"))<CR>'
1405 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Left> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[D"))<CR>'
1406
1407 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Up> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[A"))<CR>'
1408 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Down> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[B"))<CR>'
1409 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Right> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[C"))<CR>'
1410 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Left> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[D"))<CR>'
1411
1412 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Home> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1bOH"))<CR>'
1413 sil exe 'i' . map_modifier . 'map <silent> <buffer> <End> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1bOF"))<CR>'
1414 else
1415 sil exe 'i' . map_modifier . 'map <silent> <buffer> <BS> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x08"))<CR>'
1416 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Space> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u(" "))<CR>'
1417
1418 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-BS> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x08"))<CR>'
1419 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Space> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u(" "))<CR>'
1420
1421 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Up> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_UP . ')<CR>'
1422 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Down> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_DOWN . ')<CR>'
1423 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Right> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_RIGHT . ')<CR>'
1424 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Left> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_LEFT . ')<CR>'
1425
1426 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Up> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_UP . ')<CR>'
1427 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Down> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_DOWN . ')<CR>'
1428 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Right> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_RIGHT . ')<CR>'
1429 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Left> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_LEFT . ')<CR>'
1430
1431 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Up> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk("' . s:windows_vk.VK_UP_CTL . '")<CR>'
1432 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Down> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk("' . s:windows_vk.VK_DOWN_CTL . '")<CR>'
1433 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Right> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk("' . s:windows_vk.VK_RIGHT_CTL . '")<CR>'
1434 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Left> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk("' . s:windows_vk.VK_LEFT_CTL . '")<CR>'
1435
1436 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Del> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_DELETE . ')<CR>'
1437 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Home> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_HOME . ')<CR>'
1438 sil exe 'i' . map_modifier . 'map <silent> <buffer> <End> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_END . ')<CR>'
1439 endif
1440 else
1441 sil exe 'i' . map_modifier . 'map <silent> <buffer> <BS>'
1442 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Space>'
1443 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-BS>'
1444 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Space>'
1445
1446 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Up>'
1447 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Down>'
1448 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Right>'
1449 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Left>'
1450
1451 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Up>'
1452 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Down>'
1453 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Right>'
1454 sil exe 'i' . map_modifier . 'map <silent> <buffer> <S-Left>'
1455
1456 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Up>'
1457 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Down>'
1458 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Right>'
1459 sil exe 'i' . map_modifier . 'map <silent> <buffer> <C-Left>'
1460
1461 sil exe 'i' . map_modifier . 'map <silent> <buffer> <Home>'
1462 sil exe 'i' . map_modifier . 'map <silent> <buffer> <End>'
1463 endif
1464 " }}}
1465
1466 " <F-> keys {{{
1467 if g:ConqueTerm_SendFunctionKeys
1468 if l:action == 'start'
1469 if s:platform == 'unix'
1470 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F1> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[11~"))<CR>'
1471 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F2> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[12~"))<CR>'
1472 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F3> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("1b[13~"))<CR>'
1473 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F4> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[14~"))<CR>'
1474 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F5> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[15~"))<CR>'
1475 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F6> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[17~"))<CR>'
1476 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F7> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[18~"))<CR>'
1477 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F8> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[19~"))<CR>'
1478 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F9> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[20~"))<CR>'
1479 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F10> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[21~"))<CR>'
1480 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F11> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[23~"))<CR>'
1481 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F12> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write(u("\x1b[24~"))<CR>'
1482 else
1483 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F1> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F1 . ')<CR>'
1484 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F2> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F2 . ')<CR>'
1485 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F3> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F3 . ')<CR>'
1486 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F4> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F4 . ')<CR>'
1487 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F5> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F5 . ')<CR>'
1488 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F6> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F6 . ')<CR>'
1489 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F7> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F7 . ')<CR>'
1490 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F8> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F8 . ')<CR>'
1491 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F9> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F9 . ')<CR>'
1492 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F10> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F10 . ')<CR>'
1493 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F11> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F11 . ')<CR>'
1494 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F12> <C-o>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_vk(' . s:windows_vk.VK_F12 . ')<CR>'
1495 endif
1496 else
1497 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F1>'
1498 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F2>'
1499 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F3>'
1500 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F4>'
1501 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F5>'
1502 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F6>'
1503 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F7>'
1504 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F8>'
1505 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F9>'
1506 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F10>'
1507 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F11>'
1508 sil exe 'i' . map_modifier . 'map <silent> <buffer> <F12>'
1509 endif
1510 endif
1511 " }}}
1512
1513 " various global mappings {{{
1514 " don't overwrite existing mappings
1515 if l:action == 'start'
1516 if maparg(g:ConqueTerm_SendVisKey, 'v') == ''
1517 sil exe 'v' . map_modifier . 'map <silent> ' . g:ConqueTerm_SendVisKey . ' :<C-u>call conque_term#send_selected(visualmode())<CR>'
1518 endif
1519 if maparg(g:ConqueTerm_SendFileKey, 'n') == ''
1520 sil exe 'n' . map_modifier . 'map <silent> ' . g:ConqueTerm_SendFileKey . ' :<C-u>call conque_term#send_file()<CR>'
1521 endif
1522 endif
1523 " }}}
1524
1525 " remap paste keys {{{
1526 if l:action == 'start'
1527 sil exe 'n' . map_modifier . 'map <silent> <buffer> p :' . s:py . ' ' . b:ConqueTerm_Var . '.write_expr("@@")<CR>a'
1528 sil exe 'n' . map_modifier . 'map <silent> <buffer> P :' . s:py . ' ' . b:ConqueTerm_Var . '.write_expr("@@")<CR>a'
1529 sil exe 'n' . map_modifier . 'map <silent> <buffer> ]p :' . s:py . ' ' . b:ConqueTerm_Var . '.write_expr("@@")<CR>a'
1530 sil exe 'n' . map_modifier . 'map <silent> <buffer> [p :' . s:py . ' ' . b:ConqueTerm_Var . '.write_expr("@@")<CR>a'
1531 else
1532 sil exe 'n' . map_modifier . 'map <silent> <buffer> p'
1533 sil exe 'n' . map_modifier . 'map <silent> <buffer> P'
1534 sil exe 'n' . map_modifier . 'map <silent> <buffer> ]p'
1535 sil exe 'n' . map_modifier . 'map <silent> <buffer> [p'
1536 endif
1537 if has('gui_running') == 1
1538 if l:action == 'start'
1539 sil exe 'i' . map_modifier . 'map <buffer> <S-Insert> <Esc>:' . s:py . ' ' . b:ConqueTerm_Var . '.write_expr("@+")<CR>a'
1540 sil exe 'i' . map_modifier . 'map <buffer> <S-Help> <Esc>:<C-u>' . s:py . ' ' . b:ConqueTerm_Var . '.write_expr("@+")<CR>a'
1541 else
1542 sil exe 'i' . map_modifier . 'map <buffer> <S-Insert>'
1543 sil exe 'i' . map_modifier . 'map <buffer> <S-Help>'
1544 endif
1545 endif
1546 " }}}
1547
1548 " disable other normal mode keys which insert text {{{
1549 if l:action == 'start'
1550 sil exe 'n' . map_modifier . 'map <silent> <buffer> r :echo "Replace mode disabled in shell."<CR>'
1551 sil exe 'n' . map_modifier . 'map <silent> <buffer> R :echo "Replace mode disabled in shell."<CR>'
1552 sil exe 'n' . map_modifier . 'map <silent> <buffer> c :echo "Change mode disabled in shell."<CR>'
1553 sil exe 'n' . map_modifier . 'map <silent> <buffer> C :echo "Change mode disabled in shell."<CR>'
1554 sil exe 'n' . map_modifier . 'map <silent> <buffer> s :echo "Change mode disabled in shell."<CR>'
1555 sil exe 'n' . map_modifier . 'map <silent> <buffer> S :echo "Change mode disabled in shell."<CR>'
1556 else
1557 sil exe 'n' . map_modifier . 'map <silent> <buffer> r'
1558 sil exe 'n' . map_modifier . 'map <silent> <buffer> R'
1559 sil exe 'n' . map_modifier . 'map <silent> <buffer> c'
1560 sil exe 'n' . map_modifier . 'map <silent> <buffer> C'
1561 sil exe 'n' . map_modifier . 'map <silent> <buffer> s'
1562 sil exe 'n' . map_modifier . 'map <silent> <buffer> S'
1563 endif
1564 " }}}
1565
1566 " set conque as on or off {{{
1567 if l:action == 'start'
1568 let b:conque_on = 1
1569 else
1570 let b:conque_on = 0
1571 endif
1572 " }}}
1573
1574 " map command to toggle terminal key mappings {{{
1575 if a:action == 'start'
1576 sil exe 'nnoremap ' . g:ConqueTerm_ToggleKey . ' :<C-u>call conque_term#set_mappings("toggle")<CR>'
1577 endif
1578 " }}}
1579
1580 " call user defined functions
1581 if l:action == 'start'
1582 call conque_term#call_hooks('after_keymap', conque_term#get_instance())
1583 endif
1584
1585endfunction " }}}
1586
1587" Initialize global mappings. Should only be called once per Vim session
1588function! conque_term#init() " {{{
1589
1590 if s:initialized == 1
1591 return
1592 endif
1593
1594 augroup ConqueTerm
1595
1596 " abort any remaining running terminals when Vim exits
1597 autocmd ConqueTerm VimLeave * call conque_term#close_all()
1598
1599 " read more output when this isn't the current buffer
1600 if g:ConqueTerm_ReadUnfocused == 1
1601 autocmd ConqueTerm CursorHold * call conque_term#read_all(0)
1602 endif
1603
1604 let s:initialized = 1
1605
1606endfunction " }}}
1607
1608function! s:buffer_update(insert_mode) "{{{
1609 " restart updatetime
1610 if a:insert_mode
1611 if col(".") == col("$")
1612 call feedkeys("\<Right>", "n")
1613 else
1614 call feedkeys("\<Right>\<Left>", "n")
1615 endif
1616 else
1617 call feedkeys("f\e", "n")
1618 endif
1619endfunction " }}}
1620
1621" read from all known conque buffers
1622function! conque_term#read_all(insert_mode) "{{{
1623
1624 let term_running = 0
1625 let buffer = bufnr("%")
1626
1627 for i in range(1, g:ConqueTerm_Idx)
1628 try
1629 if !g:ConqueTerm_Terminals[i].active
1630 continue
1631 endif
1632
1633 let term_running = 1
1634
1635 if g:ConqueTerm_Terminals[i].buffer_number == buffer
1636 sil exe s:py . ' ' . b:ConqueTerm_Var . '.auto_read(False)'
1637 else
1638 call g:ConqueTerm_Terminals[i].read(1)
1639 endif
1640
1641 if !g:ConqueTerm_Terminals[i].is_buffer && exists('*g:ConqueTerm_Terminals[i].callback')
1642 call g:ConqueTerm_Terminals[i].callback(output)
1643 endif
1644 catch
1645 " probably a deleted buffer
1646 endtry
1647 endfor
1648
1649 if term_running
1650 call s:buffer_update(a:insert_mode)
1651 endif
1652
1653endfunction "}}}
1654
1655" close all subprocesses
1656function! conque_term#close_all() "{{{
1657
1658 for i in range(1, g:ConqueTerm_Idx)
1659 try
1660 call g:ConqueTerm_Terminals[i].close()
1661 catch
1662 " probably a deleted buffer
1663 endtry
1664 endfor
1665
1666endfunction "}}}
1667
1668" gets called when user enters conque buffer.
1669" Useful for making temp changes to global config
1670function! conque_term#on_focus(...) " {{{
1671
1672 let startup = get(a:000, 0, 0)
1673
1674 " Disable NeoComplCache. It has global hooks on CursorHold and CursorMoved :-/
1675 let s:NeoComplCache_WasEnabled = exists(':NeoComplCacheLock')
1676 if s:NeoComplCache_WasEnabled == 2
1677 NeoComplCacheLock
1678 endif
1679
1680 if g:ConqueTerm_ReadUnfocused == 1
1681 autocmd! ConqueTerm CursorHoldI *
1682 autocmd! ConqueTerm CursorHold *
1683 endif
1684
1685 " resume subprocess fast polling
1686 if startup == 0 && exists('b:ConqueTerm_Var')
1687 sil exe s:py . ' ' . g:ConqueTerm_Var . '.resume()'
1688 endif
1689
1690 " call user defined functions
1691 if startup == 0
1692 call conque_term#call_hooks('buffer_enter', conque_term#get_instance())
1693 endif
1694
1695 " if configured, go into insert mode
1696 if g:ConqueTerm_InsertOnEnter == 1
1697 startinsert!
1698 endif
1699
1700endfunction " }}}
1701
1702function! s:set_term_updatetime(time)
1703 if a:time
1704 sil exe 'set updatetime=' . a:time
1705 endif
1706 let s:reset_updatetime = a:time
1707endfunction
1708
1709function! s:insert_enter() " {{{
1710 call s:set_term_updatetime(g:ConqueTerm_FocusedUpdateTime)
1711endfunction " }}}
1712
1713function! s:insert_leave() " {{{
1714 call s:set_term_updatetime(g:ConqueTerm_UnfocusedUpdateTime)
1715endfunction " }}}
1716
1717" gets called when user exits conque buffer.
1718" Useful for resetting changes to global config
1719function! conque_term#on_blur(is_buffer) " {{{
1720 " re-enable NeoComplCache if needed
1721 if exists('s:NeoComplCache_WasEnabled') && exists(':NeoComplCacheUnlock') && s:NeoComplCache_WasEnabled == 2
1722 NeoComplCacheUnlock
1723 endif
1724
1725 " turn off subprocess fast polling
1726 if exists('b:ConqueTerm_Var')
1727 sil exe s:py . ' ' . b:ConqueTerm_Var . '.idle()'
1728 endif
1729
1730 " reset poll interval
1731 if g:ConqueTerm_ReadUnfocused
1732 call s:set_term_updatetime(g:ConqueTerm_UnfocusedUpdateTime)
1733 autocmd ConqueTerm CursorHoldI * call conque_term#read_all(1)
1734 autocmd ConqueTerm CursorHold * call conque_term#read_all(0)
1735 elseif s:reset_updatetime
1736 sil exe 'set updatetime=' . s:save_updatetime
1737 endif
1738
1739 " call user defined functions
1740 call conque_term#call_hooks('buffer_leave', conque_term#get_instance())
1741
1742endfunction " }}}
1743
1744" bell event (^G)
1745function! conque_term#bell() " {{{
1746 if g:ConqueTerm_ShowBell
1747 echohl WarningMsg | echomsg "BELL!" | echohl None
1748 endif
1749endfunction " }}}
1750
1751" register function to be called at conque events
1752function! conque_term#register_function(event, function_name) " {{{
1753
1754 if !has_key(s:hooks, a:event)
1755 echomsg 'No such event: ' . a:event
1756 return
1757 endif
1758
1759 if !exists('*' . a:function_name)
1760 echomsg 'No such function: ' . a:function_name)
1761 return
1762 endif
1763
1764 " register the function
1765 call add(s:hooks[a:event], function(a:function_name))
1766
1767endfunction " }}}
1768
1769" call hooks for an event
1770function! conque_term#call_hooks(event, t_obj) " {{{
1771
1772 for Fu in s:hooks[a:event]
1773 call Fu(a:t_obj)
1774 endfor
1775
1776endfunction " }}}
1777
1778" }}}
1779
1780" **********************************************************************************************************
1781" **** Windows only functions ******************************************************************************
1782" **********************************************************************************************************
1783
1784" {{{
1785
1786" find python.exe in windows
1787function! conque_term#find_python_exe() " {{{
1788
1789 " first check configuration for custom value
1790 if g:ConqueTerm_PyExe != '' && executable(g:ConqueTerm_PyExe)
1791 return g:ConqueTerm_PyExe
1792 endif
1793
1794 let sys_paths = split($PATH, ';')
1795
1796 " get exact python version
1797 sil exe ':' . s:py . ' import sys, vim'
1798 sil exe ':' . s:py . ' vim.command("let g:ConqueTerm_PyVersion = " + str(sys.version_info[0]) + str(sys.version_info[1]))'
1799
1800 " ... and add to path list
1801 call add(sys_paths, 'C:\Python' . g:ConqueTerm_PyVersion)
1802 call reverse(sys_paths)
1803
1804 " check if python.exe is in paths
1805 for path in sys_paths
1806 let cand = path . '\' . 'python.exe'
1807 if executable(cand)
1808 return cand
1809 endif
1810 endfor
1811
1812 echohl WarningMsg | echomsg "Unable to find python.exe, see :help ConqueTerm_PythonExe for more information" | echohl None
1813
1814 return ''
1815
1816endfunction " }}}
1817
1818" initialize concealed colors
1819function! conque_term#init_conceal_color() " {{{
1820
1821 highlight link ConqueCCBG Normal
1822
1823 " foreground colors, low intensity
1824 syn region ConqueCCF000 matchgroup=ConqueConceal start="\esf000;" end="\eef000;" concealends contains=ConqueCCBG
1825 syn region ConqueCCF00c matchgroup=ConqueConceal start="\esf00c;" end="\eef00c;" concealends contains=ConqueCCBG
1826 syn region ConqueCCF0c0 matchgroup=ConqueConceal start="\esf0c0;" end="\eef0c0;" concealends contains=ConqueCCBG
1827 syn region ConqueCCF0cc matchgroup=ConqueConceal start="\esf0cc;" end="\eef0cc;" concealends contains=ConqueCCBG
1828 syn region ConqueCCFc00 matchgroup=ConqueConceal start="\esfc00;" end="\eefc00;" concealends contains=ConqueCCBG
1829 syn region ConqueCCFc0c matchgroup=ConqueConceal start="\esfc0c;" end="\eefc0c;" concealends contains=ConqueCCBG
1830 syn region ConqueCCFcc0 matchgroup=ConqueConceal start="\esfcc0;" end="\eefcc0;" concealends contains=ConqueCCBG
1831 syn region ConqueCCFccc matchgroup=ConqueConceal start="\esfccc;" end="\eefccc;" concealends contains=ConqueCCBG
1832
1833 " foreground colors, high intensity
1834 syn region ConqueCCF000 matchgroup=ConqueConceal start="\esf000;" end="\eef000;" concealends contains=ConqueCCBG
1835 syn region ConqueCCF00f matchgroup=ConqueConceal start="\esf00f;" end="\eef00f;" concealends contains=ConqueCCBG
1836 syn region ConqueCCF0f0 matchgroup=ConqueConceal start="\esf0f0;" end="\eef0f0;" concealends contains=ConqueCCBG
1837 syn region ConqueCCF0ff matchgroup=ConqueConceal start="\esf0ff;" end="\eef0ff;" concealends contains=ConqueCCBG
1838 syn region ConqueCCFf00 matchgroup=ConqueConceal start="\esff00;" end="\eeff00;" concealends contains=ConqueCCBG
1839 syn region ConqueCCFf0f matchgroup=ConqueConceal start="\esff0f;" end="\eeff0f;" concealends contains=ConqueCCBG
1840 syn region ConqueCCFff0 matchgroup=ConqueConceal start="\esfff0;" end="\eefff0;" concealends contains=ConqueCCBG
1841 syn region ConqueCCFfff matchgroup=ConqueConceal start="\esffff;" end="\eeffff;" concealends contains=ConqueCCBG
1842
1843 " background colors, low intensity
1844 syn region ConqueCCB000 matchgroup=ConqueCCBG start="\esb000;" end="\eeb000;" concealends
1845 syn region ConqueCCB00c matchgroup=ConqueCCBG start="\esb00c;" end="\eeb00c;" concealends
1846 syn region ConqueCCB0c0 matchgroup=ConqueCCBG start="\esb0c0;" end="\eeb0c0;" concealends
1847 syn region ConqueCCB0cc matchgroup=ConqueCCBG start="\esb0cc;" end="\eeb0cc;" concealends
1848 syn region ConqueCCBc00 matchgroup=ConqueCCBG start="\esbc00;" end="\eebc00;" concealends
1849 syn region ConqueCCBc0c matchgroup=ConqueCCBG start="\esbc0c;" end="\eebc0c;" concealends
1850 syn region ConqueCCBcc0 matchgroup=ConqueCCBG start="\esbcc0;" end="\eebcc0;" concealends
1851 syn region ConqueCCBccc matchgroup=ConqueCCBG start="\esbccc;" end="\eebccc;" concealends
1852
1853 " background colors, high intensity
1854 syn region ConqueCCB000 matchgroup=ConqueCCBG start="\esb000;" end="\eeb000;" concealends
1855 syn region ConqueCCB00f matchgroup=ConqueCCBG start="\esb00f;" end="\eeb00f;" concealends
1856 syn region ConqueCCB0f0 matchgroup=ConqueCCBG start="\esb0f0;" end="\eeb0f0;" concealends
1857 syn region ConqueCCB0ff matchgroup=ConqueCCBG start="\esb0ff;" end="\eeb0ff;" concealends
1858 syn region ConqueCCBf00 matchgroup=ConqueCCBG start="\esbf00;" end="\eebf00;" concealends
1859 syn region ConqueCCBf0f matchgroup=ConqueCCBG start="\esbf0f;" end="\eebf0f;" concealends
1860 syn region ConqueCCBff0 matchgroup=ConqueCCBG start="\esbff0;" end="\eebff0;" concealends
1861 syn region ConqueCCBfff matchgroup=ConqueCCBG start="\esbfff;" end="\eebfff;" concealends
1862
1863
1864 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1865 """"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""
1866
1867 "highlight link ConqueCCConceal Error
1868
1869 " foreground colors, low intensity
1870 highlight ConqueCCF000 guifg=#000000
1871 highlight ConqueCCF00c guifg=#0000cc
1872 highlight ConqueCCF0c0 guifg=#00cc00
1873 highlight ConqueCCF0cc guifg=#00cccc
1874 highlight ConqueCCFc00 guifg=#cc0000
1875 highlight ConqueCCFc0c guifg=#cc00cc
1876 highlight ConqueCCFcc0 guifg=#cccc00
1877 highlight ConqueCCFccc guifg=#cccccc
1878
1879 " foreground colors, high intensity
1880 highlight ConqueCCF000 guifg=#000000
1881 highlight ConqueCCF00f guifg=#0000ff
1882 highlight ConqueCCF0f0 guifg=#00ff00
1883 highlight ConqueCCF0ff guifg=#00ffff
1884 highlight ConqueCCFf00 guifg=#ff0000
1885 highlight ConqueCCFf0f guifg=#ff00ff
1886 highlight ConqueCCFff0 guifg=#ffff00
1887 highlight ConqueCCFfff guifg=#ffffff
1888
1889 " background colors, low intensity
1890 highlight ConqueCCB000 guibg=#000000
1891 highlight ConqueCCB00c guibg=#0000cc
1892 highlight ConqueCCB0c0 guibg=#00cc00
1893 highlight ConqueCCB0cc guibg=#00cccc
1894 highlight ConqueCCBc00 guibg=#cc0000
1895 highlight ConqueCCBc0c guibg=#cc00cc
1896 highlight ConqueCCBcc0 guibg=#cccc00
1897 highlight ConqueCCBccc guibg=#cccccc
1898
1899 " background colors, high intensity
1900 highlight ConqueCCB000 guibg=#000000
1901 highlight ConqueCCB00f guibg=#0000ff
1902 highlight ConqueCCB0f0 guibg=#00ff00
1903 highlight ConqueCCB0ff guibg=#00ffff
1904 highlight ConqueCCBf00 guibg=#ff0000
1905 highlight ConqueCCBf0f guibg=#ff00ff
1906 highlight ConqueCCBff0 guibg=#ffff00
1907 highlight ConqueCCBfff guibg=#ffffff
1908
1909 " background colors, low intensity
1910 highlight link ConqueCCB000 ConqueCCBG
1911 highlight link ConqueCCB00c ConqueCCBG
1912 highlight link ConqueCCB0c0 ConqueCCBG
1913 highlight link ConqueCCB0cc ConqueCCBG
1914 highlight link ConqueCCBc00 ConqueCCBG
1915 highlight link ConqueCCBc0c ConqueCCBG
1916 highlight link ConqueCCBcc0 ConqueCCBG
1917 highlight link ConqueCCBccc ConqueCCBG
1918
1919 " background colors, high intensity
1920 highlight link ConqueCCB000 ConqueCCBG
1921 highlight link ConqueCCB00f ConqueCCBG
1922 highlight link ConqueCCB0f0 ConqueCCBG
1923 highlight link ConqueCCB0ff ConqueCCBG
1924 highlight link ConqueCCBf00 ConqueCCBG
1925 highlight link ConqueCCBf0f ConqueCCBG
1926 highlight link ConqueCCBff0 ConqueCCBG
1927 highlight link ConqueCCBfff ConqueCCBG
1928
1929endfunction " }}}
1930
1931" }}}
1932
1933" **********************************************************************************************************
1934" **** Add-on features *************************************************************************************
1935" **********************************************************************************************************
1936
1937" {{{
1938
1939" send selected text from another buffer
1940function! conque_term#send_selected(type) "{{{
1941
1942 " get most recent/relevant terminal
1943 let term = conque_term#get_instance()
1944
1945 " shove visual text into @@ register
1946 let reg_save = @@
1947 sil exe "normal! `<" . a:type . "`>y"
1948 let @@ = substitute(@@, '^[\r\n]*', '', '')
1949 let @@ = substitute(@@, '[\r\n]*$', '', '')
1950
1951 " go to terminal buffer
1952 call term.focus()
1953
1954 " execute yanked text
1955 call term.write(@@)
1956
1957 " reset original values
1958 let @@ = reg_save
1959
1960 " scroll buffer left
1961 startinsert!
1962 normal! 0zH
1963
1964endfunction "}}}
1965
1966function! conque_term#send_file() "{{{
1967
1968 let file_lines = readfile(expand('%:p'))
1969 if type(file_lines) == 3 && len(file_lines) > 0
1970 let term = conque_term#get_instance()
1971 call term.focus()
1972
1973 for line in file_lines
1974 call term.writeln(line)
1975 endfor
1976 else
1977 echomsg 'Could not read file: ' . expand('%:p')
1978 endif
1979
1980endfunction "}}}
1981
1982
1983function! conque_term#exec_file() "{{{
1984
1985 let current_file = expand('%:p')
1986 if !executable(current_file)
1987 echomsg "Could not run " . current_file . ". Not an executable."
1988 return
1989 endif
1990 sil exe ':ConqueTermSplit ' . current_file
1991
1992endfunction "}}}
1993
1994
1995" called on SessionLoadPost event
1996function! conque_term#resume_session() " {{{
1997 " Session support is currently not working
1998 return
1999 if g:ConqueTerm_SessionSupport == 1
2000
2001 " make sure terminals exist
2002 if !exists('s:saved_terminals') || type(s:saved_terminals) != 4
2003 return
2004 endif
2005
2006 " rebuild terminals
2007 for idx in keys(s:saved_terminals)
2008
2009 " don't recreate inactive terminals
2010 if s:saved_terminals[idx].active == 0
2011 continue
2012 endif
2013
2014 " check we're in the right buffer
2015 let bufname = substitute(s:saved_terminals[idx].buffer_name, '\', '', 'g')
2016 if bufname != bufname("%")
2017 continue
2018 endif
2019
2020 " reopen command
2021 call conque_term#open(s:saved_terminals[idx].command)
2022
2023 endfor
2024
2025 endif
2026endfunction " }}}
2027
2028" }}}
2029
2030" **********************************************************************************************************
2031" **** "API" functions *************************************************************************************
2032" **********************************************************************************************************
2033
2034" {{{
2035
2036" Write to a conque terminal buffer
2037function! s:term_obj.write(...) dict " {{{
2038
2039 let text = get(a:000, 0, '')
2040 let jump_to_buffer = get(a:000, 1, 0)
2041
2042 " if we're not in terminal buffer, pass flag to not position the cursor
2043 sil exe s:py . ' ' . self.var . '.write_expr("text", False, False)'
2044
2045 " move cursor to conque buffer
2046 if jump_to_buffer
2047 call self.focus()
2048 endif
2049
2050endfunction " }}}
2051
2052" same as write() but adds a newline
2053function! s:term_obj.writeln(...) dict " {{{
2054
2055 let text = get(a:000, 0, '')
2056 let jump_to_buffer = get(a:000, 1, 0)
2057
2058 call self.write(text . "\r", jump_to_buffer)
2059
2060endfunction " }}}
2061
2062" move cursor to terminal buffer
2063function! s:term_obj.focus() dict " {{{
2064
2065 let save_sb = &switchbuf
2066 sil set switchbuf=usetab
2067 sil exe 'sb ' . self.buffer_number
2068 sil exe ":set switchbuf=" . save_sb
2069 startinsert!
2070
2071endfunction " }}}
2072
2073" read from terminal buffer and return string
2074function! s:term_obj.read(...) dict " {{{
2075
2076 sil exe s:py . ' if not ' . self.var . '.proc.is_alive(): vim.command("call conque_term#get_instance(' . self.idx . ').close()")'
2077
2078 let read_time = get(a:000, 0, 1)
2079 let update_buffer = get(a:000, 1, self.is_buffer)
2080
2081 if update_buffer
2082 let term_win = bufwinnr(self.buffer_number)
2083 if term_win == -1
2084 " Don't read when the buffer window isn't visible
2085 return ''
2086 endif
2087
2088 let last_win = winnr()
2089
2090 " Keep users previous window
2091 sil noautocmd wincmd p
2092 " Focus to the terminal window
2093 sil exe 'noautocmd ' . term_win . 'wincmd w'
2094
2095 let up_py = 'True'
2096 else
2097 let up_py = 'False'
2098 endif
2099
2100 let output = ''
2101
2102 " read!
2103 sil exec s:py . " conque_tmp = " . self.var . ".read(timeout = " . read_time . ", set_cursor = " . up_py . ", return_output = True, update_buffer = " . up_py . ")"
2104
2105 " ftw!
2106 try
2107 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"
2108 sil exec s:py . pycode
2109 catch
2110 " d'oh
2111 endtry
2112
2113 if update_buffer
2114 sil exec s:py . ' ' . self.var . '.update_window()'
2115
2116 " First go to the users previous window (#)
2117 sil noautocmd wincmd p
2118 " Next go to the users last window (%)
2119 sil exe 'noautocmd ' . last_win . 'wincmd w'
2120 endif
2121
2122 return output
2123endfunction " }}}
2124
2125" set output callback
2126function! s:term_obj.set_callback(callback_func) dict " {{{
2127
2128 let g:ConqueTerm_Terminals[self.idx].callback = function(a:callback_func)
2129
2130endfunction " }}}
2131
2132" close subprocess with ABORT signal
2133function! s:term_obj.close() dict " {{{
2134
2135 let last_buf = bufnr("%")
2136 sil exe 'noautocmd buffer ' . self.buffer_number
2137
2138 " kill process
2139 try
2140 sil exe s:py . ' ' . self.var . '.abort()'
2141 catch
2142 " probably already dead
2143 endtry
2144
2145 " delete buffer if option is set
2146 if self.is_buffer
2147 try
2148 call conque_term#set_mappings('stop')
2149 catch
2150 endtry
2151 if exists('g:ConqueTerm_CloseOnEnd') && g:ConqueTerm_CloseOnEnd && buflisted(self.buffer_number)
2152 sil exe 'bwipeout ' . self.buffer_number
2153 stopinsert
2154 endif
2155 endif
2156
2157 " mark ourselves as inactive
2158 let self.active = 0
2159
2160 " rebuild session options
2161 let g:ConqueTerm_TerminalsString = string(g:ConqueTerm_Terminals)
2162
2163 " Reset update time if this is the last terminal
2164 if s:term_count <= 1
2165 if s:reset_updatetime
2166 sil exe 'set updatetime=' . s:save_updatetime
2167 endif
2168 let s:term_count = 0
2169 else
2170 let s:term_count = s:term_count - 1
2171 endif
2172
2173 " call user defined functions
2174 call conque_term#call_hooks('after_close', self)
2175
2176 if last_buf != self.buffer_number
2177 sil exe 'noautocmd buffer ' . last_buf
2178 endif
2179
2180endfunction " }}}
2181
2182" create a new terminal object
2183function! conque_term#create_terminal_object(...) " {{{
2184
2185 " find conque buffer to update
2186 let buf_num = get(a:000, 0, 0)
2187 if buf_num > 0
2188 let pvar = 'ConqueTerm_' . buf_num
2189 elseif exists('b:ConqueTerm_Var')
2190 let pvar = b:ConqueTerm_Var
2191 let buf_num = b:ConqueTerm_Idx
2192 else
2193 let pvar = g:ConqueTerm_Var
2194 let buf_num = g:ConqueTerm_Idx
2195 endif
2196
2197 " is ther a buffer?
2198 let is_buffer = get(a:000, 1, 1)
2199
2200 " the buffer name
2201 let bname = get(a:000, 2, '')
2202
2203 " the command
2204 let command = get(a:000, 3, '')
2205
2206 " parse out the program name (not perfect)
2207 let arg_split = split(command, '[^\\]\@<=\s')
2208 let arg_split[0] = substitute(arg_split[0], '\\ ', ' ', 'g')
2209 let slash_split = split(arg_split[0], '[/\\]')
2210 let prg_name = substitute(slash_split[-1], '\(.*\)\..*', '\1', '')
2211
2212 let l:t_obj = copy(s:term_obj)
2213 let l:t_obj.is_buffer = is_buffer
2214 let l:t_obj.idx = buf_num
2215 let l:t_obj.buffer_name = bname
2216 let l:t_obj.buffer_number = bufnr("%")
2217 let l:t_obj.var = pvar
2218 let l:t_obj.command = command
2219 let l:t_obj.program_name = prg_name
2220
2221 return l:t_obj
2222
2223endfunction " }}}
2224
2225" get an existing terminal instance
2226function! conque_term#get_instance(...) " {{{
2227
2228 " find conque buffer to update
2229 let buf_num = get(a:000, 0, 0)
2230
2231 if exists('g:ConqueTerm_Terminals[buf_num]')
2232
2233 elseif exists('b:ConqueTerm_Var')
2234 let buf_num = b:ConqueTerm_Idx
2235 else
2236 let buf_num = g:ConqueTerm_Idx
2237 endif
2238
2239 return g:ConqueTerm_Terminals[buf_num]
2240
2241endfunction " }}}
2242
2243" Get python version
2244function! conque_term#get_py() " {{{
2245 return s:py
2246endfunction " }}}
2247
2248" }}}
2249
2250" **********************************************************************************************************
2251" **** PYTHON **********************************************************************************************
2252" **********************************************************************************************************
2253
2254function! conque_term#load_python() " {{{
2255
2256 sil exec s:py . "file " . s:scriptdirpy . "conque_globals.py"
2257 sil exec s:py . "file " . s:scriptdirpy . "conque.py"
2258 if s:platform == 'windows'
2259 sil exec s:py . "file " . s:scriptdirpy . "conque_win32_util.py"
2260 sil exec s:py . "file " . s:scriptdirpy . "conque_sole_shared_memory.py"
2261 sil exec s:py . "file " . s:scriptdirpy . "conque_sole.py"
2262 sil exec s:py . "file " . s:scriptdirpy . "conque_sole_wrapper.py"
2263 else
2264 sil exec s:py . "file " . s:scriptdirpy . "conque_screen.py"
2265 sil exec s:py . "file " . s:scriptdirpy . "conque_subprocess.py"
2266 endif
2267
2268endfunction " }}}
2269
2270" vim:foldmethod=marker
2271autoload/conque_gdb/conque_gdb.py [[[1
2272294
2273import re, collections
2274
2275# Marks that a breakpoint has been hit
2276GDB_BREAK_MARK = '\x1a\x1a'
2277
2278# Marks that a program opened by gdb has terminated
2279GDB_EXIT_MARK = '\x1a\x19'
2280
2281# Marks a prompt has started and stopped
2282GDB_PROMPT_MARK = '\x1a\x18'
2283
2284GDB_BREAK_REGEX = re.compile('.*' + GDB_BREAK_MARK + '.*')
2285
2286GDB_EXIT_REGEX = re.compile('.*' + GDB_EXIT_MARK + '.*')
2287
2288GDB_PROMPT_REGEX = re.compile('.*' + GDB_PROMPT_MARK + '.*')
2289
2290GET_BPS_REGEX = re.compile('(bkpt\s*?\=\s*?\{.*?(?:["].*?["])+?\s*?\]?\s*?\}(?!\s*?,\s*?\{).*?)', re.I)
2291
2292GET_ATTR_STR = '\s*?\=\s*?["](.*?)["].*?'
2293
2294ATTR_LINE_REGEX = re.compile('(line' + GET_ATTR_STR + ')', re.I)
2295ATTR_FILE_REGEX = re.compile('(fullname' + GET_ATTR_STR + ')', re.I)
2296ATTR_NUM_REGEX = re.compile('(number' + GET_ATTR_STR + ')', re.I)
2297ATTR_ENABLE_REGEX = re.compile('(enabled' + GET_ATTR_STR + ')', re.I)
2298ATTR_TYPE_REGEX = re.compile('(type' + GET_ATTR_STR + ')', re.I)
2299
2300IS_BREAKPOINT_REGEX = re.compile('.*breakpoint.*', re.I)
2301
2302class RegisteredBreakpoint:
2303 def __init__(self, fname, line, enable):
2304 self.filename = fname
2305 self.lineno = line
2306 self.enabled = enable
2307
2308 def __str__(self):
2309 return self.filename + ':' + self.lineno + ',' + self.enabled
2310
2311class RegisteredBpDict(collections.MutableMapping):
2312 def __init__(self):
2313 self.r_breaks = dict()
2314 self.lookups = dict()
2315
2316 def lookup(self, filename, line):
2317 if filename in self.lookups:
2318 if line in self.lookups[filename]:
2319 return self.lookups[filename][line]
2320 return []
2321
2322 def get_lookups(self):
2323 return self.lookups
2324
2325 def get_equal_breakpoints(self, bp):
2326 return self.lookups[bp.filename][bp.lineno]
2327
2328 def get_file_breakpoints(self, filename):
2329 if filename in self.lookups:
2330 return self.lookups[filename]
2331 return dict()
2332
2333 def __getitem__(self, key):
2334 return self.r_breaks[self.__keytransform__(key)]
2335
2336 def __setitem__(self, key, r_bp):
2337 if r_bp.filename in self.lookups:
2338 if r_bp.lineno in self.lookups[r_bp.filename]:
2339 self.lookups[r_bp.filename][r_bp.lineno].append(r_bp)
2340 else:
2341 self.lookups[r_bp.filename][r_bp.lineno] = [r_bp]
2342 else:
2343 self.lookups[r_bp.filename] = {r_bp.lineno : [r_bp]}
2344 self.r_breaks[self.__keytransform__(key)] = r_bp
2345
2346 def __delitem__(self, key):
2347 del self.r_breaks[self.__keytransform__(key)]
2348
2349 def __iter__(self):
2350 return iter(self.r_breaks)
2351
2352 def __len__(self):
2353 return len(self.r_breaks)
2354
2355 def __keytransform__(self, key):
2356 return key
2357
2358class ConqueGdb(Conque):
2359 """
2360 Unix specific implementation of the Conque class needed by the Conque GDB terminal.
2361 """
2362 # File name and linenumber of next break point
2363 breakpoint = None
2364
2365 # Indicates whether a program opened by gdb has terminated
2366 inferior_exit = False
2367
2368 # Internal string before the gdb prompt
2369 prompt = None
2370
2371 # True if we are adding to the prompt string
2372 is_prompt = False
2373
2374 # Breakpoints which have been registered to exist
2375 registered_breakpoints = RegisteredBpDict()
2376
2377 # Mapping from linenumber + filename to a tuple containing the id of the sign
2378 # placed there and whether the breakpoint is enabled ('y') or disabled ('n')
2379 lookup_sign_ids = dict()
2380
2381 # Id number of the next sign to place. Start from 15607 FTW!
2382 next_sign_id = 15607
2383
2384 def plain_text(self, input):
2385 """
2386 Append plain text to a gdb break point or the vim buffer.
2387 """
2388 if self.breakpoint != None:
2389 self.append_breakpoint(input)
2390 elif GDB_BREAK_REGEX.match(input):
2391 self.begin_breakpoint()
2392 self.plain_text(input.split(GDB_BREAK_MARK, 1)[1])
2393 elif GDB_EXIT_REGEX.match(input):
2394 self.handle_inferior_exit()
2395 self.plain_text(input.split(GDB_EXIT_MARK, 1)[1])
2396 elif GDB_PROMPT_REGEX.match(input):
2397 sp = input.split(GDB_PROMPT_MARK)
2398 if sp[0] != '':
2399 self.plain_text(sp[0])
2400 self.ctl_nl()
2401 self.toggle_prompt()
2402 self.plain_text(sp[1])
2403 elif self.prompt != None:
2404 self.append_prompt(input)
2405 else:
2406 super(ConqueGdb, self).plain_text(input)
2407
2408 def ctl_nl(self):
2409 """
2410 Append new line to vim buffer or finalize a break point.
2411 """
2412 if self.breakpoint != None:
2413 self.finalize_breakpoint()
2414 elif self.is_prompt:
2415 self.is_prompt = False
2416 elif self.inferior_exit:
2417 self.finalize_inferior_exit()
2418 else:
2419 super(ConqueGdb, self).ctl_nl()
2420
2421 def toggle_prompt(self):
2422 self.is_prompt = True
2423 if (self.prompt == None):
2424 self.prompt = ''
2425 else:
2426 self.finalize_prompt()
2427 self.prompt = None
2428
2429 def append_prompt(self, string):
2430 self.is_prompt = True
2431 self.prompt += string
2432
2433 def bp_to_look_key(self, bp):
2434 return bp.filename + "\n" + bp.lineno
2435
2436 def look_key_split(self, look_key):
2437 return look_key.split("\n")
2438
2439 def look_key_filename(self, look_key):
2440 return look_key.split("\n")[0]
2441
2442 def get_bp_attribute(self, bp, regex):
2443 return regex.findall(bp)[0][1].strip()
2444
2445 def convert_to_vim_file(self, filename):
2446 return filename.replace("'", "\n").replace("\\\\", "\\")
2447
2448 def place_sign(self, breakpoints, line):
2449 enabled = 'n'
2450 for bp in breakpoints:
2451 if bp.enabled == 'y':
2452 enabled = 'y'
2453 break
2454
2455 old = self.lookup_sign_ids.get(line)
2456 if old:
2457 vim.command("call conque_gdb#remove_breakpoint_sign('%d','%s')" % (old[0], self.convert_to_vim_file(bp.filename)))
2458 self.lookup_sign_ids[line] = (self.next_sign_id, enabled)
2459 bp = breakpoints[0]
2460 vim.command("call conque_gdb#set_breakpoint_sign('%d','%s','%s','%s')" % (self.next_sign_id, self.convert_to_vim_file(bp.filename), bp.lineno, enabled))
2461 self.next_sign_id += 1
2462
2463 def remove_sign(self, id, line):
2464 fname = self.look_key_filename(line)
2465 vim.command("call conque_gdb#remove_breakpoint_sign('%d','%s')" % (id, self.convert_to_vim_file(fname)))
2466
2467 def unplace_sign(self, line):
2468 id = self.lookup_sign_ids[line][0]
2469 self.remove_sign(id, line)
2470 del self.lookup_sign_ids[line]
2471
2472 def reset_registered_breakpoints(self):
2473 new_breakpoints = RegisteredBpDict()
2474 changed_lines = set()
2475
2476 bps = GET_BPS_REGEX.findall(self.prompt.replace('\\"', '\\x1a'))
2477 for bp in bps:
2478 try:
2479 num = self.get_bp_attribute(bp, ATTR_NUM_REGEX)
2480 enable = self.get_bp_attribute(bp, ATTR_ENABLE_REGEX)
2481 if num in self.registered_breakpoints.keys():
2482 if enable == self.registered_breakpoints[num].enabled:
2483 new_breakpoints[num] = self.registered_breakpoints[num]
2484 del self.registered_breakpoints[num]
2485 else:
2486 breakpoint = self.registered_breakpoints[num]
2487 del self.registered_breakpoints[num]
2488 breakpoint.enabled = enable
2489 new_breakpoints[num] = breakpoint
2490 changed_lines.add(self.bp_to_look_key(breakpoint))
2491 else:
2492 type = self.get_bp_attribute(bp, ATTR_TYPE_REGEX)
2493 if not IS_BREAKPOINT_REGEX.match(type):
2494 continue
2495 fname = self.get_bp_attribute(bp, ATTR_FILE_REGEX).replace('\\x1a', '"')
2496 line = self.get_bp_attribute(bp, ATTR_LINE_REGEX)
2497 breakpoint = RegisteredBreakpoint(fname, line, enable)
2498 new_breakpoints[num] = breakpoint
2499 changed_lines.add(self.bp_to_look_key(breakpoint))
2500 except:
2501 pass
2502 for breakpoint in self.registered_breakpoints.values():
2503 changed_lines.add(self.bp_to_look_key(breakpoint))
2504
2505 self.registered_breakpoints = new_breakpoints
2506 return changed_lines
2507
2508 def apply_breakpoint_changes(self, changed_lines):
2509 for line in changed_lines:
2510 (fname, lineno) = self.look_key_split(line)
2511 equal_bps = self.registered_breakpoints.lookup(fname, lineno)
2512 if len(equal_bps) == 0:
2513 self.unplace_sign(line)
2514 elif line in self.lookup_sign_ids:
2515 (old_id, old_enabled) = self.lookup_sign_ids[line]
2516 self.place_sign(equal_bps, line)
2517 self.remove_sign(old_id, line)
2518 else:
2519 self.place_sign(equal_bps, line)
2520
2521 def finalize_prompt(self):
2522 changed_lines = self.reset_registered_breakpoints()
2523 self.apply_breakpoint_changes(changed_lines)
2524
2525 def place_file_breakpoints(self, filename):
2526 files_dict = self.registered_breakpoints.get_lookups()
2527 bp_dict = self.registered_breakpoints.get_file_breakpoints(filename)
2528 for bps in bp_dict.values():
2529 self.place_sign(bps, self.bp_to_look_key(bps[0]))
2530
2531 def remove_all_signs(self):
2532 files_dict = self.registered_breakpoints.get_lookups()
2533 for bp_dict in files_dict.values():
2534 for bps in bp_dict.values():
2535 self.unplace_sign(self.bp_to_look_key(bps[0]))
2536
2537 def vim_toggle_breakpoint(self, filename, line):
2538 bps = self.registered_breakpoints.lookup(filename, line)
2539 if len(bps) == 0:
2540 vim.command('let l:command = "break "')
2541
2542 def begin_breakpoint(self):
2543 self.breakpoint = ''
2544
2545 def append_breakpoint(self, string):
2546 self.breakpoint += string
2547
2548 def handle_inferior_exit(self):
2549 """
2550 Handle termination of process running in gdb.
2551 """
2552 self.inferior_exit = True
2553 # Remove break point sign pointer from vim (if any)
2554 vim.command('call conque_gdb#remove_prev_pointer()')
2555
2556 def finalize_breakpoint(self):
2557 """
2558 Extract file name and line number from a gdb break point.
2559 And send it to the conque gdb vim script.
2560 """
2561 sp = self.breakpoint.rsplit(':', 4)
2562 self.breakpoint = None
2563 vim.command("call conque_gdb#breakpoint('%s','%s')" % (self.convert_to_vim_file(sp[0]), sp[1]))
2564
2565 def finalize_inferior_exit(self):
2566 self.inferior_exit = False
2567autoload/conque_gdb/conque_gdb_gdb.py [[[1
256817
2569import gdb, os, signal
2570
2571def exit_handler(event):
2572 """
2573 Print '\x1a\x19' to gdb buffer to indicate a process has terminated.
2574 """
2575 print('\x1a\x19')
2576
2577def prompt_hook(prompt):
2578 print('\x1a\x18')
2579 gdb.execute('interp mi "-break-list"')
2580 print('\x1a\x18')
2581
2582gdb.events.exited.connect(exit_handler)
2583gdb.prompt_hook = prompt_hook
2584
2585gdb.execute('source ' + os.path.dirname(os.path.abspath(__file__)) + '/conque_gdb.gdb', False, True)
2586autoload/conque_gdb/conque_sole_gdb.py [[[1
258782
2588import re
2589import os
2590
2591# Marks that a breakpoint has been hit
2592GDB_BREAK_MARK_SOLE = 0x2192
2593
2594# Marks end of breakpoint output from gdb
2595GDB_BREAK_END_REGEX = re.compile('^\(gdb\)\s*')
2596
2597class ConqueSoleGdb(ConqueSole):
2598 """
2599 Windows specific implementation of the ConqueSole class needed by the Conque GDB terminal.
2600 """
2601
2602 # File name and line number of next break point
2603 breakpoint = None
2604
2605 # Indicates whether a breakpoint is currently being constructed
2606 is_building_bp = False
2607
2608 # Specifies whether we have lost a break point, and we must wait for it to appear again
2609 # -1 if we are not waiting, otherwise contains the line number of the break point we wait for
2610 waiting_for_bp = -1
2611
2612 # Line number of the most recent breakpoint hit
2613 last_bp_line = -1
2614
2615 # Line number of the current breakpoint being processed
2616 curr_bp_line = -1
2617
2618 def is_breakpoint(self, text):
2619 return ord(text[0]) == GDB_BREAK_MARK_SOLE and ord(text[1]) == GDB_BREAK_MARK_SOLE
2620
2621 def append_breakpoint(self, text):
2622 """
2623 Append text to the break point being created currently or finalize the breakpoint
2624 """
2625
2626 if GDB_BREAK_END_REGEX.match(text):
2627 self.finalize_breakpoint()
2628 else:
2629 self.breakpoint += text
2630 text = ' ' * len(text)
2631 return text
2632
2633 def start_breakpoint(self, text, line):
2634 """
2635 Indicate a new breakpoint is being processed
2636 """
2637
2638 self.is_building_bp = True
2639 self.curr_bp_line = line
2640 self.breakpoint = text[2:]
2641 return ' ' * len(text)
2642
2643 def finalize_breakpoint(self):
2644 """
2645 Extract file name and line number from a gdb break point.
2646 And send it to the conque gdb vim script.
2647 """
2648
2649 self.is_building_bp = False
2650 if (self.curr_bp_line > self.last_bp_line and not self.waiting_for_bp != -1) or \
2651 self.curr_bp_line == self.waiting_for_bp:
2652 self.last_bp_line = self.curr_bp_line
2653 self.waiting_for_bp = -1
2654 sp = self.breakpoint.rsplit(':', 4)
2655 if os.path.isfile(sp[0]):
2656 vim.command("call conque_gdb#breakpoint('%s','%s')" % (sp[0], sp[1]))
2657 else:
2658 self.waiting_for_bp = self.curr_bp_line
2659
2660 def plain_text(self, line_nr, text, attributes, stats):
2661 """
2662 Append plain text to a gdb break point or the vim buffer.
2663 """
2664
2665 if self.is_breakpoint(text):
2666 text = self.start_breakpoint(text, line_nr)
2667 elif self.is_building_bp:
2668 text = self.append_breakpoint(text)
2669 super(ConqueSoleGdb, self).plain_text(line_nr, text, attributes, stats)
2670autoload/conque_gdb/gdbinit_confirm.gdb [[[1
267124
2672set confirm off
2673
2674set prompt (gdb)
2675define set prompt
2676 echo set prompt is not supported by ConqueGdb\n
2677end
2678
2679define set annotate
2680 echo set annotate is not supported by ConqueGdb\n
2681end
2682
2683define layout
2684 echo layout command is not supported by ConqueGdb\n
2685end
2686
2687define tui
2688 echo tui command is not supported by ConqueGdb\n
2689end
2690
2691define refresh
2692 echo refresh command is not supported by ConqueGdb\n
2693end
2694
2695set confirm on
2696autoload/conque_gdb/gdbinit_no_confirm.gdb [[[1
269720
2698set prompt (gdb)
2699define set prompt
2700 echo set prompt is not supported by ConqueGdb\n
2701end
2702
2703define set annotate
2704 echo set annotate is not supported by ConqueGdb\n
2705end
2706
2707define layout
2708 echo layout command is not supported by ConqueGdb\n
2709end
2710
2711define tui
2712 echo tui command is not supported by ConqueGdb\n
2713end
2714
2715define refresh
2716 echo refresh command is not supported by ConqueGdb\n
2717end
2718autoload/conque_gdb/conque_gdb.gdb [[[1
271912
2720
2721define set annotate
2722 echo set annotate is not supported by ConqueGdb\n
2723end
2724
2725define layout
2726 echo layout command is not supported by ConqueGdb\n
2727end
2728
2729define tui
2730 echo tui command is not supported by ConqueGdb\n
2731end
2732autoload/conque_term/conque.py [[[1
27331176
2734# FILE: autoload/conque_term/conque.py
2735# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
2736# WEBSITE: http://conque.googlecode.com
2737# MODIFIED: 2011-09-12
2738# VERSION: 2.3, for Vim 7.0
2739# LICENSE:
2740# Conque - Vim terminal/console emulator
2741# Copyright (C) 2009-2011 Nico Raffo
2742#
2743# MIT License
2744#
2745# Permission is hereby granted, free of charge, to any person obtaining a copy
2746# of this software and associated documentation files (the "Software"), to deal
2747# in the Software without restriction, including without limitation the rights
2748# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
2749# copies of the Software, and to permit persons to whom the Software is
2750# furnished to do so, subject to the following conditions:
2751#
2752# The above copyright notice and this permission notice shall be included in
2753# all copies or substantial portions of the Software.
2754#
2755# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
2756# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
2757# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
2758# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
2759# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
2760# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
2761# THE SOFTWARE.
2762
2763"""
2764Vim terminal emulator.
2765
2766This class is the main interface between Vim and the terminal application. It
2767handles both updating the Vim buffer with new output and accepting new keyboard
2768input from the Vim user.
2769
2770Although this class was originally designed for a Unix terminal environment, it
2771has been extended by the ConqueSole class for Windows.
2772
2773Usage:
2774 term = Conque()
2775 term.open('/bin/bash', {'TERM': 'vt100'})
2776 term.write("ls -lha\r")
2777 term.read()
2778 term.close()
2779"""
2780
2781import vim
2782import re
2783import math
2784import time
2785
2786
2787class Conque(object):
2788
2789 # screen object
2790 screen = None
2791
2792 # subprocess object
2793 proc = None
2794
2795 # terminal dimensions and scrolling region
2796 columns = 80 # same as $COLUMNS
2797 lines = 24 # same as $LINES
2798 working_columns = 80 # can be changed by CSI ? 3 l/h
2799 working_lines = 24 # can be changed by CSI r
2800
2801 # top/bottom of the scroll region
2802 top = 1 # relative to top of screen
2803 bottom = 24 # relative to top of screen
2804
2805 # cursor position
2806 l = 1 # current cursor line
2807 c = 1 # current cursor column
2808
2809 # autowrap mode
2810 autowrap = True
2811
2812 # absolute coordinate mode
2813 absolute_coords = True
2814
2815 # tabstop positions
2816 tabstops = []
2817
2818 # enable colors
2819 enable_colors = True
2820
2821 # color changes
2822 color_changes = {}
2823
2824 # color history
2825 color_history = {}
2826
2827 # color highlight cache
2828 highlight_groups = {}
2829
2830 # prune terminal colors
2831 color_pruning = True
2832
2833 # don't wrap table output
2834 unwrap_tables = True
2835
2836 # wrap CUF/CUB around line breaks
2837 wrap_cursor = False
2838
2839 # do we need to move the cursor?
2840 cursor_set = False
2841
2842 # current character set, ascii or graphics
2843 character_set = 'ascii'
2844
2845 # used for auto_read actions
2846 read_count = 0
2847
2848 # input buffer, array of ordinals
2849 input_buffer = []
2850
2851 def open(self):
2852 """ Start program and initialize this instance.
2853
2854 Arguments:
2855 command -- Command string to execute, e.g. '/bin/bash --login'
2856 options -- Dictionary of environment vars to set and other options.
2857
2858 """
2859 # get arguments
2860 command = vim.eval('command')
2861 options = vim.eval('options')
2862
2863 # create terminal screen instance
2864 self.screen = ConqueScreen()
2865
2866 # int vars
2867 self.columns = vim.current.window.width
2868 self.lines = vim.current.window.height
2869 self.working_columns = vim.current.window.width
2870 self.working_lines = vim.current.window.height
2871 self.bottom = vim.current.window.height
2872
2873 # offset first line to make room for startup messages
2874 if int(options['offset']) > 0:
2875 self.l = int(options['offset'])
2876
2877 # init color
2878 self.enable_colors = int(options['color']) and not CONQUE_FAST_MODE
2879
2880 # init tabstops
2881 self.init_tabstops()
2882
2883 # open command
2884 self.proc = ConqueSubprocess()
2885 self.proc.open(command, {'TERM': options['TERM'], 'CONQUE': '1', 'LINES': str(self.lines), 'COLUMNS': str(self.columns)})
2886
2887 # send window size signal, in case LINES/COLUMNS is ignored
2888 self.update_window_size(True)
2889
2890
2891 def write(self, input, set_cursor=True, read=True):
2892 """ Write a unicode string to the subprocess.
2893
2894 set_cursor -- Position the cursor in the current buffer when finished
2895 read -- Check program for new output when finished
2896
2897 """
2898 # check if window size has changed
2899 if not CONQUE_FAST_MODE:
2900 self.update_window_size()
2901
2902 # write and read
2903 self.proc.write(input)
2904
2905 # read output immediately
2906 if read:
2907 self.read(1, set_cursor)
2908
2909
2910
2911 def write_ord(self, input, set_cursor=True, read=True):
2912 """ Write a single character to the subprocess, using an unicode ordinal. """
2913
2914 if CONQUE_PYTHON_VERSION == 2:
2915 self.write(unichr(input), set_cursor, read)
2916 else:
2917 self.write(chr(input), set_cursor, read)
2918
2919
2920
2921 def write_expr(self, expr, set_cursor=True, read=True):
2922 """ Write the value of a Vim expression to the subprocess. """
2923
2924 if CONQUE_PYTHON_VERSION == 2:
2925 try:
2926 val = vim.eval(expr)
2927 self.write(unicode(val, CONQUE_VIM_ENCODING, 'ignore'), set_cursor, read)
2928 except:
2929
2930 pass
2931 else:
2932 try:
2933 # XXX - Depending on Vim to deal with encoding, sadly
2934 self.write(vim.eval(expr), set_cursor, read)
2935 except:
2936
2937 pass
2938
2939
2940 def write_latin1(self, input, set_cursor=True, read=True):
2941 """ Write latin-1 string to conque. Very ugly, shood be removed. """
2942 # XXX - this whole method is a hack, to be removed soon
2943
2944 if CONQUE_PYTHON_VERSION == 2:
2945 try:
2946 input_unicode = input.decode('latin-1', 'ignore')
2947 self.write(input_unicode.encode('utf-8', 'ignore'), set_cursor, read)
2948 except:
2949 return
2950 else:
2951 self.write(input, set_cursor, read)
2952
2953
2954 def write_buffered_ord(self, chr):
2955 """ Add character ordinal to input buffer. In case we're not allowed to modify buffer a time of input. """
2956 self.input_buffer.append(chr)
2957
2958
2959 def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True):
2960 """ Read new output from the subprocess and update the Vim buffer.
2961
2962 Arguments:
2963 timeout -- Milliseconds to wait before reading input
2964 set_cursor -- Set the cursor position in the current buffer when finished
2965 return_output -- Return new subprocess STDOUT + STDERR as a string
2966 update_buffer -- Update the current Vim buffer with the new output
2967
2968 This method goes through the following rough steps:
2969 1. Get new output from subprocess
2970 2. Split output string into control codes, escape sequences, or plain text
2971 3. Loop over and process each chunk, updating the Vim buffer as we go
2972
2973 """
2974 output = ''
2975
2976 # this may not actually work
2977 try:
2978
2979 # read from subprocess and strip null characters
2980 output = self.proc.read(timeout)
2981
2982 if output == '':
2983 return output
2984
2985 # for bufferless terminals
2986 if not update_buffer:
2987 return output
2988
2989
2990
2991 # strip null characters. I'm still not sure why they appear
2992 output = output.replace(chr(0), '')
2993
2994 # split input into individual escape sequences, control codes, and text output
2995 chunks = CONQUE_SEQ_REGEX.split(output)
2996
2997
2998
2999 # if there were no escape sequences, skip processing and treat entire string as plain text
3000 if len(chunks) == 1:
3001 self.plain_text(chunks[0])
3002
3003 # loop through and process escape sequences
3004 else:
3005 for s in chunks:
3006 if s == '':
3007 continue
3008
3009
3010
3011
3012 # Check for control character match
3013 if CONQUE_SEQ_REGEX_CTL.match(s[0]):
3014
3015 nr = ord(s[0])
3016 if nr in CONQUE_CTL:
3017 getattr(self, 'ctl_' + CONQUE_CTL[nr])()
3018 else:
3019
3020 pass
3021
3022 # check for escape sequence match
3023 elif CONQUE_SEQ_REGEX_CSI.match(s):
3024
3025 if s[-1] in CONQUE_ESCAPE:
3026 csi = self.parse_csi(s[2:])
3027
3028 getattr(self, 'csi_' + CONQUE_ESCAPE[s[-1]])(csi)
3029 else:
3030
3031 pass
3032
3033 # check for title match
3034 elif CONQUE_SEQ_REGEX_TITLE.match(s):
3035
3036 self.change_title(s[2], s[4:-1])
3037
3038 # check for hash match
3039 elif CONQUE_SEQ_REGEX_HASH.match(s):
3040
3041 if s[-1] in CONQUE_ESCAPE_HASH:
3042 getattr(self, 'hash_' + CONQUE_ESCAPE_HASH[s[-1]])()
3043 else:
3044
3045 pass
3046
3047 # check for charset match
3048 elif CONQUE_SEQ_REGEX_CHAR.match(s):
3049
3050 if s[-1] in CONQUE_ESCAPE_CHARSET:
3051 getattr(self, 'charset_' + CONQUE_ESCAPE_CHARSET[s[-1]])()
3052 else:
3053
3054 pass
3055
3056 # check for other escape match
3057 elif CONQUE_SEQ_REGEX_ESC.match(s):
3058
3059 if s[-1] in CONQUE_ESCAPE_PLAIN:
3060 getattr(self, 'esc_' + CONQUE_ESCAPE_PLAIN[s[-1]])()
3061 else:
3062
3063 pass
3064
3065 # else process plain text
3066 else:
3067 self.plain_text(s)
3068
3069 # set cusor position
3070 if set_cursor:
3071 self.screen.set_cursor(self.l, self.c)
3072
3073 # we need to set the cursor position
3074 self.cursor_set = False
3075
3076 except:
3077
3078
3079 pass
3080
3081 if return_output:
3082 if CONQUE_PYTHON_VERSION == 3:
3083 return output
3084 else:
3085 return output.encode(CONQUE_VIM_ENCODING, 'replace')
3086
3087
3088 def auto_read(self, reset_timer = True):
3089 """ Poll program for more output.
3090
3091 Since Vim doesn't have a reliable event system that can be triggered when new
3092 output is available, we have to continually poll the subprocess instead. This
3093 method is called many times a second when the terminal buffer is active, so it
3094 needs to be very fast and efficient.
3095
3096 The feedkeys portion is required to reset Vim's timer system. The timer is used
3097 to execute this command, typically set to go off after 50 ms of inactivity.
3098
3099 """
3100
3101 # process buffered input if any
3102 if len(self.input_buffer):
3103 for chr in self.input_buffer:
3104 self.write_ord(chr, set_cursor=False, read=False)
3105 self.input_buffer = []
3106 self.read(1)
3107
3108 if not self.proc.is_alive():
3109 vim.command('call conque_term#get_instance().close()')
3110 return
3111
3112 # check subprocess status, but not every time since it's CPU expensive
3113 if self.read_count % 32 == 0:
3114 if self.read_count > 512:
3115 self.read_count = 0
3116
3117 # trim color history occasionally if desired
3118 if self.enable_colors and self.color_pruning:
3119 self.prune_colors()
3120
3121 # ++
3122 self.read_count += 1
3123
3124 # read output
3125 self.read(1)
3126
3127 if reset_timer:
3128 try:
3129 # reset timer
3130 if self.c == vim.eval('col("$")'):
3131 vim.command('call feedkeys("\<Right>", "n")')
3132 else:
3133 vim.command('call feedkeys("\<Right>\<Left>", "n")')
3134 except:
3135 pass
3136
3137 # stop here if cursor doesn't need to be moved
3138 if self.cursor_set:
3139 return
3140
3141 # otherwise set cursor position
3142 try:
3143 self.set_cursor(self.l, self.c)
3144 except:
3145 pass
3146
3147 self.cursor_set = True
3148
3149
3150 def plain_text(self, input):
3151 """ Write text output to Vim buffer.
3152
3153
3154 This method writes a string of characters without any control characters or escape sequences
3155 to the Vim buffer. In simple terms, it writes the input string to the buffer starting at the
3156 current cursor position, wrapping the text to a new line if needed. It also triggers the
3157 terminal coloring methods if needed.
3158
3159
3160 """
3161 # translate input into graphics character set if needed
3162 if self.character_set == 'graphics':
3163 old_input = input
3164 input = u('')
3165 for i in range(0, len(old_input)):
3166 chrd = ord(old_input[i])
3167
3168
3169 try:
3170 if chrd > 255:
3171
3172 input = input + old_input[i]
3173 else:
3174 input = input + uchr(CONQUE_GRAPHICS_SET[chrd])
3175 except:
3176
3177 pass
3178
3179
3180
3181 # get current line from Vim buffer
3182 current_line = self.screen[self.l]
3183
3184 # pad current line with spaces, if it's shorter than cursor position
3185 if len(current_line) < self.c:
3186 current_line = current_line + ' ' * (self.c - len(current_line))
3187
3188 # if line is wider than screen
3189 if self.c + len(input) - 1 > self.working_columns:
3190
3191 # Table formatting hack
3192 if self.unwrap_tables and CONQUE_TABLE_OUTPUT.match(input):
3193 self.screen[self.l] = current_line[:self.c - 1] + input + current_line[self.c + len(input) - 1:]
3194 self.apply_color(self.c, self.c + len(input))
3195 self.c += len(input)
3196 return
3197
3198
3199 diff = self.c + len(input) - self.working_columns - 1
3200
3201 # if autowrap is enabled
3202 if self.autowrap:
3203 self.screen[self.l] = current_line[:self.c - 1] + input[:-1 * diff]
3204 self.apply_color(self.c, self.working_columns)
3205 self.ctl_nl()
3206 self.ctl_cr()
3207 remaining = input[-1 * diff:]
3208
3209 self.plain_text(remaining)
3210 else:
3211 self.screen[self.l] = current_line[:self.c - 1] + input[:-1 * diff - 1] + input[-1]
3212 self.apply_color(self.c, self.working_columns)
3213 self.c = self.working_columns
3214
3215 # no autowrap
3216 else:
3217 self.screen[self.l] = current_line[:self.c - 1] + input + current_line[self.c + len(input) - 1:]
3218 self.apply_color(self.c, self.c + len(input))
3219 self.c += len(input)
3220
3221
3222
3223 def apply_color(self, start, end, line=0):
3224 """ Apply terminal colors to buffer for a range of characters in a single line.
3225
3226 When a text attribute escape sequence is encountered during input processing, the
3227 attributes are recorded in the dictionary self.color_changes. After those attributes
3228 have been applied, the changes are recorded in a second dictionary self.color_history.
3229
3230
3231 This method inspects both dictionaries to calculate any syntax highlighting
3232 that needs to be executed to render the text attributes in the Vim buffer.
3233
3234
3235 """
3236
3237
3238 # stop here if coloration is disabled
3239 if not self.enable_colors:
3240 return
3241
3242 # allow custom line nr to be passed
3243 if line:
3244 buffer_line = line
3245 else:
3246 buffer_line = self.get_buffer_line(self.l)
3247
3248 # check for previous overlapping coloration
3249
3250 to_del = []
3251 if buffer_line in self.color_history:
3252 for i in range(len(self.color_history[buffer_line])):
3253 syn = self.color_history[buffer_line][i]
3254
3255 if syn['start'] >= start and syn['start'] < end:
3256
3257 vim.command('syn clear ' + syn['name'])
3258 to_del.append(i)
3259 # outside
3260 if syn['end'] > end:
3261
3262 self.exec_highlight(buffer_line, end, syn['end'], syn['highlight'])
3263 elif syn['end'] > start and syn['end'] <= end:
3264
3265 vim.command('syn clear ' + syn['name'])
3266 to_del.append(i)
3267 # outside
3268 if syn['start'] < start:
3269
3270 self.exec_highlight(buffer_line, syn['start'], start, syn['highlight'])
3271
3272 # remove overlapped colors
3273 if len(to_del) > 0:
3274 to_del.reverse()
3275 for di in to_del:
3276 del self.color_history[buffer_line][di]
3277
3278 # if there are no new colors
3279 if len(self.color_changes) == 0:
3280 return
3281
3282 # build the color attribute string
3283 highlight = ''
3284 for attr in self.color_changes.keys():
3285 highlight = highlight + ' ' + attr + '=' + self.color_changes[attr]
3286
3287 # execute the highlight
3288 self.exec_highlight(buffer_line, start, end, highlight)
3289
3290
3291 def exec_highlight(self, buffer_line, start, end, highlight):
3292 """ Execute the Vim commands for a single syntax highlight """
3293
3294 syntax_name = 'ConqueHighLightAt_%d_%d_%d_%d' % (self.proc.pid, self.l, start, len(self.color_history) + 1)
3295 syntax_options = 'contains=ALLBUT,ConqueString,MySQLString,MySQLKeyword oneline'
3296 syntax_region = 'syntax match %s /\%%%dl\%%>%dc.\{%d}\%%<%dc/ %s' % (syntax_name, buffer_line, start - 1, end - start, end + 1, syntax_options)
3297
3298 # check for cached highlight group
3299 hgroup = 'ConqueHL_%d' % (abs(hash(highlight)))
3300 if hgroup not in self.highlight_groups:
3301 syntax_group = 'highlight %s %s' % (hgroup, highlight)
3302 self.highlight_groups[hgroup] = hgroup
3303 vim.command(syntax_group)
3304
3305 # link this syntax match to existing highlight group
3306 syntax_highlight = 'highlight link %s %s' % (syntax_name, self.highlight_groups[hgroup])
3307
3308
3309
3310 vim.command(syntax_region)
3311 vim.command(syntax_highlight)
3312
3313 # add syntax name to history
3314 if not buffer_line in self.color_history:
3315 self.color_history[buffer_line] = []
3316
3317 self.color_history[buffer_line].append({'name': syntax_name, 'start': start, 'end': end, 'highlight': highlight})
3318
3319
3320 def prune_colors(self):
3321 """ Remove old syntax highlighting from the Vim buffer
3322
3323 The kind of syntax highlighting required for terminal colors can make
3324 Conque run slowly. The prune_colors() method will remove old highlight definitions
3325 to keep the maximum number of highlight rules within a reasonable range.
3326
3327 """
3328
3329
3330 buffer_line = self.get_buffer_line(self.l)
3331 ks = list(self.color_history.keys())
3332
3333 for line in ks:
3334 if line < buffer_line - CONQUE_MAX_SYNTAX_LINES:
3335 for syn in self.color_history[line]:
3336 vim.command('syn clear ' + syn['name'])
3337 del self.color_history[line]
3338
3339
3340
3341
3342 ###############################################################################################
3343 # Control functions
3344
3345 def ctl_nl(self):
3346 """ Process the newline control character. """
3347 # if we're in a scrolling region, scroll instead of moving cursor down
3348 if self.lines != self.working_lines and self.l == self.bottom:
3349 del self.screen[self.top]
3350 self.screen.insert(self.bottom, '')
3351 elif self.l == self.bottom:
3352 self.screen.append('')
3353 else:
3354 self.l += 1
3355
3356 self.color_changes = {}
3357
3358 def ctl_cr(self):
3359 """ Process the carriage return control character. """
3360 self.c = 1
3361
3362 self.color_changes = {}
3363
3364 def ctl_bs(self):
3365 """ Process the backspace control character. """
3366 if self.c > 1:
3367 self.c += -1
3368
3369 def ctl_soh(self):
3370 """ Process the start of heading control character. """
3371 pass
3372
3373 def ctl_stx(self):
3374 pass
3375
3376 def ctl_bel(self):
3377 """ Process the bell control character. """
3378 vim.command('call conque_term#bell()')
3379
3380 def ctl_tab(self):
3381 """ Process the tab control character. """
3382 # default tabstop location
3383 ts = self.working_columns
3384
3385 # check set tabstops
3386 for i in range(self.c, len(self.tabstops)):
3387 if self.tabstops[i]:
3388 ts = i + 1
3389 break
3390
3391
3392
3393 self.c = ts
3394
3395 def ctl_so(self):
3396 """ Process the shift out control character. """
3397 self.character_set = 'graphics'
3398
3399 def ctl_si(self):
3400 """ Process the shift in control character. """
3401 self.character_set = 'ascii'
3402
3403
3404
3405 ###############################################################################################
3406 # CSI functions
3407
3408 def csi_font(self, csi):
3409 """ Process the text attribute escape sequence. """
3410 if not self.enable_colors:
3411 return
3412
3413 # defaults to 0
3414 if len(csi['vals']) == 0:
3415 csi['vals'] = [0]
3416
3417 # 256 xterm color foreground
3418 if len(csi['vals']) == 3 and csi['vals'][0] == 38 and csi['vals'][1] == 5:
3419 self.color_changes['ctermfg'] = str(csi['vals'][2])
3420 self.color_changes['guifg'] = '#' + self.xterm_to_rgb(csi['vals'][2])
3421
3422 # 256 xterm color background
3423 elif len(csi['vals']) == 3 and csi['vals'][0] == 48 and csi['vals'][1] == 5:
3424 self.color_changes['ctermbg'] = str(csi['vals'][2])
3425 self.color_changes['guibg'] = '#' + self.xterm_to_rgb(csi['vals'][2])
3426
3427 # 16 colors
3428 else:
3429 for val in csi['vals']:
3430 if val in CONQUE_FONT:
3431
3432 # ignore starting normal colors
3433 if CONQUE_FONT[val]['normal'] and len(self.color_changes) == 0:
3434
3435 continue
3436 # clear color changes
3437 elif CONQUE_FONT[val]['normal']:
3438
3439 self.color_changes = {}
3440 # save these color attributes for next plain_text() call
3441 else:
3442
3443 for attr in CONQUE_FONT[val]['attributes'].keys():
3444 if attr in self.color_changes and (attr == 'cterm' or attr == 'gui'):
3445 self.color_changes[attr] += ',' + CONQUE_FONT[val]['attributes'][attr]
3446 else:
3447 self.color_changes[attr] = CONQUE_FONT[val]['attributes'][attr]
3448
3449
3450 def csi_clear_line(self, csi):
3451 """ Process the line clear escape sequence. """
3452
3453
3454 # this escape defaults to 0
3455 if len(csi['vals']) == 0:
3456 csi['val'] = 0
3457
3458
3459
3460
3461 # 0 means cursor right
3462 if csi['val'] == 0:
3463 self.screen[self.l] = self.screen[self.l][0:self.c - 1]
3464
3465 # 1 means cursor left
3466 elif csi['val'] == 1:
3467 self.screen[self.l] = ' ' * (self.c) + self.screen[self.l][self.c:]
3468
3469 # clear entire line
3470 elif csi['val'] == 2:
3471 self.screen[self.l] = ''
3472
3473 # clear colors
3474 if csi['val'] == 2 or (csi['val'] == 0 and self.c == 1):
3475 buffer_line = self.get_buffer_line(self.l)
3476 if buffer_line in self.color_history:
3477 for syn in self.color_history[buffer_line]:
3478 vim.command('syn clear ' + syn['name'])
3479
3480
3481
3482
3483
3484 def csi_cursor_right(self, csi):
3485 """ Process the move cursor right escape sequence. """
3486 # we use 1 even if escape explicitly specifies 0
3487 if csi['val'] == 0:
3488 csi['val'] = 1
3489
3490
3491
3492
3493 if self.wrap_cursor and self.c + csi['val'] > self.working_columns:
3494 self.l += int(math.floor((self.c + csi['val']) / self.working_columns))
3495 self.c = (self.c + csi['val']) % self.working_columns
3496 return
3497
3498 self.c = self.bound(self.c + csi['val'], 1, self.working_columns)
3499
3500
3501 def csi_cursor_left(self, csi):
3502 """ Process the move cursor left escape sequence. """
3503 # we use 1 even if escape explicitly specifies 0
3504 if csi['val'] == 0:
3505 csi['val'] = 1
3506
3507 if self.wrap_cursor and csi['val'] >= self.c:
3508 self.l += int(math.floor((self.c - csi['val']) / self.working_columns))
3509 self.c = self.working_columns - (csi['val'] - self.c) % self.working_columns
3510 return
3511
3512 self.c = self.bound(self.c - csi['val'], 1, self.working_columns)
3513
3514
3515 def csi_cursor_to_column(self, csi):
3516 """ Process the move cursor to column escape sequence. """
3517 self.c = self.bound(csi['val'], 1, self.working_columns)
3518
3519
3520 def csi_cursor_up(self, csi):
3521 """ Process the move cursor up escape sequence. """
3522 self.l = self.bound(self.l - csi['val'], self.top, self.bottom)
3523
3524 self.color_changes = {}
3525
3526
3527 def csi_cursor_down(self, csi):
3528 """ Process the move cursor down escape sequence. """
3529 self.l = self.bound(self.l + csi['val'], self.top, self.bottom)
3530
3531 self.color_changes = {}
3532
3533
3534 def csi_clear_screen(self, csi):
3535 """ Process the clear screen escape sequence. """
3536 # default to 0
3537 if len(csi['vals']) == 0:
3538 csi['val'] = 0
3539
3540 # 2 == clear entire screen
3541 if csi['val'] == 2:
3542 self.l = 1
3543 self.c = 1
3544 self.screen.clear()
3545
3546 # 0 == clear down
3547 elif csi['val'] == 0:
3548 for l in range(self.bound(self.l + 1, 1, self.lines), self.lines + 1):
3549 self.screen[l] = ''
3550
3551 # clear end of current line
3552 self.csi_clear_line(self.parse_csi('K'))
3553
3554 # 1 == clear up
3555 elif csi['val'] == 1:
3556 for l in range(1, self.bound(self.l, 1, self.lines + 1)):
3557 self.screen[l] = ''
3558
3559 # clear beginning of current line
3560 self.csi_clear_line(self.parse_csi('1K'))
3561
3562 # clear coloration
3563 if csi['val'] == 2 or csi['val'] == 0:
3564 buffer_line = self.get_buffer_line(self.l)
3565 for line in self.color_history.keys():
3566 if line >= buffer_line:
3567 for syn in self.color_history[line]:
3568 vim.command('syn clear ' + syn['name'])
3569
3570 self.color_changes = {}
3571
3572
3573 def csi_delete_chars(self, csi):
3574 self.screen[self.l] = self.screen[self.l][:self.c] + self.screen[self.l][self.c + csi['val']:]
3575
3576
3577 def csi_add_spaces(self, csi):
3578 self.screen[self.l] = self.screen[self.l][: self.c - 1] + ' ' * csi['val'] + self.screen[self.l][self.c:]
3579
3580
3581 def csi_cursor(self, csi):
3582 if len(csi['vals']) == 2:
3583 new_line = csi['vals'][0]
3584 new_col = csi['vals'][1]
3585 else:
3586 new_line = 1
3587 new_col = 1
3588
3589 if self.absolute_coords:
3590 self.l = self.bound(new_line, 1, self.lines)
3591 else:
3592 self.l = self.bound(self.top + new_line - 1, self.top, self.bottom)
3593
3594 self.c = self.bound(new_col, 1, self.working_columns)
3595 if self.c > len(self.screen[self.l]):
3596 self.screen[self.l] = self.screen[self.l] + ' ' * (self.c - len(self.screen[self.l]))
3597
3598
3599
3600 def csi_set_coords(self, csi):
3601 if len(csi['vals']) == 2:
3602 new_start = csi['vals'][0]
3603 new_end = csi['vals'][1]
3604 else:
3605 new_start = 1
3606 new_end = vim.current.window.height
3607
3608 self.top = new_start
3609 self.bottom = new_end
3610 self.working_lines = new_end - new_start + 1
3611
3612 # if cursor is outside scrolling region, reset it
3613 if self.l < self.top:
3614 self.l = self.top
3615 elif self.l > self.bottom:
3616 self.l = self.bottom
3617
3618 self.color_changes = {}
3619
3620
3621 def csi_tab_clear(self, csi):
3622 # this escape defaults to 0
3623 if len(csi['vals']) == 0:
3624 csi['val'] = 0
3625
3626
3627
3628 if csi['val'] == 0:
3629 self.tabstops[self.c - 1] = False
3630 elif csi['val'] == 3:
3631 for i in range(0, self.columns + 1):
3632 self.tabstops[i] = False
3633
3634
3635 def csi_set(self, csi):
3636 # 132 cols
3637 if csi['val'] == 3:
3638 self.csi_clear_screen(self.parse_csi('2J'))
3639 self.working_columns = 132
3640
3641 # relative_origin
3642 elif csi['val'] == 6:
3643 self.absolute_coords = False
3644
3645 # set auto wrap
3646 elif csi['val'] == 7:
3647 self.autowrap = True
3648
3649
3650 self.color_changes = {}
3651
3652
3653 def csi_reset(self, csi):
3654 # 80 cols
3655 if csi['val'] == 3:
3656 self.csi_clear_screen(self.parse_csi('2J'))
3657 self.working_columns = 80
3658
3659 # absolute origin
3660 elif csi['val'] == 6:
3661 self.absolute_coords = True
3662
3663 # reset auto wrap
3664 elif csi['val'] == 7:
3665 self.autowrap = False
3666
3667
3668 self.color_changes = {}
3669
3670
3671
3672
3673 ###############################################################################################
3674 # ESC functions
3675
3676 def esc_scroll_up(self):
3677 self.ctl_nl()
3678
3679 self.color_changes = {}
3680
3681
3682 def esc_next_line(self):
3683 self.ctl_nl()
3684 self.c = 1
3685
3686
3687 def esc_set_tab(self):
3688
3689 if self.c <= len(self.tabstops):
3690 self.tabstops[self.c - 1] = True
3691
3692
3693 def esc_scroll_down(self):
3694 if self.l == self.top:
3695 del self.screen[self.bottom]
3696 self.screen.insert(self.top, '')
3697 else:
3698 self.l += -1
3699
3700 self.color_changes = {}
3701
3702
3703
3704
3705 ###############################################################################################
3706 # HASH functions
3707
3708 def hash_screen_alignment_test(self):
3709 self.csi_clear_screen(self.parse_csi('2J'))
3710 self.working_lines = self.lines
3711 for l in range(1, self.lines + 1):
3712 self.screen[l] = 'E' * self.working_columns
3713
3714
3715
3716 ###############################################################################################
3717 # CHARSET functions
3718
3719 def charset_us(self):
3720 self.character_set = 'ascii'
3721
3722 def charset_uk(self):
3723 self.character_set = 'ascii'
3724
3725 def charset_graphics(self):
3726 self.character_set = 'graphics'
3727
3728
3729
3730 ###############################################################################################
3731 # Random stuff
3732
3733 def set_cursor(self, line, col):
3734 """ Set cursor position in the Vim buffer.
3735
3736 Note: the line and column numbers are relative to the top left corner of the
3737 visible screen. Not the line number in the Vim buffer.
3738
3739 """
3740 self.screen.set_cursor(line, col)
3741
3742 def change_title(self, key, val):
3743 """ Change the Vim window title. """
3744
3745
3746 if key == '0' or key == '2':
3747
3748 vim.command('setlocal statusline=' + re.escape(val))
3749 try:
3750 vim.command('set titlestring=' + re.escape(val))
3751 except:
3752 pass
3753
3754 def update_window(self, force=False):
3755 """
3756 Update Conque buffer size attributes if needed.
3757 """
3758 if force or vim.current.window.width != self.columns or vim.current.window.height != self.lines:
3759
3760 # reset all window size attributes to default
3761 self.columns = vim.current.window.width
3762 self.lines = vim.current.window.height
3763 self.working_columns = vim.current.window.width
3764 self.working_lines = vim.current.window.height
3765 self.bottom = vim.current.window.height
3766
3767 # reset screen object attributes
3768 self.l = self.screen.reset_size(self.l)
3769
3770 # reset tabstops
3771 self.init_tabstops()
3772
3773 return True
3774
3775 return False
3776
3777 def update_window_size(self, force=False):
3778 """ Check and save the current buffer dimensions.
3779
3780 If the buffer size has changed, the update_window_size() method both updates
3781 the Conque buffer size attributes as well as sending the new dimensions to the
3782 subprocess pty.
3783
3784 """
3785 if self.update_window(force):
3786 # signal process that screen size has changed
3787 self.proc.window_resize(self.lines, self.columns)
3788
3789 def insert_enter(self):
3790 """ Run commands when user enters insert mode. """
3791
3792 # check window size
3793 self.update_window_size()
3794
3795 # we need to set the cursor position
3796 self.cursor_set = False
3797
3798 def init_tabstops(self):
3799 """ Intitialize terminal tabstop positions. """
3800 for i in range(0, self.columns + 1):
3801 if i % 8 == 0:
3802 self.tabstops.append(True)
3803 else:
3804 self.tabstops.append(False)
3805
3806 def idle(self):
3807 """ Called when this terminal becomes idle. """
3808 pass
3809
3810 def resume(self):
3811 """ Called when this terminal is no longer idle. """
3812 pass
3813 pass
3814
3815 def close(self):
3816 """ End the process running in the terminal. """
3817 self.abort()
3818
3819 def abort(self):
3820 """ Forcefully end the process running in the terminal. """
3821 self.proc.signal(1)
3822 self.poll_wait_for_proc(10);
3823
3824 def poll_wait_for_proc(self, tries):
3825 """ Try 'tries' times to see if self.proc has become a zombie
3826 such that we can reclaim its resources. Wait for 2ms before each try.
3827 """
3828 pid = self.proc.getpid()
3829 try:
3830 for i in range(tries):
3831 time.sleep(0.02)
3832 if os.waitpid(pid, os.WNOHANG)[0]:
3833 break;
3834 except:
3835 pass
3836
3837
3838
3839
3840 ###############################################################################################
3841 # Utility
3842
3843 def parse_csi(self, s):
3844 """ Parse an escape sequence into it's meaningful values. """
3845
3846 attr = {'key': s[-1], 'flag': '', 'val': 1, 'vals': []}
3847
3848 if len(s) == 1:
3849 return attr
3850
3851 full = s[0:-1]
3852
3853 if full[0] == '?':
3854 full = full[1:]
3855 attr['flag'] = '?'
3856
3857 if full != '':
3858 vals = full.split(';')
3859 for val in vals:
3860
3861 val = re.sub("\D", "", val)
3862
3863 if val != '':
3864 attr['vals'].append(int(val))
3865
3866 if len(attr['vals']) == 1:
3867 attr['val'] = int(attr['vals'][0])
3868
3869 return attr
3870
3871
3872 def bound(self, val, min, max):
3873 """ TODO: This probably exists as a builtin function. """
3874 if val > max:
3875 return max
3876
3877 if val < min:
3878 return min
3879
3880 return val
3881
3882
3883 def xterm_to_rgb(self, color_code):
3884 """ Translate a terminal color number into a RGB string. """
3885 if color_code < 16:
3886 ascii_colors = ['000000', 'CD0000', '00CD00', 'CDCD00', '0000EE', 'CD00CD', '00CDCD', 'E5E5E5',
3887 '7F7F7F', 'FF0000', '00FF00', 'FFFF00', '5C5CFF', 'FF00FF', '00FFFF', 'FFFFFF']
3888 return ascii_colors[color_code]
3889
3890 elif color_code < 232:
3891 cc = int(color_code) - 16
3892
3893 p1 = "%02x" % (math.floor(cc / 36) * (255 / 5))
3894 p2 = "%02x" % (math.floor((cc % 36) / 6) * (255 / 5))
3895 p3 = "%02x" % (math.floor(cc % 6) * (255 / 5))
3896
3897 return p1 + p2 + p3
3898 else:
3899 grey_tone = "%02x" % math.floor((255 / 24) * (color_code - 232))
3900 return grey_tone + grey_tone + grey_tone
3901
3902
3903
3904
3905 def get_buffer_line(self, line):
3906 """ Get the buffer line number corresponding to the supplied screen line number. """
3907 return self.screen.get_buffer_line(line)
3908
3909
3910autoload/conque_term/conque_globals.py [[[1
3911317
3912# FILE: autoload/conque_term/conque_globals.py
3913# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
3914# WEBSITE: http://conque.googlecode.com
3915# MODIFIED: 2011-09-12
3916# VERSION: 2.3, for Vim 7.0
3917# LICENSE:
3918# Conque - Vim terminal/console emulator
3919# Copyright (C) 2009-2011 Nico Raffo
3920#
3921# MIT License
3922#
3923# Permission is hereby granted, free of charge, to any person obtaining a copy
3924# of this software and associated documentation files (the "Software"), to deal
3925# in the Software without restriction, including without limitation the rights
3926# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
3927# copies of the Software, and to permit persons to whom the Software is
3928# furnished to do so, subject to the following conditions:
3929#
3930# The above copyright notice and this permission notice shall be included in
3931# all copies or substantial portions of the Software.
3932#
3933# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
3934# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
3935# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
3936# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
3937# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
3938# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
3939# THE SOFTWARE.
3940
3941"""Common global constants and functions for Conque."""
3942
3943import sys
3944import re
3945
3946
3947# PYTHON VERSION
3948CONQUE_PYTHON_VERSION = sys.version_info[0]
3949
3950# Encoding
3951
3952try:
3953 # Vim's character encoding
3954 import vim
3955 CONQUE_VIM_ENCODING = vim.eval('&encoding')
3956
3957except:
3958 CONQUE_VIM_ENCODING = 'utf-8'
3959
3960
3961def u(str_val, str_encoding='utf-8', errors='strict'):
3962 """ Foolhardy attempt to make unicode string syntax compatible with both python 2 and 3. """
3963
3964 if not str_val:
3965 str_val = ''
3966
3967 if CONQUE_PYTHON_VERSION == 3:
3968 return str_val
3969
3970 else:
3971 return unicode(str_val, str_encoding, errors)
3972
3973def uchr(str):
3974 """ Foolhardy attempt to make unicode string syntax compatible with both python 2 and 3. """
3975
3976 if CONQUE_PYTHON_VERSION == 3:
3977 return chr(str)
3978
3979 else:
3980 return unichr(str)
3981
3982
3983# Logging
3984
3985
3986
3987
3988
3989
3990
3991
3992
3993
3994
3995
3996
3997
3998
3999
4000# Unix escape sequence settings
4001
4002CONQUE_CTL = {
4003 1: 'soh', # start of heading
4004 2: 'stx', # start of text
4005 7: 'bel', # bell
4006 8: 'bs', # backspace
4007 9: 'tab', # tab
4008 10: 'nl', # new line
4009 13: 'cr', # carriage return
4010 14: 'so', # shift out
4011 15: 'si' # shift in
4012}
4013# 11 : 'vt', # vertical tab
4014# 12 : 'ff', # form feed
4015
4016# Escape sequences
4017CONQUE_ESCAPE = {
4018 'm': 'font',
4019 'J': 'clear_screen',
4020 'K': 'clear_line',
4021 '@': 'add_spaces',
4022 'A': 'cursor_up',
4023 'B': 'cursor_down',
4024 'C': 'cursor_right',
4025 'D': 'cursor_left',
4026 'G': 'cursor_to_column',
4027 'H': 'cursor',
4028 'P': 'delete_chars',
4029 'f': 'cursor',
4030 'g': 'tab_clear',
4031 'r': 'set_coords',
4032 'h': 'set',
4033 'l': 'reset'
4034}
4035# 'L': 'insert_lines',
4036# 'M': 'delete_lines',
4037# 'd': 'cusor_vpos',
4038
4039# Alternate escape sequences, no [
4040CONQUE_ESCAPE_PLAIN = {
4041 'D': 'scroll_up',
4042 'E': 'next_line',
4043 'H': 'set_tab',
4044 'M': 'scroll_down'
4045}
4046# 'N': 'single_shift_2',
4047# 'O': 'single_shift_3',
4048# '=': 'alternate_keypad',
4049# '>': 'numeric_keypad',
4050# '7': 'save_cursor',
4051# '8': 'restore_cursor',
4052
4053# Character set escape sequences, with "("
4054CONQUE_ESCAPE_CHARSET = {
4055 'A': 'uk',
4056 'B': 'us',
4057 '0': 'graphics'
4058}
4059
4060# Uber alternate escape sequences, with # or ?
4061CONQUE_ESCAPE_QUESTION = {
4062 '1h': 'new_line_mode',
4063 '3h': '132_cols',
4064 '4h': 'smooth_scrolling',
4065 '5h': 'reverse_video',
4066 '6h': 'relative_origin',
4067 '7h': 'set_auto_wrap',
4068 '8h': 'set_auto_repeat',
4069 '9h': 'set_interlacing_mode',
4070 '1l': 'set_cursor_key',
4071 '2l': 'set_vt52',
4072 '3l': '80_cols',
4073 '4l': 'set_jump_scrolling',
4074 '5l': 'normal_video',
4075 '6l': 'absolute_origin',
4076 '7l': 'reset_auto_wrap',
4077 '8l': 'reset_auto_repeat',
4078 '9l': 'reset_interlacing_mode'
4079}
4080
4081CONQUE_ESCAPE_HASH = {
4082 '8': 'screen_alignment_test'
4083}
4084# '3': 'double_height_top',
4085# '4': 'double_height_bottom',
4086# '5': 'single_height_single_width',
4087# '6': 'single_height_double_width',
4088
4089CONQUE_GRAPHICS_SET = [
4090 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
4091 0x0008, 0x0009, 0x000A, 0x000B, 0x000C, 0x000D, 0x000E, 0x000F,
4092 0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
4093 0x0018, 0x0019, 0x001A, 0x001B, 0x001C, 0x001D, 0x001E, 0x001F,
4094 0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
4095 0x0028, 0x0029, 0x002A, 0x2192, 0x2190, 0x2191, 0x2193, 0x002F,
4096 0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
4097 0x0038, 0x0039, 0x003A, 0x003B, 0x003C, 0x003D, 0x003E, 0x003F,
4098 0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
4099 0x0048, 0x0049, 0x004A, 0x004B, 0x004C, 0x004D, 0x004E, 0x004F,
4100 0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
4101 0x0058, 0x0059, 0x005A, 0x005B, 0x005C, 0x005D, 0x005E, 0x00A0,
4102 0x25C6, 0x2592, 0x2409, 0x240C, 0x240D, 0x240A, 0x00B0, 0x00B1,
4103 0x2591, 0x240B, 0x2518, 0x2510, 0x250C, 0x2514, 0x253C, 0xF800,
4104 0xF801, 0x2500, 0xF803, 0xF804, 0x251C, 0x2524, 0x2534, 0x252C,
4105 0x2502, 0x2264, 0x2265, 0x03C0, 0x2260, 0x00A3, 0x00B7, 0x007F,
4106 0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
4107 0x0088, 0x0089, 0x008A, 0x008B, 0x008C, 0x008D, 0x008E, 0x008F,
4108 0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
4109 0x0098, 0x0099, 0x009A, 0x009B, 0x009C, 0x009D, 0x009E, 0x009F,
4110 0x00A0, 0x00A1, 0x00A2, 0x00A3, 0x00A4, 0x00A5, 0x00A6, 0x00A7,
4111 0x00A8, 0x00A9, 0x00AA, 0x00AB, 0x00AC, 0x00AD, 0x00AE, 0x00AF,
4112 0x00B0, 0x00B1, 0x00B2, 0x00B3, 0x00B4, 0x00B5, 0x00B6, 0x00B7,
4113 0x00B8, 0x00B9, 0x00BA, 0x00BB, 0x00BC, 0x00BD, 0x00BE, 0x00BF,
4114 0x00C0, 0x00C1, 0x00C2, 0x00C3, 0x00C4, 0x00C5, 0x00C6, 0x00C7,
4115 0x00C8, 0x00C9, 0x00CA, 0x00CB, 0x00CC, 0x00CD, 0x00CE, 0x00CF,
4116 0x00D0, 0x00D1, 0x00D2, 0x00D3, 0x00D4, 0x00D5, 0x00D6, 0x00D7,
4117 0x00D8, 0x00D9, 0x00DA, 0x00DB, 0x00DC, 0x00DD, 0x00DE, 0x00DF,
4118 0x00E0, 0x00E1, 0x00E2, 0x00E3, 0x00E4, 0x00E5, 0x00E6, 0x00E7,
4119 0x00E8, 0x00E9, 0x00EA, 0x00EB, 0x00EC, 0x00ED, 0x00EE, 0x00EF,
4120 0x00F0, 0x00F1, 0x00F2, 0x00F3, 0x00F4, 0x00F5, 0x00F6, 0x00F7,
4121 0x00F8, 0x00F9, 0x00FA, 0x00FB, 0x00FC, 0x00FD, 0x00FE, 0x00FF
4122]
4123
4124# Font codes
4125CONQUE_FONT = {
4126 0: {'description': 'Normal (default)', 'attributes': {'cterm': 'NONE', 'ctermfg': 'NONE', 'ctermbg': 'NONE', 'gui': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE'}, 'normal': True},
4127 1: {'description': 'Bold', 'attributes': {'cterm': 'BOLD', 'gui': 'BOLD'}, 'normal': False},
4128 4: {'description': 'Underlined', 'attributes': {'cterm': 'UNDERLINE', 'gui': 'UNDERLINE'}, 'normal': False},
4129 5: {'description': 'Blink (appears as Bold)', 'attributes': {'cterm': 'BOLD', 'gui': 'BOLD'}, 'normal': False},
4130 7: {'description': 'Inverse', 'attributes': {'cterm': 'REVERSE', 'gui': 'REVERSE'}, 'normal': False},
4131 8: {'description': 'Invisible (hidden)', 'attributes': {'ctermfg': '0', 'ctermbg': '0', 'guifg': '#000000', 'guibg': '#000000'}, 'normal': False},
4132 22: {'description': 'Normal (neither bold nor faint)', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True},
4133 24: {'description': 'Not underlined', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True},
4134 25: {'description': 'Steady (not blinking)', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True},
4135 27: {'description': 'Positive (not inverse)', 'attributes': {'cterm': 'NONE', 'gui': 'NONE'}, 'normal': True},
4136 28: {'description': 'Visible (not hidden)', 'attributes': {'ctermfg': 'NONE', 'ctermbg': 'NONE', 'guifg': 'NONE', 'guibg': 'NONE'}, 'normal': True},
4137 30: {'description': 'Set foreground color to Black', 'attributes': {'ctermfg': '16', 'guifg': '#000000'}, 'normal': False},
4138 31: {'description': 'Set foreground color to Red', 'attributes': {'ctermfg': '1', 'guifg': '#ff0000'}, 'normal': False},
4139 32: {'description': 'Set foreground color to Green', 'attributes': {'ctermfg': '2', 'guifg': '#00ff00'}, 'normal': False},
4140 33: {'description': 'Set foreground color to Yellow', 'attributes': {'ctermfg': '3', 'guifg': '#ffff00'}, 'normal': False},
4141 34: {'description': 'Set foreground color to Blue', 'attributes': {'ctermfg': '4', 'guifg': '#0000ff'}, 'normal': False},
4142 35: {'description': 'Set foreground color to Magenta', 'attributes': {'ctermfg': '5', 'guifg': '#990099'}, 'normal': False},
4143 36: {'description': 'Set foreground color to Cyan', 'attributes': {'ctermfg': '6', 'guifg': '#009999'}, 'normal': False},
4144 37: {'description': 'Set foreground color to White', 'attributes': {'ctermfg': '7', 'guifg': '#ffffff'}, 'normal': False},
4145 39: {'description': 'Set foreground color to default (original)', 'attributes': {'ctermfg': 'NONE', 'guifg': 'NONE'}, 'normal': True},
4146 40: {'description': 'Set background color to Black', 'attributes': {'ctermbg': '16', 'guibg': '#000000'}, 'normal': False},
4147 41: {'description': 'Set background color to Red', 'attributes': {'ctermbg': '1', 'guibg': '#ff0000'}, 'normal': False},
4148 42: {'description': 'Set background color to Green', 'attributes': {'ctermbg': '2', 'guibg': '#00ff00'}, 'normal': False},
4149 43: {'description': 'Set background color to Yellow', 'attributes': {'ctermbg': '3', 'guibg': '#ffff00'}, 'normal': False},
4150 44: {'description': 'Set background color to Blue', 'attributes': {'ctermbg': '4', 'guibg': '#0000ff'}, 'normal': False},
4151 45: {'description': 'Set background color to Magenta', 'attributes': {'ctermbg': '5', 'guibg': '#990099'}, 'normal': False},
4152 46: {'description': 'Set background color to Cyan', 'attributes': {'ctermbg': '6', 'guibg': '#009999'}, 'normal': False},
4153 47: {'description': 'Set background color to White', 'attributes': {'ctermbg': '7', 'guibg': '#ffffff'}, 'normal': False},
4154 49: {'description': 'Set background color to default (original).', 'attributes': {'ctermbg': 'NONE', 'guibg': 'NONE'}, 'normal': True},
4155 90: {'description': 'Set foreground color to Black', 'attributes': {'ctermfg': '8', 'guifg': '#000000'}, 'normal': False},
4156 91: {'description': 'Set foreground color to Red', 'attributes': {'ctermfg': '9', 'guifg': '#ff0000'}, 'normal': False},
4157 92: {'description': 'Set foreground color to Green', 'attributes': {'ctermfg': '10', 'guifg': '#00ff00'}, 'normal': False},
4158 93: {'description': 'Set foreground color to Yellow', 'attributes': {'ctermfg': '11', 'guifg': '#ffff00'}, 'normal': False},
4159 94: {'description': 'Set foreground color to Blue', 'attributes': {'ctermfg': '12', 'guifg': '#0000ff'}, 'normal': False},
4160 95: {'description': 'Set foreground color to Magenta', 'attributes': {'ctermfg': '13', 'guifg': '#990099'}, 'normal': False},
4161 96: {'description': 'Set foreground color to Cyan', 'attributes': {'ctermfg': '14', 'guifg': '#009999'}, 'normal': False},
4162 97: {'description': 'Set foreground color to White', 'attributes': {'ctermfg': '15', 'guifg': '#ffffff'}, 'normal': False},
4163 100: {'description': 'Set background color to Black', 'attributes': {'ctermbg': '8', 'guibg': '#000000'}, 'normal': False},
4164 101: {'description': 'Set background color to Red', 'attributes': {'ctermbg': '9', 'guibg': '#ff0000'}, 'normal': False},
4165 102: {'description': 'Set background color to Green', 'attributes': {'ctermbg': '10', 'guibg': '#00ff00'}, 'normal': False},
4166 103: {'description': 'Set background color to Yellow', 'attributes': {'ctermbg': '11', 'guibg': '#ffff00'}, 'normal': False},
4167 104: {'description': 'Set background color to Blue', 'attributes': {'ctermbg': '12', 'guibg': '#0000ff'}, 'normal': False},
4168 105: {'description': 'Set background color to Magenta', 'attributes': {'ctermbg': '13', 'guibg': '#990099'}, 'normal': False},
4169 106: {'description': 'Set background color to Cyan', 'attributes': {'ctermbg': '14', 'guibg': '#009999'}, 'normal': False},
4170 107: {'description': 'Set background color to White', 'attributes': {'ctermbg': '15', 'guibg': '#ffffff'}, 'normal': False}
4171}
4172
4173
4174# regular expression matching (almost) all control sequences
4175CONQUE_SEQ_REGEX = re.compile("(\x1b\[?\??#?[0-9;]*[a-zA-Z0-9@=>]|\x1b\][0-9];.*?\x07|[\x01-\x0f]|\x1b\([AB0])")
4176CONQUE_SEQ_REGEX_CTL = re.compile("^[\x01-\x0f]$")
4177CONQUE_SEQ_REGEX_CSI = re.compile("^\x1b\[")
4178CONQUE_SEQ_REGEX_TITLE = re.compile("^\x1b\]")
4179CONQUE_SEQ_REGEX_HASH = re.compile("^\x1b#")
4180CONQUE_SEQ_REGEX_ESC = re.compile("^\x1b.$")
4181CONQUE_SEQ_REGEX_CHAR = re.compile("^\x1b[()]")
4182
4183# match table output
4184CONQUE_TABLE_OUTPUT = re.compile("^\s*\|\s.*\s\|\s*$|^\s*\+[=+-]+\+\s*$")
4185
4186# basic terminal colors
4187CONQUE_COLOR_SEQUENCE = (
4188 '000', '009', '090', '099', '900', '909', '990', '999',
4189 '000', '00f', '0f0', '0ff', 'f00', 'f0f', 'ff0', 'fff'
4190)
4191
4192
4193# Windows subprocess constants
4194
4195# shared memory size
4196CONQUE_SOLE_BUFFER_LENGTH = 1000
4197CONQUE_SOLE_INPUT_SIZE = 1000
4198CONQUE_SOLE_STATS_SIZE = 1000
4199CONQUE_SOLE_COMMANDS_SIZE = 255
4200CONQUE_SOLE_RESCROLL_SIZE = 255
4201CONQUE_SOLE_RESIZE_SIZE = 255
4202
4203# interval of screen redraw
4204# larger number means less frequent
4205CONQUE_SOLE_SCREEN_REDRAW = 50
4206
4207# interval of full buffer redraw
4208# larger number means less frequent
4209CONQUE_SOLE_BUFFER_REDRAW = 500
4210
4211# interval of full output bucket replacement
4212# larger number means less frequent, 1 = every time
4213CONQUE_SOLE_MEM_REDRAW = 1000
4214
4215# maximum number of lines with terminal colors
4216# ignored if g:ConqueTerm_Color = 2
4217CONQUE_MAX_SYNTAX_LINES = 200
4218
4219# windows input splitting on special keys
4220CONQUE_WIN32_REGEX_VK = re.compile("(\x1b\[[0-9;]+VK)")
4221
4222# windows attribute string splitting
4223CONQUE_WIN32_REGEX_ATTR = re.compile("((.)\\2*)", re.DOTALL)
4224
4225# special key attributes
4226CONQUE_VK_ATTR_CTRL_PRESSED = u('1024')
4227
4228
4229autoload/conque_term/conque_screen.py [[[1
4230236
4231# FILE: autoload/conque_term/conque_screen.py
4232# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
4233# WEBSITE: http://conque.googlecode.com
4234# MODIFIED: 2011-09-12
4235# VERSION: 2.3, for Vim 7.0
4236# LICENSE:
4237# Conque - Vim terminal/console emulator
4238# Copyright (C) 2009-2011 Nico Raffo
4239#
4240# MIT License
4241#
4242# Permission is hereby granted, free of charge, to any person obtaining a copy
4243# of this software and associated documentation files (the "Software"), to deal
4244# in the Software without restriction, including without limitation the rights
4245# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4246# copies of the Software, and to permit persons to whom the Software is
4247# furnished to do so, subject to the following conditions:
4248#
4249# The above copyright notice and this permission notice shall be included in
4250# all copies or substantial portions of the Software.
4251#
4252# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4253# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4254# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4255# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4256# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4257# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4258# THE SOFTWARE.
4259
4260"""
4261ConqueScreen is an extention of the vim.current.buffer object
4262
4263Unix terminal escape sequences usually reference line numbers relative to the
4264top of the visible screen. However the visible portion of the Vim buffer
4265representing the terminal probably doesn't start at the first line of the
4266buffer.
4267
4268The ConqueScreen class allows access to the Vim buffer with screen-relative
4269line numbering. And handles a few other related tasks, such as setting the
4270correct cursor position.
4271
4272 E.g.:
4273 s = ConqueScreen()
4274 ...
4275 s[5] = 'Set 5th line in terminal to this line'
4276 s.append('Add new line to terminal')
4277 s[5] = 'Since previous append() command scrolled the terminal down, this is a different line than first cb[5] call'
4278
4279"""
4280
4281import vim
4282
4283class ConqueScreen(object):
4284
4285 # the buffer
4286 buffer = None
4287
4288 # screen and scrolling regions
4289 screen_top = 1
4290
4291 # screen width
4292 screen_width = 80
4293 screen_height = 80
4294
4295 # char encoding for vim buffer
4296 screen_encoding = 'utf-8'
4297
4298
4299 def __init__(self):
4300 """ Initialize screen size and character encoding. """
4301
4302 self.buffer = vim.current.buffer
4303
4304 # initialize screen size
4305 self.screen_top = 1
4306 self.screen_width = vim.current.window.width
4307 self.screen_height = vim.current.window.height
4308
4309 # save screen character encoding type
4310 self.screen_encoding = vim.eval('&fileencoding')
4311
4312
4313 def __len__(self):
4314 """ Define the len() function for ConqueScreen objects. """
4315 return len(self.buffer)
4316
4317
4318 def __getitem__(self, key):
4319 """ Define value access for ConqueScreen objects. """
4320 buffer_line = self.get_real_idx(key)
4321
4322 # if line is past buffer end, add lines to buffer
4323 if buffer_line >= len(self.buffer):
4324 for i in range(len(self.buffer), buffer_line + 1):
4325 self.append(' ')
4326
4327 return u(self.buffer[buffer_line], 'utf-8')
4328
4329
4330 def __setitem__(self, key, value):
4331 """ Define value assignments for ConqueScreen objects. """
4332 buffer_line = self.get_real_idx(key)
4333
4334 if CONQUE_PYTHON_VERSION == 2:
4335 val = value.encode(self.screen_encoding)
4336 else:
4337 # XXX / Vim's python3 interface doesn't accept bytes object
4338 val = str(value)
4339
4340 # if line is past end of screen, append
4341 if buffer_line == len(self.buffer):
4342 self.buffer.append(val)
4343 else:
4344 self.buffer[buffer_line] = val
4345
4346
4347 def __delitem__(self, key):
4348 """ Define value deletion for ConqueScreen objects. """
4349 del self.buffer[self.screen_top + key - 2]
4350
4351
4352 def append(self, value):
4353 """ Define value appending for ConqueScreen objects. """
4354
4355 if len(self.buffer) > self.screen_top + self.screen_height - 1:
4356 self.buffer[len(self.buffer) - 1] = value
4357 else:
4358 self.buffer.append(value)
4359
4360 if len(self.buffer) > self.screen_top + self.screen_height - 1:
4361 self.screen_top += 1
4362
4363 if vim.current.buffer.number == self.buffer.number:
4364 vim.command('normal! G')
4365
4366
4367 def insert(self, line, value):
4368 """ Define value insertion for ConqueScreen objects. """
4369
4370 l = self.screen_top + line - 2
4371 try:
4372 self.buffer.append(value, l)
4373 except:
4374 self.buffer[l:l] = [value]
4375
4376
4377 def get_top(self):
4378 """ Get the Vim line number representing the top of the visible terminal. """
4379 return self.screen_top
4380
4381
4382 def get_real_idx(self, line):
4383 """ Get the zero index Vim line number corresponding to the provided screen line. """
4384 return (self.screen_top + line - 2)
4385
4386
4387 def get_buffer_line(self, line):
4388 """ Get the Vim line number corresponding to the provided screen line. """
4389 return (self.screen_top + line - 1)
4390
4391
4392 def set_screen_width(self, width):
4393 """ Set the screen width. """
4394 self.screen_width = width
4395
4396
4397 def clear(self):
4398 """ Clear the screen. Does not clear the buffer, just scrolls down past all text. """
4399
4400 self.screen_width = width
4401 self.buffer.append(' ')
4402 vim.command('normal! Gzt')
4403 self.screen_top = len(self.buffer)
4404
4405
4406 def set_cursor(self, line, column):
4407 """ Set cursor position. """
4408
4409 # figure out line
4410 buffer_line = self.screen_top + line - 1
4411 if buffer_line > len(self.buffer):
4412 for l in range(len(self.buffer) - 1, buffer_line):
4413 self.buffer.append('')
4414
4415 # figure out column
4416 real_column = column
4417 if len(self.buffer[buffer_line - 1]) < real_column:
4418 self.buffer[buffer_line - 1] = self.buffer[buffer_line - 1] + ' ' * (real_column - len(self.buffer[buffer_line - 1]))
4419
4420 if not CONQUE_FAST_MODE:
4421 # set cursor at byte index of real_column'th character
4422 vim.command('call cursor(' + str(buffer_line) + ', byteidx(getline(' + str(buffer_line) + '), ' + str(real_column) + '))')
4423
4424 else:
4425 # old version
4426 # python version is occasionally grumpy
4427 try:
4428 vim.current.window.cursor = (buffer_line, real_column - 1)
4429 except:
4430 vim.command('call cursor(' + str(buffer_line) + ', ' + str(real_column) + ')')
4431
4432
4433 def reset_size(self, line):
4434 """ Change screen size """
4435
4436
4437
4438
4439
4440 # save cursor line number
4441 buffer_line = self.screen_top + line
4442
4443 # reset screen size
4444 self.screen_width = vim.current.window.width
4445 self.screen_height = vim.current.window.height
4446 self.screen_top = len(self.buffer) - vim.current.window.height + 1
4447 if self.screen_top < 1:
4448 self.screen_top = 1
4449
4450
4451 # align bottom of buffer to bottom of screen
4452 vim.command('normal! ' + str(self.screen_height) + 'kG')
4453
4454 ret = buffer_line - self.screen_top
4455 if ret > self.screen_height:
4456 ret = self.screen_height
4457
4458 # return new relative line number
4459 return ret
4460
4461
4462 def align(self):
4463 """ align bottom of buffer to bottom of screen """
4464 vim.command('normal! ' + str(self.screen_height) + 'kG')
4465
4466
4467autoload/conque_term/conque_sole.py [[[1
4468461
4469# FILE: autoload/conque_term/conque_sole.py
4470# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
4471# WEBSITE: http://conque.googlecode.com
4472# MODIFIED: 2011-09-12
4473# VERSION: 2.3, for Vim 7.0
4474# LICENSE:
4475# Conque - Vim terminal/console emulator
4476# Copyright (C) 2009-2011 Nico Raffo
4477#
4478# MIT License
4479#
4480# Permission is hereby granted, free of charge, to any person obtaining a copy
4481# of this software and associated documentation files (the "Software"), to deal
4482# in the Software without restriction, including without limitation the rights
4483# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4484# copies of the Software, and to permit persons to whom the Software is
4485# furnished to do so, subject to the following conditions:
4486#
4487# The above copyright notice and this permission notice shall be included in
4488# all copies or substantial portions of the Software.
4489#
4490# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4491# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4492# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4493# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4494# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4495# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4496# THE SOFTWARE.
4497
4498"""
4499Windows Console Emulator
4500
4501This is the main interface to the Windows emulator. It reads new output from the background console
4502and updates the Vim buffer.
4503"""
4504
4505import vim
4506
4507
4508class ConqueSole(Conque):
4509
4510 window_top = None
4511 window_bottom = None
4512
4513 color_cache = {}
4514 attribute_cache = {}
4515 color_mode = None
4516 color_conceals = {}
4517
4518 buffer = None
4519 encoding = None
4520
4521 # counters for periodic rendering
4522 buffer_redraw_ct = 1
4523 screen_redraw_ct = 1
4524
4525 # line offset, shifts output down
4526 offset = 0
4527
4528
4529 def open(self):
4530 """ Start command and initialize this instance
4531
4532 Arguments:
4533 command - Command string, e.g. "Powershell.exe"
4534 options - Dictionary of config options
4535 python_exe - Path to the python.exe executable. Usually C:\PythonXX\python.exe
4536 communicator_py - Path to subprocess controller script in user's vimfiles directory
4537
4538 """
4539 # get arguments
4540 command = vim.eval('command')
4541 options = vim.eval('options')
4542 python_exe = vim.eval('py_exe')
4543 communicator_py = vim.eval('py_vim')
4544
4545 # init size
4546 self.columns = vim.current.window.width
4547 self.lines = vim.current.window.height
4548 self.window_top = 0
4549 self.window_bottom = vim.current.window.height - 1
4550
4551 # color mode
4552 self.color_mode = vim.eval('g:ConqueTerm_ColorMode')
4553
4554 # line offset
4555 self.offset = int(options['offset'])
4556
4557 # init color
4558 self.enable_colors = options['color'] and not CONQUE_FAST_MODE
4559
4560 # open command
4561 self.proc = ConqueSoleWrapper()
4562 self.proc.open(command, self.lines, self.columns, python_exe, communicator_py, options)
4563
4564 self.buffer = vim.current.buffer
4565 self.screen_encoding = vim.eval('&fileencoding')
4566
4567
4568 def read(self, timeout=1, set_cursor=True, return_output=False, update_buffer=True):
4569 """ Read from console and update Vim buffer. """
4570
4571 try:
4572 stats = self.proc.get_stats()
4573
4574 if not stats:
4575 return
4576
4577 # disable screen and buffer redraws in fast mode
4578 if not CONQUE_FAST_MODE:
4579 self.buffer_redraw_ct += 1
4580 self.screen_redraw_ct += 1
4581
4582 update_top = 0
4583 update_bottom = 0
4584 lines = []
4585
4586 # full buffer redraw, our favorite!
4587 #if self.buffer_redraw_ct == CONQUE_SOLE_BUFFER_REDRAW:
4588 # self.buffer_redraw_ct = 0
4589 # update_top = 0
4590 # update_bottom = stats['top_offset'] + self.lines
4591 # (lines, attributes) = self.proc.read(update_top, update_bottom)
4592 # if return_output:
4593 # output = self.get_new_output(lines, update_top, stats)
4594 # if update_buffer:
4595 # for i in range(update_top, update_bottom + 1):
4596 # if CONQUE_FAST_MODE:
4597 # self.plain_text(i, lines[i], None, stats)
4598 # else:
4599 # self.plain_text(i, lines[i], attributes[i], stats)
4600
4601 # full screen redraw
4602 if stats['cursor_y'] + 1 != self.l or stats['top_offset'] != self.window_top or self.screen_redraw_ct >= CONQUE_SOLE_SCREEN_REDRAW:
4603
4604 self.screen_redraw_ct = 0
4605 update_top = self.window_top
4606 update_bottom = max([stats['top_offset'] + self.lines + 1, stats['cursor_y']])
4607 (lines, attributes) = self.proc.read(update_top, update_bottom - update_top + 1)
4608 if return_output:
4609 output = self.get_new_output(lines, update_top, stats)
4610 if update_buffer:
4611 for i in range(update_top, update_bottom + 1):
4612 if CONQUE_FAST_MODE:
4613 self.plain_text(i, lines[i - update_top], None, stats)
4614 else:
4615 self.plain_text(i, lines[i - update_top], attributes[i - update_top], stats)
4616
4617
4618 # single line redraw
4619 else:
4620 update_top = stats['cursor_y']
4621 (lines, attributes) = self.proc.read(update_top, 1)
4622 if return_output:
4623 output = self.get_new_output(lines, update_top, stats)
4624 if update_buffer:
4625 if lines[0].rstrip() != u(self.buffer[update_top].rstrip()):
4626 if CONQUE_FAST_MODE:
4627 self.plain_text(update_top, lines[0], None, stats)
4628 else:
4629 self.plain_text(update_top, lines[0], attributes[0], stats)
4630
4631
4632 # reset current position
4633 self.window_top = stats['top_offset']
4634 self.l = stats['cursor_y'] + 1
4635 self.c = stats['cursor_x'] + 1
4636
4637 # reposition cursor if this seems plausible
4638 if set_cursor:
4639 self.set_cursor(self.l, self.c)
4640
4641 if return_output:
4642 return output
4643
4644 except:
4645
4646 pass
4647
4648
4649 def get_new_output(self, lines, update_top, stats):
4650 """ Calculate the "new" output from this read. Fake but useful """
4651
4652 if not (stats['cursor_y'] + 1 > self.l or (stats['cursor_y'] + 1 == self.l and stats['cursor_x'] + 1 > self.c)):
4653 return ""
4654
4655
4656
4657
4658
4659
4660 try:
4661 num_to_return = stats['cursor_y'] - self.l + 2
4662
4663 lines = lines[self.l - update_top - 1:]
4664
4665
4666 new_output = []
4667
4668 # first line
4669 new_output.append(lines[0][self.c - 1:].rstrip())
4670
4671 # the rest
4672 for i in range(1, num_to_return):
4673 new_output.append(lines[i].rstrip())
4674
4675 except:
4676
4677 pass
4678
4679
4680
4681 return "\n".join(new_output)
4682
4683
4684 def plain_text(self, line_nr, text, attributes, stats):
4685 """ Write plain text to Vim buffer. """
4686
4687
4688
4689
4690
4691 # handle line offset
4692 line_nr += self.offset
4693
4694 self.l = line_nr + 1
4695
4696 # remove trailing whitespace
4697 text = text.rstrip()
4698
4699 # if we're using concealed text for color, then s- is weird
4700 if self.color_mode == 'conceal':
4701
4702 text = self.add_conceal_color(text, attributes, stats, line_nr)
4703
4704
4705 # deal with character encoding
4706 if CONQUE_PYTHON_VERSION == 2:
4707 val = text.encode(self.screen_encoding)
4708 else:
4709 # XXX / Vim's python3 interface doesn't accept bytes object
4710 val = str(text)
4711
4712 # update vim buffer
4713 if len(self.buffer) <= line_nr:
4714 self.buffer.append(val)
4715 else:
4716 self.buffer[line_nr] = val
4717
4718 if self.enable_colors and not self.color_mode == 'conceal' and line_nr > self.l - CONQUE_MAX_SYNTAX_LINES:
4719 relevant = attributes[0:len(text)]
4720 if line_nr not in self.attribute_cache or self.attribute_cache[line_nr] != relevant:
4721 self.do_color(attributes=relevant, stats=stats)
4722 self.attribute_cache[line_nr] = relevant
4723
4724
4725 def add_conceal_color(self, text, attributes, stats, line_nr):
4726 """ Add 'conceal' color strings to output text """
4727
4728 # stop here if coloration is disabled
4729 if not self.enable_colors:
4730 return text
4731
4732 # if no colors for this line, clear everything out
4733 if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes):
4734 return text
4735
4736 new_text = ''
4737 self.color_conceals[line_nr] = []
4738
4739 attribute_chunks = CONQUE_WIN32_REGEX_ATTR.findall(attributes)
4740 offset = 0
4741 ends = []
4742 for attr in attribute_chunks:
4743 attr_num = ord(attr[1])
4744 ends = []
4745 if attr_num != stats['default_attribute']:
4746
4747 color = self.translate_color(attr_num)
4748
4749 new_text += chr(27) + 'sf' + color['fg_code'] + ';'
4750 ends.append(chr(27) + 'ef' + color['fg_code'] + ';')
4751 self.color_conceals[line_nr].append(offset)
4752
4753 if attr_num > 15:
4754 new_text += chr(27) + 'sb' + color['bg_code'] + ';'
4755 ends.append(chr(27) + 'eb' + color['bg_code'] + ';')
4756 self.color_conceals[line_nr].append(offset)
4757
4758 new_text += text[offset:offset + len(attr[0])]
4759
4760 # close color regions
4761 ends.reverse()
4762 for i in range(0, len(ends)):
4763 self.color_conceals[line_nr].append(len(new_text))
4764 new_text += ends[i]
4765
4766 offset += len(attr[0])
4767
4768 return new_text
4769
4770
4771 def do_color(self, start=0, end=0, attributes='', stats=None):
4772 """ Convert Windows console attributes into Vim syntax highlighting """
4773
4774 # if no colors for this line, clear everything out
4775 if len(attributes) == 0 or attributes == u(chr(stats['default_attribute'])) * len(attributes):
4776 self.color_changes = {}
4777 self.apply_color(1, len(attributes), self.l)
4778 return
4779
4780 attribute_chunks = CONQUE_WIN32_REGEX_ATTR.findall(attributes)
4781 offset = 0
4782 for attr in attribute_chunks:
4783 attr_num = ord(attr[1])
4784 if attr_num != stats['default_attribute']:
4785 self.color_changes = self.translate_color(attr_num)
4786 self.apply_color(offset + 1, offset + len(attr[0]) + 1, self.l)
4787 offset += len(attr[0])
4788
4789
4790 def translate_color(self, attr):
4791 """ Convert Windows console attributes into RGB colors """
4792
4793 # check for cached color
4794 if attr in self.color_cache:
4795 return self.color_cache[attr]
4796
4797
4798
4799
4800
4801
4802 # convert attribute integer to bit string
4803 bit_str = bin(attr)
4804 bit_str = bit_str.replace('0b', '')
4805
4806 # slice foreground and background portions of bit string
4807 fg = bit_str[-4:].rjust(4, '0')
4808 bg = bit_str[-8:-4].rjust(4, '0')
4809
4810 # ok, first create foreground #rbg
4811 red = int(fg[1]) * 204 + int(fg[0]) * int(fg[1]) * 51
4812 green = int(fg[2]) * 204 + int(fg[0]) * int(fg[2]) * 51
4813 blue = int(fg[3]) * 204 + int(fg[0]) * int(fg[3]) * 51
4814 fg_str = "#%02x%02x%02x" % (red, green, blue)
4815 fg_code = "%02x%02x%02x" % (red, green, blue)
4816 fg_code = fg_code[0] + fg_code[2] + fg_code[4]
4817
4818 # ok, first create foreground #rbg
4819 red = int(bg[1]) * 204 + int(bg[0]) * int(bg[1]) * 51
4820 green = int(bg[2]) * 204 + int(bg[0]) * int(bg[2]) * 51
4821 blue = int(bg[3]) * 204 + int(bg[0]) * int(bg[3]) * 51
4822 bg_str = "#%02x%02x%02x" % (red, green, blue)
4823 bg_code = "%02x%02x%02x" % (red, green, blue)
4824 bg_code = bg_code[0] + bg_code[2] + bg_code[4]
4825
4826 # build value for color_changes
4827
4828 color = {'guifg': fg_str, 'guibg': bg_str}
4829
4830 if self.color_mode == 'conceal':
4831 color['fg_code'] = fg_code
4832 color['bg_code'] = bg_code
4833
4834 self.color_cache[attr] = color
4835
4836 return color
4837
4838
4839 def write_vk(self, vk_code):
4840 """ write virtual key code to shared memory using proprietary escape seq """
4841
4842 self.proc.write_vk(vk_code)
4843
4844 def update_window(self, force=False):
4845 # This magically works
4846 vim.command("normal! i")
4847
4848
4849 def update_window_size(self, tell_subprocess = True):
4850 """ Resize underlying console if Vim buffer size has changed """
4851
4852 if vim.current.window.width != self.columns or vim.current.window.height != self.lines:
4853
4854 # reset all window size attributes to default
4855 self.columns = vim.current.window.width
4856 self.lines = vim.current.window.height
4857 self.working_columns = vim.current.window.width
4858 self.working_lines = vim.current.window.height
4859 self.bottom = vim.current.window.height
4860
4861 if tell_subprocess:
4862 self.proc.window_resize(vim.current.window.height, vim.current.window.width)
4863
4864
4865 def set_cursor(self, line, column):
4866 """ Update cursor position in Vim buffer """
4867
4868
4869
4870 # handle offset
4871 line += self.offset
4872
4873 # shift cursor position to handle concealed text
4874 if self.enable_colors and self.color_mode == 'conceal':
4875 if line - 1 in self.color_conceals:
4876 for c in self.color_conceals[line - 1]:
4877 if c < column:
4878 column += 7
4879 else:
4880 break
4881
4882
4883
4884 # figure out line
4885 buffer_line = line
4886 if buffer_line > len(self.buffer):
4887 for l in range(len(self.buffer) - 1, buffer_line):
4888 self.buffer.append('')
4889
4890 # figure out column
4891 real_column = column
4892 if len(self.buffer[buffer_line - 1]) < real_column:
4893 self.buffer[buffer_line - 1] = self.buffer[buffer_line - 1] + ' ' * (real_column - len(self.buffer[buffer_line - 1]))
4894
4895 # python version is occasionally grumpy
4896 try:
4897 vim.current.window.cursor = (buffer_line, real_column - 1)
4898 except:
4899 vim.command('call cursor(' + str(buffer_line) + ', ' + str(real_column) + ')')
4900
4901
4902 def idle(self):
4903 """ go into idle mode """
4904
4905 self.proc.idle()
4906
4907
4908 def resume(self):
4909 """ resume from idle mode """
4910
4911 self.proc.resume()
4912
4913
4914 def close(self):
4915 """ end console subprocess """
4916 self.proc.close()
4917
4918
4919 def abort(self):
4920 """ end subprocess forcefully """
4921 self.proc.close()
4922
4923
4924 def get_buffer_line(self, line):
4925 """ get buffer line """
4926 return line
4927
4928
4929# vim:foldmethod=marker
4930autoload/conque_term/conque_sole_communicator.py [[[1
4931183
4932# FILE: autoload/conque_term/conque_sole_communicator.py
4933# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
4934# WEBSITE: http://conque.googlecode.com
4935# MODIFIED: 2011-09-12
4936# VERSION: 2.3, for Vim 7.0
4937# LICENSE:
4938# Conque - Vim terminal/console emulator
4939# Copyright (C) 2009-2011 Nico Raffo
4940#
4941# MIT License
4942#
4943# Permission is hereby granted, free of charge, to any person obtaining a copy
4944# of this software and associated documentation files (the "Software"), to deal
4945# in the Software without restriction, including without limitation the rights
4946# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
4947# copies of the Software, and to permit persons to whom the Software is
4948# furnished to do so, subject to the following conditions:
4949#
4950# The above copyright notice and this permission notice shall be included in
4951# all copies or substantial portions of the Software.
4952#
4953# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
4954# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
4955# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
4956# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
4957# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
4958# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
4959# THE SOFTWARE.
4960
4961"""
4962
4963ConqueSoleCommunicator
4964
4965This script will create a new Windows console and start the requested program
4966inside of it. This process is launched independently from the parent Vim
4967program, so it has no access to the vim module.
4968
4969The main loop in this script reads data from the console and syncs it onto
4970blocks of memory shared with the Vim process. In this way the Vim process
4971and this script can communicate with each other.
4972
4973"""
4974
4975import time
4976import sys
4977
4978from conque_globals import *
4979from conque_win32_util import *
4980from conque_sole_subprocess import *
4981from conque_sole_shared_memory import *
4982
4983##############################################################
4984# only run if this file was run directly
4985
4986if __name__ == '__main__':
4987
4988 # attempt to catch ALL exceptions to fend of zombies
4989 try:
4990
4991 # simple arg validation
4992
4993 if len(sys.argv) < 5:
4994
4995 exit()
4996
4997 # maximum time this thing reads. 0 means no limit. Only for testing.
4998 max_loops = 0
4999
5000 # read interval, in seconds
5001 sleep_time = 0.01
5002
5003 # idle read interval, in seconds
5004 idle_sleep_time = 0.10
5005
5006 # are we idled?
5007 is_idle = False
5008
5009 # mem key
5010 mem_key = sys.argv[1]
5011
5012 # console width
5013 console_width = int(sys.argv[2])
5014
5015 # console height
5016 console_height = int(sys.argv[3])
5017
5018 # code page
5019 code_page = int(sys.argv[4])
5020
5021 # code page
5022 fast_mode = int(sys.argv[5])
5023
5024 # the actual subprocess to run
5025 cmd_line = " ".join(sys.argv[6:])
5026
5027
5028 # width and height
5029 options = {'LINES': console_height, 'COLUMNS': console_width, 'CODE_PAGE': code_page, 'FAST_MODE': fast_mode}
5030
5031
5032
5033 # set initial idle status
5034 shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
5035 shm_command.create('write')
5036
5037 cmd = shm_command.read()
5038 if cmd:
5039
5040 if cmd['cmd'] == 'idle':
5041 is_idle = True
5042 shm_command.clear()
5043
5044
5045 ##############################################################
5046 # Create the subprocess
5047
5048 proc = ConqueSoleSubprocess()
5049 res = proc.open(cmd_line, mem_key, options)
5050
5051 if not res:
5052
5053 exit()
5054
5055 ##############################################################
5056 # main loop!
5057
5058 loops = 0
5059
5060 while True:
5061
5062 # check for idle/resume
5063 if is_idle or loops % 25 == 0:
5064
5065 # check process health
5066 if not proc.is_alive():
5067
5068 proc.close()
5069 break
5070
5071 # check for change in buffer focus
5072 cmd = shm_command.read()
5073 if cmd:
5074
5075 if cmd['cmd'] == 'idle':
5076 is_idle = True
5077 shm_command.clear()
5078
5079 elif cmd['cmd'] == 'resume':
5080 is_idle = False
5081 shm_command.clear()
5082
5083
5084 # sleep between loops if moderation is requested
5085 if sleep_time > 0:
5086 if is_idle:
5087 time.sleep(idle_sleep_time)
5088 else:
5089 time.sleep(sleep_time)
5090
5091 # write, read, etc
5092 proc.write()
5093 proc.read()
5094
5095 # increment loops, and exit if max has been reached
5096 loops += 1
5097 if max_loops and loops >= max_loops:
5098
5099 break
5100
5101 ##############################################################
5102 # all done!
5103
5104
5105
5106 proc.close()
5107
5108 # if an exception was thrown, croak
5109 except:
5110
5111 proc.close()
5112
5113
5114# vim:foldmethod=marker
5115autoload/conque_term/conque_sole_shared_memory.py [[[1
5116210
5117# FILE: autoload/conque_term/conque_sole_shared_memory.py
5118# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
5119# WEBSITE: http://conque.googlecode.com
5120# MODIFIED: 2011-09-12
5121# VERSION: 2.3, for Vim 7.0
5122# LICENSE:
5123# Conque - Vim terminal/console emulator
5124# Copyright (C) 2009-2011 Nico Raffo
5125#
5126# MIT License
5127#
5128# Permission is hereby granted, free of charge, to any person obtaining a copy
5129# of this software and associated documentation files (the "Software"), to deal
5130# in the Software without restriction, including without limitation the rights
5131# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5132# copies of the Software, and to permit persons to whom the Software is
5133# furnished to do so, subject to the following conditions:
5134#
5135# The above copyright notice and this permission notice shall be included in
5136# all copies or substantial portions of the Software.
5137#
5138# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5139# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5140# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5141# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5142# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5143# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5144# THE SOFTWARE.
5145
5146"""
5147Wrapper class for shared memory between Windows python processes
5148
5149Adds a small amount of functionality to the standard mmap module.
5150
5151"""
5152
5153import mmap
5154import sys
5155
5156# PYTHON VERSION
5157CONQUE_PYTHON_VERSION = sys.version_info[0]
5158
5159if CONQUE_PYTHON_VERSION == 2:
5160 import cPickle as pickle
5161else:
5162 import pickle
5163
5164
5165class ConqueSoleSharedMemory():
5166
5167 # is the data being stored not fixed length
5168 fixed_length = False
5169
5170 # maximum number of bytes per character, for fixed width blocks
5171 char_width = 1
5172
5173 # fill memory with this character when clearing and fixed_length is true
5174 FILL_CHAR = None
5175
5176 # serialize and unserialize data automatically
5177 serialize = False
5178
5179 # size of shared memory, in bytes / chars
5180 mem_size = None
5181
5182 # size of shared memory, in bytes / chars
5183 mem_type = None
5184
5185 # unique key, so multiple console instances are possible
5186 mem_key = None
5187
5188 # mmap instance
5189 shm = None
5190
5191 # character encoding, dammit
5192 encoding = 'utf-8'
5193
5194 # pickle terminator
5195 TERMINATOR = None
5196
5197
5198 def __init__(self, mem_size, mem_type, mem_key, fixed_length=False, fill_char=' ', serialize=False, encoding='utf-8'):
5199 """ Initialize new shared memory block instance
5200
5201 Arguments:
5202 mem_size -- Memory size in characters, depends on encoding argument to calcuate byte size
5203 mem_type -- Label to identify what will be stored
5204 mem_key -- Unique, probably random key to identify this block
5205 fixed_length -- If set to true, assume the data stored will always fill the memory size
5206 fill_char -- Initialize memory block with this character, only really helpful with fixed_length blocks
5207 serialize -- Automatically serialize data passed to write. Allows storing non-byte data
5208 encoding -- Character encoding to use when storing character data
5209
5210 """
5211 self.mem_size = mem_size
5212 self.mem_type = mem_type
5213 self.mem_key = mem_key
5214 self.fixed_length = fixed_length
5215 self.fill_char = fill_char
5216 self.serialize = serialize
5217 self.encoding = encoding
5218 self.TERMINATOR = str(chr(0)).encode(self.encoding)
5219
5220 if CONQUE_PYTHON_VERSION == 3:
5221 self.FILL_CHAR = fill_char
5222 else:
5223 self.FILL_CHAR = unicode(fill_char)
5224
5225 if fixed_length and encoding == 'utf-8':
5226 self.char_width = 4
5227
5228
5229 def create(self, access='write'):
5230 """ Create a new block of shared memory using the mmap module. """
5231
5232 if access == 'write':
5233 mmap_access = mmap.ACCESS_WRITE
5234 else:
5235 mmap_access = mmap.ACCESS_READ
5236
5237 name = "conque_%s_%s" % (self.mem_type, self.mem_key)
5238
5239 self.shm = mmap.mmap(0, self.mem_size * self.char_width, name, mmap_access)
5240
5241 if not self.shm:
5242 return False
5243 else:
5244 return True
5245
5246
5247 def read(self, chars=1, start=0):
5248 """ Read data from shared memory.
5249
5250 If this is a fixed length block, read 'chars' characters from memory.
5251 Otherwise read up until the TERMINATOR character (null byte).
5252 If this memory is serialized, unserialize it automatically.
5253
5254 """
5255 # go to start position
5256 self.shm.seek(start * self.char_width)
5257
5258 if self.fixed_length:
5259 chars = chars * self.char_width
5260 else:
5261 chars = self.shm.find(self.TERMINATOR)
5262
5263 if chars == 0:
5264 return ''
5265
5266 shm_str = self.shm.read(chars)
5267
5268 # return unpickled byte object
5269 if self.serialize:
5270 return pickle.loads(shm_str)
5271
5272 # decode byes in python 3
5273 if CONQUE_PYTHON_VERSION == 3:
5274 return str(shm_str, self.encoding)
5275
5276 # encoding
5277 if self.encoding != 'ascii':
5278 shm_str = unicode(shm_str, self.encoding)
5279
5280 return shm_str
5281
5282
5283 def write(self, text, start=0):
5284 """ Write data to memory.
5285
5286 If memory is fixed length, simply write the 'text' characters at 'start' position.
5287 Otherwise write 'text' characters and append a null character.
5288 If memory is serializable, do so first.
5289
5290 """
5291 # simple scenario, let pickle create bytes
5292 if self.serialize:
5293 if CONQUE_PYTHON_VERSION == 3:
5294 tb = pickle.dumps(text, 0)
5295 else:
5296 tb = pickle.dumps(text, 0).encode(self.encoding)
5297
5298 else:
5299 tb = text.encode(self.encoding, 'replace')
5300
5301 # write to memory
5302 self.shm.seek(start * self.char_width)
5303
5304 if self.fixed_length:
5305 self.shm.write(tb)
5306 else:
5307 self.shm.write(tb + self.TERMINATOR)
5308
5309
5310 def clear(self, start=0):
5311 """ Clear memory block using self.fill_char. """
5312
5313 self.shm.seek(start)
5314
5315 if self.fixed_length:
5316 self.shm.write(str(self.fill_char * self.mem_size * self.char_width).encode(self.encoding))
5317 else:
5318 self.shm.write(self.TERMINATOR)
5319
5320
5321 def close(self):
5322 """ Close/destroy memory block. """
5323
5324 self.shm.close()
5325
5326
5327autoload/conque_term/conque_sole_subprocess.py [[[1
5328762
5329# FILE: autoload/conque_term/conque_sole_subprocess.py
5330# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
5331# WEBSITE: http://conque.googlecode.com
5332# MODIFIED: 2011-09-12
5333# VERSION: 2.3, for Vim 7.0
5334# LICENSE:
5335# Conque - Vim terminal/console emulator
5336# Copyright (C) 2009-2011 Nico Raffo
5337#
5338# MIT License
5339#
5340# Permission is hereby granted, free of charge, to any person obtaining a copy
5341# of this software and associated documentation files (the "Software"), to deal
5342# in the Software without restriction, including without limitation the rights
5343# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
5344# copies of the Software, and to permit persons to whom the Software is
5345# furnished to do so, subject to the following conditions:
5346#
5347# The above copyright notice and this permission notice shall be included in
5348# all copies or substantial portions of the Software.
5349#
5350# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
5351# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
5352# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
5353# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
5354# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
5355# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
5356# THE SOFTWARE.
5357
5358""" ConqueSoleSubprocess
5359
5360Creates a new subprocess with it's own (hidden) console window.
5361
5362Mirrors console window text onto a block of shared memory (mmap), along with
5363text attribute data. Also handles translation of text input into the format
5364Windows console expects.
5365
5366Sample Usage:
5367
5368 sh = ConqueSoleSubprocess()
5369 sh.open("cmd.exe", "unique_str")
5370
5371 shm_in = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "input", ...)
5372 shm_out = ConqueSoleSharedMemory(mem_key = "unique_str", mem_type = "output", ...)
5373
5374 output = shm_out.read(...)
5375 shm_in.write("dir\r")
5376 output = shm_out.read(...)
5377
5378"""
5379
5380import time
5381import re
5382import os
5383import ctypes
5384
5385from conque_globals import *
5386from conque_win32_util import *
5387from conque_sole_shared_memory import *
5388
5389
5390class ConqueSoleSubprocess():
5391
5392 # subprocess handle and pid
5393 handle = None
5394 pid = None
5395
5396 # input / output handles
5397 stdin = None
5398 stdout = None
5399
5400 # size of console window
5401 window_width = 160
5402 window_height = 40
5403
5404 # max lines for the console buffer
5405 buffer_width = 160
5406 buffer_height = 100
5407
5408 # keep track of the buffer number at the top of the window
5409 top = 0
5410 line_offset = 0
5411
5412 # buffer height is CONQUE_SOLE_BUFFER_LENGTH * output_blocks
5413 output_blocks = 1
5414
5415 # cursor position
5416 cursor_line = 0
5417 cursor_col = 0
5418
5419 # console data, array of lines
5420 data = []
5421
5422 # console attribute data, array of array of int
5423 attributes = []
5424 attribute_cache = {}
5425
5426 # default attribute
5427 default_attribute = 7
5428
5429 # shared memory objects
5430 shm_input = None
5431 shm_output = None
5432 shm_attributes = None
5433 shm_stats = None
5434 shm_command = None
5435 shm_rescroll = None
5436 shm_resize = None
5437
5438 # are we still a valid process?
5439 is_alive = True
5440
5441 # running in fast mode
5442 fast_mode = 0
5443
5444 # used for periodic execution of screen and memory redrawing
5445 screen_redraw_ct = 0
5446 mem_redraw_ct = 0
5447
5448
5449 def open(self, cmd, mem_key, options={}):
5450 """ Create subproccess running in hidden console window. """
5451
5452
5453
5454 self.reset = True
5455
5456 try:
5457 # if we're already attached to a console, then unattach
5458 try:
5459 ctypes.windll.kernel32.FreeConsole()
5460 except:
5461 pass
5462
5463 # set buffer height
5464 self.buffer_height = CONQUE_SOLE_BUFFER_LENGTH
5465
5466 if 'LINES' in options and 'COLUMNS' in options:
5467 self.window_width = options['COLUMNS']
5468 self.window_height = options['LINES']
5469 self.buffer_width = options['COLUMNS']
5470
5471 # fast mode
5472 self.fast_mode = options['FAST_MODE']
5473
5474 # console window options
5475 si = STARTUPINFO()
5476
5477 # hide window
5478 si.dwFlags |= STARTF_USESHOWWINDOW
5479 si.wShowWindow = SW_HIDE
5480 #si.wShowWindow = SW_MINIMIZE
5481
5482 # process options
5483 flags = NORMAL_PRIORITY_CLASS | CREATE_NEW_PROCESS_GROUP | CREATE_UNICODE_ENVIRONMENT | CREATE_NEW_CONSOLE
5484
5485 # created process info
5486 pi = PROCESS_INFORMATION()
5487
5488
5489
5490 # create the process!
5491 res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi))
5492
5493
5494
5495
5496
5497 # process info
5498 self.pid = pi.dwProcessId
5499 self.handle = pi.hProcess
5500
5501
5502
5503
5504 # attach ourselves to the new console
5505 # console is not immediately available
5506 for i in range(10):
5507 time.sleep(0.25)
5508 try:
5509
5510 res = ctypes.windll.kernel32.AttachConsole(self.pid)
5511
5512
5513
5514
5515
5516
5517 break
5518 except:
5519
5520 pass
5521
5522 # get input / output handles
5523 self.stdout = ctypes.windll.kernel32.GetStdHandle(STD_OUTPUT_HANDLE)
5524 self.stdin = ctypes.windll.kernel32.GetStdHandle(STD_INPUT_HANDLE)
5525
5526 # set buffer size
5527 size = COORD(self.buffer_width, self.buffer_height)
5528 res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size)
5529
5530
5531
5532
5533
5534
5535
5536 # prev set size call needs to process
5537 time.sleep(0.2)
5538
5539 # set window size
5540 self.set_window_size(self.window_width, self.window_height)
5541
5542 # set utf-8 code page
5543 if 'CODE_PAGE' in options and options['CODE_PAGE'] > 0:
5544 if ctypes.windll.kernel32.IsValidCodePage(ctypes.c_uint(options['CODE_PAGE'])):
5545
5546 ctypes.windll.kernel32.SetConsoleCP(ctypes.c_uint(options['CODE_PAGE']))
5547 ctypes.windll.kernel32.SetConsoleOutputCP(ctypes.c_uint(options['CODE_PAGE']))
5548
5549 # init shared memory
5550 self.init_shared_memory(mem_key)
5551
5552 # init read buffers
5553 self.tc = ctypes.create_unicode_buffer(self.buffer_width)
5554 self.ac = ctypes.create_unicode_buffer(self.buffer_width)
5555
5556 return True
5557
5558 except:
5559
5560 return False
5561
5562
5563 def init_shared_memory(self, mem_key):
5564 """ Create shared memory objects. """
5565
5566 self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key)
5567 self.shm_input.create('write')
5568 self.shm_input.clear()
5569
5570 self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'output', mem_key, True)
5571 self.shm_output.create('write')
5572 self.shm_output.clear()
5573
5574 if not self.fast_mode:
5575 buf_info = self.get_buffer_info()
5576 self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1')
5577 self.shm_attributes.create('write')
5578 self.shm_attributes.clear()
5579
5580 self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True)
5581 self.shm_stats.create('write')
5582 self.shm_stats.clear()
5583
5584 self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
5585 self.shm_command.create('write')
5586 self.shm_command.clear()
5587
5588 self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True)
5589 self.shm_resize.create('write')
5590 self.shm_resize.clear()
5591
5592 self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True)
5593 self.shm_rescroll.create('write')
5594 self.shm_rescroll.clear()
5595
5596 return True
5597
5598
5599 def check_commands(self):
5600 """ Check for and process commands from Vim. """
5601
5602 cmd = self.shm_command.read()
5603
5604 if cmd:
5605
5606 # shut it all down
5607 if cmd['cmd'] == 'close':
5608
5609 # clear command
5610 self.shm_command.clear()
5611
5612 self.close()
5613 return
5614
5615 cmd = self.shm_resize.read()
5616
5617 if cmd:
5618
5619 # clear command
5620 self.shm_resize.clear()
5621
5622 # resize console
5623 if cmd['cmd'] == 'resize':
5624
5625
5626
5627 # only change buffer width if it's larger
5628 if cmd['data']['width'] > self.buffer_width:
5629 self.buffer_width = cmd['data']['width']
5630
5631 # always change console width and height
5632 self.window_width = cmd['data']['width']
5633 self.window_height = cmd['data']['height']
5634
5635 # reset the console
5636 buf_info = self.get_buffer_info()
5637 self.reset_console(buf_info, add_block=False)
5638
5639
5640 def read(self):
5641 """ Read from windows console and update shared memory blocks. """
5642
5643 # no point really
5644 if self.screen_redraw_ct == 0 and not self.is_alive():
5645 stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0}
5646
5647 self.shm_stats.write(stats)
5648 return
5649
5650 # check for commands
5651 self.check_commands()
5652
5653 # get cursor position
5654 buf_info = self.get_buffer_info()
5655 curs_line = buf_info.dwCursorPosition.Y
5656 curs_col = buf_info.dwCursorPosition.X
5657
5658 # set update range
5659 if curs_line != self.cursor_line or self.top != buf_info.srWindow.Top or self.screen_redraw_ct == CONQUE_SOLE_SCREEN_REDRAW:
5660 self.screen_redraw_ct = 0
5661
5662 read_start = self.top
5663 read_end = max([buf_info.srWindow.Bottom + 1, curs_line + 1])
5664 else:
5665
5666 read_start = curs_line
5667 read_end = curs_line + 1
5668
5669
5670
5671
5672 # vars used in for loop
5673 coord = COORD(0, 0)
5674 chars_read = ctypes.c_int(0)
5675
5676 # read new data
5677 for i in range(read_start, read_end):
5678
5679 coord.Y = i
5680
5681 res = ctypes.windll.kernel32.ReadConsoleOutputCharacterW(self.stdout, ctypes.byref(self.tc), self.buffer_width, coord, ctypes.byref(chars_read))
5682 if not self.fast_mode:
5683 ctypes.windll.kernel32.ReadConsoleOutputAttribute(self.stdout, ctypes.byref(self.ac), self.buffer_width, coord, ctypes.byref(chars_read))
5684
5685 t = self.tc.value
5686 if not self.fast_mode:
5687 a = self.ac.value
5688
5689 # add data
5690 if i >= len(self.data):
5691 for j in range(len(self.data), i + 1):
5692 self.data.append('')
5693 if not self.fast_mode:
5694 self.attributes.append('')
5695
5696 self.data[i] = t
5697 if not self.fast_mode:
5698 self.attributes[i] = a
5699
5700
5701
5702
5703 #for i in range(0, len(t)):
5704
5705
5706
5707
5708 # write new output to shared memory
5709 try:
5710 if self.mem_redraw_ct == CONQUE_SOLE_MEM_REDRAW:
5711 self.mem_redraw_ct = 0
5712
5713 for i in range(0, len(self.data)):
5714 self.shm_output.write(text=self.data[i], start=self.buffer_width * i)
5715 if not self.fast_mode:
5716 self.shm_attributes.write(text=self.attributes[i], start=self.buffer_width * i)
5717 else:
5718
5719 for i in range(read_start, read_end):
5720 self.shm_output.write(text=self.data[i], start=self.buffer_width * i)
5721 if not self.fast_mode:
5722 self.shm_attributes.write(text=self.attributes[i], start=self.buffer_width * i)
5723 #self.shm_output.write(text=''.join(self.data[read_start:read_end]), start=read_start * self.buffer_width)
5724 #self.shm_attributes.write(text=''.join(self.attributes[read_start:read_end]), start=read_start * self.buffer_width)
5725
5726 # write cursor position to shared memory
5727 stats = {'top_offset': buf_info.srWindow.Top, 'default_attribute': buf_info.wAttributes, 'cursor_x': curs_col, 'cursor_y': curs_line, 'is_alive': 1}
5728 self.shm_stats.write(stats)
5729
5730 # adjust screen position
5731 self.top = buf_info.srWindow.Top
5732 self.cursor_line = curs_line
5733
5734 # check for reset
5735 if curs_line > buf_info.dwSize.Y - 200:
5736 self.reset_console(buf_info)
5737
5738 except:
5739
5740
5741
5742
5743 pass
5744
5745 # increment redraw counters
5746 self.screen_redraw_ct += 1
5747 self.mem_redraw_ct += 1
5748
5749 return None
5750
5751
5752 def reset_console(self, buf_info, add_block=True):
5753 """ Extend the height of the current console if the cursor postion gets within 200 lines of the current size. """
5754
5755 # sometimes we just want to change the buffer width,
5756 # in which case no need to add another block
5757 if add_block:
5758 self.output_blocks += 1
5759
5760 # close down old memory
5761 self.shm_output.close()
5762 self.shm_output = None
5763
5764 if not self.fast_mode:
5765 self.shm_attributes.close()
5766 self.shm_attributes = None
5767
5768 # new shared memory key
5769 mem_key = 'mk' + str(time.time())
5770
5771 # reallocate memory
5772 self.shm_output = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'output', mem_key, True)
5773 self.shm_output.create('write')
5774 self.shm_output.clear()
5775
5776 # backfill data
5777 if len(self.data[0]) < self.buffer_width:
5778 for i in range(0, len(self.data)):
5779 self.data[i] = self.data[i] + ' ' * (self.buffer_width - len(self.data[i]))
5780 self.shm_output.write(''.join(self.data))
5781
5782 if not self.fast_mode:
5783 self.shm_attributes = ConqueSoleSharedMemory(self.buffer_height * self.buffer_width * self.output_blocks, 'attributes', mem_key, True, chr(buf_info.wAttributes), encoding='latin-1')
5784 self.shm_attributes.create('write')
5785 self.shm_attributes.clear()
5786
5787 # backfill attributes
5788 if len(self.attributes[0]) < self.buffer_width:
5789 for i in range(0, len(self.attributes)):
5790 self.attributes[i] = self.attributes[i] + chr(buf_info.wAttributes) * (self.buffer_width - len(self.attributes[i]))
5791 if not self.fast_mode:
5792 self.shm_attributes.write(''.join(self.attributes))
5793
5794 # notify wrapper of new output block
5795 self.shm_rescroll.write({'cmd': 'new_output', 'data': {'blocks': self.output_blocks, 'mem_key': mem_key}})
5796
5797 # set buffer size
5798 size = COORD(X=self.buffer_width, Y=self.buffer_height * self.output_blocks)
5799
5800 res = ctypes.windll.kernel32.SetConsoleScreenBufferSize(self.stdout, size)
5801
5802
5803
5804
5805
5806
5807 # prev set size call needs to process
5808 time.sleep(0.2)
5809
5810 # set window size
5811 self.set_window_size(self.window_width, self.window_height)
5812
5813 # init read buffers
5814 self.tc = ctypes.create_unicode_buffer(self.buffer_width)
5815 self.ac = ctypes.create_unicode_buffer(self.buffer_width)
5816
5817
5818
5819 def write(self):
5820 """ Write text to console.
5821
5822 This function just parses out special sequences for special key events
5823 and passes on the text to the plain or virtual key functions.
5824
5825 """
5826 # get input from shared mem
5827 text = self.shm_input.read()
5828
5829 # nothing to do here
5830 if text == u(''):
5831 return
5832
5833
5834
5835 # clear input queue
5836 self.shm_input.clear()
5837
5838 # split on VK codes
5839 chunks = CONQUE_WIN32_REGEX_VK.split(text)
5840
5841 # if len() is one then no vks
5842 if len(chunks) == 1:
5843 self.write_plain(text)
5844 return
5845
5846
5847
5848 # loop over chunks and delegate
5849 for t in chunks:
5850
5851 if t == '':
5852 continue
5853
5854 if CONQUE_WIN32_REGEX_VK.match(t):
5855
5856 self.write_vk(t[2:-2])
5857 else:
5858 self.write_plain(t)
5859
5860
5861 def write_plain(self, text):
5862 """ Write simple text to subprocess. """
5863
5864 li = INPUT_RECORD * len(text)
5865 list_input = li()
5866
5867 for i in range(0, len(text)):
5868
5869 # create keyboard input
5870 ke = KEY_EVENT_RECORD()
5871 ke.bKeyDown = ctypes.c_byte(1)
5872 ke.wRepeatCount = ctypes.c_short(1)
5873
5874 cnum = ord(text[i])
5875
5876 ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum)
5877 ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(cnum), 0))
5878
5879 if cnum > 31:
5880 ke.uChar.UnicodeChar = uchr(cnum)
5881 elif cnum == 3:
5882 ctypes.windll.kernel32.GenerateConsoleCtrlEvent(0, self.pid)
5883 ke.uChar.UnicodeChar = uchr(cnum)
5884 ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96)
5885 ke.dwControlKeyState |= LEFT_CTRL_PRESSED
5886 else:
5887 ke.uChar.UnicodeChar = uchr(cnum)
5888 if cnum in CONQUE_WINDOWS_VK_INV:
5889 ke.wVirtualKeyCode = cnum
5890 else:
5891 ke.wVirtualKeyCode = ctypes.windll.user32.VkKeyScanW(cnum + 96)
5892 ke.dwControlKeyState |= LEFT_CTRL_PRESSED
5893
5894
5895
5896
5897 kc = INPUT_RECORD(KEY_EVENT)
5898 kc.Event.KeyEvent = ke
5899 list_input[i] = kc
5900
5901
5902
5903 # write input array
5904 events_written = ctypes.c_int()
5905 res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, len(text), ctypes.byref(events_written))
5906
5907
5908
5909
5910
5911
5912
5913
5914 def write_vk(self, vk_code):
5915 """ Write special characters to console subprocess. """
5916
5917
5918
5919 code = None
5920 ctrl_pressed = False
5921
5922 # this could be made more generic when more attributes
5923 # other than ctrl_pressed are available
5924 vk_attributes = vk_code.split(';')
5925
5926 for attr in vk_attributes:
5927 if attr == CONQUE_VK_ATTR_CTRL_PRESSED:
5928 ctrl_pressed = True
5929 else:
5930 code = attr
5931
5932 li = INPUT_RECORD * 1
5933
5934 # create keyboard input
5935 ke = KEY_EVENT_RECORD()
5936 ke.uChar.UnicodeChar = uchr(0)
5937 ke.wVirtualKeyCode = ctypes.c_short(int(code))
5938 ke.wVirtualScanCode = ctypes.c_short(ctypes.windll.user32.MapVirtualKeyW(int(code), 0))
5939 ke.bKeyDown = ctypes.c_byte(1)
5940 ke.wRepeatCount = ctypes.c_short(1)
5941
5942 # set enhanced key mode for arrow keys
5943 if code in CONQUE_WINDOWS_VK_ENHANCED:
5944
5945 ke.dwControlKeyState |= ENHANCED_KEY
5946
5947 if ctrl_pressed:
5948 ke.dwControlKeyState |= LEFT_CTRL_PRESSED
5949
5950 kc = INPUT_RECORD(KEY_EVENT)
5951 kc.Event.KeyEvent = ke
5952 list_input = li(kc)
5953
5954 # write input array
5955 events_written = ctypes.c_int()
5956 res = ctypes.windll.kernel32.WriteConsoleInputW(self.stdin, list_input, 1, ctypes.byref(events_written))
5957
5958
5959
5960
5961
5962
5963
5964 def close(self):
5965 """ Close all running subproccesses """
5966
5967 # record status
5968 self.is_alive = False
5969 try:
5970 stats = {'top_offset': 0, 'default_attribute': 0, 'cursor_x': 0, 'cursor_y': self.cursor_line, 'is_alive': 0}
5971 self.shm_stats.write(stats)
5972 except:
5973 pass
5974
5975 pid_list = (ctypes.c_int * 10)()
5976 num = ctypes.windll.kernel32.GetConsoleProcessList(pid_list, 10)
5977
5978
5979
5980 current_pid = os.getpid()
5981
5982
5983
5984
5985
5986 # kill subprocess pids
5987 for pid in pid_list[0:num]:
5988 if not pid:
5989 break
5990
5991 # kill current pid last
5992 if pid == current_pid:
5993 continue
5994 try:
5995 self.close_pid(pid)
5996 except:
5997
5998 pass
5999
6000 # kill this process
6001 try:
6002 self.close_pid(current_pid)
6003 except:
6004
6005 pass
6006
6007
6008 def close_pid(self, pid):
6009 """ Terminate a single process. """
6010
6011
6012 handle = ctypes.windll.kernel32.OpenProcess(PROCESS_TERMINATE, 0, pid)
6013 ctypes.windll.kernel32.TerminateProcess(handle, -1)
6014 ctypes.windll.kernel32.CloseHandle(handle)
6015
6016
6017 def is_alive(self):
6018 """ Check process health. """
6019
6020 status = ctypes.windll.kernel32.WaitForSingleObject(self.handle, 1)
6021
6022 if status == 0:
6023
6024 self.is_alive = False
6025
6026 return self.is_alive
6027
6028
6029 def get_screen_text(self):
6030 """ Return screen data as string. """
6031
6032 return "\n".join(self.data)
6033
6034
6035 def set_window_size(self, width, height):
6036 """ Change Windows console size. """
6037
6038
6039
6040 # get current window size object
6041 window_size = SMALL_RECT(0, 0, 0, 0)
6042
6043 # buffer info has maximum window size data
6044 buf_info = self.get_buffer_info()
6045
6046
6047 # set top left corner
6048 window_size.Top = 0
6049 window_size.Left = 0
6050
6051 # set bottom right corner
6052 if buf_info.dwMaximumWindowSize.X < width:
6053
6054 window_size.Right = buf_info.dwMaximumWindowSize.X - 1
6055 else:
6056 window_size.Right = width - 1
6057
6058 if buf_info.dwMaximumWindowSize.Y < height:
6059
6060 window_size.Bottom = buf_info.dwMaximumWindowSize.Y - 1
6061 else:
6062 window_size.Bottom = height - 1
6063
6064
6065
6066 # set the window size!
6067 res = ctypes.windll.kernel32.SetConsoleWindowInfo(self.stdout, ctypes.c_bool(True), ctypes.byref(window_size))
6068
6069
6070
6071
6072
6073
6074 # reread buffer info to get final console max lines
6075 buf_info = self.get_buffer_info()
6076
6077 self.window_width = buf_info.srWindow.Right + 1
6078 self.window_height = buf_info.srWindow.Bottom + 1
6079
6080
6081 def get_buffer_info(self):
6082 """ Retrieve commonly-used buffer information. """
6083
6084 buf_info = CONSOLE_SCREEN_BUFFER_INFO()
6085 ctypes.windll.kernel32.GetConsoleScreenBufferInfo(self.stdout, ctypes.byref(buf_info))
6086
6087 return buf_info
6088
6089
6090
6091autoload/conque_term/conque_sole_wrapper.py [[[1
6092278
6093# FILE: autoload/conque_term/conque_sole_wrapper.py
6094# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
6095# WEBSITE: http://conque.googlecode.com
6096# MODIFIED: 2011-09-12
6097# VERSION: 2.3, for Vim 7.0
6098# LICENSE:
6099# Conque - Vim terminal/console emulator
6100# Copyright (C) 2009-2011 Nico Raffo
6101#
6102# MIT License
6103#
6104# Permission is hereby granted, free of charge, to any person obtaining a copy
6105# of this software and associated documentation files (the "Software"), to deal
6106# in the Software without restriction, including without limitation the rights
6107# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6108# copies of the Software, and to permit persons to whom the Software is
6109# furnished to do so, subject to the following conditions:
6110#
6111# The above copyright notice and this permission notice shall be included in
6112# all copies or substantial portions of the Software.
6113#
6114# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6115# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6116# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6117# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6118# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6119# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
6120# THE SOFTWARE.
6121
6122"""
6123
6124ConqueSoleSubprocessWrapper
6125
6126Subprocess wrapper to deal with Windows insanity. Launches console based python,
6127which in turn launches originally requested command. Communicates with cosole
6128python through shared memory objects.
6129
6130"""
6131
6132import ctypes
6133import time
6134
6135
6136class ConqueSoleWrapper():
6137
6138 # unique key used for shared memory block names
6139 shm_key = ''
6140
6141 # process info
6142 handle = None
6143 pid = None
6144
6145 # queue input in this bucket
6146 bucket = None
6147
6148 # console size
6149 lines = 24
6150 columns = 80
6151
6152 # shared memory objects
6153 shm_input = None
6154 shm_output = None
6155 shm_attributes = None
6156 shm_stats = None
6157 shm_command = None
6158 shm_rescroll = None
6159 shm_resize = None
6160
6161 # console python process
6162 proc = None
6163
6164
6165 def open(self, cmd, lines, columns, python_exe='python.exe', communicator_py='conque_sole_communicator.py', options={}):
6166 """ Launch python.exe subprocess which will in turn launch the user's program.
6167
6168 Arguments:
6169 cmd -- The user's command to run. E.g. "Powershell.exe" or "C:\Python27\Scripts\ipython.bat"
6170 lines, columns -- The size of the console, also the size of the Vim buffer
6171 python.exe -- The path to the python executable, typically C:\PythonXX\python.exe
6172 communicator_py -- The path to the subprocess controller script in the user's vimfiles directory
6173 options -- optional configuration
6174
6175 """
6176 self.lines = lines
6177 self.columns = columns
6178 self.bucket = u('')
6179
6180 # create a shm key
6181 self.shm_key = 'mk' + str(time.time())
6182
6183 # python command
6184 cmd_line = '%s "%s" %s %d %d %d %d %s' % (python_exe, communicator_py, self.shm_key, int(self.columns), int(self.lines), int(options['CODE_PAGE']), int(CONQUE_FAST_MODE), cmd)
6185
6186
6187 # console window attributes
6188 flags = NORMAL_PRIORITY_CLASS | DETACHED_PROCESS | CREATE_UNICODE_ENVIRONMENT
6189 si = STARTUPINFO()
6190 pi = PROCESS_INFORMATION()
6191
6192 # start the stupid process already
6193 try:
6194 res = ctypes.windll.kernel32.CreateProcessW(None, u(cmd_line), None, None, 0, flags, None, u('.'), ctypes.byref(si), ctypes.byref(pi))
6195 except:
6196
6197 raise
6198
6199 # handle
6200 self.pid = pi.dwProcessId
6201
6202
6203
6204 # init shared memory objects
6205 self.init_shared_memory(self.shm_key)
6206
6207
6208 def read(self, start_line, num_lines, timeout=0):
6209 """ Read a range of console lines from shared memory.
6210
6211 Returns a pair of lists containing the console text and console text attributes.
6212
6213 """
6214 # emulate timeout by sleeping timeout time
6215 if timeout > 0:
6216 read_timeout = float(timeout) / 1000
6217
6218 time.sleep(read_timeout)
6219
6220 output = []
6221 attributes = []
6222
6223 # get output
6224 for i in range(start_line, start_line + num_lines + 1):
6225 output.append(self.shm_output.read(self.columns, i * self.columns))
6226 if not CONQUE_FAST_MODE:
6227 attributes.append(self.shm_attributes.read(self.columns, i * self.columns))
6228
6229 return (output, attributes)
6230
6231
6232 def get_stats(self):
6233 """ Return a dictionary with current console cursor and scrolling information. """
6234
6235 try:
6236 rescroll = self.shm_rescroll.read()
6237 if rescroll != '' and rescroll != None:
6238
6239
6240
6241 self.shm_rescroll.clear()
6242
6243 # close down old memory
6244 self.shm_output.close()
6245 self.shm_output = None
6246
6247 if not CONQUE_FAST_MODE:
6248 self.shm_attributes.close()
6249 self.shm_attributes = None
6250
6251 # reallocate memory
6252
6253 self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'output', rescroll['data']['mem_key'], True)
6254 self.shm_output.create('read')
6255
6256 if not CONQUE_FAST_MODE:
6257 self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns * rescroll['data']['blocks'], 'attributes', rescroll['data']['mem_key'], True, encoding='latin-1')
6258 self.shm_attributes.create('read')
6259
6260 stats_str = self.shm_stats.read()
6261 if stats_str != '':
6262 self.stats = stats_str
6263 else:
6264 return False
6265 except:
6266
6267 return False
6268
6269 return self.stats
6270
6271
6272 def is_alive(self):
6273 """ Get process status. """
6274
6275 if not self.shm_stats:
6276 return True
6277
6278 stats_str = self.shm_stats.read()
6279 if stats_str:
6280 return (stats_str['is_alive'])
6281 else:
6282 return True
6283
6284
6285 def write(self, text):
6286 """ Write input to shared memory. """
6287
6288 self.bucket += text
6289
6290 istr = self.shm_input.read()
6291
6292 if istr == '':
6293
6294 self.shm_input.write(self.bucket[:500])
6295 self.bucket = self.bucket[500:]
6296
6297
6298 def write_vk(self, vk_code):
6299 """ Write virtual key code to shared memory using proprietary escape sequences. """
6300
6301 seq = u("\x1b[") + u(str(vk_code)) + u("VK")
6302 self.write(seq)
6303
6304
6305 def idle(self):
6306 """ Write idle command to shared memory block, so subprocess controller can hibernate. """
6307
6308
6309 self.shm_command.write({'cmd': 'idle', 'data': {}})
6310
6311
6312 def resume(self):
6313 """ Write resume command to shared memory block, so subprocess controller can wake up. """
6314
6315 self.shm_command.write({'cmd': 'resume', 'data': {}})
6316
6317
6318 def close(self):
6319 """ Shut it all down. """
6320
6321 self.shm_command.write({'cmd': 'close', 'data': {}})
6322 time.sleep(0.2)
6323
6324
6325 def window_resize(self, lines, columns):
6326 """ Resize console window. """
6327
6328 self.lines = lines
6329
6330 # we don't shrink buffer width
6331 if columns > self.columns:
6332 self.columns = columns
6333
6334 self.shm_resize.write({'cmd': 'resize', 'data': {'width': columns, 'height': lines}})
6335
6336
6337 def init_shared_memory(self, mem_key):
6338 """ Create shared memory objects. """
6339
6340 self.shm_input = ConqueSoleSharedMemory(CONQUE_SOLE_INPUT_SIZE, 'input', mem_key)
6341 self.shm_input.create('write')
6342 self.shm_input.clear()
6343
6344 self.shm_output = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'output', mem_key, True)
6345 self.shm_output.create('write')
6346
6347 if not CONQUE_FAST_MODE:
6348 self.shm_attributes = ConqueSoleSharedMemory(CONQUE_SOLE_BUFFER_LENGTH * self.columns, 'attributes', mem_key, True, encoding='latin-1')
6349 self.shm_attributes.create('write')
6350
6351 self.shm_stats = ConqueSoleSharedMemory(CONQUE_SOLE_STATS_SIZE, 'stats', mem_key, serialize=True)
6352 self.shm_stats.create('write')
6353 self.shm_stats.clear()
6354
6355 self.shm_command = ConqueSoleSharedMemory(CONQUE_SOLE_COMMANDS_SIZE, 'command', mem_key, serialize=True)
6356 self.shm_command.create('write')
6357 self.shm_command.clear()
6358
6359 self.shm_resize = ConqueSoleSharedMemory(CONQUE_SOLE_RESIZE_SIZE, 'resize', mem_key, serialize=True)
6360 self.shm_resize.create('write')
6361 self.shm_resize.clear()
6362
6363 self.shm_rescroll = ConqueSoleSharedMemory(CONQUE_SOLE_RESCROLL_SIZE, 'rescroll', mem_key, serialize=True)
6364 self.shm_rescroll.create('write')
6365 self.shm_rescroll.clear()
6366
6367 return True
6368
6369
6370# vim:foldmethod=marker
6371autoload/conque_term/conque_subprocess.py [[[1
6372213
6373# FILE: autoload/conque_term/conque_subprocess.py
6374# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
6375# WEBSITE: http://conque.googlecode.com
6376# MODIFIED: 2011-09-12
6377# VERSION: 2.3, for Vim 7.0
6378# LICENSE:
6379# Conque - Vim terminal/console emulator
6380# Copyright (C) 2009-2011 Nico Raffo
6381#
6382# MIT License
6383#
6384# Permission is hereby granted, free of charge, to any person obtaining a copy
6385# of this software and associated documentation files (the "Software"), to deal
6386# in the Software without restriction, including without limitation the rights
6387# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6388# copies of the Software, and to permit persons to whom the Software is
6389# furnished to do so, subject to the following conditions:
6390#
6391# The above copyright notice and this permission notice shall be included in
6392# all copies or substantial portions of the Software.
6393#
6394# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6395# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6396# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6397# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6398# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6399# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
6400# THE SOFTWARE.
6401
6402"""
6403ConqueSubprocess
6404
6405Create and interact with a subprocess through a pty.
6406
6407Usage:
6408
6409 p = ConqueSubprocess()
6410 p.open('bash', {'TERM':'vt100'})
6411 output = p.read()
6412 p.write('cd ~/vim' + "\r")
6413 p.write('ls -lha' + "\r")
6414 output += p.read(timeout = 500)
6415 p.close()
6416"""
6417
6418import os
6419import signal
6420import pty
6421import tty
6422import select
6423import fcntl
6424import termios
6425import struct
6426import shlex
6427
6428class ConqueSubprocess:
6429
6430 # process id
6431 pid = 0
6432
6433 # stdout+stderr file descriptor
6434 fd = None
6435
6436
6437 def open(self, command, env={}):
6438 """ Create subprocess using forkpty() """
6439
6440 # parse command
6441 command_arr = shlex.split(command)
6442 executable = command_arr[0]
6443 args = command_arr
6444
6445
6446 # try to fork a new pty
6447 try:
6448 self.pid, self.fd = pty.fork()
6449
6450 except:
6451
6452 return False
6453
6454 # child proc, replace with command after altering terminal attributes
6455 if self.pid == 0:
6456
6457 # Set signals to default values in child
6458 try:
6459 signal.signal(signal.SIGCHLD, signal.SIG_DFL)
6460 except:
6461 pass
6462
6463 try:
6464 signal.signal(signal.SIGHUP, signal.SIG_DFL)
6465 except:
6466 pass
6467
6468 # set requested environment variables
6469 for k in env.keys():
6470 os.environ[k] = env[k]
6471
6472 # set tty attributes
6473 try:
6474 attrs = tty.tcgetattr(1)
6475 attrs[0] = attrs[0] ^ tty.IGNBRK
6476 attrs[0] = attrs[0] | tty.BRKINT | tty.IXANY | tty.IMAXBEL
6477 attrs[2] = attrs[2] | tty.HUPCL
6478 attrs[3] = attrs[3] | tty.ICANON | tty.ECHO | tty.ISIG | tty.ECHOKE
6479 attrs[6][tty.VMIN] = 1
6480 attrs[6][tty.VTIME] = 0
6481 tty.tcsetattr(1, tty.TCSANOW, attrs)
6482 except:
6483
6484 pass
6485
6486 # replace this process with the subprocess
6487 os.execvp(executable, args)
6488
6489 # else master, do nothing
6490 else:
6491 pass
6492
6493
6494 def read(self, timeout=1):
6495 """ Read from subprocess and return new output """
6496
6497 output = ''
6498 read_timeout = float(timeout) / 1000
6499 read_ct = 0
6500
6501 try:
6502 # read from fd until no more output
6503 while 1:
6504 s_read, s_write, s_error = select.select([self.fd], [], [], read_timeout)
6505
6506 lines = ''
6507 for s_fd in s_read:
6508 try:
6509 # increase read buffer so huge reads don't slow down
6510 if read_ct < 10:
6511 lines = os.read(self.fd, 32)
6512 elif read_ct < 50:
6513 lines = os.read(self.fd, 512)
6514 else:
6515 lines = os.read(self.fd, 2048)
6516 read_ct += 1
6517 except:
6518 pass
6519 output = output + lines.decode('utf-8')
6520
6521 if lines == '' or read_ct > 100:
6522 break
6523 except:
6524
6525 pass
6526
6527 return output
6528
6529
6530 def write(self, input):
6531 """ Write new input to subprocess """
6532
6533 try:
6534 if CONQUE_PYTHON_VERSION == 2:
6535 os.write(self.fd, input.encode('utf-8', 'ignore'))
6536 else:
6537 os.write(self.fd, bytes(input, 'utf-8'))
6538 except:
6539
6540 pass
6541
6542
6543 def signal(self, signum):
6544 """ signal process """
6545
6546 try:
6547 os.kill(self.pid, signum)
6548 except:
6549 pass
6550
6551
6552 def close(self):
6553 """ close process with sigterm signal """
6554
6555 self.signal(15)
6556
6557
6558 def is_alive(self):
6559 """ get process status """
6560
6561 p_status = True
6562 try:
6563 if os.waitpid(self.pid, os.WNOHANG)[0]:
6564 p_status = False
6565 except:
6566 p_status = False
6567
6568 return p_status
6569
6570
6571 def window_resize(self, lines, columns):
6572 """ update window size in kernel, then send SIGWINCH to fg process """
6573
6574 try:
6575 fcntl.ioctl(self.fd, termios.TIOCSWINSZ, struct.pack("HHHH", lines, columns, 0, 0))
6576 os.kill(self.pid, signal.SIGWINCH)
6577 except:
6578 pass
6579
6580
6581 def getpid(self):
6582 return self.pid;
6583
6584
6585# vim:foldmethod=marker
6586autoload/conque_term/conque_win32_util.py [[[1
6587448
6588# FILE: autoload/conque_term/conque_win32_util.py
6589# AUTHOR: Nico Raffo <nicoraffo@gmail.com>
6590# WEBSITE: http://conque.googlecode.com
6591# MODIFIED: 2011-09-12
6592# VERSION: 2.3, for Vim 7.0
6593# LICENSE:
6594# Conque - Vim terminal/console emulator
6595# Copyright (C) 2009-2011 Nico Raffo
6596#
6597# MIT License
6598#
6599# Permission is hereby granted, free of charge, to any person obtaining a copy
6600# of this software and associated documentation files (the "Software"), to deal
6601# in the Software without restriction, including without limitation the rights
6602# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
6603# copies of the Software, and to permit persons to whom the Software is
6604# furnished to do so, subject to the following conditions:
6605#
6606# The above copyright notice and this permission notice shall be included in
6607# all copies or substantial portions of the Software.
6608#
6609# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
6610# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
6611# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
6612# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
6613# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
6614# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
6615# THE SOFTWARE.
6616
6617""" Python constants and structures used for ctypes interaction. """
6618
6619from ctypes import *
6620
6621# Constants
6622
6623# create process flag constants
6624
6625CREATE_BREAKAWAY_FROM_JOB = 0x01000000
6626CREATE_DEFAULT_ERROR_MODE = 0x04000000
6627CREATE_NEW_CONSOLE = 0x00000010
6628CREATE_NEW_PROCESS_GROUP = 0x00000200
6629CREATE_NO_WINDOW = 0x08000000
6630CREATE_PROTECTED_PROCESS = 0x00040000
6631CREATE_PRESERVE_CODE_AUTHZ_LEVEL = 0x02000000
6632CREATE_SEPARATE_WOW_VDM = 0x00000800
6633CREATE_SHARED_WOW_VDM = 0x00001000
6634CREATE_SUSPENDED = 0x00000004
6635CREATE_UNICODE_ENVIRONMENT = 0x00000400
6636
6637
6638DETACHED_PROCESS = 0x00000008
6639EXTENDED_STARTUPINFO_PRESENT = 0x00080000
6640INHERIT_PARENT_AFFINITY = 0x00010000
6641
6642
6643# process priority constants
6644
6645ABOVE_NORMAL_PRIORITY_CLASS = 0x00008000
6646BELOW_NORMAL_PRIORITY_CLASS = 0x00004000
6647HIGH_PRIORITY_CLASS = 0x00000080
6648IDLE_PRIORITY_CLASS = 0x00000040
6649NORMAL_PRIORITY_CLASS = 0x00000020
6650REALTIME_PRIORITY_CLASS = 0x00000100
6651
6652
6653# startup info constants
6654
6655STARTF_FORCEONFEEDBACK = 0x00000040
6656STARTF_FORCEOFFFEEDBACK = 0x00000080
6657STARTF_PREVENTPINNING = 0x00002000
6658STARTF_RUNFULLSCREEN = 0x00000020
6659STARTF_TITLEISAPPID = 0x00001000
6660STARTF_TITLEISLINKNAME = 0x00000800
6661STARTF_USECOUNTCHARS = 0x00000008
6662STARTF_USEFILLATTRIBUTE = 0x00000010
6663STARTF_USEHOTKEY = 0x00000200
6664STARTF_USEPOSITION = 0x00000004
6665STARTF_USESHOWWINDOW = 0x00000001
6666STARTF_USESIZE = 0x00000002
6667STARTF_USESTDHANDLES = 0x00000100
6668
6669
6670# show window constants
6671
6672SW_FORCEMINIMIZE = 11
6673SW_HIDE = 0
6674SW_MAXIMIZE = 3
6675SW_MINIMIZE = 6
6676SW_RESTORE = 9
6677SW_SHOW = 5
6678SW_SHOWDEFAULT = 10
6679SW_SHOWMAXIMIZED = 3
6680SW_SHOWMINIMIZED = 2
6681SW_SHOWMINNOACTIVE = 7
6682SW_SHOWNA = 8
6683SW_SHOWNOACTIVATE = 4
6684SW_SHOWNORMAL = 1
6685
6686
6687# input event types
6688
6689FOCUS_EVENT = 0x0010
6690KEY_EVENT = 0x0001
6691MENU_EVENT = 0x0008
6692MOUSE_EVENT = 0x0002
6693WINDOW_BUFFER_SIZE_EVENT = 0x0004
6694
6695
6696# key event modifiers
6697
6698CAPSLOCK_ON = 0x0080
6699ENHANCED_KEY = 0x0100
6700LEFT_ALT_PRESSED = 0x0002
6701LEFT_CTRL_PRESSED = 0x0008
6702NUMLOCK_ON = 0x0020
6703RIGHT_ALT_PRESSED = 0x0001
6704RIGHT_CTRL_PRESSED = 0x0004
6705SCROLLLOCK_ON = 0x0040
6706SHIFT_PRESSED = 0x0010
6707
6708
6709# process access
6710
6711PROCESS_CREATE_PROCESS = 0x0080
6712PROCESS_CREATE_THREAD = 0x0002
6713PROCESS_DUP_HANDLE = 0x0040
6714PROCESS_QUERY_INFORMATION = 0x0400
6715PROCESS_QUERY_LIMITED_INFORMATION = 0x1000
6716PROCESS_SET_INFORMATION = 0x0200
6717PROCESS_SET_QUOTA = 0x0100
6718PROCESS_SUSPEND_RESUME = 0x0800
6719PROCESS_TERMINATE = 0x0001
6720PROCESS_VM_OPERATION = 0x0008
6721PROCESS_VM_READ = 0x0010
6722PROCESS_VM_WRITE = 0x0020
6723
6724
6725# input / output handles
6726
6727STD_INPUT_HANDLE = c_ulong(-10)
6728STD_OUTPUT_HANDLE = c_ulong(-11)
6729STD_ERROR_HANDLE = c_ulong(-12)
6730
6731
6732CONQUE_WINDOWS_VK = {
6733 'VK_LBUTTON': 0x0001,
6734 'VK_RBUTTON': 0x0002,
6735 'VK_CANCEL': 0x0003,
6736 'VK_BACK': 0x0008,
6737 'VK_TAB': 0x0009,
6738 'VK_CLEAR': 0x000C,
6739 'VK_RETURN': 0x0D,
6740 'VK_SHIFT': 0x10,
6741 'VK_CONTROL': 0x11,
6742 'VK_MENU': 0x12,
6743 'VK_PAUSE': 0x0013,
6744 'VK_CAPITAL': 0x0014,
6745 'VK_ESCAPE': 0x001B,
6746 'VK_SPACE': 0x0020,
6747 'VK_PRIOR': 0x0021,
6748 'VK_NEXT': 0x0022,
6749 'VK_END': 0x0023,
6750 'VK_HOME': 0x0024,
6751 'VK_LEFT': 0x0025,
6752 'VK_UP': 0x0026,
6753 'VK_RIGHT': 0x0027,
6754 'VK_DOWN': 0x0028,
6755 'VK_SELECT': 0x0029,
6756 'VK_PRINT': 0x002A,
6757 'VK_EXECUTE': 0x002B,
6758 'VK_SNAPSHOT': 0x002C,
6759 'VK_INSERT': 0x002D,
6760 'VK_DELETE': 0x002E,
6761 'VK_HELP': 0x002F,
6762 'VK_0': 0x0030,
6763 'VK_1': 0x0031,
6764 'VK_2': 0x0032,
6765 'VK_3': 0x0033,
6766 'VK_4': 0x0034,
6767 'VK_5': 0x0035,
6768 'VK_6': 0x0036,
6769 'VK_7': 0x0037,
6770 'VK_8': 0x0038,
6771 'VK_9': 0x0039,
6772 'VK_A': 0x0041,
6773 'VK_B': 0x0042,
6774 'VK_C': 0x0043,
6775 'VK_D': 0x0044,
6776 'VK_E': 0x0045,
6777 'VK_F': 0x0046,
6778 'VK_G': 0x0047,
6779 'VK_H': 0x0048,
6780 'VK_I': 0x0049,
6781 'VK_J': 0x004A,
6782 'VK_K': 0x004B,
6783 'VK_L': 0x004C,
6784 'VK_M': 0x004D,
6785 'VK_N': 0x004E,
6786 'VK_O': 0x004F,
6787 'VK_P': 0x0050,
6788 'VK_Q': 0x0051,
6789 'VK_R': 0x0052,
6790 'VK_S': 0x0053,
6791 'VK_T': 0x0054,
6792 'VK_U': 0x0055,
6793 'VK_V': 0x0056,
6794 'VK_W': 0x0057,
6795 'VK_X': 0x0058,
6796 'VK_Y': 0x0059,
6797 'VK_Z': 0x005A,
6798 'VK_LWIN': 0x005B,
6799 'VK_RWIN': 0x005C,
6800 'VK_APPS': 0x005D,
6801 'VK_SLEEP': 0x005F,
6802 'VK_NUMPAD0': 0x0060,
6803 'VK_NUMPAD1': 0x0061,
6804 'VK_NUMPAD2': 0x0062,
6805 'VK_NUMPAD3': 0x0063,
6806 'VK_NUMPAD4': 0x0064,
6807 'VK_NUMPAD5': 0x0065,
6808 'VK_NUMPAD6': 0x0066,
6809 'VK_NUMPAD7': 0x0067,
6810 'VK_NUMPAD8': 0x0068,
6811 'VK_MULTIPLY': 0x006A,
6812 'VK_ADD': 0x006B,
6813 'VK_SEPARATOR': 0x006C,
6814 'VK_SUBTRACT': 0x006D,
6815 'VK_DECIMAL': 0x006E,
6816 'VK_DIVIDE': 0x006F,
6817 'VK_F1': 0x0070,
6818 'VK_F2': 0x0071,
6819 'VK_F3': 0x0072,
6820 'VK_F4': 0x0073,
6821 'VK_F5': 0x0074,
6822 'VK_F6': 0x0075,
6823 'VK_F7': 0x0076,
6824 'VK_F8': 0x0077,
6825 'VK_F9': 0x0078,
6826 'VK_F10': 0x0079,
6827 'VK_F11': 0x007A,
6828 'VK_F12': 0x007B,
6829 'VK_F13': 0x007C,
6830 'VK_F14': 0x007D,
6831 'VK_F15': 0x007E,
6832 'VK_F16': 0x007F,
6833 'VK_F17': 0x0080,
6834 'VK_F18': 0x0081,
6835 'VK_F19': 0x0082,
6836 'VK_F20': 0x0083,
6837 'VK_F21': 0x0084,
6838 'VK_F22': 0x0085,
6839 'VK_F23': 0x0086,
6840 'VK_F24': 0x0087,
6841 'VK_NUMLOCK': 0x0090,
6842 'VK_SCROLL': 0x0091,
6843 'VK_LSHIFT': 0x00A0,
6844 'VK_RSHIFT': 0x00A1,
6845 'VK_LCONTROL': 0x00A2,
6846 'VK_RCONTROL': 0x00A3,
6847 'VK_LMENU': 0x00A4,
6848 'VK_RMENU': 0x00A5
6849}
6850
6851CONQUE_WINDOWS_VK_INV = dict([v, k] for k, v in CONQUE_WINDOWS_VK.items())
6852
6853CONQUE_WINDOWS_VK_ENHANCED = {
6854 str(int(CONQUE_WINDOWS_VK['VK_UP'])): 1,
6855 str(int(CONQUE_WINDOWS_VK['VK_DOWN'])): 1,
6856 str(int(CONQUE_WINDOWS_VK['VK_LEFT'])): 1,
6857 str(int(CONQUE_WINDOWS_VK['VK_RIGHT'])): 1,
6858 str(int(CONQUE_WINDOWS_VK['VK_HOME'])): 1,
6859 str(int(CONQUE_WINDOWS_VK['VK_END'])): 1
6860}
6861
6862
6863# structures used for CreateProcess
6864
6865# Odd types
6866
6867LPBYTE = POINTER(c_ubyte)
6868LPTSTR = POINTER(c_char)
6869
6870
6871class STARTUPINFO(Structure):
6872 _fields_ = [("cb", c_ulong),
6873 ("lpReserved", LPTSTR),
6874 ("lpDesktop", LPTSTR),
6875 ("lpTitle", LPTSTR),
6876 ("dwX", c_ulong),
6877 ("dwY", c_ulong),
6878 ("dwXSize", c_ulong),
6879 ("dwYSize", c_ulong),
6880 ("dwXCountChars", c_ulong),
6881 ("dwYCountChars", c_ulong),
6882 ("dwFillAttribute", c_ulong),
6883 ("dwFlags", c_ulong),
6884 ("wShowWindow", c_short),
6885 ("cbReserved2", c_short),
6886 ("lpReserved2", LPBYTE),
6887 ("hStdInput", c_void_p),
6888 ("hStdOutput", c_void_p),
6889 ("hStdError", c_void_p),]
6890
6891 def to_str(self):
6892 return ''
6893
6894
6895class PROCESS_INFORMATION(Structure):
6896 _fields_ = [("hProcess", c_void_p),
6897 ("hThread", c_void_p),
6898 ("dwProcessId", c_ulong),
6899 ("dwThreadId", c_ulong),]
6900
6901 def to_str(self):
6902 return ''
6903
6904
6905class MEMORY_BASIC_INFORMATION(Structure):
6906 _fields_ = [("BaseAddress", c_void_p),
6907 ("AllocationBase", c_void_p),
6908 ("AllocationProtect", c_ulong),
6909 ("RegionSize", c_ulong),
6910 ("State", c_ulong),
6911 ("Protect", c_ulong),
6912 ("Type", c_ulong),]
6913
6914 def to_str(self):
6915 return ''
6916
6917
6918class SECURITY_ATTRIBUTES(Structure):
6919 _fields_ = [("Length", c_ulong),
6920 ("SecDescriptor", c_void_p),
6921 ("InheritHandle", c_bool)]
6922
6923 def to_str(self):
6924 return ''
6925
6926
6927class COORD(Structure):
6928 _fields_ = [("X", c_short),
6929 ("Y", c_short)]
6930
6931 def to_str(self):
6932 return ''
6933
6934
6935class SMALL_RECT(Structure):
6936 _fields_ = [("Left", c_short),
6937 ("Top", c_short),
6938 ("Right", c_short),
6939 ("Bottom", c_short)]
6940
6941 def to_str(self):
6942 return ''
6943
6944
6945class CONSOLE_SCREEN_BUFFER_INFO(Structure):
6946 _fields_ = [("dwSize", COORD),
6947 ("dwCursorPosition", COORD),
6948 ("wAttributes", c_short),
6949 ("srWindow", SMALL_RECT),
6950 ("dwMaximumWindowSize", COORD)]
6951
6952 def to_str(self):
6953 return ''
6954
6955
6956class CHAR_UNION(Union):
6957 _fields_ = [("UnicodeChar", c_wchar),
6958 ("AsciiChar", c_char)]
6959
6960 def to_str(self):
6961 return ''
6962
6963
6964class CHAR_INFO(Structure):
6965 _fields_ = [("Char", CHAR_UNION),
6966 ("Attributes", c_short)]
6967
6968 def to_str(self):
6969 return ''
6970
6971
6972class KEY_EVENT_RECORD(Structure):
6973 _fields_ = [("bKeyDown", c_byte),
6974 ("pad2", c_byte),
6975 ('pad1', c_short),
6976 ("wRepeatCount", c_short),
6977 ("wVirtualKeyCode", c_short),
6978 ("wVirtualScanCode", c_short),
6979 ("uChar", CHAR_UNION),
6980 ("dwControlKeyState", c_int)]
6981
6982 def to_str(self):
6983 return ''
6984
6985
6986class MOUSE_EVENT_RECORD(Structure):
6987 _fields_ = [("dwMousePosition", COORD),
6988 ("dwButtonState", c_int),
6989 ("dwControlKeyState", c_int),
6990 ("dwEventFlags", c_int)]
6991
6992 def to_str(self):
6993 return ''
6994
6995
6996class WINDOW_BUFFER_SIZE_RECORD(Structure):
6997 _fields_ = [("dwSize", COORD)]
6998
6999 def to_str(self):
7000 return ''
7001
7002
7003class MENU_EVENT_RECORD(Structure):
7004 _fields_ = [("dwCommandId", c_uint)]
7005
7006 def to_str(self):
7007 return ''
7008
7009
7010class FOCUS_EVENT_RECORD(Structure):
7011 _fields_ = [("bSetFocus", c_byte)]
7012
7013 def to_str(self):
7014 return ''
7015
7016
7017class INPUT_UNION(Union):
7018 _fields_ = [("KeyEvent", KEY_EVENT_RECORD),
7019 ("MouseEvent", MOUSE_EVENT_RECORD),
7020 ("WindowBufferSizeEvent", WINDOW_BUFFER_SIZE_RECORD),
7021 ("MenuEvent", MENU_EVENT_RECORD),
7022 ("FocusEvent", FOCUS_EVENT_RECORD)]
7023
7024 def to_str(self):
7025 return ''
7026
7027
7028class INPUT_RECORD(Structure):
7029 _fields_ = [("EventType", c_short),
7030 ("Event", INPUT_UNION)]
7031
7032 def to_str(self):
7033 return ''
7034
7035
7036doc/conque_term.txt [[[1
7037690
7038*conque_term.txt* Vim version 7.3 Last change: 2013 April 18
7039
7040The ConqueTerm plugin will turn a Vim buffer into a terminal emulator, allowing
7041you to run and interact with a shell or shell application inside the buffer.
7042
7043This version of the Conque Term plugin ships with the Conque GDB plugin.
7044It is an improvement of Conque Term 2.3. It contains aditional options
7045and supports updating terminal buffers which are not in focus.
7046
7047==============================================================================
7048
7049Contents
7050
7051 1. Installation |conque-setup|
7052 1.1 Requirements for Unix |conque-requirements|
7053 1.2 Requirements for Windows |conque-windows|
7054 1.3 Installation |conque-installation|
7055 2. Usage |conque-usage|
7056 2.1 General Usage |conque-gen-usage|
7057 2.2 Special keys |conque-special-keys|
7058 2.2.1 Send text to Conque |conque-send|
7059 2.2.2 Toggle terminal input mode |conque-input-mode|
7060 2.2.3 Sending the <Esc> key press |conque-esc|
7061 2.2.4 Sending interrupt <C-c> |conque-interrupt|
7062 3. Options |conque-options|
7063 3.1 General |conque-general|
7064 3.1.1 Python version |ConqueTerm_PyVersion|
7065 3.1.2 Fast mode |ConqueTerm_FastMode|
7066 3.1.3 Color support |ConqueTerm_Color|
7067 3.1.4 Keep updating terminal buffer |ConqueTerm_ReadUnfocused|
7068 3.1.5 Insert mode when entering buffer |ConqueTerm_InsertOnEnter|
7069 3.1.6 Close buffer when program exits |ConqueTerm_CloseOnEnd|
7070 3.1.7 Hide start messages |ConqueTerm_StartMessages|
7071 3.1.8 Regex for prompt highlighting |ConqueTerm_PromptRegex|
7072 3.1.9 Syntax type |ConqueTerm_Syntax|
7073 3.1.10 The bell Vim message |ConqueTerm_ShowBell|
7074 3.1.11 Unfocused update time |ConqueTerm_UnfocusedUpdateTime|
7075 3.1.12 Focused update time |ConqueTerm_FocusedUpdateTime|
7076 3.1.13 Pasting text |ConqueTermPaste|
7077 3.2 Keyboard |conque-keyboard|
7078 3.3.1 The <Esc> key |ConqueTerm_EscKey|
7079 3.3.2 The <C-c> mapping |ConqueTerm_Interrupt|
7080 3.3.3 Toggle terminal input mode |ConqueTerm_ToggleKey|
7081 3.3.4 Enable <C-w> in insert mode |ConqueTerm_CWInsert|
7082 3.3.5 Execute current file in Conque |ConqueTerm_ExecFileKey|
7083 3.3.6 Send file contents to Conque |ConqueTerm_SendFileKey|
7084 3.3.7 Send selected text to Conque |ConqueTerm_SendVisKey|
7085 3.3.8 Function Keys |ConqueTerm_SendFunctionKeys|
7086 3.3 Unix |conque-config-unix|
7087 3.4.1 Choose your terminal type |ConqueTerm_TERM|
7088 3.4 Windows |conque-config-windows|
7089 3.5.1 Python executable |ConqueTerm_PyExe|
7090 3.5.2 Windows character code page |ConqueTerm_CodePage|
7091 3.5.3 Terminal color method |ConqueTerm_ColorMode|
7092 4. VimScript API |conque-api|
7093 4.1 conque_term#open() |conque-open|
7094 4.2 conque_term#subprocess() |conque-subprocess|
7095 4.3 conque_term#get_instance() |conque-get-instance|
7096 4.4 CONQUE_OBJECT.write() |conque-write|
7097 4.5 CONQUE_OBJECT.writeln() |conque-writeln|
7098 4.6 CONQUE_OBJECT.read() |conque-read|
7099 4.7 CONQUE_OBJECT.set_callback() |conque-set-callback|
7100 4.8 CONQUE_OBJECT.close() |conque-close|
7101 4.9 Registering functions |conque-events|
7102 5. Misc |conque-misc|
7103 5.1 Known bugs |conque-bugs|
7104 5.2 Contribute |conque-contribute|
7105 5.3 Feedback |conque-feedback|
7106
7107==============================================================================
7108
71091. Installation *conque-setup*
7110
7111Conque is designed for both Unix and Windows operating systems, however the
7112requirements are slightly different. Please check section below corresponding
7113to your installed OS.
7114
7115Please do also take a look at the Installation section in the Conque GDB
7116specific help file |conque_gdb.txt|.
7117
71181.1 Requirements for Unix *conque-requirements*
7119
7120 * [G]Vim 7.0+ with +python
7121 * Python 2.3+
7122 * Unix-like OS: Linux, OS X, Solaris, Cygwin, etc
7123
7124The most common stumbling block is getting a version of Vim which has the
7125python interface enabled. Most all software package managers will have a copy
7126of Vim with Python support, so that is often the easiest way to get it. If
7127you're compiling Vim from source, be sure to use the --enable-pythoninterp
7128option, or --enable-python3interp for Python 3. On OS X the best option is
7129MacVim, which installs with Python support by default.
7130
71311.2 Requirements for Windows *conque-windows*
7132
7133 * [G]Vim 7.3 with +python
7134 * Python 2.7
7135 * Modern Windows OS (XP or later)
7136
7137Conque only officially supports the latest GVim 7.3 Windows installer
7138available at www.vim.org. If you are currently using Vim 7.2 or earlier you
7139will need to upgrade to 7.3 for Windows support. The Windows installer already
7140has the +python interface built in.
7141
7142The official 7.3 release of Vim for Windows only works with Python versions
71432.7 and/or 3.1. You can download and install Python from their website
7144http://www.python.org/download
7145
7146If you are compiling Vim + Python from source on Windows, the requirements
7147become only Vim 7.3+ and Python 2.7+.
7148
71491.3 Installation *conque-installation*
7150
7151Download the latest vimball from http://www.vim.org
7152
7153Open the .vmb file with Vim and run the following commands:
7154>
7155 :so %
7156 :q
7157<
7158That's it! The :ConqueTerm* commands will be available the next time you start
7159Vim. You can delete the .vmb file when you've verified Conque was successfully
7160installed.
7161
7162==============================================================================
7163
71642. Usage *conque-usage*
7165
7166For Conque GDB usage, take check the |conque_gdb.txt| help file.
7167
71682.1 General Usage *conque-gen-usage*
7169 *ConqueTerm* *ConqueTermSplit* *ConqueTermVSplit* *ConqueTermTab*
7170
7171Type :ConqueTerm <command> to launch an application in the current window. Eg:
7172>
7173 :ConqueTerm bash
7174 :ConqueTerm mysql -h localhost -u joe_lunchbox Menu
7175 :ConqueTerm Powershell.exe
7176<
7177Use :ConqueTermSplit or :ConqueTermVSplit to open Conque in a new horizontal
7178or vertical buffer. Use :ConqueTermTab to open Conque in a new tab.
7179
7180In insert mode you can interact with the shell as you would expect in a
7181normal terminal. All key presses will be sent to the terminal, including
7182control characters. See |conque-special-keys| for more information,
7183particularly regarding the <Esc> and <C-c> mappings.
7184
7185In normal mode you can use Vim commands to browse your terminal output and
7186scroll back through the history. Most all Vim functionality will work, such
7187as searching, yanking or highlighting text.
7188
71892.2 Special keys *conque-special-keys*
7190
7191There are several keys which can be configured to have special behavior with
7192Conque.
7193
71942.2.1 Send text to Conque *conque-send*
7195
7196Conque gives you three different commands to send text from a different
7197buffer, probably a source code file, to the Conque terminal buffer. All three
7198are configurable to use your choice of key combinations.
7199
7200To send a visually selected range of text to an existing terminal buffer,
7201press the <F9> key.
7202
7203To send the entire contents of the file you are editing to an existing
7204terminal buffer, press the <F10> key.
7205
7206Finally, to execute the current file in a new terminal buffer press the <F11>
7207key. This will split the screen with a new Conque buffer. The file you are
7208editing must be executable for this command to work.
7209
7210See |conque-options| for information about configuring these commands.
7211
72122.2.2 Toggle terminal input mode *conque-input-mode*
7213
7214If you want to use insert mode to edit the terminal screen, press <F8>. You
7215will now be able to edit the terminal output freely without your cursor
7216jumping the the active prompt line. This may be useful if you want to reformat
7217terminal output for readability.
7218
7219While the terminal is paused new output will not be displayed on the screen
7220until you press <F8> again to resume.
7221
7222You can configure Conque to use a different key with the |ConqueTerm_ToggleKey|
7223option.
7224
72252.2.3 Sending the <Esc> key press *conque-esc*
7226
7227By default if you press the <Esc> key in a Conque buffer you will leave insert
7228mode. But what if you want the <Esc> character to be sent to your terminal?
7229There are two options. By default, pressing <Esc> twice will send one <Esc>
7230character to the terminal and you will remain in insert mode, while pressing
7231it once will leave insert mode.
7232
7233Alternatively you can use the |ConqueTerm_EscKey| option to choose a
7234different key for leaving insert mode. If a custom key is set, then all <Esc>
7235key presses will be sent to the terminal.
7236
72372.2.4 Sending interrupt <C-c> *conque-interrupt*
7238
7239By default Conque will to send the <C-c> key mapping to the terminal. If you
7240want to change this to something different you can use the option
7241|ConqueTerm_Interrupt|.
7242
72432.3 Registering functions *conque-register*
7244
7245Conque allows you to write your own VimScript functions which will be called
7246at certain events. See the API section |conque-events| for more.
7247
7248==============================================================================
7249
72503. Options *conque-options*
7251
7252You can set the following options in your .vimrc (default values shown).
7253
7254Conque GDB also defines some options, take a look at the |conque_gdb.txt| help
7255file for documentation of these options.
7256
72573.1 General *conque-config-general*
7258
72593.1.1 Python version *ConqueTerm_PyVersion*
7260
7261Conque will work with either Python 2.x or 3.x, assuming the interfaces have
7262been installed. By default it will try to use Python 2 first, then will try
7263Python 3. If you want Conque to use Python 3, set this variable to 3.
7264
7265Note: even if you set this to 3, if you don't have the python3 interface
7266Conque will fall back to using Python 2.
7267>
7268 let g:ConqueTerm_PyVersion = 2
7269<
72703.1.2 Fast Mode *ConqueTerm_FastMode*
7271
7272Disable features which could make Conque run slowly. This includes most
7273terminal colors and some unicode support. Set this to 1 to enable fast mode.
7274>
7275 let g:ConqueTerm_FastMode = 0
7276<
72773.1.3 Color support *ConqueTerm_Color*
7278
7279Terminal colors have the potential to slow down terminal screen rendering,
7280depending on how many colors are used and how fast the computer is. This
7281option allows you to choose how much color support will be enabled.
7282
7283If set to 0, terminal colors will be disabled. This will allow the terminal to
7284render most quickly. Syntax highlighting will still work. For example
7285highlighting quoted strings or MySQL output.
7286
7287If set to 1, terminal colors will be enabled, but only for the most recent 200
7288lines of terminal output. Older output will be periodically stripped of color
7289highlighting to keep the display responsive.
7290
7291If set to 2, terminal colors will always be enabled. If your programs don't
7292use color output very frequently this is a good choice.
7293
7294Note: Color support is automatically disabled in "fast mode".
7295>
7296 let g:ConqueTerm_Color = 1
7297<
72983.1.4 Keep updating terminal buffer *ConqueTerm_ReadUnfocused*
7299
7300If set to 1 then your Conque buffers will continue to update after you've
7301switched to another buffer.
7302>
7303 let g:ConqueTerm_ReadUnfocused = 0
7304<
73053.1.5 Insert mode when entering buffer *ConqueTerm_InsertOnEnter*
7306
7307If set to 1 then you will automatically go into insert mode when you enter the
7308buffer. This diverges from normal Vim behavior. If 0 you will still be in
7309normal mode.
7310>
7311 let g:ConqueTerm_InsertOnEnter = 0
7312<
73133.1.6 Close buffer when program exits *ConqueTerm_CloseOnEnd*
7314
7315If you want your terminal buffer to be closed and permanently deleted when the
7316program running inside of it exits, set this option to 1. Otherwise the buffer
7317will become a simple text buffer after the program exits, and you can edit the
7318program output in insert mode.
7319>
7320 let g:ConqueTerm_CloseOnEnd = 0
7321<
73223.1.7 Show start messages *ConqueTerm_StartMessages*
7323
7324Display warning messages when starting up ConqueTerm if your system is
7325configured incorrectly.
7326>
7327 let g:ConqueTerm_StartMessages = 1
7328<
73293.1.8 Regex for highlighting your prompt *ConqueTerm_PromptRegex*
7330
7331Use this regular expression for sytax highlighting your terminal prompt. Your
7332terminal will generally run faster if you use Vim highlighting instead of
7333terminal colors for your prompt. You can also use it to do more advanced
7334syntax highlighting for the prompt line.
7335>
7336 let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$'
7337<
73383.1.9 Choose Vim syntax type *ConqueTerm_Syntax*
7339
7340Set the buffer syntax. The default has highlighting for MySQL,
7341but not much else.
7342>
7343 let g:ConqueTerm_Syntax = 'conque_term'
7344<
73453.1.10 The bell Vim message *ConqueTerm_ShowBell*
7346
7347You can choose whether you want Conque to echo the warning message 'BELL!'
7348whenever the bell character is written to a Conque terminal.
7349>
7350 let g:ConqueTerm_ShowBell = 0
7351<
73523.1.11 Unfocused update time *ConqueTerm_UnfocusedUpdateTime*
7353
7354Use this option to define how often in milliseconds you want Conque to
7355update your terminals when you are not in insert mode. The value 0 (zero)
7356is special, use 0 if you want to keep you normal update time (|updatetime|)
7357when you are in normal mode.
7358>
7359 let g:ConqueTerm_UnfocusedUpdateTime = 500
7360>
73613.1.12 Focused update time *ConqueTerm_FocusedUpdateTime*
7362
7363Use this option to define how often in milliseconds you want Conque to
7364update the terminal in focus when you are in insert mode. The value 0 (zero)
7365is special and means that you want to keep your normal |updatetime| in insert
7366mode.
7367>
7368 let g:ConqueTerm_FocusedUpdateTime = 80
7369>
73703.1.13 Pasting *ConqueTermPaste*
7371
7372Use the ConqueTermPaste command to paste the previously yanked text.
7373
73743.2 Keyboard *conque-config-keyboard*
7375
73763.2.1 The <Esc> key *ConqueTerm_EscKey*
7377
7378If a custom key is set, then all <Esc> key presses will be sent to the
7379terminal and you must use this custom key to leave insert mode. If left to the
7380default value of '<Esc>' then you must press it twice to send the escape
7381character to the terminal, while pressing it once will leave insert mode.
7382
7383Note: You cannot use a key which is internally coded with the escape
7384character. This includes the <F-> keys and often the <A-> and <M-> keys.
7385Picking a control key, such as <C-k> will be your best bet.
7386>
7387 let g:ConqueTerm_EscKey = '<Esc>'
7388<
73893.2.2 The <C-c> mapping *ConqueTerm_Interrupt*
7390
7391This key mapping defines how ConqueTerm will send interrupt to the terminal
7392in both normal and insert mode. By default this will be <C-c>. If you are
7393used to <C-c> for leaving insert mode you might want to change it.
7394>
7395 let g:ConqueTerm_Interrupt = '<C-c>'
7396<
73973.2.3 Toggle terminal input mode *ConqueTerm_ToggleKey*
7398
7399Press this key to pause terminal input and output display. You will then be
7400able to edit the terminal screen as if it were a normal text buffer. Press
7401this key again to resume terminal mode.
7402>
7403 let g:ConqueTerm_ToggleKey = '<F8>'
7404<
74053.2.4 Enable <C-w> in insert mode *ConqueTerm_CWInsert*
7406
7407If set to 1 then you can leave the Conque buffer using the <C-w> commands
7408while you're still in insert mode. If set to 0 then the <C-w> character will
7409be sent to the terminal. If both this option and ConqueTerm_InsertOnEnter are
7410set you can go in and out of the terminal buffer while never leaving insert
7411mode.
7412>
7413 let g:ConqueTerm_CWInsert = 0
7414<
74153.2.5 Execute current file in Conque *ConqueTerm_ExecFileKey*
7416
7417Press this key to execute the file you're currently editing in a Conque
7418buffer. Is equivelent to running the command :ConqueTermSplit YOUR_FILE. Your
7419file must be executable for this command to work correctly.
7420>
7421 let g:ConqueTerm_ExecFileKey = '<F11>'
7422<
74233.2.6 Send file contents to Conque *ConqueTerm_SendFileKey*
7424
7425Press this key to send your entire file contents to the most recently opened
7426Conque buffer as keyboard input.
7427>
7428 let g:ConqueTerm_SendFileKey = '<F10>'
7429<
74303.2.7 Send selected text to Conque *ConqueTerm_SendVisKey*
7431
7432Use this key to send the currently selected text to the most recently created
7433Conque buffer.
7434>
7435 let g:ConqueTerm_SendVisKey = '<F9>'
7436<
74373.2.8 Function Keys *ConqueTerm_SendFunctionKeys*
7438
7439By default, function keys (the F1-F12 row at the top of your keyboard) are not
7440passed to the terminal. Set this option to 1 to send these key events.
7441
7442Note: Unless you configured |ConqueTerm_SendVisKey| and |ConqueTerm_ToggleKey|
7443to use different keys, <F8> and <F9> will not be sent to the terminal even if
7444you set this option to 1.
7445>
7446 let g:ConqueTerm_SendFunctionKeys = 0
7447<
74483.3 Unix *conque-config-unix*
7449
74503.3.1 Choose your terminal type, Unix ONLY *ConqueTerm_TERM*
7451
7452Use this option to tell Conque what type of terminal it should identify itself
7453as. Conque officially uses the more limited VT100 terminal type for
7454developement and testing, although it supports some more advanced features
7455such as colors and title strings.
7456
7457You can change this setting to a more advanced type, namely 'xterm', but your
7458results may vary depending on which programs you're running.
7459>
7460 let g:ConqueTerm_TERM = 'vt100'
7461<
74623.4 Windows *conque-config-windows*
7463
74643.4.1 Python executable, Windows ONLY *ConqueTerm_PyExe*
7465
7466The Windows version of Conque needs to know the path to the python.exe
7467executable for the version of Python Conque is using. If you installed Python
7468in the default location, or added the Python directory to your system path,
7469Conque should be able to find python.exe without you changing this variable.
7470
7471For example, you might set this to 'C:\Program Files\Python27\python.exe'
7472>
7473 let g:ConqueTerm_PyExe = ''
7474<
74753.4.2 Windows character code page *ConqueTerm_CodePage*
7476
7477Set the "code page" Windows will use for your console. Leave this value set to
7478zero to use the environment code page.
7479
7480Note: Displaying unicode characters on Conque for Windows needs work.
7481>
7482 let g:ConqueTerm_CodePage = 0
7483<
74843.4.3 Terminal color method, Windows ONLY *ConqueTerm_ColorMode*
7485
7486Vim syntax highlighting by coordinate (e.g. the 3-7th characters on the 42nd
7487line) can be very slow. If you set this variable to 'conceal', you can use
7488the new conceal feature to render terminal colors. Requires Vim 7.3 and only
7489works on the Windows version of Conque. This will make colors render faster,
7490however it will also add hidden characters to the screen, which may be
7491annoying if you're copying and pasting terminal output out of the Conque
7492buffer. Set this to an empty string '' to disable concealed highlighting.
7493>
7494 let g:ConqueTerm_ColorMode = 'conceal'
7495<
7496==============================================================================
7497
74984. VimScript API *conque-api*
7499
7500The Conque scripting API allows you to create and interact with Conque
7501terminals with the VimScript language.
7502
75034.1 conque_term#open({command}, [buf_opts], [remain]) *conque-open*
7504
7505The open() function will create a new terminal buffer and start your command.
7506
7507The {command} must be an executable, either an absolute path or relative to
7508your system path.
7509
7510You can pass in a list of vim commands [buf_opts] which will be executed after
7511the new buffer is created but before the command is started. These are
7512typically commands to alter the size, position or configuration of the buffer
7513window.
7514
7515Note: If you don't pass in a command such as 'split', the terminal will open
7516in the current buffer.
7517
7518If you don't want the new terminal buffer to become the new active buffer, set
7519 [remain] to 1. Only works if you create a split screen using [options].
7520
7521Returns a Conque terminal object.
7522
7523Examples:
7524>
7525 let my_terminal = conque_term#open('/bin/bash')
7526 let my_terminal = conque_term#open('ipython', ['split', 'resize 20'], 1)
7527<
75284.2 conque_term#subprocess({command}) (experimental) *conque-subprocess*
7529
7530Starts a new subprocess with your {command}, but no terminal buffer is ever
7531created. This may be useful if you need asynchronous interaction with a
7532subprocess, but want to handle the output on your own.
7533
7534Returns a Conque terminal object.
7535
7536Example:
7537>
7538 let my_subprocess = conque_term#subprocess('tail -f /var/log/foo.log')
7539<
75404.3 conque_term#get_instance( [terminal_number] ) *conque-get-instance*
7541
7542Use the get_instance() function to retrieve an existing terminal object. The
7543terminal could have been created either with the user command :ConqueTerm or
7544with an API call to conque_term#open() or subprocess().
7545
7546Use the optional [terminal_number] to retrieve a specific terminal instance.
7547Otherwise if the current buffer is a Conque terminal, it will be returned,
7548else the most recently created terminal. The terminal number is what you see
7549at the end of a terminal buffer name, e.g. "bash - 2".
7550
7551Returns a Conque terminal object.
7552
7553Example:
7554>
7555 nnoremap <F4> :call conque_term#get_instance().writeln('clear')<CR>
7556<
75574.4 CONQUE_OBJECT.write({text}) *conque-write*
7558
7559Once you have a terminal object from open(), subprocess() or get_instance()
7560you can send text input to it with the write() method.
7561
7562No return value.
7563
7564Examples:
7565>
7566 call my_terminal.write("whoami\n")
7567 call my_terminal.write("\<C-c>")
7568<
75694.5 CONQUE_OBJECT.writeln({text}) *conque-writeln*
7570
7571The same as write() except adds a \n character to the end if your input.
7572
7573Examples:
7574>
7575 call my_subprocess.writeln('make')
7576<
75774.6 CONQUE_OBJECT.read( [timeout], [update_buffer] ) *conque-read*
7578
7579Read new output from a Conque terminal subprocess. New output will be returned
7580as a string, and the terminal buffer will also be updated by default.
7581
7582If you are reading immediately after calling the write() method, you may want
7583to wait [timeout] milliseconds for output to be ready.
7584
7585If you want to prevent the output from being displayed in the terminal buffer,
7586set [update_buffer] to 0. This option has no effect if the terminal was
7587created with the subprocess() function, since there never is a buffer to
7588update.
7589
7590Returns output string.
7591
7592Note: The terminal buffer will not automatically scroll down if the new output
7593extends beyond the bottom of the visible buffer. Vim doesn't allow "unfocused"
7594buffers to be scrolled at the current version, although hopefully this will
7595change.
7596
7597Examples:
7598>
7599 call my_terminal.writeln('whoami')
7600 let output = my_terminal.read(500)
7601 call my_terminal.writeln('ls -lha')
7602 let output = my_terminal.read(1000, 1)
7603<
76044.7 CONQUE_OBJECT.set_callback( {funcname} ) *conque-set-callback*
7605
7606Register a callback function for this subprocess instance. This function will
7607automatically be called whenever new output is available. Only practical with
7608subprocess() objects.
7609
7610Conque checkes for new subprocess output once a second when Vim is idle. If
7611new output is found your function will be called.
7612
7613Pass in the callback function name {funcname} as a string.
7614
7615No return value.
7616
7617Note: this method requires the g:ConqueTerm_ReadUnfocused option to be set.
7618
7619Note: this method is experimental, results may vary.
7620
7621Example:
7622>
7623 let sp = conque_term#subprocess('tail -f /home/joe/log/error_log')
7624
7625 function! MyErrorAlert(output)
7626 echo a:output
7627 endfunction
7628
7629 call sp.set_callback('MyErrorAlert')
7630<
76314.8 CONQUE_OBJECT.close() *conque-close*
7632
7633Kill your terminal subprocess. Sends the ABORT signal. You probably want to
7634close your subprocess in a more graceful manner with the write() method, but
7635this can be used when needed. Does not close the terminal buffer, if it
7636exists.
7637
7638This method will be called on all existing Conque subprocesses when Vim exits.
7639
7640Example:
7641>
7642 let term = conque_term#open('ping google.com', ['belowright split'])
7643 call term.read(5000)
7644 call term.close()
7645<
76464.9 Registering functions *conque-events*
7647
7648Conque provides the option to register callback functions which will be
7649executed at several different events. The currently available events are:
7650
7651 after_startup After your application has loaded into the buffer.
7652 after_close After your application has terminated, but not when the
7653 application buffer gets unloaded.
7654 buffer_enter When you switch to a Conque buffer.
7655 buffer_leave When you leave a Conque buffer.
7656
7657You may use the function conque_term#register_function(event, function_name)
7658to add additional hooks at a particular event. The second argument should be
7659the name of a callback function which has one parameter, the current
7660terminal object (see |conque-api| for more about terminal objects).
7661
7662For example:
7663>
7664 function MyConqueStartup(term)
7665
7666 " set buffer syntax using the name of the program currently running
7667 let syntax_associations = { 'ipython': 'python', 'irb': 'ruby' }
7668
7669 if has_key(syntax_associations, a:term.program_name)
7670 execute 'setlocal syntax=' . syntax_associations[a:term.program_name]
7671 else
7672 execute 'setlocal syntax=' . a:term.program_name
7673 endif
7674
7675 " shrink window height to 10 rows
7676 resize 10
7677
7678 " silly example of terminal api usage
7679 if a:term.program_name == 'bash'
7680 call a:term.writeln('svn up ~/projects/*')
7681 endif
7682
7683 endfunction
7684
7685 call conque_term#register_function('after_startup', 'MyConqueStartup')
7686<
7687
7688==============================================================================
7689
76905. Misc *conque-misc*
7691
7692
76935.1 Known bugs *conque-bugs*
7694
7695The following are known limitations:
7696
7697 - Font/color highlighting is imperfect and slow. If you don't care about
7698 color in your shell, set g:ConqueTerm_Color = 0 in your .vimrc
7699 - Conque only supports the extended ASCII character set for input, not utf-8.
7700 - VT100 escape sequence support is not complete.
7701 - Alt/Meta key support in Vim isn't great in general, and conque is no
7702 exception. Pressing <Esc><Esc>x or <Esc><M-x> instead of <M-x> works in
7703 most cases.
7704
77055.2 Contribute *conque-contribute*
7706
7707The two contributions most in need are improvements to Vim itself. I currently
7708use hacks to capture key press input from the user, and to poll the terminal
7709for more output. The Vim todo.txt document lists proposed improvements to give
7710users this behavior without hacks. Having a key press event should allow
7711Conque to work with multi- byte input. If you are a Vim developer, please
7712consider prioritizing these two items:
7713
7714 - todo.txt (Autocommands, line ~3137)
7715 8 Add an event like CursorHold that is triggered repeatedly, not just
7716 once after typing something.
7717
7718
77195.3 Feedback *conque-feedback*
7720
7721Bugs, suggestions and patches are all welcome.
7722
7723For more information visit http://conque.googlecode.com
7724
7725Check out the latest from svn at http://conque.googlecode.com/svn/trunk/
7726
7727vim:tw=78:ts=8:ft=help:norl:
7728doc/conque_gdb.txt [[[1
7729366
7730*conque_gdb.txt* Vim version 7.3 Last change: 2013 May 7
7731
7732This help file explains the Conque GDB Vim plugin.
7733
7734==============================================================================
7735
7736Introduction
7737
7738The Conque GDB plugin extends the Conque (Conque Term) plugin. Like Conque
7739Term, Conque GDB is a terminal emulator. The |ConqueGdb|, |ConqueGdbSplit|,
7740|ConqueGdbVsplit| and |ConqueGdbTab| commands will turn a Vim buffer into a
7741GDB command line interface (CLI).
7742
7743When debugging a program with one of the |ConqueGdb|* commands, Conque GDB will
7744automatically open the appropriate source files when break points are hit,
7745and highlight the line where program execution has stopped. And if you install
7746Conque GDB on a Unix system with GDB 7.0+ compiled with python support, Conque
7747GDB will place signs on lines to mark where you have placed break points.
7748
7749Conque GDB ships with a modified version of Conque Term 2.3. This new version
7750of Conque Term comes with new options and new features. Please see the
7751|conque_term.txt| help file for help regarding Conque Term. Most of the Conque
7752Term options also apply to Conque GDB, so even if you don't plan on using
7753Conque Term it's a good idea to take a look at the Conque Term options.
7754Especially regarding the |ConqueTerm_ReadUnfocused| option, which is now fully
7755functional.
7756
7757==============================================================================
7758
7759Contents
7760
77611. Installation |conque-gdb-setup|
7762 1.1 Requirements for Unix |conque-gdb-unix-requirements|
7763 1.2 Requirements for Windows |conque-gdb-window-requirements|
7764 1.3 Vimball installation |conque-gdb-installation|
77652. Usage |conque-gdb-usage|
7766 2.1 Opening Conque GDB CLI |conque-gdb-open|
7767 2.2 Delete unneeded buffers |conque-gdb-delete-buffers|
7768 2.3 Send command to GDB |conque-gdb-command|
7769 2.4 Send command to GDB |conque-gdb-exe|
77703. Options |conque-gdb-options|
7771 3.1 GDB Source code split |conque-gdb-src-split|
7772 3.2 Path to GDB |conque-gdb-path|
7773 3.3 Disable GDB commands |conque-gdb-disable|
7774 3.4 Save command history |conque-gdb-save-history|
7775 3.5 Set Read Timeout For GDB Resposes |conque-gdb-read-timeout|
7776 3.6 Keyboard Mappings |conque-gdb-mappings|
7777 3.6.1 Mappings leader |conque-gdb-leader|
7778 3.6.2 Run program mapping |conque-gdb-run-mapping|
7779 3.6.3 Continue program mapping |conque-gdb-continue-mapping|
7780 3.6.4 Next line mapping |conque-gdb-next-mapping|
7781 3.6.5 Step line mapping |conque-gdb-step-mapping|
7782 3.6.6 Print identifier under cursor |conque-gdb-print-mapping|
7783 3.6.7 Toggle break point mapping |conque-gdb-toggle-mapping|
7784 3.6.8 Set break point mapping |conque-gdb-break-mapping|
7785 3.6.9 Delete break point mapping |conque-gdb-delete-break-mapping|
7786 3.6.10 Finish mapping |conque-gdb-finish-mapping|
7787 3.6.11 Backtrace mapping |conque-gdb-backtrace-mapping|
77884. Custom key mappings |conque-gdb-custom-key-mappings|
7789
7790==============================================================================
7791
77921. Installation *conque-gdb-setup*
7793
7794Conque GDB works on both Unix and Windows. The requirements are slightly
7795different though. Note that Conque GDB supports some features on Unix which
7796are not supported on Windows.
7797
77981.1 Requirements for Unix *conque-gdb-unix-requirements*
7799
7800 * [G]Vim 7.3+ with +python
7801 * Python 2.3+
7802 * Unix-like OS: Linux, OS X, Solaris, Cygwin, etc
7803 * GDB 7.0+ (see note below)
7804
7805Note: Conque GDB actually works with older versions of GDB (GDB 6.3+).
7806However GDB 7.0+ is recommended since it is likely to support all the Conque
7807GDB features.
7808
7809Even tough you have GDB 7.0+ installed on your system it is not 100% sure that
7810it will support all the Conque GDB features, namely the ability to place signs
7811on lines to mark where break points are currently placed. If you encounter
7812this problem with GDB 7.0+ installed on your system, then go ahead and build
7813GDB 7.0+ from source with python support by specifying the '--with-python'
7814configuration option.
7815
78161.2 Requirements for Windows *conque-gdb-windows-requirements*
7817
7818 * [G]Vim 7.3 with +python
7819 * Python 2.7
7820 * Modern Windows OS (XP or later)
7821 * MinGW GDB 7.0+
7822
7823See http://www.mingw.org/wiki/Getting_Started for an explanation on how to
7824install MinGW. If you don't install MinGW in the C:\MinGW directory and you
7825haven't specified a path to the path\to\MinGW\bin directory in your PATH
7826environment variable. Then you have to tell Conque GDB where MinGW GDB is
7827installed on your system. See the |ConqueGdb_GdbExe| option for an explanation
7828on how to do this.
7829
78301.3 Vimball Installation *conque-gdb-installation*
7831
7832Download the latest conque_gdb.vmb vimball from http://www.vim.org.
7833
7834Open conque_gdb.vmb with Vim and run the following commands:
7835>
7836 :so %
7837 :q
7838<
7839Next time you open Vim the |ConqueTerm|* and |ConqueGdb|* commands will be
7840available.
7841
7842==============================================================================
7843
78442. Usage *conque-gdb-usage*
7845
7846This section describes the usage of Conque GDB. See the Conque Term specific
7847file |conque_term.txt|, for Conque Term usage.
7848
78492.1 Opening Conque GDB CLI *conque-gdb-open*
7850 *ConqueGdb* *ConqueGdbVSplit*
7851 *ConqueGdbTab* *ConqueGdbSplit*
7852
7853Type :ConqueGdb <gdb-arguments> to launch GDB in the current window. E.g.:
7854>
7855 :ConqueGdb
7856 :ConqueGdb program
7857 :ConqueGdb -d dir --args program [arguments]
7858<
7859Use :ConqueGdbSplit or :ConqueGdbVSplit to open GDB in a new horizontal or
7860vertical buffer. When opening GDB with one of the split commands, it will
7861use the current window as its destination window for source files when
7862break points are hit. Use :ConqueGdbTab to open GDB in a new tab.
7863
7864When issuing the :ConqueGdbTab or :ConqueGdb commands Conque GDB will open a
7865new split window for the source files. See |g:ConqueGdb_SrcSplit| to change how
7866Conque should split the GDB window.
7867
78682.2 Delete unneeded buffers *conque-gdb-delete-buffers*
7869 *ConqueGdbBDelete*
7870
7871Once you have debugged a program with one of the |ConqueGdb|* commands, you
7872might experience that a lot of new source files have been opened in buffers.
7873If you want Conque to get rid of some of these buffers, you can use the
7874|ConqueGdbBDelete| command. This command deletes the buffers ConqueGdb opened
7875while you were debugging.
7876
7877Note that only buffers opened by Conque GDB will be deleted, and if you have
7878modified a buffer opened by Conque GDB, this buffer will not be deleted either.
7879>
7880 :ConqueGdbBDelete
7881>
78822.3 Send command to GDB *conque-gdb-command*
7883 *ConqueGdbCommand*
7884
7885If you are currently outside the GDB CLI window and would like to send a
7886command to GDB use |ConqueGdbCommand| to send any command to GDB. E.g.
7887>
7888 :ConqueGdbCommand disable 1
7889>
7890This will only work properly if the |ConqueTerm_ReadUnfocused| option is
7891enabled. See the help file |conque_term.txt| for information.
7892
78932.4 Set path to GDB *conque-gdb-exe*
7894 *ConqueGdbExe*
7895
7896If switch is needed between different GDB executables, for instance, during
7897cross-development, you can specify path to a GDB executable as follows:
7898>
7899 :ConqueGdbExe /path/to/gdb-cross
7900 :ConqueGdbExe
7901>
7902When zero arguments are given to the |ConqueGdbExe| command, Conque GDB will
7903use the default path to GDB, as specified by the |g:ConqueGdb_GdbExe| option
7904on startup. See |g:ConqueGdb_GdbExe|.
7905==============================================================================
7906
79073. Options *conque-gdb-options*
7908
7909This section describes the modifiable options Conque Gdb offers. Please take
7910a look at the |conque_term.txt| help file for Conque Term options. Most of
7911these options also apply to Conque Gdb.
7912
79133.1 GDB Source code split *conque-gdb-src-split*
7914 *g:ConqueGdb_SrcSplit*
7915
7916When Conque GDB splits the GDB CLI window to open source files it will by
7917defaut split the window such that the source code will appear above the GDB
7918CLI window. You can change the value of |g:ConqueGdb_SrcSplit| to 'above',
7919'below', 'left' or 'right' if you want Conque GDB to split the GDB window
7920such that the source code will spilt above, below, left or right to the
7921GDB CLI window.
7922>
7923 let g:ConqueGdb_SrcSplit = 'above'
7924<
79253.2 Path to GDB *conque-gdb-path*
7926 *g:ConqueGdb_GdbExe*
7927
7928If the |ConqueGdb| commands can't find GDB in the system path, then you might
7929need to specify the path to the GDB executable manually. However on Windows
7930Conque will also look for GDB in C:\MinGW\bin. To define the path to the GDB
7931executable you can change the value of |g:ConqueGdb_GdbExe|. By default this
7932option is:
7933>
7934 let g:ConqueGdb_GdbExe = ''
7935<
7936Note that you have to restart Vim before changes to |g:ConqueGdb_GdbExe| are
7937recognized. If you would like to change path to the GDB executable at runtime,
7938use the |ConqueGdbExe| command.
7939
79403.3 Disable GDB commands *conque-gdb-disable*
7941 *g:ConqueGdb_Disable*
7942
7943With this option you can disable the Conque GDB plugin. By default it is
7944enabled:
7945>
7946 let g:ConqueGdb_Disable = 0
7947<
79483.4 Save command history *conque-gdb-save-history*
7949 *g:ConqueGdb_SaveHistory*
7950
7951With this option you can tell whether Conque GDB should save history of
7952commands that are issued by keyboard mappings. By default the keyboard mapping
7953command history is not saved, which implies you will not see the commands
7954issued by keyboard mappings when pressing <Up> to view previous GDB commands
7955in the CLI window.
7956>
7957 let g:ConqueGdb_SaveHistory = 0
7958
79593.5 Set Read Timeout For GDB Resposes *conque-gdb-read-timeout*
7960 *g:ConqueGdb_ReadTimeout*
7961
7962This will allow you to set the timeout before Conque GDB tries to read output
7963from GDB. You may have to change the time depending on the amount of output
7964GDB makes and system performance. The default is 50 milliseconds.
7965
7966 let g:ConqueGdb_ReadTimeout = 50
7967
7968
79693.6 Keyboard Mappings *conque-gdb-mappings*
7970
7971Conque GDB defines keyboard mappings to some of the most common gdb commands.
7972By default these Keyboard mappings use the |mapleader| (|<leader>|) as prefix.
7973However you can change this with the |g:ConqueGdb_Leader| option.
7974
7975Note that you need to enable the |ConqueTerm_ReadUnfocused| option for the
7976keyboard mappings to work properly. See the help file |conque_term.txt|.
7977
79783.6.1 Mappings leader *conque-gdb-leader*
7979 *g:ConqueGdb_Leader*
7980
7981This option specifies which keyboard key is used as prefix for the Conque GDB
7982keyboard mappings described below. By default it is:
7983>
7984 let g:ConqueGdb_Leader = '<Leader>'
7985>
7986Note that |<Leader>| is usually defined as \ (backslash). You don't have to
7987use the |g:ConqueGdb_Leader| when defining new keyboard mappings as described
7988below.
7989
79903.6.2 Run program mapping *conque-gdb-run-mapping*
7991 *g:ConqueGdb_Run*
7992
7993This option defines the keyboard mapping used to issue the GDB command run
7994from any buffer. By default this is:
7995>
7996 let g:ConqueGdb_Run = g:ConqueGdb_Leader . 'r'
7997>
79983.6.3 Continue program mapping *conque-gdb-continue-mapping*
7999 *g:ConqueGdb_Continue*
8000
8001This option defines the mapping used to issue the continue command. This
8002is by default:
8003>
8004 let g:ConqueGdb_Continue = g:ConqueGdb_Leader . 'c'
8005>
80063.6.4 Next line mapping *conque-gdb-next-mapping*
8007 *g:ConqueGdb_Next*
8008
8009Mapping to issue GDB command next. Default:
8010>
8011 let g:ConqueGdb_Next = g:ConqueGdb_Leader . 'n'
8012>
80133.6.5 Step line mapping *conque-gdb-step-mapping*
8014 *g:ConqueGdb_Step*
8015
8016Mapping to send the step command to GDB. Default:
8017>
8018 let g:ConqueGdb_Step = g:ConqueGdb_Leader . 's'
8019>
80203.6.6 Print identifier under cursor *conque-gdb-print-mapping*
8021 *g:ConqueGdb_Print*
8022
8023This mapping is used to issue the print GDB command, to print value of the
8024identifier under the cursor. By default it is:
8025>
8026 let g:ConqueGdb_Print = g:ConqueGdb_Leader . 'p'
8027>
80283.6.7 Toggle break point mapping *conque-gdb-toggle-mapping*
8029 *g:ConqueGdb_ToggleBreak*
8030
8031This is a special mapping used to toggle a break point on the current line.
8032I.e. if there is a break point on the current line already it will delete
8033the break point, otherwise it will create a new break point on the current
8034line.
8035
8036This mapping is only supported on Unix having GDB 7.0+ with full python
8037support. See |conque-gdb-unix-requirements|. By default this mapping is:
8038>
8039 let g:ConqueGdb_ToggleBreak = g:ConqueGdb_Leader . 'b'
8040>
80413.6.8 Set break point mapping *conque-gdb-break-mapping*
8042 *g:ConqueGdb_SetBreak*
8043
8044This mapping is specific to Conque GDB installations on Windows and Unix
8045systems where GDB does not have full python support. See |conque-gdb-setup|.
8046
8047It will issue the GDB command break to place a break point on the current
8048line. By default this mapping is:
8049>
8050 let g:ConqueGdb_SetBreak = g:ConqueGdb_Leader . 'b'
8051>
80523.6.9 Delete break point mapping *conque-gdb-delete-break-mapping*
8053 *g:ConqueGdb_DeleteBreak*
8054
8055This mapping is specific to Conque GDB installations on Windows and Unix
8056systems where GDB does not have full python support. See |conque-gdb-setup|.
8057
8058It will issue the GDB command clear to delete the break point on the current
8059line. Default:
8060>
8061 let g:ConqueGdb_DeleteBreak = g:ConqueGdb_Leader . 'd'
8062>
80633.6.10 Finish mapping *conque-gdb-finish-mapping*
8064 *g:ConqueGdb_Finish*
8065
8066Mapping to issue the finish command. Default:
8067>
8068 let g:ConqueGdb_Finish = g:ConqueGdb_Leader . 'f'
8069>
80703.6.11 Backtrace mapping *conque-gdb-backtrace-mapping*
8071 *g:ConqueGdb_Backtrace*
8072
8073Mapping to execute the backtrace command. By default it is:
8074>
8075 let g:ConqueGdb_Backtrace = g:ConqueGdb_Leader . 't'
8076>
80774. Custom key mappings *conque-gdb-custom-key-mappings*
8078
8079This section shows you how you can use |ConqueGdbCommand| to setup your
8080own customized Conque GDB key mappings.
8081
8082You might want to be able answer GDB confirmations (say y or n) without
8083having to go to the Conque GDB window. You can use the |ConqueGdbCommand|
8084command to achieve this:
8085>
8086 nnoremap <silent> <Leader>Y :ConqueGdbCommand y<CR>
8087 nnoremap <silent> <Leader>N :ConqueGdbCommand n<CR>
8088>
8089With those 2 lines in your vimrc file you can type the leader key followed
8090by a capital Y to answer yes to GDB confirmations and leader followed by
8091capital N to answer no to GDB confirmations.
8092
8093==============================================================================
8094
8095vim:tw=78:ts=8:ft=help:norl:
8096plugin/conque_gdb.vim [[[1
8097118
8098
8099" Option to specify whether to enable ConqueGdb
8100if !exists('g:ConqueGdb_Disable')
8101 let g:ConqueGdb_Disable = 0
8102endif
8103
8104if exists('g:plugin_conque_gdb_loaded') || g:ConqueGdb_Disable
8105 finish
8106endif
8107let g:plugin_conque_gdb_loaded = 1
8108
8109" Options how to split GDB window when opening new source file
8110let g:conque_gdb_src_splits = {'below': 'belowright split', 'above': 'aboveleft split', 'right': 'belowright vsplit', 'left': 'leftabove vsplit'}
8111
8112let g:conque_gdb_default_split = g:conque_gdb_src_splits['above']
8113
8114if !exists('g:ConqueGdb_SrcSplit')
8115 let g:ConqueGdb_SrcSplit = 'above'
8116elseif !has_key(g:conque_gdb_src_splits, g:ConqueGdb_SrcSplit)
8117 let g:ConqueGdb_SrcSplit = 'above'
8118 echohl WarningMsg
8119 echomsg "ConqueGdb: Warning the g:ConqueGdb_SrcSplit option is invalid"
8120 echomsg " valid options are: 'below', 'above', 'right' or 'left'"
8121 echomsg ""
8122 echohl None
8123endif
8124
8125" Option to define path to gdb executable
8126if !exists('g:ConqueGdb_GdbExe')
8127 let g:ConqueGdb_GdbExe = ''
8128endif
8129
8130" Option to choose leader key to execute gdb commands.
8131if !exists('g:ConqueGdb_Leader')
8132 let g:ConqueGdb_Leader = '<Leader>'
8133endif
8134
8135" Load python scripts now
8136call conque_gdb#load_python()
8137
8138" Keyboard mappings
8139if g:conque_gdb_gdb_py_support
8140 if !exists('g:ConqueGdb_ToggleBreak')
8141 let g:ConqueGdb_ToggleBreak = g:ConqueGdb_Leader . 'b'
8142 endif
8143else
8144 if !exists('g:ConqueGdb_SetBreak')
8145 let g:ConqueGdb_SetBreak = g:ConqueGdb_Leader . 'b'
8146 endif
8147 if !exists('g:ConqueGdb_DeleteBreak')
8148 let g:ConqueGdb_DeleteBreak = g:ConqueGdb_Leader . 'd'
8149 endif
8150endif
8151if !exists('g:ConqueGdb_Continue')
8152 let g:ConqueGdb_Continue = g:ConqueGdb_Leader . 'c'
8153endif
8154if !exists('g:ConqueGdb_Run')
8155 let g:ConqueGdb_Run = g:ConqueGdb_Leader . 'r'
8156endif
8157if !exists('g:ConqueGdb_Next')
8158 let g:ConqueGdb_Next = g:ConqueGdb_Leader . 'n'
8159endif
8160if !exists('g:ConqueGdb_Step')
8161 let g:ConqueGdb_Step = g:ConqueGdb_Leader . 's'
8162endif
8163if !exists('g:ConqueGdb_Print')
8164 let g:ConqueGdb_Print = g:ConqueGdb_Leader . 'p'
8165endif
8166if !exists('g:ConqueGdb_Finish')
8167 let g:ConqueGdb_Finish = g:ConqueGdb_Leader . 'f'
8168endif
8169if !exists('g:ConqueGdb_Backtrace')
8170 let g:ConqueGdb_Backtrace = g:ConqueGdb_Leader . 't'
8171endif
8172if !exists('g:ConqueGdb_ReadTimeout')
8173 let g:ConqueGdb_ReadTimeout = 50
8174endif
8175if !exists('g:ConqueGdb_SaveHistory')
8176 let g:ConqueGdb_SaveHistory = 0
8177endif
8178
8179" Commands to open conque gdb
8180command! -nargs=* -complete=file ConqueGdb call conque_gdb#open(<q-args>, [
8181 \ get(g:conque_gdb_src_splits, g:ConqueGdb_SrcSplit, g:conque_gdb_default_split),
8182 \ 'buffer ' . bufnr("%"),
8183 \ 'wincmd w'])
8184command! -nargs=* -complete=file ConqueGdbSplit call conque_gdb#open(<q-args>, [
8185 \ 'rightbelow split'])
8186command! -nargs=* -complete=file ConqueGdbVSplit call conque_gdb#open(<q-args>, [
8187 \ 'rightbelow vsplit'])
8188command! -nargs=* -complete=file ConqueGdbTab call conque_gdb#open(<q-args>, [
8189 \ 'tabnew',
8190 \ get(g:conque_gdb_src_splits, g:ConqueGdb_SrcSplit, g:conque_gdb_default_split),
8191 \ 'buffer ' . bufnr("%"),
8192 \ 'wincmd w'])
8193
8194" Command to change path to GDB executable at runtime
8195command! -nargs=? -complete=file ConqueGdbExe call conque_gdb#change_gdb_exe(<q-args>)
8196
8197" Command to delete the buffers ConqueGdb has opened
8198command! -nargs=0 ConqueGdbBDelete call conque_gdb#delete_opened_buffers()
8199
8200" Command to write a command to the gdb tertminal
8201command! -nargs=+ ConqueGdbCommand call conque_gdb#command(<q-args>)
8202
8203if g:conque_gdb_gdb_py_support
8204 exe 'nnoremap <silent> ' . g:ConqueGdb_ToggleBreak . ' :call conque_gdb#toggle_breakpoint(expand("%:p"), line("."))<CR>'
8205else
8206 exe 'nnoremap <silent> ' . g:ConqueGdb_SetBreak . ' :call conque_gdb#command("break " . expand("%:p") . ":" . line("."))<CR>'
8207 exe 'nnoremap <silent> ' . g:ConqueGdb_DeleteBreak . ' :call conque_gdb#command("clear " . expand("%:p") . ":" . line("."))<CR>'
8208endif
8209exe 'nnoremap <silent> ' . g:ConqueGdb_Continue . ' :call conque_gdb#command("continue")<CR>'
8210exe 'nnoremap <silent> ' . g:ConqueGdb_Run . ' :call conque_gdb#command("run")<CR>'
8211exe 'nnoremap <silent> ' . g:ConqueGdb_Next . ' :call conque_gdb#command("next")<CR>'
8212exe 'nnoremap <silent> ' . g:ConqueGdb_Step . ' :call conque_gdb#command("step")<CR>'
8213exe 'nnoremap <silent> ' . g:ConqueGdb_Finish . ' :call conque_gdb#command("finish")<CR>'
8214exe 'nnoremap <silent> ' . g:ConqueGdb_Backtrace . ' :call conque_gdb#command("backtrace")<CR>'
8215exe 'nnoremap <silent> ' . g:ConqueGdb_Print . ' :call conque_gdb#print_word(expand("<cword>"))<CR>'
8216plugin/conque_term.vim [[[1
8217241
8218" FILE: plugin/conque/conque_term.vim {{{
8219" AUTHOR: Nico Raffo <nicoraffo@gmail.com>
8220" WEBSITE: http://conque.googlecode.com
8221" MODIFIED: 2011-09-12
8222" VERSION: 2.3, for Vim 7.0
8223" LICENSE:
8224" Conque - Vim terminal/console emulator
8225" Copyright (C) 2009-2011 Nico Raffo
8226"
8227" MIT License
8228"
8229" Permission is hereby granted, free of charge, to any person obtaining a copy
8230" of this software and associated documentation files (the "Software"), to deal
8231" in the Software without restriction, including without limitation the rights
8232" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8233" copies of the Software, and to permit persons to whom the Software is
8234" furnished to do so, subject to the following conditions:
8235"
8236" The above copyright notice and this permission notice shall be included in
8237" all copies or substantial portions of the Software.
8238"
8239" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8240" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8241" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8242" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8243" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8244" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8245" THE SOFTWARE.
8246" }}}
8247
8248" See docs/conque.txt for help or type :help ConqueTerm
8249
8250if exists('g:ConqueTerm_Loaded') || v:version < 700
8251 finish
8252endif
8253
8254" **********************************************************************************************************
8255" **** DEFAULT CONFIGURATION *******************************************************************************
8256" **********************************************************************************************************
8257
8258" DO NOT EDIT CONFIGURATION SETTINGS IN THIS FILE!
8259" Define these variables in your local .vimrc to over-ride the default values
8260
8261" {{{
8262
8263" Fast mode {{{
8264" Disables all features which could cause Conque to run slowly, including:
8265" * Disables terminal colors
8266" * Disables some multi-byte character handling
8267if !exists('g:ConqueTerm_FastMode')
8268 let g:ConqueTerm_FastMode = 0
8269endif " }}}
8270
8271" automatically go into insert mode when entering buffer {{{
8272if !exists('g:ConqueTerm_InsertOnEnter')
8273 let g:ConqueTerm_InsertOnEnter = 0
8274endif " }}}
8275
8276" Allow user to use <C-w> keys to switch window in insert mode. {{{
8277if !exists('g:ConqueTerm_CWInsert')
8278 let g:ConqueTerm_CWInsert = 0
8279endif " }}}
8280
8281" Choose key mapping to leave insert mode {{{
8282" If you choose something other than '<Esc>', then <Esc> will be sent to terminal
8283" Using a different key will usually fix Alt/Meta key issues
8284if !exists('g:ConqueTerm_EscKey')
8285 let g:ConqueTerm_EscKey = '<Esc>'
8286endif " }}}
8287
8288" Key mapping to send interrupt to terminal in insert and normal mode {{{
8289if !exists('g:ConqueTerm_Interrupt')
8290 let g:ConqueTerm_Interrupt = '<C-c>'
8291endif " }}}
8292
8293" Use this key to execute the current file in a split window. {{{
8294" THIS IS A GLOBAL KEY MAPPING
8295if !exists('g:ConqueTerm_ExecFileKey')
8296 let g:ConqueTerm_ExecFileKey = '<F11>'
8297endif " }}}
8298
8299" Use this key to send the current file contents to conque. {{{
8300" THIS IS A GLOBAL KEY MAPPING
8301if !exists('g:ConqueTerm_SendFileKey')
8302 let g:ConqueTerm_SendFileKey = '<F10>'
8303endif " }}}
8304
8305" Use this key to send selected text to conque. {{{
8306" THIS IS A GLOBAL KEY MAPPING
8307if !exists('g:ConqueTerm_SendVisKey')
8308 let g:ConqueTerm_SendVisKey = '<F9>'
8309endif " }}}
8310
8311" Use this key to toggle terminal key mappings. {{{
8312" Only mapped inside of Conque buffers.
8313if !exists('g:ConqueTerm_ToggleKey')
8314 let g:ConqueTerm_ToggleKey = '<F8>'
8315endif " }}}
8316
8317" Enable color. {{{
8318" If your apps use a lot of color it will slow down the shell.
8319" 0 - no terminal colors. You still will see Vim syntax highlighting.
8320" 1 - limited terminal colors (recommended). Past terminal color history cleared regularly.
8321" 2 - all terminal colors. Terminal color history never cleared.
8322if !exists('g:ConqueTerm_Color')
8323 let g:ConqueTerm_Color = 1
8324endif " }}}
8325
8326" Color mode. Windows ONLY {{{
8327" Set this variable to 'conceal' to use Vim's conceal mode for terminal colors.
8328" This makes colors render much faster, but has some odd baggage.
8329if !exists('g:ConqueTerm_ColorMode')
8330 let g:ConqueTerm_ColorMode = ''
8331endif " }}}
8332
8333" TERM environment setting {{{
8334if !exists('g:ConqueTerm_TERM')
8335 let g:ConqueTerm_TERM = 'vt100'
8336endif " }}}
8337
8338" Syntax for your buffer {{{
8339if !exists('g:ConqueTerm_Syntax')
8340 let g:ConqueTerm_Syntax = 'conque_term'
8341endif " }}}
8342
8343" Keep on updating the shell window after you've switched to another buffer {{{
8344if !exists('g:ConqueTerm_ReadUnfocused')
8345 let g:ConqueTerm_ReadUnfocused = 0
8346endif " }}}
8347
8348" Use this regular expression to highlight prompt {{{
8349if !exists('g:ConqueTerm_PromptRegex')
8350 let g:ConqueTerm_PromptRegex = '^\w\+@[0-9A-Za-z_.-]\+:[0-9A-Za-z_./\~,:-]\+\$'
8351endif " }}}
8352
8353" Choose which Python version to attempt to load first {{{
8354" Valid values are 2, 3 or 0 (no preference)
8355if !exists('g:ConqueTerm_PyVersion')
8356 let g:ConqueTerm_PyVersion = 2
8357endif " }}}
8358
8359" Path to python.exe. (Windows only) {{{
8360" By default, Conque will check C:\PythonNN\python.exe then will search system path
8361" If you have installed Python in an unusual location and it's not in your path, fill in the full path below
8362" E.g. 'C:\Program Files\Python\Python27\python.exe'
8363if !exists('g:ConqueTerm_PyExe')
8364 let g:ConqueTerm_PyExe = ''
8365endif " }}}
8366
8367" Automatically close buffer when program exits {{{
8368if !exists('g:ConqueTerm_CloseOnEnd')
8369 let g:ConqueTerm_CloseOnEnd = 0
8370endif " }}}
8371
8372" Send function key presses to terminal {{{
8373if !exists('g:ConqueTerm_SendFunctionKeys')
8374 let g:ConqueTerm_SendFunctionKeys = 0
8375endif " }}}
8376
8377" Session support {{{
8378if !exists('g:ConqueTerm_SessionSupport')
8379 let g:ConqueTerm_SessionSupport = 0
8380endif " }}}
8381
8382" hide Conque startup messages {{{
8383" messages should only appear the first 3 times you start Vim with a new version of Conque
8384" and include important Conque feature and option descriptions
8385" TODO - disabled and unused for now
8386if !exists('g:ConqueTerm_StartMessages')
8387 let g:ConqueTerm_StartMessages = 1
8388endif " }}}
8389
8390" Windows character code page {{{
8391" Leave at 0 to use current environment code page.
8392" Use 65001 for utf-8, although many console apps do not support it.
8393if !exists('g:ConqueTerm_CodePage')
8394 let g:ConqueTerm_CodePage = 0
8395endif " }}}
8396
8397" InsertCharPre support {{{
8398" Disable this feature by default, still in Beta
8399if !exists('g:ConqueTerm_InsertCharPre')
8400 let g:ConqueTerm_InsertCharPre = 0
8401endif " }}}
8402
8403" Don't show 'BELL!' message by default {{{
8404if !exists('g:ConqueTerm_ShowBell')
8405 let g:ConqueTerm_ShowBell = 0
8406endif " }}}
8407
8408" Option to change update time when conque term is not in focus {{{
8409" Zero means do not change the update time
8410if !exists('g:ConqueTerm_UnfocusedUpdateTime')
8411 let g:ConqueTerm_UnfocusedUpdateTime = 500
8412endif " }}}
8413
8414" Option to change update time when conque term is in focus {{{
8415" Zero means do not change the update time
8416if !exists('g:ConqueTerm_FocusedUpdateTime')
8417 let g:ConqueTerm_FocusedUpdateTime = 80
8418endif " }}}
8419
8420" }}}
8421
8422" **********************************************************************************************************
8423" **** Startup *********************************************************************************************
8424" **********************************************************************************************************
8425
8426" Startup {{{
8427
8428let g:ConqueTerm_Loaded = 1
8429let g:ConqueTerm_Idx = 0
8430let g:ConqueTerm_Version = 230
8431
8432command! -nargs=+ -complete=shellcmd ConqueTerm call conque_term#open(<q-args>)
8433command! -nargs=+ -complete=shellcmd ConqueTermSplit call conque_term#open(<q-args>, ['belowright split'])
8434command! -nargs=+ -complete=shellcmd ConqueTermVSplit call conque_term#open(<q-args>, ['belowright vsplit'])
8435command! -nargs=+ -complete=shellcmd ConqueTermTab call conque_term#open(<q-args>, ['tabnew'])
8436
8437" }}}
8438
8439" **********************************************************************************************************
8440" **** Global Mappings & Autocommands **********************************************************************
8441" **********************************************************************************************************
8442
8443" Startup {{{
8444
8445if exists('g:ConqueTerm_SessionSupport') && g:ConqueTerm_SessionSupport == 1
8446 autocmd SessionLoadPost * call conque_term#resume_session()
8447endif
8448
8449if maparg(g:ConqueTerm_ExecFileKey, 'n') == ''
8450 exe 'nnoremap <silent> ' . g:ConqueTerm_ExecFileKey . ' :call conque_term#exec_file()<CR>'
8451endif
8452
8453" }}}
8454
8455" Command for pasting contents of previous register.
8456command! -nargs=0 ConqueTermPaste sil exe ':normal a' . @"
8457
8458" vim:foldmethod=marker
8459syntax/conque_term.vim [[[1
8460113
8461" FILE: syntax/conque_term.vim {{{
8462" AUTHOR: Nico Raffo <nicoraffo@gmail.com>
8463" WEBSITE: http://conque.googlecode.com
8464" MODIFIED: 2011-09-12
8465" VERSION: 2.3, for Vim 7.0
8466" LICENSE:
8467" Conque - Vim terminal/console emulator
8468" Copyright (C) 2009-2011 Nico Raffo
8469"
8470" MIT License
8471"
8472" Permission is hereby granted, free of charge, to any person obtaining a copy
8473" of this software and associated documentation files (the "Software"), to deal
8474" in the Software without restriction, including without limitation the rights
8475" to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8476" copies of the Software, and to permit persons to whom the Software is
8477" furnished to do so, subject to the following conditions:
8478"
8479" The above copyright notice and this permission notice shall be included in
8480" all copies or substantial portions of the Software.
8481"
8482" THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
8483" IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
8484" FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
8485" AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
8486" LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
8487" OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
8488" THE SOFTWARE.
8489" }}}
8490
8491
8492" *******************************************************************************************************************
8493" MySQL *************************************************************************************************************
8494" *******************************************************************************************************************
8495
8496" TODO Move these to syntax which is only executed for mysql
8497"syn match MySQLTableBodyG "^\s*\w\+:\(.\+\)\=$" contains=MySQLTableHeadG,MySQLNullG,MySQLBool,MySQLNumberG,MySQLStorageClass oneline skipwhite skipnl
8498"syn match MySQLTableHeadG "^\s*\w\+:" contains=MySQLTableColon skipwhite contained
8499"syn match MySQLTableColon ":" contained
8500
8501syn match MySQLTableHead "^ *|.*| *$" nextgroup=MySQLTableDivide contains=MySQLTableBar oneline skipwhite skipnl
8502syn match MySQLTableBody "^ *|.*| *$" nextgroup=MySQLTableBody,MySQLTableEnd contains=MySQLTableBar,MySQLNull,MySQLBool,MySQLNumber,MySQLStorageClass oneline skipwhite skipnl
8503syn match MySQLTableEnd "^ *+[+=-]\++ *$" oneline
8504syn match MySQLTableDivide "^ *+[+=-]\++ *$" nextgroup=MySQLTableBody oneline skipwhite skipnl
8505syn match MySQLTableStart "^ *+[+=-]\++ *$" nextgroup=MySQLTableHead oneline skipwhite skipnl
8506syn match MySQLNull " NULL " contained contains=MySQLTableBar
8507syn match MySQLStorageClass " PRI " contained
8508syn match MySQLStorageClass " MUL " contained
8509syn match MySQLStorageClass " UNI " contained
8510syn match MySQLStorageClass " CURRENT_TIMESTAMP " contained
8511syn match MySQLStorageClass " auto_increment " contained
8512syn match MySQLTableBar "|" contained
8513syn match MySQLNumber "|\? *\d\+\(\.\d\+\)\? *|" contained contains=MySQLTableBar
8514syn match MySQLQueryStat "^\d\+ rows\? in set.*" oneline
8515syn match MySQLPromptLine "^.\?mysql> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline
8516syn match MySQLPromptLine "^ -> .*$" contains=MySQLKeyword,MySQLPrompt,MySQLString oneline
8517syn match MySQLPrompt "^.\?mysql>" contained oneline
8518syn match MySQLPrompt "^ ->" contained oneline
8519syn case ignore
8520syn keyword MySQLKeyword select count max sum avg date show table tables status like as from left right outer inner join contained
8521syn keyword MySQLKeyword where group by having limit offset order desc asc show contained and interval is null on
8522syn case match
8523syn region MySQLString start=+'+ end=+'+ skip=+\\'+ contained oneline
8524syn region MySQLString start=+"+ end=+"+ skip=+\\"+ contained oneline
8525syn region MySQLString start=+`+ end=+`+ skip=+\\`+ contained oneline
8526
8527
8528hi def link MySQLPrompt Identifier
8529hi def link MySQLTableHead Title
8530hi def link MySQLTableBody Normal
8531hi def link MySQLBool Boolean
8532hi def link MySQLStorageClass StorageClass
8533hi def link MySQLNumber Number
8534hi def link MySQLKeyword Keyword
8535hi def link MySQLString String
8536
8537" terms which have no reasonable default highlight group to link to
8538hi MySQLTableHead term=bold cterm=bold gui=bold
8539if &background == 'dark'
8540 hi MySQLTableEnd term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444
8541 hi MySQLTableDivide term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444
8542 hi MySQLTableStart term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444
8543 hi MySQLTableBar term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444
8544 hi MySQLNull term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444
8545 hi MySQLQueryStat term=NONE cterm=NONE gui=NONE ctermfg=238 guifg=#444444
8546elseif &background == 'light'
8547 hi MySQLTableEnd term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e
8548 hi MySQLTableDivide term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e
8549 hi MySQLTableStart term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e
8550 hi MySQLTableBar term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e
8551 hi MySQLNull term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e
8552 hi MySQLQueryStat term=NONE cterm=NONE gui=NONE ctermfg=247 guifg=#9e9e9e
8553endif
8554
8555
8556" *******************************************************************************************************************
8557" Bash **************************************************************************************************************
8558" *******************************************************************************************************************
8559
8560" Typical Prompt
8561if g:ConqueTerm_PromptRegex != ''
8562 silent execute "syn match ConquePromptLine '" . g:ConqueTerm_PromptRegex . ".*$' contains=ConquePrompt,ConqueString oneline"
8563 silent execute "syn match ConquePrompt '" . g:ConqueTerm_PromptRegex . "' contained oneline"
8564 hi def link ConquePrompt Identifier
8565endif
8566
8567" Strings
8568syn region ConqueString start=+'+ end=+'+ skip=+\\'+ contained oneline
8569syn region ConqueString start=+"+ end=+"+ skip=+\\"+ contained oneline
8570syn region ConqueString start=+`+ end=+`+ skip=+\\`+ contained oneline
8571hi def link ConqueString String
8572
8573" vim: foldmethod=marker