From 23baad4afa6b26b25dde520b8d777b0bee57f23b Mon Sep 17 00:00:00 2001 From: bekaboo <18127878294@qq.com> Date: Fri, 2 Jun 2023 19:59:15 -0500 Subject: [PATCH] docs: add more sections about making custom sources --- README.md | 156 +++++++++++++++++++++++++++++++++++++++++++++++ doc/dropbar.txt | 159 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 315 insertions(+) diff --git a/README.md b/README.md index db1de922..7d064ff8 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,9 @@ - [`dropbar_menu_hl_info_t`](#dropbar_menu_hl_info_t) - [`dropbar_source_t`](#dropbar_source_t) - [Making a New Source](#making-a-new-source) + - [Making a Source With Drop-Down Menus](#making-a-source-with-drop-down-menus) + - [Default `on_click()` Callback](#default-on_click()-callback) + - [Lazy-Loading Expensive Fields](#lazy-loading-expensive-fields) - [Similar Projects](#similar-projects) ## Features @@ -1261,6 +1264,159 @@ require('dropbar').setup({ }) ``` +#### Making a Source With Drop-Down Menus + +The following example shows how to make a source that returns two symbols with +the first symbol having a drop-down menu with a single entry saying 'World': + +```lua +local bar = require('dropbar.bar') +local menu = require('dropbar.menu') +local custom_source = { + get_symbols = function(_, _) + return { + bar.dropbar_symbol_t:new({ + icon = ' ', + icon_hl = 'WarningMsg', + name = 'Hello', + name_hl = 'Keyword', + on_click = function(self) + self.menu = menu.dropbar_menu_t:new({ + entries = { + menu.dropbar_menu_entry_t:new({ + components = { + bar.dropbar_symbol_t:new({ + icon = ' ', + icon_hl = 'WarningMsg', + name = 'World', + name_hl = 'Keyword', + on_click = function(sym) + vim.notify('Have you smiled today? ' .. sym.icon) + end, + }), + }, + }), + }, + }) + self.menu:toggle() + end, + }), + bar.dropbar_symbol_t:new({ + name = 'dropbar', + icon = ' ', + name_hl = 'Special', + icon_hl = 'Error', + }), + } + end, +} +``` + +#### Default `on_click()` Callback + +[`dropbar_symbol_t:new()`](#dropbar_symbol_t) defines a default `on_click()` +callback if non is provided. + +The default `on_click()` callback will look for these fields in the symbol +instance and create a drop-down menu accordingly on click, for more information +about these fields see [`dropbar_symbol_t`](#dropbar_symbol_t). + +| Field | Type | Description | +| ------ | ------ | ------ | +| `siblings` | `dropbar_symbol_t[]` | array of symbols to show in the first drop-down menu[`dropbar_menu_t`](#dropbar_menu_t) (the menu opened by clicking the symbol in the winbar) | +| `sibling_idx` | `integer?` | index of the symbol in `siblings` array, used to determine the initial position of the cursor in the first drop-down menu | +| `children` | `dropbar_symbol_t[]` | array of symbols to show in the sub-menus[`dropbar_menu_t`](#dropbar_menu_t) of the corresponding symbol (the menus opened by clicking a symbol inside another menu) | +| `actions.jump` | `fun(this: dropbar_symbol_t)` | jump to the start of the symbol, it will be called when clicking on the corresponding symbol[`dropbar_symbol_t`](#dropbar_symbol_t) (not the indicator) inside a menu | + +The following example shows a source that utilizes the default `on_click()` +callback: + +```lua +local bar = require('dropbar.bar') +local custom_source = { + get_symbols = function(_, _) + return { + bar.dropbar_symbol_t:new({ + name = 'Lev 1', + name_hl = 'Keyword', + siblings = { + bar.dropbar_symbol_t:new({ + name = 'Lev 1.1', + name_hl = 'WarningMsg', + }), + bar.dropbar_symbol_t:new({ + name = 'Lev 1.2', + name_hl = 'Error', + }), + bar.dropbar_symbol_t:new({ + name = 'Lev 1.3', + name_hl = 'String', + children = { + bar.dropbar_symbol_t:new({ + name = 'Lev 1.3.1', + name_hl = 'String', + actions = { + jump = function(_) + vim.notify('Jumping to Lev 1.3.1') + end + } + }), + }, + }), + }, + }), + } + end, +} +``` + +To see this source in action add it to [`opts.bar.sources`](#bar) table: + +```lua +require('dropbar').setup({ + bar = { + sources = { + custom_source, + }, + }, +}) +``` + +#### Lazy-Loading Expensive Fields + +If the symbol fields `siblings` or `children` are expensive to compute, you can +use meta-tables to lazy-load them, so that they are only computed when a menu +is opened: + +```lua +local bar = require('dropbar.bar') +local custom_source = { + get_symbols = function(_, _) + return { + bar.dropbar_symbol_t:new(setmetatable({ + name = 'Lev 1', + name_hl = 'Keyword', + }, { + __index = function(self, key) + if key == 'siblings' then + self[siblings] = -- [[ compute siblings ]] + return self[siblings] + end + if key == 'children' then + self[children] = -- [[ compute children ]] + return self[children] + end + -- ... + end, + })), + } + end, +} +``` + +To see concrete examples of lazy-loading see +[`lua/dropbar/sources`](https://github.com/Bekaboo/dropbar.nvim/tree/master/lua/dropbar/sources). + ## Similar Projects - [nvim-navic](https://github.com/SmiteshP/nvim-navic) diff --git a/doc/dropbar.txt b/doc/dropbar.txt index 2fa0d204..99c55a2d 100644 --- a/doc/dropbar.txt +++ b/doc/dropbar.txt @@ -36,6 +36,9 @@ CONTENTS *dropbar-table-of-contents* 6.2.6 `dropbar_menu_hl_info_t` |dropbar-developers-classes-dropbar_menu_hl_info_t| 6.2.7 `dropbar_source_t` |dropbar-developers-classes-dropbar_source_t| 6.3 Making a new source |dropbar-developers-making-a-new-source| + 6.3.1 Making a source with drop-down menus |dropbar-developers-making-a-source-with-drop-down-menus| + 6.3.2 Default `on_click()` callback |dropbar-developers-default-on_click-callback| + 6.3.3 Lazy-loading expensive fields |dropbar-developers-lazy-loading-expensive-fields| 7. Similar Projects |dropbar-similar-projects| @@ -1528,6 +1531,162 @@ action: >lua }) < +.............................................................................. +MAKING A SOURCE WITH DROP-DOWN MENUS +*dropbar-developers-making-a-source-with-drop-down-menus* + + +The following example shows how to make a source that returns two symbols with +the first symbol having a drop-down menu with a single entry saying 'World': +>lua + local bar = require('dropbar.bar') + local menu = require('dropbar.menu') + local custom_source = { + get_symbols = function(_, _) + return { + bar.dropbar_symbol_t:new({ + icon = ' ', + icon_hl = 'WarningMsg', + name = 'Hello', + name_hl = 'Keyword', + on_click = function(self) + self.menu = menu.dropbar_menu_t:new({ + entries = { + menu.dropbar_menu_entry_t:new({ + components = { + bar.dropbar_symbol_t:new({ + icon = ' ', + icon_hl = 'WarningMsg', + name = 'World', + name_hl = 'Keyword', + on_click = function(sym) + vim.notify('Have you smiled today? ' .. sym.icon) + end, + }), + }, + }), + }, + }) + self.menu:toggle() + end, + }), + bar.dropbar_symbol_t:new({ + name = 'dropbar', + icon = ' ', + name_hl = 'Special', + icon_hl = 'Error', + }), + } + end, + } +< + +.............................................................................. +DEFAULT ON_CLICK() CALLBACK *dropbar-developers-default-on_click-callback* + +`dropbar_symbol_t:new()` defines a default `on_click()` callback if non is +provided. + +The default `on_click()` callback will look for these fields in the symbol +instance and create a drop-down menu accordingly on click, for more +information about these fields, see +|dropbar-developers-classes-dropbar_symbol_t|: + + • `dropbar_symbol_t.siblings` + + Array of symbols to show in the first drop-down menu (the menu opened + by clicking the symbol in the winbar) + + • `dropbar_symbol_t.sibling_idx` + + Index of the symbol in `dropbar_symbol_t.siblings`, used to determine + the initial position of the cursor in the first drop-down menu + + • `dropbar_symbol_t.children` + + Array of symbols to show in the sub-menus of the corresponding symbol + (the menus opened by clicking a symbol inside another menu) + + • `dropbar_symbol_t.actions.jump` + + Jump to the start of the symbol, it will be called when clicking on + the corresponding symbol (not the indicator) inside a menu + +The following example shows a source that utilizes the default `on_click()` +callback: >lua + + local bar = require('dropbar.bar') + local custom_source = { + get_symbols = function(_, _) + return { + bar.dropbar_symbol_t:new({ + name = 'Lev 1', + name_hl = 'Keyword', + siblings = { + bar.dropbar_symbol_t:new({ + name = 'Lev 1.1', + name_hl = 'WarningMsg', + }), + bar.dropbar_symbol_t:new({ + name = 'Lev 1.2', + name_hl = 'Error', + }), + bar.dropbar_symbol_t:new({ + name = 'Lev 1.3', + name_hl = 'String', + children = { + bar.dropbar_symbol_t:new({ + name = 'Lev 1.3.1', + name_hl = 'String', + actions = { + jump = function(_) + vim.notify('Jumping to Lev 1.3.1') + end + } + }), + }, + }), + }, + }), + } + end, + } +< + +.............................................................................. +LAZY-LOADING EXPENSIVE FIELDS +*dropbar-developers-lazy-loading-expensive-fields* + +If the symbol fields `siblings` or `children` are expensive to compute, you +can use meta-tables to lazy-load them, so that they are only computed when a +menu is opened: >lua + + local bar = require('dropbar.bar') + local custom_source = { + get_symbols = function(_, _) + return { + bar.dropbar_symbol_t:new(setmetatable({ + name = 'Lev 1', + name_hl = 'Keyword', + }, { + __index = function(self, key) + if key == 'siblings' then + self[siblings] = -- [[ compute siblings ]] + return self[siblings] + end + if key == 'children' then + self[children] = -- [[ compute children ]] + return self[children] + end + -- ... + end, + })), + } + end, + } +< + +To see concrete examples of lazy-loading, see `lua/dropbar/sources`. ============================================================================== SIMILAR PROJECTS *dropbar-similar-projects*