Vim script で stacktrace 書いてみた
[関連]
これを Vim script だけでどこまで出来るかやってみた
[コード]
let s:V = vital#of("vital") let s:S = s:V.import("Palette.Scriptnames") function! s:call_stack() try throw 'abc' catch /^abc$/ return split(matchstr(v:throwpoint, 'function \zs.*\ze,.*'), '\.\.')[ : -2] endtry endfunction function! s:parse_script_function(text) let pat = '^<SNR>\(\d\+\)_\(\w\+\)\[\(\d\+\)\]' let result = matchlist(a:text, pat) if empty(result) return {} endif let path = s:S.find("SID == " . result[1]).file return { \ "kind" : "script", \ "path" : path, \ "SID" : result[1], \ "name" : result[2], \ "lnum" : result[3], \ } endfunction function! s:parse_lambda_function(text) let pat = '\<lambda>\(\d\+\)\[\(\d\+\)\]' let result = matchlist(a:text, pat) if empty(result) return {} endif return { \ "kind" : "lambda", \ "ID" : result[1], \ "name" : "", \ "lnum" : result[2], \ } endfunction function! s:parse_global_function(text) let pat = '\(\w\+\)[\(\d\+\)\]' let result = matchlist(a:text, pat) if empty(result) return {} endif return { \ "kind" : "global", \ "name" : result[1], \ "lnum" : result[2], \ } endfunction function! s:parse(text) let result = s:parse_script_function(a:text) if !empty(result) return result endif let result = s:parse_lambda_function(a:text) if !empty(result) return result endif let result = s:parse_global_function(a:text) if !empty(result) return result endif return {} endfunction function! s:stacktrace() let stack = reverse(s:call_stack()[:-2]) return map(stack, "s:parse(v:val)") endfunction function! Global() echo PP(s:stacktrace()) endfunction function! s:sub2() abort return Global() endfunction function! s:sub1() abort let F = {-> s:sub2() } call F() endfunction function! s:main() abort call s:sub1() endfunction call s:main()
[出力結果]
[ {'kind': 'global', 'lnum': '1', 'name': 'Global'}, { 'SID': '693', 'kind': 'script', 'lnum': '1', 'name': 'sub2', 'path': '/Users/rbtnn/a.vim' }, {'ID': '66', 'kind': 'lambda', 'lnum': '1', 'name': ''}, { 'SID': '693', 'kind': 'script', 'lnum': '2', 'name': 'sub1', 'path': '/Users/rbtnn/a.vim' }, { 'SID': '693', 'kind': 'script', 'lnum': '1', 'name': 'main', 'path': '/Users/rbtnn/a.vim' } ]
グローバル関数と lambda 関数はファイル名が取得できなかった…。