Bercriber's Blog

プログラミング

2025/06/02 18:52


N分、N文字

最近の日記の末尾に書いている(N分、N文字)は適当になんとなくで計算して書いているので、それをコマンド一発で入力できるようにした。

inoremap <F3> <ESC>:InsertElapsedTimeTextSize<CR>

command! InsertElapsedTimeTextSize call InsertElapsedTimeTextSize()
function InsertElapsedTimeTextSize()
  let l:path = expand("%:f")
  let l:sec = system(["ruby", "-e", "print (Time.now - ARGF.file.birthtime).round / 60", l:path])
  let l:size = system(["ruby", "-e", "print readlines(nil)[0].size", l:path])
  let l:info = printf("(%s分、%s文字)", sec, size)
  execute ":normal i" . info
endfunction

とやってできたなメモっとくかーでブログアップしようとしたら、このコマンドのエラーがでて草。rubyがそんなファイルねえよと言っているそんなばかな。

なるほど。このブログファイルを保存する前にコマンドを実行するから、まだファイルが存在してなくてエラーになるのか。しかし保存をトリガーにVimがブログファイルをgit pushしてしまうので困ったな。ruby使うのを諦めてvimscriptでやるしかなさそう。おのれ。birthtimeをvimscriptで取得する方法がないらしいぞ。

というわけで、ブログファイルのヘッダーにテキストとしてかいてあるファイル作成時間を正規表現でバッファーから取得して計算したぞ。まぁ泥臭いがこれくらいでちょうどいいのだろう。vimscriptはわからんからchatGPT先生に教えてもらいながら書いた。

function BlogInsertElapsedTimeTextSize()
  let l:time = matchstr(getline(2), '\d\+:\d\+')
  let l:ts = split(time, ":")
  let l:birth = str2nr(l:ts[0]) * 60 + str2nr(l:ts[1])
  let l:ts = split(strftime("%X", localtime()), ":")
  let l:now = str2nr(l:ts[0]) * 60 + str2nr(l:ts[1])
  let l:size = GetTotalUtf8CharCount()
  let l:info = printf("(%d分、 %d文字)", (l:now - l:birth), l:size)
  execute ":normal i" . l:info
endfunction

function! GetTotalUtf8CharCount()
  let total_chars = 0
  let num_lines = line('$') " バッファの最終行番号を取得

  for i in range(1, num_lines)
    let line_content = getline(i)
    let total_chars += len(line_content)
  endfor

  return total_chars
endfunction

(126分、 2421文字)