Skip to content

Commit

Permalink
Improve support for nerd fonts icons.
Browse files Browse the repository at this point in the history
- Added submodule icon for `{git}` module when cwd is in a submodule.
- Added `{battery:levelicon}` arg that shows an icon with the level.
- Added `{battery:onlyicon}` arg that shows only an icon (no text).
- The wizard figures out if the font is from NerdFonts v2 or v3.
- The wizard figures out if the font uses mono- or double-width icons.
- Added `flexprompt.settings.use_color_emoji` setting variable to use
  color emoji for certain icons when running in Windows Terminal.
  Currently the only way to enable it is by manually adding a Lua line
  in a script: `flexprompt.settings.use_color_emoji = true`.
  • Loading branch information
chrisant996 committed Jun 18, 2023
1 parent 73b1e4f commit 6935548
Show file tree
Hide file tree
Showing 4 changed files with 290 additions and 47 deletions.
55 changes: 55 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ Here are some recommended fonts to consider:
- [RobotoMono Nerd Font](/~https://github.com/ryanoasis/nerd-fonts/releases/): this is a patched version of Roboto Mono that adds Powerline symbols and many icon characters.
- And there are many other fonts to have fun with -- enjoy!

> **NOTE:** Most Nerd Fonts have multiple variations of the font included. The `flexprompt configure` wizard asks questions to figure out which variation of Nerd Font you're using (if any).
> - Variations named "Nerd Font Mono" or "NF Mono" have small icons that take up only 1 cell (e.g. "RobotoMono **Nerd Font Mono** Medium").
> - Variations named just "Nerd Font" without "Mono" have larger double width icons that take up 2 cells (e.g. "RobotoMono **Nerd Font** Medium").
## I installed a font; why won't it show up in the list of available terminal fonts?

The default built-in terminal window in Windows only lists a small set of predefined fonts. Other terminal hosts such as Windows Terminal or ConEmu make it easy to choose other fonts, without any extra steps.
Expand Down Expand Up @@ -344,6 +348,14 @@ flexprompt.settings.take_optional_locks = true

-- Disable detection of unpublished branches:
flexprompt.settings.dont_check_unpublished = true

-- Nerd Fonts version: (e.g. NF version 3.0.0 and higher rearranged the icons)
flexprompt.settings.nerdfonts_version = 3
-- Nerd Fonts width: (set to 1 to indicate font has mono width icons, or 2 to indicate double-width icons)
flexprompt.settings.nerdfonts_width = 2

-- Override certain icons with color emoji in Windows Terminal:
flexprompt.settings.use_color_emoji = true
```

# Writing Custom Prompt Modules
Expand Down Expand Up @@ -656,6 +668,49 @@ end

- [ ] _TBD: there is a lot of styling available, but it's poorly documented, sorry. You can reverse engineer details from reading `flexprompt.lua` and the configuration option tables near the beginning of it._

### Customizing Icons

- [ ] _TBD: for now this section just has a quick example showing the structure for icon definitions in flexprompt._

```lua
flexprompt.settings.symbol["icon_name_here"] =
{
-- All fields here are optional; supply as many or as few as you want.

-- Symbol to use in Windows Terminal.
winterminal = "W",

-- Symbol to use in ConEmu.
conemu = "C",

-- Symbol to use with Nerd Fonts v3 fonts.
-- Can be a string or a table:
-- String: Use this symbol always.
nerdfonts3 = "3",
-- Table: Use second symbol "3 " with double-width icon fonts, otherwise use first symbol "3".
nerdfonts3 = { "3", "3 " },

-- Symbol to use with Nerd Fonts v2 fonts.
-- Can be a string or a table:
-- String: Use this symbol always.
nerdfonts2 = "2",
-- Table: Use second symbol "2 " with double-width icon fonts, otherwise use first symbol "2".
nerdfonts2 = { "2", "2 " },

-- Symbol to use with fonts that have Powerline characters but not Nerd Fonts icons.
powerline = "P",

-- Symbol to use with Unicode fonts that don't have Powerline characters.
unicode = "U",

-- Symbol to use in plain ASCII mode.
ascii = "A",

-- Fallback symbol to use if none of the other available specializations are applicable.
"F"
}
```

## Running Actions

- [ ] _TBD_
Expand Down
139 changes: 121 additions & 18 deletions flexprompt.lua
Original file line number Diff line number Diff line change
Expand Up @@ -273,7 +273,8 @@ flexprompt.choices.prompt_symbols =
local symbols =
{
branch = { powerline="" },
unpublished = { powerline="" },
unpublished = { nerdfonts2={"",""}, nerdfonts3={"",""} },
submodule = { nerdfonts2={"",""}, nerdfonts3={"",""} },

conflict = { "!" },
addcount = { "+" },
Expand All @@ -288,21 +289,34 @@ local symbols =
staged = { "#", unicode="" },

battery = { "%" },
charging = { "++", powerline="" },
charging = { "++", nerdfonts2={"",""}, nerdfonts3={"󱐋","󱐋 "} },

exit_zero = { powerline="\x1b[92m\002" },
exit_nonzero = { powerline="\x1b[91m\002" },
exit_zero = { nerdfonts2={"\x1b[92m\002","\x1b[92m \002"}, nerdfonts3={"\x1b[92m\002","\x1b[92m \002"} },
exit_nonzero = { nerdfonts2={"\x1b[91m\002","\x1b[91m \002"}, nerdfonts3={"\x1b[91m\002","\x1b[91m \002"} },

prompt = { ">" },
overtype_prompt = { "" },
overtype_prompt = { ">", unicode="" },

admin = { powerline="" },
no_admin = { powerline="" },
no_admin = { nerdfonts2={"",""} },

vpn = { powerline="" },
no_vpn = { powerline="" },
vpn = { nerdfonts2={"",""}, nerdfonts3="󰖂 " },
no_vpn = { nerdfonts2={"",""}, nerdfonts3={"",""} },

refresh = { unicode="" }, --   
refresh = { nerdfonts2="", nerdfonts3="" }, --   
}

local optional_color_emoji =
{
cwd_module = "📁",
duration_module = "",
time_module = "🕒",
user_module = "🙍‍♂️",
vpn_module = "☁️",
exit_zero = "✔️", -- Requires Clink v1.4.28 or higher.
exit_nonzero = "",
vpn = "☁️",
no_vpn = "🌎",
}

--------------------------------------------------------------------------------
Expand Down Expand Up @@ -379,6 +393,43 @@ local function get_charset()
return _charset
end

local _nerdfonts_version
local function get_nerdfonts_version()
if not _nerdfonts_version then
if flexprompt.settings.nerdfonts_version == 3 then
_nerdfonts_version = "nerdfonts3"
else
local env = os.getenv("FLEXPROMPT_NERDFONTS_VERSION")
local ver = 2
if env then
local num = tonumber(env)
if num and math.floor(num) == 3 then
ver = 3
end
end
_nerdfonts_version = "nerdfonts" .. ver
end
end
return _nerdfonts_version
end

local _nerdfonts_width
local function get_nerdfonts_width()
if not _nerdfonts_width then
if flexprompt.settings.nerdfonts_width == 2 then
_nerdfonts_width = 2
else
local env = os.getenv("FLEXPROMPT_NERDFONTS_WIDTH")
if env and tonumber(env) == 2 then
_nerdfonts_width = 2
else
_nerdfonts_width = 1
end
end
end
return _nerdfonts_width
end

local function get_lines()
return flexprompt.choices.lines[flexprompt.settings.lines or "one"] or 1
end
Expand Down Expand Up @@ -474,11 +525,26 @@ local function resolve_symbol_table(symbol)
local term = clink.getansihost and clink.getansihost() or nil
if term and symbol[term] then
symbol = symbol[term]
elseif flexprompt.settings.powerline_font and symbol["powerline"] then
symbol = symbol["powerline"]
else
local charset = get_charset()
symbol = symbol[charset] or symbol[1]
local nf = get_nerdfonts_version()
if not symbol[nf] then
nf = "nerdfonts2"
end
if symbol[nf] then
symbol = symbol[nf]
if type(symbol) == "table" then
if get_nerdfonts_width() == 2 then
symbol = symbol[2] or symbol[1]
else
symbol = symbol[1]
end
end
elseif flexprompt.settings.powerline_font and symbol["powerline"] then
symbol = symbol["powerline"]
else
local charset = get_charset()
symbol = symbol[charset] or symbol[1]
end
end
end
return symbol
Expand Down Expand Up @@ -591,13 +657,33 @@ end
local function reset_render_state(keep_results)
_can_use_extended_colors = nil
_charset = nil
_nerdfonts_version = nil
_nerdfonts_width = nil
_wizard = nil
_refilter_modules = nil
if not keep_results then
_module_results = {}
end
end

local function init_optional_color_emoji()
if flexprompt.settings.use_color_emoji then
local improved_emoji = ((clink.version_encoded) or 0) >= 10040028
for name, value in pairs(optional_color_emoji) do
if improved_emoji or name ~= "exit_zero" then
local t = flexprompt.settings.symbols[name]
if not t then
t = {}
flexprompt.settings.symbols[name] = t
end
if not t["winterminal"] then
t["winterminal"] = value
end
end
end
end
end

--------------------------------------------------------------------------------
-- Other helpers.

Expand Down Expand Up @@ -1781,6 +1867,12 @@ flexprompt.get_style = get_style
-- Function to get the prompt line count.
flexprompt.get_lines = get_lines

-- Function to get the nerdfonts version (based on what the user has told us).
flexprompt.get_nerdfonts_version = get_nerdfonts_version

-- Function to get the nerdfonts width (based on what the user has told us).
flexprompt.get_nerdfonts_width = get_nerdfonts_width

-- Function to get the prompt flow.
flexprompt.get_flow = get_flow

Expand Down Expand Up @@ -2014,22 +2106,27 @@ function flexprompt.scan_upwards(dir, scan_func)
end

-- Function to format a version control branch name:
-- "on module_symbol branch_symbol branch"
-- "on module_symbol submodule_symbol branch_symbol branch"
-- - The "on" is present when flow is fluent.
-- - The module_symbol is present when using icons and the module has a symbol.
-- - The submodule_symbol is present when using icons and in a submodule.
-- - The branch_symbol is present when not lean and not fluent, or when using
-- icons (the icon_name argument is optional, and defaults to "branch").
-- - The branch name is always present.
function flexprompt.format_branch_name(branch, icon_name, refreshing)
function flexprompt.format_branch_name(branch, icon_name, refreshing, submodule)
local style = get_style()
local flow = get_flow()

local text
local text = branch

if style == "lean" or flow == "fluent" then
text = append_text(flexprompt.get_icon(icon_name or "branch"), branch)
text = append_text(flexprompt.get_icon(icon_name or "branch"), text)
else
text = append_text(flexprompt.get_symbol(icon_name or "branch"), branch)
text = append_text(flexprompt.get_symbol(icon_name or "branch"), text)
end

if submodule then
text = append_text(flexprompt.get_symbol("submodule"), text)
end

text = append_text(flexprompt.get_module_symbol(refreshing), text)
Expand Down Expand Up @@ -2448,6 +2545,7 @@ end
-- Shared event handlers.

local offered_wizard
local is_initialized

local function onbeginedit()
-- Fix our tables if a script deleted them accidentally.
Expand Down Expand Up @@ -2483,6 +2581,11 @@ local function onbeginedit()
end
offered_wizard = true
end

if not is_initialized then
init_optional_color_emoji()
is_initialized = true
end
end

local function oncommand(line_state, info) -- luacheck: no unused
Expand Down
Loading

0 comments on commit 6935548

Please sign in to comment.