4

所以我目前主要使用 Vim 在 python 中工作,我最近发现了 2 个很好的策略,可以在外部运行代码并将其带回 Vim。第一个是使用ShellVim 页面调用的函数:

function! s:ExecuteInShell(command)
  let command = join(map(split(a:command), 'expand(v:val)'))
  let winnr = bufwinnr('^' . command . '$')
  silent! execute  winnr < 0 ? 'botright new ' . fnameescape(command) : winnr . 'wincmd w'
  setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
  echo 'Execute ' . command . '...'
  silent! execute 'silent %!'. command
  silent! execute 'resize ' . line('$')
  silent! redraw
  silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
  silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
  echo 'Shell command ' . command . ' executed.'
endfunction
command! -complete=shellcmd -nargs=+ Shell call s:ExecuteInShell(<q-args>)

它允许一个人运行类似的东西:Shell nosetests并在一个新窗口中查看结果:

  1. 持久(没有“点击进入”让它消失)
  2. 使用临时缓冲区(不是临时文件)
  3. 最重要的是,再次运行该命令只会刷新当前窗口,它不会每次都打开一个新窗口。

然后我也使用这个小宝石:

:'<,'>:w !python

这让我使用我当前缓冲区中的一个选择,但在按下回车后它就消失了。

我不知道该怎么做是将两者结合起来。我想要的是:

  1. 该命令的所有窗口属性Shell,但
  2. 从屏幕上的选择运行它的能力。
  3. 编辑:对选定的 python 代码执行此操作,而不是 bash 代码。该函数已经执行了常规的 shell 命令。我不想使用 Shell 来运行,$ python script.py而是希望它直接运行代码:'<,'>:w !python

我不知道足够的 Vimscript 来修改Shell以包含选择,而且我一生都无法弄清楚如何在:'<,'>:w !python不使用临时文件的情况下至少将其放入它自己的窗口中,这对我来说似乎没有必要。有任何想法吗?提示?

4

2 回答 2

2

您可以使函数接受范围并测试是否通过了范围:

function! s:ExecuteInShell(command) range
  let lines = []
  if (a:firstline != a:lastline)
    let lines=getline(a:firstline, a:lastline)
  endif
  let command = join(map(split(a:command), 'expand(v:val)'))
  let winnr = bufwinnr('^' . command . '$')
  silent! execute  winnr < 0 ? 'botright new ' . fnameescape(command) : winnr . 'wincmd w'
  setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
  echo 'Execute ' . command . '...'
  if (len(lines))
    silent! call append(line('.'), lines)
    silent! 1d
    silent! redir => results
    silent! execute '1,$w !' . command
    silent! redir end
    silent! %d
    let lines = split(results, '\r')
    for line in lines[:1]
        call append(line('$'), line[1:])
    endfor
    silent! 1d
  else
    silent! execute 'silent %!'. command
  endif
  silent! execute 'resize ' . line('$')
  silent! redraw
  silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
  silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
  echo 'Shell command ' . command . ' executed.'
endfunction
command! -range -complete=shellcmd -nargs=+ Shell <line1>,<line2>call s:ExecuteInShell(<q-args>)

与命令一起使用:

:Shell echo 'no range supplied, but a command (echo) is.'

要在选择行时使用(您不键入“'<,'>”部分,因为按“:”将把它放在那里(作为所选行提供的命令由命令解释):

:'<,'>Shell python
于 2013-10-30T06:06:26.927 回答
0

这是一个使用缺少命令来处理一系列行的版本:

function! s:ExecuteInShell(command) range
  let lines = []
  if (!len(a:command))
    let lines=getline(a:firstline, a:lastline)
  endif
  let command = join(map(split(a:command), 'expand(v:val)'))
  let winnr = bufwinnr('^' . command . '$')
  silent! execute  winnr < 0 ? 'botright new ' . fnameescape(command) : winnr . 'wincmd w'
  setlocal buftype=nowrite bufhidden=wipe nobuflisted noswapfile nowrap number
  echo 'Execute ' . command . '...'
  if (len(lines))
    for line in lines
        silent! execute 'silent r! '. line
    endfor
    silent! 1d
  else
    silent! execute 'silent %!'. command
  endif
  silent! execute 'resize ' . line('$')
  silent! redraw
  silent! execute 'au BufUnload <buffer> execute bufwinnr(' . bufnr('#') . ') . ''wincmd w'''
  silent! execute 'nnoremap <silent> <buffer> <LocalLeader>r :call <SID>ExecuteInShell(''' . command . ''')<CR>'
  echo 'Shell command ' . command . ' executed.'
endfunction
command! -range -complete=shellcmd -nargs=* Shell <line1>,<line2>call s:ExecuteInShell(<q-args>)

与命令一起使用:

:Shell echo 'no range supplied, but a command (echo) is.'

要在选择行时使用(您不键入“'<,'>”部分,因为按“:”将把它放在那里(没有提供命令,因为选择的行提供了命令):

:'<,'>Shell
于 2013-10-30T12:26:17.307 回答