Янки имя файла / путь к текущему буферу в Vim

188

Предполагая, что текущий буфер является файлом, открытым для редактирования, :eон не отображается E32: No file name.

Я хотел бы выдернуть одно или все из:

  • Имя файла точно так же, как показано в строке состояния, например ~\myfile.txt
  • Полный путь к файлу, например c:\foo\bar\myfile.txt
  • Просто имя файла, например myfile.txt
davetapley
источник
Аналогично stackoverflow.com/q/741024/80161 и stackoverflow.com/q/2233905/80161
Натан Хартли
В буфер обмена: vi.stackexchange.com/questions/3686/…
Сиро Сантилли 郝海东 冠状 病 六四 事件 法轮功

Ответы:

209

TL; DR

:let @" = expand("%")>

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

:nmap cp :let @" = expand("%")<cr>

Вы также можете использовать это для полного пути

:let @" = expand("%:p")

объяснение

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

Используя, letмы можем вручную сохранить текст в регистре, используя, :let @" = "text"но мы также можем сохранить результат выражения.

В приведенном выше примере мы используем функцию, expandкоторая расширяет символы подстановки и ключевые слова. в нашем примере мы используем expand('%')для расширения текущего имени файла. Мы можем изменить его как expand('%:p')для полного имени файла.

Смотрите :help let :help expand :help registersдля деталей

JD Frias
источник
23
Круто только что добавил это в мой vimrc: noremap <silent> <F4>: let @ + = expand ("%: p") <CR>
ThePosey
9
В Windows вместо этого следует использовать: let @ * = expand ("%"), если вы хотите, чтобы он был в буфере обмена Windows .
KFL
15
Если вы используете в unnamedplusкачестве буфера обменаlet @+ = expand("%")
Кевин Кокс
4
Используйте, "%:h"чтобы получить полный путь без имени файла.
Полиморф
Связанные, в частности, если вам нужен каталог без имени файла - stackoverflow.com/a/2233924/1882064
arcseldon
94

Почти то, что вы просите, и это может сделать: Ctrl+R %перетянуть текущее имя файла туда, где вы находитесь (командная строка, редактировать буфер, ...). Смотрите этот Vim Совет для более.

DWC
источник
1
Когда вы выходите из режима редактирования, вы можете добавить имя файла: ctrl- "ctrl-% p
stefanB
13
Ctrl+R %работает в insertрежиме - но в editрежиме Ctrl+Rозначает повтор.
Кевин Панко
3
StefanB имел в виду «% p для нормального / командного режима. Это то же самое, что и <Cr>% в режиме вставки / cmdline-mode.
graywh
Просто для того, чтобы резюмировать или сформулировать по-другому: ответы для graywh и dwc - «вставить из регистра%». Один делает это для режима вставки, другой для нормального режима. В macvim кажется, что регистр% не может быть перезаписан.
Эрик Ху
есть ли такая же простая команда для получения белья? ) спасибо за решение
itsnikolay
73

Если вы хотите поместить текущее имя буфера в буфер обмена системного уровня, попробуйте изменить регистр на @ +:

" relative path
:let @+ = expand("%")

" full path
:let @+ = expand("%:p")

" just filename
:let @+ = expand("%:t")

Изменить 20140421: я обычно использую их, поэтому я создал несколько ярлыков. Linux Vims, по-видимому, работает немного иначе, чем Mac Vims , поэтому для этого также есть особый случай. Если вы добавите следующее в свой ~/.vimrc:

" copy current file name (relative/absolute) to system clipboard
if has("mac") || has("gui_macvim") || has("gui_mac")
  " relative path  (src/foo.txt)
  nnoremap <leader>cf :let @*=expand("%")<CR>

  " absolute path  (/something/src/foo.txt)
  nnoremap <leader>cF :let @*=expand("%:p")<CR>

  " filename       (foo.txt)
  nnoremap <leader>ct :let @*=expand("%:t")<CR>

  " directory name (/something/src)
  nnoremap <leader>ch :let @*=expand("%:p:h")<CR>
endif

" copy current file name (relative/absolute) to system clipboard (Linux version)
if has("gui_gtk") || has("gui_gtk2") || has("gui_gnome") || has("unix")
  " relative path (src/foo.txt)
  nnoremap <leader>cf :let @+=expand("%")<CR>

  " absolute path (/something/src/foo.txt)
  nnoremap <leader>cF :let @+=expand("%:p")<CR>

  " filename (foo.txt)
  nnoremap <leader>ct :let @+=expand("%:t")<CR>

  " directory name (/something/src)
  nnoremap <leader>ch :let @+=expand("%:p:h")<CR>
endif

Затем, например <leader>cf, скопирует относительный путь текущего буфера (лидером по умолчанию является обратная косая черта ( \)). Я часто использую их для запуска команд в файле или выполнения других действий в командной строке. Я не часто использую последнее имя файла / имя каталога.

Вы можете рассмотреть более интуитивные отображения, например, <leader>cfrдля относительного, <leader>cfaдля абсолютного, <leader>cffпросто для имени файла, <leader>cfdдля каталога.

Энтони Паноззо
источник
2
На Windows и Mac "*и "+эквивалентны, так что вы можете обойтись без проверок платформы и просто использовать@+
Гейб Moothart
1
Как ни странно, это не работает в функции vimscript: «echo bufname ('%: p')» пусто, но это можно исправить с помощью более длинного «fnamemodify (bufname ('%'), ': p') ) "
Дэвид Люнг Мэдисон Стеллар
6

Если вы это сделаете, :regвы увидите имя текущего файла в %реестре. Вы можете вставить его "%p, например.

Если, как и я, вы часто переключаетесь на «альтернативный» буфер, очень удобно, что его полный путь и имя файла заносятся в #регистр. Вы можете вставить его "#p, например.

Примечание (на всякий случай, это поведение, специфичное для моей установки): я использую VIM 7.4.52 в Ubuntu 14.04.4 LTS.

Роберт
источник
4

Объединение информации из пары других ответов: Если вы хотите восстановить текущий полный путь к файлу и поместить его в буфер команд в другом окне, сначала выполните :let @" = expand("%:p"), затем перейдите в другое окно и введите Ctrl+R ".

Полезно для копирования файла, оставаясь в том же каталоге и сохраняя старый открытый. Например:

Начало : Редактирование src / com / benatkin / paint / shape / Circle.java

  1. Тип :let @" = expand("%:p") (Путь возвращается к основному буферу буфера обмена.)

  2. Откройте новое окно с :sp

  3. Тип :e Ctrl+R"

  4. С помощью клавиш со стрелками вернитесь к кругу, измените его на квадрат и нажмите <CR>

Конец : Редактирование src / com / benatkin / paint / shape / Square.java

Бенджамин Аткин
источник
1

Вот мое решение:

" filename / dirname of the current file {{{
    " copy result to the system clipboard and echo the result
    " the cb> prompt means the clipboard
    " *f*ile *n*ame, ex. init.vim
    map <Leader>fn :let @+ = expand("%:t") \| echo 'cb> ' . @+<CR>
    " *f*ile *p*ath, ex. /home/user/nvim/init.vim
    map <Leader>fp :let @+ = expand("%:p") \| echo 'cb> ' . @+<CR>
    " *d*irectory *p*ath, ex. /home/user/nvim
    map <Leader>dp :let @+ = expand("%:p:h") \| echo 'cb> ' . @+<CR>
    " *d*irectory *n*ame, ex. nvim
    map <Leader>dn :let @+ = expand("%:p:h:t") \| echo 'cb> ' . @+<CR>
" }}}
Джабба
источник
-1

Я использую xclip для доступа к буферу обмена X, поэтому я использую:

nmap <localleader>d :call system("xclip -i -selection clipboard", expand("%:p"))<CR>
user189557
источник
«+» или «*» делают то же самое в Vim без необходимости использования внешней команды.
Дориан Б.