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

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

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

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

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

Ответ 1

Ближайший эквивалент ( "ближайший", а не "точный" ) к ST2 Ctrl + P - это плагин, который называется... geta... 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 из коллекции Bairui:

Flying vs cycling

У 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

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

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

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

Ответ 3

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

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

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

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

:b foo<tab>

который будет циклически перемещаться по всем буферам с помощью "foo" в пути. Вам может потребоваться установить параметры wildmode и wildmenu для получения желаемого поведения. У меня

wildmode=longest:full
wildmenu

в моем .vimrc.

Ответ 4

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

Ответ 5

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

Ответ 6

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

Сначала нажмите клавишу Esc, чтобы выйти из режима редактирования.

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

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

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