Vim[编译并]运行shortcu

2024-05-16 08:34:46 发布

您现在位置:Python中文网/ 问答频道 /正文

基本上我想要的是VIM中的键盘快捷方式,它允许我编译当前运行的正在编辑的C、C++或Python程序。在psuedocode中:

when a shortcut key is pressed:
    if current_extension == 'c' then
        shell: gcc this_filename.c -o this_filename_without_extension
        if retcode == 0 then shell: ./this_filename_without_extension
    else if current_extension == 'cpp' then
        shell: g++ this_filename.cpp -o this_filename_without_extension
    if retcode == 0 then shell: ./this_filename_without_extension
    else if current_extension == 'py' then
        shell: python this_filename.py
    end if
end key

我知道我可能会要求很多,但如果这是可能的话,我会喜欢的!


Tags: keypyifextensionvimcurrentshellfilename
3条回答

像这样的东西会有用的。只需创建映射<F4>的文件类型autocmd或任何您想要保存、编译和运行程序的文件类型。它使用exec构建字符串,并使用shellescape转义文件名。

autocmd filetype python nnoremap <F4> :w <bar> exec '!python '.shellescape('%')<CR>
autocmd filetype c nnoremap <F4> :w <bar> exec '!gcc '.shellescape('%').' -o '.shellescape('%:r').' && ./'.shellescape('%:r')<CR>
autocmd filetype cpp nnoremap <F4> :w <bar> exec '!g++ '.shellescape('%').' -o '.shellescape('%:r').' && ./'.shellescape('%:r')<CR>

%是当前缓冲区文件名。%:r是不带扩展名的缓冲区文件名

到了2018年,vim 8已经发布了2年,并与所有的mean stream Linux发行版和Mac OS X一起发布。但是很多vim教程仍然在教人们10年前的东西。

<>你可以在VIM中编译你的C++ java程序,就像使用VIM 8或Nevim的一些专用插件一样,使用高级文本或记事本+ +。

例如,AsyncRun插件将允许您在后台运行shell命令并实时读取quickfix窗口的输出。 See the screen capture

就像在ide中编译程序一样,编译错误将由errorformat匹配并突出显示并可选择。您可以在quickfix窗口中导航错误或在编译时继续编辑。

快速设置

复制并将下面的行粘贴到vimrc:

Plug 'skywind3000/asyncrun.vim'

" open quickfix window automatically when AsyncRun is executed
" set the quickfix window 6 lines height.
let g:asyncrun_open = 6

" ring the bell to notify you job finished
let g:asyncrun_bell = 1

" F10 to toggle quickfix window
nnoremap <F10> :call asyncrun#quickfix_toggle(6)<cr>

当您在命令行中输入“:AsyncRun echo hello”时:

see the capture here

您将在open quickfix窗口中看到实时命令输出。

编译并运行单个文件

使用AsyncRun编译单个文件比Sublime Text的构建系统简单得多。我们可以为此设置F9:

noremap <silent> <F9> :AsyncRun gcc -Wall -O2 "$(VIM_FILEPATH)" -o "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>

$(..)表单中的宏将被扩展为真正的文件名或目录,然后我们将有F5来运行可执行文件:

noremap <silent> <F5> :AsyncRun -raw -cwd=$(VIM_FILEDIR) "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>

双引号用于处理包含空格的路径名。选项-cwd=$(VIM_FILEDIR)表示在文件的目录中运行文件。使用绝对路径名$(VIM_FILEDIR)/$(VIM_FILENOEXT)是因为linux需要一个./前缀才能在当前目录中运行可执行文件,但windows不需要。使用二进制文件的绝对路径名可以处理这个跨平台问题。

另一个选项-raw意味着输出将不与vim的errorformat匹配,并将以quickfix的形式显示。现在可以用F9编译文件,在quickfix窗口中检查编译错误,然后按F5运行二进制文件。

<强>构建C/C++项目>P/>

无论您使用的是什么构建工具,make还是cmake,项目构建都意味着对一组文件执行操作。它需要定位项目根目录。AsyncRun使用一个名为根标记的简单方法来标识项目根。项目根目录被标识为当前文件的最近祖先目录,其中包含以下目录或文件之一:

let g:asyncrun_rootmarks = ['.svn', '.git', '.root', '_darcs'] 

如果父目录中没有包含这些根标记,则当前文件的目录将用作项目根目录。这使我们能够使用<root>$(VIM_ROOT)来表示项目根目录。可以设置F7来生成当前项目:

noremap <silent> <F7> :AsyncRun -cwd=<root> make <cr>

如果您当前的项目不在任何git或subversion存储库中呢?如何找出我的项目根在哪里?解决方案非常简单,只需在项目根目录中放置一个空的.root文件,就可以轻松找到它。

让我们继续,设置F8以运行当前项目:

noremap <silent> <F8> :AsyncRun -cwd=<root> -raw make run <cr>

项目将在其根目录下运行。当然,您需要在自己的makefile中定义运行规则。然后重新映射F6进行测试:

noremap <silent> <F6> :AsyncRun -cwd=<root> -raw make test <cr>

如果您使用的是cmake,F4可以映射以更新您的Makefile:

nnoremap <silent> <F4> :AsyncRun -cwd=<root> cmake . <cr>

由于c运行时的实现,如果进程运行的是非tty环境,那么stdout中的所有数据都将被缓冲,直到进程退出。因此,如果希望看到实时输出,那么在printf语句之后必须有一个fflush(stdout)。或者可以在开始时关闭stdout缓冲区

setbuf(stdout, NULL);

同时,如果您正在编写C++代码,则可以将STD::Endl附加到STD::CUT的结尾。它可以强制刷新stdout缓冲区。如果在windows上开发,AsyncRun可以为子进程打开一个新的cmd窗口:

nnoremap <silent> <F5> :AsyncRun -cwd=$(VIM_FILEDIR) -mode=4 "$(VIM_FILEDIR)/$(VIM_FILENOEXT)" <cr>
nnoremap <silent> <F8> :AsyncRun -cwd=<root> -mode=4 make run <cr>

在windows上使用选项-mode=4将打开一个新的提示窗口来运行命令,就像在Visual Studio中运行命令行程序一样。最后,我们拿到了这些钥匙下表:

  • F4:用cmake更新Makefile。
  • F5:运行单个文件
  • F6:运行项目测试
  • F7:建设项目
  • F8:运行项目
  • F9:编译单个文件
  • F10:切换快速修复窗口

它更像是在记事本++和GEdit中构建系统。如果您大量使用cmake,可以在~/.vim/script/build.sh中编写一个简单的shell脚本,将F4和F7组合在一起:如果CMakeList.txt已更改,它将更新Makefile,然后执行make。

高级用法

还可以在dotfiles存储库中定义shell脚本,并使用F3执行脚本:

nnoremap <F3> :AsyncRun -cwd=<root> sh /path/to/your/dotfiles/script/build_advanced.sh <cr>

以下shell环境变量由AsyncRun定义:

$VIM_FILEPATH  - File name of current buffer with full path
$VIM_FILENAME  - File name of current buffer without path
$VIM_FILEDIR   - Full path of current buffer without the file name
$VIM_FILEEXT   - File extension of current buffer
$VIM_FILENOEXT - File name of current buffer without path and extension
$VIM_CWD       - Current directory
$VIM_RELDIR    - File path relativize to current directory
$VIM_RELNAME   - File name relativize to current directory 
$VIM_ROOT      - Project root directory
$VIM_CWORD     - Current word under cursor
$VIM_CFILE     - Current filename under cursor
$VIM_GUI       - Is running under gui ?
$VIM_VERSION   - Value of v:version
$VIM_COLUMNS   - How many columns in vim's screen
$VIM_LINES     - How many lines in vim's screen
$VIM_SVRNAME   - Value of v:servername for +clientserver usage

以上所有环境变量都可以在您的build_advanced.sh中使用。使用外部shell脚本文件可以完成比单个命令更复杂的工作。

Grep符号

有时,如果您的远程linux系统中没有一个良好的安装环境,grep是在源代码之间搜索符号定义和引用的最便宜的方法。现在我们将有F2在光标下搜索关键字:

if has('win32') || has('win64')
    noremap <F2> :AsyncRun! -cwd=<root> grep -n -s -R <C-R><C-W> --include='*.h' --include='*.c*' '<root>' <cr>
else
    noremap <F2> :AsyncRun! -cwd=<root> findstr /n /s /C:"<C-R><C-W>" "\%CD\%\*.h" "\%CD\%\*.c*" <cr>
endif

上面的脚本将在项目根目录中运行grep或findstr,并且只在.c.cpp.h文件中查找符号。现在我们移动光标并按F2键,当前项目中的符号引用将立即显示在quickfix窗口中。

这个简单的键映射在大多数情况下已经足够了。您可以改进这个脚本以支持更多的文件类型或vimrc中的其他grep工具。

这是VIM 8或Nevim中构建/运行C/C++项目的实用方法。就像Sublime Text的构建系统和NotePad++的NppExec一样。

不再有过时的vim教程,尝试一些新的东西。

http://singlecompile.topbug.net似乎比你想要的做得更多。对于更简单的解决方案,您也可以将以下内容添加到vimrc中

au BufEnter *.cpp set makeprg=g++\ -g\ %\ -o\ %< 
au BufEnter *.c set makeprg=gcc\ -g\ %\ -o\ %< 
au BufEnter *.py set makeprg=python\ % 
au BufEnter *.[rR] set makeprg=Rscript\ %
map <F5> :call CompileGcc()<CR>
func! CompileGcc()
    exec "w" 
    silent make
endfunc

高温高压

相关问题 更多 >