1

次のような非常に単純な ToDo ファイルがあります。

130821 Go to the dentist
130824 Ask a question to StackOverflow
130827 Read the Vim Manual
130905 Stop reading the Vim Manual

ファイルを開くたびに、さまざまな期日までの残り日数を計算したいと思います(今日は2013年8月22日、つまりパリでは130822です)。

130821 -1 Go to the dentist
130824 2 Ask a question to StackOverflow
130827 5 Read the Vim Manual
130905 14 Stop reading the Vim Manual

しかし、それを達成する方法がわかりません(そして、それが合理的に可能かどうかはわかりません:cf. glts'comment)

あなたの助けをいただければ幸いです。

4

2 に答える 2

2

This command will do the desired substitution but the wrong calculation (it WON'T work as-is):

%s#\v^(\d{6})( -?\d+)?#\=submatch(1).' '.(submatch(1)-strftime("%y%m%d"))

See :help sub-replace-expression, :help submatch(), :help strftime().

Note my use of \v to put Vim's regex parser into "very magic" mode.

You could easily apply this whenever you load the file using a BufReadPost autocmd.

Something like:

augroup TODO_DATE_CALC
au!
au BufReadPost myToDoFileName %s#\v^(\d{6})( -?\d+)?#\=submatch(1).' '.(submatch(1)-strftime("%y%m%d"))
augroup END

Find out the time since unix epoch for a certain date time? shows how to get a unix time for a specific date, you can use the system() function in Vim to grab the result. But I don't have a system to test that out on at the moment. I think you might be out of luck, on Windows.

Unless you can change your file format to include unix time...then it ought to be fairly easy.

于 2013-08-22T21:50:28.163 に答える
0

彼らは納得していましたが、私の質問に対する回答には少しがっかりしました。解決策を見つけようとしましたが、ほぼ成功したようです。言うまでもなく、これは不器用な仕掛けですが、機能します。

まず、ファイル (テスト目的でわずかに変更) :

130825 Past ToDo test 
130827 Today's ToDo test 
130829 In two days ToDo test 
130831 Another test 
130902 Change of month ToDo test 
131025 Another change of month test 

次に、http://www.epochconverter.comによって提供されるデータ:

1 day                   = 86400 seconds
1 month (30.44 days)    = 2629743 seconds
1 year (365.24 days)    = 31556926 seconds

第三に、私がいじった機能:

function! DaysLeft()

  :normal! gg

  let linenr = 1
  while linenr <= line("$")
  let linenr += 1
  let line = getline(linenr)

  :normal! 0"ayiw
  :.s/\(\(\d\d\)\)\(\d\d\)\(\d\d\)\>/\1
  :normal! 0"byiw
  :execute "normal! diw0i\<C-R>a"

  :normal! 0"ayiw
  :.s/\(\d\d\)\(\(\d\d\)\)\(\d\d\)\>/\2
  :normal! 0"cyiw
  :execute "normal! diw0i\<C-R>a"

  :normal! 0"ayiw
  :.s/\(\d\d\)\(\d\d\)\(\(\d\d\)\)\>/\3
  :normal! 0"dyiw
  :execute "normal! diw0i\<C-R>a"

  let @l = strftime("%s")

  :execute "normal! 0wi\<C-R>=((\<C-R>b+30)*31556926+(\<C-R>c-1)*2629743+(\<C-    R>d-1)*86400+1-\<C-R>l)/86400\<Enter>\<tab>"

  exe linenr
  endwhile

  endfunction

第四に、結果:

130825 -2   Past ToDo test
130827 0    Today's ToDo test
130829 1    In two days ToDo test
130831 3    Another test
130902 5    Change of month ToDo test
131025 58   Another change of month test

ご覧のとおり、不具合があります: 130829 ToDo は 2 日ではなく 1 日で表示されます (浮動小数点計算を行っていないため)。しかし、実際には、これはプログラミングの不具合 (とりわけ…) であると考えていますが、心理的に健全な不具合であると考えています。

それは無益な練習かもしれませんが、これは純粋なVimの答えを出すために、キャプチャ、ループ、レジスタ、そしてもちろん以前のStackOverflowの貴重な答えを勉強させてくれました。

あなたが私の答えにもたらすすべての改善に感謝します。

于 2013-08-27T18:45:15.330 に答える