basyura's blog

あしたになったらほんきだす。

w、e、b でもうちょっと効率よく移動したい

(※) 既にあった - https://github.com/kana/vim-smartword

単語を移動する時に、. とか = とかで止まらなくていいからと思っていたので書いてみた。

nnoremap <silent>w :call <SID>clever_move("w")<CR>
nnoremap <silent>b :call <SID>clever_move("b")<CR>
nnoremap <silent>e :call <SID>clever_move("e")<CR>

let s:no_clever_pattern = '\.\|(\|)\|!\|:\|]\|=\|<\|>\|"\|\$\|/\|-' ."\\|'"

function! s:clever_move(word)
  execute "normal! " . a:word
  let chr =getline('.')[col('.') -1]
  if  chr =~ s:no_clever_pattern || chr == ''
    call s:clever_move(a:word)
  endif
endfunction

clever を使いたかっただけともいう。

いまさらながら w をウインドウ移動に使用していてスムーズに移動しない(待ちが発生する)のが気になった。

noremap wh <C-w>h
noremap wl <C-w>l
noremap wj <C-w>j
noremap wk <C-w>k
noremap wp <C-w>p

別のキーに当てようとしたけど長年使ってたせいでしっくりこないので断念。

neocomplete に辞書からのメンバ補完が実装された

member ブランチで。

独自実装していたのだけど、

本家で実装されました。僕が実装したところとの違いは

UIView.alloc.initWithFrame
alloc.initWithFrame

と辞書に登録してあった場合、UIView.alloc. と打った時に initWithFrame が補完候補に上がるけど、UIWindow.alloc と打った場合に補完されない。どっちがいいのかはよくわからないけど。

To: Shougo さん

それ以外の動作は特に問題無さそうです。

neco-member-dict - 辞書ファイルからメンバ補完する neocomplete の source

f:id:basyura:20140708144952g:plain

https://github.com/basyura/neco-member-dict

辞書ファイルに

UINavigationController.alloc.initWithRootViewController
UIColor.blueColor
UIColor.redColor
UIColor.whiteColor
self.view.frame.size.width

って書いといたらメンバ補完してくれたらいいのにと前々から思っていたのをやや強引に実装してみた。

いまいちなところ

  • 補完開始位置を切り出す get_complete_position は、neocomplete の member.vim を丸パクリ
  • 補完開始位置前の単語を取得する方法がよく分からんので強引に実装 (取得した単語を元に補完するキーワードを表示する)
  • s:cache で抱え込んでいる
  • . で区切られた単語が対象。 : とか :<space> も区切り文字として判定したい (けど、パターンが膨れすぎて抱えるキャッシュの量がハンパなくなりそう)

TweetVim 2.4 Release !!

f:id:basyura:20140706171605p:plain

https://github.com/basyura/TweetVim/

実装がまだ中途半端な状態ではあるけれど、Vim 7.3 で動かないツイートをチラホラみかけたので考慮を追加してリリース。

  • イベント通知 hook を追加 thanks! tokoro10g
  • UserStream に fav を表示
  • regexpengine = 1 or vim 7.3 のときは url を考慮せずに文字数でカウントする
  • typo とか hilight の改善、url 展開の改善とかたくさん thanks! rhysd
  • say バッファでタグメンションをハイライト thanks! thinca
  • vital のアップデート

tokoro10g さんがイベント通知の仕組みを組み込んでくれたので、それを利用して fav された場合に UserStream に流すようにしてみた (上の画像)。画像では basyura のツイートを tweetvim アカウントが fav してる状態。分かりづらいので、fav したアカウントのアイコンを表示でも良さそう。unfavorite、retweeted_status、notify_mention イベントもトリガとして用意しているけど、僕の方であまり動作確認できていない状態。tweetvim#hook#add(name, func_name) を使用することでイベントに対する処理を呼び出すことができる想定。

毎度、イヌさんとマンボウさんに pull request を頂いておりありがとうございます (=ΦωΦ)にゃごー

neocomplete 補完時の動作

neocomplete の source を書きたいのだけど、context に何が入ってくるのかよく分からんので調べてみる。

{context}				neocomplete-notation-{context}
			A dictionary to give context information.
			The followings are the primary information.
			The global context information can be acquired
			by |neocomplete#get_context()|.

			input			(String)
				The input string of current line.

			complete_pos		(Number)
				The complete position of current source.

			complete_str		(String)
				The complete string of current source.

			source__{name}		(Unknown)	(Optional)
				Additional source information.
				Note: Recommend sources save
				variables instead of s: variables.
input
カーソル行のカーソル位置までの入力文字列
complete_str
補完対象の文字列
complete_pos
補完開始位置。この位置から補完候補で書き換わる

これが gather_candidates(context) で呼ばれたさいにどういう値が入っているのかを見てみる。|がカーソル位置。

単語を入力

abc|

input abc
complete_str abc
complete_pos 0


補完の開始位置は先頭(0)で、入力内容(abc)と補完対象(abc)が同じ

2 つ目の単語を入力

abc def|

input abc def
complete_str def
complete_pos 4


補完の開始位置は 2 つ目の単語の先頭 (4) で、入力内容はその行の内容 (abc def) で、補完対象は 2 つ目の単語 (def)。

2 つめの単語でメソッド呼び出し (.) 相当を入力

abc def.ghi|

input abc def.ghi
complete_str ghi
complete_pos 8


補完の開始位置は 2 つ目の単語の . で、入力内容はその行の内容 (abc def.ghi) で、補完対象は 2 つ目の単語の . 以降。

開始位置の文字を取得する

abc.d|

echo a:context.input[complete_pos]
" => d

補完開始位置の前の文字列を取得するには

let pos = a:context.complete_pos - 1
let word = ""
if pos > 0 && a:context.input[pos] == '.'
  while 1
    let pos = pos -1  
    let chr = a:context.input[pos]
    if chr == '' || chr == ' ' || chr == '('
      break
    endif
    let word = chr . word
  endwhile
endif

ゴリるしかない?

Gitv したときにで出ちゃう ^M を消す

ソースを弄って直そうと思ったけど・・・どこを直したらいいのか分からなかった・・・。自力でゴリゴリで。

augroup MyGroup
  autocmd!
  autocmd WinLeave * :call s:subm()
augroup END

function! s:subm()
  if &filetype != 'git'
    return
  endif
  if &modifiable
    return
  endif
  setlocal modifiable
  silent! 1,$ s/^M//g
  setlocal nomodifiable
endfunction

unite-mdfind

https://github.com/basyura/unite-mdfind

(既に unite-spotlight という同様の plugin あった・・・)

unite-everything を常用しているのだけど、everything が windows でしか動かないので mac 版を作ってみた。mdfind (spotlight) を使った検索結果を表示する。

使い方

:Unite mdfind

または

:Unite mdfind:ディレクトリパス

どちらも -name option で検索する。
後者の場合は指定のディレクトリ配下のファイルだけを検索する (-onlyin option)。

file kind に mdfind action を追加して、その配下のファイルが探しやすくしてみた。または、以下のようにマッピングして呼び出す。

inoremap <silent><buffer><expr> <C-s> unite#do_action('mdfind')

いけてない特徴

  • -name で探しているのでファイル名をあいまい検索できない。ファイルの数が多くないのであれば rec_parent/async の方が扱いやすい。 → あいまいけんさくできたのでデフォルトにした。
  • async じゃない
  • ignore 設定が無い
  • async じゃない分入力が引っかかるので、required_pattern_length を 5 に設定している (unite#custom#profile とかで外からセットできないんだっけか?)