Как разбить две строки в открытом файле в vim?
Я иногда вижу очень длинные строки в своем коде, что мне нужно проверить, совпадают ли они. Есть ли способ в vim выбрать две строки и разделить их, чтобы показать какие-либо различия между ними?
Например, учитывая две строки в vim:
AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *lists);
AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(That *is, Overloaded *with, Multiple *different, Parameter *1ists);
Я бы хотел, чтобы vim сказал мне, что две строки на самом деле разные, потому что каждый заклинания "списывает" по-другому. Возможно ли это, и если да, то как это сделать?
Ответы
Ответ 1
Быстрое и грязное решение - просто выбрать обе строки и отсортировать их, удаляя дубликаты:
- выберите строки
- ": сортируй"
- если осталась только одна строка, обе были равны
- если оба останутся, то будет большая разница
Отмена восстанавливает все снова.
Ответ 2
Альтернатива @sehe подхода не потребует использования временных файлов:
funct! DiffTwoTexts(text1, text2)
new
put =a:text1
normal ggdd
diffthis
new
put =a:text2
normal ggdd
diffthis
endfunct
funct! DiffTwoLines(line1, line2)
let text1 = getline(a:line1)
let text2 = getline(a:line2)
call DiffTwoTexts(text1, text2)
endfunct
comma! DiffWithNext call DiffTwoLines('.', line('.') + 1)
Это все равно будет довольно трудно прочитать, поскольку он хранит все на одной строке, поэтому я придумал эту модификацию:
funct! EvalTextPreprocessor(expr, text)
let text = a:text
return eval(a:expr)
endfunct
comma! -nargs=1 DiffWithNextPre call DiffTwoTexts(
\ EvalTextPreprocessor(<q-args>, getline('.')),
\ EvalTextPreprocessor(<q-args>, getline(line('.') + 1)))
Эта новая команда принимает выражение vimscript в качестве своего аргумента, где переменная text
относится к каждой строке, которая предварительно обрабатывается. Таким образом, вы можете позвонить, например.
DiffWithNextPre split(text, '[(,)]\zs')
Для ваших данных образца это дает два буфера
AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(
That *is,
Overloaded *with,
Multiple *different,
Parameter *lists)
;
и
AVeryLongReturnType* MyLongClassName:hasAnEvenLongerFunction(
That *is,
Overloaded *with,
Multiple *different,
Parameter *1ists)
;
Выделяются только строки, начинающиеся с Parameter
.
Вы можете даже создать оттуда, создав команду
comma! DiffTwoCFunctionSigs DiffWithNextPre split(text, '[(,)]\s*\zs')
Обратите внимание, что я немного изменил регулярное выражение так, чтобы он сохранял конечные пробелы в конце строк. Вы можете заставить его полностью игнорировать их, перемещая \s*
после \zs
. См. :help /\zs
, если вы не знакомы с тем, что делает этот конкретный RE-атом.
Хорошей задачей было бы заставить команду взять диапазон (см. :help command-range
), который вы могли бы использовать, если перенести первую строку диапазона на последнюю строку. Итак, вы просто визуализируете - выбираете от первой строки до второй и вызываете команду.
Ответ 3
Это не особенность, однако она легко может быть написана сценарием, например. в вашем vimrc:
function! DiffLineWithNext()
let f1=tempname()
let f2=tempname()
exec ".write " . f1
exec ".+1write " . f2
exec "tabedit " . f1
exec "vert diffsplit " . f2
endfunction
Это откроет текущую и следующую строки в вертикальном разрезе на другой вкладке.
Обратите внимание, что этот код является образцом
- он не проверяет, существует ли следующая строка (есть следующие строки)
- он не очищает созданные tempfiles
- хорошим улучшением было бы взятие диапазона или использование метки
''
для выбора другой строки
Вы можете оставить "vert", чтобы иметь горизонтальный раскол
Сопоставьте это с чем-то необычным, поэтому вам не нужно :call
его вручную:
:nnoremap <F10> :call DiffLineWithNext()^M
Ответ 4
Я использовал linediff.vim.
Этот плагин предоставляет простую команду ": Linediff", которая используется для сравнения двух отдельных блоков текста.
Ответ 5
вы также можете просто создать новый пустой буфер окна и скопировать строку, а затем сделать команду:
:windo diffthis
это должно открыть новое окно, показывающее различия этих двух строк