vim, быстрое переключение между файлами с помощью vanilla Vim (без плагинов)


103

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

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

Но в редакторе, таком как Sublime Text , я могу просто печатать ctrl- pи сразу оказываюсь у файла.

Я знаю, что могу перейти к оболочке, но мне интересно, есть ли какие-либо другие «скрытые» секреты быстрого переключения между файлами в Vim, основанные не только на имени файла.


2
Это не отвечает на ваш вопрос, но может убедить вас подумать об использовании плагинов: dudarev.com/blog/keep-vim-settings-and-plugins-in-git-repo
ajwood

Я лично синхронизирую свои настройки с Dropbox. Это неуклюже, но более-менее работает, даже не задумываясь. Один плагин, который я использую и знаю, хорошо работает для того, что вы хотите, - это Command-T ( github.com/wincent/Command-T ). Ctrl-P может быть альтернативой ( vim.org/scripts/script.php?script_id=3736 ).
FX

1
Вы видели danielmiessler.com/study/vim ? У него очень умная практика: он помещает свой vimrc + все плагины, которые ему нужны, в Github ... куда бы он ни пошел, он может клонировать его и вуаля, Vim именно такой, как ему нравится. Brilliant
bobox 06

6
@bobox, этим занимаются десятки тысяч людей; в этом нет ничего экстраординарного.
romainl

Ответы:


236

Ближайший эквивалент («ближайший», а не «точный») для ST2 Ctrl+ P- это плагин, называемый, будьте готовы… CtrlP . Есть и другие похожие плагины, такие как Command-T или FuzzyFinder .

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


Открытие файлов

Самый простой способ открыть файл - это :e /path/to/filename. К счастью, вы получаете завершение табуляции и подстановочные знаки: классический *и специальный **, что означает «любой подкаталог».

Объединив все это, вы можете:

:e **/*foo<Tab>

выбрать из всех файлов, содержащихся fooв их имени, в рабочем каталоге или:

:e **/*foo/*bar<Tab>

для выбора из всех файлов, содержащихся barв их имени, в любом подкаталоге, содержащемся fooв его имени, в любом месте рабочего каталога.

Конечно, это работает для :tabe[dit], :sp[lit]и :vs[plit], тоже.

Однако эти команды ограничены одним файлом. Используйте :nextдля открытия нескольких файлов:

:next **/*.js

и взгляните на :help arglist.


Переход между буферами

:b[uffer] это основная команда переключения буфера:

:b4         " switch to buffer number 4
:bn         " switch to next buffer in the buffer list
:bp         " switch to previous buffer in the buffer list
:bf         " switch to first buffer in the buffer list
:bl         " switch to last buffer in the buffer list
:b foo<Tab> " switch by buffer name with tab-completion
:b#         " switch to the alternate file

Обратите внимание, что многие из этих команд и их родственники принимают счет.

Команда :lsпоказывает вам список загруженных буферов. Однако это немного «особенное»: при создании буферам присваивается номер, поэтому вы можете получить список, который будет выглядеть, как 1 2 5если бы вы удалили буферы. Да, это немного неудобно, и это делает переключение на буфер по его номеру слишком проблематичным. Предпочитайте переключение по частичному имени :b foo<Tab>или циклическое переключение :bn :bp.

В любом случае, вот классное отображение, которое перечисляет все загруженные буферы и заполняет подсказку для вас, ожидая, когда вы наберете номер буфера и нажмете <enter>:

nnoremap gb :ls<CR>:b<Space>

С этим отображением переключиться на другой буфер так же просто, как:

gb
(quickly scanning the list)
3<CR>

или:

gb
(quickly scanning the list)
foo<tab><CR>

Идея исходит из этого изображения, взятого из коллекции инфографики Vim Байруи :

Полеты против езды на велосипеде

В Vim также есть <C-^>(или <C-6>на некоторых клавиатурах) - эквивалент нормального режима - для переключения :b#между текущим буфером и предыдущим. Используйте его, если вы часто переключаетесь между двумя буферами.

Прочтите все о буферах в :help buffers.


Перейти к декларации

Внутри файла вы можете использовать gd или gD.

В рамках проекта функция «тегов» Vim - ваш друг, но вам понадобится внешний индексатор кода, например ctags или cscope. Самые простые команды - это :tag fooи <C-]>с курсором на имени метода. Оба инструмента хорошо интегрированы в Vim: см :help tags,:help ctags и :help cscope.

Что бы это ни стоило, я широко использую навигацию по тегам для перемещения внутри проекта (в основном, используя CtrlP :CtrlPTagи :CtrlPBufTagкоманды, но также и встроенные), и мой любимый «общий» метод переключения буфера - по имени.


Развертывание вашей конфигурации

Многие пользователи Vim помещают свою конфигурацию в систему контроля версий, что позволяет очень быстро и легко установить собственную конфигурацию на новую машину. Подумай об этом.


РЕДАКТИРОВАТЬ

Несколько месяцев назад мне пришлось работать на удаленной машине с устаревшим Vim. Я мог бы установить подходящий Vim и клонировать свой любимый конфиг, но на этот раз я решил путешествовать налегке, чтобы «заточить пилу». Я быстро построил минимализм .vimrcи пересмотрел пару полузабытых нативных функций. После этого выступления я решил, что CtrlP не так уж необходим, и избавился от него: собственные функции и настраиваемые сопоставления не так привлекательны, но они выполняют свою работу без особых зависимостей.


Жонглирование файлами

set path=.,**
nnoremap <leader>f :find *
nnoremap <leader>s :sfind *
nnoremap <leader>v :vert sfind *
nnoremap <leader>t :tabfind *

:findдействительно отличная команда, как только вы set pathправильно сделаете . С моими настройками рекурсивно ,ffoo<Tab>найдет все файлы, содержащиеся fooв текущем каталоге. Это быстро, интуитивно понятно и легко. Конечно, я выигрываю от того же завершения и подстановочных знаков, что и с:edit друзьями.

Чтобы сделать процесс еще быстрее, следующие сопоставления позволяют мне пропускать целые части проекта и рекурсивно находить файлы в каталоге текущего файла:

nnoremap <leader>F :find <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>S :sfind <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>V :vert sfind <C-R>=expand('%:h').'/*'<CR>
nnoremap <leader>T :tabfind <C-R>=expand('%:h').'/*'<CR>

ПРЕДУПРЕЖДЕНИЕ! pathВариант чрезвычайно мощный. Значение выше - .,**- работает для меня, но для языков, которые я использую, нет стандартной библиотеки. Правильное значение полностью зависит от ваших потребностей.


Жонглирование буферами

set wildcharm=<C-z>
nnoremap <leader>b :buffer <C-z><S-Tab>
nnoremap <leader>B :sbuffer <C-z><S-Tab>

Приведенные выше сопоставления перечисляют доступные буферы в «wildmenu» с пустой подсказкой, что позволяет мне либо перемещаться по меню, <Tab>либо вводить несколько букв и <Tab>снова сужать список. Как и в случае с отображением файлов выше, процесс выполняется быстро и практически без проблем.

nnoremap <PageUp>   :bprevious<CR>
nnoremap <PageDown> :bnext<CR>

Эти сопоставления говорят сами за себя.


Жонглирование тегами

nnoremap <leader>j :tjump /

Это сопоставление использует поиск по регулярному выражению вместо поиска по всему слову, поэтому я могу ,jba<Tab>найти тегfoobarbaz() .

Да, нечеткое сопоставление вызывает привыкание, но вы можете работать и без него. И за небольшую часть стоимости.


БОЛЬШЕ ИЗМЕНИТЬ

Пара дополнительных советов / хитростей…


Параметры Wildmenu

"Wildmenu", доступный с set wildmenu , упрощает навигацию по файлам / . Его поведение регулируется рядом параметров, которые стоит изучить:

wildmode сообщает Vim, как должно вести себя "wildmenu":

set wildmode=list:full

wildignore отфильтровывает весь мусор:

set wildignore=*.swp,*.bak
set wildignore+=*.pyc,*.class,*.sln,*.Master,*.csproj,*.csproj.user,*.cache,*.dll,*.pdb,*.min.*
set wildignore+=*/.git/**/*,*/.hg/**/*,*/.svn/**/*
set wildignore+=tags
set wildignore+=*.tar.*

wildignorecaseпозволяет искать fooи находить Foo:

set wildignorecase

Метки файлов

augroup VIMRC
  autocmd!

  autocmd BufLeave *.css  normal! mC
  autocmd BufLeave *.html normal! mH
  autocmd BufLeave *.js   normal! mJ
  autocmd BufLeave *.php  normal! mP
augroup END

Я недавно нашел этот камень у кого-то другого ~/.vimrc. Он создает метку файла в точном положении курсора всякий раз, когда вы покидаете буфер, так что, где бы вы ни находились, 'Jпереходите к последнему буферу JavaScript, который вы редактировали. Потрясающие.


2
+1. Я понятия не имел о «любой подкаталог» в сочетании с , :eно я буду использовать это много теперь. Я восхищаюсь работой, которая попала в Ctrl-P, и могу многому у нее научиться, но у меня это не сработало. Я обнаружил, что это немного вялый и, как таковой, прерывает ход моих мыслей во время работы (может быть моя система, мои настройки, я сам, но я не исследовал)
Ливен Керсмэкерс

2
**действительно здорово.
romainl

1
Я бы хотел снова проголосовать за gbкарту. Еще один, которым я буду часто пользоваться. Все буферные плагины, которые я пробовал (CtrlP, bufExplorer, ...) , не так быстры, как этот ( конечно, они предлагают больше функциональности, но недостаточно для меня, чтобы продолжать их использовать) .
Ливен Кеерсмэкерс

2
@LievenKeersmaekers, вот откуда я это взял, и отсюда и взялась глупая картинка. Спасибо, Байруи!
romainl

4
Это может быть самый лучший ответ на свете.
craigp

5

Ответ во многом зависит от ваших предпочтений и обстоятельств. Некоторые примеры:

  • Если это в основном два файла (например, заголовок C и файл реализации), <C-^>это очень удобно. В общем, альтернативный файл - важное понятие.
  • Если вы используете большое окно редактора, window :splitрешает проблему определения местоположения буфера из местоположения окна (после того, как вы открыли все буферы). Ты можешь использовать[N]<C-w><C-w> для быстрого переключения на него.
  • Если вы можете запомнить (несколько) буфер числа, то :[N]b[uffer]и :[N]sb[uffer]команды очень удобно; :lsсообщает вам числа.

Плагины (или, по крайней мере, настраиваемые сопоставления) могут значительно улучшить ситуацию, и на vim.org по этой теме есть множество разнообразных . Существуют различные механизмы распространения вашей конфигурации (Pathogen + GitHub, Dropbox, ...), или вы можете удаленно редактировать файлы сервера через плагин netrw, который поставляется с Vim.


4
Возможно, стоит упомянуть ctags, cscope, gtags, id и друзей. Я считаю, что использование заглавных букв очень полезно. Используйте mAдля сохранения отметки Aи `` A '' для возврата. Я нахожу netrw намного более полезным после того, как узнал, :Rexкакой из них возвращается в проводник. :b, :eи многие другие могут использовать подстановочные знаки, такие как *и **. Команда :bможет принимать частичное имя файла. Объедините это с <c-d>или wildmenu, вы можете далеко продвинуться. Что касается плагинов, вы можете использовать что-то специфичное для домена, например rail.vim, который предоставляет специальные навигационные команды для рельсов или что-то более общее, например CtrlP.
Питер Ринкер

@PeterRincker: +1 за упоминание о марках. Предлагаю построить ответ отметками.
Helbreder

Что означает <C - ^> и [N] <Cw> <Cw>?
Джош Десмонд

5

Иногда также удобно просматривать список файлов последовательно (например, если вы сделали что-то вроде vim *.phpоткрытия нескольких файлов одновременно). Затем вы можете использовать :n[ext](а также :prev[ious], :fir[st]и :la[st]) для навигации (в дополнение к тому , что было предложено в других ответов).


4

Вы можете выполнить завершение табуляции с подстановочными знаками в командной строке без каких-либо плагинов. например

:e src/**/foo*<tab>

позволит вам перебрать все файлы, начинающиеся с 'foo' в дереве каталогов в ./src, и выбрать тот, который вы хотите отредактировать.

Если вы уже редактировали файл, но он все еще находится в буфере, вы можете переключиться на него с помощью:

:b foo<tab>

который будет циклически проходить через все буферы с 'foo' в пути. Вам может потребоваться установить параметры wildmode и wildmenu, чтобы получить желаемое поведение. у меня есть

wildmode=longest:full
wildmenu

в моем .vimrc.


2

Если вы выбрали имя файла и хотите перейти к этому файлу, gfмы сделаем это за вас. Мне также нравится использовать ctags , который не является плагином; вы просто создаете теги и можете легко перемещаться по своей кодовой базе.


1

Если вы хотите переключаться между файлами в редакторе vim, см. Ответ ниже

Первое нажатие Esc чтобы выйти из режима редактирования.

Затем введите :e чтобы проверить текущий путь к файлу.

если вы хотите перейти к другому файлу, введите :e /path-of-file.txt/ используя его, вы можете переключиться.

Если вы хотите перейти к предыдущему файлу, просто введите, :e#чтобы переключиться на предыдущий путь к файлу.


0

У меня была такая же проблема с Vim.

Меньше всего я хочу полагаться на плагины для такой рутинной задачи, как переключение файлов.

Я добавил следующие строки в .vimrc

set path+=**
set wildmenu

И БАМ! Теперь я могу, :find any/filename/in/any/folder/пока vim находится в корневом каталоге проекта. Вкладка доработка работает. Подстановочные знаки работают!

Когда файлы уже открыты и в фоновом режиме имеется множество буферов (вы можете использовать их :lsдля просмотра всех буферов), при запуске выполняется :b any/file <TAB>нечеткий поиск всех буферов и выполняется переход к требуемому файлу. Если он не уникален, появится дикое меню вкладок (следовательно, вторая строка в .vimrc), которое можно выбрать с помощью вкладки.

Мой ответ исходит из этого потрясающего видео
https://www.youtube.com/watch?v=XA2WjJbmmoM&feature=youtu.be&t=489
Здесь есть еще уловки, и я рекомендую его посмотреть.

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