Nnn: Better coloring of icons / add support for nerdfont

Created on 30 Aug 2020  路  21Comments  路  Source: jarun/nnn

Any interest if I take a stab at coloring the various extension icons?

My method would be using the primary color associated with that lang. I personally find this helps me spot files a lot quicker and it's what I'm using to seeing in other vim explorers, so having some built in defaults would be nice.

Examples of things I know as a web dev

  • TSX, JSX React files being their teal
  • JS / Node files being green
  • Sass / Ruby files being pink / red

Don't know if I can do something similar to check for dot files? Usually I've seen them somewhat muted out.

I'm sure this can be fairly subjective, but doing a local compile I noticed how many icons were defined in icons-in-terminal.h and not in icons.h

Totally understand if this isn't wanted, and might be considered out of scope. I'm happy to just fill in the gaps of missing extensions and not apply color if that's the case (for example... scss is defined in icons-in-terminal.h but not icons.h).

Lemme know, happy to do the gruntwork over a day or two if folks would find it useful.

image

enhancement

Most helpful comment

Absolutely. Dunno if you saw, I made something like this last weekend, but it's easy to make something a little more formal that would work better on the readme. I'll also have a PR for this issue up by tomorrow.

https://www.youtube.com/watch?v=1QXU4XSqXNo

All 21 comments

Exploring this a bit more, I'm realizing I'd probably want to use my own patched Nerd font instead (which is more consistent in styling then the mixed-bag-on-purpose icons-in-terminal lib). Trying to think of a way to make this more friendly for customization without having to edit the source file directly.

I think to make this easier to theme, you might want to separate this into three files

  • icon-colors
  • icon-definitions
  • icon (which imports the two above)

That way a user can edit the colors and definitions separately without worrying about touching the main compile file. I might also suggest deduplicating the icons-in-terminal definitions file. It has so many variants (three for React), which would make it hard to touch it separately from the icons file which right now calls a mix of variants. Using a single batch of their sources and normalizing the names might be helpful (then you could use the single definition and apply one of the three -- or your own patch -- you prefer).

These are just suggestions from a habitual themer. The way it's set up currently I can certainly patch my own font in easily. I mostly worry about upgrades. Setting up the icon defs and colors separately would help there.

image

want to use my own patched Nerd font

So you'll have to set Nerd Font as your terminal/system Monospace font?

@KlzXS for his input.

IMHO, we are great with what icons-in-terminal support. If you still want to support Nerd Fonts as compile-in _and distinct from the current icons-in-terminal solution_, I am fine with that.

Also, some more details on guidelines we roughly follow:

  • Searching in nnn is filtering, also there's sort by extension among other sort options. I am pretty sure even if we use ruby red for .rb files, when there are 10 of them in the directory, you'll have to go though the file names by the sorted order. But nnn doesn't even care about mere 10 files! When there are 100s of those scattered around, I would personally prefer a filter rather than a visual binary search.
  • There are several reasons we have decided to use icons-in-terminal. So when users use descriptions like _mixed-bag-on-purpose icons-in-terminal lib_ we expect they understand it's his/her personal opinion and we will probably ignore that part. We know what we are doing.

I mostly worry about upgrades.

Didn't we say _compile-in_? It also means you'll have to backup your patch and may have to apply those back if you choose to upgrade to the source of the next release.

Yep. No worries, I get it. Like I said, ultimately it's fairly easy for me to make it how I want after I played with the source a bit. That's good enough for me! Put this up mostly because I know it's a fairly new feature so you might enjoy some feedback from someone going into it straight from the docs.

I'll keep fiddling over the next week. I think a separate nerdfont extension modeled in the same way (compile in) might be useful for others, but a separate patch is totally reasonable too. Nerdfonts are a little more common in the vim world (especially with the various powerlines), and might help with adoption. I can certainly make it very "pretty" by default if that's something that's interesting.

I appreciate the responses and detail. As you can tell, I'm trying out all the corner cases. At the end of the day, nnn is awesome because it's just so faaast. Fantastic piece of software, and I've seen immediate benefit in a couple days!

At the very least I can give you some good screenshots showing the feature off! I'll close out the issue, since it's certainly extendable enough as you can see.

image

I was not aiming at closing the discussion. Feedback in good taste is always welcome. I've already pulled in a few PRs from you and I wanted to make sure you feel at home with the general perspective of the team.

I would like to understand the gist of your proposal:

  1. are you suggesting Nerd can work along with icons-in-terminal or would it be independent?
  2. if independent, I would have a separate make option, say O_IFONT=1
  3. do I have to set the terminal font to Nerd to use Nerd-based icons?
  4. if they can work together would the code be common or separate?
  5. if they can work together would you see Unicode in square if one is not present?
  6. can Nerd make use of the current efficient algorithm without too many changes?
  7. would the code for Nerd be able to adapt any other patched font without too many changes?

Adding @KlzXS @leovilok @0xACE for their opinion based on your input to the above 7.

Preface, I know nothing about C! I'm a designer by profession and know some JavaScript, but am a Vim/Linux user familiar with hacking on configs.

If i were going for the dead simplest setup that didn't require a compile (which could very well be against your vision, which is why I'm not being pushy) I'd go for something like this.

  1. Have a setting for NNN_DISPLAY_ICONS that you have to export to get the icons to work. I'd set it to off by default, and leave it to the user to add in. This is similar to your 00 / 2D hex coloring philosophies. It would accept a string for the source system you want to use (which might grow over time).
  2. Have two icon source files to start. icons-in-terminal.h and nerd-font-icon.h that export strings with the same variable name (ex: ICON-JAVASCRIPT) that the single icons.h file reads. Let the icons.h file control the coloring to standardize.
  3. Use the NNN_DISPLAY_ICONS flag to decide which to load in.
  4. Let the use worry about the install of either icon system.
  5. Only make the user compile if they don't like the icon choices.

This would give users some choice and not require them to compile, which while fairly easy to do (it builds so fast!) was still a learning curve for someone like me who is used to installing software and editing a config file to customize.

To answer your questions:

are you suggesting Nerd can work along with icons-in-terminal or would it be independent?

I guess from the above a mix of both.

if independent, I would have a separate make option, say O_IFONT=1

This works too, but I'd rather not have to compile. Since the fonts are in my terminal already I'd rather just turn them on.

do I have to set the terminal font to Nerd to use Nerd-based icons?

Yes, but I have to imagine a good portion of the audience for this program have already done something like this already. Likely they are walking into NNN after they've used a bunch of other tooling.

As an example, when I went through the install for icons-in-terminal they make you edit ~/.config/fontconfig/conf.d/30-icons.conf which was filled already with patched nerd fonts. Nerd fonts already has 23k github starts, and icons-in-terminal has 500 or so. That's not saying one is better than the other, just that my hunch is that most people are already familiar with and using patched fonts.

if they can work together would the code be common or separate

My suggestions were above. I'm not a full time programmer though, so it's just a suggestion.

can Nerd make use of the current efficient algorithm without too many changes?

Yes! For me I was able to just paste in the icons and everything just worked. Which again is why I'm saying I'm already happy, this might just improve the default experience for others and make people not need to read the source.

would the code for Nerd be able to adapt any other patched font without too many changes?

I think you'd just keep the sources different?

Regarding point 7. I'm not familiar with the exact details of the code. But afaik the current method utilizes a lookup table to determine what to render. Applying it for nerdfont would essentially require a equivalent of the lookup table. I'm way behind master so I shouldn't be commenting.

@KlzXS and @leovilok can you please go through @snide's input? Can we have a simple design in place? I am OK with anything, including no plans to do it.

I like the idea of adding more extension rules, and setting a color for them, some already have their colors set. Though I think there should be an option somewhere to disable icon colors and display them in the same color as the filename.

Use the NNN_DISPLAY_ICONS flag to decide which to load in.

To decide which to load at runtime we would have to either:
compile in the icon strings of both options, doubling the space required to store them.
_or_
have a config file somewhere on the system that we read in.

Both of these are things we traditionally try and avoid. I think we stick to compiling for switching, that is the philosophy of minimalist software after all.

I think to make this easier to theme, you might want to separate this into three files

To make switching from one patched font to another we can remove icons-in-terminal.h taking the string we need from it and useng them in a new header (icon_defs.h?) where we would define symbols like NNN_FOLDER which are then to be used in icons.h.

icon_defs.h:
#define NNN_FOLDER "\ue155" // aka FA_FOLDER

icons.h:
static const struct icon_pair dir_icon = {"", NNN_FOLDER, 0};

A downside is when adding or removing fonts from icons-in-terminal codepoints of certain icons can move around.
You could end up needing to rewrite the whole file if you're not sure it won't do that. With these symbol names, it doesn't matter what the codepoint is, the header is autogenerated with the correct one for you. I'm not sure how many people use anything but the default though. Keeping both icons-in-terminal.h and icon_defs.h seems excessive.

In the end we have a icons-in-terminal icons_def file and a Nerdfonts one. User pick one an compiles it in.

Colors should stay in icons.h. They are extension/name specific as it is now, not icons specific and I think it should stay that way. The same icon in two different colors may have some special meaning to the user.

On my side I'd happy to trim down the icons-in-terminal.h file to just the used glyphs, normalize the naming in icons.h and add a nerd-font.h file if that's the way you want to go. I wouldn't be able to do any of the C code to do the loading, but I could at least contribute that side of the busywork.

Alternatively, if this sounds like too much trouble, I'm happy to host a gist and submit a PR against the docs to explain in better detail how to utilize nerd-font so others don't need to do the amount of source code reading to understand how things work.

I wouldn't be able to do any of the C code to do the loading

There is no further code that needs to be written. Just the headers with the icon symbols.

OK. So just to be clear where we've landed.

  1. I'll write up lookup table named nerd-font.h.
  2. I'll adjust the icons.h, icons-in-terminal and nerd-font.h file to use the same naming format? this would allow you in include whichever file you wanted at the top of icons.h and it should "just work" on compile?
  3. I'll go ahead and set a bunch of color vars in icons.h and clean up the mapping in that file for each icon?
  4. I'd write some docs that explains this stuff?

I'll try and jam on it this weekend. Thanks for walking me through everything. I'm happy to contribute and help out where I can.

You can update the docs here: https://github.com/jarun/nnn/wiki/Advanced-use-cases#file-icons

@snide would it be possible for you to make a video that demos some of the useful plugins of nnn? I would say something that explores max 10 of those (according to your choice) and shows how to use them.

Absolutely. Dunno if you saw, I made something like this last weekend, but it's easy to make something a little more formal that would work better on the readme. I'll also have a PR for this issue up by tomorrow.

https://www.youtube.com/watch?v=1QXU4XSqXNo

Wow! That's really neat and a very good introduction. :+1:

Yes, that would be very useful for new users to get accustomed to nnn. It's been a log time we were looking for some video tutorials for the plugins.

It would be great if you could add a small intro to the nnn plugins and how to use them at the start of the video.

haha, oh snap, recognized your voice immediately, brings back memories of back in the day when I frequented giant bomb :D, great to see you alive and all <3

Was this page helpful?
0 / 5 - 0 ratings

Related issues

billop picture billop  路  5Comments

kuntau picture kuntau  路  3Comments

deadpyxel picture deadpyxel  路  5Comments

leovilok picture leovilok  路  3Comments

harriott picture harriott  路  6Comments