Quantcast
Channel: Vimタグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 5608

Vimが作業を中断させてくれるコマンドをつくってみた

$
0
0

背景

人間が集中力を維持できる時間には限界があり、高い集中力を維持できる限界が15分、普通の集中力を維持できる限界が45分、そして集中力を維持できる限界が90分だといいます(参考文献:読んだら忘れない読書術)。

であれば、集中力が切れてぼーっとし始める前に、設定した時間になったら作業を中断させてくれると便利だなと考えました。

付け加えると、作業中の画面が映っていると休憩中も気になってしまうので、画面を隠してくれると嬉しいです。

ここから私が考えた解決策は、「Vimのタイマー機能でカウントダウンし、終了後にスクリーンセーバーを実行する」というものです。

コード

以下が実際のコードです。

"コマンドラインタイマー(Commandline Timer; cmdtimer)"@param 測る時間(0秒から99分59秒まで)"実行方法 :Ct {minute} [{second}]"概要:"秒単位で指定する時は、{minute}は0にする。"分単位で指定する時は、[{second}]は指定しなくても良い(0が設定される)。"0分0秒を指定することで、現在動いているタイマーを破棄出来る。"ユーザ設定が存在すればデフォルト値で上書きするletg:cmdtimer_show_screensaver= get(g:,'cmdtimer_show_screensaver',v:false)letg:cmdtimer_scrfile_path= get(g:,'cmdtimer_scrfile_path','')lets:running_timer_id=v:null
lets:running_timer_m=v:null
lets:running_timer_s=v:null
com!-nargs=+ Cmdtimer call<SID>CmdtimerMain(<f-args>)function!s:CmdtimerMain(...)letl:min_str =a:1"3つ目以降の引数は無視するletl:sec_str =(a:0>=2) ? a:2:"0""### 引数のバリデーションチェックifmatch(l:min_str,"[^0-9]")!=-1||match(l:sec_str,"[^0-9]")!=-1calls:ErrorMsg("ERROR: Either minute or second is not number format.")returnendif"引数を数値型に変換するletl:min = str2nr(l:min_str,10)letl:sec = str2nr(l:sec_str,10)"値の範囲をチェックするifl:min<0||l:min>99||l:sec<0||l:sec>59calls:ErrorMsg("ERROR: Either minute or second is out of range of [0m0s,99m59s].")returnendif"0分0秒が指定された場合、現在動いているタイマーを破棄するifl:min==0&& l:sec==0calls:CmdtimerStop()returnendif"タイマーの初期値を表示する処理は、"この関数内で行っておかなければならない
  echo "[Timer | ".l:min."min ".l:sec."sec]""他に動いているコマンドラインタイマーがあれば、破棄するifs:running_timer_id!=v:null
    call timer_stop(s:running_timer_id)endif"1秒毎に更新するタイマーを起動するletl:num_of_rep =l:min*60+l:sec
  letl:timer_id = timer_start(1000,function("s:Notifyer"),{"repeat":l:num_of_rep})"タイマーの情報を保持しておくlets:running_timer_id=l:timer_id
  lets:running_timer_m=l:min
  lets:running_timer_s=l:sec
endfunction"コマンドラインタイマーを破棄する"@param 無しfunction!s:CmdtimerStop()ifs:running_timer_id!=v:null
    call timer_stop(s:running_timer_id)lets:running_timer_id=v:null
    lets:running_timer_m=v:null
    lets:running_timer_s=v:null
    echo "Timer was aborted."elsecalls:ErrorMsg("ERROR: No running timer exists.")endifendfunction"現在のタイマーを表示する"@param タイマーIDfunction!s:Notifyer(timer_id)letl:info = timer_info(a:timer_id)letl:rep =l:info[0].repeat
  "残りのリピート回数×1秒が残り時間"※初回は1秒後に呼び出されることに注意letl:min =(l:rep-1)/60letl:sec =(l:rep-1)-l:min*60"タイマーが止まったら、メッセージの色を変え、"ダイアログを出して知らせるif(l:rep-1)==0calls:WarningMsg("[Timer | ".l:min."min ".l:sec."sec]")callconfirm(s:running_timer_m."m ".s:running_timer_s."s have passed.","&OK",1,"Info")"タイマー情報を初期化するlets:running_timer_id=v:null
    lets:running_timer_m=v:null
    lets:running_timer_s=v:null
    "強制的に休憩を挟ませるために、スクリーンセーバーを表示するifg:cmdtimer_show_screensaver&& g:cmdtimer_scrfile_path!=''call system(g:cmdtimer_scrfile_path.' /s')endifelse
    echo "[Timer | ".l:min."min ".l:sec."sec]"endifendfunction"受け取った文字列をエラーメッセージとして出力する"@param エラーメッセージfunction!s:ErrorMsg(msg)
  echohl ErrorMsg
  echo a:msg
  echohl None
endfunction"受け取った文字列を警告メッセージとして出力する"@param 警告メッセージfunction!s:WarningMsg(msg)
  echohl WarningMsg
  echo a:msg
  echohl None
endfunction

例えば、vimrcに

"カウント終了後にスクリーンセーバーを表示するletg:cmdtimer_show_screensaver=v:true
"表示するスクリーンセーバーのパスletg:cmdtimer_scrfile_path='C:\WINDOWS\System32\Ribbons.scr'

などと書くことで、任意のスクリーンセーバーを起動させることができます。

蛇足

実を言うと、昔つくったコマンドラインタイマーに、スクリーンセーバーを表示させる処理を追加しただけです。

ダイアログ表示処理をそのまま残したのは、時間経過に気づかずに、意図しないキー入力でスクリーンセーバーを消してしまう恐れがあるからです。

タイマーIDをわざわざ保持しているのは、IDを指定しないtimer_stopall()を使うと、他のプラグインが起動したタイマーを誤って破棄してしまう恐れがあるからです。


Viewing all articles
Browse latest Browse all 5608

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>