{"id":13898314,"url":"https://github.com/m-pilia/vim-yggdrasil","last_synced_at":"2025-04-30T07:32:27.626Z","repository":{"id":44707659,"uuid":"189425814","full_name":"m-pilia/vim-yggdrasil","owner":"m-pilia","description":"Vim library to generate tree-like views","archived":false,"fork":false,"pushed_at":"2022-01-29T19:26:04.000Z","size":76,"stargazers_count":22,"open_issues_count":3,"forks_count":1,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-08-07T18:45:56.938Z","etag":null,"topics":["neovim","tree-view","vim"],"latest_commit_sha":null,"homepage":null,"language":"Vim script","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/m-pilia.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-05-30T14:12:52.000Z","updated_at":"2024-07-01T06:10:39.000Z","dependencies_parsed_at":"2022-09-16T01:02:32.134Z","dependency_job_id":null,"html_url":"https://github.com/m-pilia/vim-yggdrasil","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fvim-yggdrasil","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fvim-yggdrasil/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fvim-yggdrasil/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/m-pilia%2Fvim-yggdrasil/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/m-pilia","download_url":"https://codeload.github.com/m-pilia/vim-yggdrasil/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":224202403,"owners_count":17272765,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["neovim","tree-view","vim"],"created_at":"2024-08-06T18:04:13.648Z","updated_at":"2024-11-12T01:34:46.345Z","avatar_url":"https://github.com/m-pilia.png","language":"Vim script","funding_links":[],"categories":["Vim Script"],"sub_categories":[],"readme":"vim-yggdrasil: general purpose tree viewer for vim/neovim\n===============================================================\n[![Checks](https://github.com/m-pilia/vim-yggdrasil/workflows/Checks/badge.svg)](https://github.com/m-pilia/vim-yggdrasil/actions/workflows/checks.yml)\n[![codecov](https://codecov.io/gh/m-pilia/vim-yggdrasil/branch/master/graph/badge.svg)](https://codecov.io/gh/m-pilia/vim-yggdrasil/branch/master)\n[![License](https://img.shields.io/badge/License-MIT-blue.svg)](https://github.com/m-pilia/vim-yggdrasil/blob/master/LICENSE)\n\n\u003cp align=\"center\"\u003e\n\u003cimg src=\"https://upload.wikimedia.org/wikipedia/commons/4/44/Pasaules_koks_Igdrasils.jpg\" /\u003e\n\u003cbr /\u003e\n(Image: \u003ca href=\"https://commons.wikimedia.org/wiki/File:Pasaules_koks_Igdrasils.jpg\"\u003eWikiMedia Commons\u003c/a\u003e)\n\u003c/p\u003e\n\nThis plugin implements a general purpose tree viewer library for vim/neovim. It\nuses an interface similar to VSCode's\n[TreeDataProvider](https://code.visualstudio.com/api/references/vscode-api#TreeDataProvider)\nto retrieve the data to be displayed by the view.\n\nAmong the features:\n* Nodes are expanded lazily, allowing to efficiently explore deep trees with a\n  large number of nested nodes.\n* A callback mechanism allows asynchronous execution. The data provider can\n  generate data asynchronously, and send it to the view through a callback.\n* Pure VimScript implementation, self-contained library.\n* Easy to embed in other plugins without external dependencies.\n\nFor a concrete example of usage, you can check the source of\n[vim-ccls](https://github.com/m-pilia/vim-ccls), that makes use of\nYggdrasil to show symbol hierarchies.\n\n![Example](https://user-images.githubusercontent.com/8300317/68967865-d923d500-07e9-11ea-8312-5e4636c2b7b7.png)\n\nInstall\n=======\n\nYggdrasil can be either installed as an external dependency (as a regular vim\nplugin) or it can be embedded within another plugin's file structure. The\nlatter solution allows to have an own copy of Yggdrasil, avoiding to rely on an\nexternal dependency with its potential issues.\n\nTo embed Yggdrasil in your plugin, run the `YggdrasilPlant` command, specifying\nthe root directory of your vim plugin, and optionally a name to be used as a\nnamespace (by default, the name of the root directory). For instance, if your\nplugin's root folder (containing the `autoload`, `plugin`, `doc` folders etc.)\nis `/foo/myplugin`, by calling:\n```\n:YggdrasilPlant -plugin_dir=/foo/my/plugin\n```\na copy of Yggdrasil will be installed in\n`/foo/myplugin/autoload/my/plugin`, and it can be used as\n```viml\n\" Call an Yggdrasil function in your plugin code\ncall my#plugin#tree#new(provider)\n```\nPlease note that the path passed to the `YggdrasilPlant` command shall not be\nenclosed within quotes, and white-space characters within the path need to be\nescaped with backslash.\n\nIf for some reason you want to use a different namespace than the name of the\nroot folder of your plugin, pass an optional argument to specify it. For\ninstance, a call to\n```\n:YggdrasilPlant -plugin_dir=/foo/myplugin -namespace=my/namespace\n```\nwill install a copy of Yggdrasil in `/foo/myplugin/autoload/my/namespace`,\nand it can be used as\n```viml\n\" Call an Yggdrasil function in your plugin code\ncall my#namespace#tree#new(provider)\n```\n\nFor advanced installation options, please refer to [the\ndocumentation](https://github.com/m-pilia/vim-yggdrasil/blob/master/doc/yggdrasil.txt).\n\nExample\n=======\n\nThe following is a minimal working example of usage. This example uses\nsynchronous execution, but the methods of the data provider could be\nasynchronous (e.g. launching an external job), using the provided callback\nmechanism.\n\nAfter installing Yggdrasil, you can run this example by pasting the following\nscript in a new file, open it within vim and executing `:source %`.\n\n```viml\n\" Minimal example of tree data. The objects are integer numbers.\n\" Here the tree structure is implemented with a dictionary mapping parents to\n\" children.\nlet s:tree = {\n\\     0: [1, 2],\n\\     1: [3],\n\\     2: [4, 5],\n\\     3: [],\n\\     4: [6],\n\\     5: [],\n\\     6: [],\n\\ }\n\n\" Action to be performed when executing an object in the tree.\nfunction! s:command_callback(id) abort\n    echom 'Calling object ' . a:id . '!'\nendfunction\n\n\" Auxiliary function to map each object to its parent in the tree.\nfunction! s:number_to_parent(id) abort\n    for [l:parent, l:children] in items(s:tree)\n        if index(l:children, a:id) \u003e 0\n            return l:parent\n        endif\n    endfor\nendfunction\n\n\" Auxiliary function to produce a minimal tree item representation for a given\n\" object (i.e. a given integer number).\n\"\n\" The four mandatory fields for the tree item representation are:\n\"  * id: unique string identifier for the node in the tree\n\"  * collapsibleState: string value, equal to:\n\"     + 'collapsed' for an inner node initially collapsed\n\"     + 'expanded' for an inner node initially expanded\n\"     + 'none' for a leaf node that cannot be expanded nor collapsed\n\"  * command: function object that takes no arguments, it runs when a node is\n\"    executed by the user\n\"  * label: string representing the node in the view\nfunction! s:number_to_treeitem(id) abort\n    return {\n    \\   'id': string(a:id),\n    \\   'command': function('s:command_callback', [a:id]),\n    \\   'collapsibleState': len(s:tree[a:id]) \u003e 0 ? 'collapsed' : 'none',\n    \\   'label': 'Label of node ' . a:id,\n    \\ }\nendfunction\n\n\" The getChildren method can be called with no object argument, in that case it\n\" returns the root of the tree, or with one object as second argument, in that\n\" case it returns a list of objects that are children to the given object.\nfunction! s:GetChildren(Callback, ...) abort\n    let l:children = [0]\n    if a:0 \u003e 0\n        if has_key(s:tree, a:1)\n            let l:children = s:tree[a:1]\n        else\n            call a:Callback('failure')\n        endif\n    endif\n    call a:Callback('success', l:children)\nendfunction\n\n\" The getParent method returns the parent of a given object.\nfunction! s:GetParent(Callback, object) abort\n    call a:Callback('success', s:number_to_parent(a:object))\nendfunction\n\n\" The getTreeItem returns the tree item representation of a given object.\nfunction! s:GetTreeItem(Callback, object) abort\n    call a:Callback('success', s:number_to_treeitem(a:object))\nendfunction\n\n\" Define the tree data provider.\n\"\n\" The data provider exposes three methods that, given an object as input,\n\" produce the list of children, the parent object, and the tree item\n\" representation for the object respectively.\n\"\n\" Each method takes as first argument a callback, that is called by the provider\n\" to return the result asynchronously. The callback takes two arguments, the\n\" first is a status parameter, the second is the result of the call.\nlet s:provider = {\n\\ 'getChildren': function('s:GetChildren'),\n\\ 'getParent': function('s:GetParent'),\n\\ 'getTreeItem': function('s:GetTreeItem'),\n\\ }\n\n\" Create a new buffer and a new window for the tree view\nif exists('*nvim_open_win')\n    let s:buffer_options = {\n    \\ 'anchor': 'NW',\n    \\ 'style': 'minimal',\n    \\ 'relative': 'cursor',\n    \\ 'width': 50,\n    \\ 'height': 10,\n    \\ 'row': 1,\n    \\ 'col': 0,\n    \\ }\n    call win_gotoid(nvim_open_win(nvim_create_buf(v:false, v:true), 0, s:buffer_options))\nelse\n    topleft vnew\nendif\n\n\n\" Create a tree view with the given provider\n\"\n\" This function turns the current buffer into a tree view using data from the\n\" given provider. Any pre-existing content of the buffer will be deleted\n\" without warning. It is recommended to call this function within a newly\n\" created buffer (usually in a new split window, floating window, or tab).\ncall yggdrasil#tree#new(s:provider)\n```\n\nTo notify the view of a change in the structure or representation of the tree\nnodes, because of a change inside the provider, the `update()` method can be\nused:\n```viml\n\" Update the whole tree. Allows, for instance, to change the root.\n\" The whole tree is collapsed, and all nodes will be queried again from the\n\" provider when the user expands them again.\ncall b:yggdrasil_tree.update()\n\n\" Update only the node representing the integer number \"2\" in the above\n\" example, and its subtree. Preserve the collapsing structure of the view.\n\" Only the node representing \"2\" and its subtree will be queried again from\n\" the provider.\ncall b:yggdrasil_tree.update(2)\n```\n\nTo destroy the tree view, call the `wipe()` method. This will\n[`wipe out`](http://vimdoc.sourceforge.net/htmldoc/windows.html#:bwipeout) the\nbuffer containing the tree:\n```viml\ncall b:yggdrasil_tree.wipe()\n```\n\nFor a more extensive example of usage, you can check the implementation of\n[vim-ccls](https://github.com/m-pilia/vim-ccls), that makes use of\nYggdrasil to display symbol hierarchy trees.\n\nSettings\n========\n\nThe following `\u003cPlug\u003e` mappings are available to interact with a tree buffer:\n```\n\u003cPlug\u003e(yggdrasil-toggle-node)\n\u003cPlug\u003e(yggdrasil-open-node)\n\u003cPlug\u003e(yggdrasil-close-node)\n\u003cPlug\u003e(yggdrasil-execute-node)\n\u003cPlug\u003e(yggdrasil-wipe-tree)\n```\n\nThe default key bindings are:\n```vim\nnmap \u003csilent\u003e \u003cbuffer\u003e o    \u003cPlug\u003e(yggdrasil-toggle-node)\nnmap \u003csilent\u003e \u003cbuffer\u003e \u003ccr\u003e \u003cPlug\u003e(yggdrasil-execute-node)\nnmap \u003csilent\u003e \u003cbuffer\u003e q    \u003cPlug\u003e(yggdrasil-wipe-tree)\n```\n\nThey can be disabled and replaced with custom mappings:\n```vim\nlet g:yggdrasil_no_default_maps = 1\nau FileType yggdrasil nmap \u003csilent\u003e \u003cbuffer\u003e o \u003cPlug\u003e(yggdrasil-toggle-node)\n```\n\nLicense\n=======\n\nThis software is distributed under the MIT license. The full text of the license\nis available in the [LICENSE\nfile](https://github.com/m-pilia/vim-yggdrasil/blob/master/LICENSE) distributed\nalongside the source code.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-pilia%2Fvim-yggdrasil","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fm-pilia%2Fvim-yggdrasil","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fm-pilia%2Fvim-yggdrasil/lists"}