Skip to content

Commit 567176f

Browse files
feat: add indent guides as configurable component, closes #44 (#131)
Co-authored-by: Daniil Shvalov <[email protected]>
1 parent 113fb3b commit 567176f

File tree

8 files changed

+243
-131
lines changed

8 files changed

+243
-131
lines changed

doc/neo-tree.txt

Lines changed: 95 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ Mappings .................... |neo-tree-mappings|
1010
Filter .................... |neo-tree-filter|
1111
Configuration ............... |neo-tree-configuration|
1212
Setup ..................... |neo-tree-setup|
13+
Component Configs ......... |neo-tree-component-configs|
1314
Git Status ................ |neo-tree-git-status|
1415
Diagnostics ............... |neo-tree-diagnostics|
16+
Indent markers ............ |neo-tree-indent-markers|
1517
Highlights ................ |neo-tree-highlights|
1618
Events .................... |neo-tree-events|
1719
Components and Renderers .. |neo-tree-renderers|
@@ -323,7 +325,36 @@ you still may want to dump it to a blank .lua file just to read it as
323325
documentation.
324326

325327

326-
GIT STATUS *neo-tree-git-status*
328+
COMPONENT CONFIGS *neo-tree-component-configs*
329+
330+
The visual display of a node is made up of a series of components rendered in a
331+
certain order and with certain configuration options. See |neo-tree-components|
332+
for a deeper dive into customizing this aspect. If you wish to configure those
333+
components in a universal way, the best place to do that is in the
334+
`default_component_configs` section of the config.
335+
336+
For example, to add indent markers, you can apply your settings in each renderer
337+
for each source, or just do it once in the default_component_configs section:
338+
339+
>
340+
require("neo-tree").setup({
341+
default_component_configs = {
342+
indent = {
343+
with_markers = true,
344+
indent_marker = "│",
345+
last_indent_marker = "└",
346+
indent_size = 2,
347+
},
348+
},
349+
})
350+
<
351+
See |neo-tree-indent-markers| for more details.
352+
353+
The default config has more examples of component configuration, use
354+
|NeoTreePasteConfig| to view that default config.
355+
356+
357+
GIT STATUS *neo-tree-git-status*
327358

328359
By default, Neo-tree will attempt to get the git status for files in the
329360
current directory. It will use this information to add markers to the right of
@@ -337,7 +368,7 @@ component of your renderer(s).
337368
See also: |neo-tree-git-status-source|
338369

339370

340-
DIAGNOSTICS *neo-tree-diagnostics*
371+
DIAGNOSTICS *neo-tree-diagnostics*
341372

342373
By default, Neo-tree will display diagnostic symbols next to files. It will
343374
display the highest severity level for files, and errors only for directories.
@@ -359,6 +390,62 @@ To disable this feature entirely, set `enable_diagnostics = false` in your
359390
config when calling the setup function.
360391

361392

393+
INDENT MARKERS *neo-tree-indent-markers*
394+
395+
By default, indent markers (aka indent guides) are disabled. In Neo-tree
396+
indent is a component, so to enable indent markers, you need configure the
397+
`indent` component:
398+
399+
...at the global level:
400+
>
401+
require("neo-tree").setup({
402+
default_component_configs = {
403+
indent = {
404+
with_markers = true,
405+
indent_marker = "│",
406+
last_indent_marker = "└",
407+
indent_size = 2,
408+
},
409+
},
410+
})
411+
<
412+
413+
...or in each renderer:
414+
>
415+
require("neo-tree").setup({
416+
filesystem = {
417+
renderers = {
418+
directory = {
419+
{
420+
"indent",
421+
with_markers = true,
422+
indent_marker = "│",
423+
last_indent_marker = "└",
424+
indent_size = 2,
425+
},
426+
-- other components
427+
},
428+
file = {
429+
{
430+
"indent",
431+
with_markers = true,
432+
indent_marker = "│",
433+
last_indent_marker = "└",
434+
indent_size = 2,
435+
-- other components
436+
},
437+
}
438+
}
439+
})
440+
<
441+
442+
You also can change the marker characters. To do this, you need change
443+
`indent_marker` and `last_indent_marker` settings.
444+
445+
To change highlight of indent markers, you need configure `NeoTreeIndentMarker`
446+
highlight group. By default, it refers to `Normal` highlight.
447+
448+
362449
HIGHLIGHTS *neo-tree-highlights*
363450

364451
The following highlight groups are defined by this plugin. If you set any of
@@ -385,6 +472,8 @@ NeoTreeNormalNC |hi-NormalNC| override in Neo-tree window.
385472
NeoTreeRootName The name of the root node.
386473
NeoTreeTitleBar Used for the title bar of pop-ups, when the border-style
387474
is set to "NC". This is derived from NeoTreeFloatBorder.
475+
NeoTreeIndentMarker The style of indentation markers (guides). By default,
476+
the "Normal" highlight is used.
388477

389478

390479
EVENTS *neo-tree-events*
@@ -549,7 +638,10 @@ set of components.
549638
Each component function is called with the following args:
550639
`config` The config object defined in the renderer. This is how a component
551640
can be made to be configurable. This is useful if you want different behavior
552-
in a directory renderer vs a file renderer.
641+
in a directory renderer vs a file renderer. The config is a combination of any
642+
options specified in the default_component_configs
643+
(|neo-tree-default-component-configs|), which can be overriden by settings
644+
specified within each renderer config.
553645

554646
`node` The NuiNode object for this node. The properties can vary by source, but
555647
each one will generally have at least id and name properties.

lua/neo-tree.lua

Lines changed: 55 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -393,8 +393,47 @@ M.set_log_level = function(level)
393393
log.set_level(level)
394394
end
395395

396+
local function merge_global_components_config(components, config)
397+
local indent_exists = false
398+
local merged_components = {}
399+
for _, component in ipairs(components) do
400+
local name = component[1]
401+
if type(name) == "string" then
402+
if name == "indent" then
403+
indent_exists = true
404+
end
405+
local merged = { name }
406+
local global_config = config.default_component_configs[name]
407+
if global_config then
408+
for k, v in pairs(global_config) do
409+
merged[k] = v
410+
end
411+
end
412+
for k, v in pairs(component) do
413+
merged[k] = v
414+
end
415+
table.insert(merged_components, merged)
416+
else
417+
log.error("component name is the wrong type", component)
418+
end
419+
end
420+
421+
-- If the indent component is not specified, then add it.
422+
-- We do this because it used to be implicitly added, so we don't want to
423+
-- break any existing configs.
424+
if not indent_exists then
425+
local indent = { "indent" }
426+
for k, v in pairs(config.default_component_configs.indent or {}) do
427+
indent[k] = v
428+
end
429+
table.insert(merged_components, 1, indent)
430+
end
431+
return merged_components
432+
end
433+
396434
M.setup = function(config)
397-
config = config or {}
435+
local default_config = vim.deepcopy(defaults)
436+
config = vim.deepcopy(config or {})
398437
if config.log_level ~= nil then
399438
M.set_log_level(config.log_level)
400439
end
@@ -419,13 +458,13 @@ M.setup = function(config)
419458
highlights.setup()
420459

421460
-- setup the default values for all sources
422-
local source_defaults = {}
461+
local merged_source_config = {}
423462
for _, source_name in ipairs(sources) do
424-
local source = utils.table_copy(defaults[source_name] or {})
463+
local default_source_config = default_config[source_name]
425464
local mod_root = "neo-tree.sources." .. source_name
426-
source.components = require(mod_root .. ".components")
427-
source.commands = require(mod_root .. ".commands")
428-
source.name = source_name
465+
default_source_config.components = require(mod_root .. ".components")
466+
default_source_config.commands = require(mod_root .. ".commands")
467+
default_source_config.name = source_name
429468

430469
--validate the window.position
431470
local pos_key = source_name .. ".window.position"
@@ -444,26 +483,27 @@ M.setup = function(config)
444483
end
445484

446485
-- Make sure all the mappings are normalized so they will merge properly.
447-
normalize_mappings(source)
486+
normalize_mappings(default_source_config)
448487
normalize_mappings(config[source_name])
449488

450489
-- if user sets renderers, completely wipe the default ones
451-
if utils.get_value(config, source_name .. ".renderers.directory") then
452-
source.renderers.directory = {}
453-
end
454-
if utils.get_value(config, source_name .. ".renderers.file") then
455-
source.renderers.file = {}
490+
for name, _ in pairs(default_source_config.renderers) do
491+
local user = utils.get_value(config, source_name .. ".renderers." .. name)
492+
if user then
493+
default_source_config.renderers[name] = nil
494+
end
456495
end
457-
source_defaults[source_name] = source
458496
end
459-
local default_config = utils.table_merge(defaults, source_defaults)
460497

461498
-- apply the users config
462499
M.config = utils.table_merge(default_config, config)
463500

464-
-- setup the sources with the combined config
465501
for _, source_name in ipairs(sources) do
502+
for name, rndr in pairs(M.config[source_name].renderers) do
503+
M.config[source_name].renderers[name] = merge_global_components_config(rndr, M.config)
504+
end
466505
manager.setup(source_name, M.config[source_name], M.config)
506+
manager.redraw(source_name)
467507
end
468508

469509
local event_handler = {

0 commit comments

Comments
 (0)