Vim6スクリプトお勉強スレat UNIX
Vim6スクリプトお勉強スレ - 暇つぶし2ch895:名無しさん@お腹いっぱい。
07/07/18 03:28:53
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) => []

896:名無しさん@そうだ選挙に行こう
07/07/29 00:45:26
関数名はけっこうアバウト

fun! <SNR>99_func()
endfun
fun! <SNR>func()
endfun
fun! hoge:func()
endfun
fun! hoge::func()
endfun
fun! foo:bar:func()
endfun

897:名無しさん@お腹いっぱい。
07/07/29 23:48:10 0
>>896 解説キボン

898:名無しさん@お腹いっぱい。
07/07/30 19:37:54
スクリプトのローカル関数(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な動作。

899:名無しさん@お腹いっぱい。
07/07/30 23:12:59
>>898
解説サンクス。
スクリプトローカル関数を外部から変更する方法は欲しいね。
Vim onlineにあるスクリプトはどうもイマイチなのが多くて
手を加えたくなってしまう。

あと話はずれるけど、プラグイン内で勝手にマッピングを
作るのはやめてほしい。
プラグインでは関数定義だけを提供して、.vimrcでそこへのマッピングを
作るのが理想だと思うのだが。
それプラス、
 (iswitchb-default-keybindings)
みたいにマッピングを作る関数を提供するとか。

900:名無しさん@お腹いっぱい。
07/08/06 19:05:18
>>899
もっともな意見なので自作スクリプトを修正するよ。後で。

901:名無しさん@お腹いっぱい。
07/08/06 20:40:46
NERDTreeでは
let g:NERDTreeMapOpenSplit = 'i'
という変数を定義することでOpenSplit機能へマッピングするキーを
変更できるようになってるね。
この辺の作法が統一されればいいんだけど。

902:名無しさん@お腹いっぱい。
07/08/08 06:47:00
:exe "exe \"exe \\\"exe 'new'\\\"\""
どんくらいネストできるんだろw

903:名無しさん@お腹いっぱい。
07/08/13 02:20:25
>>899
>それプラス、
> (iswitchb-default-keybindings)
>みたいにマッピングを作る関数を提供するとか。
いまそれやろうとして気付いたけど、最初に読み込まれるのは~/.vimrcだから、
そういう関数を呼ぼうにもまだ定義されていないという。

と書いてau VimEnter経由で呼べば良いことに気付いた。

904:名無しさん@お腹いっぱい。
07/08/13 09:15:53
関数じゃなくてフラグ変数にすればいいんじゃない?
let g:iswitchb_default_keybindings = 1

905:名無しさん@お腹いっぱい。
07/10/15 09:53:15
>>863
これがそうかも。
URLリンク(www.vim.org)

906:名無しさん@お腹いっぱい。
07/10/24 14:38:03
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()

とかして、当面は切り抜けるとよいと思う
どっかに変更の記述てあるのか

907:名無しさん@お腹いっぱい。
07/10/24 23:48:06
>>906
:let Fn=function("A")
:let Fn=function("B")

エラーでないけど。

908:名無しさん@お腹いっぱい。
07/10/25 10:23:47
>>907
うおー別ので試したらでなかった

うちのkaoriyaのwindows gvim7.1 10月13日コンパイルバージョンだけでる

909:KoRoN@Vim%Chalice ◆8XALICEsdk
07/10/25 23:12:55
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.

試しにこのパッチを外してコンパイルしてみたら、エラーがでなくなりました。

910:名無しさん@お腹いっぱい。
07/10/26 10:41:40
>>909
ありがとう
当面困ってなかったので古いバージョンに戻しておきます

911:名無しさん@お腹いっぱい。
07/10/29 17:00:40
:s//\=/ と eval を組み合わせると簡易テンプレートエンジンになる

たとえば
これが: 今の時間は ${strftime("%c")}
  :%s/${\([^}]*\)}/\=eval(submatch(1))/g
こうなる: 今の時間は 2007/10/29 16:55:21

912:名無しさん@お腹いっぱい。
07/10/31 17:21:56
すいません。
現在のカーソル位置が行末がどうかを調べるにはどうすればいいでしょうか?


913:名無しさん@お腹いっぱい。
07/10/31 17:30:54
getpos(".")
の現在位置のうちの列と
len(getline("."))
が同じとかどうよ

914:名無しさん@お腹いっぱい。
07/10/31 17:54:30
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

915:名無しさん@お腹いっぱい。
07/10/31 18:10:13
" >>912
" これでどうだろう?
function! IsTheCursorAtTheEndOfLine()
return search('\%#.$', 'cn')
endfunction

916:912
07/10/31 19:55:59
おお!皆さんありがとうございます。
自分で作ったスクリプトが挙動不審だったので皆さんのヤツで試してみます。

更に質問なんですが、現在開いているバッファの数ってどうやって取得するんでしょうか?
何も開いてないかどうかを知れたらそれでいいのですが。

よろしくお願いします。

917:914
07/10/31 22:47:10
>>915
それすごいな。
search() のオプションとか知らなかった。

918:名無しさん@お腹いっぱい。
07/11/01 10:29:15
もしかするとこんな感じでやるしかないかな?

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

919:名無しさん@お腹いっぱい。
07/11/01 10:33:32
空バッファをカウントしたくないなら条件に↓を追加
&& bufname("%") != ""

920:名無しさん@お腹いっぱい。
07/11/01 12:28:00
バッファのカウントなら tabpagebuflist() 使うといいかもしれない

921:912
07/11/01 12:58:22
みなさんありがとうございます。
とりあえずコピペで動いてくれています。

tabpagebuflist()という名前にまた錯乱ぎみなんですが、
VIMはタブとバッファは完全に別物で、
データとビューの関係なんですよね?

あとヘルプによく出てくるウィンドウ(変数でいう「w」)ってのはサーバーの事なんでしょうか?
グローバル(g)との違いが分かりません。


922:名無しさん@お腹いっぱい。
07/11/01 13:21:41
>VIMはタブとバッファは完全に別物で、
>データとビューの関係なんですよね?
そう。ウィンドウは:spなどで分割できるやつのこと。

let w:hoge = 1 とかすると、hogeはそのときのカレントウィンドウでのみ参照可能になる。
:h w: で出てくる。日本語版ヘルプもあるからその辺読むといいよ。
URLリンク(yukihiro.nakadaira.googlepages.com)
:h 41.2 のユーザーマニュアルの方がわかりやすいかな。

923:名無しさん@お腹いっぱい。
07/11/01 13:30:45
こんなんでもよくね

len(filter(range(1,bufnr('$')),"buflisted(v:val) && bufexists(v:val)"))


924:912
07/11/01 13:42:57
>>922
ははー、ウインドウはTABや分割された領域単位って事ですね。
って事はグローバル(g)がサーバー(exe)単位ですね。

>>923
・・・ちょっとマニュアルとにらめっこしてきますw

925:名無しさん@お腹いっぱい。
07/11/01 14:15:56
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
07/11/01 14:50:07
なるほど!perlの正規表現でいえば、「e」ですな。
それを全要素に対して処理をしてくれると。

こうやって勉強してみるとVIMスクリプトはしょぼいしょぼい言われているけど、
ネットワーク関連の組込み関数がない(?)ぐらいで、それほどひどかないですよね。


927:名無しさん@お腹いっぱい。
07/11/24 12:25:16
:echo ++++++++++++++++++++++++++++++++++++++++++++++++++++++++3

928:名無しさん@お腹いっぱい。
07/11/24 13:04:27
機能という点では何とでもなるけど
exコマンドが元になってるからスクリプト言語としては
根本的に文法が腐ってると思います
まあよしあしですけども

929:名無しさん@お腹いっぱい。
07/11/25 00:24:37
文法なんてこんなもんじゃないかな
いわゆる一つの言語的機能と普通のコマンドが混在してるから慣れが必要だけど

930:名無しさん@お腹いっぱい。
07/11/26 09:15:26
文法はなれれば我慢できるが、exコマンドが元になってるから機能的に腐ってる。
関数によって特殊文字にエスケープが必要だったりそうじゃなかったり。
bunname()とかわけわからん。
オプションの退避とかカーソル、レジスタの復元とか書かせるのも勘弁。

931:名無しさん@お腹いっぱい。
07/11/26 19:50:36
> 関数によって特殊文字にエスケープが必要だったりそうじゃなかったり。
そんな関数あったっけ

932:名無しさん@お腹いっぱい。
07/11/27 13:07:14
bufname() file-patternが展開される。代替ファイルは"#"または0
bufnr() bufname()と同じ。でも"$"で最後のバッファ。
bufexists() 展開されない。代替ファイルはbufexists(0)

vimはCの関数がすでにコマンドべったりで書かれてるからなあ。

933:名無しさん@お腹いっぱい。
07/11/28 01:08:53
なるほど。
他にはなんかある?

934:名無しさん@お腹いっぱい。
07/11/28 10:12:55
winheight(0) => 現在のウィンドウの高さ
winnr(0) => エラー
winnr("%") => エラー
winnr() => 現在のウィンドウの番号
winnr("#") => 最後にアクセスしたウィンドウの番号
winnr("$") => 最後のウィンドウの番号
とか。カレントを表すのも関数によって"%"や"."だったりするけど、
一応バッファが"%"で行が"."になってるのかな。

エスケープについては、関数だけじゃできなくて、文字列を組み立てて :exe
するときがけっこう嫌らしい。

935:名無しさん@お腹いっぱい。
07/11/28 17:17:04
じらさないで全部教えてくれよ(;´Д`)ハァハァ

936:名無しさん@お腹いっぱい。
07/11/28 17:27:46
>>935
:h

937:名無しさん@お腹いっぱい。
07/11/28 18:01:02
:echo +-+-3
:echo 1++-+-3

938:名無しさん@お腹いっぱい。
07/11/29 16:23:03
そういや一時期Ctrl+@にESCあててたな
日本語ノートね

無変換、前候補、かたかな・ひらがな、でもホームに近い余ってるキー
いくらでもあるからな
そういやスペースの両隣のキーにshiftあてるのがエルゴノミクスとか周りではやった

939:名無しさん@お腹いっぱい。
07/11/29 17:32:40
本スレと勘違いしたか

940:名無しさん@お腹いっぱい。
07/12/03 00:28:47
バッファの変更と、その内容をフックしたいのですが、できますかね?

941:名無しさん@お腹いっぱい。
07/12/03 02:18:39
インサートモードで入力したテキストだけならこんな感じでできそうだけど。

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

942:名無しさん@お腹いっぱい。
07/12/03 03:03:25
>>940
無理。
FilterReadPreとかで限定的なものはできそうだけど。

>>941
<C-c>されるとInsertLeaveは発行されないよ。

943:名無しさん@お腹いっぱい。
07/12/03 19:17:27
>>940
help {event}

で見合うものを探すのだ

944:名無しさん@お腹いっぱい。
07/12/20 05:10:46
関数名の最初の文字はアンダースコアでも通るみたい。

function! _havesex()
echo "not implemented"
endfunction

945:名無しさん@お腹いっぱい。
07/12/24 20:33:06
>>944
have sex. not implemented w

946:名無しさん@お腹いっぱい。
08/01/09 12:26:12
vimのなかでgccでコンパイルするにはどうしたらいいですか?
perlのやり方は調べたら分かったのですが、cについてはgoogle検索でざざーっと
数十件くらいそれっぽいものを見てみても見つかりませんでした。
お願いします。

947:名無しさん@お腹いっぱい。
08/01/09 13:03:15
:set makeprg=gcc\ %
:make

948:名無しさん@お腹いっぱい。
08/01/09 15:08:18
>>947
ありがとうございます。希望どおりの動作になりました。

949:名無しさん@お腹いっぱい。
08/01/09 22:39:22
:compiler gcc
するとerrorformatを設定してくれるよ

950:名無しさん@お腹いっぱい。
08/01/20 14:57:42
このスレ7年目にしてようやく次スレが見えてきたのかよワロタ

951:名無しさん@お腹いっぱい。
08/01/23 00:18:49
おお、ほんとだ。ようやくだな。
次スレではvim8に突入しちゃうかもな

952:名無しさん@お腹いっぱい。
08/01/23 14:33:17
スレタイは

vim7スクリプトお勉強スレ

なのか、汎用的に

vimスクリプトお勉強スレpart2

なのか

953:名無しさん@お腹いっぱい。
08/01/23 15:32:03
>>952
バージョン入れる必要性はないから後者の方が良いね。
むしろ本スレに統合しても問題ない気もする。分離する必要性ってある?

954:名無しさん@お腹いっぱい。
08/01/23 16:46:31
>>953
あんまりないな

最初は珍しかったから「お勉強」ということだったんだろう
スレの最初の方のレスの流れをみてもそうだけど

955:名無しさん@お腹いっぱい。
08/02/17 14:46:07
>>951-953
次スレを
vim7スクリプトお勉強スレ
にしても
次々スレが
vim8スクリプトお勉強スレ
になって(ry

956:名無しさん@お腹いっぱい。
08/02/20 23:37:56
Vim Part15
スレリンク(unix板)

953の言ってるとおり↑でいいべ

957:名無しさん@お腹いっぱい。
08/02/22 18:56:26
>>955
そいつはめでてーなぁ

958:名無しさん@お腹いっぱい。
08/03/07 01:02:27
Windowsのvim7のinputlist()っていう選択肢の中から選ばせる関数使うと、

*********(<Enter> でキャンセル)

ってメッセージが表示されるんだけど、
Enter押すと、最初の項目が選択されたことになってる。(0が返ってくる)
これって仕様ということでいいのかな?

959:名無しさん@お腹いっぱい。
08/03/07 01:54:06
サンプルコードを見ると、最初の要素はプロンプト的な使い方をするぽい

960:名無しさん@お腹いっぱい。
08/03/08 21:03:02
ほー、なるほど

961:名無しさん@お腹いっぱい。
08/03/09 02:42:55
vim6を使っているけどrenamer.vimがうらやましかったので
6でも動くようにパッチしてみた。

よかったらどうぞ

URLリンク(sakuratan.ddo.jp)

962:名無しさん@お腹いっぱい。
08/04/15 18:37:36
>>911
command! -range=% TemplateEngine <line1>,<line2>substitute/#{\(.\{-}\)}/\=eval(submatch(1))/g

コマンドにしておくと便利

963:名無しさん@お腹いっぱい。
08/04/19 18:18:32
>>962
で、この TemplateEngine コマンドは
如何に使うとよかですか?


964:名無しさん@お腹いっぱい。
08/04/24 23:04:43
tcvime.vimの文字ヘルプを使う時は、<Leader>?を入力します。この場
合の<leader>のデフォルトは<C-K>です。この<C-K>?を
tcode_cp932.vimのjfjにマップしたいのですが、下記のマップでは動作
しません。何が悪いのでしょうか?

jfj<tab>~K?

勿論fjのマップは外しています。宜しく、お願いします。


965:名無しさん@お腹いっぱい。
08/04/24 23:22:12
:h mapleader

966:名無しさん@お腹いっぱい。
08/04/25 23:50:00
>>964
tcvime.vimで<Leader>?にマップされてる文字ヘルプは、
Normal Mode時にカーソル位置にある文字の入力方法を表示する機能ですが、
Insert Mode用keymap(tcode_cp932.vim)のjfjにマップして、
どういう動作を期待してます?
Insert Modeでjfjと打ったら直前の文字のヘルプを表示して欲しいのでしょうか?

967:名無しさん@お腹いっぱい。
08/04/26 07:38:23
>966
    失礼しました。もしかしたら、keymapのファイルはInsert Mode用に
    定義されているのですか?私は、全てのモードに定義されていると思
    っていた物ですから。やりたい事は、ノーマルモードで、jfjを^K?に
    マップしたい。

    例えば、nmap jfj ^Kqは動作するが、若しもの事を考慮してnnoremap
    jfj ^?と定義すると、何故か動きません。jもfもキーマップは定義
    していないのですが。

    済みません。宜しくお願いします。



968:名無しさん@お腹いっぱい。
08/04/26 09:04:38
keymapは主にInsert mode用です(lnoremapされるものです。mbyte-keymapのヘルプ参照)。
Normal modeで<C-K>?にマップされている機能を別のキーにマップしたい場合は、
nnoremapではなくnmapを使います(nnoremapとnmapのヘルプ参照)。
:nmap jfj <C-K>?

969:名無しさん@お腹いっぱい。
08/04/26 10:40:22
>968
    mbyte-keymapのヘルプを読んだが、今一つnmapとnnoremapとの違いが
    分からない。この場合、nnoremapが動かないのは、再定義するキー
    マップが無いからなのだろうか?

    逆に、考えると確実にそのキーマップが存在していないと、nnoremap
    は動かないと考えるべきなのか。私が、nnoremapにこだわるのは何処
    でキーマップを使うか分からないので、誤動作を防ぎたい。それだけ
    の理由ですが、逆にこれが動かない結果となる。原因が分からな
    い。

    宜しく、お願いします。


970:名無しさん@お腹いっぱい。
08/04/26 19:27:08
質問をさせてください。

コマンドの結果を変数に保存する場合、どのような記述をすれば良いのでしょうか。

以下が、やりたい事をvim の疑似言語で表したものです。
ここでは、:put を実行した時に出力される内容を変数に格納したいです

let tmp = `put`

どうかよろしくお願いします。

971:名無しさん@お腹いっぱい。
08/04/26 22:41:23
>>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>?

972:名無しさん@お腹いっぱい。
08/04/27 00:00:11
>>970
let tmp = system("put")

redir => tmp
put
redir END

上か下、どちらかでいけるよ。
どちらが使えるかは、put次第

973:名無しさん@お腹いっぱい。
08/04/27 10:32:29
>971
    詳しい説明、有り難う御座います。何となく、mapとremapの違いが分
    かった様な気がします。
>965
    確かに、mapを指定するのでは無くてmapleaderの設定を変更した方が
    早いかも知れません。



最新レス表示
レスジャンプ
類似スレ一覧
スレッドの検索
話題のニュース
おまかせリスト
オプション
しおりを挟む
スレッドに書込
スレッドの一覧
暇つぶし2ch