Як видалити великий блок тексту, не рахуючи рядки?


91

У програмі vim мені часто потрібно видаляти або класти / класти великі блоки тексту.

Я можу порахувати рядки тексту та ввести щось на зразок 50ddвидалення 50 рядків.

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


4
Як ти знаєш, де кінець? Якщо ви можете описати кінець, ви можете видалити до цього пункту. Якщо ви можете описати, як можна moveдо кінця. Тоді видалення до кінця не відрізняється від переміщення до кінця.
Мартін Йорк

@Loki, рухаючись до кінця, зазвичай просто використовую сторінку вниз та клавіші зі стрілками, поки я не дістанусь туди. Це може бути перший чи десятий порожній рядок, це може бути перший фіксатор дужки. Підсумок є, він змінюється зовсім небагато.

2
також перевірити цю відповідь: stackoverflow.com/a/16407391/164835
Кент

Відповіді:


111

Перейдіть до початкового рядка свого блоку та введіть ma(позначте "a", хоча ви, звичайно, можете використовувати різні літери та навіть декілька літер для різних знаків, за умови, що ви можете тримати його прямо в голові, що означає кожна буква) .

Потім перейдіть до останнього рядка та введіть d'a(видаліть, щоб позначити "a") або y'a(yank to mark "a") (a) .

Це видалить / витягнути всі рядки з поточного до позначеного (включно).

Тоді ви можете вставити його деінде за допомогою звичайних команд вставки, наприклад, pабо P.

Це також сумісне з vi, а також vim, за винятком випадків, що ваше оточення не буде благословлено останніми.


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

Я просто позначаю поточний рядок таким же чином ma, а потім блукаю, щоб знайти все, що ви шукаєте.

Потім, як тільки я знайшов його і скопіював у реєстр, я просто входжу, 'aщоб повернутися до позначки "a", рядок, який я заздалегідь зберег, де потім зможу вставити його.


9
Можна також використовувати для цього візуальний режим, правда?
jmc

3
Це один спосіб, jmc, але я не впевнений, що стандарт vi має візуальний режим.

5
Оскільки я перейшов від візуального вибору до розмітки та відносних номерів рядків близько року тому, я виявив, що команди руху руху набагато швидші та ефективніші, ніж візуальний вибір. Навіть незважаючи на те, що пізніше простіше кожного разу, коли натискаю vклавішу, я запитую себе: мені це дійсно потрібно чи є кращий спосіб руху?
Сукіма

1
Так, @Sukima так само цікаво, що я відчуваю себе ефективніше, чим менше миші використовую навіть у графічному інтерфейсі. Я вважаю себе швидшим, якщо зможу залишитися на клавіатурі.

3
Якщо ви коли-небудь редагуєте щось із по-справжньому довгими рядками, версія цього режиму може бути дуже зручною (що стосується місця всередині рядка, а не цілого рядка).
msouth

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).

Або, як запропонував Лі Раян, використовуйте d/search-string/eдля видалення тексту з поточного курсору до рядка, що шукається.

Дивіться: :help dта :help motionдля отримання додаткової інформації.


2
Також d/search-string/eслід видалити з поточного курсору до кінця рядка пошуку, включаючи саму пошукову рядок, і c/search-queryвступити в режим вставлення після видалення. Використання d/з 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]. Тож насправді це трохи більш гнучко, ніж ви це зробили.
подвійнеDown

5

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


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

Я думаю, що деякі прив'язки @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'

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


Спочатку я вважав, що ця відповідь трохи не відповідає темі, але потім я встановив плагін, і я повинен сказати, що це зміна гри для мене. Я використовував обмін вручну, і додатковий розумовий крок означав, що я відхилявся від використання цих рухів. Дякую!
Сукіма

1
Це звучить як щось, що може зробити один autocmd InsertEnter / InsertLeave для переключення відносної нумерації рядків. Я щось пропускаю?
Бен

Я ДУЖЕ запізнююсь на вечірку, але @Ben має рацію, це всього лише кілька ліній автокоманди. Наприклад, у своєму vimrc я маю set number, set relativenumberтоді autocmd InsertEnter * :set norelativenumberіautocmd InsertLeave * :set relativenumber
B Layer

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, оскільки він також працює in vi, і, звичайно :set number, завжди корисний для пошуку номера рядка, який ви хочете перейти.
Випадково832

Вся суть цього питання полягає в тому, що ви не знаєте, скільки рядків ви хочете видалити.
200_успіх

200_досягнення успіху, вам не потрібно знати, скільки рядків ви хочете видалити за допомогою відповіді, яку я опублікував. Все, що вам потрібно знати, - це "до якої лінії ви хочете прибрати"
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.