feat: migrate v3 Nerd Font glyphs

This commit is contained in:
Jan De Dobbeleer 2023-01-27 14:29:22 +01:00 committed by Jan De Dobbeleer
parent c9c3e7fe15
commit a172c7a5ef
8 changed files with 177 additions and 14 deletions

22
.vscode/launch.json vendored
View file

@ -2,7 +2,7 @@
"version": "0.2.0", "version": "0.2.0",
"configurations": [ "configurations": [
{ {
"name": "Debug Prompt", "name": "Primary",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "debug", "mode": "debug",
@ -16,7 +16,7 @@
] ]
}, },
{ {
"name": "Debug Tooltip", "name": "Tooltip",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "debug", "mode": "debug",
@ -30,7 +30,7 @@
] ]
}, },
{ {
"name": "Debug Transient", "name": "Transient",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "debug", "mode": "debug",
@ -54,7 +54,7 @@
] ]
}, },
{ {
"name": "Print debug", "name": "Debug",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "debug", "mode": "debug",
@ -65,7 +65,7 @@
] ]
}, },
{ {
"name": "Print init", "name": "Init",
"type": "go", "type": "go",
"request": "launch", "request": "launch",
"mode": "debug", "mode": "debug",
@ -100,6 +100,18 @@
"migrate" "migrate"
] ]
}, },
{
"name": "Migrate glyphs",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceRoot}/src",
"args": [
"config",
"migrate",
"glyphs"
]
},
{ {
"name": "Get value", "name": "Get value",
"type": "go", "type": "go",

View file

@ -30,11 +30,12 @@ Migrates the ~/myconfig.omp.json config file and prints the result to stdout.
> oh-my-posh config migrate --config ~/myconfig.omp.json --format toml > oh-my-posh config migrate --config ~/myconfig.omp.json --format toml
Migrates the ~/myconfig.omp.json config file to toml and prints the result to stdout. Migrates the ~/myconfig.omp.json config file to TOML and prints the result to stdout.
> oh-my-posh config migrate --config ~/myconfig.omp.json --format toml --write > oh-my-posh config migrate --config ~/myconfig.omp.json --format toml --write
Migrates the ~/myconfig.omp.json config file to toml and writes the result to your config file. Migrates the ~/myconfig.omp.json config file to TOML and writes the result to your config file.
A backup of the current config can be found at ~/myconfig.omp.json.bak.`, A backup of the current config can be found at ~/myconfig.omp.json.bak.`,
Args: cobra.NoArgs, Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) { Run: func(cmd *cobra.Command, args []string) {

View file

@ -0,0 +1,60 @@
package cli
import (
"fmt"
"github.com/jandedobbeleer/oh-my-posh/src/engine"
"github.com/jandedobbeleer/oh-my-posh/src/platform"
"github.com/spf13/cobra"
)
// migrateCmd represents the migrate command
var migrateGlyphsCmd = &cobra.Command{
Use: "glyphs",
Short: "Migrate the nerd font glyphs in your config",
Long: `Migrate the nerd font glyphs in your config.
You can choose to print the output to stdout, or migrate your config in the format of your choice.
Example usage
> oh-my-posh config migrate glyphs --config ~/myconfig.omp.json
Migrates the ~/myconfig.omp.json config file's glyphs and prints the result to stdout.
> oh-my-posh config migrate glyphs --config ~/myconfig.omp.json --format toml
Migrates the ~/myconfig.omp.json config file's glyphs and prints the result to stdout in a TOML format.
> oh-my-posh config migrate glyphs --config ~/myconfig.omp.json --format toml --write
Migrates the ~/myconfig.omp.json config file's glyphs and writes the result to your config file in a TOML format.
A backup of the current config can be found at ~/myconfig.omp.json.bak.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
env := &platform.Shell{
Version: cliVersion,
CmdFlags: &platform.Flags{
Config: config,
},
}
env.Init()
defer env.Close()
cfg := engine.LoadConfig(env)
cfg.MigrateGlyphs = true
if write {
cfg.Backup()
cfg.Write(format)
return
}
fmt.Print(cfg.Export(format))
},
}
func init() { //nolint:gochecknoinits
migrateGlyphsCmd.Flags().BoolVarP(&write, "write", "w", false, "write the migrated config back to the config file")
migrateGlyphsCmd.Flags().StringVarP(&format, "format", "f", "json", "the config format to migrate to")
migrateCmd.AddCommand(migrateGlyphsCmd)
}

View file

@ -53,7 +53,8 @@ type Config struct {
// Deprecated // Deprecated
OSC99 bool `json:"osc99,omitempty"` OSC99 bool `json:"osc99,omitempty"`
Output string `json:"-"` Output string `json:"-"`
MigrateGlyphs bool `json:"-"`
format string format string
origin string origin string
@ -177,7 +178,7 @@ func (cfg *Config) Export(format string) string {
_ = jsonEncoder.Encode(cfg) _ = jsonEncoder.Encode(cfg)
prefix := "{\n \"$schema\": \"https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json\"," prefix := "{\n \"$schema\": \"https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json\","
data := strings.Replace(result.String(), "{", prefix, 1) data := strings.Replace(result.String(), "{", prefix, 1)
return escapeGlyphs(data) return escapeGlyphs(data, cfg.MigrateGlyphs)
} }
_, _ = config.DumpTo(&result, cfg.format) _, _ = config.DumpTo(&result, cfg.format)
@ -187,14 +188,14 @@ func (cfg *Config) Export(format string) string {
return prefix + result.String() return prefix + result.String()
case TOML: case TOML:
prefix := "#:schema https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json\n\n" prefix := "#:schema https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json\n\n"
return prefix + escapeGlyphs(result.String()) return prefix + escapeGlyphs(result.String(), cfg.MigrateGlyphs)
default: default:
return result.String() return result.String()
} }
} }
func (cfg *Config) BackupAndMigrate(env platform.Environment) { func (cfg *Config) BackupAndMigrate(env platform.Environment) {
cfg.backup() cfg.Backup()
cfg.Migrate(env) cfg.Migrate(env)
cfg.Write(cfg.format) cfg.Write(cfg.format)
} }
@ -216,7 +217,7 @@ func (cfg *Config) Write(format string) {
_ = f.Close() _ = f.Close()
} }
func (cfg *Config) backup() { func (cfg *Config) Backup() {
dst := cfg.origin + ".bak" dst := cfg.origin + ".bak"
source, err := os.Open(cfg.origin) source, err := os.Open(cfg.origin)
if err != nil { if err != nil {
@ -234,7 +235,7 @@ func (cfg *Config) backup() {
} }
} }
func escapeGlyphs(s string) string { func escapeGlyphs(s string, migrate bool) string {
shouldExclude := func(r rune) bool { shouldExclude := func(r rune) bool {
if r < 0x1000 { // Basic Multilingual Plane if r < 0x1000 { // Basic Multilingual Plane
return true return true
@ -266,6 +267,11 @@ func escapeGlyphs(s string) string {
return false return false
} }
var cp codePoints
if migrate {
cp = getGlyphCodePoints()
}
var builder strings.Builder var builder strings.Builder
for _, r := range s { for _, r := range s {
// exclude regular characters and emojis // exclude regular characters and emojis
@ -274,6 +280,12 @@ func escapeGlyphs(s string) string {
continue continue
} }
if migrate {
if val, OK := cp[int(r)]; OK {
r = rune(val)
}
}
if r > 0x10000 { if r > 0x10000 {
// calculate surrogate pairs // calculate surrogate pairs
one := 0xd800 + (((r - 0x10000) >> 10) & 0x3ff) one := 0xd800 + (((r - 0x10000) >> 10) & 0x3ff)

View file

@ -57,7 +57,7 @@ func TestEscapeGlyphs(t *testing.T) {
{Input: "🏚", Expected: "🏚"}, {Input: "🏚", Expected: "🏚"},
} }
for _, tc := range cases { for _, tc := range cases {
assert.Equal(t, tc.Expected, escapeGlyphs(tc.Input), tc.Input) assert.Equal(t, tc.Expected, escapeGlyphs(tc.Input, false), tc.Input)
} }
} }

View file

@ -0,0 +1,52 @@
package engine
import (
"context"
"encoding/csv"
"net/http"
"strconv"
"time"
)
type codePoints map[int]int
func getGlyphCodePoints() codePoints {
var codePoints = make(codePoints)
client := &http.Client{}
ctx, cncl := context.WithTimeout(context.Background(), time.Millisecond*time.Duration(5000))
defer cncl()
request, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://ohmyposh.dev/codepoints.csv", nil)
if err != nil {
return codePoints
}
response, err := client.Do(request)
if err != nil {
return codePoints
}
defer response.Body.Close()
lines, err := csv.NewReader(response.Body).ReadAll()
if err != nil {
return codePoints
}
for _, line := range lines {
if len(line) < 2 {
continue
}
oldGlyph, err := strconv.ParseUint(line[0], 16, 32)
if err != nil {
continue
}
newGlyph, err := strconv.ParseUint(line[1], 16, 32)
if err != nil {
continue
}
codePoints[int(oldGlyph)] = int(newGlyph)
}
return codePoints
}

View file

@ -0,0 +1,12 @@
package engine
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestGetCodePoints(t *testing.T) {
codepoints := getGlyphCodePoints()
assert.Equal(t, 1939, len(codepoints))
}

View file

@ -223,6 +223,20 @@ setopt appendhistory
You should update fish to v3.4.0 or higher. Fish supports `$(...)` and `"$(...)"` since v3.4.0, as described in its [changelog][fish-changelog]. You should update fish to v3.4.0 or higher. Fish supports `$(...)` and `"$(...)"` since v3.4.0, as described in its [changelog][fish-changelog].
### After updating my Nerd Font to a newer version, the prompt displays unknown characters
Nerd Fonts moved the icons to a different location in the font for v3.
This can cause the prompt to display unknown characters. There's a built-in migration in Oh My Posh to fix this.
To migrate, run the following command:
```bash
oh-my-posh config migrate glyphs --write
```
This will update your configuration file to use the new glyph locations. Do know they might look different, as they also
updated the icons themselves. A backup of the current config can be found in the same location with a `.bak` extension.
[exclusion]: https://support.microsoft.com/en-us/windows/add-an-exclusion-to-windows-security-811816c0-4dfd-af4a-47e4-c301afe13b26 [exclusion]: https://support.microsoft.com/en-us/windows/add-an-exclusion-to-windows-security-811816c0-4dfd-af4a-47e4-c301afe13b26
[arch-terminfo]: https://wiki.archlinux.org/title/Bash/Prompt_customization#Terminfo_escape_sequences [arch-terminfo]: https://wiki.archlinux.org/title/Bash/Prompt_customization#Terminfo_escape_sequences
[ps-ansi-docs]: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_ansi_terminals?view=powershell-7.2 [ps-ansi-docs]: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_ansi_terminals?view=powershell-7.2