teratermマクロをvimで書くときの設定
シンタックスファイル
補完するほどじゃないと思うけど、色がついてくれることで間違いに気づける。
http://hp.vector.co.jp/authors/VA048353/garage.html
上記のサイトで公開されてるものを使わせてもらう。ただ足りない部分もあるので継ぎ足す。
編集したやつ。
https://gist.github.com/3154584
--- ttl.vim.orig Sat Jul 21 12:22:09 2012 +++ ttl.vim Sat Jul 21 13:29:34 2012 @@ -4,14 +4,21 @@ if version < 600 syntax clear elseif exists("b:current_syntax") - finishendif + finish +endif -syn keyword ttlStatement goto call end include return call execcmnd exit pause +syn keyword ttlStatement goto call end include return call execcmnd exit pause mpause syn keyword ttlRepeat for next while endwhile +syn keyword ttlRepeat do loop break untile enduntil syn keyword ttlConditional if then elseif else endif syn keyword ttlOperator and not or xor -syn keyword ttlArgument inputstr param2 param3 result timeout + +" system variables +syn keyword ttlArgument param1 param2 param3 param4 param5 param6 param7 param8 param9 paramcnt +syn keyword ttlArgument groupmatchstr1 groupmatchstr2 groupmatchstr3 groupmatchstr4 groupmatchstr5 +syn keyword ttlArgument groupmatchstr6 groupmatchstr7 groupmatchstr8 groupmatchstr9 matchstr +syn keyword ttlArgument result timeout mtimeout inputstr syn match ttlOperator "\s[-+\*/%]\s" syn match ttlOperator "=" @@ -19,13 +26,16 @@ syn match ttlString "\"[^"]*\"" syn match ttlString "\'[^']*\'" +syn match ttlString "#1[0-1][0-9]\|#1[2][0-7]\|#[1-9][0-9]\|#[1-9]" +syn match ttlString "#$[0-7]\x" -syn match ttlLabel "^\s*:\s*\h\w*\>" +syn match ttlLabel "^\s*:\s*\h\w*\>" syn match ttlLabel "\<\(goto\|call\)\s\+:\h\w*\>" -syn match ttlLabel "\<goto\s\+\h\w*\>" -syn match ttlLabel ":\h\w*\>" +syn match ttlLabel "\<goto\s\+\h\w*\>" +syn match ttlLabel ":\h\w*\>" -syn match ttlComment "^[ \t]*;.*$" +syn match ttlComment ";.*$" +syn region ttlComment start="/\*" end="\*/" syn keyword ttlImplicit bplusrecv bplussend changedir clearscreen closett syn keyword ttlImplicit connect disconnect enablekeyb flushrecv gettitle @@ -49,6 +59,23 @@ syn keyword ttlImplicit beep closesbox exec getdate getenv gettime inputbox messagebox syn keyword ttlImplicit setdate setdlgpos setexitcode settime show statusbox yesnobox + +" new ttl commands +syn keyword ttlImplicit callmenu cygconnect dispstr gethostname loginfo scprecv scpsend +syn keyword ttlImplicit sendbroadcast sendlnbroadcast sendmulticast setbaud setdebug setdtr +syn keyword ttlImplicit setmulticastname setrts wait4all waitn waitregex ymodemrecv ymodemsend + +syn keyword ttlImplicit expandenv sprintf sprintf2 strinsert strjoin strmatch strremove +syn keyword ttlImplicit strreplace strspecial strsplit strtrim tolower toupper + +syn keyword ttlImplicit basename dirname filelock fileread filestat filetruncate fileunlock +syn keyword ttlImplicit foldercreate folderdelete foldersearch getfileattr setfileattr + +syn keyword ttlImplicit ispassword setpassword + +syn keyword ttlImplicit clipb2var crc32 crc32file filenamebox getspecialfolder getttdir getver +syn keyword ttlImplicit ifdefined intdim random rotateleft rotateright setenv strdim var2clipb + if version >= 508 || !exists("did_ttl_syntax_inits") if version < 508
vimrc
filetypeの設定とか。
autocmd BufWinEnter,BufNewFile *.ttl setlocal filetype=ttl " for NERD_commenter autocmd Filetype ttl setlocal commentstring=;\ %s " for quickrun let g:quickrun_config['ttl'] = {'command': 'ttpmacro' }
サブルーチン
あとは設定ではなくて、teratermマクロを書くときにこうしたよという話。
teratermマクロにはサブルーチンがあるのだけど、引数や戻り値がないので使い勝手が悪い。かといって、まとめられる処理をベタ書きにするのも地獄なので、予め入力と出力用の変数を決めておいて、サブルーチン呼び出し前にそれらを初期化し、サブルーチン内で出力用変数に値を入れるようにすると、まあまあすっきりする。cobolっぽい。プリフィクスにIN_とかOUT_とかつけるルールにするとまあ見やすいかも。cobolぽく。
日付の計算
今のところTTLコマンドには日時に関するものはあまりなくて、一日前の日付なんか取得できない。なので、サーバにログインした後、日付を計算するコマンドを発行してから、その結果を受け取る。具体的には、sendlnでdateコマンドをログイン先のシェルに実行させて、その出力をwaitlnで受け取る。
sendln 'date "%a %Y%m%d" -d "20120721 1 days"' waitln 'invalid' 'Sun' 'Mon' 'Tue' 'Wed' 'Thu' 'Fri' 'Sat' messagebox inputstr 'test'
確認してないけど(!)こんな感じ。dateコマンドのエラーメッセージは環境で変わるだろうし、正常な出力結果として曜日をベタ書きにしてるのが、うわって感じがする。
vimperatorで時計の表示
表示領域を少しでも広く使いたいときに、Windowsではタスクバーを隠して使いたいのだけど、時計は見たい。何故なら時間を気にしながらじゃないと延々とインターネットしてしまう。だからvimperatorに時計を表示させたい。そんなときはclock.jsと思ってロードすると、
clock.js: not found the commandline.
なんてエラーメッセージが出る。もともとclock.jsはコマンドラインの右端に時計を出すプラグインのようで、今のvimperatorはコマンドライン(のバー)がないよってことなのかな。vimperatorのxulをぼんやり眺めると、下に表示されてるバー(vimのステータスラインぽいもの)がbottombarというものかな、多分そんな気がする。そこに時計が出ればな。windowsのタスクバーは不要になるのにな。clock.jsを無理やり動かすしかないな。
ブラウザのコンポーネントいじるjsってよく分かってないので、試しにいじったら動いたというレベル。localNameがstackじゃないとどういう事態なのとか、全く分かってない。
diff --git a/clock.js b/clock.js index 2897a01..baafaa8 100644 --- a/clock.js +++ b/clock.js @@ -337,9 +337,7 @@ function year() { // node control function getCommandlineStack() { - let messageTextarea = window.document.getElementById('liberator-message'); - let commandlineStack = messageTextarea.parentNode; - return commandlineStack.localName === 'stack' ? commandlineStack : null; + return window.document.getElementById('liberator-bottombar'); } } )();
.vimrcに最近追加したもの
自動で構文チェック
rubyとphpで書く用。保存時にシンタックスチェックが走って、エラーがあればQuickFixが開く。直れば閉じる。
phpに関しては、vimインストール時に同梱されてるコンパイラプラグインだと僕の環境に合ってなくて、makeprgに解釈できないオプションが付いてて実行時に固まってしまったり、errorformatが上手くマッチしなかったりする。かといってインストールされたものを修正するよりかは自前のvimrcで整えたい。
phpのerrorformatはwindowsのxammpのもので確認しながら書いた。手探りで書いたのであまりよく分かってない。
augroup My autocmd! autocmd FileType ruby setlocal makeprg=ruby\ -cw\ % autocmd FileType php setlocal makeprg=php\ -l\ % autocmd FileType php setlocal errorformat=%-E,%m\ in\ %f\ on\ line\ %l,%ZErrors\ parsing\ %f autocmd BufWritePost *.php,*.rb silent make autocmd QuickFixCmdPost make cw 3 augroup END
tagsの設定
tagsオプションの末尾に;をつけておくと、ディレクトリを遡ってtagsファイルを探しに行ってくれる。
if has('path_extra') set tags+=.tags; endif
tagsファイルを生成する場所
生成する場所について、ネットを見回してもこうしてますといった話がない。ctagsコマンドの説明の上で、こうすればカレントディレクトリにtagsファイルができますといった程度で、そんなことしてたらあらゆる場所にtagsファイルが散乱するじゃないか。そういうものなの? それはそれとして、僕はプロジェクトルートとなる場所に一つだけできて欲しい。カレントディレクトリはバッファの場所になるよう設定してるし、どうしようかな…と考えた結果、自分の場合は.git/がある場所に決め打ちすることにした。
ファイル保存時にctagsコマンドが走るようにしたんだけど、今のところ100行前後の小さいものでしか動作させてないので、まともなプロジェクトで走らせたら重くてしょうがなくなるかもしれない。
augroup Ctags autocmd! autocmd BufWritePost *.vim,*.php,*.rb silent call s:ctags() autocmd BufWinEnter .tags setlocal filetype=tags augroup END function! s:ctags() let l:project_root = s:search_dir('./') if exists('l:project_root') call system("cd ". shellescape(l:project_root) . \" && ctags -R " . " -f " . shellescape(l:project_root . ".tags")) endif endfunction function! s:search_dir(dir) if !has('file_in_path') return endif let l:save_path = &path if &path[-1:-1] != ';' set path+=; endif let l:dir = finddir(a:dir) if l:dir =~ a:dir . '$' let l:dir = substitute(l:dir, a:dir . '$', '', '') endif let &path = l:save_path return l:dir endfunction
gvimrc_local.vim
KaoriYa版を使わせてもらってるんだけど、今まではインストール時に同梱されてるgvimrcに直接手を入れて使ってた。gvimrc_local.vimがgvimrcに先立ってロードされて、さらに下記の設定しておくとgvimrc読み込みを抑止するんですね、ということを知ったので、gvimrc_local.vimには必要な気がするものだけgvimrcからコピペして使ってる。gvimrcにちゃんと書いてあるのにね…。vimrc_local.vimについても同様にした。
" $VIM/gvimrcで設定を上書きしない let g:gvimrc_local_finish = 1
■
初めて自分でvim script書いた。
職場で日次でファイルを作成してメモを取ることをしていて、毎朝yyyymmdd.txtを作るバッチを叩いている。具体的な手順は、vimでバッチを開いて、quickrunさせて、結果とバッチの2つのバッファを閉じて、生成したメモ用ファイルを開く。面倒くさい。キーストロークふたつくらいでできたい。
function! s:OpenTodayLog() let l:dir = expand('~/log') if !isdirectory(l:dir) call mkdir(l:dir) endif execute ':edit ' . l:dir . '/' . strftime('%Y%m%d') . '.txt' endfunction command! -nargs=0 TodayLog call s:OpenTodayLog() nnoremap <Leader>l :TodayLog<CR>
初めてちゃんとvim scriptを書いた。コマンド定義してからキーマッピングしてるのが冗長で、本当はキーマッピングに直接関数呼び出しを指定できたらいいんだけど、SIDがないとか、それはスクリプトローカルな関数だからとか、もうちょっとどうすべきかヘルプ読んで決めなくちゃと思う。特にSIDがよくわからない。
なんとなく.vimrc読み返してたら、殆ど同じ記述があって驚いた。
http://vim-users.jp/2010/11/hack181/
上記サイトの:JunkFileコマンドを、そのままコピペして使ってなかったものだった。あー車輪再発明した、けれども、おっかなびっくり書いた自分のスクリプトが間違った書き方ではない(小物スクリプトではあるものの)と思って安心はした。
追記
コメントをもらって、キーマップから関数呼び出しの書き方を教わったので.vimrcをそのように直した。
動きを確認してからヘルプを読んだら、最初に読んだときに分からなかったことが少し分かった気がする。SIDはmapコマンドの変換処理を挟んで、スクリプトローカルなスコープを解決する修飾子みたいなものになると理解しました。
# 英語を読むときも、ある程度あたりがついてないと読めないなあ。
SQL ゼロからはじめるデータベース操作を読んだ
CD付 SQL ゼロからはじめるデータベース操作 (プログラミング学習シリーズ)
- 作者: ミック
- 出版社/メーカー: 翔泳社
- 発売日: 2010/06/29
- メディア: 大型本
- 購入: 39人 クリック: 484回
- この商品を含むブログ (15件) を見る
以下、改めて知ったことや良かったこと。
- つまづきやすいところが書かれてある
- WHERE句に取れる式の制限とか
- 書ける場所、書けない場所を教えてくれている
- 句の実行順序
- 上ふたつのことも、実行順序が分かっていればだいたい理屈で納得できる
- 主要なDBMSでの記法をサポートしてる
- SQL標準で書くことを推奨してる
- 例えば僕はテーブル結合でjoin句を使ってなかった
- そもそも何がSQL標準か、何がそうでないかを知らなかった
- ところどころで中級への道を示している
- EXISTS述語とIN述語の違い
- 関係除算
- NOT IN述語にNULLを取ったときの動作
これを書いてる途中でおさらいをしたんだけど、相関サブクエリの動作イメージが分かった。気がする。SQLの実行順は内側から、つまりサブクエリから展開されていくというのに捕らわれていて、相関サブクエリ内のバインドの部分を解釈できないでいた。サブクエリ単体で見ると、バインドの値が未定で表が出来上がらないから。じゃあ逆にと思って外側からレコード一行ずつ見ていくと、バインドする値は当然決まるし、そうなると相関サブクエリが返す値はひとつに絞られてWHERE句に収まることができる。すっきりした。
やっぱり分からないのは関係除算で例に出てたSQL。EXISTSと相関サブクエリの関係をよくわかってることが前提なのかな。EXCEPTで差集合を取ってるのだけど、引く側が引かれる側を内包してる(と思う)ので空集合になるのではないか、とかよく分からない。今後の課題。
■
ubuntu 10.04をインストールした。DELLのLatitude D400に。一度無邪気に9.04からアップグレードさせたら起動画面から真っ黒になって動かなくなって悲しい思いをしたので、以来慎重になっていたのだけど、LPIに受かったので腕試しのつもりでやってみた。とはいえハードウェアのことは全然分からない。検索してみて、対策とされているものを調べながらひとつずつlive cdでオプションを試していく。
ここに辿り着くまでに、他所のサイトで見たオプションを幾つか試した。
quiet splashを外す
起動時のカーネルメッセージを画面に出力してくれるようになった。全部の意味は分からないけど、何の処理らへんでつまってるか分かるかも。
xforcevesa
ドライバをvesaというものに変えるオプション。これをつけるとテキストモードでは起動するまでには至った。startxを打つとエラーが出て終わる。
LPI対策
LPIのレベル1に合格しました。Linuxには多少慣れていたので苦労しなかったのですが、受験料が安くないので失敗はできません。どう勉強したかというのを少し書きます。
試験は結局暗記であるので、効率よく記憶するには手を動かす必要がある。自分の環境を作ってそのなかで遊ぶために、仮想環境の構築をしました。重いソフトウェアは嫌なので、coLinuxを選びました。(普段使ってるOSはWindowsです。)またパッケージ管理の問いでdebian系とRedHat系の二通りあるので、debianとfedoraを選びました。これらのOSにはTeraTermProで接続します。Windowsのコンソールより使いやすいし、さらにGnu screenを使えばひとつのウィンドウで済むのでAlt+tabでガチャガチャアプリケーションを探さなくて済みます。sshの勉強にもなる。
まとめ