mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-17 14:04:52 +02:00
feat: add per-mapping --allow-fallback for layout-independent shortcuts
Add --allow-fallback option to the map command that controls shifted and ascii (alternate_key) fallback for individual key mappings. For non-Latin keyboard layouts, when the current layout key is non-ascii (codepoint > 127 and < 0xE000), the alternate_key from the base layout is used for matching if the mapping opts in via --allow-fallback=shifted,ascii. Default kitty bindings use --allow-fallback=shifted,ascii so they work out of the box with non-Latin layouts. User custom mappings default to --allow-fallback=shifted (preserving existing shifted_key behavior without ascii fallback). --allow-fallback=none disables all fallback for a mapping. Python side: parse_options_for_map() in options/utils.py handles flag parsing, ShortcutMapping uses it in __init__. get_shortcut() filters candidates by per-mapping allow_fallback. Go side: ParseMap() handles --allow-fallback, KeyAction stores AllowFallback, ShortcutTracker.Match passes it to matching. MatchesParsedShortcut defaults to shifted,ascii for hardcoded shortcuts. Migrated kittens (themes, command_palette, diff, choose_files) to use ShortcutTracker with configurable map entries. Tests added for Python (5 test methods) and Go (ParseMap + key matching).
This commit is contained in:
@@ -156,15 +156,15 @@ map('Change to root directory', 'cd_root ctrl+/ cd /')
|
||||
map('Change to home directory', 'cd_home ctrl+~ cd ~')
|
||||
map('Change to home directory', 'cd_home ctrl+` cd ~')
|
||||
map('Change to home directory', 'cd_home ctrl+shift+` cd ~')
|
||||
map('Change to temp directory', 'cd_tmp ctrl+t cd /tmp')
|
||||
map('Change to temp directory', 'cd_tmp --allow-fallback=shifted,ascii ctrl+t cd /tmp')
|
||||
|
||||
map('Next filter', 'next_filter ctrl+f 1')
|
||||
map('Previous filter', 'prev_filter alt+f -1')
|
||||
map('Next filter', 'next_filter --allow-fallback=shifted,ascii ctrl+f 1')
|
||||
map('Previous filter', 'prev_filter --allow-fallback=shifted,ascii alt+f -1')
|
||||
|
||||
map('Toggle showing dotfiles', 'toggle_dotfiles alt+h toggle dotfiles')
|
||||
map('Toggle showing ignored files', 'toggle_ignorefiles alt+i toggle ignorefiles')
|
||||
map('Toggle sorting by dates', 'toggle_sort_by_dates alt+d toggle sort_by_dates')
|
||||
map('Toggle showing preview', 'toggle_preview alt+p toggle preview')
|
||||
map('Toggle showing dotfiles', 'toggle_dotfiles --allow-fallback=shifted,ascii alt+h toggle dotfiles')
|
||||
map('Toggle showing ignored files', 'toggle_ignorefiles --allow-fallback=shifted,ascii alt+i toggle ignorefiles')
|
||||
map('Toggle sorting by dates', 'toggle_sort_by_dates --allow-fallback=shifted,ascii alt+d toggle sort_by_dates')
|
||||
map('Toggle showing preview', 'toggle_preview --allow-fallback=shifted,ascii alt+p toggle preview')
|
||||
|
||||
egr() # }}}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@ import (
|
||||
"strings"
|
||||
|
||||
"github.com/kovidgoyal/kitty/tools/cli"
|
||||
"github.com/kovidgoyal/kitty/tools/config"
|
||||
"github.com/kovidgoyal/kitty/tools/tty"
|
||||
"github.com/kovidgoyal/kitty/tools/tui"
|
||||
"github.com/kovidgoyal/kitty/tools/tui/loop"
|
||||
@@ -256,21 +257,23 @@ type CachedSettings struct {
|
||||
}
|
||||
|
||||
type Handler struct {
|
||||
lp *loop.Loop
|
||||
screen_size loop.ScreenSize
|
||||
all_items []DisplayItem
|
||||
filtered_idx []int // indices into all_items for current results
|
||||
match_infos []matchInfo // parallel to filtered_idx, valid when query != ""
|
||||
query string
|
||||
selected_idx int
|
||||
scroll_offset int
|
||||
input_data InputData
|
||||
result string // action definition to execute after exit
|
||||
display_lines []displayLine
|
||||
results_start_y int
|
||||
results_height int
|
||||
show_unmapped bool
|
||||
cv *utils.CachedValues[*CachedSettings]
|
||||
lp *loop.Loop
|
||||
screen_size loop.ScreenSize
|
||||
all_items []DisplayItem
|
||||
filtered_idx []int // indices into all_items for current results
|
||||
match_infos []matchInfo // parallel to filtered_idx, valid when query != ""
|
||||
query string
|
||||
selected_idx int
|
||||
scroll_offset int
|
||||
input_data InputData
|
||||
result string // action definition to execute after exit
|
||||
display_lines []displayLine
|
||||
results_start_y int
|
||||
results_height int
|
||||
show_unmapped bool
|
||||
cv *utils.CachedValues[*CachedSettings]
|
||||
shortcut_tracker config.ShortcutTracker
|
||||
keyboard_shortcuts []*config.KeyAction
|
||||
}
|
||||
|
||||
func (h *Handler) initialize() (string, error) {
|
||||
@@ -290,6 +293,8 @@ func (h *Handler) initialize() (string, error) {
|
||||
settings := h.cv.Load()
|
||||
h.show_unmapped = settings.ShowUnmapped
|
||||
|
||||
h.keyboard_shortcuts = config.ResolveShortcuts(NewConfig().KeyboardShortcuts)
|
||||
|
||||
if err := h.loadData(); err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -852,16 +857,27 @@ func (h *Handler) onKeyEvent(ev *loop.KeyEvent) error {
|
||||
h.triggerSelected()
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesPressOrRepeat("up") || ev.MatchesPressOrRepeat("ctrl+k") || ev.MatchesPressOrRepeat("ctrl+p") {
|
||||
if ev.MatchesPressOrRepeat("up") {
|
||||
ev.Handled = true
|
||||
h.moveSelection(-1)
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesPressOrRepeat("down") || ev.MatchesPressOrRepeat("ctrl+j") || ev.MatchesPressOrRepeat("ctrl+n") {
|
||||
if ev.MatchesPressOrRepeat("down") {
|
||||
ev.Handled = true
|
||||
h.moveSelection(1)
|
||||
return nil
|
||||
}
|
||||
if ac := h.shortcut_tracker.Match(ev, h.keyboard_shortcuts); ac != nil {
|
||||
ev.Handled = true
|
||||
switch ac.Name {
|
||||
case "selection_up":
|
||||
h.moveSelection(-1)
|
||||
case "selection_down":
|
||||
h.moveSelection(1)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
if ev.MatchesPressOrRepeat("page_up") {
|
||||
ev.Handled = true
|
||||
delta := max(1, int(h.screen_size.HeightCells)-4)
|
||||
|
||||
@@ -6,11 +6,38 @@ import sys
|
||||
from functools import partial
|
||||
from typing import Any
|
||||
|
||||
from kitty.conf.types import Definition
|
||||
from kitty.fast_data_types import add_timer, get_boss
|
||||
from kitty.typing_compat import BossType
|
||||
|
||||
from ..tui.handler import result_handler
|
||||
|
||||
definition = Definition(
|
||||
'!kittens.command_palette',
|
||||
)
|
||||
|
||||
agr = definition.add_group
|
||||
egr = definition.end_group
|
||||
map = definition.add_map
|
||||
|
||||
# shortcuts {{{
|
||||
agr('shortcuts', 'Keyboard shortcuts')
|
||||
|
||||
map('Move selection up',
|
||||
'selection_up --allow-fallback=shifted,ascii ctrl+k selection_up',
|
||||
)
|
||||
map('Move selection up',
|
||||
'selection_up --allow-fallback=shifted,ascii ctrl+p selection_up',
|
||||
)
|
||||
map('Move selection down',
|
||||
'selection_down --allow-fallback=shifted,ascii ctrl+j selection_down',
|
||||
)
|
||||
map('Move selection down',
|
||||
'selection_down --allow-fallback=shifted,ascii ctrl+n selection_down',
|
||||
)
|
||||
|
||||
egr() # }}}
|
||||
|
||||
|
||||
def collect_keys_data(opts: Any) -> dict[str, Any]:
|
||||
"""Collect all keybinding data from options into a JSON-serializable dict."""
|
||||
@@ -188,3 +215,5 @@ elif __name__ == '__doc__':
|
||||
cd['options'] = OPTIONS
|
||||
cd['help_text'] = help_text
|
||||
cd['short_desc'] = help_text
|
||||
elif __name__ == '__conf__':
|
||||
sys.options_definition = definition # type: ignore
|
||||
|
||||
@@ -192,21 +192,21 @@ egr() # }}}
|
||||
agr('shortcuts', 'Keyboard shortcuts')
|
||||
|
||||
map('Quit',
|
||||
'quit q quit',
|
||||
'quit --allow-fallback=shifted,ascii q quit',
|
||||
)
|
||||
map('Quit',
|
||||
'quit esc quit',
|
||||
)
|
||||
|
||||
map('Scroll down',
|
||||
'scroll_down j scroll_by 1',
|
||||
'scroll_down --allow-fallback=shifted,ascii j scroll_by 1',
|
||||
)
|
||||
map('Scroll down',
|
||||
'scroll_down down scroll_by 1',
|
||||
)
|
||||
|
||||
map('Scroll up',
|
||||
'scroll_up k scroll_by -1',
|
||||
'scroll_up --allow-fallback=shifted,ascii k scroll_by -1',
|
||||
)
|
||||
map('Scroll up',
|
||||
'scroll_up up scroll_by -1',
|
||||
@@ -227,41 +227,41 @@ map('Scroll to next page',
|
||||
'scroll_page_down space scroll_to next-page',
|
||||
)
|
||||
map('Scroll to next page',
|
||||
'scroll_page_down ctrl+f scroll_to next-page',
|
||||
'scroll_page_down --allow-fallback=shifted,ascii ctrl+f scroll_to next-page',
|
||||
)
|
||||
|
||||
map('Scroll to previous page',
|
||||
'scroll_page_up page_up scroll_to prev-page',
|
||||
)
|
||||
map('Scroll to previous page',
|
||||
'scroll_page_up ctrl+b scroll_to prev-page',
|
||||
'scroll_page_up --allow-fallback=shifted,ascii ctrl+b scroll_to prev-page',
|
||||
)
|
||||
|
||||
map('Scroll down half page',
|
||||
'scroll_half_page_down ctrl+d scroll_to next-half-page',
|
||||
'scroll_half_page_down --allow-fallback=shifted,ascii ctrl+d scroll_to next-half-page',
|
||||
)
|
||||
map('Scroll up half page',
|
||||
'scroll_half_page_up ctrl+u scroll_to prev-half-page',
|
||||
'scroll_half_page_up --allow-fallback=shifted,ascii ctrl+u scroll_to prev-half-page',
|
||||
)
|
||||
|
||||
map('Scroll to next change',
|
||||
'next_change n scroll_to next-change',
|
||||
'next_change --allow-fallback=shifted,ascii n scroll_to next-change',
|
||||
)
|
||||
|
||||
map('Scroll to previous change',
|
||||
'prev_change p scroll_to prev-change',
|
||||
'prev_change --allow-fallback=shifted,ascii p scroll_to prev-change',
|
||||
)
|
||||
|
||||
map('Scroll to next file',
|
||||
'next_file shift+j scroll_to next-file',
|
||||
'next_file --allow-fallback=shifted,ascii shift+j scroll_to next-file',
|
||||
)
|
||||
|
||||
map('Scroll to previous file',
|
||||
'prev_file shift+k scroll_to prev-file',
|
||||
'prev_file --allow-fallback=shifted,ascii shift+k scroll_to prev-file',
|
||||
)
|
||||
|
||||
map('Show all context',
|
||||
'all_context a change_context all',
|
||||
'all_context --allow-fallback=shifted,ascii a change_context all',
|
||||
)
|
||||
|
||||
map('Show default context',
|
||||
@@ -299,15 +299,17 @@ map('Scroll to previous search match',
|
||||
)
|
||||
|
||||
map('Search forward (no regex)',
|
||||
'search_forward_simple f start_search substring forward',
|
||||
'search_forward_simple --allow-fallback=shifted,ascii f start_search substring forward',
|
||||
)
|
||||
|
||||
map('Search backward (no regex)',
|
||||
'search_backward_simple b start_search substring backward',
|
||||
'search_backward_simple --allow-fallback=shifted,ascii b start_search substring backward',
|
||||
)
|
||||
|
||||
map('Copy selection to clipboard', 'copy_to_clipboard y copy_to_clipboard')
|
||||
map('Copy selection to clipboard or exit if no selection is present', 'copy_to_clipboard_or_exit ctrl+c copy_to_clipboard_or_exit')
|
||||
map('Copy selection to clipboard', 'copy_to_clipboard --allow-fallback=shifted,ascii y copy_to_clipboard')
|
||||
map('Copy selection to clipboard or exit if no selection is present',
|
||||
'copy_to_clipboard_or_exit --allow-fallback=shifted,ascii ctrl+c copy_to_clipboard_or_exit',
|
||||
)
|
||||
|
||||
egr() # }}}
|
||||
|
||||
|
||||
@@ -3,8 +3,59 @@
|
||||
|
||||
import sys
|
||||
|
||||
from kitty.conf.types import Definition
|
||||
from kitty.simple_cli_definitions import CompletionSpec
|
||||
|
||||
definition = Definition(
|
||||
'!kittens.themes',
|
||||
)
|
||||
|
||||
agr = definition.add_group
|
||||
egr = definition.end_group
|
||||
map = definition.add_map
|
||||
|
||||
# shortcuts {{{
|
||||
agr('shortcuts', 'Keyboard shortcuts')
|
||||
|
||||
# Browsing mode shortcuts
|
||||
map('Quit',
|
||||
'quit --allow-fallback=shifted,ascii q quit',
|
||||
)
|
||||
map('Scroll down',
|
||||
'scroll_down --allow-fallback=shifted,ascii j scroll_down',
|
||||
)
|
||||
map('Scroll up',
|
||||
'scroll_up --allow-fallback=shifted,ascii k scroll_up',
|
||||
)
|
||||
map('Start search',
|
||||
'search --allow-fallback=shifted,ascii s search',
|
||||
)
|
||||
map('Accept theme',
|
||||
'accept --allow-fallback=shifted,ascii c accept',
|
||||
)
|
||||
|
||||
# Accepting mode shortcuts
|
||||
map('Abort and return to browsing',
|
||||
'abort --allow-fallback=shifted,ascii a abort',
|
||||
)
|
||||
map('Place theme file',
|
||||
'place_theme --allow-fallback=shifted,ascii p place_theme',
|
||||
)
|
||||
map('Modify config file',
|
||||
'modify_conf --allow-fallback=shifted,ascii m modify_conf',
|
||||
)
|
||||
map('Save as dark scheme',
|
||||
'dark_scheme --allow-fallback=shifted,ascii d dark_scheme',
|
||||
)
|
||||
map('Save as light scheme',
|
||||
'light_scheme --allow-fallback=shifted,ascii l light_scheme',
|
||||
)
|
||||
map('Save as no preference scheme',
|
||||
'no_preference --allow-fallback=shifted,ascii n no_preference',
|
||||
)
|
||||
|
||||
egr() # }}}
|
||||
|
||||
help_text = (
|
||||
'Change the kitty theme. If no theme name is supplied, run interactively, otherwise'
|
||||
' change the current theme to the specified theme name.'
|
||||
@@ -57,3 +108,5 @@ elif __name__ == '__doc__':
|
||||
cd['help_text'] = help_text
|
||||
cd['short_desc'] = 'Manage kitty color schemes easily'
|
||||
cd['args_completion'] = CompletionSpec.from_string('type:special group:complete_themes')
|
||||
elif __name__ == '__conf__':
|
||||
sys.options_definition = definition # type: ignore
|
||||
|
||||
@@ -62,15 +62,17 @@ type handler struct {
|
||||
opts *Options
|
||||
cached_data *CachedData
|
||||
|
||||
state State
|
||||
fetch_result chan fetch_data
|
||||
all_themes *themes.Themes
|
||||
themes_closer io.Closer
|
||||
themes_list *ThemesList
|
||||
category_filters map[string]func(*themes.Theme) bool
|
||||
colors_set_once bool
|
||||
tabs []string
|
||||
rl *readline.Readline
|
||||
state State
|
||||
fetch_result chan fetch_data
|
||||
all_themes *themes.Themes
|
||||
themes_closer io.Closer
|
||||
themes_list *ThemesList
|
||||
category_filters map[string]func(*themes.Theme) bool
|
||||
colors_set_once bool
|
||||
tabs []string
|
||||
rl *readline.Readline
|
||||
shortcut_tracker config.ShortcutTracker
|
||||
keyboard_shortcuts []*config.KeyAction
|
||||
}
|
||||
|
||||
// fetching {{{
|
||||
@@ -123,6 +125,7 @@ func (self *handler) initialize() {
|
||||
self.category_filters = make(map[string]func(*themes.Theme) bool, len(category_filters)+1)
|
||||
maps.Copy(self.category_filters, category_filters)
|
||||
self.category_filters["recent"] = recent_filter(self.cached_data.Recent)
|
||||
self.keyboard_shortcuts = config.ResolveShortcuts(NewConfig().KeyboardShortcuts)
|
||||
go self.fetch_themes()
|
||||
self.draw_screen()
|
||||
}
|
||||
@@ -230,7 +233,7 @@ func (self *handler) next(delta int, allow_wrapping bool) {
|
||||
}
|
||||
|
||||
func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
||||
if ev.MatchesPressOrRepeat("esc") || ev.MatchesCaseInsensitiveTextOrKey("q") {
|
||||
if ev.MatchesPressOrRepeat("esc") {
|
||||
self.lp.Quit(0)
|
||||
ev.Handled = true
|
||||
return nil
|
||||
@@ -255,12 +258,12 @@ func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
||||
ev.Handled = true
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("j") || ev.MatchesPressOrRepeat("down") {
|
||||
if ev.MatchesPressOrRepeat("down") {
|
||||
self.next(1, true)
|
||||
ev.Handled = true
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("k") || ev.MatchesPressOrRepeat("up") {
|
||||
if ev.MatchesPressOrRepeat("up") {
|
||||
self.next(-1, true)
|
||||
ev.Handled = true
|
||||
return nil
|
||||
@@ -281,12 +284,12 @@ func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("s") || ev.MatchesCaseInsensitiveTextOrKey("/") {
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("/") {
|
||||
ev.Handled = true
|
||||
self.start_search()
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("c") || ev.MatchesPressOrRepeat("enter") {
|
||||
if ev.MatchesPressOrRepeat("enter") {
|
||||
ev.Handled = true
|
||||
if self.themes_list == nil || self.themes_list.Len() == 0 {
|
||||
self.lp.Beep()
|
||||
@@ -294,6 +297,27 @@ func (self *handler) on_browsing_key_event(ev *loop.KeyEvent) error {
|
||||
self.state = ACCEPTING
|
||||
self.draw_screen()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if ac := self.shortcut_tracker.Match(ev, self.keyboard_shortcuts); ac != nil {
|
||||
switch ac.Name {
|
||||
case "quit":
|
||||
self.lp.Quit(0)
|
||||
case "scroll_down":
|
||||
self.next(1, true)
|
||||
case "scroll_up":
|
||||
self.next(-1, true)
|
||||
case "search":
|
||||
self.start_search()
|
||||
case "accept":
|
||||
if self.themes_list == nil || self.themes_list.Len() == 0 {
|
||||
self.lp.Beep()
|
||||
} else {
|
||||
self.state = ACCEPTING
|
||||
self.draw_screen()
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
return nil
|
||||
}
|
||||
@@ -495,49 +519,41 @@ func (self *handler) draw_theme_demo() {
|
||||
// accepting {{{
|
||||
|
||||
func (self *handler) on_accepting_key_event(ev *loop.KeyEvent) error {
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("q") || ev.MatchesPressOrRepeat("esc") || ev.MatchesPressOrRepeat("shift+q") {
|
||||
if ev.MatchesPressOrRepeat("esc") {
|
||||
ev.Handled = true
|
||||
self.lp.Quit(0)
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("a") || ev.MatchesPressOrRepeat("shift+a") {
|
||||
ev.Handled = true
|
||||
self.state = BROWSING
|
||||
self.draw_screen()
|
||||
if ac := self.shortcut_tracker.Match(ev, self.keyboard_shortcuts); ac != nil {
|
||||
switch ac.Name {
|
||||
case "quit":
|
||||
self.lp.Quit(0)
|
||||
case "abort":
|
||||
self.state = BROWSING
|
||||
self.draw_screen()
|
||||
case "place_theme":
|
||||
self.themes_list.CurrentTheme().SaveInDir(utils.ConfigDir())
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
case "modify_conf":
|
||||
self.themes_list.CurrentTheme().SaveInConf(utils.ConfigDir(), self.opts.ReloadIn, self.opts.ConfigFileName)
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
case "dark_scheme":
|
||||
self.themes_list.CurrentTheme().SaveInFile(utils.ConfigDir(), kitty.DarkThemeFileName)
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
case "light_scheme":
|
||||
self.themes_list.CurrentTheme().SaveInFile(utils.ConfigDir(), kitty.LightThemeFileName)
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
case "no_preference":
|
||||
self.themes_list.CurrentTheme().SaveInFile(utils.ConfigDir(), kitty.NoPreferenceThemeFileName)
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("p") || ev.MatchesPressOrRepeat("shift+p") {
|
||||
ev.Handled = true
|
||||
self.themes_list.CurrentTheme().SaveInDir(utils.ConfigDir())
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
return nil
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("m") || ev.MatchesPressOrRepeat("shift+m") {
|
||||
ev.Handled = true
|
||||
self.themes_list.CurrentTheme().SaveInConf(utils.ConfigDir(), self.opts.ReloadIn, self.opts.ConfigFileName)
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
return nil
|
||||
}
|
||||
|
||||
scheme := func(name string) error {
|
||||
ev.Handled = true
|
||||
self.themes_list.CurrentTheme().SaveInFile(utils.ConfigDir(), name)
|
||||
self.update_recent()
|
||||
self.lp.Quit(0)
|
||||
return nil
|
||||
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("d") || ev.MatchesPressOrRepeat("shift+d") {
|
||||
return scheme(kitty.DarkThemeFileName)
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("l") || ev.MatchesPressOrRepeat("shift+l") {
|
||||
return scheme(kitty.LightThemeFileName)
|
||||
}
|
||||
if ev.MatchesCaseInsensitiveTextOrKey("n") || ev.MatchesPressOrRepeat("shift+n") {
|
||||
return scheme(kitty.NoPreferenceThemeFileName)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user