tyru / caw.vim

Vim comment plugin: supported operator/non-operator mappings, repeatable by dot-command, 300+ filetypes
378 stars 48 forks source link

C/C++ comment out/uncomment timing error with kana/vim-textobj-function #128

Open tsuyoshicho opened 4 years ago

tsuyoshicho commented 4 years ago

2020/03/27 latest use.

Error happen after caw.vim updated.

Problem resolving, but my vim is complexity and does no make simple reproduction .vimrc. Information suggests only.

[Vim(unlet):E108: その変数はありません: "b:textobj_function_select"]::[function caw#keymapping_stub[63]..329[5]..326[3]..328[1]..322[1]..338[1]..341[1]..343[5]..caw#load_ftplugin, 行 2]

kana/vim-textobj-function is https://github.com/kana/vim-textobj-function

kana/vim-textobj-function are set unlet in b:undo_ftplugin

https://github.com/kana/vim-textobj-function/blob/adb50f38499b1f558cbd58845e3e91117e4538cf/after/ftplugin/c/textobj-function.vim#L28-L38

This is a timing issue or ftplugin policy conflict issue?

tsuyoshicho commented 4 years ago

b:undo_ftplugin execute manually, need clearing in b:undo_ftplugin ?

tyru commented 4 years ago

Sorry, I couldn't clearly understand what you said. 日本語でいいですよ〜

いくつか質問があるのですが、以下がちょっと曖昧で良く分かりませんでした。

b:undo_ftplugin execute manually, need clearing in b:undo_ftplugin ?

tsuyoshicho commented 4 years ago

あー、ありがとうございます。

問題は現在も再現し続けているのか?

再現はすることがありますが、契機が不明です。 出るときはコメントアウトの初回だけ出て、2回は出ません。

一番出るのは、deinのtoml内のvim script(context_filetypeでセットされる)でコメントアウトしようとするとですね、ちなみにそこで一度出ると、処理されず、再度やると出なくなりますがCのコメントアウトが発動する(以降そのまま)という... (他でも出たときは同様になる)

以下の意味がよく分かりませんでした

b:undo_ftpluginをexecしてますが、手動でやるなら、b:undo_ftplguinをクリアしないといけないのでは?と思いました。

通常はvimがファイルタイプを変更するときに、一度除去する処理としてb:undo_ftpluginを実施して、改めてFiletypeをセットする理解です ここで手動でb:undo_ftpluginを実施してるなら、消さないと残って再実行してしまうのでは?と思いまして...

tsuyoshicho commented 4 years ago

再現性の高い手順で実施できたので、結果を付けます。 (ただし自分の環境下で、ですが)

  1. 以下のvim scriptを詠み込み済み(or quickrunする)
function! s:undo_check() abort
  " unlet b:undo_ftplugin
  echomsg 'exists' exists('b:undo_ftplugin')
  try
    echomsg 'undo ftplugin' b:undo_ftplugin
  catch
    echomsg 'cache' v:exception
  endtry
  echomsg 'exists b:textobj_function_select' exists('b:textobj_function_select')
  try
    echomsg 'value' b:textobj_function_select
  catch
    echomsg 'cache' v:exception
  endtry
endfunction

command! UndoCheck call s:undo_check()
  1. 以下のcファイルを読む
#include <stdio.h>

int
main(int argc, char* argv[]) {
  // int a;
  return 0;
}
  1. UndoCheck 後 変数を caw でアンコメント

  2. エラーで動作しない(結果参照)

  3. 再度実施すると以下になる

#include <stdio.h>

int
main(int argc, char* argv[]) {
  /* // int a; */
  return 0;
}

結果

exists 1
undo ftplugin setl fo< com< ofu< cms< def< inc< | if has('vms') | setl isk< | endif | unlet! b:caw_oneline_comment b:caw_wrap_oneline_comment b:caw_wrap_multiline_comment b:did_caw_ftplugin|unlet b:textobj_function_select
exists b:textobj_function_select 1
value function('textobj#function#c#select')
[Vim(unlet):E108: その変数はありません: "b:textobj_function_select"]::[function caw#keymapping_stub[63]..436[5]..433[3]..435[1]..429[1]..445[1]..448[1]..450[5]..caw#load_ftplugin, 行 2]

ちなみに

https://github.com/kana/vim-textobj-function/search?q=unlet&unscoped_q=unlet

影響するのは vim/java/c だけ、と思われる

tsuyoshicho commented 4 years ago
function! s:undo_check() abort
  " unlet b:undo_ftplugin
  echomsg 'filetype' &l:filetype
  echomsg 'context filetype' context_filetype#get_filetype()
  echomsg 'exists' exists('b:undo_ftplugin')
  try
    echomsg 'undo ftplugin' b:undo_ftplugin
  catch
    echomsg 'cache' v:exception
  endtry
  echomsg 'exists b:textobj_function_select' exists('b:textobj_function_select')
  try
    echomsg 'value' b:textobj_function_select
  catch
    echomsg 'cache' v:exception
  endtry
endfunction

command! UndoCheck call s:undo_check()

上記とload関数呼ぶところにメッセージを仕込みました。

filetype c
context filetype c
exists 1
undo ftplugin setl fo< com< ofu< cms< def< inc< | if has('vms') | setl isk< | endif | unlet! b:caw_oneline_comment b:caw_wrap_oneline_comment b:caw_wrap_multiline_comment b:did_caw_ftplugin|unlet b:textobj_function_select
exists b:textobj_function_select 1
value function('textobj#function#c#select')
s:base._get_related_ft_comments
ft masm
s:base._get_related_ft_comments
ft gas
[Vim(unlet):E108: その変数はありません: "b:textobj_function_select"]::[function caw#keymapping_stub[66]..406[5]..403[3]..405[1]..399[1]..415[1]..418[1]..420[7]..caw#load_ftplugin, 行 2]

caw#get_related_filetypes(a:context.filetype)

のループで呼び出しをしている様子です。

tsuyoshicho commented 4 years ago

ログコードを仕込んでみたところこうなりました。

unlet! 付きでないのがあるとエラーとなってしまうので silent! にすれば正常動作するようです。 PRを作ります。

b:textobj_function_select is not exists: 0
b:undo_ftplugin dump: call VimFtpluginUndo() | unlet! b:caw_oneline_comment b:caw_wrap_oneline_comment b:caw_wrap_multiline_comment b:did_caw_ftplugin | unlet! b:did_sandwich_vim_ftplugin b:sandwich_magicchar_f_patterns|unlet b:textobj_function_select | unlet! b:caw_oneline_comment b:caw_wrap_oneline_comment b:caw_wrap_multiline_comment b:did_caw_ftplugin
silent exec
function! caw#load_ftplugin(ft) abort
  if exists('b:undo_ftplugin')
    if !exists('b:textobj_function_select')
      echomsg 'b:textobj_function_select is not exists:' exists('b:textobj_function_select')
      echomsg 'b:undo_ftplugin dump:' b:undo_ftplugin
      echomsg 'silent exec'
      silent! execute b:undo_ftplugin
    else
      execute b:undo_ftplugin
    endif
  endif
  unlet! b:did_caw_ftplugin
  execute 'runtime! after/ftplugin/' . a:ft . '/caw.vim'
endfunction