2行をXORして違いを確認する


7

「XOR」のような2行を計算して、2行間で異なるすべての文字を見つける必要があります。このvim-diff機能でそれを簡単に実現できることはわかっていますが、2つの行を比較するために、すべてを同じバッファーに保持したかったのです。

例えば

1wYT4SH8f8VjRA25u8AItlrTdAY4Y7n-g8if8VjRA3q25u8AItlrTdwTbv8if8VjRA3q25u8AItlrTdJjMY
1wYT4SH8f8VjRA25u8AItlrTdAY4Y7n-g8if8VjRA3q25u8AIt1rTdwTbv8if8VjRA3q25u8AItlrTdJjMY
                                                  1

どうすればできますか?

回答:


13

このソリューションは、2つのライン間の差異を示すが、それらを強調表示し、あなたがそれらを介してナビゲートすることはできませんnし、Nこのように:

関数のスクリーンキャスト

これを行うには、この関数を以下に追加します.vimrc

function! CompareLines(line1, line2)
    let l1 = getline(a:line1)
    let l2 = getline(a:line2)
    let pattern = ""

    for i in range(strlen(l1))
        if strpart(l1, i, 1) != strpart(l2, i, 1)
            if pattern != ""
                let pattern = pattern . "\\|"
            endif
            let pattern = pattern . "\\%" . a:line1 . "l" . "\\%" . ( i+1 ) . "c"
            let pattern = pattern . "\\|" . "\\%" . a:line2 . "l" . "\\%" . ( i+1 ) . "c"
        endif
    endfor

    execute "let @/='" . pattern . "'"
    set hlsearch
    normal n
endfunction

:call CompareLines(1, 2)引数が比較す​​る行数である関数を呼び出すことができます。

関数がどのように機能するかについてもう少し詳細を追加するには:

  • 最初の行は、いくつかの変数で比較する行を取得します。
  • ループはこれらの文字列を反復処理します。文字列の各文字が比較され、それらが一致しないときに、フォームのパターンは\%Xl\%Yc変数に追加されると、行と文字の列です。patternXY

    :h /ordinary-atom特に、パターン\%23lが23行目と\%23c23列目との一致を許可することを説明する最後の行を参照してください)

  • パターンが作成されると、検索レジスタに挿入されます(レジスタlet @/=の内容を定義できるようになり、パターンを引用する必要があります)。

  • 最後set hlsearchに、パターンのすべての一致を強調表示しnormal n、カーソルを最初の異なる文字に移動するために使用されます。

注1この機能は検索履歴を変更します。

注2パターンを使用して検索する部分は、おそらく大幅に改善される可能性があります。

おまけとして、この行をに追加して.vimrc、関数の呼び出しを高速化するコマンドを作成します。

command! -nargs=* CompLines call CompareLines(<f-args>)

このように、:CompLines 1 22つの行を比較するために簡単に使用できます。


編集次に、関数とコマンドの改良版を示します。違いは、次の3つの方法で呼び出すことができることです。

  • :CL 現在の行と次の行を比較します
  • :CL 23 現在の行と行23を比較します
  • :CL 23 42 23行目と42行目を比較します

これがコードです:

command! -nargs=* CL call CompareLines(<f-args>)

function! CompareLines(...)

    " Check the number of arguments
    " And get lines numbers
    if len(a:000) == 0
        let l1=line(".")
        let l2=line(".")+1
    elseif len(a:000) == 1
        let l1 =line(".")
        let l2 =a:1
    elseif len(a:000) == 2
        let l1 = a:1
        let l2 = a:2
    else
        echom "bad number of arguments"
        return;
    endif

    " Get the content of the lines
    let line1 = getline(l1)
    let line2 = getline(l2)

    let pattern = ""

    " Compare lines and create pattern of diff
    for i in range(strlen(line1))
        if strpart(line1, i, 1) != strpart(line2, i, 1)
            if pattern != ""
                let pattern = pattern . "\\|"
            endif
            let pattern = pattern . "\\%" . l1 . "l" . "\\%" . ( i+1 ) . "c"
            let pattern = pattern . "\\|" . "\\%" . l2 . "l" . "\\%" . ( i+1 ) . "c"
        endif
    endfor

    " Search and highlight the diff
    execute "let @/='" . pattern . "'"
    set hlsearch
    normal n
endfunction

EDIT 2私はそれ作ったプラグイン。通常のプラグインマネージャーを使ってインストールできます(例:):

Plug 'statox/vim-compare-lines'
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.