Подтвердить что ты не робот

Как разбить две строки в открытом файле в 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 сказал мне, что две строки на самом деле разные, потому что каждый заклинания "списывает" по-другому. Возможно ли это, и если да, то как это сделать?

4b9b3361

Ответ 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 

это должно открыть новое окно, показывающее различия этих двух строк