0

Is there a way to have vim (or a plugin) read a json file and use that to define a browsing structure?

In my case, the json file defines a novel, which is a collection of chapters. A chapter is a set of scene files.

The reason to do this is to allow many different organizations of the same set of files. A disk-based directory/file structure isn't flexible enough for multiple hierarchies.

I'd like to see something like this in the file browser window, with the structure defined in a json file (see example below):

MyNovel/
  Beginning/
    001
    002
    003
  Middle/
    004
    100
    101
  End/
    203
    202
    201
{
"version" : "2.0",
"manuscript" : { 
    "title" : "MyNovel",
    "chapters" : [
        {   
            "title"   : "Beginning",
            "scenes"  : ["001", "002", "003"]
        },  
        {   
            "title"   : "Middle",
            "scenes"  : ["004", "100", "101"]
        },  
        {   
            "title"   : "End",
            "scenes"  : ["203", "202", "201"]
        }
    ]   
}
}

In this case, MyNovel, Beginning, Middle, and End are virtual groupings of the scene files, and do not exist on disk.

I'm happy to hack my own solution. I've looked at most common vim plugins, and don't see an example to use as a starting point, but it seems like something like this has got to be out there somewhere ...

Thanks!

dhr
  • 1
  • 1

1 Answers1

-1

VimScript already has two builtin functions to natively support json: json_encode() and json_decode(). And a "browser" can be implemented as yet another buffer with a preset content.

A very primitive sketch (w/o any error checking and such):

function! DisplayAsTree(bufnr)
    let l:mytree = json_decode(join(getbufline(a:bufnr, 1, "$")))
    new
    call setline(1, l:mytree.manuscript.title . "/")
    for l:chap in l:mytree.manuscript.chapters
        call append("$", repeat(' ', &ts) . l:chap.title . "/")
        for l:scene in l:chap.scenes
            call append("$", repeat(' ', 2 * &ts) . l:scene)
        endfor
    endfor
endfunction

But the most complex and annoying part will be the actual "browser-like" implementation of the desired functionality. For example, you may want to setup some options, such as :h 'buftype' and :h 'concealcursor', and some :h map-<buffer> mappings within a few :h autocommands.

In principle, there's a ton of Vim plugins showing one or another kind of such "specialized buffer", not just "file browsers" such as vim-dirvish, but, say, many plugin managers (e.g. minpac) do it too. Also some books may discuss writing of such plugins (e.g. "The VimL Primer"), and so on.

Matt
  • 13,674
  • 1
  • 18
  • 27
  • Thanks, Matt. I ordered the book, and will dig into the example above. I hadn't thought of this as its own buffer/context - was hoping to add to an existing plugin - but that would be a simple, self-contained solution. Thanks! – dhr Nov 02 '19 at 19:07