Skip to content

feat: Indicate modified buffers #1835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 25 commits into from
Dec 31, 2022
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
b65ecd6
Outlined new options
chomosuke Dec 17, 2022
b14b135
Merge branch 'master' into feat-modified-buffers
chomosuke Dec 17, 2022
ece4c37
highlight_modified is highlight_opened_files
chomosuke Dec 18, 2022
a34c907
prototype with autocmd
chomosuke Dec 18, 2022
84e4ff5
Merge branch 'master' into feat-modified-buffers
chomosuke Dec 19, 2022
e501f16
moved modified into glyphs
chomosuke Dec 19, 2022
00d3739
show_on_dirs and show_on_open_dirs
chomosuke Dec 21, 2022
2ad6125
icon placement before & after
chomosuke Dec 21, 2022
b3ed7c9
_get_filename_offset
chomosuke Dec 21, 2022
b4ef5e0
fixed :wq doesn't update modified indicator
chomosuke Dec 22, 2022
e95d3a5
highlight_modified, signcolumn modified_placement
chomosuke Dec 23, 2022
9b04ff5
updated doc to match the reality of no multi char for glyphs.modified
chomosuke Dec 23, 2022
8bf609c
fixed git signcolumn doesn't show
chomosuke Dec 23, 2022
c7b20ca
fixed highlight_modified gets replaced by highlight_opened_files
chomosuke Dec 23, 2022
621d634
fixed renderer.icons.show.modified = false crash
chomosuke Dec 23, 2022
2bbccb1
updated doc to reflect empty icon not breaking rendering
chomosuke Dec 23, 2022
845069d
removed debounce_delay to implement in a later PR
chomosuke Dec 27, 2022
efb3805
doc nit: order placement
alex-courtis Dec 30, 2022
ad6cb10
change modified dirs default to be consistent with git
chomosuke Dec 31, 2022
061a154
illegal git & modified placement changed to default
chomosuke Dec 31, 2022
38846ab
don't assume icon exist
chomosuke Dec 31, 2022
9e15b32
nit remove comment
alex-courtis Dec 31, 2022
e5c104d
Merge branch 'master' into feat-modified-buffers
chomosuke Dec 31, 2022
4554681
Noted in doc that glyphs can't have more than 2 characters if in sign…
chomosuke Dec 31, 2022
413dc30
Don't sign_define if placement isn't signcolumn
chomosuke Dec 31, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 51 additions & 1 deletion doc/nvim-tree-lua.txt
Original file line number Diff line number Diff line change
Expand Up @@ -222,6 +222,7 @@ Subsequent calls to setup will replace the previous configuration.
highlight_git = false,
full_name = false,
highlight_opened_files = "none",
highlight_modified = "none",
root_folder_label = ":~:s?$?/..?",
indent_width = 2,
indent_markers = {
Expand All @@ -240,6 +241,8 @@ Subsequent calls to setup will replace the previous configuration.
git_placement = "before",
padding = " ",
symlink_arrow = " ➛ ",
modified = "[+]",
modified_placement = "after",
show = {
file = true,
folder = true,
Expand Down Expand Up @@ -324,6 +327,12 @@ Subsequent calls to setup will replace the previous configuration.
show_on_open_dirs = true,
timeout = 400,
},
modified = {
enable = false,
show_on_dirs = true,
show_on_open_dirs = false,
Copy link
Member

Choose a reason for hiding this comment

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

Could we perhaps change this to be consistent with git?

      show_on_dirs = true,
      show_on_open_dirs = true,

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I actually wanted to change git & diagnostics to the same as modified because I think that'd be the default that most people want, but didn't cause i thought that'd be breaking.

Idk what is this plugin's stance on changes in default though, if you think it's alright I can make that change in this PR.

In the mean time I'll change modified to be consistent with git for now :).

Copy link
Member

@alex-courtis alex-courtis Dec 31, 2022

Choose a reason for hiding this comment

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

Yeah, I'd like to change those defaults, they make more sense. That's what I use.

Users do get upset when we make changes like that so we have avoided doing so.

I am open to trying it again: how about we make a separate PR for those sensible defaults that we can revert if there is upset.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I have this idea in my head for a while now. Wanted to open an issue but didn't find time to do investigation deep enough to justify it.
I would like to discuss future of the project and breaking changes moving forward. I wanted to argue in favour of releasing pre-release version with multiple breaking changes: removed/unified functionality, reorganised configuration options, general clean up. I think project could greatly benefit from refactor without worrying about breaking changes. It would then be released as version 2 for example. Would there be any appetite for that at all?

Copy link
Member

Choose a reason for hiding this comment

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

reorganised configuration options, general clean up

Yes. git.ignore not being in filters. renderer too large. diagnostics.icons not in icons.glyphs. Some root options not in view or their own section.

I would like to discuss future of the project and breaking changes moving forward.

We can break things in a controlled manner that will result in a better experience. We are also good at refactoring options, although we don't use it much.

I wanted to argue in favour of releasing pre-release version with multiple breaking changes

It would then be released as version 2 for example.

Many lua plugins and packer are getting very good at handling versions. I think it is time.

master could remain as "version 1" to avoid interruptions to users, however we could add devel, weekly etc. along with stable, stable-2, stable-2.1, stable-2.1.3 etc. I like SEMVER.

Copy link
Member

Choose a reason for hiding this comment

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

I did discover an interesting pattern with lualine:

User is prompted to run :LualineNotices when there is a configuration problem.

theme(base16): nvim-base16 is not currently present in your runtimepath, make sure it is properly installed, fallback to default colors.

Copy link
Collaborator

Choose a reason for hiding this comment

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

That's great to hear. Let's open a dedicated issue to discuss it further.

Copy link
Member

Choose a reason for hiding this comment

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

debounce_delay = 50,
},
actions = {
use_system_clipboard = true,
change_dir = {
Expand Down Expand Up @@ -542,6 +551,7 @@ Configuration options for the system open command.

*nvim-tree.diagnostics*
Show LSP and COC diagnostics in the signcolumn
Note that the modified sign will take precedence over the diagnostics signs.

`NOTE`: it will use the default diagnostic color groups to highlight the signs.
If you wish to customize, you can override these groups:
Expand Down Expand Up @@ -617,6 +627,28 @@ Git integration with icons and colors.
milliseconds but a few seconds), it will not render anything until the git
process returned the data.

*nvim-tree.modified*
Indicate which file have unsaved modification.

*nvim-tree.modified.enable*
Enable / disable the feature.
Type: `boolean`, Default: `false`

*nvim-tree.modified.show_on_dirs*
Show modified indication on directory whose children are modified.
Type: `boolean`, Default: `true`

*nvim-tree.modified.show_on_open_dirs*
Show modified indication on open directories.
Only relevant when |modified.show_on_dirs| is `true`.
Type: `boolean`, Default: `false`

*nvim-tree.modified.debounce_delay*
Idle milliseconds between the file is modified and action.
This helps performance when large number of files are modified in quick
succession (e.g. lsp rename).
Type: `number`, Default: `50` (ms)

*nvim-tree.filesystem_watchers*
Will use file system watcher (libuv fs_event) to watch the filesystem for
changes.
Expand Down Expand Up @@ -773,6 +805,13 @@ UI rendering setup
Value can be `"none"`, `"icon"`, `"name"` or `"all"`.
Type: `string`, Default: `"none"`

*nvim-tree.renderer.highlight_modified*
Highlight icons and/or names for modified files using `NvimTreeModified`
highlight groups.
Value can be `"none"`, `"icon"`, `"name"` or `"all"`
This can be used with or without the icons.
Type: `string`, Default `"none"`

*nvim-tree.renderer.root_folder_label* (previously `renderer.root_folder_modifier`)
In what format to show root folder. See `:help filename-modifiers` for
available `string` options.
Expand Down Expand Up @@ -815,7 +854,7 @@ UI rendering setup
Place where the git icons will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Note that the diagnostic signs will take precedence over the git signs.
Note that the diagnostic signs and the modified sign will take precedence over the git signs.
Type: `string`, Default: `before`

*nvim-tree.renderer.icons.padding*
Expand All @@ -827,6 +866,17 @@ UI rendering setup
Used as a separator between symlinks' source and target.
Type: `string`, Default: `" ➛ "`

*nvim-tree.renderer.icons.modified*
Icon to display for modified files. Can be multiple characters if
|renderer.icons.modified_placement| isn't `"signcolumn"`.
Type: `string`, Default: `"[+]"`

*nvim-tree.renderer.icons.modified_placement*
Place where the modified icon will be rendered.
Can be `"after"` or `"before"` filename (after the file/folders icons)
or `"signcolumn"` (requires |nvim-tree.view.signcolumn| enabled).
Type: `string`, Default: `after`

*nvim-tree.renderer.icons.show*
Configuration options for showing icon types.

Expand Down
19 changes: 19 additions & 0 deletions lua/nvim-tree.lua
Original file line number Diff line number Diff line change
Expand Up @@ -468,6 +468,16 @@ local function setup_autocommands(opts)
end,
})
end

if opts.modified.enable then
create_nvim_tree_autocmd("BufModifiedSet", {
callback = function()
utils.debounce("BufModifiedSet:modified_files", opts.modified.debounce_delay, function()
reloaders.reload_explorer()
end)
end,
})
end
end

local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
Expand Down Expand Up @@ -523,6 +533,7 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
highlight_git = false,
full_name = false,
highlight_opened_files = "none",
highlight_modified = "none",
root_folder_label = ":~:s?$?/..?",
indent_width = 2,
indent_markers = {
Expand All @@ -541,6 +552,8 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
git_placement = "before",
padding = " ",
symlink_arrow = " ➛ ",
modified = "[+]",
modified_placement = "after",
show = {
file = true,
folder = true,
Expand Down Expand Up @@ -625,6 +638,12 @@ local DEFAULT_OPTS = { -- BEGIN_DEFAULT_OPTS
show_on_open_dirs = true,
timeout = 400,
},
modified = {
enable = false,
show_on_dirs = true,
show_on_open_dirs = false,
debounce_delay = 50,
},
actions = {
use_system_clipboard = true,
change_dir = {
Expand Down
19 changes: 16 additions & 3 deletions lua/nvim-tree/renderer/builder.lua
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@ function Builder:configure_git_icons_placement(where)
return self
end

function Builder:configure_modified(modified_icon, modified_placement, modified)
self.modified = modified
self.modified.icon = modified_icon
self.modified.placement = modified_placement
return self
end

function Builder:configure_symlink_destination(show)
self.symlink_destination = show
return self
Expand Down Expand Up @@ -206,15 +213,19 @@ function Builder:_highlight_opened_files(node, offset, icon_length, git_icons_le
self:_insert_highlight("NvimTreeOpenedFile", from, to)
end

function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr)
function Builder:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr, modified)
local offset = string.len(padding)

local icon = self:_build_file_icon(node, offset)

local git_icons_starts_at = offset + #icon + (self.is_git_after and #node.name + 1 or 0)
local git_icons = self:_unwrap_git_data(git_icons_tbl, git_icons_starts_at)

self:_insert_line(self:_format_line(padding .. icon, node.name, git_icons))
local name = node.name
if modified then
name = name .. self.modified.icon
end
self:_insert_line(self:_format_line(padding .. icon, name, git_icons))

local git_icons_length = self.is_git_after and 0 or #git_icons
local col_start = offset + #icon + git_icons_length
Expand Down Expand Up @@ -263,6 +274,8 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
end
end

local modified = vim.fn.bufloaded(node.absolute_path) > 0 and vim.fn.getbufinfo(node.absolute_path)[1].changed == 1

local is_folder = node.nodes ~= nil
local is_symlink = node.link_to ~= nil

Expand All @@ -271,7 +284,7 @@ function Builder:_build_line(node, idx, num_children, unloaded_bufnr)
elseif is_symlink then
self:_build_symlink(node, padding, git_highlight, git_icons_tbl)
else
self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr)
self:_build_file(node, padding, git_highlight, git_icons_tbl, unloaded_bufnr, modified)
end
self.index = self.index + 1

Expand Down
2 changes: 2 additions & 0 deletions lua/nvim-tree/renderer/init.lua
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,7 @@ function M.draw(unloaded_bufnr)
:configure_opened_file_highlighting(M.config.highlight_opened_files)
:configure_git_icons_padding(M.config.icons.padding)
:configure_git_icons_placement(M.config.icons.git_placement)
:configure_modified(M.config.icons.modified, M.config.icons.modified_placement, M.config.modified)
:configure_symlink_destination(M.config.symlink_destination)
:configure_filter(live_filter.filter, live_filter.prefix)
:build_header(view.is_root_folder_visible(core.get_cwd()))
Expand Down Expand Up @@ -100,6 +101,7 @@ end

function M.setup(opts)
M.config = opts.renderer
M.config.modified = opts.modified

_padding.setup(opts)
full_name.setup(opts)
Expand Down