Vimマップでスクリプトローカル辞書を参照する方法は?

Vimマップでスクリプトローカル辞書を参照する方法は?

どういうわけか、次のマッピングを実行できません。

function! s:MySurroundingFunctionIWantToKeep()
  let s:Foobar={'foo': 'bar'}
  map \42 :echo <sid>Foobar.foo<cr>
endfunction
call s:MySurroundingFunctionIWantToKeep()

私の考えでは、スクリプトローカル関数と同じように動作すると思います。

function! s:MySurroundingFunctionIWantToKeep()
  function! s:Foobar()
    echo 'bar'
  endfunction
  map \42 :call <sid>Foobar()<cr>
endfunction
call s:MySurroundingFunctionIWantToKeep()

s:Foobarこれを削除してもs:MySurroundingFunctionIWantToKeep()役に立ちません。たとえば、次のようになります。

let s:Foobar={'foo': 'bar'}
map \42 :echo <sid>Foobar.foo<cr>

s:Foobarスクリプトローカル変数をg:Foobarグローバル変数として宣言するだけです。

ベストアンサー1

(私が知る限り)そのスクリプトのコンテキストの外からスクリプトローカル変数に直接アクセスする方法はありません<SID>

ただし、次の機能により間接的なアクセスを提供できます。

function! s:FoobarHash()
  return s:Foobar
endfunction
function! s:MySurroundingFunctionIWantToKeep()
  let s:Foobar={'foo': 'bar'}
  map \42 :echo <sid>FoobarHash()['foo']<cr>
endfunction
call s:MySurroundingFunctionIWantToKeep()

変数をどの程度分離したいかに応じて、「接続者」機能をより制限的に作成できます(特定のキーのみを許可、読み取りアクセスのみを許可、特定のキーへの書き込みのみを許可するなど)。

let s:Foobar={'foo': 'bar', 'baz': 'quux'}
function! s:FoobarAccess(...)
  " Provide limited access to the script-local hash s:Foobar

  if a:0 == 1
    " allow read access to all keys
    return s:Foobar[a:1]

  elseif a:0 == 2
    " allow write access to only 'foo'
    if a:1 !=# 'foo'
      throw 'FoobarAccess: not allowed to write to key ' . a:1
    endif
    let old = s:Foobar[a:1]
    let s:Foobar[a:1] = a:2
    return old

  else
    throw 'FoobarAccess must take exactly one or two arguments'
  endif
endfunction


map \42 :echo <sid>FoobarAccess('foo')<cr>
map \43 :echo <sid>FoobarAccess('foo','new value')<cr>
map \44 :echo <sid>FoobarAccess('baz')<cr>
map \45 :echo <sid>FoobarAccess('baz',1)<cr>

おすすめ記事