web-dev-qa-db-ja.com

Vimでファイルを保存する前に変更を確認できますか?

Vimを使用しています。ファイルを開きます。編集して、保存する前に編集した内容を確認したい。

Vimでこれを行うにはどうすればよいですか?

127
teerapap

http://vim.wikia.com/wiki/Diff_current_buffer_and_the_original_file

以下は、現在編集されているファイルとファイルシステム内の変更されていないバージョンとの差分を確認するための関数とコマンドです。これをvimrcまたはプラグインディレクトリに置き、ファイルを開いて、保存せずにいくつかの変更を行い、:DiffSavedを実行します。

function! s:DiffWithSaved()
  let filetype=&ft
  diffthis
  vnew | r # | normal! 1Gdd
  diffthis
  exe "setlocal bt=nofile bh=wipe nobl noswf ro ft=" . filetype
endfunction
com! DiffSaved call s:DiffWithSaved()

Diffビューを終了するには、:diffoffコマンドを使用できます。

以下は、'cvs diff'コマンドを模倣するように適合された同様の関数です...

51
Bill Lynch
:w !diff % -
144
chaos

一部の人々はコマンドの説明について尋ねたので

:w !diff % -

より詳細な答えを書くための私の試みは次のとおりです。

catおよびechoがインストールされたシステム(たとえば、ほぼすべてのGNU/Linux、Mac OS、BSD、およびその他のUNIXライクなシステム)で作業していると想定しています。

上記のコマンドは次のように機能します。

  1. Vimでファイルを保存するための構文は次のとおりです。

    :w <filename>
    
  2. Vimでシェルコマンドを実行するための構文は次のとおりです。

    :!<command>
    
  3. Vim %によって発行されたシェル環境内では、現在のファイル名を指すことがあります。これを確認するには、次を実行します。

    :!echo %
    

    これにより、ファイル名が出力されます(または、vimがファイル名なしで実行された場合はエラー)。

    Catを使用して、ファイルのコンテンツを出力することもできます。

    :!cat %
    

    これにより、最後に保存された状態のファイルコンテンツが返されるか、一度も保存されていない場合はエラーが返されます。

  4. プログラムdiffは、標準入力(stdin)から読み取ることができます。そのマニュアルページには次のように記載されています。

    [...] FILEが '-'の場合、標準入力を読み取ります。 [...]

  5. ファイル名を指定せずにsaveコマンドを実行すると、その背後にあるシェルコマンドが実行され、vimはファイルの内容を物理ファイルに保存する代わりにシェルの標準入力に書き込みます。これを確認するには、次を実行します

    :w !cat
    

    これにより、常に現在のコンテンツ(代わりにファイルに書き込まれるはずのファイル)が印刷されます。

まとめる(またはtl; dr):ファイルはstdinに「保存」され、入力としてファイル名とstdinを使用してdiffが実行されます。

これを知っていると、ファイルを比較してvimdiffが次のようなことをすることもできます。これは、これをしたくないという考えにすぎません。

:w !cat > /tmp/tempFile && vimdiff /tmp/tempFile % && rm /tmp/tempFile

(その後、読み取り専用で開き、:qallを使用してvimdiffを閉じます)

88
Tobias Heinicke

diffchanges -素晴らしく、シンプルで、うまくいきます。

10
Rook

vimrc_example.vimから:

" Convenient command to see the difference between the current buffer and the
" file it was loaded from, thus the changes you made.
if !exists(":DiffOrig")
  command DiffOrig vert new | set bt=nofile | r # | 0d_ | diffthis
          \ | wincmd p | diffthis
endif
9
0x89

以下を入手し、:DIFFコマンドを使用します

function! s:diff()
    let tmpa = tempname()
    let tmpb = tempname()
    earlier 100h
    exec 'w '.tmpa
    later 100h
    exec 'w '.tmpb
    update
    exec 'tabnew '.tmpa
    diffthis
    vert split
    exec 'edit '.tmpb
    diffthis
endfunction
command! -nargs=0 DIFF call <SID>diff()
2
Mykola Golubyev

探しているものではありませんが、 SCMDiff.vim は本当にクールです。キーを1回押すと、現在のファイルがソース管理レポジトリの最新リビジョンで差分強調表示されます。これは、多くのSCMSで動作することを意図しています。 PERFORCEで使用します。

2
prestomation

ここに異なる答えに基づいたプラグインがあります: https://github.com/gangleri/vim-diffsaved

:w !diff % -メソッドとより複雑なdiffthisメソッド。

それとは別に ndotree もこれを許可しますが、さらに多く(異なる取り消しチェックポイント間の差分)も許可します。 Gundo と同様です。

2
blueyed

Vimdiffのように比較のためにvimを使用したい場合、次のようなことができます:

.vimrcを編集して追加します:

nmap <F8> :w !vim -M -R - -c ":vnew % \| windo diffthis"<CR><CR>

そこから変更が表示され、コマンドモードでF8を押してvimdiffのようにqallを使用してdiffビューを終了できます。 F8を任意のキーに置き換えます。

編集:-Mを追加して、保存しないため、変更を禁止します。

1
Tobias Heinicke

histwin プラグインをお勧めします。

現在の保存ファイルのバージョン(他の回答と同様)には差分をとりませんが、編集を開始してからvimdiffが変更できます、さらには再生順番に変更します。中間に保存すると、違いがわかります。

さらに、すべての元に戻す履歴ブランチのリストを表示し、それらの切り替えまたは差分を行うことができます。

PS:プラグインはファイルが変更されるたびに編集履歴の瞬間を自動的に追跡しませんが、ファイルを保存する瞬間に明示的に「タグ」を付けることができます。多分これは自動化できますか?

1
catchmeifyoutry