Как использовать vim-скрипт для выполнения команд в функции

#shell #vim #neovim

#оболочка #vim #neovim

Вопрос:

Я пишу новый код в своем .vimrc (я очень новичок в написании сценариев vim)

чего я хочу, так это

Откройте страницу определения word под курсором в правой части разделенного окна

итак, левое окно предназначено только для индекса, а правое — для предварительного просмотра (как на рисунке ниже)

Моя функция предназначена

  1. в первый раз откройте разделение в виде вертикального окна, затем выполните K (в обычном режиме)
  2. и после первого раза я закрываю правое окно и выполняю тот же процесс

но когда я вызвал функцию, я получил сообщение об ошибке Invalid argument

 nnoremap <Leader><CR> :call Goto_definition() <CR>

let g:first_open=0
function! Goto_definition() 
    if g:first_open
        :vs <bar> :wincmd l <CR> // 1. vertical split and go to right window
        :exe 'normal K'          // 2. then press shortcut K (in normal mode)
        let g:first_open=0       // 3. set variable
    else 
        :wincmd l<bar> :q<bar>  // 4 .close right window first (because it's not a first time)
        :vs <bar> :wincmd l <CR> // repeat step 1~3 
        :exe 'normal K'
    endif
endfunction

  

Какой неправильный код в моей функции??

введите описание изображения здесь

Ответ №1:

Вы выразили свои действия так, как если бы написали сопоставление.

Вам не нужно и не должно использовать <CR> <bar> в конце строки) — ни :exe — в вашем случае. И не бойтесь писать свои команды в нескольких строках.

И не забудьте обновить переменную.

 nnoremap <Leader><CR> :<c-u>call <sid>Goto_definition()<CR>

let s:first_open = get(s:, 'first_open', 0) " set to 0 the first time, keep the old value when resourcing the plugin

function! s:Goto_definition() abort
    if ! s:first_open
        wincmd l
        q
    endif

    " Looks like the following steps shall always be executed.
    rightbelow vs " same as vs   wincmd l
    normal K
    " with a K command (which doesn't exist), it could have been done with: "rightbelow vs  K"

    let s:first_open = 1 - s:first_open
endfunction
  

PS: номера строк помогают понять, в чем проблема.

Комментарии:

1. спасибо за помощь мне, я хочу знать, что означает s: и abort , и не могли бы вы рассказать мне, почему вы используете <c-u> и <sid> в map?

2. s: ограничивает область действия функции текущим файлом. Это позволяет избежать загрязнения глобального пространства имен. abort сообщает интерпретатору прекратить интерпретацию функции при первой обнаруженной ошибке, в противном случае он пытается продолжить. <c-u> очищает любой ожидающий подсчет, который вы могли ввести ранее (попробуйте 1<leader><cr> с и без <c-u> ). <sid> позволяет использовать локальную функцию скрипта из сопоставления.