1 #ls###############################################################################
4 # purpose: allows execution of shell commands in a vim buffer
6 # author: brian m sturk bsturk@adelphia.net,
7 # http://users.adelphia.net/~bsturk
12 # usage, etc: see vimsh.readme
13 # history: see ChangeLog
14 # in the works: see TODO
16 ###############################################################################
18 import vim
, sys
, os
, string
, signal
, re
, time
20 ## NOTE: If you're having a problem running vimsh, please
21 ## change the 0 to a 1 for _DEBUG_ and send me an email
27 ################################################################################
30 if sys
.platform
== 'win32':
35 import pty
, tty
, select
39 print 'vimsh: import error'
41 ################################################################################
43 ################################################################################
46 def __init__( self
, _sh
, _arg
, _filename
):
50 self
.filename
= _filename
52 self
.prompt_line
, self
.prompt_cursor
= self
.get_vim_cursor_pos()
54 self
.password_regex
= [ '^\s*Password:', ## su, ssh, ftp
55 'password:', ## ???, seen this somewhere
56 'Password required' ] ## other ftp clients
58 self
.last_cmd_executed
= "foobar"
59 self
.keyboard_interrupt
= 0
61 self
.buffer = vim
.current
.buffer
63 ################################################################################
65 def setup_pty( self
, _use_pty
):
67 self
.using_pty
= _use_pty
71 ## The lower this number is the more responsive some commands
72 ## may be ( printing prompt, ls ), but also the quicker others
73 ## may timeout reading their output ( ping, ftp )
77 ## Hack to get pty name until I can figure out to get name
78 ## of slave pty using pty.fork() I've tried everything
79 ## including using all of the python src for pty.fork().
80 ## I'm probably trying to do something I can't do. However,
81 ## there does seem to be a std call named ptsname() which
82 ## returns the slave pty name i.e. /dev/pty/XX
84 ## Assumption is, that between the dummy call to
85 ## master_open is done and the pty.fork happens, we'll be
86 ## the next pty entry after the one from pty.master_open()
87 ## According to SysV docs it will look for the first
88 ## unused, so this shouldn't be too bad besides its looks.
89 ## Only have to make sure they're not already in use and
90 ## if it is try the next one etc.
92 self
.master
, pty_name
= pty
.master_open()
93 dbg_print ( 'setup_pty: slave pty name is ' + pty_name
)
95 self
.pid
, self
.fd
= pty
.fork()
101 signal
.signal( signal
.SIGCHLD
, self
.sigchld_handler
)
105 ## In spawned shell process, NOTE: any 'print'ing done within
106 ## here will corrupt vim.
108 attrs
= tty
.tcgetattr( 1 )
110 attrs
[ 6 ][ tty
.VMIN
] = 1
111 attrs
[ 6 ][ tty
.VTIME
] = 0
112 attrs
[ 0 ] = attrs
[ 0 ] | tty
.BRKINT
113 attrs
[ 0 ] = attrs
[ 0 ] & tty
.IGNBRK
114 attrs
[ 3 ] = attrs
[ 3 ] & ~tty
.ICANON
& ~tty
.ECHO
116 tty
.tcsetattr( 1, tty
.TCSANOW
, attrs
)
119 os
.execv( self
.sh
, [ self
.sh
, self
.arg
] )
122 os
.execv( self
.sh
, [ self
.sh
, ] )
127 attrs
= tty
.tcgetattr( 1 )
129 termios_keys
= attrs
[ 6 ]
132 dbg_print ( 'setup_pty: tcgetattr failed' )
135 # Get *real* key-sequence for standard input keys, i.e. EOF
137 self
.eof_key
= termios_keys
[ tty
.VEOF
]
138 self
.eol_key
= termios_keys
[ tty
.VEOL
]
139 self
.erase_key
= termios_keys
[ tty
.VERASE
]
140 self
.intr_key
= termios_keys
[ tty
.VINTR
]
141 self
.kill_key
= termios_keys
[ tty
.VKILL
]
142 self
.susp_key
= termios_keys
[ tty
.VSUSP
]
146 ## Use pipes on Win32. not as reliable/nice. works OK but with limitations.
153 dbg_print ( 'setup_pty: using windows extensions' )
154 self
.stdin
, self
.stdout
, self
.stderr
= win32pipe
.popen3( self
.sh
+ " " + self
.arg
)
158 dbg_print ( 'setup_pty: not using windows extensions' )
159 self
.stdout
, self
.stdin
, self
.stderr
= popen2
.popen3( self
.sh
+ " " + self
.arg
, -1, 'b' )
161 self
.outd
= self
.stdout
.fileno()
162 self
.ind
= self
.stdin
.fileno ()
163 self
.errd
= self
.stderr
.fileno()
165 self
.intr_key
= '\x03'
166 self
.eof_key
= '\x04'
168 ################################################################################
170 def execute_cmd( self
, _cmd
= None, _null_terminate
= 1 ):
172 dbg_print ( 'execute_cmd: Entered cmd is ' + str( _cmd
) )
174 if self
.keyboard_interrupt
:
175 dbg_print( 'execute_cmd: keyboard interrupt earlier, cleaning up' )
177 self
.page_output( 1 )
178 self
.keyboard_interrupt
= 0
182 ## This is the main worker function
185 print "" ## Clears the ex command window
188 cur_line
, cur_row
= self
.get_vim_cursor_pos()
192 ## Grab everything from the prompt to the current cursor position.
194 _cmd
= cur
[ self
.prompt_line
- 1 : cur_line
] # whole line
195 _cmd
[0] = _cmd
[0][ ( self
.prompt_cursor
- 1 ) : ] # remove prompt, zero based slicing
197 if re
.search( r
'^\s*\bclear\b', _cmd
[0] ) or re
.search( r
'^\s*\bcls\b', _cmd
[0] ):
199 dbg_print ( 'execute_cmd: clear detected' )
200 self
.clear_screen( True )
202 elif re
.search( r
'^\s*\exit\b', _cmd
[0] ):
204 dbg_print ( 'execute_cmd: exit detected' )
205 self
.handle_exit_cmd( _cmd
)
209 dbg_print ( 'execute_cmd: other command executed' )
213 self
.write( c
+ '\n' )
219 vim
.command( "startinsert!" )
221 self
.last_cmd_executed
= _cmd
[0]
223 except KeyboardInterrupt:
225 dbg_print( 'execute_cmd: in keyboard interrupt exception, sending SIGINT' )
227 self
.keyboard_interrupt
= 1
229 ## TODO: Sending Ctrl-C isn't working on Windows yet, so
230 ## executing something like 'findstr foo' will hang.
232 if sys
.platform
!= 'win32':
235 ################################################################################
237 def end_exe_line( self
):
239 ## read anything that's on stdout after a command is executed
241 dbg_print( 'end_exe_line: enter' )
246 vim
.command( "normal G$" )
249 self
.check_for_passwd()
251 ################################################################################
253 def write( self
, _cmd
):
255 dbg_print( 'write: writing out --> ' + _cmd
)
257 os
.write( self
.ind
, _cmd
)
259 ################################################################################
261 def read( self
, _buffer
):
263 num_iterations
= 0 ## counter for periodic redraw
264 iters_before_redraw
= 10
265 any_lines_read
= 0 ## sentinel for reading anything at all
267 if sys
.platform
== 'win32':
268 iters_before_redraw
= 1
272 r
, w
, e
= select
.select( [ self
.outd
], [], [], self
.delay
)
275 r
= [1,] ## pipes, unused, fake it out so I don't have to special case
282 lines
= os
.read( self
.outd
, 32 )
285 lines
= self
.pipe_read( self
.outd
, 2048 )
288 dbg_print( 'read: No more data on stdout pipe_read' )
290 r
= [] ## sentinel, end of data to read
296 lines
= self
.process_read( lines
)
297 self
.print_lines( lines
, _buffer
)
299 ## Give vim a little cpu time, so programs that spit
300 ## output or are long operations seem more responsive
302 if not num_iterations
% iters_before_redraw
:
303 dbg_print( 'read: Letting vim redraw' )
304 vim
.command( 'call VimShRedraw()' )
307 dbg_print( 'read: end of data to self.read()' )
308 self
.end_read( any_lines_read
)
312 ################################################################################
314 def process_read( self
, _lines
):
316 dbg_print( 'process_read: Raw lines read from stdout:' )
319 lines_to_print
= string
.split( _lines
, '\n' )
321 ## On windows cmd is "echoed" and output sometimes has leading empty line
323 if sys
.platform
== 'win32':
324 m
= re
.search( re
.escape( self
.last_cmd_executed
.strip() ), lines_to_print
[ 0 ] )
326 if m
!= None or lines_to_print
[ 0 ] == "":
327 dbg_print( 'process_read: Win32, removing leading blank line' )
328 lines_to_print
= lines_to_print
[ 1: ]
330 num_lines
= len( lines_to_print
)
332 ## Split on '\n' sometimes returns n + 1 entries
335 last_line
= lines_to_print
[ num_lines
- 1 ].strip()
338 lines_to_print
= lines_to_print
[ :-1 ]
340 errors
= self
.chk_stderr()
343 dbg_print( 'process_read: Prepending stderr --> ' )
344 lines_to_print
= errors
+ lines_to_print
346 return lines_to_print
348 ################################################################################
350 def print_lines( self
, _lines
, _buffer
):
352 num_lines
= len( _lines
)
354 dbg_print( 'print_lines: Number of lines to print--> ' + str( num_lines
) )
356 for line_iter
in _lines
:
358 dbg_print( 'print_lines: Current line is --> %s' % line_iter
)
362 while re
.search( '\r$', line_iter
):
364 dbg_print( 'print_lines: removing trailing ^M' )
366 line_iter
= line_iter
[ :-1 ] # Force it
369 ## Jump to the position of the last insertion to the buffer
370 ## if it was a new line it should be 1, if it wasn't
371 ## terminated by a '\n' it should be the end of the string
373 vim
.command( "normal " + str( self
.prompt_cursor
) + "|" )
375 cur_line
, cur_row
= self
.get_vim_cursor_pos()
376 dbg_print( 'print_lines: After jumping to end of last cmd: line %d row %d' % ( cur_line
, cur_row
) )
378 dbg_print( 'print_lines: Pasting ' + line_iter
+ ' to current line' )
379 _buffer
[ cur_line
- 1 ] += line_iter
381 ## If there's a '\n' or using pipes and it's not the last line
383 if not self
.using_pty
or m
!= None:
385 dbg_print( 'print_lines: Appending new line since ^M or not using pty' )
388 vim
.command( "normal G$" )
389 vim
.command( "startinsert!" )
391 self
.prompt_line
, self
.prompt_cursor
= self
.get_vim_cursor_pos()
392 dbg_print( 'print_lines: Saving cursor location: line %d row %d ' % ( self
.prompt_line
, self
.prompt_cursor
) )
394 ################################################################################
396 def end_read( self
, any_lines_read
):
398 cur_line
, cur_row
= self
.get_vim_cursor_pos( )
400 if not self
.using_pty
and any_lines_read
:
402 ## remove last line for last read only if lines were
403 ## read from stdout. TODO: any better way to do this?
405 vim
.command( 'normal dd' )
407 vim
.command( "normal G$" )
408 vim
.command( "startinsert!" )
410 ## Tuck away location, all data read is in buffer
412 self
.prompt_line
, self
.prompt_cursor
= self
.get_vim_cursor_pos()
413 dbg_print( 'end_read: Saving cursor location: line %d row %d ' % ( self
.prompt_line
, self
.prompt_cursor
) )
415 ################################################################################
417 def page_output( self
, _add_new_line
= 0 ):
419 dbg_print( 'page_output: enter' )
421 ## read anything that's left on stdout
428 vim
.command( "normal G$" )
432 self
.check_for_passwd()
434 vim
.command( "startinsert!" )
436 ################################################################################
440 # NOTE: Only called via autocommand
442 dbg_print( 'cleanup: enter' )
444 # Remove autocommand so we don't get multiple calls
446 vim
.command( 'au! BufDelete ' + self
.filename
)
448 remove_buf( self
.filename
)
450 if self
.shell_exited
:
451 dbg_print( 'cleanup: process is already dead, nothing to do' )
456 if not self
.using_pty
:
458 os
.close( self
.outd
)
460 os
.close( self
.errd
) ## all the same if pty
463 os
.kill( self
.pid
, signal
.SIGKILL
)
466 dbg_print( 'cleanup: Exception, process probably already killed' )
468 ################################################################################
470 def send_intr( self
):
472 dbg_print( 'send_intr: enter' )
474 if show_workaround_msgs
== '1':
475 print 'If you do NOT see a prompt in the vimsh buffer, press F5 or go into insert mode and press Enter'
476 print 'If you need a new prompt press F4'
477 print 'NOTE: To disable this help message set \'g:vimsh_show_workaround_msgs\' to 0 in your .vimrc'
479 ## This triggers another KeyboardInterrupt async
482 dbg_print( 'send_intr: writing intr_key' )
483 self
.write( self
.intr_key
)
485 self
.page_output( 1 )
487 except KeyboardInterrupt:
489 dbg_print( 'send_intr: caught KeyboardInterrupt in send_intr' )
492 ################################################################################
494 def send_eof( self
):
496 dbg_print( 'send_eof: enter' )
498 try: ## could cause shell to exit
500 self
.write( self
.eof_key
)
501 self
.page_output( 1 )
505 dbg_print( 'send_eof: exception' )
507 ## shell exited, self.shell_exited may not have been set yet in
510 dbg_print( 'send_eof: shell_exited is ' + str( self
.shell_exited
) )
514 ################################################################################
516 def handle_exit_cmd( self
, _cmd
):
518 ## Exit was typed, could be the spawned shell, or a subprocess like
521 dbg_print( 'handle_exit_cmd: enter' )
523 if not self
.shell_exited
: ## process is still around
525 try: ## could cause shell to exit
527 dbg_print ( 'handle_exit_cmd: shell is still around, writing exit command' )
528 self
.write( _cmd
[0] + '\n' )
531 vim
.command( "startinsert!" )
535 dbg_print( 'handle_exit_cmd: exception' )
537 ## shell exited, self.shell_exited may not have been set yet in
540 dbg_print( 'handle_exit_cmd: shell_exited is ' + str( self
.shell_exited
) )
544 ################################################################################
546 def exit_shell( self
):
548 dbg_print( 'exit_shell: enter' )
550 ## when exiting this way can't have the autocommand
551 ## for BufDelete run. It crashes vim. TODO: Figure this out.
553 vim
.command( 'stopinsert' )
554 vim
.command( 'au! BufDelete ' + self
.filename
)
555 vim
.command( 'bdelete! ' + self
.filename
)
557 remove_buf( self
.filename
)
559 ################################################################################
561 def sigchld_handler( self
, sig
, frame
):
563 dbg_print( 'sigchld_handler: caught SIGCHLD' )
567 ################################################################################
569 def sigint_handler( self
, sig
, frame
):
571 dbg_print( 'sigint_handler: caught SIGINT' )
576 ################################################################################
580 ## This routine cannot do anything except for marking that the original
581 ## shell process has gone away if it has. This is due to the async
582 ## nature of signals.
584 if os
.waitpid( self
.pid
, os
.WNOHANG
)[0]:
586 self
.shell_exited
= 1
587 dbg_print( 'waitpid: shell exited' )
591 dbg_print( 'waitpid: shell hasn\'t exited, ignoring' )
593 ################################################################################
595 def set_timeout( self
):
599 while not timeout_ok
:
602 vim
.command( 'let timeout = input( "Enter new timeout in seconds (i.e. 0.1), currently set to ' + str( self
.delay
) + ' : " )' )
604 except KeyboardInterrupt:
607 timeout
= vim
.eval( "timeout" )
609 if timeout
== "": ## usr cancelled dialog, break out
613 timeout
= float( timeout
)
616 print ' ---> New timeout is ' + str( timeout
) + ' seconds'
620 ################################################################################
622 def clear_screen( self
, in_insert_mode
):
624 dbg_print( 'clear_screen: insert mode is ' + str( in_insert_mode
) )
626 self
.write( "" + "\n" ) ## new prompt
629 vim
.command( "normal ggdG" )
634 vim
.command( "normal zt" )
637 vim
.command( "startinsert!" )
640 vim
.command( 'stopinsert' )
642 ################################################################################
644 def new_prompt( self
):
646 self
.execute_cmd( [""] ) # just press enter
648 vim
.command( "normal G$" )
649 vim
.command( "startinsert!" )
651 ################################################################################
653 def get_vim_cursor_pos( self
):
655 cur_line
, cur_row
= vim
.current
.window
.cursor
657 return cur_line
, cur_row
+ 1
659 ################################################################################
661 def check_for_passwd( self
):
663 cur_line
, cur_row
= self
.get_vim_cursor_pos()
665 prev_line
= self
.buffer[ cur_line
- 1 ]
667 for regex
in self
.password_regex
:
669 if re
.search( regex
, prev_line
):
672 vim
.command( 'let password = inputsecret( "Password? " )' )
674 except KeyboardInterrupt:
677 password
= vim
.eval( "password" )
679 self
.execute_cmd( [password
] ) ## recursive call here...
681 ################################################################################
683 def pipe_read( self
, pipe
, minimum_to_read
):
685 ## Hackaround since Windows doesn't support select() except for sockets.
687 dbg_print( 'pipe_read: minimum to read is ' + str( minimum_to_read
) )
688 dbg_print( 'pipe_read: sleeping for ' + str( self
.delay
) + ' seconds' )
690 time
.sleep( self
.delay
)
693 count
= os
.fstat( pipe
)[stat
.ST_SIZE
]
697 dbg_print( 'pipe_read: initial count via fstat is ' + str( count
) )
701 tmp
= os
.read( pipe
, 1 )
704 count
= os
.fstat( pipe
)[stat
.ST_SIZE
]
707 dbg_print( 'pipe_read: count ' + str( count
) + ' but nothing read' )
710 ## Be sure to break the read, if asked to do so,
711 ## after we've read in a line termination.
713 if minimum_to_read
!= 0 and len( data
) > 0 and data
[ len( data
) -1 ] == '\n':
715 if len( data
) >= minimum_to_read
:
716 dbg_print( 'pipe_read: found termination and read at least the minimum asked for' )
720 dbg_print( 'pipe_read: not all of the data has been read: count is ' + str( count
) )
722 dbg_print( 'pipe_read: returning' )
726 ################################################################################
728 def chk_stderr( self
):
731 dbg_print( 'chk_stderr: enter' )
733 if sys
.platform
== 'win32':
735 err_txt
= self
.pipe_read( self
.errd
, 0 )
736 errors
= string
.split( err_txt
, '\n' )
738 num_lines
= len( errors
)
739 dbg_print( 'chk_stderr: Number of error lines is ' + `num_lines`
)
741 last_line
= errors
[ num_lines
- 1 ].strip()
744 dbg_print( 'chk_stderr: Removing last line, it\'s empty' )
745 errors
= errors
[ :-1 ]
749 ################################################################################
751 #def thread_worker( self ):
754 ## Not working 100% yet
755 #thread.start_new_thread( self.thread_worker, () )
762 ## This doesn't seem to work
763 ## vim.command( 'let dummy = remote_send( v:servername, "<C-\><C-N>:python periodic( \'' + self.filename + '\' )<CR>" )' )
766 #vim.command( 'let dummy = v:servername' )
767 #servername = vim.eval( "dummy" )
768 #os.system( 'gvim --remote-send --servername ' + servername + '"<C-\><C-N>:python periodic( ' + self.filename + ')<CR>"' )
771 # os.system( 'gvim --remote-expr ":python periodic( \'' + self.filename + '\' )<CR>"' )
773 ## This works well so far ( haven't testing thoroughly though )
774 ## only problem is it changes to normal mode while the user may
777 #os.system( 'gvim --remote-send "<C-\><C-N>:python periodic( \'' + self.filename + '\' )<CR>"' )
782 ################################################################################
783 ## Helper functions ##
784 ################################################################################
786 def test_and_set( vim_var
, default_val
):
790 vim
.command( 'let dummy = exists( "' + vim_var
+ '" )' )
791 exists
= vim
.eval( "dummy" )
793 ## exists will always be a string representation of the evaluation
796 ret
= vim
.eval( vim_var
)
797 dbg_print( 'test_and_set: variable ' + vim_var
+ ' exists, using supplied ' + ret
)
800 dbg_print( 'test_and_set: variable ' + vim_var
+ ' doesn\'t exist, using default ' + ret
)
804 ################################################################################
806 def dump_str_as_hex( _str
):
810 print 'length of string is ' + str( len( _str
) )
812 for x
in range( 0, len( _str
) ):
813 hex_str
= hex_str
+ hex( ord( _str
[x
] ) ) + "\n"
815 print 'raw line ( hex ) is:'
818 ################################################################################
820 def dbg_print( _str
):
825 ################################################################################
827 def new_buf( _filename
):
829 ## If a buffer named vimsh doesn't exist create it, if it
830 ## does, switch to it. Use the config options for splitting etc.
835 vim
.command( 'let dummy = buflisted( "' + filename
+ '" )' )
836 exists
= vim
.eval( "dummy" )
839 dbg_print( 'new_buf: buffer ' + filename
+ ' doesn\'t exist' )
841 if split_open
== '0':
842 vim
.command( 'edit ' + filename
)
845 vim
.command( 'new ' + filename
)
847 vim
.command( 'setlocal buftype=nofile' )
848 vim
.command( 'setlocal bufhidden=hide' )
849 vim
.command( 'setlocal noswapfile' )
850 vim
.command( 'setlocal tabstop=4' )
851 vim
.command( 'setlocal modifiable' )
852 vim
.command( 'setlocal nowrap' )
853 vim
.command( 'setlocal textwidth=999' )
854 vim
.command( 'setfiletype vim_shell' )
856 vim
.command( 'au BufDelete ' + filename
+ ' :python lookup_buf( "' + filename
+ '" ).cleanup()' )
858 vim
.command( 'inoremap <buffer> <CR> <ESC>:python lookup_buf( "' + filename
+ '" ).execute_cmd()<CR>' )
860 vim
.command( 'inoremap <buffer> ' + timeout_key
+ ' <ESC>:python lookup_buf( "' + filename
+ '" ).set_timeout()<CR>' )
861 vim
.command( 'nnoremap <buffer> ' + timeout_key
+ ' :python lookup_buf( "' + filename
+ '" ).set_timeout()<CR>' )
863 vim
.command( 'inoremap <buffer> ' + new_prompt_key
+ ' <ESC>:python lookup_buf ( "' + filename
+ '" ).new_prompt()<CR>' )
864 vim
.command( 'nnoremap <buffer> ' + new_prompt_key
+ ' :python lookup_buf( "' + filename
+ '" ).new_prompt()<CR>' )
866 vim
.command( 'inoremap <buffer> ' + page_output_key
+ ' <ESC>:python lookup_buf ( "' + filename
+ '" ).page_output()<CR>' )
867 vim
.command( 'nnoremap <buffer> ' + page_output_key
+ ' :python lookup_buf( "' + filename
+ '" ).page_output()<CR>' )
869 vim
.command( 'inoremap <buffer> ' + eof_signal_key
+ ' <ESC>:python lookup_buf ( "' + filename
+ '" ).send_eof()<CR>' )
870 vim
.command( 'nnoremap <buffer> ' + eof_signal_key
+ ' :python lookup_buf( "' + filename
+ '" ).send_eof()<CR>' )
872 vim
.command( 'inoremap <buffer> ' + intr_signal_key
+ ' <ESC>:python lookup_buf ( "' + filename
+ '" ).send_intr()<CR>' )
873 vim
.command( 'nnoremap <buffer> ' + intr_signal_key
+ ' :python lookup_buf( "' + filename
+ '" ).send_intr()<CR>' )
875 vim
.command( 'inoremap <buffer> ' + clear_key
+ ' <ESC>:python lookup_buf ( "' + filename
+ '" ).clear_screen( True )<CR>')
876 vim
.command( 'nnoremap <buffer> ' + clear_key
+ ' :python lookup_buf( "' + filename
+ '").clear_screen( False )<CR>' )
882 dbg_print( 'new_buf: file ' + filename
+ ' exists' )
884 vim
.command( "edit " + filename
)
888 dbg_print( 'new_buf: exception!' + str( sys
.exc_info()[0] ) )
890 ################################################################################
892 def spawn_buf( _filename
):
894 exists
= new_buf( _filename
)
898 dbg_print( 'spawn_buf: buffer doesn\'t exist so creating a new one' )
900 cur
= vim
.current
.buffer
902 ## Make vimsh associate buffer with _filename and add to list of buffers
903 vim_shell
= vimsh( sh
, arg
, _filename
)
905 _BUFFERS_
.append( ( _filename
, vim_shell
) )
906 vim_shell
.setup_pty( use_pty
)
908 vim_shell
.read( cur
)
909 cur_line
, cur_row
= vim_shell
.get_vim_cursor_pos()
911 ## last line *should* be prompt, tuck it away for syntax hilighting
912 hi_prompt
= cur
[ cur_line
- 1 ]
916 dbg_print( 'main: buffer does exist' )
917 vim
.command( "normal G$" )
918 vim_shell
= lookup_buf( _filename
)
920 vim
.command( "startinsert!" )
922 ################################################################################
924 def periodic( _filename
):
926 print( 'periodic: enter for ' + _filename
)
932 vim_shell
= lookup_buf( _filename
)
934 if vim_shell
== None:
935 dbg_print( 'periodic: couldn\'t find buffer' )
941 r
, w
, e
= select
.select( [ vim_shell
.outd
], [], [], 0.1 )
946 dbg_print( 'periodic: new data to read on pty' )
948 vim_shell
.page_output()
953 ################################################################################
955 def lookup_buf( _filename
):
957 for key
, val
in _BUFFERS_
:
961 dbg_print( 'lookup_buf: found match ' + str( val
) )
964 dbg_print( 'lookup_buf: couldn\'t find match for ' + _filename
)
968 ################################################################################
970 def remove_buf( _filename
):
972 dbg_print ( 'remove_buf: looking for ' + _filename
+ ' to remove from buffer list' )
976 for key
, val
in _BUFFERS_
:
983 if ( len( _BUFFERS_
) >= idx
) & ( len( _BUFFERS_
) != 0 ):
985 dbg_print ( 'remove_buf: removing buffer from list' )
988 ############################# customization ###################################
990 # Don't edit the lines below, instead set the g:<variable> in your
991 # .vimrc to the value you would like to use. For numeric settings
992 # *DO NOT* put quotes around them. The quotes are only needed in
993 # this script. See vimsh.readme for more details
995 ###############################################################################
997 ## Allow pty prompt override, useful if you have an ansi prompt, etc
1000 prompt_override
= int( test_and_set( "g:vimsh_pty_prompt_override", "1" ) )
1002 ## Prompt override, used for pty enabled. Just use a very simple prompt
1003 ## and make no definitive assumption about the shell being used if
1004 ## vimsh_prompt_pty is not set. This will only be used if
1005 ## vimsh_pty_prompt_override (above) is 1.
1007 ## NOTE: [t]csh doesn't use an environment variable for setting the prompt so setting
1008 ## an override prompt will not work.
1013 new_prompt
= test_and_set( 'g:vimsh_prompt_pty', r
'> ' )
1015 os
.environ
['prompt'] = new_prompt
1016 os
.environ
['PROMPT'] = new_prompt
1017 os
.environ
['PS1'] = new_prompt
1019 ## shell program and supplemental arg to shell. If no supplemental
1023 if sys
.platform
== 'win32':
1024 sh
= test_and_set( 'g:vimsh_sh', 'cmd.exe' ) # NT/Win2k
1025 arg
= test_and_set( 'g:vimsh_sh_arg', '-i' )
1028 sh
= test_and_set( 'g:vimsh_sh', '/bin/sh' ) # Unix
1029 arg
= test_and_set( 'g:vimsh_sh_arg', '-i' )
1031 ## clear shell command behavior
1032 # 0 just scroll for empty screen
1033 # 1 delete contents of buffer
1036 clear_all
= test_and_set( "g:vimsh_clear_all", "0" )
1038 ## new vimsh window behavior
1039 # 0 use current buffer if not modified
1043 split_open
= test_and_set( "g:vimsh_split_open", "1" )
1045 ## show helpful (hopefully) messages, mostly for issues that aren't resolved but
1047 # 0 don't show them, you know what your doing
1051 show_workaround_msgs
= test_and_set( "g:vimsh_show_workaround_msgs", "1" )
1053 ## Prompts for the timeouts for read( s )
1055 # set low for local usage, higher for network apps over slower link
1056 # 0.1 sec is the lowest setting
1057 # over a slow link ( 28.8 ) 1+ seconds works well
1060 timeout_key
= test_and_set( "g:vimsh_timeout_key", "<F3>" )
1062 ## Create a new prompt at the bottom of the buffer, useful if stuck.
1063 ## Please try to give me a bug report of how you got stuck if possible.
1065 new_prompt_key
= test_and_set( "g:vimsh_new_prompt_key", "<F4>" )
1067 ## If output just stops, could be because of short timeouts, allow a key
1068 ## to attempt to read more, rather than sending the <CR> which keeps
1069 ## spitting out prompts.
1071 page_output_key
= test_and_set( "g:vimsh_page_output_key", "<F5>" )
1073 ## Send a process SIGINT (INTR) (usually control-C)
1075 intr_signal_key
= test_and_set( "g:vimsh_intr_key", "<C-c>" )
1077 ## Send a process EOF (usually control-D) python needs it to
1078 ## quit interactive shell.
1080 eof_signal_key
= test_and_set( "g:vimsh_eof_key", "<C-d>" )
1084 clear_key
= test_and_set( "g:vimsh_clear_key", "<C-l>" )
1086 ############################ end customization #################################