mini.nvim icon indicating copy to clipboard operation
mini.nvim copied to clipboard

Beta-testing 'mini.icons'

Open echasnovski opened this issue 1 year ago • 118 comments

Please leave your feedback about new mini.icons module here. Feel free to either add new comment or positively upvote existing one.

Some things I am interested to find out (obviously, besides bugs):

  • Does it work well out of the box with your existing setup? Like:

    • Are icons rendered well? If not, there might be a terminal emulator and/or font issue, see Dependencies section.
    • Are colors for icons that are important for you chosen reasonably?
  • Do you have any suggestion about changing some icon's glyph and/or highlight group? I'd like to warn right away about what probably won't be done:

    • Adding narrowly scoped programming language-related icons. For example: special treatment of d.ts extension.
    • Changing glyph which is explicitly designed for where it is used. For example: almost whole "lsp" category.

    What I am open for and welcome:

    • Adjusting filetype glyph which was added from a set of "generic" nf-md-alpha-* icons. For example, like this. It needs a reasonable suggestion, though.
    • Adding new filetype icon data for plugins, if they have workflow which allows making buffer with that filetype current (like opening floating window or split with the buffer). Most of popular ones are already added, but I might have missed some.
  • Is configuration intuitive enough?

  • Are default values of settings convenient for you?

  • Is documentation and examples clear enough?

Thanks!

echasnovski avatar Jul 03 '24 13:07 echasnovski

Great new module! I've been playing with it and doing some comparations with devicons and I found out that icons are missing in files with "double" extensions. Specially in typescript files (javascript is working ok). I can't think of any other language I use that have those.

Here is a pic from telescope (that works great with the mocking).

wezterm-gui_1GrTuDXBP9

Still not sure about some colors, will have to think about it as I'm not sure if I think they are wrong or it's just that I have to get use to them. Will post later about it.

SebasF1349 avatar Jul 03 '24 15:07 SebasF1349

First of all, thank you for this great new module!

Just wanted to let you know it currently doesn't work with fzf-lua. It trips at the line https://github.com/ibhagwan/fzf-lua/blob/3b91c1a471160bd8620bdca8f18743d954994daa/lua/fzf-lua/devicons.lua#L81

folke avatar Jul 03 '24 15:07 folke

You should probably also change this line https://github.com/echasnovski/mini.icons/blob/b5e40acb2f0de7127bbcf026f3a0a55189a428a4/lua/mini/icons.lua#L427

When lua starts loading a module, it changes the value in package.loaded to true. So better to check for type == "table".

folke avatar Jul 03 '24 15:07 folke

Work-around to make it work on fzf-lua

  {
    "echasnovski/mini.icons",
    lazy = true,
    opts = {},
    init = function()
      package.preload["nvim-web-devicons"] = function()
        local Icons = require("mini.icons")
        local ret = {}
        package.loaded["nvim-web-devicons"] = ret
        Icons.mock_nvim_web_devicons()

        local function get(cat)
          local all = {}
          for _, name in ipairs(Icons.list(cat)) do
            local icon, color = ret.get_icon_color(cat == "file" and name, cat == "extension" and name)
            all[name] = { icon = icon, color = color }
          end
          return all
        end

        ret.get_icons_by_extension = function()
          return get("extension")
        end

        ret.get_icons_by_filename = function()
          return get("file")
        end

        ret.get_icons = function()
          return vim.tbl_extend("force", get("file"), get("extension"))
        end
        return ret
      end
    end,
  },

folke avatar Jul 03 '24 15:07 folke

I found out that icons are missing in files with "double" extensions. Specially in typescript files (javascript is working ok). I can't think of any other language I use that have those.

@SebasF1349, thanks for the info! I am mostly positive that it is a typescript issue and not a "double extension" one. The problem here is that built-in vim.filetype.match() doesn't currently recognize 'ts' extension at all when used outside of some buffer context.

This means that telescope uses 'nvim-web-devicons' as get_icon(nil, 'd.ts', {}) instead of get_icon('app.d.ts', nil, {}) (i.e. supplies extension directly instead of file name.

You can check that 'mini.icons' does work correctly via :=MiniIcons.get('file', 'app.d.ts') which should return icon for typescript and "MiniIconsAzure" highlight group.


That said, during writing this I've got an idea of quite an easy fix for this in 'mini.icons'. Needs a bit more profiling but I think it will be solved.


So better to check for type == "table".

Work-around to make it work on fzf-lua

@folke, thanks for early beta-testing! I thought that mocking all get_icons_*() is meaningless as did not see the use for it. Seems like it will have to be done (at least so that you don't have to have it in LazyVim :) ). As it needs testing, I hope to do this tomorrow.

echasnovski avatar Jul 03 '24 17:07 echasnovski

About that ts thing, I had to include work-arounds for that in a number of my plugins. The reason is that the ft detector tries to read the buffer (which is nil) and will error. That in turn will completely stop the ft check unfortunately.

The offending line in filetypes.lua is ts = detect_line1('<%?xml', 'xml', 'typescript').

Easiest way to fix is probably to always have a hidden scratch buffer ready that can be used as an argument.

And thanks for adding that extra stuff for nvim-web-devicons!

folke avatar Jul 03 '24 17:07 folke

About that ts thing, I had to include work-arounds for that in a number of my plugins. The reason is that the ft detector tries to read the buffer (which is nil) and will error. That in turn will completely stop the ft check unfortunately.

Yes, I figured this also some time ago. I planned to make fix this upstream by also recognizing contents properly instead of buf.

Easiest way to fix is probably to always have a hidden scratch buffer ready that can be used as an argument.

That was exactly what I thought about during writing that comment. Don't know why I didn't think about this sooner :facepalm:

echasnovski avatar Jul 03 '24 17:07 echasnovski

extension field doesn't seem to have any effect on dotfiles. E.g. :

require('mini.icons').setup({
  extension = {
    ['ghci'] = {
      glyph = '󰅩',
      hl = 'MiniIconsPurple'
    },
  }
})

Results in: Untitled

EDIT: Scratch that, there's a file field for this case. Should've read the docs more thoroughly instead of skimming through :confused:

0x0003 avatar Jul 03 '24 22:07 0x0003

Thank for this! Testing it right now.

Are icons rendered well? If not, there might be a terminal emulator and/or font issue, see Dependencies section.

Note for those using Kitty; make sure to update your symbol_map here: https://sw.kovidgoyal.net/kitty/faq/#kitty-is-not-able-to-use-my-favorite-font


Changing glyph which is explicitly designed for where it is used. For example: almost whole "lsp" category.

Adjusting filetype glyph which was added from a set of "generic" nf-md-alpha-* icons. For example, like this. It needs a reasonable suggestion, though.

After using it today, here are some personal observations that might offer a different perspective;

Directory icons:

Enforcing "folder" type icons for all results in a mixed set. Personally, I believe that allowing exceptions for directories such as .github and .git contributes to better overall visual consistency:

- ['.git']      = { glyph = '', hl = 'MiniIconsOrange' },
- ['.github']   = { glyph = '', hl = 'MiniIconsAzure'  },
+ ['.git']      = { glyph = '󰊢', hl = 'MiniIconsOrange' },
+ ['.github']   = { glyph = '󰊤', hl = 'MiniIconsAzure'  },
Software:

The "executable" icon really stands out from the other "outline" icons in the same category. I think nf-oct-gear would fit better overall here (nf-md-cog-outline is a little too thick to blend well with the rest):

-exe  = { glyph = '󰒔', hl = 'MiniIconsGrey'  },
+exe  = { glyph = '', hl = 'MiniIconsGrey'  },
File icons:

The README icon stands out too much. Something like nf-md-file_document or nf-md-file_document_alert would, I believe, be more fitting:

-README = { glyph = '', hl = 'MiniIconsYellow' },
+README = { glyph = '󰈙', hl = 'MiniIconsYellow' },
-['README.md'] = { glyph = '', hl = 'MiniIconsYellow' },
+['README.md'] = { glyph = '󰈙', hl = 'MiniIconsYellow' },
Everything else:

Skipped, as it seems too specific to warrant any significant changes, and it already looks quite good to me as it is :)


Will continue to use it for the time being :partying_face:

wroyca avatar Jul 04 '24 00:07 wroyca

Thanks for yet another amazing module! I'm loving the style out of the box enough that I haven't really messed with any settings just yet. I have it working in oil currently. That being said, for some odd reason I am slightly different icons in Telescope (but they also aren't the same as nvim-web-devicons), I have attached a screenshot: Screenshot from 2024-07-03 22-46-54

xarvex avatar Jul 04 '24 03:07 xarvex

Consider adding a Projects directory icon; the proposal is ongoing: https://gitlab.freedesktop.org/xdg/xdg-user-dirs/-/issues/3 but it'd be nice for those already using it :)

image

wroyca avatar Jul 04 '24 14:07 wroyca

I've pushed some changes after early beta-testing.


There is now better fallback to vim.filetype.match(). @SebasF1349, this should fix the "missing ts icons in Telescope" problem (I've checked).


There is now fuller and (hopefully) smarter mocking in mock_nvim_web_devicons(). @folke, I think the whole LazyVim/LazyVim#3899 workarounds are now not needed. At least, I've tested and 'ibhagwan/fzf-lua' works with mocks. Although first class 'mini.icons' support should come to it eventually.


@wroyca, thanks for detailed feedback. Highly appreciated! Here are some thoughts:

  • I have very strong opinion that directory icons should all resemble same "folder" icon. This is the main way to differentiate files and directories. Especially considering that '.git' can be both file and directory.
  • I understand the point of "README icon stands out too much", but standing out was the intention here. Especially as it is shown in demo, it will be hard to convince me to change it :)
  • Agree about "exe" icon. I replaced it with "windows" icon (as I saw LazyGit uses it) with red color (that draws attention and is not blue used in "os").
  • I'll gladly add "Projects" directory after it is made official. I don't think it is used universally enough to be included now.

@xarvex, the reason why you see this seems to be because in floating window require('nvim-web-devicons').get_icon() is used with extension and not as the file name. While 'oil.nvim' seems to use file name. Those are mocked with "extension" and "file" categories respectively which act slightly differently. The best suggestion here is to wait for the first class 'mini.icons' support.

echasnovski avatar Jul 04 '24 15:07 echasnovski

Sweet! Just merged my PR to use mini.icons in LazyVim :)

folke avatar Jul 04 '24 16:07 folke

Sweet! Just merged my PR to use mini.icons in LazyVim :)

Very noice! Expecting bazillion issues about it now :)


Is there a reason you still use package.preload["nvim-web-devicons"]? Because 'mini.icons' now sets it itself. I hoped this would result in you not needing it in LazyVim.

echasnovski avatar Jul 04 '24 16:07 echasnovski

That's just to lazyload mini.icons. mini.icons will only be loaded (and setup) when either mini.icons or nvim-web-devicons is required

folke avatar Jul 04 '24 16:07 folke

For your use-case you should probably not use preload, since you're executing the code anyway, so there's no benefit and you can just define the nvim-web-devicons module.

folke avatar Jul 04 '24 16:07 folke

Hm, OK. I would have assumed that this would conflict with how mocking is now done. But if it works, then fine.

I don't think there is more 'mini.icons' can do here to make it easier for this type of mocking on user side, right?

For your use-case you should probably not use preload, since you're executing the code anyway, so there's no benefit and you can just define the nvim-web-devicons module.

Oh, well. It's already there, so let it be until it causes some issue.

echasnovski avatar Jul 04 '24 16:07 echasnovski

preload is only useful when:

  • you want to define a module that is not a real module
  • and you want to defer the cost of creating the module to the point where the module is initially required

So for LazyVim it is useful, but not inside mini.icons, since the cost of defining the module in your case is currently return M. You could put that whole local M = {} .... inside the preload, but the benefit in terms of loading would be practically nothing either, so not worth it.

Either way, that if statement at the end, indeed makes sure this won't lead to issues, so all good :)

folke avatar Jul 04 '24 17:07 folke

Confirming the issue with TS is gone. Thanks!

But now I've found another icon missing, again with Telescope:

wezterm-gui_QxqJ5HEC21

The same happens with .npmignore and apparently all icons in H.file_icons. For example, README.md shows a md icon and init.lua shows a lua icon.

After looking at the code, I see you are prioritazing extension over file, so the result makes sense. Is this a design choice?

SebasF1349 avatar Jul 04 '24 17:07 SebasF1349

But now I've found another icon missing, again with Telescope:

This is because Telescope calls get_icon() with both filename and (manually computed based on some custom logic) extension. In this case the original get_icon() first checks exact filename match, then prefers extension until finally computing extension from file name. I might add the first part of preferring exact file match, but the second one I'd not add to mock. I think the most proper way to original get_icon() in this scenario is to supply only filename.

echasnovski avatar Jul 04 '24 18:07 echasnovski

Hello, is this normal ? mini.icons not working for me. I just added require("mini.icons").setup() like the other mini.plugins Output : 2024-07-04_20-43-45 Arch Linux 6.6.36-1-lts - NVIM v 0.10.0 - LuaJIT 2.1.1713484068

Thanks

Yushi5058 avatar Jul 04 '24 19:07 Yushi5058

Hello, is this normal ? mini.icons not working for me. I just added require("mini.icons").setup() like the other mini.plugins

Hi! No, this is not normal. It looks like you haven't updated 'mini.nvim' to latest main branch. Your dotfiles point at latest stable 0.13.0 release.

echasnovski avatar Jul 04 '24 20:07 echasnovski

It's awesome to see this plugin and the "mock" nvim-web-devicons. Another plugin that is quite popular in the community is lspkind-nvim which is used in many plugins as well. Would it be beneficial to have a mock setup for lspkind as well which would help users use mini.icons in more places such as LSP symbol browsers, their nvim-cmp formats, etc.

mehalter avatar Jul 04 '24 20:07 mehalter

Hello, is this normal ? mini.icons not working for me. I just added require("mini.icons").setup() like the other mini.plugins

Hi! No, this is not normal. It looks like you haven't updated 'mini.nvim' to latest main branch. Your dotfiles point at latest stable 0.13.0 release.

Thanks, it's working !

Yushi5058 avatar Jul 04 '24 20:07 Yushi5058

Hello, some recent changes broke lualine. When I pin mini.icons to b5e40acb2f0de7127bbcf026f3a0a55189a428a4 from yesterday, there is no such error.

For reference, here is my commit with the changes I made and the (working) pinned mini.icon

edit: This is the not working commit: 3c51394b8815e0cb9beb385909803cd4816951c4

version

   Error  22:51:21 msg_show.lua_error Error executing vim.schedule lua callback: ...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:429: Error executing lua: ...im/lazy/lualine.nvim/lua/lualine/components/filetype.lua:34: attempt to call field 'get_icon' (a nil value)
stack traceback:
	...im/lazy/lualine.nvim/lua/lualine/components/filetype.lua:34: in function 'apply_icon'
	...l/share/nvim/lazy/lualine.nvim/lua/lualine/component.lua:280: in function 'draw'
	...are/nvim/lazy/lualine.nvim/lua/lualine/utils/section.lua:26: in function 'draw_section'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:170: in function 'statusline'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:298: in function <...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:279>
	[C]: in function 'nvim_win_call'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:429: in function 'refresh'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:353: in function <...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:352>
stack traceback:
	[C]: in function 'nvim_win_call'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:429: in function 'refresh'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:353: in function <...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:352>
   Error  22:51:25 msg_show.lua_error Error executing vim.schedule lua callback: ...share/nvim/lazy/lualine.nvim/lua/lualine/utils/utils.lua:211: lualine: Failed to refresh statusline:
...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:429: Error executing lua: ...im/lazy/lualine.nvim/lua/lualine/components/filetype.lua:34: attempt to call field 'get_icon' (a nil value)
stack traceback:
	...im/lazy/lualine.nvim/lua/lualine/components/filetype.lua:34: in function 'apply_icon'
	...l/share/nvim/lazy/lualine.nvim/lua/lualine/component.lua:280: in function 'draw'
	...are/nvim/lazy/lualine.nvim/lua/lualine/utils/section.lua:26: in function 'draw_section'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:170: in function 'statusline'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:298: in function <...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:279>
	[C]: in function 'nvim_win_call'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:429: in function 'refresh'
	...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:524: in function <...hael/.local/share/nvim/lazy/lualine.nvim/lua/lualine.lua:523>
	[C]: in function 'pcall'
	...share/nvim/lazy/lualine.nvim/lua/lualine/utils/utils.lua:214: in function ''
	vim/_editor.lua: in function <vim/_editor.lua:0>
stack traceback:
	[C]: in function 'error'
	...share/nvim/lazy/lualine.nvim/lua/lualine/utils/utils.lua:211: in function ''
	vim/_editor.lua: in function <vim/_editor.lua:0>

Allaman avatar Jul 04 '24 20:07 Allaman

Is there a way to add an icon and a HEX code in the highlight?

Joao-Queiroga avatar Jul 04 '24 23:07 Joao-Queiroga

It's awesome to see this plugin and the "mock" nvim-web-devicons. Another plugin that is quite popular in the community is lspkind-nvim which is used in many plugins as well. Would it be beneficial to have a mock setup for lspkind as well which would help users use mini.icons in more places such as LSP symbol browsers, their nvim-cmp formats, etc.看到这个插件和“模拟”nvim-web-devicons 真是太棒了。另一个在社区中非常流行的插件是 lspkind-nvim ,它也被用于许多插件中。对 lspkind 进行模拟设置是否有益,这将有助于用户在更多地方使用 mini.icons ,例如 LSP 符号浏览器及其 nvim-cmp 格式, ETC。

About mocking lspkind-nvim in nvim-cmp, you can simply use the following code to achieve the same effect:


    cmp.setup({
      formatting = {
        format = function(entry, vim_item)
          -- replace kind with mini lsp icon
          local icon, _ = require("mini.icons").get("lsp", vim_item.kind)
          if icon ~= nil then
            vim_item.kind = icon
          end
          return vim_item
        end,
      },
    })

wenjinnn avatar Jul 05 '24 01:07 wenjinnn

@xarvex, the reason why you see this seems to be because in floating window require('nvim-web-devicons').get_icon() is used with extension and not as the file name. While 'oil.nvim' seems to use file name. Those are mocked with "extension" and "file" categories respectively which act slightly differently. The best suggestion here is to wait for the first class 'mini.icons' support.

Okay, so the issue here is on the Telescope side only passing the extension, got it. Appreciate the looking into it, fantastic module yet again!

xarvex avatar Jul 05 '24 03:07 xarvex

Hello, some recent changes broke lualine. When I pin mini.icons to b5e40acb2f0de7127bbcf026f3a0a55189a428a4 from yesterday, there is no such error.

For reference, here is my commit with the changes I made and the (working) pinned mini.icon

edit: This is the not working commit: 3c51394b8815e0cb9beb385909803cd4816951c4

@Allaman, it doesn't look like 'mini.icons' or 'nvim-lualine' issue. The "get_icon is nil value" error means that mocking was not actually done. There were changes in how 'nvim-web-devicons' mocking is done which breaks the code snippet you use in init filed of lazy specification. Take a look at how this now done in LazyVim, which should work.


Is there a way to add an icon and a HEX code in the highlight?

@Joao-Queiroga, yes but not very straightforward. You can create custom highlight group with desired foreground and then use it inside customization. Something like this:

vim.api.nvim_set_hl(0, 'MyGreen', { fg = '#00ff00' })
require('mini.icons').setup({
  default = { file = { hl = 'MyGreen' } },
})

Okay, so the issue here is on the Telescope side only passing the extension, got it.

Not exactly, as it turned out. It supplies both filename and extension, from which 'mini.icons' mock chooses the second one. After thinking about it, I think I might switch to prefer the first one.


@mehalter, I'll take a look if mocking 'lspkind.nvim' is feasible. If it has a lot of API surface area, then it probably won't happen.

echasnovski avatar Jul 05 '24 05:07 echasnovski

tried it instead of nvim-dev-webicons and all icons disappeared :( . even on mini.files. Not sure what is wrong with or without MiniIcons.mock_nvim_web_devicons() makes no difference - all icons are just Screenshot_20240705_135622

olekspickle avatar Jul 05 '24 07:07 olekspickle