Skip to content

feat(explorer): add configurable line formatters - #472

Merged
esmuellert merged 4 commits into
esmuellert:mainfrom
richardgill:explorer-line-formatters
Jul 29, 2026
Merged

feat(explorer): add configurable line formatters#472
esmuellert merged 4 commits into
esmuellert:mainfrom
richardgill:explorer-line-formatters

Conversation

@richardgill

@richardgill richardgill commented Jul 26, 2026

Copy link
Copy Markdown
Collaborator
  • Add explorer.formatters.{file,folder,group}callbacks.
  • Support styled left/right regions with display-width-aware truncation.
  • Add explorer.ellipsis to customize truncated-region markers, defaulting to .
  • Provide row metadata for files, folders, and groups while preserving selected-row backgrounds.
  • Passing nil to the formatters uses the default formatters from formatters.lua
    • New default formatter includes ... truncation (this is a change).

This extracts only the Explorer line formatter functionality from #448. Git line statistics and custom Explorer keymaps are intentionally excluded.

Demo

All three recordings use the same repository fixture, window dimensions, cursor position, and inputs. The Explorer is resized to demonstrate display-width-aware truncation and right-aligned regions.

Before - upstream main

Default Explorer rendering:

1-before.mp4

After - default formatters

  • No formatter configuration is provided.
  • Normal-width rendering remains unchanged;
  • narrowing demonstrates the new built-in formatter truncation:
2-after-default.mp4

After - custom formatters with mini.icons

Configuration: custom Explorer formatters using mini.icons

  • This example replaces file, folder, and group rows with custom function.
  • Uses metadata such as file counts and Git groups
  • Demonstrates using mini.icons for file and directory icons.
3-after-custom.mp4

@NeOzay

NeOzay commented Jul 27, 2026

Copy link
Copy Markdown
Contributor

Hello, I see that your PR is a much more elaborate version of mine.

For truncation, the character "…" should be more appropriate as it uses one space instead of three.

I'm also going to close my PR since it duplicates yours.

@richardgill

Copy link
Copy Markdown
Collaborator Author

@NeOzay nice suggestion! I've made the ellipsis configurable in config and defaulted it to the one you suggested 👍

cc: @esmuellert

@esmuellert

esmuellert commented Jul 29, 2026

Copy link
Copy Markdown
Owner

@richardgill I will merge this PR, then can you write a doc that might include your gist to show how to customize the formatter to get the look in the third video? That would be very helpful. You can put it in https://github.com/esmuellert/codediff.nvim/tree/main/docs and point us to there from README.md briefly. Thank you!

@esmuellert

Copy link
Copy Markdown
Owner

Oh, I see a short section in README.md, but feel like a longer page with some screenshots or videos and your gist snippet will be more helpful. Then we can trim README.md into just a link, which is already pretty long (I might split the whole README.md eventually later)

… raw layout tables

The region() local helper wrapped every layout region in vim.tbl_extend, hiding the { segments = ..., truncate_priority = ... } schema behind a positional two-argument call. Since formatters.lua is the reference example users read when writing their own formatters, showing the raw table shape is more valuable than the tiny brevity win.

prefix() is kept — it factors out the icon-conditional prefix logic actually shared between the file and folder formatters, so it's real DRY rather than schema decoration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b8fc9c4e-ddd0-4b67-b38b-70ba06220865
…at the call site

Previously config.lua imported codediff.ui.explorer.formatters at the top and set every explorer.formatters.{file,folder,group} to the built-in function. That made config a non-leaf module: loading config forced loading UI/formatters/line_layout/highlights transitively, and introduced a latent cycle risk if formatters ever needs to read config.

Now config's defaults use nil as the 'use the built-in' sentinel. The explorer's rendering call site (nodes.lua) resolves nil against the default_formatters module imported at nodes.lua's top-level (so the require works reliably under the plenary test harness, whose package.path lacks the plugin's /lua/ path — the module can still be found via the runtimepath-based require done at initial load, but a lazy require inside prepare_node was unreliable in that environment).

User setup behavior is unchanged: overriding any subset of { file, folder, group } works as before via vim.tbl_deep_extend; unspecified fields fall back to the built-ins.

Test update: the assertion that config.options.explorer.formatters.{file,folder,group} were functions now checks that they are nil and that the built-ins are exposed on the codediff.ui.explorer.formatters module.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot-Session: b8fc9c4e-ddd0-4b67-b38b-70ba06220865
@esmuellert
esmuellert requested a review from yanuoma as a code owner July 29, 2026 02:49

@esmuellert esmuellert left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved, with some changes to make formatter schema more explicit in formatter.lua. Also, I try to avoid importing modules in config.lua, so I set the default formatter to be nil there and let downstream fallback to default.

Then it is the suggestion above to add docs

@esmuellert
esmuellert enabled auto-merge July 29, 2026 02:52
@esmuellert
esmuellert merged commit 6ff6dd2 into esmuellert:main Jul 29, 2026
13 checks passed
esmuellert added a commit that referenced this pull request Jul 29, 2026
- Add `explorer.formatters.{file,folder,group}`callbacks.
- Support styled left/right regions with display-width-aware truncation.
- Add `explorer.ellipsis` to customize truncated-region markers,
defaulting to `…`.
- Provide row metadata for files, folders, and groups while preserving
selected-row backgrounds.
- Passing `nil` to the formatters uses the default formatters from
`formatters.lua`
  - New default formatter includes `...` truncation (this is a change).

This extracts only the Explorer line formatter functionality from #448.
Git line statistics and custom Explorer keymaps are intentionally
excluded.

## Demo

All three recordings use the same repository fixture, window dimensions,
cursor position, and inputs. The Explorer is resized to demonstrate
display-width-aware truncation and right-aligned regions.

### Before - upstream `main`

Default Explorer rendering:



https://github.com/user-attachments/assets/c106ba3e-e130-4265-8d32-95e8aa613b7e



### After - default formatters

- No formatter configuration is provided.
- Normal-width rendering remains unchanged;
- narrowing demonstrates the new built-in formatter truncation:


https://github.com/user-attachments/assets/7a1c8908-c2b2-4cae-be3c-98391dc88dbc




### After - custom formatters with `mini.icons`

Configuration: [custom Explorer formatters using
`mini.icons`](https://gist.github.com/richardgill/050a30e1c253dd8a20413f614b563ed0)

- This example replaces file, folder, and group rows with custom
function.
- Uses metadata such as file counts and Git groups
- Demonstrates using `mini.icons` for file and directory icons.



https://github.com/user-attachments/assets/d3766882-7233-43e2-a66c-f040285228b8
@richardgill

Copy link
Copy Markdown
Collaborator Author

Thanks @esmuellert. I'll follow up with the docs example 👍.

Planning to do it after #491 so we can include customizing git stats too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants