Как удалить большой блок текста без подсчета строк?


91

В vim мне часто нужно удалять, или дергать / помещать большие блоки текста.

Я могу посчитать строки текста и ввести что-то вроде 50ddудаления 50 строк.

Но это немного больно. Как я могу удалить этот большой блок текста, не зная заранее, сколько строк удалить?


4
Откуда ты знаешь, где конец? Если вы можете описать конец, вы можете удалить до этой точки. Если вы можете описать, как вы можете moveдо конца. Тогда удаление до конца ничем не отличается от перемещения до конца.
Мартин Йорк,

@Loki, перемещение до конца обычно происходит просто с помощью перелистывания и клавиш со стрелками, пока я не достигну там. Это может быть первая или десятая пустая строка, это может быть первая закрывающая скобка. Суть в том, что она сильно варьируется.

2
также проверьте этот ответ: stackoverflow.com/a/16407391/164835
Кент

Ответы:


111

Перейдите к начальной строке своего блока и введите ma(отметьте «a», хотя вы, конечно, можете использовать разные буквы и даже несколько букв для разных отметок, при условии, что вы можете держать это прямо в голове, над чем каждая буква является знаком) ,

Затем перейдите к последней строке и введите d'a(удалить, чтобы отметить "a") или y'a(дернуть, чтобы отметить "a") (a) .

Это удалит / восстановит все строки от текущей до отмеченной (включительно).

Затем вы можете вставить его куда-нибудь с помощью обычных команд вставки, таких как pили P.

Он также совместим с vi, а также vim, на всякий случай , что среда не благословлен с последним.


(а) Я также использую это, чтобы сохранить свое место в файле, если мне придется искать в другом месте что-то вроде, например, вставки копии определения функции, которую я хочу вызвать.

Я просто помечаю текущую строку таким же образом ma, а затем отправляюсь на поиски того, что вы ищете.

Затем, как только я нашел его и скопировал в регистр, я просто 'aзахожу, чтобы вернуться, чтобы отметить «a», строку, которую я предварительно сохранил, где я могу затем вставить ее.


9
Можно ли использовать визуальный режим для этого, верно?
JMC

3
Это один из способов, jmc, но я не уверен, что стандартный vi имеет визуальный режим.

5
Так как около года назад я перешел от визуального выбора к маркировке и относительным номерам строк, я обнаружил, что команды перемещения vi работают намного быстрее и эффективнее, чем визуальный выбор. Несмотря на то, что потом легче каждый раз, когда я нажимаю vклавишу, я спрашиваю себя, действительно ли она мне нужна или есть лучший способ движения?
Sukima

1
Да, точно так же интересно, @Sukima, что я чувствую себя более эффективно, чем меньше использую мышь, даже в графическом интерфейсе. Я чувствую себя быстрее, если я могу оставаться на клавиатуре.

3
Если вы когда-либо редактируете что-то с действительно длинными строками, обратная версия этого также может оказаться очень полезной (которая относится к месту в строке, а не ко всей строке).
MST

65

В Vim используйте режим визуальной линии :

  1. Наведите курсор на верхнюю строку блока текста / кода для удаления
  2. Нажмите V(это заглавная "V": Shift+ v)
  3. Наведите курсор на нижнюю часть блока текста / кода, чтобы удалить
  4. Нажмите d

Для удаления больших блоков текста это предпочтительнее простого визуального режима, потому что вам не нужно беспокоиться о том, в каком столбце находится курсор.


3
На шаге 3. вы можете двигаться быстрее, используя движения объекта. Например, можно использовать, }чтобы выбрать весь абзац или )для предложений. Есть еще, вы можете прочитать о них в:h object-motions
mxlian

2
Также поиск подстроки с /something<CR>помощью очень эффективного метода для достижения конца вашего блока выбора
mxlian

1
Это мой предпочтительный метод. Однако в качестве альтернативы без необходимости многократного нажатия jдля перемещения курсора вниз (шаг 3), вы можете ввести номер строки, а затем Gвыбрать ее до этой строки. Пример:V150Gd
Ранхиру Джуд Курай


39

Вы можете легко удалить большой блок текста, зная его структуру.

Если это абзац, используйте: d{(например, вы можете использовать префикс с количеством абзацев)

Если это блок кода в скобках, используйте: d%

Если текст появляется до конца файла, используйте: dG

Если вы знаете, как он заканчивается, используйте: d/и введите конечный текст, за которым следует Enter(вы также можете использовать регулярное выражение, поэтому возможности безграничны).

В качестве альтернативы используйте визуальный режим ( V) и используйте клавиши перемещения для быстрого выделения текста (например, с помощью {) и удаления его ( d).

Или, как предложил Lie Ryan, используйте d/search-string/eдля удаления текста из текущего курсора в искомую строку.

Смотрите: :help dи :help motionдля получения дополнительной информации.


2
Также есть d/search-string/eвозможность удалить от текущего курсора до конца строки поиска, включая саму строку поиска, и c/search-queryперейти в режим вставки после удаления. Использование d/with set incsearch- это аккуратная комбинация, так как она позволяет вам в интерактивном режиме выяснить, работаете ли вы с правильным текстовым диапазоном, и помочь вам узнать, когда прекратить вводить поисковый запрос, чтобы избежать ввода больше, чем необходимо.
Ли Райан

4
Я также нахожу dс a(внешний) или i(внутренний) и спецификатор объекта очень полезным. Объекты, такие как wдля слова, pдля абзаца, (или bдля (...), [для [...], {или Bдля {...}и т. Д. Документации для визуальных операторов .
Шахбаз

22

Вы можете использовать движения и / или текстовые объекты. Например, вы можете удалить все от курсора до следующей пустой строки с помощью d}. Если курсор находится внутри абзаца, абзац можно удалить с помощью dipили dap. Если курсор находится внутри тега HTML, вы можете удалить его с помощью ditили dat.

Хорошей мнемоникой для них являются « d elete i nside » и « d elete a round» (параграф / метка / скобка).


11

Я обычно делаю

:<start>,<end>d

который удалит каждую строку между указанными номерами начальной и конечной строк (включая указанные строки).

Обратите внимание, что оба startи endмогут быть абсолютными номерами линий, шаблонами или смещениями из другой позиции.

Также посмотрите комментарий DoubleDown о просмотре документации по диапазону Vim , в нем есть несколько полезных советов.

Пример:

Допустим, у вас есть следующий файл:

1. The quick brown
2. fox jumps
3. over the
4. lazy dog.

Затем с помощью команды :2,3dили :/fox/,/over/dили :/quick/+1,/lazy/-1или, :+1,+2dесли вы находитесь на первой строке, или :-1,.dесли вы находитесь на третьей строке, вы получите:

1. The quick brown
4. lazy dog.

Но это значит, что вам все еще нужно считать строки? Или я неправильно понял ваш ответ?
Мартин Турной

7
Вам не нужно считать строки, но вам нужно знать номера строк.
JMC

Сначала сделайте :set ruler, затем перейдите к верху и низу текста, чтобы найти startи найти endномера строк, затем сделайте:<start>,<end>d
roblogic

1
Вы также можете использовать относительные номера строк:+12,+24d
rpattabi

2
На самом деле, вы можете использовать пару номеров строк, пару шаблонов или смешанную пару для <start>и <end>для этого. Для справки см :h [range]. Так что это на самом деле немного более гибко, чем вы предполагали.
DoubleDown

5

Если вы имеете дело с блоками с разделителями (например: код или теги XML / HTML), с которыми вы имеете дело, вы можете поместить курсор в начало блока и использовать визуальный режим, %чтобы быстро выбрать целые блоки кода, а затем нажать dудалить их.


5
Кроме того , вы можете использовать , dapчтобы удалить пункт, da(, da{, da[, удалять блоки delimeted в круглые скобки, фигурные скобки, или квадратные скобки. Для html есть dat, который удаляет тег, da'и da"удаляет строки. Существует также dip, di(и т.д. варианты, которые будут удалять все внутри ограничителей, но оставить разделители нетронутыми. Кроме того, вы можете использовать vap(соответственно vip), чтобы выбрать весь (соответственно внутренний) абзац. (И так есть va(и vi(.) Далее есть capи cip(или ca(и ci() удалить и перейти в режим вставки (т. Е. «Изменить»). И yapдергать
JMC

Я думаю, что некоторые из привязок @jmc, описанных в его предыдущем комментарии, взяты из плагина Surround.vim Тима Попа. Это отличный плагин, который я бы рекомендовал установить, но это означает, что эти привязки не являются частью установки vim по умолчанию.
Хаегин

5

Помимо всего прочего полезного совета я добавляю d+ Shift+ Lдля удаления всего с текущей позиции курсора до последней видимой строки на экране. Повторение команды поможет вам сравнительно быстро.


5

Numbers.vim плагин очень полезен для этого. Это улучшенный способ предварять каждую строку номером строки. Вроде 'number'и 'relativenumber'оба в одном!

Он включен по умолчанию после установки, вы также хотите добавить его set numberв свой vimrc, если у вас его еще нет, поскольку он ведет себя странным образом, если у вас его нет.

В обычном режиме это выглядит примерно так :set relativenumber:

  3 call plug#begin('~/.vim/plugged')
  2 
  1 Plug 'myusuf3/numbers.vim'
7   set number█
  1 
  2 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
  3 Plug 'Yggdroot/indentLine'

Он показывает относительные номера строк, за исключением строки, в которой находится курсор, где он показывает абсолютный номер строки (7 в данном случае).

Если мы затем переключимся в режим вставки , он будет вести себя так, как если бы он numberбыл установлен, всегда показывая абсолютные номера строк:

  4 call plug#begin('~/.vim/plugged')
  5 
  6 Plug 'myusuf3/numbers.vim'
  7 set number█
  8   
  9 " Add indentation 'guidelines' (:IndentLinesToggle or <F11>)
 10 Plug 'Yggdroot/indentLine'

Есть еще несколько опций и несколько команд (проверьте домашнюю страницу), но значения по умолчанию должны работать для большинства людей.


Сначала я думал, что этот ответ был немного не по теме, но затем я установил плагин, и я должен сказать, что это изменит правила игры для меня. Я имел обыкновение менять местами вручную, и дополнительный умственный шаг означал, что я уклонялся от использования этих движений. Спасибо!
Sukima

1
Это похоже на то, что может сделать один AutoCMD InsertEnter / InsertLeave для переключения относительной нумерации строк. Я что-то пропустил?
Бен

Я ОЧЕНЬ опаздываю на вечеринку, но @Ben прав, это всего лишь пара строк автокоманды. Например, в моем vimrc у меня есть set number, set relativenumberто autocmd InsertEnter * :set norelativenumberиautocmd InsertLeave * :set relativenumber
B слой

4

Другой подход - если вы пытаетесь удалить определенный шаблон, вы можете просто напечатать d/delimEnter.


2

Вы можете использовать обычную процедуру ввода dплюс движение (как уже объяснено в других ответах). Плагин EasyMotion предоставляет новые движения, которые вы можете использовать, чтобы быстро и легко решить вашу проблему.

Скажем, вы хотите удалить из текущей позиции курсора до конца любого данного слова на экране, клавиши перемещения будут <Leader><Leader>e(сродни обычному eдвижению). Затем введите выделенную букву (буквы), которые появляются в конце слова, о котором идет речь. Существует также движение линии, поэтому вы можете удалить текущую строку до указанной строки с помощью <Leader><Leader>j.

У меня есть <Leader>ключ к ,. Итак, полная команда: d<Leader><Leader>e{выделенная буква (ы)}.

От :help easymotion:

EasyMotion предоставляет гораздо более простой способ использования некоторых движений в vim. Он принимает <number>отказ от <number>ш или <number>е {char}, выделяя все возможные варианты и позволяя вам нажать одну клавишу , чтобы перейти непосредственно к цели.

Когда запускается одно из доступных движений, весь видимый текст, предшествующий или следующий за курсором, исчезает, и цели движения выделяются.

Редактировать:

GitHub- репозиторий EasyMotion находится по адресу https://github.com/Lokaltog/vim-easymotion .

Это реддит о людях, использующих easymotion, может быть весело читать.


1

Существует простое решение, которое может решить вашу проблему.

Поместите курсор в начале текстового блока, который вы хотите удалить, и сделайте d50gg.

Это удалит все строки из вашей текущей позиции до 50-й строки вашего текста.

eq: если ваш курсор находится на строке 46 , d50ggудалит 4 строки.


1
Я бы предложил использовать Gвместо gg, так как он также работает в vi, и, конечно :set number, всегда полезно найти номер строки, на которую вы хотите перейти.
Random832 20.02.15

Весь смысл этого вопроса в том, что вы не знаете, сколько строк вы хотите удалить.
200_success

200_success, вам не нужно знать, сколько строк вы хотите удалить с ответом, который я разместил. Все, что вам нужно знать, это «на какую строку вы хотите удалить»
Geee

1

Используйте визуальный режим с подсветкой строк.

  1. Наведите курсор на верхнюю строку блока текста / кода для удаления
  2. Нажмите Shift+v
  3. Наведите курсор на нижнюю часть блока текста / кода, чтобы удалить
  4. Нажмите d

Я предпочитаю этот метод для удаления блоков кода, потому что он удаляет целые строки по сравнению с простым использованием визуального режима, где вы должны поместить курсор в правом столбце, чтобы удалить то, что вы хотите.


3
По сути, вы повторяете ответ по @ 200_success.
Мартин Шредер

1

Я не люблю, чтобы relativenumberвсе время было включено, поэтому я настроил свой Vim, чтобы он включался только тогда, когда я нахожусь в визуальном режиме:

" Entering Visual mode
nnoremap <silent>     v :set relativenumber cursorcolumn<CR>v
nnoremap <silent> <C-q> :set relativenumber cursorcolumn<CR><C-q>
nnoremap <silent>    gv :set relativenumber cursorcolumn<CR>gv
nnoremap <silent>     V :set relativenumber<CR>V

" When finished
augroup ClearCursorColumnAndLine
    autocmd!
    autocmd CursorHold * set norelativenumber nocursorcolumn nocursorline
augroup END

Это облегчает вашу задачу:

V49jd

потому что после удара Vвы можете увидеть, как далеко находится целевая линия.

Это может раздражать в долгосрочной перспективе (текст смещается вправо и влево, когда относительное число включено / отключено), но пока мне это очень нравится.


1
Я думаю, что вы используете v<Esc>d50j?
Мартин Турной

Спасибо, я действительно написал это неправильно. На самом деле, я начинаю с Vтого, что знаю, что буду выполнять линейную операцию, а затем могу оставить dдо последнего для большей уверенности.
Joeytwiddle

Мой ответ выглядит как приближение бедного человека к плагину numbers.vim, предложенному в другом ответе. ;-)
joeytwiddle

1

Что отлично сработало для меня vi:

  1. :set number просматривать номер строки до того места, где я хотел удалить;

    +1289 idle 
    +1289 idle 
    +1290 # <- I want to delete until here
    +1291 if [[ ! -z "$SFIN" ]]
    
  2. Вернитесь к строке, где должно было начаться удаление

  3. Используется удаление из текущей строки, в обычном режиме> d1290G
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.