haya14busa / vim-asterisk

:snowflake: *-Improved
http://www.vim.org/scripts/script.php?script_id=5059
MIT License
384 stars 19 forks source link

selection=exclusive 時にビジュアルモードから <Plug>(asterisk-*) を呼び出すと検索するワードが横にずれる #14

Closed osyo-manga closed 9 years ago

osyo-manga commented 9 years ago

タイトルそのままなんですが、set selection=exclusive が設定されている時に例えば

NeoBundle "kannokanno/previm"

Neo を選択して <Plug>(asterisk-*) を呼び出すと NeoB が検索されます。

presuku commented 9 years ago

これは、s:get_multibyte_aware_col(pos)で、set selection=exclusiveのことを 考慮してないからの様です。(こんなオプションあったのですね)

set selection=exclusiveされていると、let c = col(pos)で、cが+1されるみたいです。

また、本題とはそれるのですが、#3 でマージしてもらったs:get_multibyte_aware_col(pos)の修正で、 この他にもバグを見つけてしまいました… selectionはデフォルトで、マルチバイトな文字の上で v<Plug>(asterisk-z*)、つまり1文字を範囲選択して検索すると、 マルチバイト文字の中途半端なところで切られて検索してしまいます。

haya14busa commented 9 years ago

@osyo-manga @presuku 報告ありがとうございます

タイトルそのままなんですが、set selection=exclusive が設定されている時に例えば NeoBundle "kannokanno/previm" の Neo を選択して <Plug>(asterisk-*) を呼び出すと NeoB が検索されます。

んーこちらでは再現しないですね. なんでだろう

selectionはデフォルトで、マルチバイトな文字の上で v→<Plug>(asterisk-z*)、つまり1文字を範囲選択して検索すると、 マルチバイト文字の中途半端なところで切られて検索してしまいます。

こちらは再現しました.

haya14busa commented 9 years ago

マルチバイト文字の中途半端なところで切られて検索してしまいます。

こちらは直してみました

haya14busa commented 9 years ago

.themisrcset selection=exclusive 書いたら3つだけテスト落ちた. のでおかしいことはわかった

haya14busa commented 9 years ago

.themisrcset selection=exclusive 書いたら3つだけテスト落ちた. のでおかしいことはわかった https://github.com/haya14busa/vim-asterisk/issues/14#issuecomment-91233276

これ確認するとおかしいのはテストの仕方の方だったので仕様はおかしくなかった. ※ 実行前に選択する viw の選択範囲がselectionによって変わったのが問題で,選択範囲の文字列を取得する動作は問題がなかった

haya14busa commented 9 years ago

んーやっぱり同様のテストケースを作成してみても再現しないですね. @presuku さんも再現しているのでしょうか?

申し訳ないですがもう少し詳しく再現手順おねがいします

haya14busa commented 9 years ago

ちなみにこちらの手順はこんなかんじ(一応) https://github.com/haya14busa/vim-asterisk/commit/eea912f2eda9bd912dc71e99d086c984673d3a77

haya14busa commented 9 years ago

いらない o がありますが消しても同じ結果

osyo-manga commented 9 years ago

んーこちらでは再現しないですね. なんでだろう

なんでだろう。 あ、あとそのテストは間違っている気がします。 期待する結果としては、

selection=exclusive 時に \V\<Ne selection=inclusive 時に \V\<Neo

となるはずです。 これは selection の設定によってビジュアルの範囲が変わってしまうためです。 normal! v2ly を実行すると selection の設定でヤンクされるテキストが異なることがわかると思います。

再現 vimrc

if has('vim_starting')
    set nocompatible
endif

set runtimepath+=/home/worker/neobundle/vim-asterisk
syntax enable

set hlsearch
set selection=exclusive

map * <Plug>(asterisk-*)

再現手順

  1. 上記の vimrc を読みこんで vim を起動
  2. homu を複数行挿入
  3. :normal ggv2l* を実行
  4. 期待する挙動としては ho を検索して欲しいが hom が検索される

これで試してもらえないでしょうか。 ※SS載せ忘れてたので追記

presuku commented 9 years ago

@haya14busa 再現しています。 exclusiveの時はnormal v2lo*ではなくてnormal v3lo*で、 Neoの3文字の選択だと思います。

とりあえず、こんな感じで直りました… exclusiveの時に、カーソルを動かさないで*した場合は、 No selected stringとなるようにしてみました。

--- a/autoload/asterisk.vim
+++ b/autoload/asterisk.vim
@@ -197,6 +197,11 @@ function! s:get_selected_text(...) abort
     let current_pos = [line('.'), end_col]
     let other_end_pos = [line('v'), s:get_multibyte_aware_col('v')]
     let [begin, end] = s:sort_pos([current_pos, other_end_pos])
+    if &selection ==# 'exclusive'
+        if s:compare_pos(current_pos, other_end_pos) == 0
+            return ''
+        endif
+    endif
     if mode !=# 'V' && begin ==# end
         " multibyte handling for one char selection
         let lines = [matchstr(getline(begin[0]), printf('\%%%dc.', begin[1]))]
@@ -223,10 +228,13 @@ endfunction
 function! s:get_multibyte_aware_col(pos) abort
     let [pos, other] = [a:pos, a:pos is '.' ? 'v' : '.']
     let c = col(pos)
-    let d = s:compare_pos(getpos(pos)[1:2], getpos(other)[1:2]) > 0
-    \   ? len(matchstr(getline(pos), '.', c - 1)) - 1
-    \   : 0
-    return c + d
+    let d = 0
+    let offset = &selection is 'exclusive' ? 1 : 0
+    if s:compare_pos(getpos(pos)[1:2], getpos(other)[1:2]) > 0
+        let c = c - offset
+        let d = len(matchstr(getline(pos), '.', c - 1)) - 1
+    endif
+    return &selection is 'exclusive' ? c : c + d
 endfunction

 function! s:get_multi_col(pos) abort
presuku commented 9 years ago

@osyo-manga おっと、行き違いでしたね。

うーん、上記だけでは不十分みたいです。 set selection=exclusiveで、 NeoBundleNeoBundlまで、選択して*すると、 \V\<NeoBundl\>となって、末尾に余計な\>がついてしまいます。 s:convert_2_word_pattern_4_visual()かなぁ。

haya14busa commented 9 years ago

あーとりあえず勘違いしていたことがわかった.すいません.こちらでも再現しました. 見かけ上選択範囲っぽくてもexclusiveだと最後の文字は含まれないのか

haya14busa commented 9 years ago

@presuku さん

s:get_multibyte_aware_col() のfix (https://github.com/haya14busa/vim-asterisk/issues/14#issuecomment-91278922 ),このブランチ https://github.com/haya14busa/vim-asterisk/tree/fix-selection-handling に pull request して頂いてもいいでしょうか? (コントリビューションに入るので)

末尾に余計な\>がついてしまう問題はやっていただいてももちろんいいですが,ボクもやれると思うのでそのまま PR していただいて OKデス! :ok_woman:

presuku commented 9 years ago

@haya14busa さん 連絡おそくなって、申し訳ないです。 https://github.com/haya14busa/vim-asterisk/issues/14#issuecomment-91278922 の変更では、シングルバイト文字の選択時に 問題があることがわかったので、それを修正してからプルリクします。

また、一応確認ですが、上記の修正にはs:get_selected_text()の変更も含まれてますが、 これも一緒でも良いですか?

末尾に余計な\>がついてしまう問題はやっていただいてももちろんいいですが,ボクもやれると思うのでそのまま PR していただいて OKデス! :ok_woman:

こちらは、お願いします!

haya14busa commented 9 years ago

14 (comment) の変更では、シングルバイト文字の選択時に

問題があることがわかったので、それを修正してからプルリクします。

了解です!

上記の修正にはs:get_selected_text()の変更も含まれてますが、 これも一緒でも良いですか?

okです.おねがいします.

haya14busa commented 9 years ago

exclusiveの時に、カーソルを動かさないで*した場合は、 No selected stringとなるようにしてみました。

これカーソルを動かさないでyしたときにはカーソル下の文字が取得できるので,*でもカーソル下の文字を取得する仕様にします

haya14busa commented 9 years ago

修正してマスターにマージしました.確認をよろしくお願いします.

osyo-manga commented 9 years ago

こちらでも動作することを確認しました。 ありがとうございます。

haya14busa commented 9 years ago

ありがとうございましたっ

presuku commented 9 years ago

確認しました :+1: