web-dev-qa-db-ja.com

Vim [コンパイルして]ショートカットを実行

基本的に私が欲しいのは、現在編集中のC、C++、またはPythonプログラムを[コンパイルして]実行できるvimのキーボードショートカットです。擬似コードでは:

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

私は少し質問しているかもしれないと思いますが、これが可能であればそれが大好きです!

24
user1318194

このようなものが機能します。 <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は、拡張子のないバッファファイル名です

32
FDinoff

http://singlecompile.topbug.ne​​t あなたが望む以上のことをしているようです。より簡単な解決策として、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

HTH

2018年になりました。vim8は2年間リリースされ、すべての平均ストリームLinuxディストリビューションとMac OS Xに同梱されています。しかし、多くのvimチュートリアルはまだ10年前に人々に何かを教えています。

C++/Javaプログラムは、Vim8またはNeoVim専用のプラグインを使用してSublimeTextまたはNotePad ++と同じくらい便利にvimでコンパイルできます。

たとえば、 AsyncRun プラグインを使用すると、バックグラウンドでシェルコマンドを実行し、クイックフィックスウィンドウからの出力をリアルタイムで読み取ることができます。 スクリーンキャプチャを参照

IDEでプログラムをコンパイルするのと同じように、コンパイルエラーはerrorformatと照合され、強調表示されて選択可能になります。クイックフィックスウィンドウでエラーをナビゲートするか、コンパイル中に編集を続行できます。

クイックセットアップ

以下の行をコピーして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>
_

コマンドラインで「:AsyncRunecho hello」と入力すると、次のようになります。

ここでキャプチャを参照

開いているクイックフィックスウィンドウにリアルタイムコマンドの出力が表示されます。

単一のファイルをコンパイルして実行します

AsyncRunを使用して単一のファイルをコンパイルすることは、SublimeTextのビルドシステムよりもはるかに簡単です。これのために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)は、ファイルのディレクトリでファイルを実行することを意味します。 Linuxでは現在のディレクトリで実行可能ファイルを実行するために_./_プレフィックスが必要ですが、Windowsでは必要ないため、絶対パス名$(VIM_FILEDIR)/$(VIM_FILENOEXT)が使用されます。バイナリファイルの絶対パス名を使用すると、この交差するプラットフォームの問題を処理できます。

別のオプション_-raw_は、出力がvimのerrorformatと一致せず、quickfixでそのまま表示されることを意味します。これで、F9を使用してファイルをコンパイルし、クイックフィックスウィンドウでコンパイルエラーを確認し、F5を押してバイナリを実行できます。

C/C++プロジェクトのビルド

Makeまたはcmakeのどちらのビルドツールを使用していても、プロジェクトのビルドとは、ファイルのグループに対して機能することを意味します。プロジェクトのルートディレクトリを見つける必要があります。 AsyncRunは、ルートマーカーと呼ばれる単純なメソッドを使用して、プロジェクトのルートを識別します。プロジェクトルートは、次のディレクトリまたはファイルの1つを含む現在のファイルの最も近い祖先ディレクトリとして識別されます。

_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>
_

プロジェクトはそのルートディレクトリで実行されます。もちろん、独自のメイクファイルで実行ルールを定義する必要があります。次に、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 :: coutの末尾に追加できます。 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:Makefileをcmakeで更新します。
  • F5:単一のファイルを実行します
  • F6:プロジェクトテストを実行する
  • F7:ビルドプロジェクト
  • F8:プロジェクトを実行する
  • F9:単一のファイルをコンパイルします
  • F10:クイックフィックスウィンドウを切り替えます

これは、NotePad ++およびGEditのビルドシステムに似ています。 cmakeを多用している場合は、_~/.vim/script/build.sh_にある単純なシェルスクリプトを記述して、F4とF7を組み合わせることができます。CMakeList.txtが変更されている場合はMakefileが更新され、makeが実行されます。

高度な使用法

Dotfilesリポジトリでシェルスクリプトを定義し、F3でスクリプトを実行することもできます。

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

次のシェル環境変数は、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_で使用できます。外部シェルスクリプトファイルを使用すると、単一のコマンドよりも複雑な作業を実行できます。

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キーを押すと、現在のプロジェクトのシンボル参照がクイックフィックスウィンドウにすぐに表示されます。

ほとんどの場合、この単純なキーマップで十分です。また、このスクリプトを改善して、vimrcでより多くのファイルタイプやその他のgrepツールをサポートすることができます。

これは、Vim8またはNeoVimでC/C++プロジェクトをビルド/実行するための実用的な方法です。 SublimeTextのビルドシステムやNotePad ++のNppExecと同じです。

古いvimチュートリアルはもう必要ありません。何か新しいことを試してください。

2
skywind3000

これは私の地図です。実際に機能し、任意の言語に更新できます。

" <!----------------------------" gcc compile C files----------------------------------------!>
autocmd filetype c nnoremap <Leader>c :w <CR>:!gcc % -o %:r && ./%:r<CR>

" <!----------------------------" Java compile files----------------------------------------!>
autocmd filetype Java nnoremap <Leader>c :w <CR>:!javac % :r&& Java %:r<CR>
" <!----------------------------" php compile files----------------------------------------!>
autocmd filetype php nnoremap <Leader>c :w <CR>:!clear && php  %<CR>

もしあなたがvimでそれらのファイルの1つであるなら、通常モードでやってください:

<leader>c
0