06/11/22 06:01:20
gVimなんですが、ウインドウのサイズって取得できますか?
やりたいのは
1. サイズ取得して変数x, y にいれとく
2. フォントのサイズを変える
3. winsize x y でサイズを戻す
これだけなんですが。
840:名無しさん@お腹いっぱい。
06/11/22 16:50:23
let x = &columns
let y = &lines
841:839
06/11/22 20:21:12
>>840
ありがとうございます。
ちょっと勘違いしていました、winsizeはピクセルで指定するものだと・・
フォントのサイズを変えると、ウインドウのサイズも変わってしまうので
それを防止したかったんです。
842:名無しさん@お腹いっぱい。
06/11/27 13:07:08
vimにて、
:split FILE
などで、別ディレクトリにあるファイルを開いたとき、
また、
^W h
などで、ウィンドウ(?)を切り替えたときに
自動でそのファイルがあるディレクトリにチェンジディレクトリするようにするには
どうすればよいでしょうか?
843:名無しさん@お腹いっぱい。
06/11/28 01:09:34
:set autochdir
または
:autocmd BufEnter * :cd %:p:h
たぶん
844:852
06/11/28 09:30:37
>>843
思い通りの動作をするようになりました。
どうもありがとうございます。
845:名無しさん@お腹いっぱい。
06/11/28 15:35:25
let count = 1
E46: Cannot change read-only variable "count"
(゚Д゚)
846:名無しさん@お腹いっぱい。
07/01/10 04:17:20
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
847:名無しさん@お腹いっぱい。
07/01/10 04:18:39
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
848:名無しさん@お腹いっぱい。
07/01/10 04:20:21
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
849:名無しさん@お腹いっぱい。
07/01/10 04:22:43
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
850:名無しさん@お腹いっぱい。
07/01/10 09:45:24
別のやり方としてこんなのはどうかな?
--- 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
851:名無しさん@お腹いっぱい。
07/01/10 23:03:32
ちらついても構わないなら毎回 :redraw! で再描画するとか
個人的にはwildmenuを使った標準的な方法をお勧めする
(:buffer <Tab> および :help :command-completion)
852:名無しさん@お腹いっぱい。
07/01/11 03:58:25
HIT ENTERはfeedkeysで解決できることわかったんですが、
なぜか846のバージョンだと、候補リストが全部消え切らず、残ってしまうんですよ。
一行だけの場合は\rで行頭復帰してそこに上書きするので
前回の候補リストが消えるのですが。
もとのincbufswitch-colorと表示の方法は変えていないし、
なぜこうなってしまったのか原因も気になるんですよね。
853:名無しさん@お腹いっぱい。
07/01/12 00:49:05
redraw してないから
854:名無しさん@お腹いっぱい。
07/01/12 02:12:33
>>853
ISwitchB_ShowList()の1行目にredrawをいれたら直りました。
ありがとうございます。
けど実用上はlookupfile.vimがあれば十分かもしれないですね。
URLリンク(subtech.g.hatena.ne.jp)
このプラグインは本当にすごい。
>>851
確かにvim標準の方法で満足できるならベターですけどね。
しかし、そのためにはvim標準の設定・機能は利便性が低過ぎると
いつも感じます。
855:名無しさん@お腹いっぱい。
07/01/12 19:58:53
エコーエリアをクリアする関数と
Press ENTER プロンプトを表示しない :echo は欲しいね
856:名無しさん@お腹いっぱい。
07/01/17 20:41:00
名無しに反応するオートコマンド
:autocmd WinEnter {} :echo "hoge"
オートコマンドで否定のパターンは使えないのかなぁ
*.txt以外のファイルみたいな
857:名無しさん@お腹いっぱい。
07/01/18 20:15:13
au WinEnter * if expand("<afile>")=~? '\.txt$'|echo|endif
amatchとかafileで判定すればいいんじゃない?
858:名無しさん@お腹いっぱい。
07/01/23 22:57:20
>>716に出てた
URLリンク(yukihiro.nakadaira.googlepages.com)
これって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:
とかいうエラーがでまくるんだが
859:名無しさん@お腹いっぱい。
07/01/26 19:04:59
>>858
むしろ vim7 でしか動かないです。
E10 エラーは行継続の \ が原因だと思います。
compatible モードで使ってたりするんでしょうか。
行継続を使わないように変更したので新しいやつを試してみてください。
860:名無しさん@お腹いっぱい。
07/01/27 15:19:23
>>859
compatible モードで使ってました
でも新しいやつ試したら日本語入力でキタ━━(゚∀゚)━━!!!!!!
ありがとうございます
でも今度は日本語入力モードでバックスペースすると
??b
が入力される・・・
文字コードUTF-8にしたら平気だった
EUC-JPじゃ無理ですか?
861:名無しさん@お腹いっぱい。
07/01/27 17:22:24
>>860
修正したので新しいの使ってみてください。
862:名無しさん@お腹いっぱい。
07/01/27 18:57:02
>>861
できるようになりました
ありがとうございます!
これでnvi+canna捨てられるかも
863:名無しさん@お腹いっぱい。
07/02/04 23:57:23
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:名無しさん@お腹いっぱい。
07/03/28 21:41:19
getchar()の使い方が良く分からない。
下記のスクリプトでは、
②で、"私の名前は"を表示する
③で、入力する
④で、入力した内容を表示して、その後に"です。"を表示する
の様な処理をしたいのですが、実際は下記の様になります。
1. ③で入力をするまで、何も変化は発生しない。
2. ③で入力をすると一気に②と④を表示する。
どこが、まずいのでしょうか?そもそもが、出来ない事をやろうとし
ているのだろうか?
①function! s:Map(...)
② execute "normal i私の名前は\<esc>"
③ let s:name=getchar()
④ execute "normal a" . s:name . "です。\<esc>"
⑤endfunction
865:名無しさん@お腹いっぱい。
07/04/20 19:23:18
libcallで呼び出されたCの関数のなかでvimの組み込み関数を呼ぶ仕組みは用意されてますか?
高速に補完用のリストを作るためにcall complete_add相当をCの関数の中から呼びたいです
libcallの戻り値をcomplete_addに渡すと長い文字列のコピーが行われてしまうかもしれないのでCの関数から直接complete_addを呼びたいです
866:名無しさん@お腹いっぱい。
07/04/20 19:25:58
沖縄県の方へ(命に関わる注意事項です)
沖縄県での選挙ですが、どうか民主党だけは避けてください。県民の生命に関わる可能性があります。
民主党の最大の公約は一国二制度(※)ですが、一度「一国二制度 沖縄 三千万」で検索をお願いします。
この際、民主党のHPで調べても良いです。以下の注釈↓と矛盾することは書いてないはずですから…
※一国二制度
簡単に言えば沖縄を中国と日本の共有物にし、そこに3000万人の中国人を入植させます。
(つまり沖縄人口の 96% を中国人にして、実質、沖縄を中国人の居住地とします。)
さらに「自主」の名の下、沖縄で有事が起きても自衛隊は干渉できません。
3000万人の中国人が、少数派となった130万人の日本人に何をしても、です。
そして反日教育を受けた中国人の反日感情の強さは、ほとんどの日本人の理解を超えるものです。
今回の選挙で民主党が勝った場合、「自主」「発展」を連呼しつつ段階的に進めていくことになります。
自主と言っても、自主を認めるのが「住人の96%が中国人となった」後だということに気をつけてください。
発展と言っても、新沖縄の少数派となった「少数民族日本人」の発展ではないことに気をつけてください。
867:名無しさん@お腹いっぱい。
07/04/21 10:20:51
>>865
pythonの拡張を作ってその中からでvim.eval()を呼ぶみたいな方法しかないとおもう
はやいかどうかはしらん
868:初心者
07/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:初心者
07/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
870:KoRoN@Vim%Chalice ◆8XALICEsdk
07/05/03 00:02:52
>>868-869 "<SID>This2"を"s:This2"という風に書き換えてみてください。
871:初心者
07/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:初心者
07/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
873:KoRoN@Vim%Chalice ◆8XALICEsdk
07/05/03 15:49:43
>>872
function! s:MyFunc()
return 321
endfunction
let Fn = function('s:MyFunc')
echo Fn()
こういうスクリプトをtest.vimとして保存して、so test.vimをすると動きます。と
いうことは、もしかしてfunction('s:...')の、s:の評価は実行時のコンテキストに
依存するのかもしれませんね。
874:初心者
07/05/03 16:36:43
KoRoNさん、返事有り難う。しかし、最初から実行時のコンテキス
トと言われても、範囲が広すぎて途方に暮れる。この場合のコンテキ
ストは、何でしょうか?
エラーメッセージでは、スクリプト以外で<SID>が使われましたです
が、他のスクリプトでは使っていません。実行時に何が影響するのだ
ろうか?初心者は挫折しそうだ。
875:KoRoN@Vim%Chalice ◆8XALICEsdk
07/05/03 18:02:35
>>874
挫折して済む話ならば、挫折しちゃったほうが良いかも知れませんよ。
まずb:の時に動くのは、それがバッファに対して定義された関数だからです。
ShuffleBを実行したのがそのスクリプトを読み込んだのと同じバッファであれば、特
定可能で呼出せることになります。逆にいうとスクリプトを読み込んだ後で、別の
ファイルを開いてそちらにカーソルがある状態でShuffleBを実行すると、そのファイ
ル用のバッファには関数が定義されていませんから動かないでしょう。
s:についてはちょっと実験してからもう一度書きます。
876:KoRoN@Vim%Chalice ◆8XALICEsdk
07/05/03 18:09:07
>>874
っていうか、このスクリプトはどういう目的で何をしようとしているのですか?
なんかいろいろ間違ってる気がしてきました。
877:KoRoN@Vim%Chalice ◆8XALICEsdk
07/05/03 19:22:50
>>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:初心者
07/05/08 20:32:57
休暇で岩登りの為、両手両足が使えず。返事が遅くなりました。懇
切丁寧な回答有り難う。良く分かりました。頑張ってみます。
879:名無しさん@お腹いっぱい。
07/05/21 19:21:33
日本語全角モードになってたとき
ESC押せば、全角モードも同時に消えるようにするには、
どうしたらいいのだろうか
880:名無しさん@お腹いっぱい。
07/05/21 20:30:27
>>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:名無しさん@お腹いっぱい。
07/06/04 08:58:22
Hacking Vim: A Cookbook to get the Most out of the Latest Vim Editor (Paperback)
by Kim Schulz (Author)
URLリンク(www.amazon.com)
題名のとおり、Vimスクリプトによる拡張やカスタマイズ、その他のディープな機能に的を絞った本らしい。
882:名無しさん@お腹いっぱい。
07/06/04 17:00:40
vimのscriptの勉強をしてます。
:lsした時に取れる、各bufferのstatusってどうやったらvimのscript上から取れるのでしょうか?
例えばイジってあるbufferである+のstatusとか。
一応次ぎのようなscriptで、一覧を取得出来る所までは出来ました。
続く
883:882
07/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
07/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
07/06/04 17:06:12
あー、indentが崩れてる。ごめんなさい。。。
886:名無しさん@お腹いっぱい。
07/06/04 23:51:12
>>882
+ &modified
= &modifiable
bufloaded()
&buflisted
h bufwinnr()
statのような便利なものはないのでヘルプを見ながらがんばりんさい。
バッファエクスプローラプラグインはたくさんあるから参考にするといいかも。
887:882
07/06/05 23:43:00
出来ました。thx。
ずっと関数だと思って、optionは探していなかったよ。
888:名無しさん@お腹いっぱい。
07/06/06 14:46:24
>>881
amazon.co.jpだと
通常3~5週間以内に発送します
なんだが、もっと早く手に入るところってないかな?
889:名無しさん@お腹いっぱい。
07/06/06 17:58:43
>>881
ebookで買ってみた。
内容は、ディープとまでは感じなかった。Vimスクリプトバリバリ書いてる人は必要なし。
ヘルプにも書いてあるような解説+こう使うと便利になるよというサンプル少々。
>>803のCompleteMailやvim wikiのAutoSaveSessionに似たスクリプトも書いてあった。
やはりこれを買うよりヘルプ、vim wiki、vim onlineのTipsを熟読した方がいいと思う。
890:名無しさん@お腹いっぱい。
07/06/14 12:50:55
質問です.
「文章中にある文字列をもとに 辞書を引く」…というような
スクリプトを書こうとしています.
「カーソル位置の単語を拾い出す」のは expand("<cword>")
で…簡単に作ることができたのですが
でも 調べたい(拾いたい)文字列が 丁度 単語単位とは限らないので
「自分で範囲選択した箇所を スクリプトに渡せるようにしたい」と
考えています.
(小文字の)v キー&範囲選択直後に,
その「選択中の文字列」を 取り出すには どうしたらよいのでしょうか?
<cword> 同様に, 範囲の中身が取り出せるキーワードが
あるような気がするのですが…なかなか探せない....
あるいは 選択範囲の 開始&終了の文字位置 が分かれば
それを手がかりに 取り出せると思うのですが
これもわからない... (どちらも「行単位」なら楽勝なのですが)
…というわけで
何か分かるかた 以上よろしくお願いします.
891:名無しさん@お腹いっぱい。
07/06/14 21:21:08
いったんレジスタにヤンクするのが定石だと思う。
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>
892:名無しさん@お腹いっぱい。
07/06/14 21:34:49
expand('<selected>') みたいなものがあればいいのにな
と思う。
893:名無しさん@お腹いっぱい。
07/06/14 22:43:06
>>891
normal! gv"ay
だけで もう満足です(笑)なるほど
gv って コマンドも 今,知りました
以上 ありがとうございました.
894:名無しさん@お腹いっぱい。
07/06/29 16:49:21
>>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
895:名無しさん@お腹いっぱい。
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の設定を変更した方が
早いかも知れません。