diff --git a/src/engine/config.go b/src/engine/config.go index 46c96057..d53ea1f4 100644 --- a/src/engine/config.go +++ b/src/engine/config.go @@ -235,13 +235,54 @@ func (cfg *Config) backup() { } func escapeGlyphs(s string) string { + shouldExclude := func(r rune) bool { + if r < 0x1000 { // Basic Multilingual Plane + return true + } + if r > 0x1F600 && r < 0x1F64F { // Emoticons + return true + } + if r > 0x1F300 && r < 0x1F5FF { // Misc Symbols and Pictographs + return true + } + if r > 0x1F680 && r < 0x1F6FF { // Transport and Map + return true + } + if r > 0x2600 && r < 0x26FF { // Misc symbols + return true + } + if r > 0x2700 && r < 0x27BF { // Dingbats + return true + } + if r > 0xFE00 && r < 0xFE0F { // Variation Selectors + return true + } + if r > 0x1F900 && r < 0x1F9FF { // Supplemental Symbols and Pictographs + return true + } + if r > 0x1F1E6 && r < 0x1F1FF { // Flags + return true + } + return false + } + var builder strings.Builder for _, r := range s { - // exclude regular characters and emoji - if r < 0x1000 || r > 0x10000 { + // exclude regular characters and emojis + if shouldExclude(r) { builder.WriteRune(r) continue } + + if r > 0x10000 { + // calculate surrogate pairs + one := 0xd800 + (((r - 0x10000) >> 10) & 0x3ff) + two := 0xdc00 + ((r - 0x10000) & 0x3ff) + quoted := fmt.Sprintf("\\u%04x\\u%04x", one, two) + builder.WriteString(quoted) + continue + } + quoted := fmt.Sprintf("\\u%04x", r) builder.WriteString(quoted) } diff --git a/src/engine/config_test.go b/src/engine/config_test.go index 8a60c33a..fd69d02f 100644 --- a/src/engine/config_test.go +++ b/src/engine/config_test.go @@ -49,6 +49,7 @@ func TestEscapeGlyphs(t *testing.T) { Input string Expected string }{ + {Input: "󰉋", Expected: "\\udb80\\ude4b"}, {Input: "a", Expected: "a"}, {Input: "\ue0b4", Expected: "\\ue0b4"}, {Input: "\ufd03", Expected: "\\ufd03"},