Vim:显示当前的json路径

7

我是一个有用的助手,可以帮您进行文本翻译。

我正在使用vim编辑一个非常庞大且嵌套的JSON文档(如果您感兴趣的话,这是rightscale api),并且希望知道当前的json-path(类似于json的xpath)类似于:

给定JSON:

 {                                    
     "leve1": {                       
         "level2": {                  
             "level3": {              
                 "name": "goes here"  
             }                        
         }                            
     }                                
}

当光标位于"name":和"goes here"之间时,我想要一个命令(或状态栏)显示:

level1/level2/level3/name

有类似的东西吗?或者类似的技术存在吗?
2个回答

6

我最近为此编写了一个名为vim-jsonpath的插件。它目前提供以下命令(当然可以映射):

  • :JsonPath:回显鼠标下标识符的路径。
  • :JsonPath path.to.prop:搜索活动缓冲区中给定路径,如果找到则将光标放置在其上。

3

我已经写了两个映射,使用折叠信息(因此它们应该适用于任何结构,而不仅仅是 JSON)。对于你的示例,它们输出

{ / "leve1": { / "level2": { / "level3": {

并且(长版本):

1  {
2      "leve1": {
3          "level2": {
4              "level3": {

以下是脚本。它依赖于我的ingo-library插件

" [count]z?     Print all lines (with numbers) that start a fold where
"           the current line is contained in (for [count] upper
"           levels). When a line consists of just a symbol like "{",
"           the preceding non-empty line is printed, too.
" [count]z/     Like z?, but use a short output format with all line
"           contents concatenated, and without line numbers and
"           symbols.
if ! exists('g:PrintFoldHierarchySymbolLinePattern')
    let g:PrintFoldHierarchySymbolLinePattern = '^\s*{\s*$'
endif
function! s:PrintFoldHierarchy( count, isJoin )
    if foldclosed('.') != -1
        return 0
    endif

    let l:save_view = winsaveview()
        let l:levels = []
        let l:lnum = line('.')
        while (a:count ? len(l:levels) < a:count : 1)
            silent! normal! [z
            if line('.') == l:lnum
                break
            endif
            let l:lnum = line('.')
            call insert(l:levels, l:lnum)
            if getline(l:lnum) =~# g:PrintFoldHierarchySymbolLinePattern
                let l:precedingLnum = prevnonblank(l:lnum - 1)
                if l:precedingLnum > 0
                    if a:isJoin
                        let l:levels[0] = l:precedingLnum
                    else
                        call insert(l:levels, l:precedingLnum)
                    endif
                endif
            endif
        endwhile
    call winrestview(l:save_view)

    if a:isJoin
        echo
        let l:isFirst = 1
        for l:lnum in l:levels
            if l:isFirst
                let l:isFirst = 0
            else
                echohl SpecialKey
                echon ' / '
                echohl None
            endif
            echon ingo#str#Trim(getline(l:lnum))
        endfor
    else
        for l:lnum in l:levels
            echohl LineNr
            echo printf('%' . (ingo#window#dimensions#GetNumberWidth(1) - 1) . 'd ', l:lnum)
            echohl None
            echon getline(l:lnum)
        endfor
    endif

    return 1
endfunction
nnoremap <silent> z? :<C-u>if ! <SID>PrintFoldHierarchy(v:count, 0)<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>
nnoremap <silent> z/ :<C-u>if ! <SID>PrintFoldHierarchy(v:count, 1)<Bar>execute "normal! \<lt>C-\>\<lt>C-n>\<lt>Esc>"<Bar>endif<CR>

您可以将这些内容放入您的~/.vimrc文件(或一个单独的~/.vim/plugin/PrintFoldHierarchy.vim文件),并通过z?z/在正常模式下调用映射。

那个脚本没有插件吗? - Vitaly Zdanevich
在正常模式下,键入“z?”或“z/”不会产生任何效果 :( - Vitaly Zdanevich

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接