1 名前:名無しさん@お腹いっぱい。 [01/12/17 12:15] みんなでスクリプトを覚えよう
70 名前:1 mailto:sage [01/12/31 23:07] >>69 殺伐としてましたねぇ。んで突然「水きぼーん」の声。もうワライ堪えるのが大変。 詳しくはこちら↓今見たら、なんか元旦もやるとかいってるし(w 大晦日は殺伐と吉野家へ(集合)その7 corn.2ch.net/test/read.cgi/entrance/1009805196/ >>68 OSには依存しないから大丈夫。 Winで覚えたことはLinuxになってもそのまま活かせるし。
71 名前:名無しさん@お腹いっぱい。 [01/12/31 23:11] なにやら新ルール { つゆだくを頼むヤツがいたら鼻で笑ってやってください 牛鮭定食を頼むヤツがいたら舌打ちしてやってください }とさ
72 名前:1 [02/01/01 22:28] 今日も吉野家逝ってきた。あえて牛鮭頼んだら 隣の奴がブチ切れだったららしい(w というわけで<args>と<q-args>の違いの確かめる。 command! -nargs=* Test1 echo <args> command! -nargs=* Test2 echo <q-args> command! で Test1 と Test2 のコマンドを定義。 -nargs=* は引数を0個以上取る :Test1 "Hello" Hello :Test2 "Hello" "Hello" <q-args>は " をクォートしてくれていると。 そんだけ。 明日から牛の鳴き声が聞こえるような所に帰省します、、、。
73 名前:1 mailto:sage [02/01/01 22:32] なんか誤字が多いなー、牛乳飲も。
74 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/03 01:02] システム関数とファイル操作関数: browse() put up a file requester(GUI バージョン使ってないから分からん) glob() ワイルドカードの展開 globpath() 指定されたパス内で glob resolve() ショートカット先を探す(MS-Win) fnamemodify() ファイル名変更 executable() 実行可能プログラムがあるかどうか調べる filereadable() ファイルが読み込み可能かどうか調べる isdirectory() ディレクトリがあるかどうか調べる getcwd() カレントディレクトリを得る getfsize() ファイルサイズを得る getftime() ファイルの最終更新時を得る localtime() 現在時刻を得る strftime() 時間を文字列に変換 tempname() テンポラリファイル名を得る delete() ファイル削除 rename() ファイルリネーム system() シェルコマンドの実行結果を得る hostname() システムのホスト名を得る バッファ,ウィンドウ,引数リスト: argc() 引数リストの引数の数 argidx() 引数リストでの現在位置 argv() 引数リストから一つの要素を得る bufexists() バッファが存在するかどうかを調べる buflisted() バッファがバッファリストに存在するかどうかを調べる bufloaded() バッファがロードされているかどうかを調べる bufname() バッファ名を得る bufnr() バッファナンバーを得る winnr() カレントウィンドウのバッファナンバーを得る bufwinnr() バッファのウィンドウナンバーを得る winbufnr() ウィンドウのバッファナンバーを得る getbufvar() バッファの変数を得る setbufvar() バッファの変数を設定する getwinvar() ウィンドウの変数を得る setwinvar() ウィンドウの変数を設定する
75 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/03 01:03] なんか訳しててあんま楽しくない個所なんで今日はここまで(苦笑)
76 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/03 02:00] 陰ながら応援してますよ、がんばってください。
77 名前:KoRoN@Vim%Chalice ◆ALICEsdk [02/01/03 10:39] >>75 eval.txtの翻訳の時、同じ気持ちになった(苦笑)
78 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/03 23:31] Folding: foldclosed() ある行のfoldが閉じているかどうかを調べる foldlevel() ある行のfoldの深さを調べる foldtext() 閉じている fold を表示する行の生成 シンタクスハイライティング: hlexists() ハイライトのグループがあるかどうかを調べる hlID() ハイライトのグループのIDを得る synID() ある位置における syntax ID を得る synIDattr() syntax ID の特定の属性を得る synIDtrans() translated syntax ID を得る 履歴: histadd() 履歴に要素を追加 histdel() 履歴から要素を削除 histget() 履歴から要素を得る histnr() 履歴の現在のインデックスを得る 対話: confirm() 選択肢の表示 getchar() ユーザからの入力(文字)を得る getcharmod() 最後に入力された文字のモディファイア(CtrlとかShiftとか)を得る input() ユーザからの入力(行)を得る inputsecret() ユーザからの入力(行)を得る(表示はしない) inputdialog() ユーザからの入力(行)を得る(ダイアログで) Vim サーバ: serverlist() サーバ名のリストを得る remote_send() コマンド文字列を Vim サーバに送信 remote_expr() Vim サーバで式を評価 server2client() クライアントに返信 remote_peek() Vim サーバからの返答があるかどうかを調べる remote_read() Vim サーバからの返答を読み込む foreground() Vim のウィンドウを全面へ移動 remote_foreground() Vim サーバのウィンドウを全面へ移動 Various: mode() 現在の編集モードを得る visualmode() 最後に使われたビジュアルモード("v" or "V" or "C-V") hasmapto() map が存在するかどうかを調べる mapcheck() マッチする map が存在するかどうかを調べる maparg() マッピングの実体(rhs)を得る exists() 変数,関数等が存在するかどうかを調べる has() vim が機能を備えているかどうかを調べる cscope_connection() cscope のコネクションがあるかどうか調べる did_filetype() check if a FileType autocommand was used eventhandler() イベントハンドラによって起動されたのかどうかを調べる getwinposx() GUI Vim ウィンドウの X 位置を得る getwinposy() GUI Vim ウィンドウの Y 位置を得る winheight() ウィンドウの高さを得る winwidth() ウィンドウの幅を得る libcall() 外部ライブラリの関数呼び出し(戻り値が文字列) libcallnr() 外部ライブラリの関数呼び出し(戻り値が整数値)
79 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/03 23:32] やっとツマランところ終了. KoRoN 殿のような方々の辛さを実感(苦笑)
80 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:sage [02/01/03 23:49] >>79 お疲れさん!!
81 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/05 22:00] 現在行から一番近い上か下のマークへジャンプするスクリプトを作ってみました。 皆様のおかげです。厨房くさいスクリプトですが思い切って、投稿してみます。 まずいとことかあったら教えてください。 行単位でしか見てないので、一行に複数のマークがあっても無視してます。 "マークにジャンプする function! JumpToMark(mode) let i = 0x61 if a:mode == "up" let s:LineNo = 0 endif if a:mode == "down" let s:LineNo = line("$") + 1 endif let s:LineNoOrg = line(".") let s:MarkChar = "" "a-z をチェック while i < 0x7b let s:x = line("'" . nr2char(i)) if (a:mode == "up" && s:LineNoOrg > s:x && s:LineNo < s:x) || (a:mode == "down" && s:LineNoOrg < s:x && s:LineNo > s:x) let s:MarkChar = nr2char(i) let s:LineNo = s:x endif let i = i + 1 endwhile if (a:mode == "up" && s:LineNo > 0) || (a:mode == "down" && s:LineNo < line("$") + 1) "移動 execute "normal `" . s:MarkChar echo "マーク" s:MarkChar "にジャンプ" else execute "echohl ErrorMsg" echo "該当するマークがない;;" echohl None endif endfunction ■使い方 "上のマークへ :call JumpToMark('up') "下のマークへ :call JumpToMark('down') なぜか画面のスクロールを伴うマークへのジャンプをした後の echo で出力した メッセージが表示されません(表示されて消える?) スクロールされた後でもメッセージが表示できるようにする方法はあるんでしょうか? win2000 のgvim 6.0 です。
82 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/06 00:45] 折角公開してくれたのだから少し細かくコメントしましょう。こういうのは全く無反 応だと公開した方・使っている方、両方にとってためになりませんからね。 > function! JumpToMark(mode) s:を使ってスクリプトファイルローカルに宣言しませう。 で、command SomeCmd call <SID>JumpToMark()な感じで呼び出すようにする。 > let i = 0x61 let i = char2nr('a')とかのほうが意味合いがしっかりする。 もしくはlet markchar = "abc...xyz"としてmarkchar[i]でアクセスするように。 後者のほうが移植性に富むからベター。 > if a:mode == "up" 演算子==は'ignorecase'の影響を受けるので==#とか==?とかも考慮する。 > let s:LineNo = 0 関数内のletは関数にローカルな変数になるので特に必要性がないのならs:は使わな い。(以下全変数同様) > endif > (中略) > if (a:mode == "up" && s:LineNoOrg > s:x && s:LineNo < s:x) || (a:mode == "down" && s:LineNoOrg < s:x && s:LineNo > s:x) この判定ロジック、もうちょっと工夫のしようがないかしら?。 同じような文字列の比較が何度も出てくる場合は簡潔に書き直せることが多い。 > let s:MarkChar = nr2char(i) > (中略) > execute "echohl ErrorMsg" なんでここexecuteしてるの?。生で実行できる。 > echo "該当するマークがない;;" > (中略) > :call JumpToMark('up') 前述のとおりcommandでコマンド定義するかmapすべし。 > なぜか画面のスクロールを伴うマークへのジャンプをした後の echo で出力した > メッセージが表示されません(表示されて消える?) マークでジャンプした後にredraw!で強制的に更新バッファをflushしませう。 Chaliceの中では多用しているテクニックです。 私からはこんなところです。
83 名前:81 mailto:sage [02/01/06 03:07] KoRoNさんにこんなに詳細にコメントを頂けるなんて感激です。 ありがとうございます。 このスレでvimスクリプト入門を果たしたので知らないことばかりですが これからも精進したいです。 修正したものを貼り付けます。 # マーク位置を判定 の部分は私の能力では簡潔に書き直せなかった;; "マークにジャンプする function! s:JumpToMark(mode) let markchars = "abcdefghijklmnopqrstuvwxyz" if a:mode ==? "up" let LineNo = 0 endif if a:mode ==? "down" let LineNo = line("$") + 1 endif let LineNoOrg = line(".") let MarkChar = "" let i = 0 "a-z をチェック while i <= (char2nr('z') - char2nr('a')) let x = line("'" . markchars[i]) "マーク位置を判定 if (a:mode ==? "up" && LineNoOrg > x && LineNo < x) || (a:mode ==? "down" && LineNoOrg < x && LineNo > x) let MarkChar = markchars[i] let LineNo = x endif let i = i + 1 endwhile if MarkChar != "" "移動 execute "normal `" . MarkChar redraw! echo "マーク" MarkChar "にジャンプ" else echohl ErrorMsg echo "該当するマークがない;;" echohl None endif endfunction "コマンド定義 command! JumpToMarkDown call <SID>JumpToMark('down') command! JumpToMarkUp call <SID>JumpToMark('up')
84 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/06 04:05] >>83 ナイスですねぇ。 > while i <= (char2nr('z') - char2nr('a')) ここだけwhile i < strlen(markchars)としたほうが良いでしょう。 私は変数名を大文字で始めるのは避けるようにしています。ユーザ定義コマンドや関 数名は大文字で始めなければなりませんよね。それとかぶって見づらいかなと思うわ けです。スタイルの問題なのですぐ宗教論争になってしまいますが一応参考意見とし て。
85 名前:81 mailto:sage [02/01/06 21:10] >>KoRoNさん > 私は変数名を大文字で始めるのは避けるようにしています。 確かにです。私もそうしたいと思います。 ほんとにありがとうございました。 これから vim online に逝ってきます。
86 名前:1 [02/01/06 21:42] >>81-84 うーん、いろいろ勉強になりますなー。 <SID>はスクリプトローカル関数を呼ぶ時の為のものだったのか、、、 で、引き続き foo.vim の解読。 2〜4行目のfooをbarに置換するには、 :2,4 s/foo/bar/g と書くけど 2 と 4 が変数a,bの場合、 :a,b s/foo/bar/g と書いてしまうと正常に動作しない。 それに対応するのが次のスクリプト。 command! -nargs=* Line \ | let Line_range = matchstr(<q-args>, '\S\+') \ | let Line_range = "(" . substitute(Line_range, ",", ").','.(", "") . ")" \ | execute "let Line_range = " . Line_range \ | execute Line_range . substitute(<q-args>, '\S\+', "", "") \ | unlet Line_range 使い方。 :let a=2 :let b=4 :Line a,b s/foo/bar/g あと範囲指定部分で演算が可能。 :Line a-1,b+1 s/foo/bar/g スクリプト解読。 -nargs=* は引数を0個以上取る。 行をまたいで定義するには \ で繋ぐ。 <q-args>は引数を一つの文字列として参照する "a,b s/foo/bar/g" \S\+ は1個以上の空白以外で matchstr は最初のにヒットするから、 matchstr("a,b s/foo/bar/g", '\S\+') は "a,b" がヒットする。 んで、ごちゃごちゃしているけど Line_range="(a).','.(b)" となって、次がポイント。 Line_range が execute で評価されて結果 "2,4" が Line_range に入る。 ちなみに let Line_range = execute(Line_range) などとは書けそうで書けない。 で、substitute(<q-args>, '\S\+', "", "") は a,b の部分を消して " s/foo/bar/g" が残る。 二つを連結して execute "2,4 s/foo/bar/g" が実行されると。
87 名前:1 [02/01/08 00:32] 逆転裁判(GBA)をやっとクリアした今日この頃。 じゃ、foo.vim解読の続き。 >>86 の別のやり方。 command! -nargs=* Range \ | execute substitute(<q-args>, '\(\S\+\)\s\+\(\S\+\)\(.*\)', \ 'let Range_range=\1.",".\2', "") \ | execute Range_range . substitute(<q-args>, '\S\+\s\+\S\+', "", "") \ | unlet Range_range a〜b行目を置換するには? :let a = 2 :let b = 4 :Range a b s/foo/bar/g ごちゃごちゃしている正規表現もよく見れば簡単。 \s は空白。\S は空白以外。+は前の文字が1個以上。 ()で囲ったのは置換文字列内で順に \1 \2 とかで参照出来る。 + と () には \ を付ける。 んで、let Range_range=a.",".b が実行されて変数が数値に展開されて、 execute "2,4" . " s/foo/bar/g" となると。
88 名前:1 [02/01/08 23:17] 可変長引数の参照方法。 fun! Foo(...) echo a:0 a:1 a:2 endfun :call Foo("A","B") 2 A B なんとも奇妙な感じがするけど、 a:1 から順に引数が入ってて a:0 に引数の数が入っていると。 ちなみに :call Foo("A") だと a:2 が参照出来ないのでエラーになった。
89 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/08 23:27] 初めて見てみたけどわけわかんないっす。 「じゃあ来るな」はナシよ。
90 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/08 23:30] >>89 馴れろ
91 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/08 23:56] >>88 変数の有無のチェックにexists()を使う方法もあります。 >>89 確かにVimとは、Vimスクリプトとはなんぞや、 とかいうリンクは出てなかったかもしれませんね。 まとめてくれると嬉しいかも。
92 名前:1 mailto:sage [02/01/09 01:41] >>89 漏れもわけわからんで(w ま、とりあえず>>2 からやってみよう。 踏み出せばその一足が道となり・・・(略 >>91 ナルホド。a:0 >= 2 と書くより、場合によっては 読み易さを考慮(?)して exists("a:2") と書く方法もありと。
93 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/09 02:04] コメントの書き方って説明がまだ出てきてないみたいなんですけど " で始まる行がそうなんでしょうか?
94 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/09 11:06] >>93 お察しのとおりです。
95 名前:68 mailto:sage [02/01/09 18:41] >>68 です。 やっとhjklに拒絶反応が出なくなりました。先は、、長いですね、、(●´ω`●)
96 名前:名無しさん@お腹いっぱい。 [02/01/09 22:17] 勉強age
97 名前:1 [02/01/10 01:05] foo.vim解読の続き。 カーソル位置移動と画面上の表示開始行をセットする コマンド文字列を取得するスクリプト。 ma 〜 `a に似てるけどちょっと違う。 fun! Mark(...) if a:0 == 0 let mark = line(".") . "G" . virtcol(".") . "|" normal! H let mark = "normal!" . line(".") . "Gzt" . mark execute mark return mark elseif a:0 == 1 return "normal!" . a:1 . "G1|" else return "normal!" . a:1 . "G" . a:2 . "|" endif endfun line('.')はカーソル行。virtcol('.')はカーソル桁。 G は指定行移動。| は指定桁移動。 引数なしで呼んでみると、 :echo Mark() normal!20Gzt30G8| このコマンド文字列を変数に保存しといて後で実行させれば元の位置に戻るという仕組みか。 20G は20行目にジャンプ。zt はその行を画面上での先頭に移動。 これで画面上での表示開始行がセットされる。 30G8| は 30行 8桁目に移動と。 引数1つの場合は指定された行番号でコマンド文字列を作る。 :echo Mark(100) normal!100G1| 引数2つの場合は指定された行と桁でコマンド文字列を作ると。 :echo Mark(100,30) normal!100G30| 実際に使う場合こんな感じ。 :let a = Mark() :exe a
98 名前:名無しさん@お腹いっぱい。 mailto:age [02/01/11 00:11] age
99 名前:1 [02/01/11 00:40] Mark() の続きで取得したコマンド文字列から、 行または桁を取り出すスクリプトの解読。 " 行取得 fun! Line(mark) if a:mark =~ '\dG\d\+|$' return substitute(a:mark, '.\{-}\(\d\+\)G\d\+|$', '\1', "") else return line(a:mark) endif endfun " 桁取得 fun! Virtcol(mark) if a:mark =~ '\d\+G\d\+|$' return substitute(a:mark, '.*G\(\d\+\)|$', '\1', "") else return col(a:mark) endif endfun 引数が 数字G数字| というフォーマットなら、、 Mark() で作ったコマンド文字列と見なして、 それ以外なら通常の関数に引数を渡す仕組み。 正規表現の初めて見る \{-} は最短一致する * らしい。 けど、どうして * を使うとまずかったのか、などということは深く考えない。 実際に試してみると、 :echo Line("normal!10Gzt20G30|") Virtcol("normal!10Gzt20G30|") 20 30 line() または col() としても機能する。 :echo Line(".") Virtcol(".") 31 23 ん?なんで Virtcol() のなかで呼ばれているのが、 virtcol() じゃなくて col() なんだろ? ま、いいか。
100 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/11 13:49] 「100ゲット!!」 だけじゃあんまりだから、ちょっとマメ知識を。 vimスクリプトで1行が長くなってしまった時に、改行を入れて先頭を \ にすると次 行に繋がっていると見なされる。C言語の行末の \ と一緒。 # なおvimスクリプトでは \ の直前の空白は無視されるのでインデント可能 ここまでは一般常識。ここからが本題。実は'cpoptions'に"C"フラグが含まれていな い時には、この \ が使えずエラーとなる。なので一般に公開したいスクリプトを書 くときには \ による行連結は使わないほうが良いかも。 # それともスクリプトごとに避ける設定があるのかしら?
101 名前:1 [02/01/12 02:24] foo.vim解読の為の予習。 偶然Vim6スレでも話題になっている行範囲を、 関数側で受け取るテスト。 関数名定義の最後に range と書くだけで行範囲を、 a:firstline と a:lastline で参照出来るようになるらしい。 さっそく受け取った範囲を表示する関数を作ってみる。 fun! RangeCheck() range echo a:firstline a:lastline endfun そのままつかうと現在の行だけが対象 :call RangeCheck() 10 10 範囲指定すると、ちゃんと範囲が受けとれている :3,7call RangeCheck() 3 7 全体行でも大丈夫。% は 1,$ と同等 :%call RangeCheck() 1 10 >>100 どもっ、でもなぜかCフラグが無いのに、 \が使えたので調べてたらCフラグの意味が逆?? それにしても options.txt すんげぇサイズ。 翻訳してくれてる人、大変だろうなぁ。
102 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/12 03:16] >>101 あ、逆でした。>>100 は'cpoptions'に"C"が含まれる時には行頭の \ が連結の意味に ならない、といので正しいです。
103 名前:mattn@Vim%Chalice mailto:sage [02/01/12 19:32] >>74 > resolve() ショートカット先を探す(MS-Win) あれ〜・・・ bram氏、docの変更忘れてんのかなぁ・・・(^^;) unix系はシンボリックリンクを解析するよう変更したはずのに・・・ と言っても訳は間違ってないのでsage
104 名前:1 [02/01/12 23:16] foo.vim解読の続き。 現在の文書から引数で指定した単語を最後の行に出力するスクリプト。 :%call Pippo('\\\a\+') とやって LaTex での辞書を作る為の単語を収集するのに使うらしい。 (LaTex使ったこと無いからよくわからんけど) fun! Pippo(...) range if a:0 let pat = a:1 else let pat = '\<pippo\d\+\>' endif let bot = line("$") execute a:firstline . "," . a:lastline . 'g/' . pat . '/copy $' if bot == line("$") return endif execute (bot+1) . ',$s/' . pat . '/&\r/ge' execute (bot+1) . ',$v/' . pat . '/d' execute (bot+1) . ',$s/.\{-}\(' . pat . '\)$/\1/e' endfun 選択したテキストがこれ。先頭のは :set nu で表示した行番号。 10 pippo1 aaa pippo2 bbb 11 pippo3 12 ccc そこで :10,12call Pippo() を実行すると :10,12g/\<pippo\d\+\>/copy $ が呼ばれ て、10〜12行目でpippoの後に数値がある単語が含まれる行を最後の行にコピーすると いう意味だから、最後の行が50だとこうなる。 50 51 pippo1 aaa pippo2 bbb 52 pippo3 copy はノーマルコマンドの p 同じような機能らしいから次行からペーストされる。 :51.$s/\<pippo\d\+\>/&\r/ge が実行される。& は検索文字列。\r は改行だから検索 文字列の直後に改行入る。 51 pippo1 52 aaa pippo2 53 bbb 54 pippo3 次に :51,$v/\<pippo\d\+\>/d の実行。v は検索されなかった行を返す。d は :delete の事だから、 51 pippo1 52 aaa pippo2 53 pippo3 次に :51,$s/.\{-}\(\<pippo\d\+\>\)$/\1/e は pippo数値 の単語だけを残すから、 51 pippo1 52 pippo2 53 pippo3 になると。ふぅ勉強になった。
105 名前:1 mailto:sage [02/01/12 23:29] copy 命令に感動したのでちょっと練習。 ■20〜30行目を100行目にコピーするには? :20,30copy 100 ■カレント行を2重化するには?(:normal Yp と同じ) :copy . ■全体行をを2重化するには? :%copy $ ■上の3つを短く書くと? :20,30co100 :co. :%co$ copy の仲間で move というのもあってこれがまた凄い。 コピーじゃなくて移動しちまう。 ■20〜30行目を100行目に移動するには? :20,30move 100 そんなところ。
106 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/13 01:45] This script is intended to provide an easy and quick way of sending e-mail messages from within vim vim.sourceforge.net/scripts/script.php?script_id=179
107 名前:名無しさん@お腹いっぱい。 mailto:age [02/01/13 02:11] age
108 名前:1 [02/01/13 23:28] >>106 のViMail.vimを使ってみようとしたけど、 sendmail使っててCygwinだと無くて動かないようだから 練習でblatjに変えてみた。 BlatJ www.piedey.co.jp/softs/blat182bj7.html 103,106c103,107 < let s:cmd = "cat " . s:tempfile < let s:cmd = s:cmd . "\| sendmail -- " . s:to . " 2>&1" < let s:error = system(s:cmd) < --- > let smtp_server = 'xxxx' " SMTPサーバー名を指定 > let mail_address = substitute(s:sender, '.*<\(.*\)>.*', '\1', '') > call system('blatj -install ' . smtp_server . ' ' . mail_address) > let s:error = system('blatj ' . s:tempfile . ' -t ' . s:to . ' -s ' . s:subject . ' -q') > 123a125 >
109 名前:1 [02/01/14 00:31] foo.vim解読の続き。 ALT+4 で行の最後の空白以外にカーソルを移動する方法 :map <M-4> 0:let@9=@/<Bar>set nohls<CR>/.*\S/e<CR>:let @/=@9<Bar>set hls<CR> 読みにくいのでバラしてみると下のようになる 0 :let @9=@/ :set nohls /.*\S/e :let @/=@9 :set hls 0 は行頭に移動。:let @9=@/ 〜 :let @/=@9 はレジスタ / を 9 に保存して復帰。 :set nohls 〜 :set hls は検索文字列ハイライトを一時的に無効化。 で残ったのが /.*\S/e でこれが最後の空白以外に飛ぶ処理をやっていると。 ちなみに /e をつけないとなぜか次の行にカーソルが飛ぶ。
110 名前:1 [02/01/14 21:56] foo.vim解読続き。 >>109 の別の方法 map <M-4> :call LastNonBlank()<CR> fun! LastNonBlank() let i = matchend(getline("."), '.*\S')-1 if i > 0 execute "normal!0" . i . "l" elseif i == 0 execute "normal!0" endif endfun 現在行で .*\S で最後にヒットする位置を取得して最初に 0 で行頭に移動してからそ の位置へ l で移動する。最初に 0 しないで | で直接指定カラムに飛べば if else は 必要無くなるような気がする。
111 名前:1 [02/01/15 23:22] foo.vim解読の続き。 ちなみにfoo.vimとはこれのことです。 vim.sourceforge.net/scripts/script.php?script_id=72 キーワードからパターンを剥いでタグにジャンプするスクリプト 例えば、 nmap <C-]> :call StripTag("Hello")<CR> と定義しておくと HelloWorld という単語の上で C-] した時、HelloWorld の Hello の部分が削除されて残った World でタグジャンプしてくれる! ・・・これがどんな時に役に立つのかよくわからないけど。 nmap <C-]> :call StripTag("xxx")<CR> fun! StripTag(pattern) let keyword = expand("<cword>") if keyword =~ '^' . a:pattern execute "tag!" . substitute(keyword, a:pattern, "", "") else execute "normal! \<C-]>" end endfun expand("<cword>") はカーソル位置の単語(キーワード)を返す。 指定パターンがキーワードの先頭からヒットしたらヒットした部分を消してタグジャンプ。 autowrite オプションを有効にしておくと tag 実行時に自動的にカレントのファイル が保存されるけど、tag! にすると保存されない。 パターンがヒットしなかったら通常の <C-]> を呼ぶと。
112 名前:1 [02/01/17 08:28] foo.vimの続き 拡張子が jsp のファイルを編集中 <scr と入力した瞬間に、 <script language="JavaScript"> function foo() { alert("Hello, world."); } </script> ↑ここまでふくれあがるスクリプト。 augroup Foo autocmd BufEnter *.jsp imap r r<Esc>:call JS_template()<CR>a autocmd BufLeave *.jsp iunmap r augroup END fun! JS_template() if getline(".") !~ '<scr$' return endif s/scr$/script language="JavaScript">/ append function foo() { alert("Hello, world."); } </script> . endfun>>61 にも登場した書き方で、*.jsp のバッファに入った時に、r を再定義してバッファ から抜けたら解除。Ver6.0からはバッファローカルで設定出来るからいちいち入った 時、出たときって書かなくてよいらしい(>>63 より) append は次の行から . だけを含んだ行の前までを入力する。 これはCのコメント生成とかにも使えるかな。
113 名前:1 [02/01/17 22:45] foo.vim続き。 C++ソースで << を次の行に続けて書いてると、 cout << "Hello" << "World" << endl; こんな風に << のカラムを一つ上の行に合わせて、 自動的にそろえていってくれるスクリプト。 augroup Foo autocmd BufEnter *.cpp imap < <<C-O>:call LineUpLT()<CR> autocmd BufLeave *.cpp iunmap < augroup END fun! LineUpLT() " 1行目や、<< だけを入力してない行ならなんもせん if line(".") == 1 || getline(".") !~ '^\s*<<$' return endif " 一つ上の行を取得して << が始まる位置を取得 let newline = getline(line(".")-1) let col = match(newline, "<<") if col != -1 " 上の行に << があったら << が始まる前までを取得して、全てスペースに置換し " て << を付け加える。 let newline = strpart(newline, 0, col) let newline = substitute(newline, '\S', " ", "g") . "<<" " それをカレント行にセットしてカーソルを最後に移動 call setline(line("."), newline) normal!$ endif endfun
114 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/17 23:26] まっつんさんのcalender.vim、次のように設定すると日本語暦。 vim.sourceforge.net/scripts/script.php?script_id=52 let g:calendar_mruler = '睦月,如月,弥生,卯月,皐月,水無月,文月,葉月,長月,神無月,霜月,師走' let g:calendar_wruler = '日 月 火 水 木 金 土' これに加えて「平成14年」とか「皇紀2662年」 とかいう表記ができたらまさにパーフェクト(苦笑)
115 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/17 23:54] それだったら縦書きとか るせま読に左らか右 とかも出来るようにしないと。
116 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/18 00:29] きれいなカレンダーにびっくり
117 名前:KoRoN@Vim%Chalice mailto:sage [02/01/18 14:24] >>115 rightleft時にMBを正しく捌けるようにするか(苦笑)
118 名前:1 [02/01/18 23:17] foo.vim解読続き。 指定パターンにマッチする行数を得るスクリプト。 例) Helloを含む行はいくつある? :echo Count("Hello") 10 fun! Count(pat) let num = 0 execute 'g/' . a:pat . '/let num = num + 1' return num endfun numを0で定義して g/ で検索したパターンが出現するたびに num をインクリメントしてそれを返すと。 # calendar.vim使ってます。
119 名前:1 [02/01/20 21:40] foo.vim解読の続き。 ハイライト設定一覧を新しいウィンドウでハイライト付きで確認出来るスクリプト。 fun! ShowHi() " a に hi の内容を取得 let save_more = &more set nomore redir @a hi redir END let &more = save_more " 新しいウィンドウでハイライト設定 new put a v/\h/d %s/.\{-}\(\h\w*\).*/syn keyword \1 \1/ %y a @a endfun hi はハイライト設定一覧を表示する。その時、画面が一杯になると表示が止まってし まうので more オプションを一旦保存して nomore に設定しておく。redir @a は、コ マンドの出力がレジスタ a にも入るようにする。だから hi の表示結果が a にも入 る。redir END でリダイレクトを停止。 次に new で新しいウィンドウを開いて a に入っている hi の結果をペースト。v/ の 部分は、単語の先頭が [A-Za-z] で始まらない行を削除。%s の部分は、ハイライト設 定をハイライト設定名自身に反映させるコマンドとなるように置換。例えば :syn keyword Visual save_more とするとsave_more の部分が選択範囲用の色になるみた い。%y a は全体をレジスタ a に入れる。ノーマルコマンドで ggVG"ay という方法も あるけど、%y a の方がずっと読みやすいな。で、コマンドとして @a を実行すると、 なんとレジスタ a の中のコマンドが一気に実行されてハイライトが反映される仕組み。
120 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/21 03:04] >1 お疲れ様です。 # ちょっと前に、ハイライト表示の定義をしようとして出来なかったのですが # もう一回チャレンジしようかな?
121 名前:mattn@Vim%Chalice mailto:sage [02/01/21 09:54] >>118 > # calendar.vim使ってます。 どもです。 でも、実は使おうとおもって作ったわけじゃないんです。(^^;) 単に、cal を中呼びしてるスクリプトを見つけて、 「これならスクリプトだけでかける」と思ったのと M-x calendar があるなら :Calendar もあっていいかなと思って作り始めたのが、きっかけです。
122 名前:1 [02/01/21 21:09] foo.vim解読の続き。 指定関数の内容を新しいウィンドウで見るスクリプト。 fun! EditFun(name) " 指定関数の中身をレジスタ a に取得 let save_more = &more set nomore redir @a execute "function " . a:name redir END let &more = save_more " 新しいウィンドウに a をペーストして vim 用のハイライト設定 execute "sp " . tempname() put a set ft=vim endfun 前のスクリプトと似てるからあんまり書くことないけど、:function EditFun とすると EditFun の内容が表示されて set ft=vim でvim用のハイライト設定になると。 >>120 漏れもハイライト定義の方法はまだよくわかってないです。 foo.vimが終わったら覚えようかな。 >>121 へー、なんかEmacsに対抗して作ってるのかなとは思ってましたが(w
123 名前:mattn@Vim%Chalice mailto:sage [02/01/22 12:25] >>122 > ... なんかEmacsに対抗して作ってる ... って言いつつも emacs21 + navi2ch xyzzy + 2ch-mode が何時でも準備OKな状態だったりします。(w
124 名前:1 [02/01/22 19:58] foo.vim解読の続き。 ユーザーが独自に定義したモードラインを取得するスクリプト fun! GetModelines(pat, ...) " start と finish に範囲を求める let EOF = line("$") if a:0 > 1 let start = a:1 let finish = a:2 elseif 0 if a:1 > 0 let start = 1 let finish = a:1 else let start = EOF + a:1 + 1 let finish = EOF endif endif if !exists("start") || start < 1 let start = 1 endif if !exists("finish") || finish > EOF let finish = EOF endif " モードラインの行を n に取得 let n = 0 silent execute start . "," . finish \ 'g/' . escape(a:pat, "/") . "/let n=line('.')" " モードラインが見つかったら指定したパターンで置換 if n execute "normal!<C-O>" return substitute(getline(n), '.\{-}\(' . a:pat . '\).*', n.':\2', '') else echo return "0:" endif endfun これよくわかんねーな。 とりあえず前半は臨機応変な範囲指定に対応する処理 GetModelines(pattern, 100) ・・・先頭から100行まで GetModelines(pattern, -100) ・・・最後の100行 GetModelines(pattern, 50, 80) ・・・50行目から80行目まで GetModelines(pattern) ・・・全体行 んで、30行目に /* foo: bar=78 */ と書いておいて下のを実行すると、 :echo GetModelines('/\*\s*foo:\s*\(.\{-}\)\s*\*/') 30:bar=78 モードラインは g/ で検索されているから、その後の "normal!<C-O>" でモードライン にジャンプすると。でも、30:bar=78 を受け取ってどうすりゃいいのだろう。 30はいらないとして、bar=78 ってのを独自のオプションとして取り込めばいいのかなぁ。
125 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/23 02:44] 41.7 関数定義 Vim では独自の関数も定義出来るぞ.基本的には関数定義はこんな感じでやれば良し. :function {name}({var1}, {var2}, ...) : {body} :endfunction 注意: 関数名は大文字で始めるべし. とりあえず二つの値の小さい方を返す関数でも定義してみっぺかね.とりあえず最初の行は, :function Min(num1, num2) で,これは Vim に関数名が "Min" で,引数を"num1" と "num2" の二つ取るっ てことを宣言しとるっぺよ. まず最初はどっちが小さいかチェックせにゃいかんから, : if a:num1 < a:num2 と."a:" っつー接頭辞は Vim にこの変数が関数の引数だって事を宣言しと るだけぢゃ.んで,"smaller"という変数に,小さい方の数字を代入すれば OK ね,と. : if a:num1 < a:num2 : let smaller = a:num1 : else : let smaller = a:num2 : endif で,"smaller" って変数はローカル変数になるぞ.関数内で使われる変数は, "g:"とか "a:", "s:" とかって接頭辞が付かない場合はローカル変数になる からな. 注意: グローバル変数に関数内からアクセスする場合は "g:" って接頭辞を付ける べし.つまり,"g:count" を関数内から使うと,グローバル変数の "count" だ し,普通に "count" ってやったら,それとは別の関数ローカルの変数になるっ てわけよ.
126 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:滅入り苦しみます!! [02/01/23 02:44] んで, ":return" 文を使って小さい方の値をユーザに返しましょーかね. 最終的にはこの関数は : return smaller :endfunction ってな感じで終了するわけだ.まぁ完全な形で書くとこんな感じになるべさ. :function Min(num1, num2) : if a:num1 < a:num2 : let smaller = a:num1 : else : let smaller = a:num2 : endif : return smaller :endfunction ユーザ定義関数はビルトイン関数と同じように呼べるぞ.名前だけは違うけど. だから,Min 関数はこんな感じで呼べるわけよ. :echo Min(5, 8) って. >Only now will the function be executed and the lines be interpreted by Vim. 何言ってるんだ?ココは.分からん(鬱 もし未定義の関数や変数使ってたり,なんか間違いがあったらエラーメッセー ジが表示されるぞ.関数定義の時点ではエラーは検出されないんだよねー. もし関数が ":endfunction" まで到達しちゃったり, ":return" が引数無しで 呼ばれたりしてたら関数はゼロを返すぞ. 既にある関数を再定義する場合は ":function" コマンドに ! を使えばいい. つまり, :function! Min(num1, num2, num3) って事ね.
127 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:age [02/01/23 02:46] ふぅ,お久しぶりでヤンス. 最近忙しいでヤンスよ. まぁ暇が出来たらまたちょくちょくやるっす. そんぢゃ.
128 名前:mattn@Vim%Chalice mailto:sage [02/01/23 17:53] お遊びスクリプト・・・ if has('win32') && ($OSTYPE=='cygwin' || $TERM=='cygwin') let cygwin_root = "c:\\cygwin" let iargs = 0 let nargs = argc() while iargs < nargs let varg = argv(iargs) if varg =~ '^/cygdrive/' let varg = substitute(varg,'^/cygdrive/\(\a\)/\(.*\)','\1:/\2','g') elseif varg =~ '^/' let varg = cygwin_root.varg endif let varg = substitute(varg,'/','\\','g') exec "argadd ".varg let iargs = iargs + 1 exec "argdelete ".iargs endwhile let iargs = 0 while iargs < argc() silent argdo! rewind let iargs = iargs + 1 endwhile unlet iargs unlet nargs unlet varg unlet cygwin_root endif
129 名前:1 [02/01/23 20:43] Cygwin形式のパスをDOS形式に変換するスクリプトですかー とりあえず、 argadd - 引数リストにファイル追加 argdelete - 引数リストからファイルを削除 argdo! - 引数の全てのファイル対してコマンドを実行 を覚えました。 これらって5.7のマニュアルには見つからなかったから最近のコマンドかな。
130 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:sage [02/01/23 20:56] 余談ですけど、最近のCygwinってDOS形式(但しディレクトリセパレータは/)のパスを 受け付けますよね。おかげで'shellslash'との親和性がスゴク良い。 % ls d:/HOME/vim/vim60 とか出来ますから。 >>129 そうですね。6.0の新機能です。 :help new-argument-list
131 名前:1 mailto:sage [02/01/23 22:24] >>43 のAllargs関数を見つけた時はずいぶん喜んでたんだけど、 既にそれに代わるargdoってのがあったのかぁ。 それはいいとしてversion6.txt読んでたら gi って新コマンドを発見。 前回入力し終えた所にジャンプして i してくれる。これは(・∀・)イイ!!
132 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/24 01:19] 関係無いかもしれんけど cygwinで cygpath っちゅうコマンドも便利だよ。 # 外出か?
133 名前:1 mailto:sage [02/01/25 02:15] 糞みたいな残業強制させられて今タクシーで帰宅。 これじゃお勉強する暇ねーよ。あーあ。
134 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:sage [02/01/25 10:37] >>133 お疲れさんです(^-^;
135 名前:1 [02/01/26 22:43] foo.vim解読の続き。 入力モードの時に F7 で独自に指定したタブを挿入するスクリプト。 imap <F7> <C-R>=VarTab(virtcol("."),8,17,26,35)<CR> fun! VarTab(c, ...) " 最初のタブ位置を探す let i = 1 while i <= a:0 execute "let num_sp = -a:c + a:" . i if num_sp > 0 break endif let i = i + 1 endwhile if i > a:0 return "" endif " スペースを挿入する let spaces = " " let len = 1 while len < num_sp let spaces = spaces . spaces let len = len + len endwhile return strpart(spaces, 0, num_sp) endfun 可変長引数の部分でタブストップするカラム 8,17,26,35 が指定されている。 最初のタブを探す部分は定石として覚えとこ。 strpart() は spaces のインデックス 0 から num_sp 個分を返す関数。 上の場合 spaces の全体を返すから使う必要ない気もするけど。 そんだけ。
136 名前:名無しさん@お腹いっぱい。 [02/01/27 04:17] これvimスクリプトかどうか分かんないんだけどステータスラインに 文字コードとか改行コードを表示させるって出来る? もしかして、関数つくって呼ぶとかそんな方法ですか? つか、自分で調べろって?・・・スマソ。
137 名前:1 [02/01/27 11:16] >>136 set statusline=%<%f%h%m%r%=%b\ 0x%B\ \ %l,%c%V\ %P ↑これでできた(:help statusline より) お勉強スレなので解説付き 重要なカレントの文字コードは %b と %B で解る %b - 10進数 %B - 16進数 他のは %f - ファイル名 %h - ヘルプを見ている時だけ[ヘルプ]になる %m - nomodifiable の時 [-] になる %r - readonly の時に [RO] になる %l - 行番号 %c - カラム値 %V - 選択部分のライン番号。カラム値と同じ場合は表示されない? (再現できず) %P - ページの位置らしい 先頭 or 末尾 んで表示制御が、 %< - 1行に入りきらなかった時にこの位置から表示する?? (再現できず) %= - これ以降を右側に表示 あとスペースは \ でエスケープ
138 名前:136 [02/01/27 13:09] >>137 いやそうじゃなくて 文字コード = euc-jp, sjis, jis, utf8 改行コード = CRLF, LF, CR を言いたかったのです・・・。 説明の仕方が悪かったですかね・・・。
139 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/27 13:25] >136 function! GetStatusEx() let str = '' let str = str . '[' . &fileformat . ']' if has('multi_byte') && &fileencoding != '' let str = str . '[' . &fileencoding . ']' endif return str endfunction set statusline=%n:\ %<%f%y\ %m%r%h%w%{GetStatusEx()}\ %l,%c\ %P 確かコレ KoRoN 殿に教わったんだと思ったけど,こんな感じでどーよ? ゴチャゴチャ付いてるのはヲレのヤツそのまんまだからっつーことで御免 翻訳しなくっちゃなー
140 名前:1 [02/01/28 22:51] foo.vim解読の続き。 HTMLファイル編集中にバックスペース一発で とかを一気に消すスクリプト。 augroup Foo autocmd BufEnter *.html,*.htm inoremap <BS> x<Esc>:call SmartBs('&[^ \t;]*;')<CR>a<BS><BS> autocmd BufLeave *.html,*.htm iunmap <BS> augroup END fun! SmartBs(pat) let init = strpart(getline("."), 0, col(".")-1) let len = strlen(matchstr(init, a:pat . "$")) - 1 if len > 0 execute "normal!" . len . "X" endif endfun カレント行のカーソル位置より前の文字列を init に取得。 その文字列の最後に みたいな文字列があればその文字数を len に取得。 みたいな文字列が無ければ matchstr は "" を返し、len は 0 になる。 だから len > 0 の時、その数だけバックスペースすれば が消える仕組みらしい。
141 名前:1 mailto:sage [02/01/28 22:55] ありゃりゃ消えとるがな。 &nbsp の事です。
142 名前:名無しさん [02/01/29 00:41] Buf* の訳というか説明があるとイイナって思った。 BufNewとBufNewFileの違いが分からんし。
143 名前:ヘッポコ訳者 ◆xBY/hgW2 [02/01/29 00:45] >142 さぁ,言い出しっぺの法則ぢゃ!!ガムバレ(・∀・)!!! # ヲレ今風邪で寝込んどる.スマソ
144 名前:142 [02/01/29 00:48] ウワー。 マジ勘弁。英語できないし。 誰かにパス。なんていうのはアマい(・∀・)?
145 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/29 01:03] >142 しゃーないのぅ autocmd.txt を見ると, BufNewFile: 存在しないファイルの変数を始めた時. スケルトンからの読み込み時でも使われる. BufNew: 新しいバッファを作成した直後. バッファ名をリネームした時にも使われる. バッファがバッファリストに追加された時は BufAdd も 実行されるぞ. 注::この autocommand が実行された時はカレントバッファ"%" はその時作成されようとしてる"<afile>" とは違うよん とりあえず上記二つはこんな感じかな
146 名前:1 [02/01/29 23:40] foo.vim解読続き。 sed の y コマンドを実現するスクリプト 使い方(aをxにbをyにcをzに置換するには?) :Transform abc xyz (カレント行を対象) :%Transform abc xyz (全体行を対象) 素直にsedを使うと? :.!sed 'y/abc/xyz/' :%!sed 'y/abc/xyz/' command! -nargs=* -range Transform <line1>,<line2> call Transform(<f-args>) fun! Transform(old, new, ...) if a:0 let string = a:1 else let string = getline(".") endif let i = 0 while i < strlen(a:old) && i < strlen(a:new) execute "let string=substitute(string, '".a:old[i]."','".a:new[i]."','g')" let i = i + 1 endwhile if a:0 return string else call setline(".", string) endif endfun -range を付けているから <line1> と <line2> が有効に。 <f-args> は空白で区切った引数が自動的に , 区切りになって関数へ渡される。 だから :Transform abc xyz は Transform("abc", "xyz") となって関数が呼ばれる。 んで↓のように一文字ずつ対応するように置換されていく。 let string=substitute(string, 'a', 'x', 'g') let string=substitute(string, 'b', 'y', 'g') let string=substitute(string, 'c', 'z', 'g') setline(".", string) はカレント行を string の内容にする。 あと第3引数があればカレント行よりそっちを優先するので別のスクリプトからも使い まわせる。 :echo Transform("abc", "xyz", "aabbcc") xxyyzz
147 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/01/30 00:19] >>146 便利そうなスクリプトなので日本語対応版を書いてみました。ちょっと圧縮バージョ ンなので見難いかもしれないけどこれも勉強になるでしょう。 # 香り屋版には組み込むかも。 command! -nargs=* -range Transform <line1>,<line2>call Transform(<f-args>) function! Transform(from_str, to_str, ...) if a:0 | let string = a:1 | else | let string = getline(".") | endif let from_str = a:from_str | let to_str = a:to_str while 1 let from_char = matchstr(from_str, '^.') if from_char == '' | break | endif let to_char = matchstr(to_str, '^.') let from_str = strpart(from_str, strlen(from_char)) let to_str = strpart(to_str, strlen(to_char)) let string = substitute(string, from_char, to_char, 'g') endwhile if a:0 | return string | else | call setline(".", string) | endif endfunction
148 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [02/01/30 00:26] <<<範囲(Range) を使う>>> ":call" コマンドには行範囲(line range) を指定する事も出来るよん. This can have one of two meanings. 関数が "range" キーワードと一緒に定義されてたら,その関数は行範囲を扱う んだな. そーゆー関数は,"a:firstline" と "a:lastline" っつー二つの引数が渡さ れる事になるぜぃ.この二つは関数が呼ばれた時に指定されてる行範囲の最 初と最後の行数でござるよ. 例: :function Count_words() range : let n = a:firstline : let count = 0 : while n <= a:lastline : let count = count + Wordcount(getline(n)) : endwhile : echo "found " . count . " words" :endfunction この関数は, :10,30call Count_words() と,こんな感じで呼び出せる. この場合関数は一回のみ実行されて,その行範囲に含まれてる単語数を出力するよん. # 訳者注: Wordcount っつー関数は自前で作らんとダメっぽい. # ついでに, while の中に let n = n+1 が要るような気もするんだが・・・ ちなみに"range" keyword 無しで定義した関数で行範囲を扱う事も出来て, 例: :function Number() : echo "line " . line(".") . " contains: " . getline(".") :endfunction これを :10,15call Number() って呼んでやると,この関数が 6 回呼ばれるよーになるのだ.
149 名前:ヘッポコ訳者 ◆xBY/hgW2 [02/01/30 00:27] 訳注のところってもしかして嘘書いてます? getline は行数 n をインクリメントしたりしないですよねぇ…? 風邪引いてるんで今日はここまで
150 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:sage [02/01/30 00:34] >>149 試せばすぐわかりますがインクリメントはきっと必要でしょう。 # 丁度Transformもrangeの無い例になってて、タイムリーですなぁ
151 名前:名無しさん@お腹いっぱい。 mailto:sage [02/01/30 01:31] >146 ご苦労様です。 >sed の y コマンドを実現するスクリプト cygwin で man sed したんですが、s コマンドと y コマンドの違いがいまいちわからなかったです。 わかりやすく説明してるようなサイトなど教えていただけないでしょうか? スレ違いでごめんなさい。
152 名前:ヘッポコ訳者 ◆xBY/hgW2 [02/01/30 01:43] >KoRoN殿 ええ,一応試してはみたんですよ,ハイ(^^; ただなんとなくちょっと自信が無かったので… >151 日本語 man より [2addr]y/string1/string2/ string1 に現れるパタンスペース中の文字を string2 の対応した文字に 置換する。たとえば、`y/abc/ABC/' はパタンスペース中の文字 a、b、c を大文字に置換する。バックスラッシュと改行以外のすべての文字を区 切りとして用いることができる。 string1 、 stirng2 中では、`\' 直 後の改行以外の文字はリテラルに解釈され、`\n' は改行と解釈されま す。 あぁ,コリャ分からんかもね. つまり,s/sage/mona/ だと,'sage' が 'mona' に置換されるけど, y/sage/mona' だと s->m a->o g->n e->a ってな感じで置換される.分かるかな?これで. 例を挙げると,'sega' は s/sage/mona/ だと何も起こらんけど, y/sage/mona/ だと 'mano' になるのよ.
153 名前:151 mailto:sage [02/01/30 02:04] >152 ヘッポコ訳者さん、ありがとうございます。 試してみてわかりました。キャラクタ単位で複数の置換を一度にするって感じでしょうか? 風邪はやってますね。翻訳がんばってください。では
154 名前:1 [02/01/31 01:08] foo.vim解読の続き。 指定パターンを検索してセレクトモードで囲むスクリプト command! -nargs=1 Search call Search(<f-args>) fun! Search(pat) execute "normal! /" . a:pat . "\<CR>" execute "normal! v//e+1\<CR>\<C-G>" endfun -nargs=1 だから 1 個の引数が必要。 :Search foo だと /foo が実行されて次の foo にジャンプする。 v//e+1 は v でビジュアルモードにして //e+1 で再び検索ジャンプする。 // という表記は間に前回の検索文字列が省略されているので /foo/e+1 の 意味になってカーソル位置の foo の最後の文字の次のカラムまでカーソル 移動する。最後にビジュアルモードを Ctrl+G でセレクトモードに変更。 /foo の後に v//e+1 やらならくても単に vel でいいんじゃないのかと 思ったけど、検索されるのは単語とは限らないから v//e+1 の方がいいのかな。 あと Ctrl+G のセレクトモードって初めて知ったけど単純にWindowsの選択と 同じように選択後に何か入力すると選択部分が消えるモードらしい。
155 名前:mattn@Vim%Chalice mailto:sage [02/01/31 19:45] UNIXユーザへ送る条件演算子の応用 imap <silent> <c-\> <C-O>:let &iminsert=(&iminsert==2?0:2)<CR>
156 名前:1 [02/01/31 23:43] foo.vim解読の続き。 挿入モード時に _foo_ のように入力すると FOO に変換されるスクリプト :imap _ _<Esc>:call Capitalize()<CR>s fun! Capitalize() if exists("b:Capitalize_flag") unlet b:Capitalize_flag normal! vF_Ux, else let b:Capitalize_flag = 1 execute "normal! a_\<Esc>" endif endfun 挿入モードで _ をタイプすると _ を挿入してノーマルモードにして Capitalize() が 呼ばれる。最初は b:Capitalize_flag は定義されていないので else 側の a_<ESC> が 実行されてもう一個 _ が入力される。そして Capitalize() を抜けて s で _ が 消えて挿入モードに戻る。 _ は入力しないで a で挿入モードに戻ればいいような気も するけど。 んで _foo_ までタイプすると再び Capitalize() が呼ばれて b:Capitalize_flag はさっき 定義されたので if 側が実行される。vF_UX, はビジュアルモードにして foo の左側の _にジャンプして全部大文字にして _ を消して右側の _ に移動するという意味。で、s で右側の _ も消されて挿入モードに戻ると。 b: はバッファローカルという意味。 >>155 Ctrl+\ でIMEをトグルする方法っすね。
157 名前:1 [02/02/02 23:04] foo.vim解読の続き。 カレントウィンドウをマウスの左クリックで切り替えた時に、 前のウィンドウの入力モードを保持するスクリプト。 inoremap <LeftMouse> <Esc>:let w:lastmode="Insert"<CR><LeftMouse> \ :if exists("w:lastmode") && w:lastmode=="Insert"<Bar> \ startinsert<Bar>endif<CR> nnoremap <LeftMouse> <Esc>:let w:lastmode="Normal"<CR><LeftMouse> \ :if exists("w:lastmode") && w:lastmode=="Insert"<Bar> \ startinsert<Bar>endif<CR> 前者は挿入モードで左クリックされた場合でウィンドウローカルなユーザー変数 lastmode を "Insert" に設定。後者はノーマルモード時で "Normal" に設定する。ん で左クリックでウィンドウに戻ってきた時、lastmode == "Insert" だったら、 startinsert にする。startinsert はスクリプトが終了した後に挿入モードになる命令 らしい。 おまけ。 nmap (マッピングあり) と nnoremap (マッピングなし) の違いをテスト。 ↓マッピングありの場合 _a → _b → OKの表示 :nmap _a _b :nmap _b :echo "OK"<CR> ↓マッピングなしの場合 _a → _b で何も起こらない :nnoremap _a _b :nmap _b :echo "OK"<CR> これで foo.vim 解読は全部終わり。
158 名前:151 mailto:sage [02/02/03 01:29] > 1さん おつかれさまです。
159 名前:1 [02/02/05 01:38] これこそVimの醍醐味!? シンタックスハイライト設定のお勉強その1 とりあえず独自の設定を作ってみる。 まず :set filetype=memo と設定した時には runtime/syntax/memo.vim というファイル を vim は開こうとするようなので runtime/syntax/memo.vim を作ってみる。 中には↓これを書いてみる。 highlight MemoHead guifg=#00FFFF syntax match MemoHead display "^■.*" 水色設定を MemoHead って名前にして正規表現 ^■.* にマッチする部分を MemoHead の設定色にするという意味。 んで適当なファイルを開いて行頭から ■なんとか と書く。 んで :set filetype=memo を実行。「■なんとか」 の行が水色になったら成功と。 もうちょっと調べたいけど、もう寝ないとやべぇ。
160 名前:名無しさん@お腹いっぱい。 mailto:sage [02/02/06 00:23] スクリプト実行してるとき例えば exe "normal i\<C-D>" ってなってると i_CTRL-D が実行されるけど、 これってユーザー毎に Mapping を変更していたら違う結果が返ってくるよね? これを Mapping に依存せずに本来の動作をさせたいんだけど どうすればよいの?
161 名前:160 [02/02/06 00:24] sage が残ってた。 age
162 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [02/02/06 00:27] >>160 「!」を使ってこうします。 :exe "normal! i\<C-D>"
163 名前:名無しさん@お腹いっぱい。 [02/02/06 00:41] >>162 おお、ありがとう テトリス落としてやってたんだけどなんか表示が変だなって思って調べてたら・・・ 案外こういうのっていいかげんに思われてるんですかねえ。 まあこういう(どんな環境でも動作させようという)意識の差っていうのは個人差があるんでしょうけど。
164 名前:名無しさん@お腹いっぱい。 mailto:sage [02/02/06 00:46] >163 テトリスって?検索したけどわからなかった。 vim でテトリス?
165 名前:160 mailto:sage [02/02/06 00:57] vim.sourceforge.net/ の Recent Script Updates にあったんで試してみた
166 名前:名無しさん@お腹いっぱい。 mailto:sage [02/02/06 01:15] ありがとう、おもしろい。 こんなこともできるんですね。
167 名前:名無しさん@お腹いっぱい。 [02/02/06 01:22] > Source it! To start the game, press <Leader>te. の <Leader> って何?
168 名前:名無しさん@お腹いっぱい。 mailto:sage [02/02/06 01:23] :h <leader> 設定してなければ\らしい
169 名前:160 mailto:sage [02/02/06 01:24] オレもよう分からんけどとりあえずノーマルモードで \te ってやったらできるぞ
170 名前:167 mailto:sage [02/02/06 01:46] >168,169 thanx!