"============================================================================= " FILE: iexe.vim " AUTHOR: Shougo Matsushita " License: MIT license {{{ " Permission is hereby granted, free of charge, to any person obtaining " a copy of this software and associated documentation files (the " "Software"), to deal in the Software without restriction, including " without limitation the rights to use, copy, modify, merge, publish, " distribute, sublicense, and/or sell copies of the Software, and to " permit persons to whom the Software is furnished to do so, subject to " the following conditions: " " The above copyright notice and this permission notice shall be included " in all copies or substantial portions of the Software. " " THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS " OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF " MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. " IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY " CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, " TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE " SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. " }}} "============================================================================= let s:manager = vimshell#util#get_vital().import('Vim.Buffer') let s:command = { \ 'name' : 'iexe', \ 'kind' : 'execute', \ 'description' : 'iexe [{options}...] {command}', \} function! s:command.execute(commands, context) abort "{{{ " Interactive execute command. if empty(a:commands) return endif let commands = a:commands let [commands[0].args, options] = vimshell#parser#getopt(commands[0].args, { \ 'arg=' : ['--encoding', '--split'], \ }, { \ '--encoding' : vimshell#interactive#get_default_encoding(a:commands), \ '--split' : g:vimshell_split_command, \ }) let args = commands[0].args if empty(args) return endif if has_key(g:vimshell_interactive_cygwin_commands, fnamemodify(args[0], ':r')) " Use Cygwin pty. call insert(args, 'fakecygpty') endif let use_cygpty = vimshell#util#is_windows() && \ args[0] =~ '^fakecygpty\%(\.exe\)\?$' if use_cygpty if !executable('fakecygpty') call vimshell#error_line(a:context.fd, \ 'iexe: "fakecygpty.exe" is required. Please install it.') return endif " Get program path from g:vimshell_interactive_cygwin_path. if len(args) < 2 call vimshell#error_line(a:context.fd, 'iexe: command is required.') return endif let args[1] = vimproc#get_command_name( \ args[1], g:vimshell_interactive_cygwin_path) endif let cmdname = fnamemodify(args[0], ':r') if !use_cygpty && has_key(g:vimshell_interactive_command_options, cmdname) for arg in vimproc#parser#split_args( \ g:vimshell_interactive_command_options[cmdname]) call add(args, arg) endfor endif if vimshell#util#is_windows() && cmdname == 'cmd' " Run cmdproxy.exe instead of cmd.exe. if !executable('cmdproxy.exe') call vimshell#error_line(a:context.fd, \ 'iexe: "cmdproxy.exe" is not found. Please install it.') return endif let args[0] = 'cmdproxy.exe' endif " Encoding conversion. if options['--encoding'] != '' && options['--encoding'] != &encoding for command in commands call map(command.args, \ 'vimproc#util#iconv(v:val, &encoding, options["--encoding"])') endfor endif if exists('b:interactive') && !empty(b:interactive.process) \ && b:interactive.process.is_valid " Delete zombie process. call vimshell#interactive#force_exit() endif " Initialize. let home_save = {} if use_cygpty && g:vimshell_interactive_cygwin_home != '' " Set $HOME. let home_save = vimshell#util#set_variables({ \ '$HOME' : g:vimshell_interactive_cygwin_home, \}) endif try let [new_pos, old_pos] = vimshell#helpers#split(options['--split']) " Set environment variables. let environments_save = vimshell#util#set_variables({ \ '$TERM' : g:vimshell_environment_term, \ '$TERMCAP' : 'COLUMNS=' . vimshell#helpers#get_winwidth(), \ '$VIMSHELL' : 1, \ '$COLUMNS' : vimshell#helpers#get_winwidth(), \ '$LINES' : g:vimshell_scrollback_limit, \ '$VIMSHELL_TERM' : 'interactive', \ '$EDITOR' : vimshell#helpers#get_editor_name(), \ '$GIT_EDITOR' : vimshell#helpers#get_editor_name(), \ '$PAGER' : g:vimshell_cat_command, \ '$GIT_PAGER' : g:vimshell_cat_command, \}) " Initialize. let sub = vimproc#ptyopen(commands) finally " Restore environment variables. call vimshell#util#restore_variables(environments_save) if !empty(home_save) " Restore $HOME. call vimshell#util#restore_variables(home_save) endif endtry " Set variables. let interactive = { \ 'type' : 'interactive', \ 'process' : sub, \ 'fd' : a:context.fd, \ 'encoding' : options['--encoding'], \ 'is_secret': 0, \ 'prompt_history' : {}, \ 'is_pty' : (!vimshell#util#is_windows() || use_cygpty), \ 'args' : args, \ 'echoback_linenr' : 0, \ 'prompt_nr' : line('.'), \ 'width' : vimshell#helpers#get_winwidth(), \ 'height' : g:vimshell_scrollback_limit, \ 'stdout_cache' : '', \ 'stderr_cache' : '', \ 'command' : fnamemodify(use_cygpty ? args[1] : args[0], ':t:r'), \ 'cmdline' : join(args), \ 'is_close_immediately' : \ get(a:context, 'is_close_immediately', 0), \ 'hook_functions_table' : {}, \} call vimshell#commands#iexe#init(a:context, interactive, \ new_pos, old_pos, 1) call vimshell#interactive#execute_process_out(1) if b:interactive.process.is_valid call vimshell#view#_simple_insert() endif endfunction"}}} function! s:command.complete(args) abort "{{{ if len(a:args) == 1 return vimshell#complete#helper#executables(a:args[-1]) elseif vimshell#util#is_windows() && \ len(a:args) > 1 && a:args[1] == 'fakecygpty' return vimshell#complete#helper#executables( \ a:args[-1], g:vimshell_interactive_cygwin_path) endif return vimshell#complete#helper#args(a:args[1], a:args[2:]) endfunction"}}} function! vimshell#commands#iexe#define() abort return s:command endfunction " Set interactive options. "{{{ if vimshell#util#is_windows() " Windows only options. call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'bash,bc,gosh,python,zsh', '-i') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'irb', '--inf-ruby-mode') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'powershell', '-Command -') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'scala', '-Xnojline') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'nyaos', '-t') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'fsi', '--gui- --readline-') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'sbt', \ '-Djline.WindowsTerminal.directConsole=false') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'ipython,ipython3', \ '--TerminalInteractiveShell.readline_use=False') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_cygwin_commands, 'tail,zsh,ssh', 1) endif call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'termtter', '--monochrome') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_command_options, 'php', '-a') " Set interpreter commands. call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'ruby', 'irb') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'python', 'python') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'perl', 'perlsh') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'perl6', 'perl6') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'sh', 'sh') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'zsh', 'zsh') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'bash', 'bash') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'erlang', 'erl') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'scheme', 'gosh') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'clojure', 'clj') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'lisp', 'clisp') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'ps1', 'powershell') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'haskell', 'ghci') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'dosbatch', 'cmdproxy') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'scala', \ vimshell#util#is_windows() ? 'scala.bat' : 'scala') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'ocaml', 'ocaml') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'sml', 'sml') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'javascript', 'js') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_interpreter_commands, 'php', 'php') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_prompts, 'termtter', '> ') call vimshell#util#set_default_dictionary_helper( \ g:vimshell_interactive_monochrome_commands, 'earthquake', '1') "}}} function! s:default_settings() abort "{{{ " Common. call vimshell#init#_default_settings() " Define mappings. call vimshell#int_mappings#define_default_mappings() endfunction"}}} function! s:default_syntax() abort "{{{ " Set syntax. syntax match InteractiveError \ '!!![^!].*!!!' contains=InteractiveErrorHidden highlight def link InteractiveError Error if has('conceal') " Supported conceal features. syntax match InteractiveErrorHidden \ '!!!' contained conceal else syntax match InteractiveErrorHidden \ '!!!' contained highlight def link InteractiveErrorHidden Ignore endif endfunction"}}} function! vimshell#commands#iexe#init(context, interactive, new_pos, old_pos, is_insert) abort "{{{ " Save current directiory. let cwd = getcwd() let loaded = s:manager.open('iexe-'.substitute(join(a:interactive.args), \ '[<>|]', '_', 'g') .'@'.(bufnr('$')+1), 'silent edit') if !loaded call vimshell#echo_error( \ '[vimshell] Failed to open Buffer.') return endif let [a:new_pos[2], a:new_pos[3]] = [bufnr('%'), getpos('.')] let b:interactive = a:interactive call s:default_settings() call vimshell#cd(cwd) let syntax = 'int-' . a:interactive.command let &filetype = syntax let b:interactive.syntax = syntax call s:default_syntax() " Set autocommands. augroup vimshell autocmd BufDelete,VimLeavePre \ call vimshell#interactive#hang_up(expand('')) autocmd BufWinEnter,WinEnter \ call s:event_bufwin_enter() augroup END " Set send buffer. call vimshell#interactive#set_send_buffer(bufnr('%')) noautocmd call vimshell#helpers#restore_pos(a:old_pos) if get(a:context, 'is_single_command', 0) call vimshell#next_prompt(a:context, a:is_insert) noautocmd call vimshell#helpers#restore_pos(a:new_pos) endif endfunction"}}} function! s:event_bufwin_enter() abort "{{{ if has('conceal') setlocal conceallevel=3 setlocal concealcursor=nvi endif endfunction"}}} " vim: foldmethod=marker