Hatena::Groupvim

選択されたテキストの取得

選択されたテキストの取得

実装例 by id:ns9tks

function GetVisualText()
  let p0 = getpos('''<')
  let p1 = getpos('''>')

  if p0[1] == p1[1]
    return getline(p0[1])[ p0[2] - 1 : p1[2] - 1 ]
  else
    return join([ getline(p0[1])[ p0[2] - 1 : ] ] +  getline(p0[1] + 1, p1[1] - 1) +
          \     [ getline(p1[1])[ : p1[2] - 1 ] ] , "\n")
  endif
endfunction
  • この方法では選択が文字単位/行単位/矩形単位だったのかの情報が含まれていないため、完全に同じテキストを得られるとは限らない。参考: help visual-characterwise / help visual-linewise / help visual-blockwise

レジスタとノーマルモードコマンドを利用したスマートな実装例 by id:tanakaBox

Haskell mode for Vim - ボクノスのs:GetSelect()

  • id:ns9tksの実装例と同様の問題がある。
  • レジスタ0(最後にヤンクされたテキストを保持するレジスタ)が関数呼び出し時の値に復元されていない。
  • カーソル位置が関数呼び出し時の位置に復元されていない。
  • ビジュアルモードから呼び出されると場合によっては期待通りの動作をしない。

上記の問題を修正した実装例 by id:ka-nacht

function! x:selected_text(...)
  let [visual_p, pos] = [mode() =~# "[vV\<C-v>]", getpos('.')]
  let [r_, r_t] = [@@, getregtype('"')]
  let [r0, r0t] = [@0, getregtype('0')]

  if visual_p
    execute "normal! \<Esc>"
  endif
  silent normal! gvy
  let [_, _t] = [@@, getregtype('"')]

  call setreg('"', r_, r_t)
  call setreg('0', r0, r0t)
  if visual_p
    normal! gv
  else
    call setpos('.', pos)
  endif
  return a:0 && a:1 ? [_, _t] : _
endfunction