[表示 : 全て 最新50 1-99 101- 201- 301- 401- 501- 601- 701- 801- 901- 2chのread.cgiへ]
Update time : 03/18 19:04 / Filesize : 368 KB / Number-of Response : 974
[このスレッドの書き込みを削除する]
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧] [類似スレッド一覧]


↑キャッシュ検索、類似スレ動作を修正しました、ご迷惑をお掛けしました

Vim6スクリプトお勉強スレ



1 名前:名無しさん@お腹いっぱい。 [01/12/17 12:15]
みんなでスクリプトを覚えよう

2 名前:1 [01/12/17 12:22]
まずはHelloWorldから。
適当なファイル hello.vim とかに
echo "HelloWorld"
とだけ書いて :source hello.vim で実行
HelloWorld が表示されれば大成功!

3 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/17 14:39]
もう終わりかよ!
とりあえず
vim.sourceforge.net/scripts/
位書いとけ。

4 名前:名無しさん@Vim%Chalice [01/12/17 14:53]
>>3 を見に行った。
emacs時代にこよなく愛していたlatex支援のauctexが
vim6に対応してた。
泣いた。ただただ泣いた。
さて、使ってみるか…

5 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [01/12/17 15:16]
>>1
なんかあっという間に叩かれ荒される危険が伴ってますが…スレ建て記念にマメ知識
を紹介しておきます。

■変数代入
実行例:
:let foo = "Hello World"
:echo foo
Hello World
:let foo = 5
:let bar = "2"
:echo "foo+bar=" . (foo + bar)
foo+bar=7

スクリプトの中では例のように変数に値を代入できます。代入できるのは整数値もし
くは文字列で、Perlのようにコンテキストに応じて相互に自動変換されます。変数名
は必ず英小文字で始まり、英小文字、アンダーバー(_)、数字を組み合わせて構成し
ます。本当は他に幾つかの文字が使えます。"b:"、"s:"、"v:"、"&"、"$"等の文字で
始まる変数には特別な意味があります。しかし今はまだ覚えなくて良いでしょう。

6 名前:1 [01/12/17 21:48]
なるほどー、なんとなく数値文字列から数値変換はstrtol関数使ってる
だけなのかなって気がするけど、実際のソースは見たことないからわからん
とりあえず
:echo "0xff"==255
1
となった。真は1らしい。
で、& はオプション変数に付けて $ は環境変数に付けるらしい(:help variableより)
:set number
:echo &number
1
:echo $shell
/bin/bash
:echo $SHELL
/bin/bash
大小文字は問わないと。

7 名前:ヘッポコ訳者 ◆xBY/hgW2 [01/12/17 22:16]
41.1 イントロ

まずは vimrc から始めよーかね.Vim は起動時にこいつを読み込んで実行すん
のよ.んでもって,vimrc では変数は好きなように設定出来るし,好きなコ
マンドも実行出来る.

ちなみに syntax ファイルも vim script なんだな,コレが.
 > As are files that set options for a specific file type.
 (コレはどー訳すべか?
 「特定のファイルタイプに応じた設定をするよーなファイルだぜ」
 でいいのかな?)
んでもって,複雑なマクロは vim script の別ファイルにも出来るのさ.
 > You can think of other uses yourself.
 (「あとは色々あるけど皆でテキトーにやってくれ」ぐらいの意味か?)

よーし,そんじゃシンプルなのから始めるぜ!

:let i = 1
:while i < 5
: echo "count is" i
: let i = i + 1
:endwhile

# おっと,ここで注意だ.実は行頭の ":"コマンド入力の時はいるんだけど,
# Vim script のファイルの中ではいらねーからな.まーここでは目立って分か
# りやすくするためにも行頭に":"は入れとくことにすっからヨロピク.

8 名前:ヘッポコ訳者 ◆xBY/hgW2 [01/12/17 22:16]

":let" ってのは変数に値を代入する命令ってヤツよ.ま,一般的には

:let {variable} = {expression}

ってな感じで使うと思ってくれ.んだから,上の例(の一行目)の場合は変数
名(variable)が "i" で,式(expression)はただの値である 1 ってわけさ.

":while" コマンドはループの開始な.フツーは

:while {condition}
: {statements}
:endwhile

こんな感じで使うぞ.":endwhile" までにある文(statements)は条件
(condition) が真の間はずっと実行されるからな.上の例だと条件は "i < 5"
ってヤツな.これは i が 5 より小さい時は真になんのよ.

んでもって ":echo" コマンドは引数を表示するコマンドね.上の例だと,
"cout is" と,変数 i の値が表示されるってわけ. んだから最初は i の値は
1 だから,

count is 1

って表示されるってなもんよ.んで,その後にはまた別の ":let i=" ってコマ
ンドが出てきてるよな.んで右辺には "i + 1" っつー式が使われてる.これは
変数 i の値に 1 を足した値を i に代入するって事な.

んだもんで,上の例の最終的な出力はこーなる.

count is 1
count is 2
count is 3
count is 4

# 間違って無限ループにハマっちまったら CTRL-C で中止出来るからビビら
# んよーに.(Win では CTRL+Break な)

9 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/17 22:17]
<<<三種類の数値>>>
数値は10進数か,8進数,もしくは16 進数が使えるぞ.16進数は頭に "0x"
か "0X" を付けるべし.たとえば "0x1f" っつったら10進数の 31 な.んで,
8進数は頭に "0" を付けるべし.つまり "017" で10進数の 15 ってことな.
# 十進数を使ってるつもりなら頭に "0" なんか付けるんじゃねーぞ. Vim
# には8進数だと思われちまうからな.

んで,":echo" コマンドの出力は10進数になるからな.だから例えば
:echo 0x7f 036
ってやったら
127 30
って表示される.

そんで,数値はマイナス記号で負の値になるぞ.8進数でも16進数でも一緒な.
さらにマイナス記号は引き算にもなるぞ.
:echo 0x7f -036
ってやったら
97
って表示される.上の例と比べて見とけや.

ちなみに式に含まれてる空白は無視されるぞ.ま,各々を分割して読みやすく
するために空白入れるのはいい事だけどな.例えば負の数と間違わんよーに
マイナス記号と後に続く数字の間にスペース入れるとかそーゆー事な.

:echo 0x7f - 036

って事.

10 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/17 22:19]
とりあえず help の Vim Script とかゆーところをボチボチ
ウソ日本語訳でもかまそーかなと.
全角スペースでインデントしてあるのは良く分かんねーところ
だから適当にツッコミよろしく.
今日はここまで.



11 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [01/12/17 22:39]
>>10 お疲れ様です。折角なのでもうちょっと入門用の情報を。

5.7のeval.txt(リファレンスマニュアルのほう。ちなみに>>7-9は6.0で追加された
ユーザマニュアルの翻訳ですね)は日本語訳が次のURLにあるので参考にしてくださ
い。6.0による主な仕様の追加はスクリプトローカルな名前(s:で始まる名前)と関数
群なので、まずは5.7リファレンスマニュアルと>>7-9(ユーザマニュアル)の日本語訳
を読んで理解することから始めるのが吉でしょう。

 ixeris.bios.ics.saitama-u.ac.jp/~noiz/gvim/text/eval.txt

# 本当は自分で訳すのが一番身に付くんですけど、既にあるショートカットは利用し
# たほうが近道ですよね。

12 名前:1 mailto:sage [01/12/17 23:51]
:echo 1 2
1 2
:echo 1 -2
-1
なんで - をつけると演算されるんだー
:echo 1 +2
3
ま、そういうもんか。

:echo 1/0
2147483647
あ、0で割れた!

13 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/18 00:26]
>>10
ヘッポコ訳者 さん
それ英語でよんだけど、もう一度勉強させてもらいます。サンクス
>>KoRoNさん
eval.txt も参考にさせていただきます。

いいスレ

14 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/18 00:41]
口調が v(^.^)v みたいでウザいとかそーゆーレスを期待(?)
してたんだが・・・
# まぁヤツほどアレぢゃないけど

> 1
echo 1 "-2" とかってやらんとダメみたいね.

15 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/18 18:40]
41.2 変数

変数名は ASCII 文字と数字とアンダースコアのみで作ってくれよ.
でも,数字から始めるのはダメだからな.

counter
_aap3
very_long_variable_name_with_dashes
FuncLength
LENGTH

ってな感じであれば OK. "foo+bar" とか "6var" なんつーのはダメだからな.

んで,こーやって宣言した変数はグローバル扱いになるぞ.その時に宣言さ
れてる変数を見たい時は

:let

ってやれば全部ダーッと表示されるぜぃ.グローバル変数はどこでも使える
変数ってヤツね.んだから, "count" っつー変数がある script ファイルの中
で使われてたら,他のファイルからでもその "count" は使えるって事.
これってとにかく混乱するし,最悪の問題にブチ当たる事もあるんだよねぇ.
そんなわけで,変数の頭に "s:" を付けるとその script ファイル内のみで
しか使えない変数になるからこれをやると混乱を避けられるぞ.たとえば,

:let s:count = 1
:while s:count < 5
: source other.vim
: let s:count = s:count + 1
:endwhile

ってコードが,あるscript ファイルにあったとすると, "s:count" はファ
イルローカルの変数になるから,"other.vim" とかっていう別の script ファ
イルを読んじゃったりしても,この変数が変更されちゃったりする心配はご
無用ってワケさ.もしその "other.vim" って script ファイルが "s:count"
って変数を使っていたって大丈夫,それは名前は一緒かもしんないけど,
"other.vim" の中だけでしか使われない全く別の変数なんだ.もっと詳しく
知りたければ |script-variable| の頁でも見てくれや.

ちなみにもっと色々な種類の変数があるんで,詳しくは|internal-variables|
を見てくれ.まぁ良く使うのだけ簡単に並べとくと,


b:name バッファローカルな変数
w:name ウィンドウローカルな変数
g:name (関数内で宣言されてても)グローバルな変数
v:name Vim で最初っから用意されてる変数

ってなぐらいかな.

16 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/18 18:45]
とりあえず今はこんだけ.
夜暇が出来たら続きを出すカモ.
ところでウィンドウローカルって何だ?
っつーか Vim でのウィンドウって何だべさ?
文脈からするとバッファとは当然違うんだよな・・・
バッファが表示されてる時のみ有効とかそんな感じ?全然違う?
help window ってやってもとんちんかんなのしか出て来ない・・・
# 何故ヲレの文章は階段状になっているのだろう・・・・・・・・・・・・

17 名前:KoRoN@Vim%Chalice mailto:koron@tka.att.ne.jp [01/12/18 19:19]
>>16
一つのファイル(バッファ)を編集中に:spすると分かれるのがVimのウィンドウです。
それぞれのウィンドウで:echo winnr()すると異なる番号が帰ってきます。

18 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/18 19:57]
>>KoRoN 殿
あー,なるほど.そーゆー事ですか.そっかそっか.
いつもウィンドウ分割(ってこの言葉使ってるぢゃん(藁) する時って
複数のファイル開く時
ばっかりだから気付かなかったでござるよ.
なるほど,なるほど.ウィンドウサイズとかに使うんですな.
お教えを賜わりましてありがとう存じ奉りまする.

19 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/18 21:32]
<<<変数の削除>>>
変数はメモリを食ってて,":let" コマンドで一覧を見る事が出来るぜぃ.
で,変数を削除したい時には ":unlet" コマンドを使うべし.

:unlet s:count

こんな感じ.この場合はファイルローカルな変数 "s:count" を削除して
メモリを解放するってわけだ.変数が存在すんのかしねぇのか分からん
けど,無い時でもエラーメッセージが出るのはウザいから嫌って場合は
"!" を後にくっつければいいだけ.

:unlet! s:count

つまりこーゆー事ね.んで, script が終了した後でも,ローカル変数が自
動的に削除されるって事は無くって,次にその script が読み込まれた時に,
前に使った時と同じままの値になるからな.まぁつまり,

:if !exists("s:call_count")
: let s:call_count = 0
:endif
:let s:call_count = s:call_count + 1
:echo "called" s:call_count "times"

こんな事が出来るってわけだ."exists()" 関数は変数が定義されてるかどーか
を調べる関数な.引数には調べたい変数の名前(の文字列)を与えてやりゃー
いい.変数そのものを与えちゃダメだぞ.もし,

:if !exists(s:call_count)

なんてやっちまったら s:call_count という変数に「格納されてる値」が調
べたい変数の名前として適用されちまうからな.これはやりたい事とは違う
だろ.

感嘆符 "!" は値を反転(否定)するぞ.つまり値が真だったら偽にするし,値が
偽だったんなら真にするってわけだ.まぁつまり"not"って読めゃいいんだよ.
んだから, "if !exists()" っつーのは "if not exists()" ってわけ.

Vim で真っつったらゼロ以外の事だぞ.んでもってゼロだけが偽な.

20 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/18 22:27]
:let で全変数が見れるんかー。デバッグ時に便利そう。
:let hoge だと hoge だけの値が表示されると。
表示に # がついていたら数値らしい。

:let hoge=123
:let hoge
hoge #123

:let hoge="123"
:let hoge
hoge 123



21 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/19 21:23]
<<<文字列変数と定数>>>

今んとこまだ変数には数字しか使ってねーんだけど,文字列も使えるんだ
ぜぃ. Vim で使える変数ってのは数字と文字列しか無ぇんだよ.どっちの型に
なるのかは ":let" で変数に代入する毎に,その場その場で決まるからな.

文字列を変数にブチ込みたい時は文字列定数を使うんだぞ.まぁ文字列定数っつっても
二種類あって,一個はダブルクウォートで括るやつで,

:let name = "giko"
:echo name
giko

ってな感じな.んで,文字列中にダブルクウォートそのものを含みたい時は
ダブルクウォートの前にバックスラッシュを置くべし.つまり,

:let name = "\"mona\""
:echo name
"mona"

こーゆー事.んで,バックスラッシュがメンドい場合は文字列をシングルク
ウォートで括ればよし.

:let name = '"KoRoN"'
:echo name
"KoRoN"

んで,シングルクウォートに挟まれた文字列は全部そのまんま文字通り扱わ
れるぞ.って事はシングルクウォートその物を含む事は出来ないってことだ.
もちろんバックスラッシュもそのまんま扱われるから,直後の文字を変換す
る為には使えねーからな.

ダブルクウォートに挟まれた文字列は特殊文字(special characters)が使え
るぞ.まーちっとばかり例を挙げてやると,

\t     <Tab>
\n     <NL>, 改行
\r     <CR>, <Enter> (復帰)
\e     <Esc>
\b     <BS>, バックスペース
\"     "
\\     \, バックスラッシュ
\<Esc>   <Esc>
\<C-W>   CTRL-W

最後の二つはただの例だぞ. "\<name>" ってやったら "name" っつー特殊キー
として扱われるって事な.

文字列中の特殊文字の全リストは |expr-quote| にあるぞ.

22 名前:KoRoN@Vim%Chalice mailto:koron@tka.att.ne.jp [01/12/20 16:55]
>>21
うわ。気づかなかったけど何気に
> :let name = "\"mona\""
> :let name = '"KoRoN"'
とかなってるし!!。見過ごしてた(゜Д゜)

23 名前:名無しさん@Vim%Chalice [01/12/20 17:42]
vimメーラに期待age

24 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/20 22:47]
>> KoRoN 殿
見つかってしまいましたか(藁
まぁ敬意を込めてのお遊びなんでお許しを.他意はありませぬ.

今日は忙しいから訳無し.スマソ.

25 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/22 00:32]
41.3 式 (Expressions)

Vimは大胆かつシンプルな式の扱いが出来るよーになってるぜぃ.定義について
は |expression-syntax| を見ろや.まーとりあえず一般的な事だけここでは
教えといてやろう.

これまでに言ってきた数字や文字列,変数っつーのはそれ自体で式になって
るぞ.んだから,式が要求されるところにはいつでも数字や文字列や変数が
使えるってわけだ.他の式の中で使われる基本的なものっつったら,

$NAME     環境変数
&name     オプション
@r       レジスタ

ってな感じかな.

例)
:echo "The value of 'tabstop' is" &ts
:echo "Your home directory is" $HOME
:if @a > 5

&option っつー形は,オプションをまずどっかに保存しといて,それからそのオプ
ションを新しい値に設定した後に何かしてから,先に保存しておいた値を元に戻す
時なんかに使われるぞ.

例)
:let save_ic = &ic
:set noic
:/The Start/,$delete
:let &ic = save_ic

26 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/22 00:33]
今日はこれだけ.
忘年会シーズンは酔っぱらってる時はやらない方がいいカモ・・・

27 名前:名無しさん@お腹いっぱい。 [01/12/22 02:20]
Vim6スクリプトでアウトラインプロセッサを作る事は出来ますか?
行編集の vi の系列だから、そういうのは得意そうな気がするのですが、
如何でしょう?

もし既に在るならば、素の vi から乗り換えたいな。

28 名前:名無しさん@お腹いっぱい。 [01/12/22 02:48]
vimのコマンドにエイリアスみたいのをつけたいんだけど。
例えば、
:aiueo
ってやったら
:se ts=2 sw=2 sts=2 et
のかわりになるみたいな。

あと、よくvimでかかれたテキストファイルに
vim:se ts=2 sw=2 sts=2 et
とかあるけどあれって意味あるの?

29 名前:名無しさん@お腹いっぱい。 [01/12/22 05:51]
>>28
その書き方は知らない。
C++とかJavaのソースなんかでは
// vi:ts=4 sw=4 number:
とか書いたりはするけど(これはちゃんと効く)

30 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [01/12/22 08:46]
ここはスクリプトの勉強スレなので一連(>>27-28)の質問がココにふさわしいかは疑
問ですが、折角ですから答えられる部分は答えてしまいましょう。
■ ◆Vim6 2スレ
 pc.2ch.net/test/read.cgi/unix/1006246205/l50


>>27
完全なアウトラインプロセッサとは言えないのですが、folding(折畳み)機能を使え
ばスクリプトを駆使しなくてもそれに近いことが実現可能です。foldingというのは
テキスト中の指定された範囲を折畳んで隠す機能です。例えばプログラミングであれ
ば特定のブロックを隠したり、関数の実装を隠したりできます。またちょっと毛色は
違いますがテンプレートコンパイラを利用する方法も考えられるかもしれません。
■ テンプレートコンパイラの紹介
 www.kaoriya.net/bbs/bbs.cgi?article=1238&bbs=bbs


>>28
:help commandしてみて下さい。自分で任意のコマンドを定義することができます。
但しコマンド名は英大文字で始まる必要があります。
 例: command! Aiueo set ts=2 sw=2 sts=2 et

> あと、よくvimでかかれたテキストファイルに
> vim:se ts=2 sw=2 sts=2 et
> とかあるけどあれって意味あるの?

もちろんあります。modelineといって(詳細は:help modelineを参照)これが書かれた
ファイルを開いた時に、これらのオプションが自動的に設定されます。スクリプトが
実行されるわけではないので注意してください。modelineを書ける範囲はファイルの
先頭と末尾のそれぞれ5行(この5行はオプション'modelines'により変更可能)です。
 例: *.cの先頭に /* vim:set ts=8 tw=4 sw=4 tw=0: */ と書く
もちろんファイルタイプに拠らず*.txtでもなんでも書いてあれば有効になります。



31 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/22 13:57]
modeline と fold ってけっこう組み合わせて使うよね。
KoRoN さんのサイトのソースなんか参考になるかもね。

32 名前:名無しさん@お腹いっぱい。 [01/12/22 20:42]
うわ、マジココイイわ。そしてマジコココイイわ。要するにイイ。

33 名前:1 [01/12/22 23:11]
ほんとに初めてVimスクリプトをお勉強しょうとおもーとる人の為に書いとくけんな。

スクリプト読んどって解らん命令出てきたら何でもその上で K を入力じゃ
親切なマニュアルが飛び出てくるけん。んで閉じるのは Ctrl+wc

英語じゃわけわからんとかいう場合はこっち
ixeris.bios.ics.saitama-u.ac.jp/~noiz/gvim/
から日本語化してくれとるマニュアルを落として runtime/doc にコピーしときゃーええ。

それにしても日本語化を進めてくれとる人達には大感謝じゃなぁ。

# 酔っていると方言になります。

34 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/22 23:18]
<<<演算>>>
んで,まぁ上で挙げたよーな要素が結合とか出来たら面白い事が出来るでしょ.
まずは数値の演算から行ってみよー!!

a + b      加算
a - b      減算
a * b      積算
a / b      除算
a % b      剰余

まぁ優先順位は普通の算数と同じだぞ.例を挙げると,

:echo 10 + 5 * 2
20

って事な(足し算よりかけ算の方が優先度が高い).
んでジョーシキ通り,括弧を使えば優先度は変えられるぞ.つまり,

:echo (10 + 5) * 2
30

って事ね.

文字列は "." で結合出来るぜぃ.だから,

:echo "Vim" . "Manse-"
VimManse-

ってなもんよ.

":echo" コマンドは複数の引数を受け取ると,それぞれをスペースで区切っ
て表示するんだけど,上の例は全部引数は一個の式だったからスペースで区
切られて表示する事は無いんだ.

C 言語のパクリなんだけど,3項演算子

a ? b : c

も式として使えるぞ.もし "a" が真だったら "b" が使われて,そうでなかっ
たら "c" が使われる.つまり,

:let i = 4
:echo i > 5 ? "i is big" : "i is small"
i is small

ってな感じで使えるわけだ.んで,3つの各パートは必ず最初に評価されるから
な.つまり,

(a) ? (b) : (c)

ってなってると思えばいいわけよ.

35 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/22 23:20]
KoRoN 殿や mattn 殿に続けぇ〜!!!!
#マダミチハトオイナ・・・

今日もこんだけ.なんかアンマリススマナイナ

36 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/23 01:10]
>>33
>日本語化してくれとるマニュアルを落として runtime/doc にコピーしときゃーええ。
日本語のヘルプすごく助かるけど、Version 6.0 で追加された項目が見れなくなっちゃうんだよね。
ウィンドウの縦分割について調べるときにはまった。

37 名前:27 [01/12/23 04:11]
>>30
どうもありがとう。

vim6.0 使ってみましたが emacs のような高機能ぶりで驚きました。
スクリプト機能は emacs の elisp にあたると考えて良いのでしょうか?

38 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [01/12/23 10:20]
>>37
難しい質問です。elispはemacsのベースとして存在しているのでまったく同様に捉え
られてしまうと間違いなのですが、エディタを制御したり内部の関数を利用できると
いう表面的な意味においては同じと考えても差し支えないでしょう。lispに比べれば
表現力に相当の制約がありますが、それでもいかにもvimらしい命令体系で強力なス
クリプトになっています。

39 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/24 00:44]
41.4 条件

":if" コマンドは条件が満足された時のみ,それ以降の":endif" までの文を実
行しまっせ.まぁ普通は

:if {condition}
 {statements}
:endif

こんな感じで.つまり, {condition}が真(ゼロ以外)って評価された時のみ
{statements}が実行されるって事ね.当然その文はちゃんとしたコマンドじゃ
なきゃダメだぞ.余計な変なのがあったりすると Vim が ":endif"を見付け
られなくなっちまうからな.

んで,":else" も使えるぞ.まぁ一般的な使い方っつったら,

:if {condition}
 {statements}
:else
 {statements}
:endif

こうね.2番目の{statements}は最初の{statements}が実行されない場合に実行
されるぞ.

んでもって,やっとこさ":elseif"のご登場

:if {condition}
 {statements}
:elseif {condition}
 {statements}
:endif

これは,":else" の後に ":if" を使ったよーに動くぞ.ただ,余計な
":endif" はいらない(つまり最後の一個だけでいい)けどね.

vimrc ファイルに書くよーな,'term'オプションをチェックして,その値に応じて
ちょっとした事をする便利な例をご紹介.

:if &term == "xterm"
: " ここに xterm 用のコマンドを書くべし
:elseif &term == "vt100"
: " ここに vt100 ターミナル用のコマンドを書くべし
:else
: " 他のターミナルについてのコマンドをここに書くべし
:endif

40 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/24 00:45]
<<<論理演算(っつーか単純な「比較」なだけなよーな)>>>

まーいくつかは例の中で使って来たわけなんだけど,良く使われるのは

a == b     等しい
a != b     等しくない
a > b     より大きい
a >= b     以上
a < b     より小さい
a <= b     以下

結果は条件が満たされてれ 1 で,そーじゃなかったら 0 ね.

例)
:if v:version >= 600
: echo "おめでたう"
:else
: echo "バージョン古いぞ,アップデートしろや!"
:endif

"v:version" ってのは Vimのバージョンを表す,Vim に既に定義されてる変
数ね.600 は バージョン 6.0 の事で,バージョン 6.1 は 601 ってなるぞ.
これ使うと,Vim の色々なバージョンで動くスクリプトを書く時には便利だ
ぞ. |v:version|

論理演算(っつーか比較なんぢゃぁ…)は数値にも文字列にも使えるぞ.文字
列を比較した時は数学的な差が使われるぞ.つまり,バイト値が比較される
から,言語によっては正しくない事もあるからな.

文字列と数値とで比較した場合は,まず文字列が数値に変換されて,それか
ら比較されるぞ.これはちょっとトリッキーで,文字列が数字と認識されない
場合は文字列はゼロとして扱われるぞ.つまり,

:if 0 == "one"
: echo "禿同"
:endif

ってやると,"one" が数字とは認識されないから,ゼロに変換されちゃって,
んでもって"禿同"が表示されちゃうわけよ.



41 名前:ヘッポコ訳者 ◆xBY/hgW2 [01/12/24 00:46]
文字列に対してはあと二つばかりまだあんのよ.

a =~ b  正規表現にマッチする
a !~ b  正規表現にマッチしない

左辺の "a" は文字列で,右辺の "b" は検索で使うような正規表現(以下パター
ン)だぞ.
例)

:if str =~ " "
: echo "str contains a space"
:elseif str !~ '\.$'
: echo "str ends in a full stop"
:endif

シングルクウォートで括った文字列をパターンに使ってる事にご注目.パター
ンって結構バックスラッシュ良く使うんだけど,ダブルクウォートの文字列
使うと,バックスラッシュ二重にしなくっちゃならないから,シングルク
ウォートの文字列使った方が便利なわけよ.

文字列比較する時は 'ignorecase' オプションが使われるぞ.もしそれが嫌
だったら,大文字小文字を考慮する場合は "#",無視する場合は"?" を演算
子の後に付ければいいぞ.つまり,"==?" は大文字小文字関係無く一致を調
べるし, "!~#" ってやれば,大文字小文字を考慮して,パターンにマッチしな
いかどうかを調べるってわけよ.まぁ完全な一覧は |expr-==| を見てくれや.


<<<ループについてもーちっとばかり>>>

":while" コマンドについてはもうしゃべっちまったけど,あと2つばかり
":while" と ":endwhile" の間に使えるコマンドがあるのよ,実は.


:continue    while ループの先頭まで戻ってループを続ける
:break      ":endwhile" まで飛んで,ループから抜ける

例)
:while counter < 40
: call do_something()
: if skip_flag
:  continue
: endif
: if finished_flag
:  break
: endif
: sleep 50m
:endwhile

":sleep" コマンドは待機するコマンド(makes Vim take a nap)ね. "50m"
ってのは 50 ミリ秒の事.まぁもーちっと例を挙げると,":sleep 4" ってやれ
ば 4秒間待機するってわけさ.

42 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/24 00:48]
ハイ,クリスマスプレゼントは以上です(藁

ところで "LOGICAL OPERATION" って「論理演算」だよねぇ?
これって僕の勝手な感覚では「論理和」とかあっちの方の意味
なんだけど,この感覚ってもしかして間違ってる?

43 名前:1 [01/12/24 01:25]
全バッファに対して一括置換が行える便利スクリプトをマニュアルの中に発見しました。
:help map.txt|/Allargs でジャンプ

抜粋。
> :function Allargs(command)
> : let i = 0
> : while i < argc()
> : if filereadable(argv(i))
> : execute "e " . argv(i)
> : execute a:command
> : endif
> : let i = i + 1
> : endwhile
> :endfunction
> :command -nargs=+ -complete=command Allargs call Allargs(<q-args>)

function 〜 endfunction で関数定義。
argc() は バッファ数。
argv(i) は i 番のバッファ名の取得。(:ls で確認できる)
filereadable() は指定バッファが読み出せるか?
execute は ex コマンドの実行。

使う時。foo を bar に置換しまくる。
:Allargs %s/foo/bar/ge|update
eオプションをつけないと foo が無いというメッセージがのんびり表示されて、いつま
でたっても置換が終わらないので気をつけよう(それに気づかずに密かにハマった)
コマンドは | で連続で実行できて、update は変更のあったバッファだけを保存。と。

カレントの *.cpp を置換する場合は予め、
:ar *.cpp
ってやっとくと全部読み込まれる。
確認するには
:ar
と。

すげー便利というか、他のエディタだったら最初から
装備しているような機能だから当然、 _vimrc に書いといて、
_vimrc に書くときは何回定義しても起こられないように
function と command の後に ! を付けとくほうがいいかも。

>>36
縦分割って6.0から追加された機能あるの?? :sp とかじゃなくて?

>>42
御苦労さんです。LOGICALだと同じく or and って感覚ですねえ。

44 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/24 01:57]
>>38
わざわざどうもありがとう。
>>3 のリンクを見てなんとなく感じがつかめました。

今日から Vim Scriptor ということで宜しく。

45 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/24 03:27]
>>43
ctrl-W_V
とか

46 名前:45 mailto:sage [01/12/24 03:30]
スレ違いなのね
ちょっと反省

47 名前:1 mailto:(´Д`;) [01/12/24 22:34]
call confirm("クリスマスイブ", "逝ってよし(´Д`;)")

48 名前:1 mailto:(´Д`;) [01/12/24 22:57]
さぁて、お勉強。
とりあえずKoRoNさんのwc相当スクリプト解析

:function! s:CountChar(first, last)
"!をつけると上書き定義になる。んで s: をつけているから command! のところで
"<SID>CountChar と書かなくてはならない。
: let i = a:first "引数は a: を付けて参照する。a:first は先頭行
: let sum = 0
: while i <= a:last " a:lastは最後の行
: "echo "line: " . i " デバッグ用につけているみたい
: let sum = sum + strlen(substitute(getline(i), '.', ' ', 'g'))
" getline()は指定行の文字列取得。先頭行は0じゃなくて1
" substitute(a,b,c,d) は a =~ s/b/c/d と同等(たぶん)
: let i = i + 1
: endwhile
: return sum "戻り値はreturnで返す。Cと一緒。
:endfunction
:command! -range=% CountChar :echo "Count of characters: " . <SID>CountChar(<line1>, <line2>)
"command! で上書き。定義されるコマンド名は CountChar で別に関数名と同じにしなくちゃいけない
"という決まりがあるわけじゃない。-range=% とすると <line1> に最初の行 <line2> に後の行が格納される。
"<SID>はしらん。と。

49 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/24 23:14]
41.5 式の実行

今んところコマンドは全部 Vim から直接実行されてたわけなんだが,
":execute" コマンドを使えば式の結果を実行する事が出来るぞ.こいつを使う
とコマンドを作って実行する時にカナリ便利!!

例として,変数に含まれてるタグまでジャンプするのを挙げてやろう.

:execute "tag " . tag_name

"." は "tag " という文字列と, "tag_name" という変数に格納されてる値
を結合するのに使ってるんだぞ.つまり "tag_name" って変数の値が
"get_cmd" だったとすると,

:tag get_cmd

っていうコマンドが実行される事になるわけよ.

":execute" コマンドはコロンコマンド(colon commands)しか実行出来ねーから
な.":normal" コマンドを使えばノーマルモードのコマンド(Normal mode
commands)が実行出来るぞ.でもその場合は引数は式じゃなくって,コマンドと
なる文字だからそこんとこ分かっとくよーに.つまり,

:normal gg=G

ってやると,最初の行にジャンプしてから "=" の操作によって最後の行までを
整形するってわけ.

":normal" を式と一緒に使いたければ,":execute"と組み合わせればいいぞ.
つまり,

:execute "normal " . normal_commands

ってやればいい."normal_commands" に格納されてる値はノーマルモードの
コマンドになる文字じゃないとダメなのは当然な.

":normal"
コマンドへの引数は完璧なコマンドじゃなきゃダメだぞ.そーしねーと Vim は
引数の最後まで実行した後はそのままそのコマンドを終了しちまうからな.
 # つまり,引数で指定されたコマンド以上の事は何一つとして余計な事は
 # しないって意味でしょうな,たぶん.
例えば,挿入モードを始めて,そこから抜け出すなんて事も出来る.

:execute "normal Inew text \<Esc>"

これで,カレント行に "new text " っていう文字列を挿入するぞ.特殊キー
"\<Esc>" を使ってるところに御注目あれ.こーすれば実際のエスケープ文字を
スクリプトに書かなく済むわけだ.

50 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:滅入り苦しみます!! [01/12/24 23:16]
今日はこれだけにしときます.
あー,ヤダヤダ.世間様は楽しんでるんだろうなァ・・・



51 名前:実話 mailto:sage [01/12/25 00:07]
KoRoN さんは今ごろセックスにふけってますよ

52 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/26 00:53]
なんか一気にモチベーツョン下がった…
なんで漏れはこんななんだろう…
ハァ…………

53 名前:名無しさん@お腹いっぱい。 [01/12/26 01:03]
>>52
がんばってage

54 名前:あぼーん mailto:あぼーん [あぼーん]
あぼーん

55 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/26 02:19]
今日はなんかやる気無くしちゃったのでお休み.
明日からは忘年会地獄の三連荘(しかも女っ気ゼロ)だからたぶん連休になります.
ご容赦あれ.

>53
ぐすっ…うっうっうっ…こんなヲレに愛の手を…

56 名前:1 [01/12/27 00:29]
foo.vim にある DoSp() の解読。

" 文字列中の<C-U>のような特殊文字を解釈して値を返す方法(?)
fun! DoSp(str)
 let s = substitute(a:str, '.*\<C-U>', "", "")
 return s
endfun

:echo DoSp("Hello<C-U>World")
World

特殊文字<C-U>でHelloが消されたと。
でも <C-U> に意味があるんじゃなくて単に
"〜<C-U>" が "" に置換されただけちゃうんかと。
まーええか。寝よ。

57 名前:1 [01/12/27 22:24]
" 入力モードにおける入力文字列を評価。特別文字<C-U>および<C-N>のように、入力
" モードで実行されるでしょう。生の<Esc>特徴は予測不能の結果を生むでしょう(Exciteより)
fun! EvalInput(string)
 new
 execute "normal a" . a:string . "\<Esc>ggyG"
 q!
 return @"
endfun

new は新しいウィンドウ作成
execute は引数の結果をコマンドとして実行。詳しくは>>49
a:string の a: は引数を参照するから付ける。
. は文字列の連結。
string が "Hello" なら normal aHello\<Esc>ggyG が実行されて
Hello が入力されて先頭(gg)から最後(G)までをヤンク(y)。
ちなみに ggyG は ggVGy でもいいけどチョトかっこ悪い。
q! はウィンドウを強制的に閉じる。
@ はレジスタ参照 " はヤンクのされたのが入っとるレジスタ。それが戻り値と。

今回もなにに使うのかよくわからんスクリプトじゃった。

58 名前:1 [01/12/29 13:10]
引き続き foo.vim の解読。

" HTMLの対応するタグにジャンプする
fun! HTMLmatch()
 if getline(".")[col(".")-1] !~ "\\a"
  normal! %
  return
 endif
 execute "normal ?\\A\<CR>"
 normal lye
 if getline(".")[col(".")-2] == '/'
  execute 'normal ?<\s*' . @" . "\<CR>l"
 else
  execute 'normal /<\s*\/' . @" . "\<CR>ll"
 endif
endfun

nmap % :call HTMLmatch()<CR>

getline(".") はカレント行取得。col(".") はカーソルのカラム値取得。(なんで1か
ら始まるんだろう・・・) 正規表現 \a はタグ名にヒットさせる為の [A-Za-z] の事で
マッチしないと通常の % を実行。?は後方検索。\A は [^A-Za-z] だからタグの< の
部分に移動。lye はでタグ名に移動(l)してからヤンク(ye)。んでカーソル前が / な
ら終了タグなので ?で後方タグ検索。/ じゃなければ前方タグ検索と。

nmap はノーマルモード時に有効なコマンド割り当てで、% をタイプされたら
:call HTMLmatch()<CR>
が自動的に実行されると。

これは結構勉強になったなー

59 名前:1 [01/12/30 15:07]
バッファに入った時、自動的に HelloWorld ダイアログを出す方法。

augroup Foo
 autocmd BufEnter *.cpp call confirm("HelloWorld", "OK")
augroup END

augroup 適当なグループ名 〜 augroup END の中で記述。
autocmd の引数は順に、どんな時? 対象ファイル どうする?

この機能があるから拡張子に対応したシンタックスハイライトが
自動設定されたりするわけかぁ。
だんだんVimの謎が解けてきた。

60 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/30 18:06]
なんか結構簡単に書けそうな気がしてきた。
もうちょっと勉強してみます。



61 名前:1 [01/12/31 14:04]
引き続き foo.vim の解読。

class Klass { などとタイプすると、

//-------------------- class Klass
class Klass {
};

となるスクリプト。
まず発動の準備。

augroup Foo
 autocmd BufEnter *.cpp,*.h inoremap { {<Esc>:call ClassHeader("-")<CR>a
 autocmd BufLeave *.cpp,*.h iunmap {
 " Keep your braces balanced!}}}
augroup END

*.cpp または *.h のバッファに移動した瞬間に挿入モードの時に { を
タイプすると、どさくさに ClassHeader("-") を実行する。
バッファから抜けた時(BufLeave)には { での発動を解除。

fun! ClassHeader(leader)
 if getline(".") !~ "^\\s*class"
  return
 endif
 normal yyP$x
 let width = 80
 if exists("&tw")
  let width = &tw
 endif
 execute "normal " . (width-virtcol(".")-3) . "I" . a:leader . "\<Esc>"
 execute "normal a \<Esc>"
 execute "normal I//\<Esc>"
 " Keep your braces balanced!{
 execute "normal! jo};\<Esc>"
 normal k$
endfun

行頭に空白が含まれるかもしれない class がある行じゃなかったら終了。
で、行を二重化(yyP)して、行末移動($)して "}" を削除(x)。
widthはデフォルトで80にしたけど、tw オプションがあればそっちを有効に。
virtcol(".") は画面上のカーソルX座標。col(".") とはチョット違う。
で、"60I-<ESC>" みたいなのが実行されて - がたくさん挿入されて
"a <ESC>" は右隣に一文字スペース挿入して、下移動(j)、下に一行挿入(o)して
}; を入力して、上の行の最後に移動(k$)。

って、これじゃ読んでる人わけわからんだろうーな。

ちなみに tw オプションが 0 なら上のスクリプトは "-" を負の個数分挿入する事に
なってうまく動作しないので exist("&tw") && &tw != 0 にしたほうがいいのかも。

あと、ハイライトが崩れないようにコメントで調整しているところもポイント!

なんかスクリプトの要領が若干つかめてきた感じがするなー

62 名前:1 mailto:sage [01/12/31 14:08]
>行末移動($)して "}" を削除(x)。

>行末移動($)して "{" を削除(x)。
でした。

63 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [01/12/31 14:34]
>>61 Vim6向け補足

> *.cpp または *.h のバッファに移動した瞬間に挿入モードの時に { を
> タイプすると、どさくさに ClassHeader("-") を実行する。
> バッファから抜けた時(BufLeave)には { での発動を解除。

Vim6ではバッファ毎にマップを指定できるのでftplugin/c.vimに
(ftpluginはUNIXなら$HOME/.vim/ftplugin、Winなら$VIM/vimfiles/ftplugin)
 :inoremap <buffer> { {<Esc>:call ClassHeader("-")<CR>a
と書いておけば'filetype'が"c"の時に自動的に読み込まれる。だからaugroup Fooは
要らない。
# 'filetype'がcppの時は$VIMRUNTIME/ftplugin/cpp.vimの記述から'runtimepath'の
# c.vimが読み込まれるようになっているのでc.vimだけで良い。

あと<silent>フラグも指定すればマップ実行時にコマンドラインが汚れることもなくて
更にハッピー。例:
 :inoremap <silent> <buffer> { {<Esc>:call ClassHeader("-")<CR>a

64 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/31 15:57]
41.6 関数を使う

Vim は沢山の関数を定義してて,んでもって大量の機能を提供してるわけよ.
まぁちぃとばかりこのセクションで例を挙げてやろう.全部のリストは
|functions| を見ておくれ.

関数は ":call"コマンドで呼び出されるぞ.引数はカッコの中にカンマで区
切って渡すべし.
例)

:call search("Date: ", "W")

この例は search() 関数を "Date: " と "W" という引数を渡して呼ぶぞ.
search() 関数は最初の引数を検索パターンとして使い,二番目の引数をフラグ
として使うぞ."W" フラグはファイルの最後まで検索が行ったらもう上には
戻って来ないようにするフラグ(doesn't wrap around the EOF)な.

関数は指揮の中で呼ぶ事も出来るぞ.
例)

:let line = getline(".")
:let repl = substitute(line, '\a', "*", "g")
:call setline(".", repl)

getline() 関数は現在のファイルの行を得るぞ.引数には行数を指定すべし.
この場合は "." が使われてるけど,コイツはカーソルのある行っつー意味にな
るぞ.

substitute() 関数は ":substitute" コマンドと同じよーな事をするぞ.最
初の引数は関数を適用する文字列で,二番目の引数は置換されるパターン,
三番目が置換する文字列,そんで最後の引数にはフラグを指定すべし.

setline() 関数は第一引数で指定された行の内容を第二引数で指定された文
字列にセットするぞ.つまり,この例ではカーソルのある行の内容を
substitute()関数の結果で置き換えるようになってるわけだ.んだからこの
三行は

:substitute/\a/*/g

と同じ事をやるってわけね.こーやって関数を色々使えば substitute()
を呼ぶ前や後にもっと色々やって面白い事が出来るようになるぞ.

65 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/31 15:58]
<<<関数紹介>>>

まぁ沢山関数はあるわけなんだが,使用目的別にちょいと列挙してみようか.
アルファベット順のリストは |functions| を見てくれ. CTRL-] を関数名の
上で入力すればその関数の詳細なヘルプに飛べるぞ.

文字列操作:
 char2nr()  文字から文字コードを得る
 nr2char()  文字コードから文字を得る
 escape()   文字列中の文字達を'\'を使ってエスケープする
 strtrans()  文字列を表示可能な形に変換する
 tolower()  小文字に変換
 toupper()  大文字に変換
 match()   文字列中でパターンにマッチする場所を得る
 matchend()  文字列中で最後にパターンにマッチする場所を得る
 matchstr()  文字列中でパターンにマッチする文字列を得る
 stridx()   文字列に含まれる部分文字列の位置を得る
 strridx()  文字列に含まれる最後の部分文字列の位置を得る
 strlen()   文字列の長さを得る
 substitute() 文字列中でパターンにマッチしたものを置換
 submatch()  ":substitute" 中で特定のマッチを得る(n番目の括弧の中とかそーゆーヤツ)
 strpart()  部分文字列を得るget part of a string
 expand()   特殊キーワードを展開する(%=>現在のファイル名とか)
 type()    変数の種類を得る

カレントバッファのテキストに適用:
 byte2line()  あるバイト数の行番号を得る
 line2byte()  ある行までのバイト数を得る
 col()     マークやカーソル位置の列番号を得る(tab を 1 とカウントするとか)
 virtcol()   マークやカーソル位置のscreen columnを得る(tab を tabwidth 分だけカウントするとか)
 line()   マークやカーソル位置の行番号を得る
 wincol()    カーソル位置のwindow columnを得る(set nu の数字とかも含んでカウント)
 winline()   カーソル位置のwindow lineを得る
 getline()   バッファから行を得る
 setline()   バッファ中の行を置き換える
 append()    {lnum} で指定された行の後に{string}を追加する
 indent()    指定された行のインデント数を得る
 cindent()   指定された行のインデント数を cindent に従って得る
 lispindent()  指定された行のインデント数を lisp に従って得る
 nextnonblank()  次の空行でない行の行番号を得る
 prevnonblank()  手前の空行でない行の行を得る
 search()    パターンにマッチする行を得る
 searchpair()  find the other end of a start/skip/end # 対応する if とかを探すやつ.どう訳していいか分からん.

66 名前:ヘッポコ訳者 ◆xBY/hgW2 mailto:sage [01/12/31 15:59]
とりあえずちょっと復活.
でもなんかこの関数列挙あんま意味無いよーなあるよーな.
まぁ訳してるヲレ自身は詳細のヘルプ見たりして勉強にはなるから
いいんだけど.

67 名前:1 mailto:sage [01/12/31 21:32]
吉野家で「大盛りねぎだく玉」を頼んで
殺伐として帰る2chのイベントに参加してきたよ(w

>>KoRoNさん
補足どうもです。
バッファローカルで設定出来るってことは BufLeave での設定も
必要ないってことなんですかね。
ちなみにVim6スクリプトお勉強、といいつつマニュアルは
5.7の日本語化されたのしか読んでなかったりします(ぉ

>>へっぽこ訳者さん
やっぱり、人の作った(書いた)のを漠然と読むより自分で
調べた時に、身につくような気がしますねぇ。
でもまぁ、お勉強仲間がいると切磋琢磨できるので、
気にせずマイペースでカキコしちゃってください。

68 名前:名無しさん@お腹いっぱい。 mailto:sage [01/12/31 21:48]
今までQX一辺倒だったけどここ見て急にVIMが使ってみたくなったのです(●´ω`●)
ここに書かれてることスクリプトってWindowsでも共用なのですか?

69 名前:KoRoN@Vim%Chalice ◆ALICEsdk mailto:koron@tka.att.ne.jp [01/12/31 22:02]
>>67
おおお。で、どうでした?。殺伐としてましたか?。吉野家の「ねぎたく禁止令」はデ
マでしたか?。ちょっとレポートが聞きたかったり(苦笑)。なおBufLeaveでの設定も
勿論この例では要りません。

>>68
大丈夫です。使えます。Vimはキー操作が一般のエディタとはあまりにかけ離れてい
てきっと戸惑うこととは思いますが、幸運な出逢いであることを願っています。
日本語Windows版のダウンロードはこちらからどうぞ
 www.kaoriya.net/

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 すんげぇサイズ。
翻訳してくれてる人、大変だろうなぁ。






[ 続きを読む ] / [ 携帯版 ]

前100 次100 最新50 [ このスレをブックマーク! 携帯に送る ] 2chのread.cgiへ
[+板 最近立ったスレ&熱いスレ一覧 : +板 最近立ったスレ/記者別一覧](;´∀`)<368KB

read.cgi ver5.27 [feat.BBS2 +1.6] / e.0.2 (02/09/03) / eucaly.net products.
担当:undef