-
Notifications
You must be signed in to change notification settings - Fork 11
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
複数の'filetype'を扱いたい #1034
Comments
仮定1, 2に加えて仮定3を導入し、考察を進めました. 仮定3: mftに対するプラグインはftとして読み込まれることはなく、必ずmftとして読み込まれる 仕様オプションminorfiletypes 'mft' バッファロー狩る ランタイムディレクトリmftdetect/ v:変数
関数did_filetype()は従来通り'ft'に対する変更のみ考える. 'mft'が変更されても関知しない did_minorfiltype()は今のところ必要性を感じていない $VIMRUNTIM/syntax/syntax.vim現状
これは、FileTypeがftかmftかで'syntax'を変更するか'minorsyntax'を変更するかを振り分けるように書き直す必要がある minorfiletypesをセットする方法
場合によっては mftに対する設定ftplugin/やindent/を使う派In ftplugin/○○.vim
FileType autocommand派In .vimrc
|
※例によって'ft'と'syn'両方に当てはまります 新しい関数
擬似コード
互換性についてファイルタイプが複合された時( 例2)
などと書いており、ユーザーが
という、問題点として挙げられていた動作が、まさに期待していた動作だった場合. 今のところ思いつく互換性の問題は上の2つです. vim組み込みのファイルタイプで複合ファイルタイプに対応したものはごく少数(doxygenだけ?)であること、ユーザー側が複合ファイルタイプを積極的に利用しづらい状況であったことを鑑みると、互換性を保つために何らかのフラグを設けるといった対処は必要ないように思います. Featureについて
どちらをとっても、'mft'が使えるが'msyn'が使えないといった状況があり得るため、少なくとも標準のscriptはすべての場合について対応が必要 私は案1を推します しばらく待って仕様について異論がないようであれば、この方向で実装を進めようと思います |
個人的には、新しい関数や変数を導入すると、set shiftwidth=0 の機能のような、runtime ファイルの方の対応が遅れて結局使うに使えない状況になる可能性を危惧しています。 そこで、「現状の対応策」の
この案の考えを進めて、以下のように任意の仮想ファイルタイプ(あるいは子ファイルタイプ)を作れるようにするとどうでしょうか? filetype virtual {child-filetype} extends {filetype} 仮想ファイルタイプを作った後はそのファイルタイプに対して autocmd FileType などで個別の設定を追加できます。 |
Issueのタイトルや概要が動機の文章とどう繋がるのかが分からないでいます。 command! -nargs=*
\ Autocmd
\ autocmd vimrc <args> それとも、そのコマンドを使用している部分でしょうか?それとも両方?
あと、「現状の問題点」の |
Re: @tyruさん
これに関しては、この二つの仮定から、既存のruntime/以下にあるファイルの変更は(ほぼ)ないものと考えています
例外として、
すべて 1つ上で、
と書いていましたが、メンテナの問題を鑑み、書き直すか否かは保留します. Re: @h-eastさん ハイライトしたいのはAutocmdを使用している箇所です.
おっしゃる通り可能だと思います. FileType autocommandに関しては、doautocmdを明示的に書かなくてよくなる程度の意味しかありません. 解決したいのはむしろこちらの問題です
|
@keik8128 私の最初の質問に答えて貰えると嬉しいです。 |
Re: @h-eastさん
私が考えている「複数のファイルタイプ」というのは、 説明がわかりにくく申し訳ありません |
@keik8128 なるほど。ただ、明示的に runtime! syntax/ruby.vim すればいいのではないかと思います。 現に、 " Read the C syntax to start with
runtime! syntax/c.vim
unlet b:current_syntax という処理が入っています。これを踏襲すればいいのではないでしょうか? |
Re: @h-eastさん ft=railsとすると、既存のプラグインで if !exists('g:foo_plugin#config')
let g:foo_plugin#config = {}
endif
let g:foo_plugin#config.ruby = ... のようにしていた場合、railsに対しても let g:foo_plugin#config.rails = g:foo_plugin#config.ruby が必要になります. また、rubyに対してこのfoo_pluginのデフォルト設定を使っていた場合、 let g:foo_plugin#config.rails = g:foo_plugin#config.ruby とした箇所でfoo_pluginがautoloadされます autoloadされるのを防ごうとすれば、 let g:foo_plugin#config.rails = {foo_plugin.vimからコピペしてきたft=rubyに対するデフォルト設定} となってしまいます. 更に、そもそもこのようにユーザーが設定することを考慮していないプラグインも存在します |
考察は非常に面白いと思ったのですが、自分も @h-east さんに同意見です。 現状、複数の filetype を設定するケース自体が(確かにそのようなシステムが無くて不便な時はありますが)あまり無い気がしていて、新たに minor filetype という概念を導入するほどではない、と思います。 …と書こうとしていたら先にコメントを書かれましたが、これは面白い視点だと思いました。 しかしこの用途のためにこれらの関数やオプションを導入する、というのはやはりメリットが薄いように思います。 |
このコマンドがなにをするのかがいまいち理解できておりません. 以下のような理解で正しいでしょうか?
ユーザー側から{child}や派生元({parent})が何なのかを知るには、やはり何らかのインターフェースが必要になると思いますが、もしこのインターフェースをオプションにすれば、結局'mft'に行き着いてしまうように思います.
tpope/vim-railsを例に挙げると、このプラグインはrailsかどうかを「ファイル名やディレクトリ名決め打ちで auto-command を登録して、それぞれの設定を行っ」ていますが、ftがrubyのままなので、ほかのプラグインは今扱っているファイルがrailsであるのかを知るすべがありません(正確には、vim-railsに依存せずに知るすべがありません).
得られるメリットに比べて変更範囲が大きくなりすぎることはソースコードの調査段階で私自身感じていたことでもあります. せっかくソースコードを調べたので実装はしてみようと思いますが、本家に投げるかはその後また考え直したいと思います. @h-eastさん、@tyruさん、ありがとうございました. |
すみません、コードだけでほとんど説明していませんでした。
まずこれに関しては、ユーザーが知る必要はないと思っています。
基本的に Yes ですが、1番目だけ補足します。
つまり、以下も行います。
そうすれば #1034 (comment) のコメントのようなことは起きないと思います。 |
この点は私もそのつもりでいました. わかりにくい表現になってしまいすみません.
ファイルタイプごとに設定が変わるのはftpluginやindent以下において使うプラグインだけではないので、必要なケースはあると思っています. if !exists('g:foo_plugin#config')
let g:foo_plugin#config = {}
endif
let g:foo_plugin#config.ruby = ...
let g:foo_plugin#config.rails = {rubyとは違う設定} このような設定をさせるプラグインは多く、これらの挙動を派生元と派生先で変えたいことがあります. ほとんどの場合ではft=rubyで振る舞ってほしいのですが、逆に挙動を変えたいときには何らかの形でこれがrailsであることを知る必要が出てきます. もしこのfoo_pluginがmftに対応すれば、mft=railsという付加情報を受け取ることができます. また、対応できていなくとも、少なくともft=rubyにはなります. |
すみません、返信が遅れました。 |
実装終了しました。ドキュメントはおそらくまだまだ抜けがあります。
https://github.com/keik8128/vim/tree/feature/extrafiletypes 使用例: " .vimrcの最後にモードラインとして
" vim: ft=vim:eft=vimrc
" もしくは .vim/eftdetect/vimrc.vim
autocmd BufNewFile,BufRead *vimrc* set eft=vimrc " .vim/syntax/vimrc.vim
if exists("b:current_syntax_vimrc")
finish
endif
if !v:syn_isextra
finish
endif
if b:current_syntax !=# 'vim'
finish
endif
" Autocmd
syn keyword vimrcAutocmd Autocmd skipwhite nextgroup=vimAutoEventList
" Plugin manager command
syn keyword vimrcPluginManager Plug
hi default link vimrcAutocmd vimAutocmd
hi default link vimrcPluginManager vimCommand
let b:current_syntax_vimrc = 1 |
@keik8128 👍 |
修正しました |
|
なるほど、encodingのせいでしたか。今度こそ修正できたはずです。 |
まだまだ仕様について検討が必要ですが、必要か否か、実装難度、仕様の不備などについてご意見をいただければ幸いです. なお、実装には
ほとんど手を着けていません完了しました.概要
現状でも
setl ft=foo.bar
は可能だが, 様々な問題が起こる(後述). これを何とかしたい※以下の議論のほとんどは'filetype'だけでなく'syntax'にも当てはまる
動機
のようにしているとき,
Autocmd
をautocmd
と同様にハイライトしたい(他のvimファイルでは必要ない)現状
setl ft=foo.bar
することで, fooとbarをfiletypeとして設定できる現状の問題点
&filetype==#'foo'
というようにしてファイルタイプを判定するので, この場合fooでもbarでもないファイルタイプとして扱われる※なお, 'syntax'については
==#
で判定することが(たぶん)ほぼないので, それほど問題ではない現状の対応策
&filetype==#'foo'
の判定にかからないfiletype =~# '\<foo\>'
か?getmainft(), getfts(), getminorfts(), ...
autocmd {group} BufRead *.bar {let b:何らかの変数}
ftdetect/vimrc.vim
で、autocmd BufRead *vimrc* let b:ftplugin_vim_enable_vimrc = v:true
after/{syntax,ftplugin}/vim_vimrc.vim
で、↑の変数をチェック求められる仕様
set ft=foo.bar
はこの点に大きな問題がある. foo.barはfooでもbarでもない実現手段
新しいオプション
'minorfiletypes' 名前は暫定(候補: filetypes, subfiletypes, ...)
新しい関数
shiftwidth()
のような役割)...など
プラグイン側の対応とユーザーの設定
運用1: (best practice)
ftは常に一つに保ち, mftに追加していく.
この方法が優れているのは, 古いプラグインも少なくともftは認識する, という点. これが他の解決策と大きく違う. すなわち、mftを見ないプラグインにはPRを送らなくていい
運用2:
ftにピリオド区切りで追加していく
パターン1: プラグイン非対応でユーザーがmftを使用
パターン2: プラグイン非対応でユーザーがmftを不使用
パターン3: プラグイン対応でユーザーがmftを使用
パターン4: プラグイン対応でユーザーがmftを不使用
新しい関数は, このパターン3, 4において意味を持つ.
すなわち, 運用2が使われた場合でも, 従来とは違ってきちんと複合ファイルタイプを認識できる
(プラグインが直接オプションに触れずに関数からアクセスしていればの話)
使用例
indent/やsyntax/も同様
その他考察
TODO commentstring, defineなどのファイルタイプに深く関わるオプションをどうするか. なにも考えずに実装すると後に指定したファイルタイプほど優先される(上書きされていく)と思う. 上書きした方がいいか残した方がいいかは場合によって変わりそうなので、もう少し考察する必要がある
TODO major filtypeとして呼ばれたのかminor filetypeとして呼ばれたのかは判別できた方がよさそう. 別のイベントを発行するわけにはいかないので, v:変数を使うことになる
TODO feature. 新しいfeatureにすべきか(filetypeやsyntaxに準じるべきではないか). また、'syntax'が使える条件と'filetype'が使える条件は異なる. 'syntax'が使えないのに+minorsyntaxされると困る. 現在feature同士の依存関係はあるのか? 要調査
TODO did_filetype()はどうなるべきか?
TODO filetypeは排他的にするべきか? 現在は排他的でない(
ft=foo.bar
が可能)ので, 排他的にすると互換性が壊れる.:setf
を使えば排他的になるTODO ft=不明でmft=foo.barはあり得るか? ftがない状態でmftが設定されても予想外の事態は起きないか?
TODO b:did_ftpluginやb:undo_ftpluginの扱い
TODO 'ft'と'mft'はディレクトリを分けるべきか? mftplugin/, mindent/, msyntax/とか
以下の仮定をおくと上の問題のいくつかが(たぶん)解決する
仮定1: mftに対するftpluginやindentは新しく作られる
すなわち, 必ずmftに対応している
仮定2: mftはEmacsのように様々なファイルタイプに対する共通の設定ではなく, ftに付随するものである(is a関係が成立する)
e.g.) ruby <- rspec vim <- vimrc cpp <- cppheader
問題1は, commentstringやdefineが書き換わりようがない(XXX is a YYYが常に成立している)ため, 問題にならない
例えばft=vim, mft=vimrcだとすれば、vimrcでvimと矛盾するような設定はするはずがない(いきなり
setl iskeyword+=?
なんてことはしない)問題4,7は, 仮定1があるため, 新しい関数, 変数を用意することで解決する
The text was updated successfully, but these errors were encountered: