Vim: `cd` для пути, хранящегося в переменной

Я новичок в vim, и мне трудно понять некоторые тонкости с помощью скриптов vim. В частности, у меня возникают проблемы с работой с командами, которые ожидают некорректную строку (есть ли название для этого?). Например

cd some/unquoted/string/path

Проблема в том, что я хотел бы передать переменную, но вызываю

let pathname = 'some/path'
cd pathname

попытается изменить текущий каталог на "путь" вместо "some/path". Один из способов - использовать

let cmd = 'cd ' . pathname
execute cmd

но это кажется немного окольным. qaru.site/info/517418/... фактически использует cd с переменной, но он не работает в моей системе ( "a: path" рассматривается как путь, как описано выше).

Я использую cd как конкретный пример, но это поведение не уникально для cd; например, команда edit также ведет себя так. (Есть ли имя для этого типа команды?)

Ответ 1

TL; DR: используйте execute 'cd' fnameescape(pathname)

Объяснение. Множество базовых команд, которые принимают имена файлов в качестве аргумента, поддерживают синтаксис backtick:

command `shell command`

или

command `=vim_expression`

поэтому ваш пример может быть записан как

cd `=pathname`

если вы используете это в контролируемой среде. Вы не должны использовать этот вариант в плагинах, потому что: a) есть параметр &wildignore, который может мешать вам: set wildignore=*|cd =pathname приведет к ошибке cd, независимо от того, что хранится в pathname и b), если pathname содержит символы новой строки, он будет разделен на две или более директорий. Таким образом, то, что вы должны использовать для любой части кода, которую вы собираетесь использовать, -

execute 'cd' fnameescape(pathname)

Обратите внимание: вы не должны использовать execute "cd" pathname, потому что это не касается специальных символов в имени пути (например, пробел).

Ответ 2

Основные команды в Vim никогда не обрабатывают переменные (как бы знать, что вы не хотели менять каталог каталогов, а не какой-то/путь?). Вы не должны быть настолько крутыми, как вы предлагали, вы можете просто сделать:

exe 'cd' pathname

Обратите внимание, что exe автоматически объединяет аргументы с пробелом, поэтому вам не нужно делать:

exe 'cd ' . pathname

Ответ 3

Много времени назад я написал этот плагин (функция FixPathName() для решения таких проблем. Теперь vim имеет несколько новых функций например, shellescape(), когда путь должен использоваться с внешними командами.