1 :
名無しさん@お腹いっぱい。 :
01/12/17 12:15 みんなでスクリプトを覚えよう
まずはHelloWorldから。 適当なファイル hello.vim とかに echo "HelloWorld" とだけ書いて :source hello.vim で実行 HelloWorld が表示されれば大成功!
4 :
名無しさん@Vim%Chalice :01/12/17 14:53
>>3 を見に行った。
emacs時代にこよなく愛していたlatex支援のauctexが
vim6に対応してた。
泣いた。ただただ泣いた。
さて、使ってみるか…
>>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:"、"&"、"$"等の文字で
始まる変数には特別な意味があります。しかし今はまだ覚えなくて良いでしょう。
なるほどー、なんとなく数値文字列から数値変換は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 な)
<<<三種類の数値>>> 数値は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 って事.
とりあえず help の Vim Script とかゆーところをボチボチ ウソ日本語訳でもかまそーかなと. 全角スペースでインデントしてあるのは良く分かんねーところ だから適当にツッコミよろしく. 今日はここまで.
:echo 1 2 1 2 :echo 1 -2 -1 なんで - をつけると演算されるんだー :echo 1 +2 3 ま、そういうもんか。 :echo 1/0 2147483647 あ、0で割れた!
>>10 ヘッポコ訳者 さん
それ英語でよんだけど、もう一度勉強させてもらいます。サンクス
>>KoRoNさん
eval.txt も参考にさせていただきます。
いいスレ
口調が v(^.^)v みたいでウザいとかそーゆーレスを期待(?) してたんだが・・・ # まぁヤツほどアレぢゃないけど > 1 echo 1 "-2" とかってやらんとダメみたいね.
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 で最初っから用意されてる変数 ってなぐらいかな.
とりあえず今はこんだけ. 夜暇が出来たら続きを出すカモ. ところでウィンドウローカルって何だ? っつーか Vim でのウィンドウって何だべさ? 文脈からするとバッファとは当然違うんだよな・・・ バッファが表示されてる時のみ有効とかそんな感じ?全然違う? help window ってやってもとんちんかんなのしか出て来ない・・・ # 何故ヲレの文章は階段状になっているのだろう・・・・・・・・・・・・
>>16 一つのファイル(バッファ)を編集中に:spすると分かれるのがVimのウィンドウです。
それぞれのウィンドウで:echo winnr()すると異なる番号が帰ってきます。
>>KoRoN 殿 あー,なるほど.そーゆー事ですか.そっかそっか. いつもウィンドウ分割(ってこの言葉使ってるぢゃん(藁) する時って 複数のファイル開く時 ばっかりだから気付かなかったでござるよ. なるほど,なるほど.ウィンドウサイズとかに使うんですな. お教えを賜わりましてありがとう存じ奉りまする.
<<<変数の削除>>> 変数はメモリを食ってて,":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 で真っつったらゼロ以外の事だぞ.んでもってゼロだけが偽な.
:let で全変数が見れるんかー。デバッグ時に便利そう。 :let hoge だと hoge だけの値が表示されると。 表示に # がついていたら数値らしい。 :let hoge=123 :let hoge hoge #123 :let hoge="123" :let hoge hoge 123
<<<文字列変数と定数>>> 今んとこまだ変数には数字しか使ってねーんだけど,文字列も使えるんだ ぜぃ. 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| にあるぞ.
>>21 うわ。気づかなかったけど何気に
> :let name = "\"mona\""
> :let name = '"KoRoN"'
とかなってるし!!。見過ごしてた(゜Д゜)
23 :
名無しさん@Vim%Chalice :01/12/20 17:42
vimメーラに期待age
>> KoRoN 殿 見つかってしまいましたか(藁 まぁ敬意を込めてのお遊びなんでお許しを.他意はありませぬ. 今日は忙しいから訳無し.スマソ.
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
今日はこれだけ. 忘年会シーズンは酔っぱらってる時はやらない方がいいカモ・・・
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:
とか書いたりはするけど(これはちゃんと効く)
ここはスクリプトの勉強スレなので一連(
>>27-28 )の質問がココにふさわしいかは疑
問ですが、折角ですから答えられる部分は答えてしまいましょう。
■ ◆Vim6 2スレ
http://pc.2ch.net/test/read.cgi/unix/1006246205/l50 >>27 完全なアウトラインプロセッサとは言えないのですが、folding(折畳み)機能を使え
ばスクリプトを駆使しなくてもそれに近いことが実現可能です。foldingというのは
テキスト中の指定された範囲を折畳んで隠す機能です。例えばプログラミングであれ
ば特定のブロックを隠したり、関数の実装を隠したりできます。またちょっと毛色は
違いますがテンプレートコンパイラを利用する方法も考えられるかもしれません。
■ テンプレートコンパイラの紹介
http://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でもなんでも書いてあれば有効になります。
modeline と fold ってけっこう組み合わせて使うよね。 KoRoN さんのサイトのソースなんか参考になるかもね。
32 :
名無しさん@お腹いっぱい。 :01/12/22 20:42
うわ、マジココイイわ。そしてマジコココイイわ。要するにイイ。
ほんとに初めてVimスクリプトをお勉強しょうとおもーとる人の為に書いとくけんな。
スクリプト読んどって解らん命令出てきたら何でもその上で K を入力じゃ
親切なマニュアルが飛び出てくるけん。んで閉じるのは Ctrl+wc
英語じゃわけわからんとかいう場合はこっち
http://ixeris.bios.ics.saitama-u.ac.jp/~noiz/gvim/ から日本語化してくれとるマニュアルを落として runtime/doc にコピーしときゃーええ。
それにしても日本語化を進めてくれとる人達には大感謝じゃなぁ。
# 酔っていると方言になります。
<<<演算>>> んで,まぁ上で挙げたよーな要素が結合とか出来たら面白い事が出来るでしょ. まずは数値の演算から行ってみよー!! 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) ってなってると思えばいいわけよ.
KoRoN 殿や mattn 殿に続けぇ〜!!!! #マダミチハトオイナ・・・ 今日もこんだけ.なんかアンマリススマナイナ
>>33 >日本語化してくれとるマニュアルを落として runtime/doc にコピーしときゃーええ。
日本語のヘルプすごく助かるけど、Version 6.0 で追加された項目が見れなくなっちゃうんだよね。
ウィンドウの縦分割について調べるときにはまった。
>>30 どうもありがとう。
vim6.0 使ってみましたが emacs のような高機能ぶりで驚きました。
スクリプト機能は emacs の elisp にあたると考えて良いのでしょうか?
>>37 難しい質問です。elispはemacsのベースとして存在しているのでまったく同様に捉え
られてしまうと間違いなのですが、エディタを制御したり内部の関数を利用できると
いう表面的な意味においては同じと考えても差し支えないでしょう。lispに比べれば
表現力に相当の制約がありますが、それでもいかにもvimらしい命令体系で強力なス
クリプトになっています。
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
<<<論理演算(っつーか単純な「比較」なだけなよーな)>>> まーいくつかは例の中で使って来たわけなんだけど,良く使われるのは 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秒間待機するってわけさ.
ハイ,クリスマスプレゼントは以上です(藁 ところで "LOGICAL OPERATION" って「論理演算」だよねぇ? これって僕の勝手な感覚では「論理和」とかあっちの方の意味 なんだけど,この感覚ってもしかして間違ってる?
全バッファに対して一括置換が行える便利スクリプトをマニュアルの中に発見しました。
: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 って感覚ですねえ。
>>38 わざわざどうもありがとう。
>>3 のリンクを見てなんとなく感じがつかめました。
今日から Vim Scriptor ということで宜しく。
スレ違いなのね ちょっと反省
call confirm("クリスマスイブ", "逝ってよし(´Д`;)")
さぁて、お勉強。 とりあえず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>はしらん。と。
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>" を使ってるところに御注目あれ.こーすれば実際のエスケープ文字を スクリプトに書かなく済むわけだ.
今日はこれだけにしときます. あー,ヤダヤダ.世間様は楽しんでるんだろうなァ・・・
KoRoN さんは今ごろセックスにふけってますよ
なんか一気にモチベーツョン下がった… なんで漏れはこんななんだろう… ハァ…………
53 :
名無しさん@お腹いっぱい。 :01/12/26 01:03
あぼーん
今日はなんかやる気無くしちゃったのでお休み. 明日からは忘年会地獄の三連荘(しかも女っ気ゼロ)だからたぶん連休になります. ご容赦あれ. >53 ぐすっ…うっうっうっ…こんなヲレに愛の手を…
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>" が "" に置換されただけちゃうんかと。 まーええか。寝よ。
" 入力モードにおける入力文字列を評価。特別文字<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! はウィンドウを強制的に閉じる。
@ はレジスタ参照 " はヤンクのされたのが入っとるレジスタ。それが戻り値と。
今回もなにに使うのかよくわからんスクリプトじゃった。
引き続き 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> が自動的に実行されると。 これは結構勉強になったなー
バッファに入った時、自動的に HelloWorld ダイアログを出す方法。 augroup Foo autocmd BufEnter *.cpp call confirm("HelloWorld", "OK") augroup END augroup 適当なグループ名 〜 augroup END の中で記述。 autocmd の引数は順に、どんな時? 対象ファイル どうする? この機能があるから拡張子に対応したシンタックスハイライトが 自動設定されたりするわけかぁ。 だんだんVimの謎が解けてきた。
なんか結構簡単に書けそうな気がしてきた。 もうちょっと勉強してみます。
引き続き 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 にしたほうがいいのかも。 あと、ハイライトが崩れないようにコメントで調整しているところもポイント! なんかスクリプトの要領が若干つかめてきた感じがするなー
>行末移動($)して "}" を削除(x)。 は >行末移動($)して "{" を削除(x)。 でした。
>>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
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() を呼ぶ前や後にもっと色々やって面白い事が出来るようになるぞ.
<<<関数紹介>>> まぁ沢山関数はあるわけなんだが,使用目的別にちょいと列挙してみようか. アルファベット順のリストは |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 とかを探すやつ.どう訳していいか分からん.
とりあえずちょっと復活. でもなんかこの関数列挙あんま意味無いよーなあるよーな. まぁ訳してるヲレ自身は詳細のヘルプ見たりして勉強にはなるから いいんだけど.
吉野家で「大盛りねぎだく玉」を頼んで 殺伐として帰る2chのイベントに参加してきたよ(w >>KoRoNさん 補足どうもです。 バッファローカルで設定出来るってことは BufLeave での設定も 必要ないってことなんですかね。 ちなみにVim6スクリプトお勉強、といいつつマニュアルは 5.7の日本語化されたのしか読んでなかったりします(ぉ >>へっぽこ訳者さん やっぱり、人の作った(書いた)のを漠然と読むより自分で 調べた時に、身につくような気がしますねぇ。 でもまぁ、お勉強仲間がいると切磋琢磨できるので、 気にせずマイペースでカキコしちゃってください。
今までQX一辺倒だったけどここ見て急にVIMが使ってみたくなったのです(●´ω`●) ここに書かれてることスクリプトってWindowsでも共用なのですか?
>>67 おおお。で、どうでした?。殺伐としてましたか?。吉野家の「ねぎたく禁止令」はデ
マでしたか?。ちょっとレポートが聞きたかったり(苦笑)。なおBufLeaveでの設定も
勿論この例では要りません。
>>68 大丈夫です。使えます。Vimはキー操作が一般のエディタとはあまりにかけ離れてい
てきっと戸惑うこととは思いますが、幸運な出逢いであることを願っています。
日本語Windows版のダウンロードはこちらからどうぞ
http://www.kaoriya.net/
71 :
名無しさん@お腹いっぱい。 :01/12/31 23:11
なにやら新ルール { つゆだくを頼むヤツがいたら鼻で笑ってやってください 牛鮭定食を頼むヤツがいたら舌打ちしてやってください }とさ
今日も吉野家逝ってきた。あえて牛鮭頼んだら 隣の奴がブチ切れだったららしい(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>は " をクォートしてくれていると。 そんだけ。 明日から牛の鳴き声が聞こえるような所に帰省します、、、。
なんか誤字が多いなー、牛乳飲も。
システム関数とファイル操作関数: 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() ウィンドウの変数を設定する
なんか訳しててあんま楽しくない個所なんで今日はここまで(苦笑)
陰ながら応援してますよ、がんばってください。
77 :
KoRoN@Vim%Chalice ◆ALICEsdk :02/01/03 10:39
>>75 eval.txtの翻訳の時、同じ気持ちになった(苦笑)
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() 外部ライブラリの関数呼び出し(戻り値が整数値)
やっとツマランところ終了. KoRoN 殿のような方々の辛さを実感(苦笑)
現在行から一番近い上か下のマークへジャンプするスクリプトを作ってみました。 皆様のおかげです。厨房くさいスクリプトですが思い切って、投稿してみます。 まずいとことかあったら教えてください。 行単位でしか見てないので、一行に複数のマークがあっても無視してます。 "マークにジャンプする 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 です。
折角公開してくれたのだから少し細かくコメントしましょう。こういうのは全く無反 応だと公開した方・使っている方、両方にとってためになりませんからね。 > 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の中では多用しているテクニックです。 私からはこんなところです。
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')
>>83 ナイスですねぇ。
> while i <= (char2nr('z') - char2nr('a'))
ここだけwhile i < strlen(markchars)としたほうが良いでしょう。
私は変数名を大文字で始めるのは避けるようにしています。ユーザ定義コマンドや関
数名は大文字で始めなければなりませんよね。それとかぶって見づらいかなと思うわ
けです。スタイルの問題なのですぐ宗教論争になってしまいますが一応参考意見とし
て。
>>KoRoNさん > 私は変数名を大文字で始めるのは避けるようにしています。 確かにです。私もそうしたいと思います。 ほんとにありがとうございました。 これから vim online に逝ってきます。
>>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" が実行されると。
逆転裁判(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" となると。
可変長引数の参照方法。 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 が参照出来ないのでエラーになった。
初めて見てみたけどわけわかんないっす。 「じゃあ来るな」はナシよ。
>>88 変数の有無のチェックにexists()を使う方法もあります。
>>89 確かにVimとは、Vimスクリプトとはなんぞや、
とかいうリンクは出てなかったかもしれませんね。
まとめてくれると嬉しいかも。
>>89 漏れもわけわからんで(w
ま、とりあえず
>>2 からやってみよう。
踏み出せばその一足が道となり・・・(略
>>91 ナルホド。a:0 >= 2 と書くより、場合によっては
読み易さを考慮(?)して exists("a:2") と書く方法もありと。
コメントの書き方って説明がまだ出てきてないみたいなんですけど " で始まる行がそうなんでしょうか?
>>68 です。
やっとhjklに拒絶反応が出なくなりました。先は、、長いですね、、(●´ω`●)
96 :
名無しさん@お腹いっぱい。 :02/01/09 22:17
勉強age
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
age
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ゲット!!」 だけじゃあんまりだから、ちょっとマメ知識を。 vimスクリプトで1行が長くなってしまった時に、改行を入れて先頭を \ にすると次 行に繋がっていると見なされる。C言語の行末の \ と一緒。 # なおvimスクリプトでは \ の直前の空白は無視されるのでインデント可能 ここまでは一般常識。ここからが本題。実は'cpoptions'に"C"フラグが含まれていな い時には、この \ が使えずエラーとなる。なので一般に公開したいスクリプトを書 くときには \ による行連結は使わないほうが良いかも。 # それともスクリプトごとに避ける設定があるのかしら?
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 すんげぇサイズ。
翻訳してくれてる人、大変だろうなぁ。
>>101 あ、逆でした。
>>100 は'cpoptions'に"C"が含まれる時には行頭の \ が連結の意味に
ならない、といので正しいです。
>>74 > resolve() ショートカット先を探す(MS-Win)
あれ〜・・・
bram氏、docの変更忘れてんのかなぁ・・・(^^;)
unix系はシンボリックリンクを解析するよう変更したはずのに・・・
と言っても訳は間違ってないのでsage
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 になると。ふぅ勉強になった。
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 そんなところ。
age
>>106 のViMail.vimを使ってみようとしたけど、
sendmail使っててCygwinだと無くて動かないようだから
練習でblatjに変えてみた。
BlatJ
http://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
>
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 をつけないとなぜか次の行にカーソルが飛ぶ。
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 は
必要無くなるような気がする。
foo.vim解読の続き。
ちなみにfoo.vimとはこれのことです。
http://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-]> を呼ぶと。
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のコメント生成とかにも使えるかな。
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
まっつんさんのcalender.vim、次のように設定すると日本語暦。
http://vim.sourceforge.net/scripts/script.php?script_id=52 let g:calendar_mruler = '睦月,如月,弥生,卯月,皐月,水無月,文月,葉月,長月,神無月,霜月,師走'
let g:calendar_wruler = '日 月 火 水 木 金 土'
これに加えて「平成14年」とか「皇紀2662年」
とかいう表記ができたらまさにパーフェクト(苦笑)
それだったら縦書きとか るせま読に左らか右 とかも出来るようにしないと。
きれいなカレンダーにびっくり
>>115 rightleft時にMBを正しく捌けるようにするか(苦笑)
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使ってます。
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 の中のコマンドが一気に実行されてハイライトが反映される仕組み。
>1 お疲れ様です。 # ちょっと前に、ハイライト表示の定義をしようとして出来なかったのですが # もう一回チャレンジしようかな?
>>118 > # calendar.vim使ってます。
どもです。
でも、実は使おうとおもって作ったわけじゃないんです。(^^;)
単に、cal を中呼びしてるスクリプトを見つけて、
「これならスクリプトだけでかける」と思ったのと
M-x calendar
があるなら
:Calendar
もあっていいかなと思って作り始めたのが、きっかけです。
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
>>122 > ... なんかEmacsに対抗して作ってる ...
って言いつつも
emacs21 + navi2ch
xyzzy + 2ch-mode
が何時でも準備OKな状態だったりします。(w
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 ってのを独自のオプションとして取り込めばいいのかなぁ。
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" ってやったら,それとは別の関数ローカルの変数になるっ てわけよ.
んで, ":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) って事ね.
ふぅ,お久しぶりでヤンス. 最近忙しいでヤンスよ. まぁ暇が出来たらまたちょくちょくやるっす. そんぢゃ.
お遊びスクリプト・・・ 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
Cygwin形式のパスをDOS形式に変換するスクリプトですかー とりあえず、 argadd - 引数リストにファイル追加 argdelete - 引数リストからファイルを削除 argdo! - 引数の全てのファイル対してコマンドを実行 を覚えました。 これらって5.7のマニュアルには見つからなかったから最近のコマンドかな。
余談ですけど、最近のCygwinってDOS形式(但しディレクトリセパレータは/)のパスを
受け付けますよね。おかげで'shellslash'との親和性がスゴク良い。
% ls d:/HOME/vim/vim60
とか出来ますから。
>>129 そうですね。6.0の新機能です。
:help new-argument-list
>>43 のAllargs関数を見つけた時はずいぶん喜んでたんだけど、
既にそれに代わるargdoってのがあったのかぁ。
それはいいとしてversion6.txt読んでたら gi って新コマンドを発見。
前回入力し終えた所にジャンプして i してくれる。これは(・∀・)イイ!!
関係無いかもしれんけど cygwinで cygpath っちゅうコマンドも便利だよ。 # 外出か?
糞みたいな残業強制させられて今タクシーで帰宅。 これじゃお勉強する暇ねーよ。あーあ。
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スクリプトかどうか分かんないんだけどステータスラインに 文字コードとか改行コードを表示させるって出来る? もしかして、関数つくって呼ぶとかそんな方法ですか? つか、自分で調べろって?・・・スマソ。
>>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行に入りきらなかった時にこの位置から表示する?? (再現できず)
%= - これ以降を右側に表示
あとスペースは \ でエスケープ
>>137 いやそうじゃなくて
文字コード = euc-jp, sjis, jis, utf8
改行コード = CRLF, LF, CR
を言いたかったのです・・・。
説明の仕方が悪かったですかね・・・。
>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 殿に教わったんだと思ったけど,こんな感じでどーよ? ゴチャゴチャ付いてるのはヲレのヤツそのまんまだからっつーことで御免 翻訳しなくっちゃなー
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 の時、その数だけバックスペースすれば が消える仕組みらしい。
ありゃりゃ消えとるがな。 &nbsp の事です。
142 :
名無しさん :02/01/29 00:41
Buf* の訳というか説明があるとイイナって思った。 BufNewとBufNewFileの違いが分からんし。
143 :
ヘッポコ訳者 ◆xBY/hgW2 :02/01/29 00:45
>142 さぁ,言い出しっぺの法則ぢゃ!!ガムバレ(・∀・)!!! # ヲレ今風邪で寝込んどる.スマソ
ウワー。 マジ勘弁。英語できないし。 誰かにパス。なんていうのはアマい(・∀・)?
>142 しゃーないのぅ autocmd.txt を見ると, BufNewFile: 存在しないファイルの変数を始めた時. スケルトンからの読み込み時でも使われる. BufNew: 新しいバッファを作成した直後. バッファ名をリネームした時にも使われる. バッファがバッファリストに追加された時は BufAdd も 実行されるぞ. 注::この autocommand が実行された時はカレントバッファ"%" はその時作成されようとしてる"<afile>" とは違うよん とりあえず上記二つはこんな感じかな
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
>>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
<<<範囲(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 をインクリメントしたりしないですよねぇ…? 風邪引いてるんで今日はここまで
>>149 試せばすぐわかりますがインクリメントはきっと必要でしょう。
# 丁度Transformもrangeの無い例になってて、タイムリーですなぁ
>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' になるのよ.
>152 ヘッポコ訳者さん、ありがとうございます。 試してみてわかりました。キャラクタ単位で複数の置換を一度にするって感じでしょうか? 風邪はやってますね。翻訳がんばってください。では
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の選択と 同じように選択後に何か入力すると選択部分が消えるモードらしい。
UNIXユーザへ送る条件演算子の応用 imap <silent> <c-\> <C-O>:let &iminsert=(&iminsert==2?0:2)<CR>
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をトグルする方法っすね。
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 解読は全部終わり。
> 1さん おつかれさまです。
これこそ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 を実行。「■なんとか」 の行が水色になったら成功と。 もうちょっと調べたいけど、もう寝ないとやべぇ。
スクリプト実行してるとき例えば exe "normal i\<C-D>" ってなってると i_CTRL-D が実行されるけど、 これってユーザー毎に Mapping を変更していたら違う結果が返ってくるよね? これを Mapping に依存せずに本来の動作をさせたいんだけど どうすればよいの?
sage が残ってた。 age
>>160 「!」を使ってこうします。
:exe "normal! i\<C-D>"
163 :
名無しさん@お腹いっぱい。 :02/02/06 00:41
>>162 おお、ありがとう
テトリス落としてやってたんだけどなんか表示が変だなって思って調べてたら・・・
案外こういうのっていいかげんに思われてるんですかねえ。
まあこういう(どんな環境でも動作させようという)意識の差っていうのは個人差があるんでしょうけど。
>163 テトリスって?検索したけどわからなかった。 vim でテトリス?
ありがとう、おもしろい。 こんなこともできるんですね。
167 :
名無しさん@お腹いっぱい。 :02/02/06 01:22
> Source it! To start the game, press <Leader>te. の <Leader> って何?
:h <leader> 設定してなければ\らしい
オレもよう分からんけどとりあえずノーマルモードで \te ってやったらできるぞ
>168,169 thanx!
171 :
名無しさん@お腹いっぱい。 :02/02/10 22:36
emacsの〜-modeみたいに、新しい言語のモードを作ろうと思った場合、 vimではどうやるんですか?
172 :
名無しさん@お腹いっぱい。 :02/02/10 23:02
>>171 :help ftplugin
:help mysyntaxfile
Tetrisに続いてSokobanなるゲームが(w まだ試してないけど。
>>173 遊んでみました。
j と k のマッピングが逆になってたから直さないとやり辛いよ(w
Tetirsと違ってソースは解り易く書かれててうれしいね
>>174 マッピングは明らかなミスですよね。まだアップデートされてないみたい
だけど。そんなことよりレベル1で258歩も歩いてしもた…。鬱打。
176 :
名無しさん@お腹いっぱい。 :02/02/17 23:29
age
カーソル行のフォールドが開いてるか閉じてるかを調べる関数、乃至 変数なんて無いですよね。今後実装されるかは別として。 何で聞くかというと、それで困ってる人がいるんですよ。winmanagerの 作者さんなんだけど。
>>177 See :help foldclosed() and its families.
スレ違いかな? ま、マルチポストは控えときます。
>>178 改めて、有難うございます。言い訳ですが、作者さんは、foldlevel という
関数はご存知でしたし、ずいぶん長いこと悩んでる様だったので、
てっきり調べ尽くしてるものと思っちゃいました。あと、今yahooのvim-ml
のアーカイブを見たんですが、すでにそこで回答を得られてたようです。
二重に失礼。
# もっとヘルプ読もう。
>>181 あ、今気付いた。なんか嬉しい。てか、また見ずに投稿(以下略
>>183 (>177)
刑法177条は(以下略)。昔、そういうゲームも(以下略)
>>184 > 刑法177条は
ガ━━(゚Д゚;)━━ン!せっかく気に入ってたのに…。
# 開き直ってコテハンにでもするか。
186 :
名無しさん@お腹いっぱい。 :02/02/19 00:11
Linux版のVIMの日本語判定をどうにかするスクリプト作って〜♥
>>186 「どうにかする」は「無効にする」もしくは「決め打ちする」と
解釈してよろしいでしょうか?
>>185 (177)
> # 開き直ってコテハンにでもするか。
漢を感じちゃった。カコ(・∀・)イイ!!
>>186 187の言う通り、どうして欲しいのかを具体的にハッキリさせてくれたら書く可能性
が高いです。というよりも、既に書いてある可能性も高いけど。
189 :
名無しさん@お腹いっぱい。 :02/02/19 22:06
>>188 私の環境では判定について特に問題はないので、
具体的にどういうときに誤判定するのか教えてくれないと
修正のしようがありません。
またeuc-jpの文がcp932の半角カナ文として認識されてしまうことがあるのは、
それは基本的には仕方のないことでしょう。
191 :
名無しさん@お腹いっぱい。 :02/02/19 23:17
Linux版だと確実にcp932とeuc-jpの判定に失敗する。 fileencodingsで先に書いてる方になっちゃう。
テキストの最初の方の行に「焼肉定食」と入れておくと吉かも 漏れはそうしてる(藁
>>191 2つおかしい点が。
1. encをeuc-jpにしている場合にはfencsにeuc-jpを含めるべきではない。
2. 「確実に」は疑わしい。
「euc-jpのファイルをcp932として誤読することがある」というならば納得します。
194 :
名無しさん@お腹いっぱい。 :02/02/23 00:46
∩ | | | | | | | | ∧_∧ | | / ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ̄ ( ´Д`)/ / < 先生!忙しいんですか? / / \________________ / /| / __| | .| | \  ̄ ̄ ̄ ̄ ̄ ̄ ̄\ ||\ \ ||\|| ̄ ̄ ̄ ̄ ̄ ̄ ̄|| ̄ || || ̄ ̄ ̄ ̄ ̄ ̄ ̄|| .|| ||
196 :
名無しさん@お腹いっぱい。 :02/03/02 01:50
空揚げ
ん?カラアゲ?.....どこだ?
ほとんど(全部に近い) KoRoN さんのおかげですが、現在行の URL を開くスクリプト。
chalice.vim から、OpenURL と DoExternalCommand を借りてくれば動くのでは?
win では動きました。
"
" 現在行に URL 文字列があるとき、それを取得しOpenURLへ渡す
" URL 文字列がない場合素の <CR> を実行
"
function! s:CheckURL()
let url = matchstr(getline("."), '\(
http://[-#%&+,./0-9:;=?@A-Za-z_~]\+\ )')
if url != ''
call <SID>OpenURL(url)
else
:exe "normal! \<CR>"
endif
endfunction
"map 定義
nnoremap <silent> <buffer> <CR> :call <SID>CheckURL()<CR>
既にありそうですね。
199 :
良スレ救済 :02/03/11 00:32
age
200 :
名無しさん@お腹いっぱい。 :02/03/16 21:24
1さん & ヘッポコ訳者さん 降臨希望age
201 :
名無しさん@お腹いっぱい。 :02/03/21 17:39
保全age
202 :
名無しさん@お腹いっぱい。 :02/03/22 00:38
指定した単語の個数を数える関数ってないですか? :g/pattern/let n=n+1 だと同じ行にふたつ以上あってもひとつとしか数えないので。
com! Test call <SID>VimTest() let s:foo = 'foo' fun! s:VimTest() python << EOF from vim import * foo = eval('s:foo') print foo hoge = 'hoge' buf = '"'+hoge+'"' command('let s:test='+buf) command('call s:Show()') EOF endfun fun! s:Show() execute 'echo s:test' endfun こうすれば、変数を渡せました。 出来たのでまとめとしてここに書いておきます。 KoRoN さんありがとうございました。
205 :
名無しさん@お腹いっぱい。 :02/03/31 00:46
age
>>204 せっかくだから趙治勲を倒せるvim scriptきぼんぬ
Calendarちとだけ機能追加...
let g:calendar_erafmt = '平成,-1988'
let g:calendar_mruler =
\'睦月,如月,弥生,卯月,皐月,水無月'.
\',文月,葉月,長月,神無月,霜月,師走'
let g:calendar_wruler = '日 月 火 水 木 金 土'
で
平成14/4(卯月)
日 月 火 水 木 金 土
1 2 3 4 5 6
7 8 9*10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
こんな風になります。
これがいっぱい設定できれば
>>114 > これに加えて「平成14年」とか「皇紀2662年」
> とかいう表記ができたらまさにパーフェクト(苦笑)
パーフェクトへ一歩近づけますか?(笑)
>>207 let calendar_erafmt = '皇紀,660'
とかやってみました。最高です!
('-`).oO○(ヒジュラ暦。。。
210 :
名無しさん@お腹いっぱい。 :02/04/11 05:54
211 :
名無しさん@お腹いっぱい。 :02/05/01 08:57
保守上げ
>>212 outlineMode.vim(・∀・)イイ!
関数の中にカーソルを置いてると勝手にその関数がハイライトされる…。はじめ
てCursorHoldなんてイベントを知りましたよ。
214 :
名無しさん@お腹いっぱい。 :02/05/08 06:55
>>215 > え、英語を添削させてくれーっ!!
KoRoN氏、確かどっかで英語のドキュメンタリスト募集してたから
more than welcomeと思われ
This plugin inserts and updates a time stamp automatically.
Users can specify a format and position of the time stamp by options.
By default, autodate.vim searches a keyword "Last Change: ."
in the first 50 lines of the buffer, and inserts a time stamp. Example:
Last Change: 07-May-2002.
添削に挑戦してみる。(
>>215 さんじゃないけど)
誰か英語力のある人が、とくにマルチバイト関連のやり取りで、バリバリドキュメントを
書いてくれるとうれしいかも。
追加。 autodate.vim の副題 >Custumizable auto update time stamp tool. Customizable
223 :
名無しさん@お腹いっぱい。 :02/05/15 15:45
すばらしい。
>>223 これはこれで便利だとは思うけど、ある程度大きいプログラムを扱う時は
そのファイルだけじゃなくて全てのファイルのタグが入ってないとあまり
意味がないような気も…
参照したい関数が編集中のファイル内にあることの方が珍しいので。
>>225 winmanagerに付属のタグ・エクスプローラってのはどう?
227 :
名無しさん@お腹いっぱい。 :02/05/19 04:35
Vimacs utility -1 1 Vim-Improved eMACS: Emacs emulation for Vim emacs.vim color scheme -9 553 Emacs like colors
>>227 いきなりマイナスに点数がつくんですよね(^-^;;;
vimacs では <M-x> は使えないんですか?
>>231 しらんけど、elisp動いてるわけでもないのに<M-x>使う意味あるのかなあ?
なんなら<M-x>を:にmapするとか
>>232 nmap <M-x> :
としてますが、動きません。
素早いレス thanx です。 emacs のように meta(alt) キーを使っての1ストローク は使えないということでしょうか?
>>235 完全に把握しているわけではないですが、端末の種類や設定などによって違ってきま
す。経験則ではterm経由だと<M->はEscなんとかにと記述してやる必要があります。
>>235 ソースをみましたが、
おそらく、<m-x> がマルチバイト文字のリードバイトと判断されて
いるため、トレイルバイトの入力を要求されているかと思います。
2回入力してませんか?
追記・・・ もし開発環境をお持ちならば以下のパッチを試してもらえますか? *** getchar.c~ Mon May 27 12:23:48 2002 --- getchar.c Mon May 27 12:23:38 2002 *************** *** 1843,1849 **** * multi-byte char. Happens when mapping * <M-a> and then changing 'encoding'. */ if (has_mbyte && MB_BYTE2LEN(c1) ! > (*mb_ptr2len_check)(mp->m_keys)) mlen = 0; #endif /* --- 1843,1849 ---- * multi-byte char. Happens when mapping * <M-a> and then changing 'encoding'. */ if (has_mbyte && MB_BYTE2LEN(c1) ! > (*mb_ptr2len_check)(mp->m_keys) && mp->m_keylen > 1) mlen = 0; #endif /*
>>238 当方、cygwin ですが、vimacs で m-x が使えました V(^_^)V パチパチ
>>238 開発環境がないのでリリースされるのを待ちます。m(_ _)m
>>240 ,
>>241 vim-dev には送ったんですが、bram 氏は今週カンファレンスらしくて
来週以降にみると返事が来てます。
よって来週になって、「ダメ」と言われるかもしれません。(^_^;)
リリースされるのはパッチですので、win32 ならば KoRoN 氏の NetupVim で
更新、それ以外のプラットフォームならば開発環境を用意して頂くことに
なります。
>>242 > リリースされるのはパッチですので、win32 ならば KoRoN 氏の NetupVim で
暫定的にまっつんさんのパッチを取込ませてもらいました。
う〜ん…まっつんさんのパッチあてたんだけど、たとえば :nmap <M-X> : がうまく出来ませんね。環境は香り屋版W2Kです。 :help map-multibyte にあるようにencをlatin1に設定してmapしてみたりもしたんですけど。 う〜ん…なんでだろ?
245 :
mattn@Vim%Chalice :02/06/04 18:59
>>244 Alt + Shift + x もしくは
:nmap <M-x> :
で動きませんか?
>>226 超亀レスですみませんが、ありがとうございました。
しかし、これ、ちょっと遅すぎるような。。。(褪
248 :
名無しさん@お腹いっぱい。 :02/06/07 14:09
現在分割しているウインドウの数を返す命令って何になりますか?
bufwinnr('$')
>>247 そうですねぇ。かなり欠点は多いかもしれませんが。逆に改善の余地は大
いにあるかもね。パッチ送ると喜ばれますよ。
>>248 一番ボトムのウィンドウに行って :echo winnr() ぐらいかなぁ。。
>>249 それは違うと思います。
251 :
名無しさん@お腹いっぱい。 :02/06/08 15:13
>249 >250 bufwinnr('$')では駄目でしたが、一番下のウィンドウでwinnr()は巧くいきました。 ただし、一番下に行く方法ってありますか? 安直かもしれないけど、ループさせて一番大きかった値が分割ウィンドウの数って 判定も出来るかもしれないけど…。
>>251 Ex command であれば、:wincmd b です。(元に戻るには :wincmd p)
詳しくは :h windows を読みませう。
253 :
名無しさん@お腹いっぱい。 :02/06/09 01:23
>252 ありがとうございます。 確認できました!
254 :
名無しさん@お腹いっぱい。 :02/06/21 19:36
保守。
自由。
高度なテクニックの紹介: コールバックの実装 2つのファイルを作りこのようなコマンドを実行する :so manager.vim :so callback.vim :call DoCallback() ----ファイル: manager.vim " コールバック関数登録用変数と関数 let s:procs = '' function! RegistFunc(proc) let s:procs = s:procs . a:proc . ';' endfunction " ダミーコールバック function! s:Dummy1() echo "Dummy1" endfunction " ダミーコールバックを登録 call RegistFunc('s:Dummy1') " コールバックを実行する関数 function! DoCallback() let mx = '^\([^;]\+\);\(.*\)$' let procs = s:procs while procs != '' let proc = substitute(procs, mx, '\1', '') let procs = substitute(procs, mx, '\2', '') if proc != '' && exists('*'.proc) call {proc}() endif endwhile endfunction ----ファイル: callback.vim " スクリプトIDを取得 map <SID>xx <SID>xx let s:_id = substitute(maparg('<SID>xx'), 'xx$', '', '') unmap <SID>xx " コールバック関数 function! s:Proc() echo 'callback.vim:Proc()' endfunction " コールバック関数を登録 call RegistFunc(s:_id.'Proc')
258 :
名無しさん@お腹いっぱい。 :02/08/14 01:55
winのみですが、vimからCMAIL WRITERでメール送信。ウマー
標準プラグイン netrw.vim を使って
:e
ftp://ftp.hoge/hage とやるとエラーになってしまいました。
:Nread
ftp://ftp.hoge/hage だとうまくいくのに。
'verbose' を設定してメッセージを出させ、それに従って netrw.vim を見てみると、
FTPを扱っているところで
exec "norm! mzoopen " ファイル...
となっています。
"mz" は後の操作のためにマークをつけているんだろうけど、
まず "o" が分かりません。新しい行を開いている?
そして "open" って何でしょう? :open なら obsolete なコマンドだとヘルプにありました。
どなたかお助け。
ちなみに、netrw.vim ではHTTPを持ってくるときにwget.exeを使う仕組みになっていますが、
Chaliceのために手に入れたcurl.exeを使うように手を加えてあります。
それがいけないのかな?しかしFTPにはftp.exeを使うので影響ないはず。
あぼーん
>>259 > "open" って何でしょう?
直接解決にはならないですけど、こういうことをやってるみたいです。
open servername port
username passwd
mode
get remote-filename local-filename
↑のようなコマンド行を生成し、その部分をftpに渡して実行、と。
なぜエラーになるかはちょっとわかんないっす。
ああ、"open" はFTPのコマンドでしたか。少し分かってきたような気がします。 完全に修正できたら報告します。 少し分かったのは、netrw.vimの " which the following blots out. Does Win-NT/98/2000 do the same??? exe "'y-3,'yd" というところでexeをコメントアウトするとよいことにはすでに気づきました。 何でもWin95のFTPには空行を勝手にくっつける癖があるそうで、 それを消そうとしているのですが、私のWin98のFTPではそんな癖がないのでいらないんです。 でもVimスクリプトではWin95とWin98の区別ができませんから、おかしくなっていました。
訂正っす。
.vimrc で let netrw_win95ftp = 0 とすると、
上記のコメントアウトは必要ありませんでした。
なんでこういう変数を Options: で説明しないで、
ずっと下の方の Variables: なんて項目に載せておくんだ?
netrw で FTP が使えないのは、BufReadCmd 内で
>>261 さんのおっしゃるような
コマンド文字列の生成ができていないためだ、という気がしてきました。
exe "'z+1,.!ftp -i -n" とすることで、
コマンド文字列を ftp.exe をフィルタ扱いにすることで送っているらしいですが、その前に
exe "'z+1,.w c:/windows/temp/cmdtmp"
exe "'z+1,.d"
を付け加えても、空行2行しか保存されません。この辺りが鍵?
こうした後に :r
ftp://hoge/hage としたときはちゃんとftp.exeに対するコマンドが ファイルに保存されるんですよ。こちらでは FileReadCmd を使っているので動作するのかな。
保守さげ
相変わらずわからんちんです。 学校始まって忙しいのであまりハックできない...鬱 Chaliceスレではw3m.vimネタがまた出たみたい。
vimスクリプトなんて書いたことないけど、し、質問があります。 ぼ、僕は正規表現厨房なので、 :% s/hoge11/moge :% s/hoge2232/moge :% s/hoge_3_3/moge ・ ・ ・ と連続して実行するのに、 上の文字列をどっかに記憶させて、それを読み込んで実行するって出来ますか?
>>266 先頭のコロンを削除して
%s/hoge11/moge
%s/hoge2232/moge
%s/hoge_3_3/moge
・
・
・
というテキストを作成しtest.vimとして保存します。
あとは :source test.vim とすれば実行できます。
詳細は :help :source を参照してください。
>>266 :%s/hoge11/moge^M^[:%s/hoge11/moge^M^[:%s/hoge_3_3/moge^M^[
と書いて、その行の上で、
例えば、
"aY
と入力する。
その後、実行したい時には、
@a
とする。
ぜんぜん関係無いけど、
>>269 みたいに今現在アクセスできない所も、
Googleの検索窓にURLを入れて検索すると、キャッシュでは見ることが出来ます。
(キャッシュがあればね)
>>269 のは、本人の説明はないが、
+---+----+-----+
| a | g | hig |
+---+----+-----+
| a | ss | s |
| b | s | i |
+---+----+-----+
こういうのを作るスクリプトのようです。
>>269 > こういったスクリプト向けにvimスクリプトは向いていますか?
向いているか向いてないか、という問なら間違いなく向いていません。配列やデータ
構造とかそういう高級な機能は一切ありませんから、ちょっと複雑なことをしようと
すれば作成側の知恵が試されることになります。そこが面白いところではあります。
望みの処理を行なってくれる既成の外部ツールがあるのなら、フィルタとしてそちら
を使うようにしたほうが利口なのは確実です。でもテーブル用スクリプトは既にどこ
かにあったような気もします。
ここはvimだった…… すみません。すれ違いでした。
275 :
名無しさん@お腹いっぱい。 :02/11/13 21:13
age
Vim scriptって便利そうですね。 今までキーレコーディングで満足してたから…。
>277 便利なの?
279 :
名無しさん@お腹いっぱい。 :02/12/02 23:20
vim初心者ですが、vim上でメール見れますか?
Windowsで香り屋gVimを使わせて頂いております。 起動するたびにcolorsディレクトリ以下にあるcolor schemeを ランダムに呼ぶVimスクリプトを作ろうかと考えています。 質問1)そんなスクリプト、すでにありますか?あるなら、どこにあるか教えて下さい。 質問2)俺には、そんなスクリプトを作るのは無理ですか? 質問3)もしかしてVimスクリプトに乱数って無いんですか? 当方、シロウトに縮れ毛が生えた程度の似非プログラマです。
秒数の1桁目を取得して擬似的に乱数をつくればいいんじゃなかろか。
>>281 > 質問1)そんなスクリプト、すでにありますか?あるなら、どこにあるか教えて下さい。
vim.sf.netを見る限りなさそうです。
> 質問2)俺には、そんなスクリプトを作るのは無理ですか?
それは自分で決めてください。できないと思ってしまえばどんな些細なことであって
も絶対にできません。逆にできると思えば大概のことはできるものです。あとはやる
かやらないか。
> 質問3)もしかしてVimスクリプトに乱数って無いんですか?
無いです。線形合同法等を使って擬似乱数生成関数を書くなり、もしくは外部ライブ
ラリを利用する必要があります。線形合同法についてはこちらを参照:
http://www.ysr.net.it-chiba.ac.jp/data/rand/node5.html
ヒントはtetris.vimにあり
たまにageると早速↑こういう目にあう。トホホ
(´・ω・`)…ゴメンなさい。
>>283 ありがと。
いきなり壁に突き当たってしまった。
let color = "evening"
colorscheme color
→カラースキームcolorが見つかりません
let color = "evening"
echo ":colorscheme " color
→:colorscheme evening(と下に表示されるだけ)
なんかヒント欲しいです・・・
>>289 :help :execute なんてどうでしょ。
>>289 let color = "evening"
execute "colorscheme ".color
:help :execute
>>290-291 ご教授ありがとうございます。
またVimスクリプトを書こうかなって思ったら、
またこのスレに来ますんでよろしくお願いします。
>>292 あらら、あったのね。どうもです。
早速使わせて頂きました。希望通りの動きでとっても幸せです。
>>293 おいしいスクリプトが出来たらvim.orgにうpしてね♪
現在のバッファの情報を外部アプリケーションに渡すには、一時ファイルを作ってそれを渡す というのが、Vim スクリプトの作法なのでしょうか? cvscommand.vimスクリプトってのを見てたら、そう思いました。
>>295 パイプで繋いでどうこうということは残念ながらできないので、
そういう情報が必要ならば一時ファイルを作ることになります。
引数だけで済む場面では勿論引数で済ませます。
>>296 あ、フィルタ使う方法はありますね。前書き込みのパイプ云々は外部コマンドと
動的にインタラクションするということを頭の片隅に置いた上での発言と読んでください。
まぁ、最終的にどれを使うかは個人の裁量です。作法とかそういったものは気にせず、
その時一番efficientだと思えた方法を使うのが吉でしょう。
いろいろ調べてみましたが、そのようですね。 とりあえず、現行の編集ファイル (バッファではない) に対して、 やりたいことができるようになってから考えます。
300
>>301 225じゃないけど、土日に試して見る。
sokoban.vimはxsokobanと同じだった。
vimスクリプトに配列ってありますか?
>>305 配列そのものは無いです。が、ダミーバッファに対してsetline()/getline()を使っ
たり、{}記法を使うことで代用品を仕立てることはできます。後者は次のような感じ
で使います。
:let index = 2
:let array_{index} = "some string";
:let index = 3
:let array_{index} = "another string";
:echo array_2
some string
:echo array_{index}
another string
あと、これはVimに閉じないのですがif_perlやif_rubyを使う方法も考えられます。
307 :
名無しさん@お腹いっぱい。 :02/12/26 00:21
emacsでいうところの vc-mode のようなことをvimスクリプトで実現した 例はあるのでしょうか。
>>308 searchの使い方が分かりました :)
どちらかというと欲しいのはRCSに対するものです。emacsのものだと、
- RCSのファイルが転がっていると自動的にRCSモードの表示に
- C-x C-q で write-protectedを解除 → co -l foo
- 修正後 c-x c-q で write-protectedに → commitメッセージを聞いてきて
C-c C-c で ci -u -m"メッセージ" foo
てなことをやってくれるようなんです。
vimで
- ファイルオープン時に実行されるフック
- set readonly状態の時に何かバッファを修正したら実行されるフック
- set readonly状態を変更したら実行されるフック
があればなんとかできそうかなと思います。
HTML で困るものをエスケープするスクリプトを書いたんですが、 範囲選択の後に :'<,'>call HtmlEscape と入力しなければならないです。 そうじゃなくて、:'<,'>HtmlEscape にするにはどうすればいいの? # command あたりがあやしかったがわからなかった... if exists("loaded_html_escape") finish endif let loaded_html_escape = 1 function HtmlEscape() range let index = a:firstline while index <= a:lastline let line = getline(index) let line = substitute(line, "&", "\\&", "g") let line = substitute(line, "<", "\\<", "g") let line = substitute(line, ">", "\\>", "g") call setline(index, line) let index = index + 1 endwhile endfunction
>>310 :command! -range HtmlEscape <line1>,<line2>call HtmlEscape()
多分こんな感じです。
:help E177
E177 のヘルプ見たのにー! そうか。 <line1>と<line2>はそうやって使えばいいのか。 これで年が越せます。ありがとう!>KoRoN 氏
別もんですよん
315 :
名無しさん@お腹いっぱい。 :03/01/05 15:23
>>315 そういえばデフォルトでgzip.vimってのがはいってるね。
vim素人の私は最近、zcatってコマンドライン覚えたよ。 こういうのがエディタ上から、呼び出せるのはvimのいいところね。
(^^)
alias Info="vim -c 'source hoge/info.vim|Info'" 便利です
激しく禿同
最近スクリプトを覚えようと思って、この板にやってきました。
mattnさんの
>>128 を試しているんですが、
silent argdo! rewind
のラインを
silent argdo! rewind!
にしないとE37が出たり gvim ~/vimrc が開けず、でもrewind!にすると
after/ftplugin/ 以下が読みこまれないという症状に悩まされています。
上記スクリプトを.vimrcのどの位置で定義するのかにも関係するんですかね?
:h rewind しても良くわからなかったのでカキコしてみました。
KaoriYa タンのは FreeBSD PORTS には入らんの?
微妙に誤爆。スマソ
326 :
名無しさん@お腹いっぱい。 :03/02/10 00:32
file(*.vim)はどこに置くの?
>>326 OSによって違う。UNIXっぽいシステムだったら、
~/.vim/plugin/
あたり。システムグローバルは :echo $VIMRUNTIME あたりに。
328 :
名無しさん@お腹いっぱい。 :03/02/10 00:42
linuxだけど、好きなところには置けないですか?
>>328 .vimrcでその「好きな所」を
set runtimepath+=好きな所
すれば好きな所に置けるけど、~/.vim/plugin で問題ある?
嘘。runtimepath+=hoge だったら、hoge/plugin/ だな。
正規表現で制御文字そのものを表すatomって無いんでしょうか? <Esc>, <Tab>, <CR>, <BS>は既に存在する(\e, \t, \r, \b)んですが、 ^Jなどは表現できないですよねぇ…? 例えば、レジスタaに入ってる文字列から<Ctrl-J>を削除しようとした時に substitute(@a, '^@', '', 'g') のように、関数内で<Ctrl-V><Ctrl-J>して直接char codeを入れちゃうと 実行時にエラーになってしまうので… # ^@の部分が<Ctrl-V><Ctrl-J>です。 # ^@は改行を意味するのでsubstitute()の呼び出しが無効になります。 <Ctrl-V><Ctrl-J>の代わりに\rや[:cntrl:]で置換しようとしてもできませんでした。 文字を直接ascii codeで指定できたりすると良いんですけどね… \0x0a (← ctrl-J)みたいな感じで (\0x61なら'a'になるみたいな)
>>331 Chalice内のplugin/alice.vimにあるAL_firstline()とかが参考になるかもしれませ
ん。レジスタ内の改行記号^Jには"\<NL>"が対応します。このあたりはVimが文字列を
どのように扱っているかを知っていれば至極当然なのですが、知らないとかなりメン
ドイので以下のように慣用句として覚えてしまうのが良いでしょう。
substitute(@a, "\<NL>", '', 'g')
331です。
>>332 KoRoNさん、解説どうもありがとうございました。
とりあえず納得はしたのですが、"至極当然"とか言われちゃうと
どうしても文字列をどのように扱ってるかが気になってしもたので、
vimのsource codeを見てみましたが、漏れには解析追いつかずでした… (´Д⊂グスン
しかし!
trans_special()が定義されているmisc2.c内で偶然<Char->の存在を知り、
:help <Char->
を見ると、なんと!ロトのつるぎを見つけた! …じゃなくて、
漏れが
>>331 で
> > 文字を直接ascii codeで指定できたりすると良いんですけどね…
> > \0x0a (← ctrl-J)みたいな感じで (\0x61なら'a'になるみたいな)
と言っていた機能が既に有るではないですかぁ!
てことで、
substitute(@a, "\<Char-0x0a>", '', 'g')
と書いても
> substitute(@a, "\<NL>", '', 'g')
これと同じ動作になることが確認できますた。 ヽ(´▽`)ノ
<Char->は元々multi-byteを扱うのに便利な機能として用意されていたらしいですが、
これなら\e, \t, \r, \b以外の制御文字も(知ってればですが)扱えますね。
あまり綺麗じゃありませんし、素人にはお勧めできない諸刃の剣かもしれませんが…
# もしかして反則技ですか?
あ! ASCIIじゃなくてEBCDICの時に使えないですね…
# 早くもダメケースをハケーンしてしまった… ΣΣ(゚д゚lll)ガーン!!
もっかい331です。
>>332 ついでに…
余談ですがregexp.cのbackslash_trans()で
\r, \t, \e, \b の振る舞いが書かれてますね。
あくまで仮の話になりますが、
static char_u REGEXP_ABBR[] = "nrtebj";
というように、jを加えて
case 'j': return NL;
のようなcaseを1個追加するだけで、正規表現として
\j が <NL> にマッチする
といった動作になったりするんですかね…?
# 考えが浅はかかな?…
んー。なんかスレ違いになってきちゃったかな? ^^;
これぢゃVim6ソースコードお勉強スレですな(w
335 :
名無しさん@お腹いっぱい。 :03/02/20 19:42
autocmd BufReadPost * \ if line("'\"") > 0 && line("'\"") <= line("$") | \ exe "normal g`\"" | \ endif vimrc_exampleのこの部分ですが、2行目と3行目の最後の|はなんですか? それと g`\"のgはなんのためにあるのですか?
| はコマンドの連結 g を前置するのはジャンプリストを変更しないようにジャンプする
>>336 autocmdだから1行にする必要があるのですね。
gの方は:h g'にありましたね。ありがとうございます。
>>337 1行にするのは行頭の '\' の働き.
'|' は,本来autocmdで実行するのは単一のコマンドだから,
複数のコマンドを実行するために連結が必要になっているということ.
質問があります。 vimのevalはかなり高機能なので、スクリプトインタプリタとして 使用してみようと思い、いろいろ試行錯誤してみたのですが、 そもそも、echoが標準出力に出力できないです。 どうすればできるのでしょうか?
多分標準出力には出せないと思われます。 一時ファイルを使うのが良いでしょう。
>>341 了解しました。
perlやpythonが使えるので、逆にevalが独立して
スクリプトインタプリタとして使えると楽しめそうなんですが。
あと、ソケットをたたくAPIが追加されるとChaliceが完全に
evalだけでできそうだし、いろいろできそうなんで、ぜひ
追加してほしいもんです。
既に備わってるlibcall()で(間に自作DLLをはさめば)ソケットが使える...かもね。 ただ標準DLLを呼ぶには力不足、とかマニュアルに書いてあるしなあ。 Vimはマルチプラットフォームが原則だから,難しいんじゃないの? でもソースがあるんだから自分で追加というのもできないことではない.
perl使えばいいじゃん
>>344 それじゃVIMを使う意味もないと思う。
>>343 Unix,Mac,Windowsで動くマルチプラットホームなソケットライブラリ
はいくつも存在するから、ようはBramの気分次第のような気がしないでもない。
そのときには、evalはどういう感じになるんだろう。いまいち想像つかないが。
まぁ、いつの日か、
+socket
が表示される日を夢見てevalをいじくるとしよう。
>>347 あ、本文の方が無いんですね(^-^;
そこのサイトマスター、友人なので執筆のお願いしてみましょうか?
2get!
私昨夜3getしたみたいです。
>>348 せかさなくて、いいです。更新直後のようですから。
今後の更新をのんびり待ちます。期待して。
354 :
名無しさん@お腹いっぱい。 :03/04/05 00:13
http://www.vim.org/scripts/script.php?script_id=356 db_ext というプラグインを使おうと思ったのですが、途中で
if exists("g:default_db_ext_{b:db_ext_type}_cmd_terminator")
という行があって、
b:db_ext_type = 'PGSQL' なんかの時に、g:default_db_ext_PGSQL_cmd_terminator
について exists() したいんだと思うのですが、そのようには動いてくれません。
つーか、そのように動かなくて正解のような気がするんですが、
実際どうなんでしょう。なんか設定とかバージョンとかなんでしょうか。
6.1.255あたりのパッチでcurly braces変数がexists()で評価できるようになったと思う。
>>355 できました。サンクスコ。
ところでスクリプト作るのって、ちょっと書いて :source して、、、ってやるんでしょうか?
例えばバッファ内のスクリプトを保存せずに実行する方法とかあるんでしょうか?
vim スクリプトの開発/デバッグのテクニックとかあったらおしえて下さい。
>>356 > 例えばバッファ内のスクリプトを保存せずに実行する方法とかあるんでしょうか?
そういうスクリプト書いちゃえばできないことはないですが、
だったら適当な名前で保存して :so% したほうが手っ取り早いです。
(^^)
あぼーん
360 :
名無しさん@お腹いっぱい。 :03/04/24 19:40
♥
Chalceで学んだことですが、スクリプトでバッファを変更する時に、一時的に undolevelsを-1にするのは非常にナイスなアイデアですよね。一回のundo分でも 無制限にメモリを消費できてしまうわけですからね。vim標準のgzip.vimとか、 いろんなスクリプトでこれをやってほしいなぁ
x Chalce o Chalice
363 :
名無しさん@お腹いっぱい。 :03/05/15 11:54
emacsであるような、ChangeLogの作成を支援してくれるような vimスクリプトってありませんか??
あぼーん
+,-などの記号を入力したときに両側にスペースを入れたいです。 そのときすでにスペースが入っていたらスペースを入れないようにします。 それで次のような関数を作ったのですがうまくいきません。 というかvimスクリプトがぜんぜんわかりません。 直してください。 inoremap <buffer> ( <c-o>:call InsertSpace()<cr>( inoremap <buffer> , <c-o>:call InsertSpace()<cr>,<space> inoremap <buffer> + <c-o>:call InsertSpace()<cr>+<space> inoremap <buffer> - <c-o>:call InsertSpace()<cr>-<space> inoremap <buffer> * <c-o>:call InsertSpace()<cr>*<space> inoremap <buffer> / <c-o>:call InsertSpace()<cr>/<space> inoremap <buffer> = <c-o>:call InsertSpace()<cr>=<space> function! InsertSpace() if strlen(getline(".")) == col(".") if strpart(getline("."), col(".")-1, 1) != " " normal a endif else if strpart(getline("."), col(".")-2, 1) != " " normal a endif endif endfunction
>>367 まず、
getline(".")[col(".")-1]
みたいに、配列を使ってみたら。
>>367 とりあえず、それっぽく動くのができたよ。
inoremap <buffer> + <C-O>:call InsertSpace('+')<CR>
function! InsertSpace(chr)
let left = getline(".")[col(".")-2]
let right = getline(".")[col(".")-1]
if left == ' ' && right == ' '
execute "normal i\<C-V>".a:chr."\<Right>"
elseif left != ' ' && right != ' '
execute "normal i \<C-V>".a:chr." \<Right>"
elseif left != ' '
execute "normal i \<C-V>".a:chr."\<Right>\<Right>"
elseif right != ' '
execute "normal i\<C-V>".a:chr." \<Right>"
endif
endfunction
>>369 ありがとうございました。すごく勉強になります。
しかし、行の最後にいるときにうまくいきません。
場合分けしたのですが、最後の\<Right>がうまく機能しません。
function! InsertSpace(chr)
let left = getline(".")[col(".")-2]
let right = getline(".")[col(".")-1]
if strlen(getline(".")) == col(".")
if right == ' '
execute "normal a\<C-V>".a:chr." \<Right>"
else
execute "normal a \<C-V>".a:chr." \<Right>"
endif
else
if left == ' ' && right == ' '
execute "normal i\<C-V>".a:chr."\<Right>"
elseif left != ' ' && right != ' '
execute "normal i \<C-V>".a:chr." \<Right>"
elseif left != ' '
execute "normal i \<C-V>".a:chr."\<Right>\<Right>"
elseif right != ' '
execute "normal i\<C-V>".a:chr." \<Right>"
endif
endif
endfunction
>しかし、行の最後にいるときにうまくいきません。 ほんとだ。σ(^◇^;) >場合分けしたのですが、最後の\<Right>がうまく機能しません。 ほんとだ。(?_?) これはちょっとわからないな。ちょっと調べてみるけど、 あてにはしないでね。なんか仕様っぽい気もするし。
違うアプローチで作ってみました. 挿入モードで演算子を入力するとスペースを挿入します. # コマンドモードに戻る必要はありません. ●注意事項 プログラミング言語の仕様に+と++のような同じ文字を使った 二種類の演算子がある場合は両方をmapして下さい. 第2引数でスペースを入れるかどうかを指定します. これにより,++の時はスペースを入れない,==の時はスペースを入れる といった使い分けが出来ます. スペースを入れない仕様は意味が無さそうですが,+をmapして++をmapしないと, ++が入力できなくなってしまうので仕方なくこういう仕様にしました. ●1点だけごめんなさい項目があります. 行頭ではmapした記号を入力できません. ただし,一般的にはインデントを入れるので気にならないでしょう. " 両側にスペースを入れたい演算子をmappingする inoremap <buffer> <silent> + <Esc>:call InsertSpaceOnBothSides('+', 1)<CR>a inoremap <buffer> <silent> - <Esc>:call InsertSpaceOnBothSides('-', 1)<CR>a inoremap <buffer> <silent> * <Esc>:call InsertSpaceOnBothSides('*', 1)<CR>a inoremap <buffer> <silent> / <Esc>:call InsertSpaceOnBothSides('/', 1)<CR>a inoremap <buffer> <silent> % <Esc>:call InsertSpaceOnBothSides('%', 1)<CR>a inoremap <buffer> <silent> = <Esc>:call InsertSpaceOnBothSides('=', 1)<CR>a inoremap <buffer> <silent> ++ <Esc>:call InsertSpaceOnBothSides('++', 0)<CR>a inoremap <buffer> <silent> -- <Esc>:call InsertSpaceOnBothSides('--', 0)<CR>a inoremap <buffer> <silent> == <Esc>:call InsertSpaceOnBothSides('==', 1)<CR>a
" 演算子の両側にスペースを入れる function! InsertSpaceOnBothSides(operator, isspace) let pre_str = strpart(getline("."), 0, col(".")) " 行の前半 let post_str = strpart(getline("."), col(".")) " 行の後半 if a:isspace == 1 if strpart(pre_str, strlen(pre_str)-1, 1) != ' ' let pre_str = pre_str . ' ' " 前半最後にスペース挿入 endif if strpart(post_str, 0, 1) != ' ' let post_str = ' ' . post_str " 後半最初にスペース挿入 endif endif " 前半と後半の間に演算子を挿入 call setline(".", pre_str . a:operator . post_str) " 次の挿入位置へ移動 if post_str == matchstr(post_str, '\s*$', 0) " 演算子挿入位置が行末の時 let motion_cmd = 'normal $' " 行末へ else let motion_cmd = 'normal 2wh' " 演算子を飛ばして次の単語の1文字前へ endif execute motion_cmd endfunction
歩野?
>>372-373 ありがとうございます。
後半ちょこっと変えてみました。
function! InsertSpaceOnBothSides(operator, isspace)
let pre_str = strpart(getline("."), 0, col(".")) " 行の前半
let post_str = strpart(getline("."), col(".")) " 行の後半
let move = 2
if a:isspace == 1
if strpart(pre_str, strlen(pre_str)-1, 1) != ' '
let pre_str = pre_str . ' ' " 前半最後にスペース挿入
let move = 3
endif
if strpart(post_str, 0, 1) != ' '
let post_str = ' ' . post_str " 後半最初にスペース挿入
endif
endif
call setline(".", pre_str . a:operator . post_str)
exec "normal " . move . "l"
endfunction
あぼーん
大手4紙のサイトにアクセスして、ヘッドラインをだけ抜き出し表示するスクリプトを
作りました。
http://www.kaoriya.net/testdir/headline.vim curl, alice.vim, +iconvが必須です。つまりChaliceを使っている人ならば、プラグ
インのディレクトリにスクリプトを置くだけで簡単に導入できるでしょう。導入後は
:Headline Asahi
:Headline Yomiuri
:Headline Sankei
:Headline Mainichi
とすることで各紙のヘッドラインが表示されます。指定する名前はasaやyomiのように、
多少の揺らぎがあっても大丈夫です。今は4紙のみの対応ですが、拡張性を考慮して設
計したので、少しの労力で他のサイトにも応用できるでしょう。興味がある方は試して
ください。
あぼーん
うう、KoRoNさんに「Vimから出ない人」にされちゃうよー nikkei.co.jpは「宿題」?
>>379 是非書いてください。<nikkei.co.jp
日経はコメント使ってマーキングされているから
やりやすそうですねぇ。
あぼーん
scriptencoding cp932を headline/以下にも書いてほしいんだけど。
388 :
名無しさん@お腹いっぱい。 :03/06/01 11:23
info.vimでinfoをみてるときにhおすとヘルプ(?)がでてしまうんですが…
hで左に移動できないじゃん。
そろそろg:chalice_curl_optionsみたいなcurlオプションキボーン 防火壁ナノネン. . .
>>395 > KORABORESHON with Mr. まっつん. It is Japanese-English translation using Excite.
コラボーレーションは無いよなぁ…(´・ω・`)
>>395 ご苦労様です。
早速試してみたところ、なんかエラーが出ましたが翻訳出来ました。
出てきたエラーはこんな奴:
E177: 未知の関数 AL_echo
33 call AL_echo('Translating...', 'WarningMsg')
良く分からなかったのでコメントアウトしちゃいました。
多分、うちの設定が悪いかなんかのせいだと思うのですが、
一応使ってる奴のバージョンをご報告しておきます。
香り屋版 Windows用y gvim V6.1
適用済みパッチ: 1-474
>>398 訳が出てくるということはcurlは入っていると思われ
>>398 ありがとうございます。
ご指摘通り、chaliceのバージョンが古いせいでした。
v1.7を使用していたのですが、
v1.8に上げたところ、エラーが出なくなりました。
お騒がせ致しました。
いや、それにしても、このプラグインは便利ですね。
感謝感謝です。
前からtweakが公開されれば、KaoriYa版からキャプション機能を削除しても良いかなぁって考えていたんです。 でもtweakでキャプションを消すとテキストエリアのウィンドウがズレることが発覚。どうしよ。
ウィンドウがズレるのは、ちょっとやだなぁ。 てか、キャプションってなんですか? Windows版で、透明度がうんたらっちゅーやつですか?
>>404 Windowsではタイトルバーというのが分かりやすいでしょうか?。
香り屋版を使っているならば :set guioptions+=C してみれば一発でわかります。
なお戻すには :set guioptions-=C
.gvimrcに、 syntax match Trailing "\s\+$" highlight link Trailing Error と書いたのですが、うまく反映されません。 なんかfiletypeとかsyntaxかがないときだけうまくいく感じです。 いつでも反映されるようにしたいのですが、 どこが間違っているんでしょうか。
>>406 Vimの基本的な動作に対する理解が足りない、のが原因です。syntaxはその型のファ
イルを開いた際に毎回設定され、その設定開始前に必ず:syntax resetかそれ相当の
処理が行なわれています。そのため起動時に1度だけ実行される.gvimrcの設定はその
時点で上書されてしまい、効力を発揮することはありません。
そんなわけなのでsyntaxの設定が終わった後に、それらの設定が追加されるように
autocmdにSyntax等々を組み合わせてみるのが良いでしょう。以下はその例です。た
ぶんこのままでは思い通りに動かないので適当に修正してみてください。
function! s:TrailingError()
syntax match Trailing "\s\+$"
highlight link Trailing Error
endfunction
autocmd Syntax * call s:TrailingError()
まぁそういうおまいも vi に対する理解があるとはとても おもえんのだが。いいかげんやめたら?
タイミングだからゆうぞ。はっきりあんた臭い。コードの占有意識高すぎ。 やることがいちいち SHIFT-JIS 臭い。 architecutre dependentily. 抱える人間としては最悪に近い。 あんたが vim を手放せば一年の停滞はあってもトータルでみな 幸せになると思う。そうおもったことはない?
>>408 >>409 まぁまぁ、vimに貢献しているのは間違いないんだから。
ただ、KoRoNさんもこのスレだけじゃないんだけど、発言にトゲ
があることを自覚してないんだろうな。
>>405 タイトルバー 消えたーー
なるほど、よう分かりました。
これで更に1行多く表示できる。 新たな発見だわぁ…
KoRoN氏は別に嘘ついたりはしてないだろ。 時々ずばっと言った真実に、自分が痛いヤツだって ことを指摘されたくせに、それを認めたくない厨ども には嫌な人に見えるかもしれんが、それだけのこと。 現実を見ずに出る杭を打ちたいだけの馬鹿は氏んでいいよ。
>>412 自分より頭のいい人間に、「おまえ馬鹿だな」と言われて
その人間をやな奴と思うのは普通だと思うが。
そのやりとりを聞いている周りの人間もイヤな気分になるのも
普通だと思うが。
そもそも、たかが掲示板で人を否定する必要はないはずだが。
いや、匿名の掲示板だからこそ否定することができるのか。
ここは、厨房お断りのスレなのか?
だったら、「vim用のくだ質」みたいなものを作らなきゃダメかな。
まぁ、そういう感情を理解せずに、論理的に肯定しようとする
お前こそいい人ぶろうとしているだけだろう。
自分ができるから当然ほかの奴もできるだろみたいに思っている
奴ほど最低なものはないからな。
>>413 ちょっとやめて頂けませんか。見苦しい。
>>413 どこが間違ってるか聞いたら、間違ってる箇所を指摘してくれただけでしょ。
言い方が気にくわない人がいるのはわかるけど、気にくわなくない人まで
否定する姿勢は見苦しいよ。
> そもそも、たかが掲示板で人を否定する必要はないはずだが。
そうですねぇ、本当に。
416 :
名無しさん@お腹いっぱい。 :03/06/24 01:25
>>408 なぜにvi?
KoRoNさんは、viに対する理解といってないが。。
保存してないバッファでZoomWinを使うと、 バッファが/tmp/v012345/0になってしまう。
>>407 もう一つ
応用的な(略
があれば原因は100%特定出来そうだなw
同じキーに2つ以上mappingされている時に 片方だけをunmapすることは出来ますか?
>>420 何を聞きたいのかイマイチわからないので想像で答えます。
:map <C-D> somestring1
:map <C-D> somestring2
このように続けて登録した時は後者が優先されるので、そもそも同じキーにマップす
るという概念が成り立ちません。次に
:map <C-D>1 somestring1
:map <C-D>2 somestring2
とした時には、これは別のマッピングとして登録されるのでそれぞれ
:unmap <C-D>1
:unmap <C-D>2
で別々に解除できます。但し「<C-D>で始まるマッピング全てを解除する」という方
法はちょっと思いつきません。
>>421 分かりにくくてすいません。
ちゃんと具体例を書けば良かったですね。
<buffer> 有りでmappingされているものと、
<buffer> 無しで登録されているものの2つがダブって見えてただけでした。
例えば、
nnoremap <C-N> somestring1
nnoremap <buffer> <C-N> somestring2
の違いでした。ここで:nmapをすると、
n <C-N> * :somestring1
n <C-N> *@:somestring2
となります。@はbuffer localの印ですよね。
やりたいことは「どちらか片方を指定してunmapしたい」ということなのですが、
ヘルプを読んでunmapにも<buffer>を指定できることが分かりました。
<buffer>付きでmapしたら<buffer>付きでunmap、
そうでなければ<buffer>を付けずにunmapということで落ち着きました。
というわけで結局、自己解決しました。お騒がせしました。
あぼーん
vim-scriptでTimer(event)は無いのでしょうか? 無い場合、何か代替案はありますか?
>>424 :help CursorHold
くらいでしょうか。単にウェイトさせるだけなら
:help :sleep
を参照してください。
>>425 ありがとうございます。
どちらも知っている内容でした。
ということは定期的にTimerEventを発生させる方法は無いのですね...
perlなどのI/Fを使うしかないのかな?
>>426 いや、それも無理です。if_perl主導で何かコトを起こすことができないんです。Perl
のスレッドを回してVIM::DoCommand使うとか、出来なくは無いんですがいろいろ不具合
があります。また私が直接確認したわけではありませんが、純粋にPerlスレッドとVim
の相性の問題も最近報告されました。
あとは外部プロセスからvim --remote-*を定期的に起動する、という方法も考えられま
すけど、これだと頻度の問題があるでしょう。
なんにしても用途に応じて別の解決法を模索した方が良いかもしれません。ユーザの操
作に割込んで、タイマーを含む何らかのイベントを起こすということはできません。そ
のようなことをしたければ半無限ループ内でgetchar()を使って、完全に入力をコント
ロールするしかないでしょう。
>>427 > if_perl主導で何かコトを起こすことができないんです。
そうだったんですか...
> Perlのスレッドを回してVIM::DoCommand使うとか、出来なくは無いんですがいろいろ不具合
> があります。また私が直接確認したわけではありませんが、純粋にPerlスレッドとVim
> の相性の問題も最近報告されました。
ちなみにどのような不具合/相性問題なんでしょうか?
> ユーザの操作に割込んで、タイマーを含む何らかのイベントを起こすということはできません。
なるほど勉強になります。
> そのようなことをしたければ半無限ループ内でgetchar()を使って、完全に入力をコント
> ロールするしかないでしょう。
残念ながらキー入力等を受け取った時にしかできそうにないんですね。
放っておいても定期的にEventが来る。ということはできないのか...
>>428 > ちなみにどのような不具合/相性問題なんでしょうか?
完全に再現条件を把握してないのですが、私が試した際にはVimを巻き込んでロック
したり落ちたりしました。
> 残念ながらキー入力等を受け取った時にしかできそうにないんですね。
getchar(0)とかすれば、キーが無くても即帰ってきます。
> 放っておいても定期的にEventが来る。ということはできないのか...
それができないからIRC on Vimとか諦めました。
>>348 s/330/331/
まぁ、それはともかく。
別にどこにばれようと問題なしです。
でなきゃURL晒さないですってば。
>>431 取扱説明書、というより各ヘッドラインの寸評ですね。
私はZDNetとAsahiとYomiuriにZDNet、それにSlashdotJapanを主に見てます。
plugin/headline/1101com.vim~ チルダがついてますが。
作ろうかなぁと考えて、結局止めたからです。
437 :
名無しさん@お腹いっぱい。 :03/08/06 14:08
現在編集中のバッファ(ファイル)が未保存かどうかを 取得する関数などはありませんか??
getbufvar()
あぼーん
:echo &modified
&modifiedで状態を取得することが出来ました。 どうもありがとうございました。
某スレで「foldはアウトラインとしては使いにくい」という至極納得な意見が出され
ていたので、なんとかしてみるスクリプトを書いてみました。
http://www.kaoriya.net/testdir/folddigest.vim foldが有効になっているテキストバッファで :call FoldDigest() を実行すると、
foldのダイジェストツリーが表示された新バッファができます。そのバッファの方で
注目したい項目の行で<CR>すると、テキストバッファの該当箇所へカーソルが飛びま
す。これで少し使いやすくなるでしょうか?。
>>442 某スレから参りました。
はぁ、便利。
あのスレの影響で使い始めたんですけど良いエディタですね。
使っていて気持ちが良いというか、リズムがあるというか。
スクリプトはだいぶ先になると思いますがちょこちょこ勉強していこうと思います。
>>443 動くようになったばかりなのでα版と考えてください。自動かそれに順ずる方法で
call FoldDigest()する仕組みとか、行がズレた時の処理とか、ウィンドウの取り回
しとか考えていますんで、もうちょっと使えるものになるでしょう。
ま、Vimに限りませんがイッペンにイロイロ覚えようとはせず、その時に必要なもの
を必要なだけ覚えていくのが良いんじゃないでしょうか。
folddigest.vimをアップデートしました。
http://www.kaoriya.net/testdir/folddigest.vim 使い方は
>>442 と一緒ですが…
> 行がズレた時の処理
主にコレについて修正しました。
:let folddigest_options = "quickfix"
とすることで+quickfixを利用し、編集してズレたり消えたりしてもちゃんと飛べる
ようになります。ただし:makeや:grepと併用できなくなるので注意してください。
:let folddigest_options = "flexnumwidth"
とすると、行番号の桁数が必要最小限になるので画面幅が狭いときには有効です。
オプションはカンマで接続して複数指定することができます。例:
:let folddigest_options = "quickfix,flexnumwidth"
この場合、行番号は一切表示されません。スッキリです。
>>418 うまく動かなかった・・
喋る前に消えたな・・
>>448 ありがとうございます。descriptionに追記しておきました。vim.orgに登録する時に
は5.0か6.0しか選べません。そのため6.2でも6.0としか表示できないのです。
あぼーん
451 :
名無しさん@お腹いっぱい。 :03/09/16 19:42
Vine Linuxでgvim(日本語版)を使っていますが、 起動時に検索など全ての文字入力が日本語になっており、 いちいち日本語をオフにしなくてはいけません。 初期設定は日本語(IME)をオフにする方法をどなたか御存じでしょうか?
昔は、は〜 むずかしそ〜だね〜と見ていたが、 今日からちょっとやってみた。 役に立ちそうな関数って何気にたくさんあるのね。
454 :
名無しさん@お腹いっぱい。 :03/10/12 02:12
すみません、前スレでfoldexprの連番処理についてカキコされたかたいらっしゃいますでしょうか? もう一度functionを書いてくれるとありがたいのですが・・・。 1 1.1 1.1.1 2 2.2 2.2.2 みたいなのを function! MyFoldFunc() let line = getline(v:lnum) if line =~ '\m^\s*[1234567890]' return '>1' elseif line =~ '\m^\s*[1-9]' return '>2' elseif line =~ '\m^\s*■' return '>3' else return '=' endif endfunction set foldmethod=expr foldexpr=MyFoldFunc() で処理したい!
>>455 間違えて名無しさん+トリップ無しで書き込んでしまいました。
457 :
名無しさん@お腹いっぱい。 :03/10/12 12:17
>>455 ありがとうございます。
何度も甘えてすみませんが、連番が入ったテストテキストファイルをvimでオープンしてもfoldされません。
何か呪文があるのでしょうか?
458 :
名無しさん@お腹いっぱい。 :03/10/12 12:26
>>457 すみません、できました。逝ってきます。。
>>457 オープンした後に :source orderedlist_fold.vim してもダメですか?
460 :
名無しさん@お腹いっぱい。 :03/10/12 16:43
>>459 あ、いえ、出来ました。とってもいい具合です。
ありがとうございます。今まで楽してきましたが、徐々にVimスクリプト勉強してみたいと思います。
ところで、このfoldはtaglistみたいに、vsplitしたwindowに表示とかはできないのでしょうか?
462 :
名無しさん@お腹いっぱい。 :03/10/13 11:17
>>461 あ、どもです。
ところで、
>>455 のfoldexpr=の後には、複数の関数つけても駄目でしょうか?
464 :
名無しさん@お腹いっぱい。 :03/10/13 16:11
すみません。
>>454 を質問したものですが、
以下のように、連番の下にさらに■が先頭にあったら、カレントの階層から一つもぐるようにするにはどうすればいいでしょうか。。
どうか初心者にお恵みを(-人-)。。
1. 折り畳み1
これは折り畳み1のテキスト
■
これは折り畳み1■のテキスト
2. 折り畳み2
これは折り畳み2のテキスト
2.1. 折り畳み2.1
これは折り畳み2.1のテキスト
これは折り畳み2.1のテキスト
■
これは折り畳み2.1■のテキスト
2.1.1. 折り畳み2.1.1
これは折り畳み2.1.1のテキスト
これは折り畳み2.1.1のテキスト
■
これは折り畳み2.1.1■のテキスト
2.1.2. 折り畳み2.1.2
466 :
名無しさん@Vim%Chalice :03/10/19 23:52
script内で/やGでジャンプしてもjumplistに 履歴が残らないようにする方法ってあるのでしょうか? scriptユーザが<C-I><C-O>でびっくりしないようにしたいのです。 できれば:Explorerがjumplistを汚さないように修正したいな〜と思いまして。 よろしくおながいします
>>466 > script内で/やGでジャンプしてもjumplistに
/の代わりにsearch()、Gの代わりにexecute linenum使ってみてください。
468 :
466@Vim%Chalice :03/10/20 00:25
>>467 おお!早速のお返事ありがとうございます。
あと、もとの場所に戻りたいときhjklで何とかしようと思って↓みたいにしてます。
気分はma, `aなんですが。。。
もっとうまい方法は無いでしょうか?
function! s:Mark() "{{{2 jumplistを汚さないMark&Jump
return s:Cons(line('.'), col('.'))
endfunction
function! s:Jump(marker) "{{{2 jumplistを汚さないMark&Jump
let l:ml = s:Car(a:marker)
let l:mc = s:Car(Cdr(a:marker))
let l:cl = line('.')
if l:ml < l:cl
let l:vmotion = (l:cl - l:ml) . 'k'
elseif
let l:vmotion = (l:ml - l:cl) . 'j'
else
let l:vmotion = ''
end
exe 'norm 0' . l:vmotion . (l:mc-1) . 'l'
endfunction
>>467 おおおお!またまたお返事ありがとうございます。一行になりますた。
function! s:Jump(marker) "{{{2 jumplistを汚さないMark&Jump
call cursor(s:Car(a:marker), s:Car(Cdr(a:marker)))
endfunction
てゆーか、漏れの真の要求が分かりますた。
scriptの副作用をユーザに与えたくないのです。
具体的には、こいつらを一発で退避・復帰したいな〜と思ってるのです。
:registers
:jumps
:marks
undobuffer
undolevels=-1だとバッファが丸ごと消えちゃうから厳しいです。
:reと:marksはスクリプトで出来そうだけど、:juとundobufferは
VIM本体に機能を追加するしかないのかな。。。
:juやundobufferについては
call これよりundobufferに追加しない()
"バッファを編集
call これよりundobufferに追加する()
みたいな機能でも充分なんだけど。
「よ〜し、パパパッチ当てちゃうぞー」とか思う人、居ません?
ちなみに、漏れは「よ〜し、パパC開発環境作っちゃうぞー」レベルだす。
#質問乱発で失礼しました >KoRoNさん
>>470 > scriptの副作用をユーザに与えたくないのです。
Chaliceとかイロイロ作っている経験から言いますと…「独立したアプリケーション」
じゃなくて「エディタのスクリプト」なんですから、そういうことに神経使う手間と時
間で別の仕事に取り掛かったほうが良いでしょう。
472 :
名無しさん@Vim%Chalice :03/10/31 01:02
class ●● { ... }; をfoldingしたい。 何か良い方法はありますか? 以下試したこと fdm=markerは正規表現使えなさそうだし, # class定義毎に予め {{{ }}} で囲んであればいいけどそんなのはまず有り得ないので fdm=exprはregion指定ができない?(できるのか?) fdm=syntax で syntax region start="^class" end="^};" しようとしたら $VIMRUNTIME/syntax/cpp.vim の keyword cppStructure に含まれる"class"の方が優先度高くて region の方で class が引っかかってくれなかった cppStructure を clear するか、clear 後にcontains付きで再定義すればOKだったが… # containedの場合は、region側で contains=cppStructure が必要 うーむ。一筋縄で行きそうにない… foldtextとか使えば出来るのかなぁ?(使ったことないから分からない…)
× clear 後にcontains付き ○ clear 後にcontained付き
おれはそういうのはexprでやった。
http://www.vim.org/tips/tip.php?tip_id=523 setl foldexpr=FoldBrace()
setl foldmethod=expr
function! FoldBrace()
if getline(v:lnum) =~ '^class .*{$
return '>1'
endif
if getline(v:lnum) =~ '^};$'
return '<1'
endif
return foldlevel(v:lnum-1)
endfunction
~
475 :
名無しさん@お腹いっぱい。 :03/10/31 20:24
検索をすると、次に起動したときに、その検索語が色づけされます。 これをキャンセルする、または色づけしないようにするにはどうしたらいいですか?
>>474 d!
vim online に tips があったんだね
>>474 試してみたんですが、returnする時に'<1'表記するとバグりません?
foldlevelが1のまま0に減らないんですよ…
'>1'の方は正しく1になっているようですが…
これらを'a1'と's1'に変えるとより分かり易く再現されます。
最初のs1の部分で減らないので、2回目にa1が実行される所でfoldlevelが更に増えて2になります。
ですが、2回目のs1の所まで来ると、一気に0まで戻ります。
vimのfold関係のバグかな?
>>479 最後の
return foldlevel(v:lnum-1)
を
return '='
にするとうまくいくかも。
helpにはfoldlevel(v:lnum-1)を使えって書いてあるけど、実際には
-1にしかならない。
シングルクウォートがぬけてました。
if getline(v:lnum) =~ '^class .*{$'
ChangeLogMemoをVimでお手軽に作れるようにとスクリプトに挑戦してみたけど
どーもうまくいかん。normalが未定義と言われ無効な表現と怒られる。
:Changelogでmemo.changelogってーファイルを開いて先頭に整形した
日付とかを入れたい。
どこがどう間違ってるか教えて。以下の関数とかは全部_vimrcに記述している。
ttp://apollo.u-gakugei.ac.jp/~yoshiki/clmemo/cltips.php ここのは試したけど動かせなかった。
command! Changelog :call Chlog()
function Chlog()
execute ":e c:\Program Files\Vim\memo.changelog"
execute "normal gg0"
map ,d ggi<CR><CR><ESC>kki<C-R>=strftime(\"%c\")<CR>
\ nanasisan <
[email protected] ><ESC>o<CR><TAB>*
endfunction
いろいろ調べてよーやく望む動作ができるようになったぞい
多分とても原始的な方法。ま、せっかく作ったんで書いとくよ。
" ,d : 時刻と署名を先頭に挿入
" ,n : エントリを追加
" どちらもChangeLogMemo用
map ,d ggi<CR><CR><ESC>kki<C-R>=strftime("%Y-%m-%d(%a) %X")<CR> nanashisan <
[email protected] ><ESC>o<CR><TAB>*
map ,n ggo<CR><TAB>*
" :Changelog : clmemo.changelogファイルを開くコマンド
command! Changelog :call Changelog()
function Changelog()
let clmemo = $VIM . "\\clmemo.changelog"
execute ":e " . clmemo
let timestamp = getline("$")
let now = strftime("%Y-%m-%d")
if (timestamp ==? now)
execute "normal " . ",n"
else
execute "normal " . ",d"
endif
endfunction
viつかいだして2年ぐらいになるし, そろそろスクリプトも書けなあかんなぁと思ってこのスレを読んでみると, 簡単なことでも四苦八苦する様を見てemacsに移行しようかと 思ってしまった. lispは応用効くし.
その程度の動機でemacsに移行できるならしとけ
485 :
名無しさん@お腹いっぱい。 :03/12/02 21:58
機能多すぎてさ。迷っちゃうわけよ。どの編集方法がもっとも最速か?少ないキータッチで実現できるか? 入力補完を使用した方が早いのか、画面ないの単語まで移動してコピって作成した方が早いのか? 迷ってるうちにマウスとキーボードでコピってるヤツの方がサクサクッと仕上げちゃってるわけよ。 編集そのものよりいかにエディタを使いこなすか?にずれちゃってるわけよ。ある程度学習すればリターン の方が大きくなるであろうとは思うのだけれど、なかなかその道が見えてこないわけよ。半年以上はvi 使ってると思われるんだけど、いまだにその辺のエディタと対してスピード変わってねーんじゃねー? っていう疑いをぬぐい切れぬわけよ。
487 :
名無しさん@お腹いっぱい。 :03/12/03 13:03
485 には vi 使いこなす能力がないっつーことだ
初めて vim スクリプトを勉強するなら、 eval.txt と usr_41.txt のどっちの方を先に 読んだ方がいいですか? 行数が eval は 41 のほうの 3 倍もあるので、どんな感じなのかと。
>>488 他のプログラミング言語に慣れているのであれば、リファレンスマニュアルである
eval.txtを必要なところだけかいつまんで読み、差分を理解するようにしたほうが近道
です。そうでないならusr_41.txtを読みながら1つ1つ順番に試した方が早く習得できる
でしょう。
このスレとか:help augroupとか色々なスクリプトとか読んでみたんだけど、 未だにaugroupが何の為にあるのか分からない。 これ使うとどんな嬉しい事があるの?
スクリプトが自分でインスコしたautocmdだけを綺麗に消せる
なるほど、そういう用途の為にあるのか。
教えてくれてどうもありがとう、
>>492 さん。
vimスクリプト開発に便利なコマンドってどんなのがありますか? とりあえず :source ってのは使えそうだけど、Emacs の eval-last-sexp みたいな、カーソル行をコマンドとして解釈して 実行、みたいなのがあると便利なんですが。これ自体スクリプトで 書けそうだけど…。
>>495 おおっ、こりゃ便利です!! ありがとうございます。
ストローク数多くなるけど、^y$:<C-R>" でもイケますね。
(行末の ^M を省くため)
お気軽スクリプト生成コマンドとしてはq:もあるね。 コマンドラインの履歴を編集してそのままスクリプトに出来る。
ストローク数だけで言うなら Y:<C-R>"<C-H>
>>497 ときどき :q と間違えて q: を押すと出てきてたのはこれだったのか…
vi初心者なもので…
これで望みどおりのことができそうです。ありがとうございます!
そう言えば、ストローク数だけで言うなら Yq:P の方が短いな
起動したスクリプトのディレクトリを取得しようとしています。 Chalice.vimをみると、 let s:scriptdir = expand('<sfile>:p:h') というのがあったので、 let s:name = 'ScriptDir' if exists("ScriptDir") finish endif command -nargs=0 ScriptDir :call s:ScriptDir() function! s:ScriptDir() let s:scriptdir = '' let s:scriptdir = expand('<sfile>:p:h') echo "This script is here.: \"" . s:scriptdir ."\"" endfunction などというのをでっち上げ、gvimを立ち上げて:ScriptDirしてみたのですが、ホームディレクトリが表示されます。 なんか大きく勘違いしていると思うのですが、どこで勘違いしているのかわかりません。 ご教示いただければ幸甚です。 よろしくお願いいたします。
>>501 let s:scriptdir = expand('<sfile>:p:h')
command! -nargs=0 ScriptDir :call s:ScriptDir()
function! s:ScriptDir()
echo "This script is here.: \"" . s:scriptdir ."\""
endfunction
expand('<sfile>:p:h') が評価されるタイミングが問題です。動作だけから判断する
と<sfile>はsource中にしか定義されないようなので、source時に確実に評価される
ように気をつける必要があります。
なるほど。ありがとうございます。 思ったような動作をするようになりました。
platexをですね、 :platex % なんて打ったら、コンパイルしてくれるわ dvioutを起動してくれるわ なんていうふうにするには どんなスクリプトをかけばよいのですか?
>>504 ちょっと違うが。
nnoremap <buffer> <c-m> :!platex %<cr>:sil !xdvi %<.dvi >/dev/null 2>&1 &<cr>
IRC (;´Д`)ハァハァ
だれか #Vim つくって...
>>508 splitしてるでしょ。確かグローバルには#vimがあったはず。
>>508 どこのネットワークだよ。
WIDE系?freenode?2ch?
511 :
名無しさん@お腹いっぱい。 :04/04/17 20:53
age
>>507 なんもかんがえずにとりあえず立ち上げてみたら、
いきなりsegmentation fault...
うーむ。
nomagicのときに /. と同様にハイライトさせたいのですが let @/='.' とやってもうまくいきません 何か良い方法はありませんか?
>>514 よくわからないけど
/\.
じゃなくて?
let @/='.'
でもうまくいくけど、一回検索しないと反転しないね。そゆこと?
>>515 set nomagicのときlet @/='.'だと全部が反転しませんか?
.と言う文字を反転させたいんです
やりたいことはノーマルモードの*と同じようなことを
ビジュアルモードで選択した部分のみをやらせたいんです
現状はこんなコードです
function! s:vsearch()
if line("'<")!=line("'>")
execute "normal! *"
else
let bkupreg=@@
silent normal gvy
if @@=~'.*\n'
let @@=strpart(@@,0,strlen(@@)-1)
end
if &magic
let @@=escape(@@,'^$.*~[]\')
else
let @@=escape(@@,'^$\')
end
exe "normal /".@@
let @/=@@
exe "normal n"
let @@=bkupreg
end
endfunction
vmap * :call <sid>vsearch()<cr>
>一回検索しないと反転しないね。そゆこと?
それも悩み所です
>>516 こんな感じで
let @/ = '\V'.escape(@@, '\')
>>517 お礼が遅くなってすみません
おかげさまで友人に見せても
文句の出ない(出ても一蹴できる)程度の
物になりました。
format.vimにenc=utf8でも禁則処理をして欲しいのでこんな感じにしてみた。
begin 644 format.vim.diff.gz
M'XL("/%1LT``"V9O<FUA="YV:6TN9&EF9@#-5-NJTT`4?3Z%_L-JD--K2A+M
M%2OHHR(^>`1!I*3IM!E))R69E!XY+Y-7+^`7B(CX'7Z*B&^^^`?.9)KT<EJ?
M/.!0FLE>:Z\]>\_.;C0:F(71PN7M%5VTPXC.SRX2@L?N)9P.''MH]X>6W%C6
MG7+)-,T=]A[1&7;Z\K<A-O979D#/:O4ZT.]*2;[W'<B=62Y!KH!PS(=:?TS9
ME#`^C@F+*:<K@A$L12-L2F=J4RXU861_,#8^@<OFB3LG1H'1&2ID36,>UXQ"
MNJ#5%>4@;@[*>,8K=^DR$FN]3>`F5'##_'<KTSN3"WB:3/!DR6G(XLQZHI"#
M;LNVG$TE,YI.(A[&[HJ,"?/"*65SF<)YOL\IYSM@-<NO6BY55)UVD-&ATO9^
M6#B>*-?J-5/V:,,0'R#>0,P@?(C?$&\AWD&\A[@/\0#B.40$P2%6$&N(UQ"!
M3N"H6/H1Z2>DGY%^0?H5Z3>DWY'^0/H3Z2^(AQ"/("
[email protected] =5O69E!T
MU<W7!E=7Q[HGEY#M<[U6_V7YCK9:M]]I=0>=HM<VQ>21C#(G/*",U(RV^I)R
MC$[7$O/"(+-#7LD6\WP)2><7DO12U1:JNI[O1@Z+:IY?Q[T1;*>O(2`B/(F8
M\EBZ$:_)9TOIM^#4-84$,='R!=GSM:$8%'(S2YBGOBH]-Y`W2W?@M'JV?3""
M;BZYNSJWOQVW"3V3#"R2@-/))2?:P%2#!14$VYDEXXS9M>/LDOTM.2"*JEU,
F]=20/&&&9-.U">RQ,^%;6GC7Z>"L)V])JM1/W\`?NMXJ$GL&```M
`
end
訂正。一文字とるなら " multibyte let str = strpart(str, idx) let len = strlen(nr2char(char2nr(str))) return strpart(str, 0, len) のがカッコええか
すまそ " multibyte return nr2char(char2nr(strpart(str, idx))) これでええやん
525 :
名無しさん@お腹いっぱい。 :04/05/27 12:30
タブ押したら半角スペースが4つ分になるようにしたい
>>525 se expandtab tabstop=4
hoge.texを編集してるときに :!xdvi % & としたら %はhoge.texを指してしまうわけですが、拡張子を除いた(hogeの)部分だけを表すには どうすればよいでしょうか?
起動するときにウインドウを希望の位置に希望の大きさで立ち上げたい
>>534 :winp[os] {X} {Y}
:win[size] {width} {height}
オートインデントは一切半角スペースで構成されるものでお願いしたい
あなたですよ、m9(・∀・)あなた!
私は半角スペースでインデントしています。
スクリプトと関係ない話はvim6本スレでよろしこ
カーソルの下にある文字列の長さを取得する関数を書いてみた。 function! UnderCursorStringLength() let line = getline(".") let cur = col(".")-1 let l = strlen(line) let backward = strpart(line, 0, cur) let forward = strpart(line, cur, l) let b = strlen(matchstr(backward, ".*\""))-1 let e = cur + match(forward, "\"") echo e-b-1 endfunction
カレント行をゲット。 カーソルが何桁目がをゲット。 カーソル位置より前と後にわけて、 前の部分の最後の"をbとする。 後の部分の最初の"をeとする。 長さはe-b-1。 複数行にわたってると無理だし、\のエスケープもわからない。 あんまり信用しないでね。
僕は、カーソルの下の文字列を取得する関数を書いて let len = strlen(UnderCursorString()) こんな感じのほうが好みかな。
" の正規表現は \ を考慮して \(\\\@<!\(\\\\\)*\\\)\@<!" でどうか
二つほどお聞きしたいのですが 行頭からカーソル位置を含む位置までの文字列を取得したいとき strpart(getline('.'),0,col('.')) としてみたところカーソル位置が日本語だとうまくいきません。 指定した行を削除したいのですが exec lnum.'d _' としたのですがfoldingされている行だとfoldingごと纏めて消えてしまいます。 何か方法はありませんか?
function! DelLine(num) if &foldenable != 0 set nofoldenable exec a:num.'d _' set foldenable else exec a:num.'d _' endif endfunction 縺薙s縺ェ諢溘§?シ?
化けた・・・ 最後の行は無視してください
function! GetPart() let lnum = line('.') let cnum = col('.') let line = getline(lnum) let cur_char = matchstr(line, '.', cnum - 1) let part_len = cnum + strlen(cur_char) - 1 return strpart(line, 0, part_len) " 一行で書くと "return strpart(getline('.'),0,col('.')+strlen(matchstr(getline('.'),'.',col('.')-1)) - 1) endfunction これでどうよ
>>549 >>551 ナルホド、参考になりました。
foldenableなんて知らなかったし
matchstrをそんな風に利用するとは思いつきませんでした。
まだまだ、修行不足ですな、精進します。
>>547 \によるエスケープを考慮した""文字列にマッチする正規表現は慣用句でして
/"\(\\.\|[^"]\)*"
と書くことが多いです。これは、クォーテーションで始まってクォーテーションで終わ
る文字列のうち、エスケープされた文字「\\.」、もしくはクォーテーション以外の文
字「[^"]」のみで構成されるもの、という意味になります。
>>548 echo matchstr(getline('.'), '^.*\%'.col('.').'c.')
こんな風にひとつのmatchstr()で行うのが速度面から有利です。わかりやすさであれば
551さんの方法が優れています。
つまりこういうことか! "エスケープバージョン function! UnderCursorStringLength() let line = getline(".") let cur = col(".")-1 let l = strlen(line) let backward = strpart(line, 0, cur) let b = matchend(backward, '.*\\\@<!"') let str = matchstr(line, '\(\\.\|[^"]\)*', b) echo strlen(str) endfunction
ちなみに
>>547 の意味は直前に奇数個の \ が存在しない "
>>555 こうだね
! let b = matchend(backward, '.*\(\\\@<!\(\\\\\)*\\\)\@<!"')
>>555 カーソルの下にある特定の正規表現にマッチする文字列を取得する方法はChaliceに含
まれるplugin/alice.vimに含まれるAL_matchstr_undercursor()が参考になります。
> function! AL_matchstr_undercursor(mx)
> let column = col('.')
> let mx = '\m\%<'.(column + 1).'c'.a:mx.'\%>'.column.'c'
> return matchstr(getline('.'), mx)
> endfunction
この/%cを使う方法であれば、正規表現を前半と後半に分けたためにわかりにくくなっ
てしまう、ということを回避できます。
let quoted = AL_matchstr_undercursor('"\(\\.\|[^"]\)*"')
質問があります。 VIM上でファイル検索>>リスト出力>>選択>>編集 が行えるようなスクリプトなどはあるでしょうか? winmanager.vim や explorer.vim では subディレクトリまで 検索してくれないので困ってます。タスケテ
よく分かりませんが > VIM上でファイル検索>>リスト出力 :new | read !find ./ -name "*.txt" or :new | read !dir /s /b "*.txt" > 選択 ご自由に > 編集 :execute 'edit! ' . getline('.')
>>560 ありがとうございます。
winmanagerみたいなToggle型(?)で実装してるスクリプトがあればうれしかったんですが、
ちょっとがんばって組んでみまふ ノシ
スクリプト書こうと思ってましたが、mapで済ませてしまいました。 map <F5> :let obufclnline = getline('.')^M^W^W:execute 'e ' . obufclnline^M :new | read !dir /s/b *.txt 等でリストを作成し、2つ以上ウィンドウがあることが 前提の仕様にしてます(´Д⊂グスン (本心は"ウィンドウが無かったら作る"というのをやりたかった) e! にしてないので、安全です^^ もっと良い方法ってありますかね? 微妙にスレ違いですか…そうでつか or2゜
>>562 ファイル名の上で <C-]> もしくは <C-W><C-]>
>>563 ありがとうございます。・゜・(ノ∀`)・゜・。
そんな簡単な方法があったとは…
vimは最近始めたのですが、viを長年つかっていた身としてなんか
妙にクヤシクなったので、スクリプト書いてみました。
処女作ですが、みなさんの忌憚の無いつっこみおまちしてます。
command! -nargs=1 Findmode :call s:StartFindMode(<f-args>)
function! Findg()
let obufclnline = getline('.')
if filereadable(obufclnline)
normal ^W^W
execute 'e ' . obufclnline
endif
endfunction
function! Finding(...)
let startcmd = "read !dir /s/b ".a:1
normal 1GdG
silent execute startcmd
endfunction
function! s:FindWindow()
nnoremap <buffer> <CR> :call Findg()^M
nnoremap <buffer> <ESC> :bd!^M
command! -buffer -nargs=1 Finding :silent call Finding(<f-args>)
endfunction
function! s:StartFindMode(...)
let startcmd = "10new __findlist__ | read !dir /s/b ".a:1
silent execute startcmd
endfunction
au BufEnter __findlist__ call s:FindWindow()
>>564 :help gf
:help :cfile
:help :copen
:help errorformat
>>565 無駄のない簡潔なメッセージだが何を言いたいのか分からない。
>>564 command! -nargs=1 Findmode :call s:StartFindMode(<f-args>)
function! Findg()
let obufclnline = getline('.')
if filereadable(obufclnline)
" ポータビリティーのため
execute 'wincmd w'
execute 'e ' . obufclnline
endif
endfunction
function! Finding(...)
let startcmd = "read !dir /s/b ".a:1
" 好み。俺はこの方が分かりやすい。
execute '1,$delete _'
silent execute startcmd
endfunction
続き function! s:FindWindow() " ポータビリティーのため。^Mより<CR>がいい。 nnoremap <buffer> <CR> :call Findg()<CR> nnoremap <buffer> <ESC> :bd<CR> command! -buffer -nargs=1 Finding :silent call Finding(<f-args>) endfunction function! s:StartFindMode(...) let startcmd = "10new __findlist__ | read !dir /s/b ".a:1 silent execute startcmd " 好み normal gg " 一時的なバッファにする。よく知らない。|special-buffers| set buftype=nowrite set bufhidden=delete set noswapfile endfunction au BufEnter __findlist__ call s:FindWindow() 感想:使ってみたら意外と便利だった。
>>564 errorformatにならって、findファイルリストをつくって
cfileで読み込んで、copenで開いて
gfで開けってことかな? いろいろためしてみたけど、いまいちうまくいきません(´Д⊂グスン
つかえたら、copenは便利そうですね。
>>566 丁寧にありがとうございます^^
あと感想ありです。誉めてもらったヽ(´ー`)ノ
なるほど wincmdかぁ、ほんとは__findlist__があるか判定して、
バッファ名でやりたかったんですが、よくわかりませんでした(´ヘ`;)
setはカレントバッファにしか影響をおよぼさないんですね?
勉強になります。
あと、modifiableとかをオフにしておいたほうがいいのかな
windowsでしかうごきませんが、使ってみて要望とかありましたらお願いします。
できるかぎり、、がんばってみます(;・∀・)
>>568 バッファがあるかどうかはbufexists()とかbufloaded()とかかな?
余裕があるならプラグインの形にまとめてどこかにうpしとくと誰かが喜ぶと思います。
なんならvim.orgに…。
あとこんぐらいしか思いつかないが
ファイル検索コマンドを変更可能に。これだけでマルチプラットフォーム。
ウインドウを縦分割に変更可能に。
ファイルを開く時に新しいウインドウを作ったり作らなかったり。
あとこんなの
nnoremap <buffer> <Space> :call Findg()<CR>:execute 'wincmd W'<CR>j
nnoremap <buffer> <S-CR> :call Findg()<CR>:execute 'wincmd W'<CR>
s/568/569/ まちがえました(´Д⊂グスン
572 :
名無しさん@お腹いっぱい。 :04/06/26 14:03
Findmode便利 まったりだけど良スレ
" modelineの拡張 if !exists('g:MX_mx') let g:MX_mx = 'vimex:\(.*\)' endif command! ModeLineEx :call s:DoModeLineEx() function! s:DoModeLineEx() let mx = g:MX_mx if exists('b:MX_mx') let mx = b:MX_mx endif let lnum = line('.') let cnum = col('.') if search(mx, 'w') > 0 normal G$ let flags = 'w' let fname = tempname() execute 'redir > ' . fname while search(mx, flags) > 0 let l = matchstr(getline('.'), mx) let cmd = substitute(l, mx, '\1', '') silent! echo cmd let flags = 'W' endwhile redir END
if filereadable(fname) execute 'source ' . fname call delete(fname) endif call cursor(lnum, cnum) endif endfunction " 自動化するならセキュリティー的にはこんな処置でいいと思う au BufReadPost * if getline(1) =~ 'vimpass:MYPASSWORD' | \ silent! ModeLineEx | \ endif " と、書いてみたが有効な使い道が思いつかない...orz
ちなみに使い方はファイルのどこでもいいので vimex: function! SayHello() vimex: return 'Hello' vimex: endfunction vimex: let test = SayHello() このようにスクリプトを書いておくと、その部分だけ抜き出して実行します。 フォーマットは g:MX_mx か b:MX_mx を書き変えて変更します。
2つ以上の name spaces を同時に指定するのはできないんですよね b:s:hoge とか bs:hoge みたいなかんじで
>>576 たしか、SIDをmapargを使って取得して、curly-braces-namesで擬似的にb:s:を実現す
ることは可能です。
map <SID>xx <SID>xx
let s:sid = substitute(maparg('<SID>xx'), 'xx$', '', '')
unmap <SID>xx
let b:somename_{s:sid} = "buffer script local variable"
579 :
名無しさん@お腹いっぱい。 :04/10/19 12:36:56
"レジスタに値が入った時点でなんだかの動作を起こすことって可能でしょうか? 具体的にはレジスタの履歴をyyした時点で保存したいのですが。
>>579 :help event 見てもそれらしきイベントは無いねぇ
map yy とかするしか無いんじゃない?
ちなみにviminfoファイルにレジスタ履歴その他を保存しておくことができるけどね
どういうものを残すかはオプションで指定できる
:help 'viminfo'
581 :
579 :04/10/21 12:05:35
>>580 返信ありがとうございます。
やっぱりひとつひとつキーマップしかないのですかねぇ。
viminfoでの履歴は、a-z 0-9なんかのレジスタしか保存できませんよね?
かたっぱしからレジスタにつっこんだ履歴を保存したので…。
スクリプトで、他のファイルに退避して、 使うときに読み込むのはどうかな?
583 :
名無しさん@お腹いっぱい。 :05/01/03 05:39:50
Vimって:wを連続で行ったときもバックアップを作ってくれちゃうから、 一定時間経過したときのみバックアップするようなスクリプトを 考えてみた。つっこみ頼みます。 " 指定したファイルのバックアップが一定時間以上古ければバックアップを作り直す。 " 例: call MyBackup("%") " この値以上古ければ更新(単位:秒) let g:my_backup_interval=1800 " バックアップファイルの拡張子 let g:my_backup_ext=".bak" " バックアップを作るディレクトリ let g:my_backup_dir="~/.bak" function! MyBackup(orgfile) let fn = substitute(expand(a:orgfile), ".*/", "", "") let bakfile = glob(g:my_backup_dir) . "/" . fn . g:my_backup_ext let baktime=getftime(bakfile) if (localtime() - baktime) > g:my_backup_interval exe "w! " . bakfile echo "Backup: " . bakfile endif endfunction
584 :
名無しさん@お腹いっぱい。 :05/01/04 01:44:42
時間よりも内容の変化で区切ってバックアップしたほうがいいと思う。 バックアップというよりバージョン管理か。 転ばぬ先の杖としてならそういう仕組もありかもね。 スクリプトは特に問題ないような気がします。 #autocmdを使って #BufWritePre: 時間が経っていなければset nobackup #BufWritePost: &backupを復元 #って手もあるけど、別口で保存しといたほうが安心か。
保存するごとに、バージョン番号を付けたコピーを作成する スクリプトがあったよ。確か。 ふと、バックアップディレクトリを覗くと、そこにはっ、、、!!
586 :
名無しさん@お腹いっぱい。 :05/01/15 15:47:37
vimonline.vim に current version の 表示を加えてみました <br> <br> begin 644 vimonli ne.diff <br> M+2TM('9I;6]N;&EN92YV:6TN;W)I9PE4:'4@2F%N(#$S(#`T.C0V.C,W(#(P <br> M,#4**RLK(' 9I;6]N;&EN92YV:6T)4V%T($IA;B`Q-2`Q,SHU.#HQ-B`R,#`U <br> M"D!`("TR-2PV("LR-2PW($!`"B`@('-I;& amp;5N="$@)7,O+R]G"B`@('-I;&5N <br> M="$@)6<O/'-P86X@8VQA<W,](FYE=W-D871E(B?L+UY<& lt;RH?"]P/B0O:F]I <br> M;@H@("!S:6QE;G0A("5G+SQT9"!C;&%S<STB;F5W<V1A=&4B+RPO/%PO =&0^ <br> M)"]J;VEN"BL@('-I;&5N="$@)7,O7EPH7&1<9"I<+EQD7&0J7"Y<9%QD*EP I <br> M)"??:#$^5FEM(%PQ(&ES('1H92!C=7)R96YT('9E<G-I;VX?"]H,3XO"B`@ <br> M(&-A;& ;P@04Q?97AE8W5T92@G)7,O+BI<*$YE=W-<*3Q<+W-P86X^+BHO7U]? <br> M)RYG.FAE861L:6YE36%R:T-A =&5G;W)Y+B=<,2]I)RD*("`@8V%L;"!!3%]E <br> M>&5C=71E*"<E<R?N*EPH4F5C96YT(%-C <FEP="!5<&1A=&5S7"D?"]S<&%N <br> M/BXJ+U]?7R<N9SIH96%D;&EN94UA< FM#871E9V]R>2XG7#$O:2<I"B`@(&-A <br> M;&P@04Q?97AE8W5T92@G)7,O+BI<*%)E8V5N="!4 :7`@061D:71I;VYS7"D? <br> M7"]S<&%N/BXJ+U]?7R<N9SIH96%D;&EN94UA<FM#871E9V]R> ;2XG7#$O:2<I <br> !"@`` <br> ` <br> end<br><br>
587 :
& ◆h9Bn.Lr5Ro :05/01/15 15:54:13
失敗しました。
>>586 begin 644 vimonline.diff
M+2TM('9I;6]N;&EN92YV:6TN;W)I9PE4:'4@2F%N(#$S(#`T.C0V.C,W(#(P
M,#4**RLK('9I;6]N;&EN92YV:6T)4V%T($IA;B`Q-2`Q,SHU.#HQ-B`R,#`U
M"D!`("TR-2PV("LR-2PW($!`"B`@('-I;&5N="$@)7,O+R]G"B`@('-I;&5N
M="$@)6<O/'-P86X@8VQA<W,](FYE=W-D871E(B?L+UY<<RH?"]P/B0O:F]I
M;@H@("!S:6QE;G0A("5G+SQT9"!C;&%S<STB;F5W<V1A=&4B+RPO/%PO=&0^
M)"]J;VEN"BL@('-I;&5N="$@)7,O7EPH7&1<9"I<+EQD7&0J7"Y<9%QD*EPI
M)"??:#$^5FEM(%PQ(&ES('1H92!C=7)R96YT('9E<G-I;VX?"]H,3XO"B`@
M(&-A;&P@04Q?97AE8W5T92@G)7,O+BI<*$YE=W-<*3Q<+W-P86X^+BHO7U]?
M)RYG.FAE861L:6YE36%R:T-A=&5G;W)Y+B=<,2]I)RD*("`@8V%L;"!!3%]E
M>&5C=71E*"<E<R?N*EPH4F5C96YT(%-C<FEP="!5<&1A=&5S7"D?"]S<&%N
M/BXJ+U]?7R<N9SIH96%D;&EN94UA<FM#871E9V]R>2XG7#$O:2<I"B`@(&-A
M;&P@04Q?97AE8W5T92@G)7,O+BI<*%)E8V5N="!4:7`@061D:71I;VYS7"D?
M7"]S<&%N/BXJ+U]?7R<N9SIH96%D;&EN94UA<FM#871E9V]R>2XG7#$O:2<I
!"@``
`
end
>>587 なんかその diff 微妙におかしくありませんか?
あ、全角「?」が含まれている?
そろそろuuencode.vimほすい鴨 ↓がんがれ
やっぱり失敗してます。
>>587 もう1回挑戦
--- vimonline.vim.orig Thu Jan 13 04:46:37 2005
+++ vimonline.vim Sat Jan 15 13:58:16 2005
@@ -25,6 +25,7 @@
silent! %s///g
silent! %g/<span class="newsdate"/,/^?s*<?/p>$/join
silent! %g/<td class="newsdate"/,/<?/td>$/join
+ silent! %s/^?(?d?d*?.?d?d*?.?d?d*?)$/<h1>Vim ? is the current version<?/h1>/
call AL_execute('%s/.*?(News?)<?/span>.*/___'.g:headlineMarkCategory.'?/i')
call AL_execute('%s/.*?(Recent Script Updates?)<?/span>.*/___'.g:headlineMarkCategory.'?/i')
call AL_execute('%s/.*?(Recent Tip Additions?)<?/span>.*/___'.g:headlineMarkCategory.'?/i')
すみません。 590も変。 全角?を半角backslashにしただけじゃ直りませんね。 1行足しただけです。 あと、"Vim ? is"の所はbackslashの後に1を足して下さい。 顔を洗って寝直して来ます。
悔しいので再挑戦させてください。 begin-base64 644 vimonline.diff.gz H4sICEfG6kEAA3ZpbW9ubGluZS5kaWZmALWQwU+DMBjFz9tf8bnMMMZoYWMjI0hYvBn14KanZoTQ BqqskLZM/e8tmR5mjIkHD22aL+/33vfqui4c+aERNRcMmRdqJC8Hu6qDm1yAvwAviIJVtAhh7nnL oeM45/rBthMn6Qr8dRSEkb8+SdMU3PlytgLH3CGk6RAAFK+Z0BdwqTDG5dmkxLFqjVFR50pdjQR7 VTTXbIRneE/UNCa4Tcb4ueHiO6bpT5ABNP0inLPoPZkQStDncYg9xnHlJ0/8AMQHrkBXDIpOSgPA kUnFG2HsjAT32UVe17C5zdgbKzrNJpaxRFMyuTfpxDbCvkeCpjjLMguVUcVy2v/XXS5frs12ZSPf kUV8zC37N78HVvQLbAvJWw2Pbd/sPwJ2vIUNpVybmn/3/wAkbgcXQwIAAA== ==== 少し変更しました。
headline/sankei.vimを 記事のタイトルを左に、 urlを補完して右に移動するように 変更してみました。 begin-base64 644 sankei.vim.diff.gz H4sICKwH80EAA3NhbmtlaS52aW0uZGlmZgCdUtuK2zAQfY6/YmxafIvl2Lm0NY5JWFpKm1Do7tKH KFm0tmJrY8vBlkv7mD+vFGeX0FIKBXmYkc7xnDmS53nQEn6gDH1nFaoblg/uig4+EQ7BWK5oMo0m MwhHo6nmuu4VeHDb8TMulLggGs2i6dset1iANx6+AVeFxUID44oGHtyeC/hGH+FYdjnjsK8bKCjJ SsapAkmKYq0J40J+tIkG6/uvyy+fl3BHmhriQ93UfCEOBBEhkCQ9HRPNM2BFWgE3BeE5jQZB6El9 ntQ0QZr722E4fj6cIg00aNOGHQXlaZ0xnkN6fDcO5b6aZRIOJ+DK2E8D0LKScqHD61bH1S5mVb7Z JVsniQkUDd3PDWxtdsYWu9g2EpXHWwfbsU8S5LzS8fzjZdQPdVMRsZKZ1XaPMk0LK7SH8FIEsjBN W/+z6en9v5ttdie2dU4MWzjDma8CqBCpgO3T03+oeSnGdi8rJWUJy9UD/UHTTlDLvJgiMnmjLC/E 3AhmRqJMQk68r7noveqVKtWxr3alNbqJ8uj5GaxJc7ghguZ18xOZONBNW3P/0s66GGHrOLj+x31T PvSP7cztoUIcI+RgVIgK29iSqS1dCEG2yHuUH/cSfT/XgPJs3/FUsJprvwDOsrrWLgMAAA== ====
>>594 を再考し
日付、記事タイトル、url
の順番にしてみました。(diffの後半)
後、トップニュースが、表示されるようにしてみましたが、
今日の紙面?でしか試していません。(.diffの前半)
begin-base64 644 sankei.vim.diff.gz
H4sICCFm80EAA3NhbmtlaS52aW0uZGlmZgCdVF2PmlAQfV5+xUB2g4qA4EcTg4Sm2aZpbPuw9smr
BuUKt4uXBq52N+mL/6M/tnfED/zYNGmil2E4nDlzZoJpmlCE/Jkya8NWVpaz+G6UrOFzyMFpy1+/
0+13euC2Wl3FMIwK+O5pzXc4V+LeSVC/1S5xQQCm0206DhjlJQgUANDg21yEjIPIfnL6q8BcSoWk
3NBZTmMYQKBhkmf5KkxViGPFBChYSrlQwZ56qmlu/8i3iVWI0DR9u/rcakpExDYQpizmAy2lS6H5
9qsUrBiXNGckxgXJMuOifG+vcN5PaBiljNNRKX3EREql3mI9LwQTa0Frt8NAa4JGvK9DXwa6Lv+x
Xpcpb57vMoAphindG0/9CTF8/QTE+hXd181d9X9yiPIIm7ts/4C6whyGIfLzvm52cECvXhyJ1rEb
UrMapL5lpEYiEtl4AB59PMjv3cMfXghJTpcDjdTGU012S+qar5/Y3HO2N+C4Xx232QFDnr39dh0a
fChUspp6bBWjnw3/JgfG3gQr2KFvNe5VMvi0n/BHXD4xlBHOUYaLpObK+RxvHByWXlevi24f/11s
PN2ySeMtm6RF/6HmeNOul7IWYZrC++GMvtAFzlDfmyIiSCiLEzHQnJ7mo0lWY7fupVelUlTt2ZiV
1qi6FR+3/0uYP38IBY2z/NXSiaPKTajs1r4cYLkbDmAs54qXe9UnbSAuVNm/5+nsqfy87Lir1A+F
7ZUabTtWQC7ucs0XgmVc+QuinupGwwQAAA==
====
あ・・・あのですねあの・・ this->hoge[ i ]なんてなってるのが200行くらいあるんですよ これら全てを急遽 (*(this->hoge + i)) に変更したいんですよ あのよろしかったら・・・その・・・・ねそのぉ・・・教えて下さい.
そのままポインタ参照したらいいやん
こんな感じ? s@\(\k\+\)->\(\k\+\)\[\s*\(\k\+\)\s*\]@(*(\1->\2 + \3))@ これでダメならPerlスレとかで聞いた方がいいかも.
要望: 1. hz_ja.vimに変な文字を全部正規化する関数が欲しいなぁ。具体的にはgHA, gZJ 2. あるフォルダ内のファイルを再帰的に検索するプラグインが欲しいなぁ。 grep -r とか find . -type f | xargs grep みたいなやつ。 Windowsでgrep.exeやcygwin用意するのが面倒な場合があるんで。 あと符号化方式の自動認識を考えたらvimでやっちゃうのも悪くないだろうし。 一個、そういうプラグインを見つけたんだけど、やたら遅くて使い物にならなかった。 それから、検索だけじゃなくて置換も出来ると良いな。リファクタリングするとき便利なんだよね。
自分で書け
WinのCygwin上でvim使ってる人いる? 見ためがいいからgvim使ってるけど,ちょっとしたとき<C-z>で シェルに降りられるのも便利なんだよねえ.
>>601 やはりそうなるのか。
「同じ事考えてますねー。ボクは作っちゃいましたよ!」という人が現れるのを期待してたんだが。
> あるフォルダ内のファイルを再帰的に検索 project.vim で出来るかな。
>>604 ありがとー。試してみるよ。これでダメなら書くか...
ttp://cvs.kaoriya.net/svn/kaoriya/vimscript/headline/trunk/plugin/headline/ から 2/13 に頂いた sankei.vim にジャンルの表示を加えてみました。
--- sankei.vim.origSun Feb 13 00:37:00 2005
+++ sankei.vimTue Feb 15 21:37:33 2005
@@ -36,14 +36,12 @@
let @" = save_reg
" Format headlines
silent! %s/<br>/\r/g
- silent! g/\m^<td height="16"><img.*Special/delete _
- silent! g/\m^<td height="16"><img.*お知らせ/delete _
- silent! g!/\m^<img[^>]*><a href="[^"]*.htm"\|^・<a href="[^"]*.htm"\|^<td height="16"><img[^>]*><b>/delete _
+ silent! g!/\m^<img[^>]*><a href="[^"]*.htm"\|^・<a href="[^"]*.htm"\|^<td width="110">/delete _
silent! %s!\m^<img[^>]*><a href="\([^"]\+\)">\([^<]*\)</a>(\(\d\d/\d\d \d\d:\d\d\)).*$!\=HeadlineFormatLine(submatch(2), submatch(1), submatch(3))!
silent! %s!\m^<img[^>]*><a href="\([^"]\+\)">\([^<]*\)</a>.*$!\=HeadlineFormatLine(submatch(2), submatch(1), '')!
silent! %s!\m^・<a href="\([^"]\+\)">\([^<]*\)</a>[^(]*(*\(\d\d/\d\d \d\d:\d\d\))*.*$!\=HeadlineFormatLine(submatch(2), submatch(1), submatch(3))!
silent! %s!\m^・<a href="\([^"]\+\)">\([^<]*\)</a>.*$!\=HeadlineFormatLine(submatch(2), submatch(1), submatch(3))!
- call AL_execute('%s!\m^<td height="16"><img.*<font[^>]*>\([^<]\+\)</font>.*!'.g:headlineMarkCategory.'\1!')
+ silent! execute '%s/^<td width=.*alt="\([^"]*\)".*$/'.g:headlineMarkCategory.'\1/'
silent! execute '%s!"\([^"]\+\)">\([^<]\+\)\(.\+\)$!>\3 \2 '.g:headlineUrl_Sankei.'\1!'
silent! %s/<[^>]*>//g
endfunction
607 :
名無しさん@お腹いっぱい。 :05/02/17 14:15:23
:syntax match と :match は、どういう風な違いがあるんですか? 一緒??
>>607 matchは1つしか定義できないし、複雑な条件を付加することもできない
ありがとう。 そっか、だから match none でも動くのか。
:match yocchan toshichan
>>610 で「tanokin torio」がマッチするようになりました。
ありがとうございました。
windows環境でgtags.vimを利用している方はいますか? 私の環境だとエラーがでて動かないのですが
SuperTab.vim、(GTKの)ximと相性悪くない? <C-X>押すとximがonになるからいちいちoffにしないと次の操作を受け付けない。
どんなとこが強まってるのかちょっと紹介してもらえるとうれしいです。
配列や連想配列が実装された
スクリプト勉強中です。環境はWin2K + Kaoriya版Vim6.3です。 自力では解決できなかったので教えてください。 これは動作しますが、Dos窓を閉じる必要があり面倒だなと思い execute "! dir > C:\\test" 以下の方法を試しましたが、うまく動作しません。 let value = system("dir > C:\\test") "test.txtは作成されない echo value "エコーは出力される 何故・・・
system()は出力をリダイレクトで受け取るから実際に実行するコマンドが dir > C:\test > tmpfile 的なことになってるとおもわれ :9verbose echo system("dir > C:\\test") とかすれば確認できる。出力を直接受け取る必要がないなら :silent execute "! dir > C:\\test" で、目的の動作になると思う
619 :
617 :2005/06/05(日) 21:57:30
>>618 ありがとうございました。期待の動作になりました。
>>612 618さんのアドバイスのおかげで、Win2Kではgtags.vimに以下の変更を加えたらとりあえず動きました。
オプションの変更は正直よく理解してません。
"let cmd = 'global' . sep . '-tq' . option . sep . pattern
let cmd = 'global' . sep . '-tq' . sep . pattern
"let stuff = system(cmd . " > " . tmpfile)
:silent execute "!" . cmd . ">" . tmpfile
ところでglobalってC++のオーバーロードも判断してくれるんですかね?期待して調べたんですが。
なんか無理っぽくてちょっとがっかり気味。
全体で数百万ステップを超えるソフトの改造に入ったんですが、でかすぎてさっぱり分からんのです。
オーバーロードを認識しないctagsでは役に立たない。
VC++で定義位置とかを追うとビルドばっかりで時間がかかり使い物にならず。
助けてくだされ。
globalはオーバーロードした関数ごとにタグ作ってるみたいだから 普通に使えるんじゃないの。さすがに文脈を判断してジャンプする とかむりだろうけど、複数候補から自分で選ぶくらいはできそう。
>>615 直接ファイルの入出力ができるようになったのが便利。
あと、まだ実装されてないみたいだけど文字列をforループで処理できるようになるらしい。
つーかリストはやっぱり強力やなぁ。
ショパン最強
Vim7はこんな風にluaやjavascriptみたいなクラスが書けるのもおもしろい let counter = {} let counter.count = 0 function counter.next() dict let self.count += 1 return self.count endfunction echo counter.next()
言語の強化よりも、もっとvim内部をいじれるように してほしいんだけど。 そういう改良はないの?
いい加減そういう反応はやめましょうよ…
改良を望む人自身が改良するのが一番いいだろ。
624の言ってるのは、スクリプトそのものの言語仕様をいくら高めたところで vim側がスクリプトに委ねてくれるものが今のままでは どのみち大したことはできないってことなんじゃないの。 スクリプトで出来ることを増やそうと言っているのに その答えがソース弄れというのは頓珍漢。
これは凄いエスパーだな。
ソース弄らなきゃその「スクリプトで出来ることを増やす」こともできないだろ 問題は誰がどのように弄るかなの だったらどうしたいかアイデアを持っている人がやるのが手っ取り早い
外部でそういう部分を弄って持ち込んでも某mattn氏の二の舞になるだけだからなあ。 hackするのと、開発の方向性を変えるのとは別次元の問題だよ。
とはいえ、開発の方向性を変えるのにパッチを送る以外に有効な方法ある? まぁ、コミュニティの方向性を変えたいならパッチを送るだけじゃなくって そういう方向に向くように開発者を説得するのも必要かもしれないが、 それにしたってまず最初にパッチは必要だよね。
こういう件に関しては、あまりそうは思わないな。 単なるhackならとりあえず自分の役には立つが、 scriptingのようなものは正式に取り込まれて初めて意味を持つ。 方向性も定まらないうちに闇雲に書いてみても労力が無駄になるだけだ。 socialを先にすべき問題だろう。
ま、一つ二つ見本くらいは作ってみせてもいいだろうけどネ patch出して取り込んで、というものとは少々違うわけですよ。
一応参考まで。 私の経験で言うとscriptingの拡張としては、User Defined CompletionがVim7で取り 込まれました。パッチはBram氏には相談せずに書き始めました。書き始めた時には無 駄になることも覚悟の上でしたが、ちょうどWin専用で無理矢理Intellisenceを行う スクリプトが発表された直後だったこともあり、コンセプトは受け入れてもらえると 確信はしていました(まさか関数の定義方法とか殆どそのままだとは思いませんでし たがorz)。仕様が小さくなかったのでVim6には見送られましたが、Vim7で日の目を見 たというわけです。 逆に言えばVim7開発中である今なら、比較的取り込んでもらいやすいでしょう。もち ろんパッチの形のほうがBram氏の手間が低くなるので取り込んでもらえる確率は高い のですが、海外の方はたとえ信義に反しても理に適っていれば納得する傾向があるの で、コンセプトだけでも背景や考え方つまり説得力があれば、採用される可能性は高 くなるでしょう。 特にMzScheme用のマルチスレッドや、関数ポインタが導入された今ならば、上手くす れば相当に面白い機能を突っ込める気がしています。
>>636 いやいや、興味深い。
今日の夜にでも試させてもらうよ。
>>636 > ありえないほど遅いです。
{}による名前の解決が多いのが原因かもしれないですねぇ。だとすればC++のテンプ
レートみたいに、functionの中でfunctionを定義する、ジェネリックなことができれ
ば解決できるかもしれません。
libcall()使っちゃうのが王道だとは思いますけど。
>>636 試してみた。
500行くらいまでなら、ありえないってほどには遅く感じなかったよ。
10000行のファイルは帰ってこねぇ、、、
synID(line,col,flag)のflagって0でも1でも同じに感じるんですが どう違うんでしょうか?いまいちわからない…
transparent 属性がついてる構文アイテムの上では違う結果を返すんじゃない。 :set ft=c として ( の上で :echo synID(line("."),col("."),1) :echo synID(line("."),col("."),0) すると違う結果になるよ。
それよりim_customの強化きぼんぬ
DLLの扱いが libcall() -> DLLロード -> 関数呼び出し -> DLLアンロード じゃなくて libopen() -> DLLロード libcall() -> 関数呼び出し libclose() -> DLLアンロード とか、DLLのインスタンスを保持できるようになってないのがちょっと不思議。
>>646 インスタンスを保持する変数が無いから。というより変数にはインスタンスを保持でき
なかったから、と考えるのが正確かも。Vim7の変数は多少事情が違うので、うまく議論
できればそのようにすることは不可能じゃない、とは思います。
単純にDLLが状態保持できればと思ったんだけど、でもそうか、 どうせなら複数インスタンスを作れた方がおもしろそうだ。 それならlibopen()がDLLから関数リストをもらって、その関数をセットした ディクショナリを返すとかがいいな。ついでに引数の制限もゆるめてほしい。 まぁ議論なんてできないわけだが...on
>>648 > それならlibopen()がDLLから関数リストをもらって、
DLL自体にはタイプライブラリ機能はありませんから。COMやXPCOMとかいうあたりがな
いとダメでしょう。
> ついでに引数の制限もゆるめてほしい。
マーシャリングですねぇ。つい最近vim-devで、if_*で呼び出せるスクリプト言語か
ら、Vim本体の変数を操作するようなジェネリックな方法がどうとか、そういう議論が
ありました。ガンバレばその流れで関連技術を滑り込ませられるかもしれません。
とはいえ、なんかそれって.NETだよなぁ。
おれはVim専用のDLLを考えてました。 char* vim_getfunclist() という関数から"1,1,func1,1,3,func2" みたいな文字列が返ってきて、この場合なら引数を一つ取るfunc1()と、 一つから三つまでの引数を取るfunc2()を、DLLは持っている。 関数のプロトタイプは char** func(int argc, char* argv[]) で、文字列のリスト(NULL終端)を返す。みたいな簡単なの。 あとはVimの関数をDLLに渡して、pVim->eval("@a")とかできるようにしたり。 あんまり深くVimの内部まで操作出来るようにすると、お手軽じゃなくなりそうなんで、 Vimへのアクセスは他のスクリプトと同程度になりそうだけど、DLLをC言語で書くなら Vimの内部表現を直接いじりたいかも。 うーん…欲しいなぁ。
あー、でもどうせvimスクリプトでDLLをラップするだろうから DLLの扱いはシンプルでいいのかも。
内部表現をいじるなら、先ずはソースコードを直接触っちゃったほうが速いでしょう。 難しいところなんですが、エディタとしての価値を直接高めるのに必要な拡張であれ ば、思いの他すんなり通るものです。一方、間接的なもの、スクリプトの表現力を上げ てそれが結果的に、というのはなかなかに難しそうです。
どうもDLLをロードするたびに新しいインスタンスが作られるわけではないようで、
複数インスタンスを作るのは難しそう。
というわけで、DLLのインスタンスを保持するだけの最低限のものを作成。
これでもけっこう遊べるかな。
http://www.uploda.org/file/uporg203304.zip.html こんな感じで使う
:call libopen('sum.dll')
:echo libcallnr('sum.dll', 'add', 1) => 1
:echo libcallnr('sum.dll', 'add', 32) => 33
:call libclose('sum.dll')
:echo libcallnr('sum.dll', 'add', 43) => 43 "いままでどおり使うこともできるが
:echo libcallnr('sum.dll', 'add', 32) => 32 "毎度初期化される
これだけでだいぶ幅が広がると思うんだけど…
GUIのウィンドウとか、通信とか...
そういうのは今でも出来るけど、ちょっとしたサーバ(daemon?)を作るのが面倒くさいな。
> 6 Add support for loading shared libraries, and calling functions in it. > :libload internal-name libname > :libunload internal-name > ... 優先度は低いながらもいちおうTodoには入ってるようで、ver5.3のころから。 たぶんこれはlibcall実装前のTodoな気もしますが…。 libcallの引数を増やすのも、DLLからVimのコマンドを呼べるようにするのも Todoに入ってますね。
656 :
名無しさん@お腹いっぱい。 :2005/11/14(月) 23:07:34
verilogの回路を、vimを使ってで記述しています。 で、vimだけ(一部、tag生成のためにperl)をつかって、ドライブ元を自動検索する スクリプトを作成中です。 そこで、質問ですが、以下の信号を検索するための正規表現をどうしたら最適だと思いますか? 正規表現が無理なら、関数でも可能です。 1. xxxxが入力ピンとして存在することを調べる input xxxx; や input yyyy, /*testdesu*/ xxxx; 2.xxxxが、ドライブされていることを検索 xxxx = yyyy ; や xxxx <= (zzzz <= yyyy) ; 3.xxxxが、接続されているピンを検索 .yyyy(xxxx) や、 .yyyy( // pin /* test */ xxxx ) 今の僕の検索は 1.input\_[^;]*\<xxxx\> 2.\<xxxx\>\_[ \t\[\]0-9:{}]*<\==\_[^;=]\+\_[^;]*; 3.(\_\s*\(\/\*\_.\{-\}\*\/\)\=\_\s*xxxx\> なんて感じです。結構適当ですが、まぁ、そこそこヒットします。 微妙にスレ違いかもしれませんが、いいアイディアがあれば教えてもらえればと思います。 結構コメントがいろいろ入る可能性があるので、本来は構文解析させるべきなんでしょうが、 それだと、リアルタイム性が薄れるので、なんとか、ベースは検索+関数って感じで やりたいと思っています。
Verilogというハードウェア記述言語のソースを書いていて、 それをサポートするツールをVimスクリプトで作っていて、 んで、C言語で例えるなら、ある変数の宣言位置や、代入されている位置や、 その変数を引数に取っているある関数を探したい、ということなんかな? なにが問題なのかよくわかんないからなんとも言えないけど、 そこそこの割り切りは必要じゃないかと。 検索するだけなら:g/xxxx/.-3number 6とかして目視とかョョョ
658 :
名無しさん@お腹いっぱい。 :2005/11/24(木) 11:56:54
たしかにあやしいw けどまっつんさんのskkim.vimより変換がかろやか
661 :
名無しさん@お腹いっぱい。 :2005/11/25(金) 00:30:13
rate this script│(*)God ( )Life Changing ( )Helpful ( )Unfulfilling [rate]
再帰登録や補完にまで対応とは、凄いですね。さっそく使わせて頂いております。
ちょっとだけ改造してみました。検討して頂けると嬉しいです。
ttp://www.jt200x.com/uploder/src/up0293.zip ・▽を<C-H>で削除した後に挙動がおかしくなる現象を修正
・gSで辞書を手動セーブ
・以下のオプションを追加
let skk_egg_like_newline = 1 " <CR>で確定しても改行しない
let skk_show_annotation = 1 " skkinput2ライクなannotation表示 (ださい)
" skkサーバなんちゃって対応 (設定するとL辞書は読まない)
let skk_external_prog = "/usr/bin/env ruby -Ke ~/ruby/skkservcaller.rb -w"
"let plugin_skk_disable = 1 " pluginの無効化
直せなかったもの:
・「. /./・/。/…;.../」のような . や \ などを見出しに含むエントリがおかしい。
search()が正規表現と解釈するため。(これはこれで/anno.* とかできて面白い?)
・タイプ速度が速いとキーを取りこぼす
・検索やコマンドラインなどで入力できない
・カタカナモードでの変換結果がかなを含む場合はトグルする必要がある(▽ヨミカタ→「読ミ方」)
・Chaliceでは[SKK:あ]が表示されない
その他:
mfdは200はないとダメみたいです。
Lisp対応は(concat "hoge")ってのだけあれば十分だと思います。
今後に大いに期待しておりますので、がんがって!
662 :
658 :2005/11/25(金) 17:22:12
>>659 >>660 さっそく使ってみてくれてありがとう。
>>661 素早い手直しありがとうございます。
ほとんど使わせてもらいましたが、
> ・▽を<C-H>で削除した後に挙動がおかしくなる現象を修正
これがよくわからないので詳しく説明して!
> ・gSで辞書を手動セーブ
ここにすると skk_keep_state == 0 のときに map されないので、
グローバルにしてみました。skk_manual_save_jisyo_keys を
空にするとこのグローバルマッピングは行わないことにしました。
> " skkサーバなんちゃって対応 (設定するとL辞書は読まない)
> let skk_external_prog = "/usr/bin/env ruby -Ke ~/ruby/skkservcaller.rb -w"
これはskkサーバを動かしていないのでわからない。取り入れたけど。
> ・「. /./・/。/…;.../」のような . や \ などを見出しに含むエントリがおかしい。
これは直しました。これを直してるときに SkkSaveEnv のバグを
発見したのでここも直しました。
> ・タイプ速度が速いとキーを取りこぼす
これは腕がないので再現できません。とりあえず screen の paste では
取りこぼしはないように見えるんだけど…。
> ・検索やコマンドラインなどで入力できない
やる気はあるけどちょっと時間がかかりそう。
> ・カタカナモードでの変換結果がかなを含む場合はトグルする必要がある(▽ヨミカタ→「読ミ方」)
これはわりとすぐにできそうです。
> ・Chaliceでは[SKK:あ]が表示されない
これは確かに自覚症状があったので、ちょっと調べてみます。
とりあえず今日できたところまで
ttp://www.jt200x.com/uploder/src/up0309.zip
>>662 おお、ありがとうございます。良い感じです。
> > ・▽を<C-H>で削除した後に挙動がおかしくなる現象を修正
> これがよくわからないので詳しく説明して!
次の手順で再現できると思います。
/ "▽|"
<C-H> "|"
/ 'Already in ▽ mode'
> elseif b:skk_henkan_mode == 1 && s:SkkCursorCol() < b:skk_hstart
ここでのSkkCursorCol()はカーソル移動「前」の値なので
"<"が成立せず、▽を消しても▽モードから抜けられない結果になります。
「消去後に、変換開始位置とカーソルが一致する」のが正しい条件なので:
> elseif b:skk_henkan_mode == 1 && s:SkkCursorCol() <= b:skk_hstart + 2
> > ・タイプ速度が速いとキーを取りこぼす
> これは腕がないので再現できません。
マシンがボロい(か、辞書がデカい)と再現するのかもです。
> > let skk_external_prog = "/usr/bin/env ruby -Ke ~/ruby/skkservcaller.rb -w"
> これはskkサーバを動かしていないのでわからない。取り入れたけど。
あるといろいろ面白いですよ。複数辞書に対応できたりして。
本当はvim scriptで直接サーバと更新できるといいのですが。
.vimrcの設定例を晒しておきましょう。 let skk_jisyo = "~/.skk-vim-jisyo" " .skk-jisyoだとemacsが起動してたら危険 let skk_show_candidates_count = 2 " これ気が効いてる let skk_keep_state = 1 let skk_egg_like_newline = 1 let skk_show_annotation = 1 let skk_special_midasi_keys = ">" " ?は普通に使いたい let skk_user_rom_kana_rules = "" \. "z<《\<NL>" \. "z>》\<NL>" \. "z \<NL>" let skk_user_rom_func_rules = "" \. ";SkkSetHenkanPoint1(kana)\<NL>" " 要はサーバさえ呼べれば何でもいい let skk_external_prog = "/usr/bin/env ruby -Ke ~/bin/skkservcaller.rb -w" set maxfuncdepth=200 実際このスクリプトはかなりのものだと思うので、 できるだけ早い段階で陽の当たる場所へ出してやってほしいです。 vim scriptのSKK! かなりインパクトありますよ。
>>663 なるほどよくわかりました。ただ skk_marker_white を変数に
しているので strlen(g:skk_marker_white) としました。
・カタカナモードでの変換結果がかなを含む場合
これは直しました。
・Chaliceでは[SKK:あ]が表示されない
これは調べてみたら Chalice は statusline を使っていて
親切にも chalice_status_line という変数があったので
let chalice_statusline = '%{SkkGetModeStr()}'
とすれば表示されるようになりました。
>>664 >>665 もうちょっとこの場所で続けさせてください。
ttp://www.jt200x.com/uploder/src/up0548.zip
# skk.vim 良いっすね。 期待してまつ。
>>666 それ、vim-devに投げてみたらどうですか? 結構賛同者は多い予感がします。
>>669 まともに受け答えできそうにないのでやめときます。
いやほんとお恥かしい…。
>>670 インストールの手順とかSpiderMonkeyのリソースなどについて、日本語で簡単に解説
してもらえますか? 何が必要で、どこから持ってきてどうすれば良いのかとかどんな
環境で動作確認できたとか。
# これだけの仕事量をうもらせてしまうのは忍びありません
>>672 乙。でも使用方法や例といった本当のドキュメントも欲しいなぁ。
っちゅうか、ドキュメントなかったら、相手してくんないかも。
675 :
名無しさん@お腹いっぱい。 :2005/12/01(木) 19:08:05
あ…あの… カレントファイル名フルパスの文字列の長さを得るにはどうすればよろしいですか…?
:echo expand("%:p")
違った... :echo strlen(expand("%:p"))
最近やたら濃かったから、何か清々しくていいなw
680 :
名無しさん@お腹いっぱい。 :2005/12/02(金) 12:30:57
二行以上(表示が)になってしまう行は、背景を違う色にしたいのですが、どうすればよろしいですか?
681 :
名無しさん@お腹いっぱい。 :2005/12/02(金) 13:07:17
ファイルパスの文字列からファイル名文字列のみ抽出するにはどうすればいいですか?
>>681 :echo fnamemodify("/path/to/file.txt", ":p:t")
>>682 ムリ。一時的に強調するだけならなんとか…
function! MatchLongLine()
let w = winwidth("%")
let w = w - &foldcolumn
if &number
if v:version >= 700
let w = w - &numberwidth
else
let w = w - 8
endif
endif
if &list && &listchars =~ 'eol:'
let w = w - 1
endif
if has('signs')
redir @a
silent sign place
redir END
if @a =~ 'line='
let w = w - 2
endif
endif
execute 'match Error /^.*\%>' . w . 'v..*$'
endfunction
683 :
名無しさん@お腹いっぱい。 :2005/12/05(月) 01:31:37
ありがとうございました^^
skk.vimの調子はいかがー?
>それとコマンドラインに入ったときは必ず off の状態になるように
>したんですが、ここら辺への意見を聞かせてください。
>>685 コマンドラインでは日本語を入力することはあまりないので問題な
いと思います。
検索の場合は日本語を入力することも多いでしょうから前回の状態
を保存できるといいかもしれません。
>skk.vim 変換候補の先頭でのxと末尾でのスペースの挙動が変です。 例えば、 1) A:藹 S:姶 D:会 F:饗 [残り 0] 2) あい<space> となります。まぁホンモノのskkは知らないのだけれど。 あとできればESCで変換をキャンセルしたいです。 困ったときのESC連打が通用しないとパニくります。
>>685 imapやcmapじゃなくてlmapを使うと
状態管理とかしなくていいし楽なんじゃなかろうか。
mapのバッティングとか気にしなくていいし、
カーソルの色も変るし。
>>687 > 変換候補の先頭でのxと末尾でのスペースの挙動が変です。
第一候補で x 読みに戻す。
最終候補で <space> 登録モードに入る。
ということでしたらこれは正しい挙動だと思いますが…。
> 困ったときのESC連打が通用しないとパニくります。
困ったときは <C-g> を連打してください。
>>688 > imapやcmapじゃなくてlmapを使うと
> 状態管理とかしなくていいし楽なんじゃなかろうか。
あ、これいけるかも。
lmap = keymapファイルというイメージがあったので、
端から除外していました。
ちょっととりかかってみます。
undoはなんとかしたいところだが、これはvimscriptの構造的な問題だな。 scriptをブロック化してundoの単位を指定する命令がないんだもん。
vimでプロセスを起動してそのプロセスと通信するにはどうすれば いいですか? emacsのstart-process, process-send-stringのようなものです。
>>685 コマンドラインや検索ではskk_egg_like_newlineが効いていないようです。
あと、コマンドラインや検索を<C-H>で抜けられなくなるようです。
>>692 if_perlとかif_rubyとか使うのが簡単じゃないすかね。
もしくはvimと他プロセスを仲介してくれるサーバーを書くとか。
if_rubyの実際の使用例やサンプルって:h ruby以外にはありませんか? ruby側と引数をやり取りする方法とかさっぱりわかんないっす。
>>694 >もしくはvimと他プロセスを仲介してくれるサーバーを書くとか。
そのサーバとどうやってやりとりするのですか?
skk.vimがないのですが。 再うpきぼんです。
>>697 :!client send message > result
とかlibcall()とか
クライアントの中身はソケットでもSendMessage()でもなんでも
>>700 どうも。if_{perl,ruby}使った方が楽そうですね。
skk.vim
>>693 とりあえず回避しました。
maxfuncdepthの件
おおよそ今までの半分ぐらいで大丈夫になったんじゃないかと思います。
(本当はループで回せればいいんだけど再描画がうまくいかなくて...。)
暫定バージョンです。
ttp://49uper.com:8080/html/img-s/99866.zip cmapの<c-\>eと<c-r>=の違いについて
throwすると<c-\>eの方はすぐに反応が返ってくる(input()を抜ける)のに、
<c-r>=だと固まる(というかinput()を抜けずにそのままの状態でいる)
わけを誰が知っていたら教えてください。
c_CTRL-R_= の処理でエラーチェックしてないから この辺 *** ex_getln.c.orig Tue Dec 13 19:04:59 2005 --- ex_getln.c Tue Dec 13 19:28:15 2005 *************** *** 1048,1053 **** --- 1048,1054 ---- break; #endif + case_esc: case ESC: /* get here if p_wc != ESC or when ESC typed twice */ case Ctrl_C: /* In exmode it doesn't make sense to return. Except when *************** *** 1094,1099 **** --- 1095,1105 ---- save_cmdline(&save_ccline); c = get_expr_register(); restore_cmdline(&save_ccline); + if (get_expr_line() == NULL) + { + beep_flush(); + goto case_esc; + } } } #endif
>>703 ありがとうございます。
ということは、現時点では <C-\>e を使うしかないということか…。
まぁ、登録の時だけなので cmap を切り替えてやってみます。
skk.vimで▽モードのときに色を付けるのはvimスクリプトでは無理?
漢字変換の仕方がわからない、、、
skk.vim をwindowsで使用しているのですが、 skk_jisyoに空白があるパスを指定するとエラーが出てしまいます。 この場合何か特別な書き方があるんでしょうか?
skk.vim,便利に使わせて頂いてます. 2点報告と,1点要望です. その1 single-repeatの挙動 あほ あほ あほ 1. コマンドラインで /あほ (「あほ」を検索) 2. 最初の「あほ」の「あ」の位置で cwばか<esc> ばか あほ あほ 3. n.n. ばか ばか ばか となってほしいところが ばか bばkか bばkか となる
その2 変換中に折り返しが来る場合の挙動 1. :set tw=20 (便宜上,少な目に) 2. 行頭から以下を入力(日本語モードで) choudoOrikaesi<spc><c-j>deHenkan ちょうど折り返しで▽ hへんかん となる その3 skk_imみたいにモード表示がほしい (これはただの要望なので,聞き流してください)
>>710 モード表示ありますよ。
se stl&
712 :
710 :2005/12/17(土) 00:32:16
>>711 ありがとう,知りせんでした.
しかも skk_im ってなんだよ…
im_customの間違いでした orz
>>700 dllの中で自身をロードすれば、libcallの呼び出し後もdllは開放されないので、
状態を保持しなきゃいけないような拡張もlibcallとdllだけで可能。
>>708 let skk_jisyo = 'C:\Program\ Files\hoge' または
let skk_jisyo = "C:\\Program\\ Files\\hoge"
>>709-710 うーん、どっちも悩ましい問題です…。
しばらく宿題とさせておいてください。
715 :
708 :2005/12/19(月) 19:39:07
>>714 ありがとうございます。無事下記のようにして読み込むことができました。
let skk_jisyo = escape( $VIM ,' ').'\_skk-jisyo'
>>716 実は私もvim-uimをrubyで作ろうとしていたのでした。(まだ手をつけていないけど)
今後の開発に期待しております。
みんな濃いなあ。。。 やっぱり日本語入力はvimmer共通の悩みなのね
>>716 コマンドラインを使えば、プリエディットに色をつけれるのか。
バッファ内にプリエディットを表示させるときは色はつけれないで
すよね?
例えば、2行3列目の文字を強調する :syn match Error /\%2l\%3c./ とか細かい指定もできるので一応できます。 ただ、C言語のコメントのような、syn-regionで範囲指定された 空間の中はどうがんばっても無理です。たぶん。
722 :
名無しさん@お腹いっぱい。 :2005/12/27(火) 13:13:46
s/>704/>709 の間違いでした...
# skk.vim vim.org の scripts に入れて見られてはどうですか? 結構日本人には、反響あると思いますし、防火壁内の人にも よいのでは? # もちろんそのあかつきには、「Life Changing」です。
>>709 に関してはバッチリ直っていることを確認しました.
(前バージョンでは出なかった)以下のエラーが出ました.
例えば
>>710 の操作で再現すると思います.
Error detected while processing function <SNR>18_SkkKey..<SNR>18_SkkInsert..<SNR>18_SkkInsertKana..<SNR>18_SkkEraseRom..<SNR>18_SkkDeleteRange:
line 23:
E474: Invalid argument: backspace+=indent,eol
Error detected while processing function <SNR>18_SkkKey:
line 42:
E171: Missing :endif
…いつも報告ばかりでスミマセン.
大掃除が終わり次第自分でも中身を見てみたいと思いますが,取り急ぎご報告まで.
>>724 こちらでは再現できません。
vim のバージョンはいくつでしょうか?
また、set backspace=indent,eol か
let &backspace = "indent,eol"
でエラーは出ますか?
726 :
725 :2005/12/28(水) 18:41:33
>>724 理由がわかりました。'backspace' の値が数値だとエラーが出るようです。
以下のパッチを当ててください。
1121c1121
< set backspace+=indent,eol
---
> set backspace=indent,eol
1196c1196
< set backspace+=indent,eol
---
> set backspace=indent,eol
1297c1297
< exe "lnoremap <silent> <buffer> " . g:skk_abbrev_to_zenei_key . " <C-r>=<SID>SkkKey(\"<C-v>" . g:skk_abbrev_to_zenei_key . "\")<CR>"
---
> exe "lnoremap <buffer> " . g:skk_abbrev_to_zenei_key . " <C-r>=<SID>SkkKey(\"<C-v><C-q>\")<CR>"
1366c1366
< elseif a:key ==# g:skk_abbrev_to_zenei_key
---
> elseif a:key == "\<C-q>"
727 :
724 :2005/12/28(水) 20:00:54
>>726 素早い反応ありがとうございます.
> 以下のパッチを当ててください。
修正(
>>721 以前のスクリプトの挙動になっていること)を確認しました ♪
728 :
名無しさん@お腹いっぱい。 :2005/12/29(木) 00:23:01
gvim は uim 1.0.0 以上の vim 協調モードでOKな気がする。 コンソールは uim-fep でこれまたOK
文章書きたい人には毎回offで始まる協調モードはあまりOKじゃないっす。
onだったらコマンド送れないやん
そりゃ当たり前。 だからコマンドモードではoff、挿入モードではonまたは前回と同じ状態という 制御が求められるのですよ。
>>716 こりゃいーわ
imcustomみたいで
というかgvimのmbyte.cは腐ってるから、誰か書き直さない?
先生!アボートしますた。 *** glibc detected *** double free or corruption (out): 0x085089e8 *** Vim: 致命的シグナル ABRT を検知しました
インストールされているカラースキームを数秒ごとにスライドショーのように 表示するスクリプト、作成お願いします。
let i = 0 let color_files = globpath(&runtimepath, "colors/*.vim") while i < strlen(color_files) let file = matchstr(color_files, "[^\n]*", i) execute "source " . file redraw echo g:colors_name let i = i + strlen(file) + 1 sleep 1 endwhile
神光臨! それにしても、colors_name を設定していない不届き者が何名がおるの。 自分がインストールしている範囲で、6カラースキームあった。
skk.vim取れないよん 再うpよろ
>>740 ありがとうございます。DLできました。
742 :
739 :2006/01/20(金) 00:55:45
あー、ちょっとこのスレ覗かないうちに・・ うpしてくれたけど、もう落とせない・・ ガーソ
745 :
743 :2006/01/23(月) 09:25:21
>> KoRoN 様 お手数をおかけして申し訳ありません。 ありがとうございました。
746 :
743 :2006/01/24(火) 02:27:19
vimスクリプトの関数って2つの値を返す、もしくは引数の値を書き 換えることってできないのですか?
>>747 function! Test()
let l = [1, 2]
return l
endfunction
let r = Test()
echo r[0]
echo r[1]
では駄目ですか?
そうですね。 vim6 では、セッション変数を利用するしかないと思われます。 # もしくは改行などのセパレータを使った文字列を返す等
知らんかった。感動した。 :let filename = "hoge.txt" :e `=filename`
gvimでなくvim(GUIでなくターミナルでvimが起動している)という判定を vimscriptで書くとどうなりますか?
:echo has('gui_running')
>>752 if has("gui_running")
"GUI
else
"CUI
endif
vim scriptだけでskkが動くのならmigemoもできるかも?
>>756 1行の候補を探せば良いだけのSKKと、探し出した複数行の候補を正規表現へ組み立て
なければならないMigemoでは少し事情が違い、大量のCPUとメモリを使ってしまうで
しょう。回避策はいくつか考えられますが、実用になる速度+メモリで動くようにな
るには少し時間がかかる気がします。
scriptの中で % s/a/b/g を実行したときにaが見つからないと ↓ 処理中にエラーが検出されました。 E486: パターンはみつかりませんでした。: a ↑ のようなエラーメッセージが表示されてうるさいので try〜catch文で囲ってるんですがどうもcatchできない みたいです。パターンがなくてもエラーメッセージが 出ないようにしたい場合どうすればいいんでしょうか?
%s/a/b/ge :h :s_flags
761 :
名無しさん@お腹いっぱい。 :2006/02/24(金) 13:46:01
:let foo = "Hello World" :echo foo Hello World :let foo = 5 :let bar = "2" :echo "foo+bar=" . (foo + bar) foo+bar=7
762 :
名無しさん@お腹いっぱい。 :2006/03/14(火) 10:56:49
764 :
710 :2006/03/15(水) 06:55:59
>>762 素晴らしいです.実用には十分です.
現在も100% skk.vimを常用しているので引き続きテストします.
本当にありがとうございます.
skk.vim すげぇぇぇ!!!!
良スレ
767 :
名無しさん@お腹いっぱい。 :2006/04/24(月) 00:54:56
>>751 えと、これはどう解釈したらいいのでしょ?
`=foo` の部分がどういう意味の構文だかわからんす。
:h `-expansion
テキストファイルがたくさんあって中身に必ず"DT[YYYY-MM-DD]"という文字列が あります(YYYY-MM-DDは年月日)。これらのファイルのうち例えば1989年以降の ファイルだけカウントしたい場合どうしたらよいでしょうか? s/DT\[\([0-9]\{4}\)/\1/g の\1みたいにマッチした文字列を変数に取り出すみたいなことはできるのでしょうか。
vimよりは、普通にegrep+wcでやっつけたほうが楽だとおもうけど...
よくわかんないけどこういうの? function! Func() let year = matchstr(getline('.'), 'DT\[\zs\d\{4}\ze-\d\{2}-\d\{2}\]') if year >= 1989 echo "ウホッ" endif endfunction g/DT\[\d\{4}-\d\{2}-\d\{2}\]/call Func()
772 :
769 :2006/05/03(水) 22:55:57
>>771 おおっありがとう。
function! CountPeriod( period )
let s:check_sum = 0
let s:period_sum = 0
bufdo call s:DoCounts( a:period )
echo a:period "以降のファイルは" s:period_sum "個でした。"
echo "チェックしたファイル数 "s:check_sum
endfunction
function! s:DoCounts( period )
g/DT\[\d\{4}[0-9\-,]*\]/call s:Counts( a:period )
endfunction
function! s:Counts( period )
let s:check_sum = s:check_sum + 1
let year = matchstr(getline('.'), 'DT\[\zs\d\{4}\ze[0-9\-,]*\]')
if year >= a:period
let s:period_sum = s:period_sum + 1
endif
endfunction
こんな感じで思っていた事ができました。
773 :
名無しさん@お腹いっぱい。 :2006/05/11(木) 17:49:17
不特定多数行の内、 folderの単語の無い行を取り去りたいのですが、どうしたらよいですか?
:g/folder/d かな? 「folderの単語の無い」っていうのの意図がわかりません。
775 :
名無しさん@お腹いっぱい。 :2006/05/11(木) 18:45:12
"folder"という単語が一度も登場しない行の事です。
776 :
名無しさん@お腹いっぱい。 :2006/05/11(木) 18:53:00
要するに、"folder"が登場する行をコレクトしたいのです。
:v/folder/d のことか
778 :
名無しさん@お腹いっぱい。 :2006/05/11(木) 23:12:54
ありがとう匿名の人
:g!は:vとも書けるのか、はじめて知った でもスレ違い気味だね
vim7にしてkaoriyaのパッチを当てたけど、migemoが効かない。 :versionでは+migemoになってるのに。
スマン。書くスレ間違えた。
782 :
780 :2006/05/14(日) 21:32:12
migemodictが設定されてませんでした。
http://tokyo.cool.ne.jp/hopper2/vimproc.zip Vimスクリプトでプロセス間通信やソケット通信しちゃうライブラリ。
例えばこのように遊べます...
let sock = g:vimproc.socket_open("www.yahoo.com", 80)
call sock.write("GET / HTTP/1.0\r\n\r\n")
let res = ""
while !sock.eof
let res .= sock.read()
endwhile
call sock.close()
for line in split(res, '\r\n\|\r\|\n')
" ...
endfor
>> 783 おもすれー。 ところで proc.vim の関数定義で書いてある dict ってどういう意味があるのでしょうか。
dict を指定した関数では self という変数が暗黙的に使えるようになります。 c++ の this や python の self みたいなもんです。 ディクショナリとともに使い、オブジェクト指向っぽいコードが書けます。 :help Dictionary-function より :function Mylen() dict : return len(self.data) :endfunction :let mydict = {'data': [0, 1, 2, 3], 'len': function("Mylen")} :echo mydict.len() この例だと、selfにはmydictが代入されます。 普通の関数と同じようには呼べません。 :call Mylen() <- これはエラーになる 関数の定義とディクショナリへの設定をまとめてすることもできます。 :help numbered-function より :let mydict = {'data': [0, 1, 2, 3]} :function mydict.len() dict : return len(self.data) :endfunction :echo mydict.len() (この方法で定義した関数には名前ではなく番号が付けられるので、 エラーが起きたときに「関数 3 でエラー」みたいに表示されて泣けます)
786 :
784 :2006/06/21(水) 11:35:50
いえ、dict を指定しなくても self が参照できるため、疑問に思ったのです。 :let mydict = {'data': [0, 1, 2, 3]} :function mydict.len() : return len(self.data) :endfunction :echo mydict.len() という dict を書かない書き方でも self が参照でき、 期待した値が帰ってくるので、dict 書かなくてもいいんじゃないかなぁ、 と思った次第です。
あーホントだ。 It is not necessary to use the "dict" attribute for a numbered function. ですね。気づかなんだ。
>>784 の vimproc を利用して簡単な HTTP クライアントを作ってみました。
http://www.bigbold.com/snippets/posts/show/2227 let h = HTTP.new('www.bigbold.com')
let res = h.get('/snippets/')
echo res.headers
if res.code < 400
echo res.body
else
echo 'error ' . res.code
endif
などして使うことができます。
エラー処理周りは全くやってないのでお遊び程度にしか使えませんが…。
むー、
>>783 のやつ面白そうなんだけど、
Windowsでも使えるようにするには、どうやってコンパイルしたらいいんだろー
Windowsでも使えるようにしたので適当にどうぞ。urlは同じです。dllも入ってます。 vimproc.dllはVisual Studioでコンパイル、vimproc_mingw.dllはmingwでコンパイル したやつです。たぶん大丈夫だろうけどダメなら交換してください。 pipeは怪しいけど他はそれなりに動くと思います。 ...ちゃんとマニアックな人がいて良かったw
>>790 やーべー、言ってみるもんだw
ありがとーです。遊ばしてもらいます。
skk.vim
毎回毎回同じローマ字ルールを計算するのも無駄なので SkkAddRulesSection()
というのを作りました。これはコンパイル済のデータを自分自身に書き込みます。
読み込み時間は多少増えますが、気にならないレベルだと思います。
削除するには SkkDeleteRulesSection() を呼んでください。
あと vim7 にも対応したつもりです。
それと、いつまでも KoRoNさんのところをお借りしているわけにもいかないので、
まっつんさんが言われたように vim.org の scripts に公開してみることにしました。
ttp://www.vim.org/scripts/script.php?script_id=1589
キタ━━━━━━(゚∀゚)━━━━━━ !!!!!
function! g:GetHere() redir => str silent function g:Here redir END let lines = split(str, '\n')[1:-2] " 前後のゴミ(関数宣言)を削除 let lines = map(lines, 'v:val[3:]') " 行番号を削除 return join(lines, "\n") endfunction function! g:Here() ねんがんの ヒアドキュメント をてにいれたぞ endfunction let a = g:GetHere() function! g:Here() これは ヒアドキュメントです ウヒョヒョ endfunction let b = g:GetHere()
どうって言われてもな。見たまんまだよ :fu! g:Here() : テキスト :endf :echo g:GetHere() テキスト
>>794 うまいね。vimスクリプトでここまでトリッキーな
技は始めて見た。
Vimの関数はグローバル関数と無名関数の二種類しかないという話。 fun Func() endf fun g:Func() <- Func()とは区別される endf fun g:func() endf fun b:func() endf fun w:func() endf fun s:func() endf fun hogehoge::func() endf 全部グローバル関数。 b:とかw:とかに特殊な意味はなくて、単に関数名にコロンが使えるってことでしかない。 s:func()は特別扱いだけど、<SNR>123_func()という特殊な名前のグローバル関数に 過ぎないので、スクリプト番号さえわかればどこからでも呼び出せる。 ちなみに関数と変数は名前空間が分かれている。
let h = ["black", "darkblue", "darkgreen", "darkcyan", "darkred", "darkmagenta", "brown", \ "lightgray", "darkgray", "blue", "green", "cyan", "red", "magenta", "yellow", "white"] for i in range(16) execute printf('syn match _%x /\c%x/', i, i) execute printf('hi _%x guifg=%s guibg=%s ctermfg=%s ctermbg=%s', i, h[i], h[i], h[i], h[i]) endfor put =' A ' put =' A2A ' put =' 7777777777777AA222AA7777777777777777' put =' 788888888888822222227888888888888888' put =' 00888888888002222222008888888888000 ' put =' 888888888222222222278888888800 ' put =' 7888888882222222227888888880 ' put =' 788888888222222277888888800 ' put =' 78888888822222278888888802A ' put =' 788888888222277888888800222A ' put =' A7888888882227888888880222222AA ' put =' A2788888888277888888800222222222A ' put =' AA227888888887888888880222222222222AA '
put ='22222788888888888888880022222222222222A' put =' 2222788888888888888008822222222222200 ' put =' 227888888888888002888222222222220 ' put =' 2788888888888022222222222222220 ' put =' 7888888888002222888228888828888 ' put =' 78888888802222228882288888888888 ' put =' 788888800222222288822882288 88 ' put =' 788888022222222888822882 88 88 ' put =' 788800 222222228882288 88 88 ' put =' 7880 22222228882288 88 88 ' put =' 780 222228882 88 88 88 ' put =' 00 2222888 88 88 88 ' put =' 220 ' put =' 0 '
メールアドレスを補完する completefunc を作ろうとしたけど 完全なものにするのはかなり大変だとわかった。 誰か改良して。 function! CompleteMail(findstart, base) if a:findstart let line = getline(".") let start = col(".") - 1 while start > 0 && line[start - 1] =~ '[A-Za-z@\.\-]' let start -= 1 endwhile return start else let res = []
while 1 let match = search('\<' . a:base, "bW") if match <= 0 return res endif let line = getline(".") let b = col(".") - 1 let e = match(line, '[^A-Za-z@\.\-]', b + 1) if e < 0 let e = strlen(line) endif call add(res, strpart(line, b, e-b)) if complete_check() return res endif endwhile endif endfunction set completefunc=CompleteMail
こんなかんじだろうか function! CompleteMail(findstart, base) if a:findstart let str = getline(".")[: col('.') - 2] let start = match(str, '[[:alnum:]_.-]*\%(@[[:alnum:]_.-]*\)\=$') return start else redir => str silent g/[[:alnum:]_.-]\+@[[:alnum:]_.-]\+/ redir END let mx = '[[:alnum:]_.-]\+@[[:alnum:]_.-]\+' let i = match(str, mx) while !complete_check() && i != -1 let address = matchstr(str, mx, i) if stridx(address, a:base) == 0 call complete_add(address) endif let i = match(str, mx, i + len(address)) endwhile return [] endif endfunction
805 :
名無しさん@お腹いっぱい。 :2006/09/11(月) 10:54:33
ふと。skk.vim にも変換予測が付かないかと思ってしまった。
>>805 変換予測って具体的にはどんなイメージですか?
807 :
名無しさん@お腹いっぱい。 :2006/09/11(月) 23:22:16
808 :
名無しさん@お腹いっぱい。 :2006/09/12(火) 01:50:44
>>807 そこまでいっちゃうと skk じゃないような気がします。
skk-dcomp.el みたいなやつ?
>>810 そうですね。そこらへんならそんなに操作性も変わらないし。
タイマーっぽい set updatetime=1000 autocmd CursorHold * call Timer() function Timer() echo strftime("%c") let K_IGNORE = "\x80\xFD\x35" "特殊な内部コード call feedkeys(K_IGNORE) endfunction
一番でかいvimスクリプトってなんだろう。chalice?
815 :
高一 :2006/09/23(土) 10:50:13
タイムサービスに勝つスクリプトってありますか? 瞬時に住所、名前とかかけちゃうような・・・ なんでもいいので攻略法あったら教えて下さい
816 :
名無しさん@お腹いっぱい。 :2006/09/24(日) 08:56:08
あげ
817 :
名無しさん@お腹いっぱい。 :2006/09/24(日) 18:12:57
なんで?
外部ファイルから文字読込んで、ループで対象文字を検索して、 それを変数に代入するコードはどんな感じになるでしょうか?
こんな感じ? function F(fname, pat) for line in readfile(a:fname) if line =~ a:pat let match = matchstr(line, a:pat) endif endfor endfunction
820 :
名無しさん@お腹いっぱい。 :2006/09/28(木) 03:49:31
setで変数をオプションに代入したいのですがうまくいきません set fdc=3 と定数にするとうまくいきます fun! Outline#Set(...) let fdc_ = 3 if a:0==1 let fdc_ = a:1 endif set foldmethod=expr set foldexpr=Outline#FoldLevel(v:lnum) set fdc=fdc_ "E521: = の後には数字が必要です: fdc=fdc_ endf com! -nargs=? Outline call Outline#Set(<args>)
822 :
名無しさん@お腹いっぱい。 :2006/10/02(月) 06:20:22
rubyで作った文字列とかvim scriptの変数にいれれるん? fu! Aaaa() let vimstr = "" ruby vimstr = "Hello Ruby!!" ....
レジスタとか経由すれば
rubydo VIM::command('let g:xyz=45')
825 :
822 :2006/10/04(水) 22:17:44
826 :
名無しさん@お腹いっぱい。 :2006/10/13(金) 10:08:09
10行コピーしたレジスタから、1行1行取り出して処理を加えるにはどうすればいいでしょうか?
829 :
名無しさん@お腹いっぱい。 :2006/10/13(金) 12:25:57
>>827 iabbrevで指定位置へのカーソル移動と複数箇所の同時編集をできるようになる。
例えば
:Iabbr class class <class><CR>{<CR>public:<CR><class>();<CR>virtual ~<class>();<CR><><CR>};
"class<space>a<S-Del>"
と入力すれば
class a
{
public:
a();
virtual ~a();
<カーソル位置>
}
というテキストが入力される。
TextMateのエミュか。 まえにTextMateのデモムービー見て感動したなぁ。 使い方も簡単だしけっこう良さげだね。
>>828 let lines = split(@@, '\n')
for i in range(len(lines))
let lines[i] = "hoge"
endfor
call setreg("@", join(lines, "\n"), getregtype("@"))
832 :
名無しさん@お腹いっぱい。 :2006/10/28(土) 00:16:14
833 :
名無しさん@お腹いっぱい。 :2006/10/28(土) 20:52:52
こんなのつくってみた。+migemoでない人向け。 if has("migemo") finish endif let cmigemo_cmd = "cmigemo -q -v -d /usr/local/share/migemo/euc-jp/migemo-dict" fun! s:init_cmigemo() let s:in = tempname() let s:out = tempname() let cmd = 'touch ' . s:in . '; mkfifo ' . s:out . "\n" let cmd = cmd . 'tail -f ' . s:in . '|' . g:cmigemo_cmd . '|' let cmd = cmd . 'while read -r line; do ' let cmd = cmd . 'echo "$line" >' . s:out . ';' let cmd = cmd . 'done & jobs -ls' let s:pids = substitute(system("sh", cmd), "\n", " ", "g") au VimLeavePre * call system('kill ' . s:pids) endf fun! s:search_cmigemo(str) if !exists("s:in") call s:init_cmigemo() endif return system('sh', "echo '" . a:str . "' >>" . s:in . '; cat ' . s:out) endf
続き fun! s:query_cmigemo(dir) let str = input('migemo' . a:dir) if !strlen(str) return '' endif let str = s:search_cmigemo(str) return strlen(str) ? a:dir . str : '' endf nnoremap <silent> <expr> g/ <SID>query_cmigemo('/') nnoremap <silent> <expr> g? <SID>query_cmigemo('?')
たしかmigemo.vimにも+migemoでない場合の処理が書いてあったと思いますよ。
そうなんだけど検索するたびにcmigemoを起動して辞書を読むのを避けて 2回目以降は前に起動したのと会話するようにしたつもりなんだけど...
gVimなんですが、ウインドウのサイズって取得できますか? やりたいのは 1. サイズ取得して変数x, y にいれとく 2. フォントのサイズを変える 3. winsize x y でサイズを戻す これだけなんですが。
let x = &columns let y = &lines
841 :
839 :2006/11/22(水) 20:21:12
>>840 ありがとうございます。
ちょっと勘違いしていました、winsizeはピクセルで指定するものだと・・
フォントのサイズを変えると、ウインドウのサイズも変わってしまうので
それを防止したかったんです。
vimにて、 :split FILE などで、別ディレクトリにあるファイルを開いたとき、 また、 ^W h などで、ウィンドウ(?)を切り替えたときに 自動でそのファイルがあるディレクトリにチェンジディレクトリするようにするには どうすればよいでしょうか?
:set autochdir または :autocmd BufEnter * :cd %:p:h たぶん
844 :
852 :2006/11/28(火) 09:30:37
>>843 思い通りの動作をするようになりました。
どうもありがとうございます。
let count = 1 E46: Cannot change read-only variable "count" (゚Д゚)
vimwiki の incbufswitch.vim を使いやすくするべく改造 していたんですが、いつのまにか echo "\r" が効かなく、 候補リストが複数行にわたる場合、前の表示が残るように なってしまいました。どこを直せばいいでしょうか? command! ISwitchB :call ISwitchB() hi link ISWitchBCurrent Search hi link ISWitchBOnlyOne IncSearch function! ISwitchB_ShowList(buflist, partial_name, current) echon "\riswitch " . a:partial_name . "{" let i = 0 for fname in a:buflist if i != 0 echon "," endif if i == a:current if len(a:buflist) == 1 echohl ISWitchBOnlyOne else echohl ISWitchBCurrent endif endif echon fname if i == a:current | echohl None | endif let i = i + 1 endfor echon "}" endfunction
function! ISwitchB() let orig_bufnr = bufnr("%") let altbufnr = bufnr("#") let lastbuf = bufnr("$") let allbuflist = [] " 代替バッファ # がリストの先頭に来るように if bufexists(altbufnr) != 0 && buflisted(altbufnr) call add(allbuflist, expand("#" . altbufnr . ":t")) endif let i = 1 while i <= lastbuf if bufexists(i) != 0 && buflisted(i) && i != altbufnr && i != orig_bufnr call add(allbuflist, expand("#" . i . ":t")) endif let i = i + 1 endwhile let buflist = allbuflist let partial_name = "" let current = 0
while 1 call ISwitchB_ShowList(buflist, partial_name, current) let c = getchar() if c == 13 " <CR> 決定 exe "silent buffer " buflist[current] break elseif c == 27 || c == 3 " <ESC> or <C-c> キャンセル echon "\r " break elseif c == "\<BS>" let partial_name = strpart(partial_name, 0, strlen(partial_name)- 1) if partial_name == "" | break | endif elseif c == 9 " <tab> 次のマッチを選択 let current = current + 1 >= len(buflist) ? 0 : current + 1 else let partial_name = partial_name . nr2char(c) endif let buflist = ISwitchB_FilterBufList(allbuflist, partial_name) endwhile " Hit Enter が出ないように call feedkeys("\<left>\<right>") echo endfunction
function! ISwitchB_FilterBufList(buflist, partial_name) let result = [] for fname in a:buflist if a:partial_name == "" || stridx(fname, a:partial_name) >= 0 call add(result, fname) endif endfor return result endfunction
別のやり方としてこんなのはどうかな? --- incbufswitch-color.vim.orig Tue Jan 9 17:36:31 2007 +++ incbufswitch-color.vim Wed Jan 10 09:26:21 2007 @@ -103,6 +103,7 @@ " Perform an incremental buffer switch " function! <SID>IncBufferSwitch() + let v:scrollstart = "" let origBufNr = bufnr("%") let partialBufName = "" let s:tabStop = 0 @@ -155,4 +156,7 @@ "echon ' {'.s:buflist.'}' call ShowBuflist(partialBufName, s:buflist) endwhile + if v:scrollstart != "" + call feedkeys("\<CR>") + endif endfunction
ちらついても構わないなら毎回 :redraw! で再描画するとか 個人的にはwildmenuを使った標準的な方法をお勧めする (:buffer <Tab> および :help :command-completion)
HIT ENTERはfeedkeysで解決できることわかったんですが、 なぜか846のバージョンだと、候補リストが全部消え切らず、残ってしまうんですよ。 一行だけの場合は\rで行頭復帰してそこに上書きするので 前回の候補リストが消えるのですが。 もとのincbufswitch-colorと表示の方法は変えていないし、 なぜこうなってしまったのか原因も気になるんですよね。
redraw してないから
エコーエリアをクリアする関数と Press ENTER プロンプトを表示しない :echo は欲しいね
名無しに反応するオートコマンド :autocmd WinEnter {} :echo "hoge" オートコマンドで否定のパターンは使えないのかなぁ *.txt以外のファイルみたいな
au WinEnter * if expand("<afile>")=~? '\.txt$'|echo|endif amatchとかafileで判定すればいいんじゃない?
>>716 に出てた
http://yukihiro.nakadaira.googlepages.com/#uim-vim これってvim7じゃ動かないのかなぁ?
Error detected while processing function <SNR>16_input..10..22:
とか
E10: \ should be followed by /, ? or &
Press ENTER or type command to continue
Error detected while processing function <SNR>16_input..10..22:
とかいうエラーがでまくるんだが
>>858 むしろ vim7 でしか動かないです。
E10 エラーは行継続の \ が原因だと思います。
compatible モードで使ってたりするんでしょうか。
行継続を使わないように変更したので新しいやつを試してみてください。
>>859 compatible モードで使ってました
でも新しいやつ試したら日本語入力でキタ━━━━(゚∀゚)━━━━!!!!!!
ありがとうございます
でも今度は日本語入力モードでバックスペースすると
??b
が入力される・・・
文字コードUTF-8にしたら平気だった
EUC-JPじゃ無理ですか?
>>860 修正したので新しいの使ってみてください。
>>861 できるようになりました
ありがとうございます!
これでnvi+canna捨てられるかも
C言語のファイルを開いたときに適切なインデント設定をするスクリプト 単純だけどけっこう楽になった いろんな言語を認識できるようにしたら便利だろうなぁ だれかやってくんないかなぁ… autocmd FileType c,cpp call s:SetIndent() function! s:SetIndent() let pos = getpos('.') if search('{$') != 0 && search('^\s\+\S', 'W') != 0 let &l:shiftwidth = indent(line('.')) let &l:softtabstop = indent(line('.')) let &l:expandtab = (search('^\t') == 0) endif call setpos('.', pos) endfunction
864 :
名無しさん@お腹いっぱい。 :2007/03/28(水) 21:41:19
getchar()の使い方が良く分からない。 下記のスクリプトでは、 Aで、"私の名前は"を表示する Bで、入力する Cで、入力した内容を表示して、その後に"です。"を表示する の様な処理をしたいのですが、実際は下記の様になります。 1. Bで入力をするまで、何も変化は発生しない。 2. Bで入力をすると一気にAとCを表示する。 どこが、まずいのでしょうか?そもそもが、出来ない事をやろうとし ているのだろうか? @function! s:Map(...) A execute "normal i私の名前は\<esc>" B let s:name=getchar() C execute "normal a" . s:name . "です。\<esc>" Dendfunction
865 :
名無しさん@お腹いっぱい。 :2007/04/20(金) 19:23:18
libcallで呼び出されたCの関数のなかでvimの組み込み関数を呼ぶ仕組みは用意されてますか? 高速に補完用のリストを作るためにcall complete_add相当をCの関数の中から呼びたいです libcallの戻り値をcomplete_addに渡すと長い文字列のコピーが行われてしまうかもしれないのでCの関数から直接complete_addを呼びたいです
866 :
名無しさん@お腹いっぱい。 :2007/04/20(金) 19:25:58
沖縄県の方へ(命に関わる注意事項です) 沖縄県での選挙ですが、どうか民主党だけは避けてください。県民の生命に関わる可能性があります。 民主党の最大の公約は一国二制度(※)ですが、一度「一国二制度 沖縄 三千万」で検索をお願いします。 この際、民主党のHPで調べても良いです。以下の注釈↓と矛盾することは書いてないはずですから… ※一国二制度 簡単に言えば沖縄を中国と日本の共有物にし、そこに3000万人の中国人を入植させます。 (つまり沖縄人口の 96% を中国人にして、実質、沖縄を中国人の居住地とします。) さらに「自主」の名の下、沖縄で有事が起きても自衛隊は干渉できません。 3000万人の中国人が、少数派となった130万人の日本人に何をしても、です。 そして反日教育を受けた中国人の反日感情の強さは、ほとんどの日本人の理解を超えるものです。 今回の選挙で民主党が勝った場合、「自主」「発展」を連呼しつつ段階的に進めていくことになります。 自主と言っても、自主を認めるのが「住人の96%が中国人となった」後だということに気をつけてください。 発展と言っても、新沖縄の少数派となった「少数民族日本人」の発展ではないことに気をつけてください。
>>865 pythonの拡張を作ってその中からでvim.eval()を呼ぶみたいな方法しかないとおもう
はやいかどうかはしらん
868 :
初心者 :2007/05/02(水) 13:44:56
GVim7で関数のリファレンスの使い方が良く分かりません。下記で次 の現象となります。どこが悪いのでしょうか? 最初にリストを送ります。 01 if exists("loaded_ShuffleB") 02 finish 03 endif 04 let loaded_ShuffleB=1 05 command! -nargs=? ShuffleB :call <sid>Map(<q-args>) 06 function! s:Map(...) 07 let b:pgname = ["<SID>This1","<SID>This2","<SID>This3"] 08 let b:Prg=function(b:pgname[1]) 09 imap <buffer> <silent> o O<c-o>:call b:Prg("O")<cr> 10 endfunction 11 12 function! s:This1(current) 13 exec "normal o" . a:current . "最初はグー" 14 endfunction 15 16 function! s:This2(current) 17 exec "normal o" . a:current . "最初はチョキ" 18 endfunction 19 20 function! s:This3(current) 21 exec "normal o" . a:current . "最初はパー" 22 endfunction
869 :
初心者 :2007/05/02(水) 13:47:18
先のリストで、下記のエラーが出ます。 どこが悪いのでしょうか? 1. pgnameに<SID>を付加した場合(7行目) oを入力した時にOを表示して下記のエラーが出る E120: スクリプト以外で<SID>が使われました:<SID>This2 2. pgnameの<SID>を外した場合(7行目) 起動時にE700: 未知の関数です: This2が表示される。 oを入力した時にOを表示して、下記のエラーが出る E117: 未知の関数です: b:Prg
>>868-869 "<SID>This2"を"s:This2"という風に書き換えてみてください。
871 :
初心者 :2007/05/03(木) 13:01:04
KoRoNさん、早速ありがどう御座いました。7行目のみ下記の様に変更 しました。 let b:pgname = ["s:This1","s:This2","s:This3"] 実行しましたら、今度は下記のエラーが出ます。 E120:スクリプト以外で<SID>が使われました: s:This2 Windows XP KaoriYaからのVim7.0.216 14-mar-2007を使っています。 頭の悪い初心者ですが、1つ宜しくお願いします。
872 :
初心者 :2007/05/03(木) 13:14:31
全体を下記の様に、修正したら今度は動作する。動いた理由と、前回 のが動かなかった理由が、さっぱり分からない。 下記に今回の内容を示します。 if exists("loaded_ShuffleB") finish endif let loaded_ShuffleB=1 command! -nargs=? ShuffleB :call <sid>Map(<q-args>) function! s:Map(...) let b:pgname = ["b:One","b:Two","b:Three"] let b:Prg = function(b:pgname[2]) call b:Prg(10) imap <buffer> <silent> o O<c-o>:call b:Prg(31)<cr> endfunction function! b:One(current) exec "normal o" . a:current . "最初はグー" endfunction function! b:Two(current) exec "normal o" . a:current . "最初はチョキ" endfunction function! b:Three(current) exec "normal o" . a:current . "最初はパー" endfunction
>>872 function! s:MyFunc()
return 321
endfunction
let Fn = function('s:MyFunc')
echo Fn()
こういうスクリプトをtest.vimとして保存して、so test.vimをすると動きます。と
いうことは、もしかしてfunction('s:...')の、s:の評価は実行時のコンテキストに
依存するのかもしれませんね。
874 :
初心者 :2007/05/03(木) 16:36:43
KoRoNさん、返事有り難う。しかし、最初から実行時のコンテキス トと言われても、範囲が広すぎて途方に暮れる。この場合のコンテキ ストは、何でしょうか? エラーメッセージでは、スクリプト以外で<SID>が使われましたです が、他のスクリプトでは使っていません。実行時に何が影響するのだ ろうか?初心者は挫折しそうだ。
>>874 挫折して済む話ならば、挫折しちゃったほうが良いかも知れませんよ。
まずb:の時に動くのは、それがバッファに対して定義された関数だからです。
ShuffleBを実行したのがそのスクリプトを読み込んだのと同じバッファであれば、特
定可能で呼出せることになります。逆にいうとスクリプトを読み込んだ後で、別の
ファイルを開いてそちらにカーソルがある状態でShuffleBを実行すると、そのファイ
ル用のバッファには関数が定義されていませんから動かないでしょう。
s:についてはちょっと実験してからもう一度書きます。
>>874 っていうか、このスクリプトはどういう目的で何をしようとしているのですか?
なんかいろいろ間違ってる気がしてきました。
>>874-875 実験してみました。結論からいうと
>>870 は誤りで、
>>873 で示唆したように、s:や
<SID>の評価が参照解決の実行時のコンテキストに依存している、ということになり
ます。まずはこのスクリプトをみてください。
function! s:MyFunc()
echo "MyFunc is executed"
endfunction
let g:FnRef = function('<SID>MyFunc')
function! s:KickMyFunc()
call g:FnRef()
endfunction
command! -nargs=0 KickMyFunc :call <sid>KickMyFunc()
このスクリプトを実行するとグローバル変数g:FnRefにs:MyFuncへの関数リファレン
スが格納されます。コマンドKickMyFuncを実行した際には関数s:KickMyFuncを経由し
てg:FnRefが呼出され、正しくs:MyFuncを呼出すことができます。一方、コマンドラ
インで:call g:FnRef()と直接呼出した場合にはE120が発生します。これはつまり、
関数の参照解決はfunction()ではなく実際の関数の呼出し時に行われるので、<SID>
を含むFuncRefは同じスクリプト内からでなければ使えない、ということです。
>>868 の例で言えば、imapで実行されるb:Prgは、Vimにとってスクリプト内の出来事
ではありませんから<SID>を含む参照が解決できていないのでしょう。なおmapであれ
ば:help :map-scriptにあるとおり<script>を使うことで解決できそうです。でもス
クリプトローカルな関数のFuncRefを別のスクリプトに渡して実行させる、というこ
とはちょっとできそうにないですね。
878 :
初心者 :2007/05/08(火) 20:32:57
休暇で岩登りの為、両手両足が使えず。返事が遅くなりました。懇 切丁寧な回答有り難う。良く分かりました。頑張ってみます。
日本語全角モードになってたとき ESC押せば、全角モードも同時に消えるようにするには、 どうしたらいいのだろうか
>>879 gvimならこれでいけるけど、コンソールのvimだとむりぽ?
香り屋氏のgvimrcより抜粋
" 日本語入力に関する設定:
"
if has('multi_byte_ime') || has('xim')
" IME ON時のカーソルの色を設定(設定例:紫)
highlight CursorIM guibg=Purple guifg=NONE
" 挿入モード・検索モードでのデフォルトのIME状態設定
set iminsert=0 imsearch=0
if has('xim') && has('GUI_GTK')
" XIMの入力開始キーを設定:
" 下記の s-space はShift+Spaceの意味でkinput2+canna用設定
"set imactivatekey=s-space
endif
" 挿入モードでのIME状態を記憶させない場合、次行のコメントを解除
"inoremap <silent> <ESC> <ESC>:set iminsert=0<CR>
endif
881 :
名無しさん@お腹いっぱい。 :2007/06/04(月) 08:58:22
vimのscriptの勉強をしてます。 :lsした時に取れる、各bufferのstatusってどうやったらvimのscript上から取れるのでしょうか? 例えばイジってあるbufferである+のstatusとか。 一応次ぎのようなscriptで、一覧を取得出来る所までは出来ました。 続く
883 :
882 :2007/06/04(月) 17:02:26
続き command! -nargs=? EnumBufs :call <SID>EnumBufs(<f-args>) function! s:EnumBufs(...) let arg = "^.*$" if a:0 == 1 let arg = a:1 endif let buf_idx = bufnr("$") let bufnames = [] while buf_idx > 0 try if ! bufexists(buf_idx) || ! buflisted(buf_idx) continue endif let bufname = bufname(buf_idx) let bufnum = bufnr(buf_idx) if bufname =~ arg call add(bufnames, [ bufnum, bufname ]) endif finally let buf_idx -= 1 endtry endwhile echo s:list2str(bufnames) endfunction 続く
884 :
882 :2007/06/04(月) 17:03:21
続き function! s:list2str(list) let output = "" for buf in a:list let output .= buf[0] . ":" . buf[1] . "\r\n" endfor return output endfunction 以上
885 :
882 :2007/06/04(月) 17:06:12
あー、indentが崩れてる。ごめんなさい。。。
>>882 + &modified
= &modifiable
bufloaded()
&buflisted
h bufwinnr()
statのような便利なものはないのでヘルプを見ながらがんばりんさい。
バッファエクスプローラプラグインはたくさんあるから参考にするといいかも。
887 :
882 :2007/06/05(火) 23:43:00
出来ました。thx。 ずっと関数だと思って、optionは探していなかったよ。
>>881 amazon.co.jpだと
通常3~5週間以内に発送します
なんだが、もっと早く手に入るところってないかな?
>>881 ebookで買ってみた。
内容は、ディープとまでは感じなかった。Vimスクリプトバリバリ書いてる人は必要なし。
ヘルプにも書いてあるような解説+こう使うと便利になるよというサンプル少々。
>>803 のCompleteMailやvim wikiのAutoSaveSessionに似たスクリプトも書いてあった。
やはりこれを買うよりヘルプ、vim wiki、vim onlineのTipsを熟読した方がいいと思う。
質問です. 「文章中にある文字列をもとに 辞書を引く」…というような スクリプトを書こうとしています. 「カーソル位置の単語を拾い出す」のは expand("<cword>") で…簡単に作ることができたのですが でも 調べたい(拾いたい)文字列が 丁度 単語単位とは限らないので 「自分で範囲選択した箇所を スクリプトに渡せるようにしたい」と 考えています. (小文字の)v キー&範囲選択直後に, その「選択中の文字列」を 取り出すには どうしたらよいのでしょうか? <cword> 同様に, 範囲の中身が取り出せるキーワードが あるような気がするのですが…なかなか探せない.... あるいは 選択範囲の 開始&終了の文字位置 が分かれば それを手がかりに 取り出せると思うのですが これもわからない... (どちらも「行単位」なら楽勝なのですが) …というわけで 何か分かるかた 以上よろしくお願いします.
いったんレジスタにヤンクするのが定石だと思う。 function! Select() let a_save = @a normal! gv"ay let selected=@a let @a=a_save return selected endfunction function! Dict(word) echo "「". a:word . "」の意味はわかりません" endfunction vnoremap \d <Esc>:call Dict(Select())<CR>
expand('<selected>') みたいなものがあればいいのにな と思う。
>>891 normal! gv"ay
だけで もう満足です(笑)なるほど
gv って コマンドも 今,知りました
以上 ありがとうございました.
>>795 いまさらなんだけど
このヒアドキュメントで関数名と関数定義をとりだして、
関数名をごにょごにょして、スクリプト内の関数にevalさせれば、
外部から動的に関数できる
function! pluginHoge#eval(source_func_name,new_define_name)
let savelist=&list
setlocal nolist
redir => str
exec "silent function " a:source_func_name
redir END
let &list=savelist
let lines = split(str, '\n')
let lines[0]=substitute(lines[0],'function[^(]\+',"function! ".a:new_func_name,'')
let lines = map(lines, 'v:val[3:]')
let str = join(lines, "\n")
exec str
endfunction
VimのrangeとPythonのrangeって違うのね。 Vim: range(2, 3) => [2, 3] range(2, 2) => [2] range(2, 1) => [] range(2, 0) => エラー Python: range(2, 3) => [2] range(2, 2) => [] range(2, 1) => [] range(2, 0) => []
関数名はけっこうアバウト fun! <SNR>99_func() endfun fun! <SNR>func() endfun fun! hoge:func() endfun fun! hoge::func() endfun fun! foo:bar:func() endfun
スクリプトのローカル関数(s:func() or <SID>func())はVim内部では <SNR>99_func()という名前(数字はスクリプト番号)のグローバル関数になってるんだけど 実は直接 :function <SNR>99_func() と書いて関数を定義できる。(:callもok) だからスクリプトのローカル関数を外部から変更できてしまう。(ただしs:var変数にはアクセスできなさそう) let sid = GetSid("plugin.vim") " redir + scriptnames で番号取得 function! <SNR>{sid}_func() ... endfunction 名前が正しいかどうかはチェックしてないみたいなので存在しないスクリプト番号が使えたり番号指定がなくても大丈夫だったりする。 そんで、おそらくs:func()とかが使える関係で関数名にコロンが使えるようになってるけど その辺の処理は適当らしくてhoge:func()とかfoo:bar:func()とかいう名前も使える。(変数名はダメらしい) どちらもundocumentedな動作。
>>898 解説サンクス。
スクリプトローカル関数を外部から変更する方法は欲しいね。
Vim onlineにあるスクリプトはどうもイマイチなのが多くて
手を加えたくなってしまう。
あと話はずれるけど、プラグイン内で勝手にマッピングを
作るのはやめてほしい。
プラグインでは関数定義だけを提供して、.vimrcでそこへのマッピングを
作るのが理想だと思うのだが。
それプラス、
(iswitchb-default-keybindings)
みたいにマッピングを作る関数を提供するとか。
>>899 もっともな意見なので自作スクリプトを修正するよ。後で。
NERDTreeでは let g:NERDTreeMapOpenSplit = 'i' という変数を定義することでOpenSplit機能へマッピングするキーを 変更できるようになってるね。 この辺の作法が統一されればいいんだけど。
:exe "exe \"exe \\\"exe 'new'\\\"\"" どんくらいネストできるんだろw
>>899 >それプラス、
> (iswitchb-default-keybindings)
>みたいにマッピングを作る関数を提供するとか。
いまそれやろうとして気付いたけど、最初に読み込まれるのは~/.vimrcだから、
そういう関数を呼ぼうにもまだ定義されていないという。
と書いてau VimEnter経由で呼べば良いことに気付いた。
関数じゃなくてフラグ変数にすればいいんじゃない? let g:iswitchb_default_keybindings = 1
vim 7.1以内で関数名と変数名の扱いで挙動が変わったようだ?? :let Fn=function("A") :let Fn=function("B") みたいな関数参照の再代入ができなくなった。E705がでる 場合に応じて関数名を繋ぎかえて動かしてた人は動かなくなる 対策として :let fnlist=[function("A"),function("B")] :call call(fnlist[1],[]) :call fnlist[1]() とか :let fndict={"A":function("A"),"B":function("B")] :call call(fndict["A"],[]) :call fndict.A() とかして、当面は切り抜けるとよいと思う どっかに変更の記述てあるのか
>>906 :let Fn=function("A")
:let Fn=function("B")
エラーでないけど。
>>907 うおー別ので試したらでなかった
うちのkaoriyaのwindows gvim7.1 10月13日コンパイルバージョンだけでる
7.1.098のパッチの副作用みたいです。香り屋のバージョンでいうと20070831から 20070909の間ですね。 > Patch 7.1.098 > Problem: ":call s:var()" doesn't work if "s:var" is a Funcref. (Andy Wokula) > Solution: Before converting "s:" into a script ID, check if it is a Funcref. 試しにこのパッチを外してコンパイルしてみたら、エラーがでなくなりました。
>>909 ありがとう
当面困ってなかったので古いバージョンに戻しておきます
:s//\=/ と eval を組み合わせると簡易テンプレートエンジンになる たとえば これが: 今の時間は ${strftime("%c")} :%s/${\([^}]*\)}/\=eval(submatch(1))/g こうなる: 今の時間は 2007/10/29 16:55:21
すいません。 現在のカーソル位置が行末がどうかを調べるにはどうすればいいでしょうか?
getpos(".") の現在位置のうちの列と len(getline(".")) が同じとかどうよ
if getpos(".")[2]==strlen(getline(".")) | echo "at the end" | endif 行末の2バイト文字上に、カーソルがあるとダメだった。 # ver7 のヘルプ全然読んでいないから getpos() の戻り値に驚き。w なんかスゲー面倒。 command! IsEnd call <sid>IsEnd() function! s:IsEnd() let ls=getline(".") if ls==# '' echo '行末' else "カーソル位置から、行末まで全部。 let str=matchstr(ls, '.\+', col('.')-1) "カーソル位置の1文字 let chr=matchstr(ls, '.', col('.')-1) if str ==# chr echo '行末' else echo '行末じゃない' endif endif endfunction
"
>>912 " これでどうだろう?
function! IsTheCursorAtTheEndOfLine()
return search('\%#.$', 'cn')
endfunction
916 :
912 :2007/10/31(水) 19:55:59
おお!皆さんありがとうございます。 自分で作ったスクリプトが挙動不審だったので皆さんのヤツで試してみます。 更に質問なんですが、現在開いているバッファの数ってどうやって取得するんでしょうか? 何も開いてないかどうかを知れたらそれでいいのですが。 よろしくお願いします。
917 :
914 :2007/10/31(水) 22:47:10
>>915 それすごいな。
search() のオプションとか知らなかった。
もしかするとこんな感じでやるしかないかな? function! BufCount() let cnt = 0 let lastbufnr = bufnr("$") let i = 1 while i <= lastbufnr " :lsで表示されるものだけカウントする if bufexists(i) && buflisted(i) let cnt += 1 endif let i += 1 endwhile return cnt endfunction
空バッファをカウントしたくないなら条件に↓を追加 && bufname("%") != ""
バッファのカウントなら tabpagebuflist() 使うといいかもしれない
921 :
912 :2007/11/01(木) 12:58:22
みなさんありがとうございます。 とりあえずコピペで動いてくれています。 tabpagebuflist()という名前にまた錯乱ぎみなんですが、 VIMはタブとバッファは完全に別物で、 データとビューの関係なんですよね? あとヘルプによく出てくるウィンドウ(変数でいう「w」)ってのはサーバーの事なんでしょうか? グローバル(g)との違いが分かりません。
こんなんでもよくね len(filter(range(1,bufnr('$')),"buflisted(v:val) && bufexists(v:val)"))
924 :
912 :2007/11/01(木) 13:42:57
>>922 ははー、ウインドウはTABや分割された領域単位って事ですね。
って事はグローバル(g)がサーバー(exe)単位ですね。
>>923 ・・・ちょっとマニュアルとにらめっこしてきますw
range(1,8) => [1,2,3,4,5,6,7,8] みたいな配列つくって それをfilter()でいるものだけ取り出したんだよ buflited()とbufexists()は真なら1を返すのでandした 例 filter([1,2,3],1) => [1,2,3] filter([1,2,3],0) => [] filter([1,2,3,4,5,6],"(v:val % 2) == 0") => [2,4,6] filter([1,2,3,4,5,6],"(v:val % 2)") => [1,3,5]
926 :
912 :2007/11/01(木) 14:50:07
なるほど!perlの正規表現でいえば、「e」ですな。 それを全要素に対して処理をしてくれると。 こうやって勉強してみるとVIMスクリプトはしょぼいしょぼい言われているけど、 ネットワーク関連の組込み関数がない(?)ぐらいで、それほどひどかないですよね。
:echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++3
機能という点では何とでもなるけど exコマンドが元になってるからスクリプト言語としては 根本的に文法が腐ってると思います まあよしあしですけども
文法なんてこんなもんじゃないかな いわゆる一つの言語的機能と普通のコマンドが混在してるから慣れが必要だけど
文法はなれれば我慢できるが、exコマンドが元になってるから機能的に腐ってる。 関数によって特殊文字にエスケープが必要だったりそうじゃなかったり。 bunname()とかわけわからん。 オプションの退避とかカーソル、レジスタの復元とか書かせるのも勘弁。
> 関数によって特殊文字にエスケープが必要だったりそうじゃなかったり。 そんな関数あったっけ
bufname() file-patternが展開される。代替ファイルは"#"または0 bufnr() bufname()と同じ。でも"$"で最後のバッファ。 bufexists() 展開されない。代替ファイルはbufexists(0) vimはCの関数がすでにコマンドべったりで書かれてるからなあ。
なるほど。 他にはなんかある?
winheight(0) => 現在のウィンドウの高さ winnr(0) => エラー winnr("%") => エラー winnr() => 現在のウィンドウの番号 winnr("#") => 最後にアクセスしたウィンドウの番号 winnr("$") => 最後のウィンドウの番号 とか。カレントを表すのも関数によって"%"や"."だったりするけど、 一応バッファが"%"で行が"."になってるのかな。 エスケープについては、関数だけじゃできなくて、文字列を組み立てて :exe するときがけっこう嫌らしい。
じらさないで全部教えてくれよ(;´Д`)ハァハァ
:echo +-+-3 :echo 1++-+-3
そういや一時期Ctrl+@にESCあててたな 日本語ノートね 無変換、前候補、かたかな・ひらがな、でもホームに近い余ってるキー いくらでもあるからな そういやスペースの両隣のキーにshiftあてるのがエルゴノミクスとか周りではやった
本スレと勘違いしたか
バッファの変更と、その内容をフックしたいのですが、できますかね?
インサートモードで入力したテキストだけならこんな感じでできそうだけど。 augroup meso au! au InsertEnter * call InsertEnterCB() au InsertLeave * call InsertLeaveCB() augroup END function! InsertEnterCB() let g:modified_save = &modified set nomodified endfunction function! InsertLeaveCB() if &modified echomsg "inserted text='". @. ."'" endif let &modified = g:modified_save endfunction
>>940 無理。
FilterReadPreとかで限定的なものはできそうだけど。
>>941 <C-c>されるとInsertLeaveは発行されないよ。
>>940 help {event}
で見合うものを探すのだ
関数名の最初の文字はアンダースコアでも通るみたい。 function! _havesex() echo "not implemented" endfunction
>>944 have sex. not implemented w
946 :
名無しさん@お腹いっぱい。 :2008/01/09(水) 12:26:12
vimのなかでgccでコンパイルするにはどうしたらいいですか? perlのやり方は調べたら分かったのですが、cについてはgoogle検索でざざーっと 数十件くらいそれっぽいものを見てみても見つかりませんでした。 お願いします。
:set makeprg=gcc\ % :make
948 :
名無しさん@お腹いっぱい。 :2008/01/09(水) 15:08:18
>>947 ありがとうございます。希望どおりの動作になりました。
949 :
名無しさん@お腹いっぱい。 :2008/01/09(水) 22:39:22
:compiler gcc するとerrorformatを設定してくれるよ
このスレ7年目にしてようやく次スレが見えてきたのかよワロタ
おお、ほんとだ。ようやくだな。 次スレではvim8に突入しちゃうかもな
スレタイは vim7スクリプトお勉強スレ なのか、汎用的に vimスクリプトお勉強スレpart2 なのか
>>952 バージョン入れる必要性はないから後者の方が良いね。
むしろ本スレに統合しても問題ない気もする。分離する必要性ってある?
>>953 あんまりないな
最初は珍しかったから「お勉強」ということだったんだろう
スレの最初の方のレスの流れをみてもそうだけど
>>951-953 次スレを
vim7スクリプトお勉強スレ
にしても
次々スレが
vim8スクリプトお勉強スレ
になって(ry
Windowsのvim7のinputlist()っていう選択肢の中から選ばせる関数使うと、 *********(<Enter> でキャンセル) ってメッセージが表示されるんだけど、 Enter押すと、最初の項目が選択されたことになってる。(0が返ってくる) これって仕様ということでいいのかな?
サンプルコードを見ると、最初の要素はプロンプト的な使い方をするぽい
ほー、なるほど
>>911 command! -range=% TemplateEngine <line1>,<line2>substitute/#{\(.\{-}\)}/\=eval(submatch(1))/g
コマンドにしておくと便利
>>962 で、この TemplateEngine コマンドは
如何に使うとよかですか?
964 :
名無しさん@お腹いっぱい。 :2008/04/24(木) 23:04:43
tcvime.vimの文字ヘルプを使う時は、<Leader>?を入力します。この場 合の<leader>のデフォルトは<C-K>です。この<C-K>?を tcode_cp932.vimのjfjにマップしたいのですが、下記のマップでは動作 しません。何が悪いのでしょうか? jfj<tab>~K? 勿論fjのマップは外しています。宜しく、お願いします。
:h mapleader
>>964 tcvime.vimで<Leader>?にマップされてる文字ヘルプは、
Normal Mode時にカーソル位置にある文字の入力方法を表示する機能ですが、
Insert Mode用keymap(tcode_cp932.vim)のjfjにマップして、
どういう動作を期待してます?
Insert Modeでjfjと打ったら直前の文字のヘルプを表示して欲しいのでしょうか?
967 :
名無しさん@お腹いっぱい。 :2008/04/26(土) 07:38:23
>966 失礼しました。もしかしたら、keymapのファイルはInsert Mode用に 定義されているのですか?私は、全てのモードに定義されていると思 っていた物ですから。やりたい事は、ノーマルモードで、jfjを^K?に マップしたい。 例えば、nmap jfj ^Kqは動作するが、若しもの事を考慮してnnoremap jfj ^?と定義すると、何故か動きません。jもfもキーマップは定義 していないのですが。 済みません。宜しくお願いします。
keymapは主にInsert mode用です(lnoremapされるものです。mbyte-keymapのヘルプ参照)。 Normal modeで<C-K>?にマップされている機能を別のキーにマップしたい場合は、 nnoremapではなくnmapを使います(nnoremapとnmapのヘルプ参照)。 :nmap jfj <C-K>?
969 :
名無しさん@お腹いっぱい。 :2008/04/26(土) 10:40:22
>968 mbyte-keymapのヘルプを読んだが、今一つnmapとnnoremapとの違いが 分からない。この場合、nnoremapが動かないのは、再定義するキー マップが無いからなのだろうか? 逆に、考えると確実にそのキーマップが存在していないと、nnoremap は動かないと考えるべきなのか。私が、nnoremapにこだわるのは何処 でキーマップを使うか分からないので、誤動作を防ぎたい。それだけ の理由ですが、逆にこれが動かない結果となる。原因が分からな い。 宜しく、お願いします。
970 :
名無しさん@お腹いっぱい。 :2008/04/26(土) 19:27:08
質問をさせてください。 コマンドの結果を変数に保存する場合、どのような記述をすれば良いのでしょうか。 以下が、やりたい事をvim の疑似言語で表したものです。 ここでは、:put を実行した時に出力される内容を変数に格納したいです let tmp = `put` どうかよろしくお願いします。
>>969 <C-K>?はtcvimeによってマップされているキーなのでnmapを使う必要があります。
:nmap jfj <C-K>?
としてjfjを打った場合、
以下の例のように<C-K>?はさらに展開されるので、tcvimeの関数が呼び出されます。
jfj → <C-K>? → :<C-U>call <SNR>4_ShowStrokeHelp()<CR>
一方、
:nnoremap jfj <C-K>?
としてjfjを打った場合、<C-K>?は展開されないので、
tcvimeの機能は呼び出されません。
jfj → <C-K>?
>>970 let tmp = system("put")
redir => tmp
put
redir END
上か下、どちらかでいけるよ。
どちらが使えるかは、put次第
973 :
名無しさん@お腹いっぱい。 :2008/04/27(日) 10:32:29
>971 詳しい説明、有り難う御座います。何となく、mapとremapの違いが分 かった様な気がします。 >965 確かに、mapを指定するのでは無くてmapleaderの設定を変更した方が 早いかも知れません。
保守
保守
保守
保守
保守
保守
保守
急に更新しているから、なんだだと思えば、埋めか? このスレは、6年半も使われていたんだよな。