Skip to content
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

feat: migrate v3 Nerd Font glyphs #3411

Merged
merged 1 commit into from
Jan 27, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
22 changes: 17 additions & 5 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"version": "0.2.0",
"configurations": [
{
"name": "Debug Prompt",
"name": "Primary",
"type": "go",
"request": "launch",
"mode": "debug",
Expand All @@ -16,7 +16,7 @@
]
},
{
"name": "Debug Tooltip",
"name": "Tooltip",
"type": "go",
"request": "launch",
"mode": "debug",
Expand All @@ -30,7 +30,7 @@
]
},
{
"name": "Debug Transient",
"name": "Transient",
"type": "go",
"request": "launch",
"mode": "debug",
Expand All @@ -54,7 +54,7 @@
]
},
{
"name": "Print debug",
"name": "Debug",
"type": "go",
"request": "launch",
"mode": "debug",
Expand All @@ -65,7 +65,7 @@
]
},
{
"name": "Print init",
"name": "Init",
"type": "go",
"request": "launch",
"mode": "debug",
Expand Down Expand Up @@ -100,6 +100,18 @@
"migrate"
]
},
{
"name": "Migrate glyphs",
"type": "go",
"request": "launch",
"mode": "debug",
"program": "${workspaceRoot}/src",
"args": [
"config",
"migrate",
"glyphs"
]
},
{
"name": "Get value",
"type": "go",
Expand Down
5 changes: 3 additions & 2 deletions src/cli/config_migrate.go
Original file line number Diff line number Diff line change
Expand Up @@ -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

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

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.`,
Args: cobra.NoArgs,
Run: func(cmd *cobra.Command, args []string) {
Expand Down
60 changes: 60 additions & 0 deletions src/cli/config_migrate_glyphs.go
Original file line number Diff line number Diff line change
@@ -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)
}
24 changes: 18 additions & 6 deletions src/engine/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ type Config struct {
// Deprecated
OSC99 bool `json:"osc99,omitempty"`

Output string `json:"-"`
Output string `json:"-"`
MigrateGlyphs bool `json:"-"`

format string
origin string
Expand Down Expand Up @@ -177,7 +178,7 @@ func (cfg *Config) Export(format string) string {
_ = jsonEncoder.Encode(cfg)
prefix := "{\n \"$schema\": \"https://raw.githubusercontent.com/JanDeDobbeleer/oh-my-posh/main/themes/schema.json\","
data := strings.Replace(result.String(), "{", prefix, 1)
return escapeGlyphs(data)
return escapeGlyphs(data, cfg.MigrateGlyphs)
}

_, _ = config.DumpTo(&result, cfg.format)
Expand All @@ -187,14 +188,14 @@ func (cfg *Config) Export(format string) string {
return prefix + result.String()
case TOML:
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:
return result.String()
}
}

func (cfg *Config) BackupAndMigrate(env platform.Environment) {
cfg.backup()
cfg.Backup()
cfg.Migrate(env)
cfg.Write(cfg.format)
}
Expand All @@ -216,7 +217,7 @@ func (cfg *Config) Write(format string) {
_ = f.Close()
}

func (cfg *Config) backup() {
func (cfg *Config) Backup() {
dst := cfg.origin + ".bak"
source, err := os.Open(cfg.origin)
if err != nil {
Expand All @@ -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 {
if r < 0x1000 { // Basic Multilingual Plane
return true
Expand Down Expand Up @@ -266,6 +267,11 @@ func escapeGlyphs(s string) string {
return false
}

var cp codePoints
if migrate {
cp = getGlyphCodePoints()
}

var builder strings.Builder
for _, r := range s {
// exclude regular characters and emojis
Expand All @@ -274,6 +280,12 @@ func escapeGlyphs(s string) string {
continue
}

if migrate {
if val, OK := cp[int(r)]; OK {
r = rune(val)
}
}

if r > 0x10000 {
// calculate surrogate pairs
one := 0xd800 + (((r - 0x10000) >> 10) & 0x3ff)
Expand Down
2 changes: 1 addition & 1 deletion src/engine/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ func TestEscapeGlyphs(t *testing.T) {
{Input: "🏚", Expected: "🏚"},
}
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)
}
}

Expand Down
52 changes: 52 additions & 0 deletions src/engine/migrate_glyphs.go
Original file line number Diff line number Diff line change
@@ -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
}
12 changes: 12 additions & 0 deletions src/engine/migrate_glyphs_test.go
Original file line number Diff line number Diff line change
@@ -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))
}
14 changes: 14 additions & 0 deletions website/docs/faq.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -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].

### 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
[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
Expand Down