XOR hai dòng để thấy sự khác biệt


7

Tôi cần tính toán một "XOR" giống như hai dòng để tìm mọi char khác nhau giữa hai dòng. Tôi biết vim-difftính năng này có thể dễ dàng đạt được điều đó, nhưng để so sánh hai dòng tôi muốn giữ mọi thứ trong cùng một bộ đệm.

ví dụ

1wYT4SH8f8VjRA25u8AItlrTdAY4Y7n-g8if8VjRA3q25u8AItlrTdwTbv8if8VjRA3q25u8AItlrTdJjMY
1wYT4SH8f8VjRA25u8AItlrTdAY4Y7n-g8if8VjRA3q25u8AIt1rTdwTbv8if8VjRA3q25u8AItlrTdJjMY
                                                  1

Nó được hoàn thiện bằng cách nào ?

Câu trả lời:


13

Giải pháp này không cho thấy sự khác biệt giữa hai dòng nhưng làm nổi bật chúng và cho phép bạn điều hướng qua chúng bằng nNnhư thế này:

Màn hình của chức năng

Để làm như vậy, hãy thêm chức năng này vào .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

Bạn có thể gọi hàm với :call CompareLines(1, 2)các đối số là số của các dòng để so sánh.

Để thêm một chút chi tiết về cách hoạt động của chức năng:

  • Các dòng đầu tiên được các dòng để so sánh trong một số biến.
  • Vòng lặp lặp qua các chuỗi này. Mỗi ký tự của các chuỗi được so sánh và khi chúng không khớp với một mẫu của biểu mẫu \%Xl\%Ycđược thêm vào biến patterntrong đó XYlà dòng và cột của một ký tự.

    (Xem :h /ordinary-atomvà đặc biệt là các dòng cuối cùng giải thích rằng mẫu \%23lcho phép khớp với dòng thứ 23 và \%23ccột thứ 23)

  • Khi mẫu được xây dựng, nó được chèn vào thanh ghi tìm kiếm ( let @/=cho phép xác định nội dung của thanh ghi và mẫu phải được trích dẫn).

  • Cuối cùng set hlsearchđược sử dụng để làm nổi bật tất cả các kết quả khớp của mẫu và normal nđưa con trỏ đến ký tự khác đầu tiên.

Lưu ý 1 Chức năng sẽ thay đổi lịch sử tìm kiếm của bạn.

Lưu ý 2 Phần sử dụng mẫu để thực hiện tìm kiếm có thể được cải thiện rất nhiều.

Và như một phần thưởng Thêm dòng này vào của bạn .vimrcđể tạo một lệnh sẽ nhanh hơn lệnh gọi của hàm:

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

Bằng cách này bạn có thể sử dụng đơn giản :CompLines 1 2để so sánh hai dòng.


EDIT Và đây là một phiên bản cải tiến của chức năng và lệnh. Sự khác biệt là bạn có thể gọi nó theo 3 cách khác nhau:

  • :CL sẽ khác dòng hiện tại và dòng sau
  • :CL 23 sẽ khác dòng hiện tại và dòng 23
  • :CL 23 42 sẽ khác dòng 23 và 42

Đây là mã:

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 Tôi đã làm cho nó một plugin . Bạn có thể cài đặt nó với trình quản lý plugin thông thường với (ví dụ):

Plug 'statox/vim-compare-lines'
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.