0

该用例由全球所有(vim)开发人员共享(恕我直言):我们希望更新源文件中每个写入操作的标签时间戳。在 Barry Arthur 的帮助下,我的尝试是这样的:

每次写入时更新的字符串示例

# 2013-01-09 01:04:31.0 +0100 / Me <me@domain.tld>

vimrc 代码

" if not maped, :x don't call UpdateTimestamp()
map :x :wq
function! UpdateTimestamp()
  let old_pos = getpos('.')
  let old_search = histget("search", -1)
  g/^\(#\|\/\/\)\s\+\d\{4\}-\d\{2\}-\d\{2\}\s\+\d\{2\}:\d\{2\}:\d\{2\}\.\d\+\s\++\d\{4\}\s\+\/\s\+Me <me@domain.tld>.*/s/.*/\="# " . strftime('%F %H:%M:%S.0 %z') . " \/ Me <me@domain.tld>"/
  exe "normal /".old_search
  call setpos('.', old_pos)
endfunction

au BufWrite * call UpdateTimestamp()

未解决的问题

  • 更新标签时不应修改撤消历史记录(如果可能)
  • 屏幕位置在写入时发生变化
  • 找不到图案时,屏幕上会显示一些不需要的错误

问题

简单:如何解决这些问题?

4

2 回答 2

2
  • RE:更新标签时不应该修改
    历史你的意思是撤消历史,对吧?这违背了 Vim 的设计。每一个变化都需要被表现出来。你能做的最好的是:undojoin,但我会觉得这很混乱。

  • RE:屏幕位置在写入时更改
    您需要使用winsaveview()/winrestview()而不是setpos().

  • 回复:当找不到模式时,屏幕上会显示一些不需要的错误在 的末尾
    传递标志,并添加到./e:substitute:silent!:global

PS:我认为 vim.org 上有插件可以满足您的需求。你试过其中一些吗?

于 2013-01-09T00:46:24.387 回答
1

您根本不需要保存/恢复位置,既不使用setpos()也不winrestview():您不能移动光标。您不需要技巧来保存/恢复搜索:使用search()函数代替:gsetline()代替s/.*/\=

function! UpdateTimestamp()
  " Removed “.*” from the end of the pattern because it is pointless
  " Also made it use very-magic mode because otherwise it looks bad (too many escapes)
  " Also replaced \d\{2\} with \d\d because \d\d takes less characters
  let lnr=search('\v^(\#|\/\/)\s+\d{4}\-\d\d\-\d\d\s+\d\d\:\d\d\:\d\d\.\d+\s+\+\d{4}\s+\/\s+\VMe <me@domain.tld>', 'wn')
  if lnr
    " Matchstr gets comment leader. Above regex intended to work with # or // comments, but \=expression supported only the former, this got fixed
    call setline(lnr, matchstr(getline(lnr), '^\S\+')." " . strftime('%F %H:%M:%S.0 %z') . " / Me <me@domain.tld>")
  endif
endfunction

. 注意:您和我的解决方案之间仍然存在一个差异:这里只更新了一个时间戳。这个问题可以修复。

于 2013-01-09T16:22:25.177 回答