将光标放在通过 append / line 附加的行之后

Placing cursor after lines appended via append / line

我使用以下函数在以下格式的注释中插入一个分隔符:

中断:

# Notes -------------------------------------------------------------------

函数:

" Insert RStudio like section break
function! InsertSectionBreak()
        let title = input("Section title: ")            " Collect title
        let title_length = strlen(title)                " Number of repetitions
        let times = 80 - (title_length + 1)
        let char = "-"                                  " Create line break
        let sep_line =  repeat(char, times)
        let final_string = '\n#' . ' ' . title . ' ' . sep_line " Create final title string
        call cursor( line('.')+1, 1)
        call append(line('.')+1, final_string)            " Get current line and insert string
endfunction

" Map function to keyboard shortcut ';s'
nmap <silent>  ;s  :call InsertSectionBreak()<CR>

问题

执行操作后,我想将光标放在创建的部分下方一行。

期望的行为:

# Notes -------------------------------------------------------------------

<cursor should land here>

当前行为

光标停留在当前行。

<some code I'm typing when I exit insert mode and call ;s - cursor stays here>
# Notes -------------------------------------------------------------------

<cursor lands here>

作为low-level函数,append()不受光标位置影响,也不影响光标位置。因此,您只需要调整 cursor() 参数。我还建议只在最后更改光标,以使基于 line('.') 的计算更容易:

function! InsertSectionBreak()
        let title = input("Section title: ")            " Collect title
        let title_length = strlen(title)                " Number of repetitions
        let times = 80 - (title_length + 1)
        let char = "-"                                  " Create line break
        let sep_line =  repeat(char, times)
        let final_string = '#' . ' ' . title . ' ' . sep_line " Create final title string
        call append(line('.')+1, ['', final_string])            " Get current line and insert string
        call cursor(line('.')+4, 1)
endfunction

补充说明

  • '\n#' 字符串包含文字 \n,而不是换行符。为此,必须使用双引号。但是,即使这样也不适用于 append(),因为它总是将 作为一个文本行 插入,将换行符呈现为 ^@。要包含前导空行,请改为传递行列表,并将第一个列表元素设为空字符串。
  • 您主要使用 low-level 函数(cursor()append());您可以使用 higher-level 函数(:normal! jj:execute lnum 用于光标定位,:put =final_string 用于添加行)。会有更多的副作用(比如添加到跳转列表,:put 取决于和定位光标,并让 更改标记 分隔添加的文本);通常这很好(但这取决于用例)。
  • 以交互方式向用户查询内容的映射不是很好Vim-like。我宁愿定义一个将标题作为参数的自定义命令(例如 :Break {title}),也可能是一个额外的(不完整的 command-line)映射以便快速访问 :nnoremap ;s :Break<Space>。这样,您可以轻松地通过 @: 重复上次插入的相同标题。例如。