2

我有一个MoveToFile将选定文本附加到文件然后将其删除的函数。

command! -nargs=* -complete=file -range=% -bang -bar MoveToFile
\   :<line1>,<line2>call MoveToFile(<q-args>, <bang>0)
function! MoveToFile(fname, overwrite) range
    let r = a:firstline . ',' . a:lastline
    exe r 'w>>' . ' !'[a:overwrite] . fnameescape(a:fname)
    exe r 'd'
endfunction

当我试图追加的文件已经在 Vim 中打开时,就会出现问题。我怎样才能解决这个问题?

4

2 回答 2

2

你可以抓住E139: File is loaded in another buffer. 如果您确实需要处理这种极端情况,请拉出内容,通过 打开现有缓冲区:buffer {fname},然后粘贴它们:

try
   exe r 'w>>' . ' !'[a:overwrite] . fnameescape(a:fname)
catch /^Vim\%((\a\+)\)\=:E139/
    exe r 'yank'
    exe 'sbuffer' fnameescape(a:fname)
    $put
    hide
endtry
于 2012-08-11T18:26:53.113 回答
0

您可以使用writefile()(请注意,这将覆盖文件,因此必须首先获取当前内容,因此不适用于大型文件):

function MoveToFile(fname, _) range abort
    let lines=readfile(a:fname, 'b')
    if !empty(lines) && empty(lines[-1])
        call remove(lines, -1)
    endif
    let [first, last]=((a:firstline>a:lastline)?([a:lastline, a:firstline]):([a:firstline, a:lastline]))
    let lines+=getline(first, last)+['']
    call writefile(lines, a:fname, 'b')
    execute first.','.last.'delete _'
endfunction

:w>>注意:要获得与您需要替换行相同的编码

    let lines+=getline(first, last)+['']

    let lines+=map(getline(first, last), 'iconv(v:val, &enc, &fenc)')+['']

. 还要尊重'dos'文件格式:

    let lines+=map(getline(first, last), 'iconv(v:val, &enc, &fenc)'.((&ff is# 'dos')?('."\r"'):('')))+[(&ff is# 'dos')?("\r"):('')]

(尊重'mac'文件格式比较棘手)。

于 2012-08-11T14:33:02.660 回答