Get rid of --debug-config
Instead have a keybind that shows the configuration used by the currently running kitty instance
This commit is contained in:
parent
a1b87f445b
commit
4a71afaf96
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
7
.github/ISSUE_TEMPLATE/bug_report.md
vendored
@ -21,10 +21,11 @@ Steps to reproduce the behavior:
|
|||||||
If applicable, add screenshots to help explain your problem.
|
If applicable, add screenshots to help explain your problem.
|
||||||
|
|
||||||
**Environment details**
|
**Environment details**
|
||||||
OS: Name and version of operating system(s)
|
|
||||||
|
|
||||||
```
|
```
|
||||||
Output of kitty --debug-config
|
Press Ctrl+Shift+F6 in kitty, to copy debug output about kitty and its
|
||||||
|
configuration to the clipboard and paste it here.
|
||||||
|
|
||||||
|
On older versions of kitty, run kitty --debug-config instead
|
||||||
```
|
```
|
||||||
|
|
||||||
**Additional context**
|
**Additional context**
|
||||||
|
|||||||
@ -116,6 +116,7 @@ Toggle maximized :sc:`toggle_maximized`
|
|||||||
Input unicode character :sc:`input_unicode_character` (also :kbd:`^+⌘+space` on macOS)
|
Input unicode character :sc:`input_unicode_character` (also :kbd:`^+⌘+space` on macOS)
|
||||||
Click URL using the keyboard :sc:`open_url`
|
Click URL using the keyboard :sc:`open_url`
|
||||||
Reset the terminal :sc:`reset_terminal`
|
Reset the terminal :sc:`reset_terminal`
|
||||||
|
Debug :file:`kitty.conf` :sc:`debug_config`
|
||||||
Pass current selection to program :sc:`pass_selection_to_program`
|
Pass current selection to program :sc:`pass_selection_to_program`
|
||||||
Edit |kitty| config file :sc:`edit_config_file`
|
Edit |kitty| config file :sc:`edit_config_file`
|
||||||
Open a |kitty| shell :sc:`kitty_shell`
|
Open a |kitty| shell :sc:`kitty_shell`
|
||||||
|
|||||||
@ -50,8 +50,8 @@ from .typing import PopenType, TypedDict
|
|||||||
from .utils import (
|
from .utils import (
|
||||||
func_name, get_editor, get_primary_selection, is_path_in_temp_dir,
|
func_name, get_editor, get_primary_selection, is_path_in_temp_dir,
|
||||||
log_error, open_url, parse_address_spec, parse_uri_list,
|
log_error, open_url, parse_address_spec, parse_uri_list,
|
||||||
platform_window_id, remove_socket_file, safe_print, set_primary_selection,
|
platform_window_id, read_shell_environment, remove_socket_file, safe_print,
|
||||||
single_instance, startup_notification_handler
|
set_primary_selection, single_instance, startup_notification_handler
|
||||||
)
|
)
|
||||||
from .window import MatchPatternType, Window
|
from .window import MatchPatternType, Window
|
||||||
|
|
||||||
@ -874,11 +874,29 @@ class Boss:
|
|||||||
s.shutdown(socket.SHUT_RDWR)
|
s.shutdown(socket.SHUT_RDWR)
|
||||||
s.close()
|
s.close()
|
||||||
|
|
||||||
def display_scrollback(self, window: Window, data: Optional[bytes], cmd: List[str]) -> None:
|
def display_scrollback(self, window: Window, data: Union[bytes, str], input_line_number: int = 0, title: str = '') -> None:
|
||||||
|
def prepare_arg(x: str) -> str:
|
||||||
|
x = x.replace('INPUT_LINE_NUMBER', str(input_line_number))
|
||||||
|
x = x.replace('CURSOR_LINE', str(window.screen.cursor.y + 1))
|
||||||
|
x = x.replace('CURSOR_COLUMN', str(window.screen.cursor.x + 1))
|
||||||
|
return x
|
||||||
|
|
||||||
|
cmd = list(map(prepare_arg, get_options().scrollback_pager))
|
||||||
|
if not os.path.isabs(cmd[0]):
|
||||||
|
import shutil
|
||||||
|
exe = shutil.which(cmd[0])
|
||||||
|
if not exe:
|
||||||
|
env = read_shell_environment(get_options())
|
||||||
|
if env and 'PATH' in env:
|
||||||
|
exe = shutil.which(cmd[0], path=env['PATH'])
|
||||||
|
if exe:
|
||||||
|
cmd[0] = exe
|
||||||
|
|
||||||
tab = self.active_tab
|
tab = self.active_tab
|
||||||
if tab is not None:
|
if tab is not None:
|
||||||
|
bdata = data.encode('utf-8') if isinstance(data, str) else data
|
||||||
tab.new_special_window(
|
tab.new_special_window(
|
||||||
SpecialWindow(cmd, data, _('History'), overlay_for=window.id, cwd=window.cwd_of_child),
|
SpecialWindow(cmd, bdata, title or _('History'), overlay_for=window.id, cwd=window.cwd_of_child),
|
||||||
copy_colors_from=self.active_window
|
copy_colors_from=self.active_window
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -1677,8 +1695,8 @@ class Boss:
|
|||||||
def show_kitty_env_vars(self) -> None:
|
def show_kitty_env_vars(self) -> None:
|
||||||
w = self.active_window
|
w = self.active_window
|
||||||
if w:
|
if w:
|
||||||
output = '\n'.join(f'{k}={v}' for k, v in os.environ.items()).encode('utf-8')
|
output = '\n'.join(f'{k}={v}' for k, v in os.environ.items())
|
||||||
self.display_scrollback(w, output, ['less'])
|
self.display_scrollback(w, output, title=_('Current kitty env vars'))
|
||||||
|
|
||||||
def open_file(self, path: str) -> None:
|
def open_file(self, path: str) -> None:
|
||||||
if path == ":cocoa::application launched::":
|
if path == ":cocoa::application launched::":
|
||||||
@ -1697,3 +1715,12 @@ class Boss:
|
|||||||
self.new_window(path)
|
self.new_window(path)
|
||||||
if w is not None:
|
if w is not None:
|
||||||
tab.remove_window(w)
|
tab.remove_window(w)
|
||||||
|
|
||||||
|
def debug_config(self) -> None:
|
||||||
|
from .debug_config import debug_config
|
||||||
|
w = self.active_window
|
||||||
|
if w is not None:
|
||||||
|
output = debug_config(get_options())
|
||||||
|
set_clipboard_string(re.sub(r'\x1b.+?m', '', output))
|
||||||
|
output += '\n\x1b[35mThis debug output has been copied to the clipboard\x1b[m'
|
||||||
|
self.display_scrollback(w, output, title=_('Current kitty options'))
|
||||||
|
|||||||
142
kitty/cli.py
142
kitty/cli.py
@ -2,22 +2,19 @@
|
|||||||
# vim:fileencoding=utf-8
|
# vim:fileencoding=utf-8
|
||||||
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
# License: GPL v3 Copyright: 2017, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
import os
|
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
from collections import deque
|
from collections import deque
|
||||||
from typing import (
|
from typing import (
|
||||||
Any, Callable, Dict, FrozenSet, Generator, Iterable, Iterator, List, Match,
|
Any, Callable, Dict, FrozenSet, Iterator, List, Match, Optional, Sequence,
|
||||||
Optional, Sequence, Set, Tuple, Type, TypeVar, Union, cast
|
Tuple, Type, TypeVar, Union, cast
|
||||||
)
|
)
|
||||||
|
|
||||||
from .cli_stub import CLIOptions
|
from .cli_stub import CLIOptions
|
||||||
from .conf.utils import KeyAction, resolve_config
|
from .conf.utils import resolve_config
|
||||||
from .constants import appname, defconf, is_macos, is_wayland, str_version
|
from .constants import appname, defconf, is_macos, str_version
|
||||||
from .options.types import Options as KittyOpts, defaults
|
from .options.types import Options as KittyOpts
|
||||||
from .options.utils import MouseMap
|
from .typing import BadLineType, TypedDict
|
||||||
from .types import MouseEvent, SingleKey
|
|
||||||
from .typing import BadLineType, SequenceMap, TypedDict
|
|
||||||
|
|
||||||
|
|
||||||
class OptionDict(TypedDict):
|
class OptionDict(TypedDict):
|
||||||
@ -701,13 +698,6 @@ type=bool-set
|
|||||||
Print out information about the selection of fallback fonts for characters not present in the main font.
|
Print out information about the selection of fallback fonts for characters not present in the main font.
|
||||||
|
|
||||||
|
|
||||||
--debug-config
|
|
||||||
type=bool-set
|
|
||||||
Print out information about the system and kitty configuration. Note that this only
|
|
||||||
reads the standard kitty.conf not any extra configuration or alternative conf files
|
|
||||||
that were specified on the command line.
|
|
||||||
|
|
||||||
|
|
||||||
--execute -e
|
--execute -e
|
||||||
type=bool-set
|
type=bool-set
|
||||||
!
|
!
|
||||||
@ -759,131 +749,13 @@ def parse_args(
|
|||||||
|
|
||||||
|
|
||||||
SYSTEM_CONF = '/etc/xdg/kitty/kitty.conf'
|
SYSTEM_CONF = '/etc/xdg/kitty/kitty.conf'
|
||||||
ShortcutMap = Dict[Tuple[SingleKey, ...], KeyAction]
|
|
||||||
|
|
||||||
|
|
||||||
def mod_to_names(mods: int) -> Generator[str, None, None]:
|
def create_opts(args: CLIOptions, accumulate_bad_lines: Optional[List[BadLineType]] = None) -> KittyOpts:
|
||||||
from .fast_data_types import (
|
|
||||||
GLFW_MOD_ALT, GLFW_MOD_CAPS_LOCK, GLFW_MOD_CONTROL, GLFW_MOD_HYPER,
|
|
||||||
GLFW_MOD_META, GLFW_MOD_NUM_LOCK, GLFW_MOD_SHIFT, GLFW_MOD_SUPER
|
|
||||||
)
|
|
||||||
modmap = {'shift': GLFW_MOD_SHIFT, 'alt': GLFW_MOD_ALT, 'ctrl': GLFW_MOD_CONTROL, ('cmd' if is_macos else 'super'): GLFW_MOD_SUPER,
|
|
||||||
'hyper': GLFW_MOD_HYPER, 'meta': GLFW_MOD_META, 'num_lock': GLFW_MOD_NUM_LOCK, 'caps_lock': GLFW_MOD_CAPS_LOCK}
|
|
||||||
for name, val in modmap.items():
|
|
||||||
if mods & val:
|
|
||||||
yield name
|
|
||||||
|
|
||||||
|
|
||||||
def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction) -> None:
|
|
||||||
from .fast_data_types import glfw_get_key_name
|
|
||||||
keys = []
|
|
||||||
for key_spec in key_sequence:
|
|
||||||
names = []
|
|
||||||
mods, is_native, key = key_spec
|
|
||||||
names = list(mod_to_names(mods))
|
|
||||||
if key:
|
|
||||||
kname = glfw_get_key_name(0, key) if is_native else glfw_get_key_name(key, 0)
|
|
||||||
names.append(kname or f'{key}')
|
|
||||||
keys.append('+'.join(names))
|
|
||||||
|
|
||||||
print('\t', ' > '.join(keys), action)
|
|
||||||
|
|
||||||
|
|
||||||
def print_shortcut_changes(defns: ShortcutMap, text: str, changes: Set[Tuple[SingleKey, ...]]) -> None:
|
|
||||||
if changes:
|
|
||||||
print(title(text))
|
|
||||||
|
|
||||||
for k in sorted(changes):
|
|
||||||
print_shortcut(k, defns[k])
|
|
||||||
|
|
||||||
|
|
||||||
def compare_keymaps(final: ShortcutMap, initial: ShortcutMap) -> None:
|
|
||||||
added = set(final) - set(initial)
|
|
||||||
removed = set(initial) - set(final)
|
|
||||||
changed = {k for k in set(final) & set(initial) if final[k] != initial[k]}
|
|
||||||
print_shortcut_changes(final, 'Added shortcuts:', added)
|
|
||||||
print_shortcut_changes(initial, 'Removed shortcuts:', removed)
|
|
||||||
print_shortcut_changes(final, 'Changed shortcuts:', changed)
|
|
||||||
|
|
||||||
|
|
||||||
def flatten_sequence_map(m: SequenceMap) -> ShortcutMap:
|
|
||||||
ans: Dict[Tuple[SingleKey, ...], KeyAction] = {}
|
|
||||||
for key_spec, rest_map in m.items():
|
|
||||||
for r, action in rest_map.items():
|
|
||||||
ans[(key_spec,) + (r)] = action
|
|
||||||
return ans
|
|
||||||
|
|
||||||
|
|
||||||
def compare_mousemaps(final: MouseMap, initial: MouseMap) -> None:
|
|
||||||
added = set(final) - set(initial)
|
|
||||||
removed = set(initial) - set(final)
|
|
||||||
changed = {k for k in set(final) & set(initial) if final[k] != initial[k]}
|
|
||||||
|
|
||||||
def print_mouse_action(trigger: MouseEvent, action: KeyAction) -> None:
|
|
||||||
names = list(mod_to_names(trigger.mods)) + [f'b{trigger.button+1}']
|
|
||||||
when = {-1: 'repeat', 1: 'press', 2: 'doublepress', 3: 'triplepress'}.get(trigger.repeat_count, trigger.repeat_count)
|
|
||||||
grabbed = 'grabbed' if trigger.grabbed else 'ungrabbed'
|
|
||||||
print('\t', '+'.join(names), when, grabbed, action)
|
|
||||||
|
|
||||||
def print_changes(defns: MouseMap, changes: Set[MouseEvent], text: str) -> None:
|
|
||||||
if changes:
|
|
||||||
print(title(text))
|
|
||||||
for k in sorted(changes):
|
|
||||||
print_mouse_action(k, defns[k])
|
|
||||||
|
|
||||||
print_changes(final, added, 'Added mouse actions:')
|
|
||||||
print_changes(initial, removed, 'Removed mouse actions:')
|
|
||||||
print_changes(final, changed, 'Changed mouse actions:')
|
|
||||||
|
|
||||||
|
|
||||||
def compare_opts(opts: KittyOpts) -> None:
|
|
||||||
from .config import load_config
|
|
||||||
print('\nConfig options different from defaults:')
|
|
||||||
default_opts = load_config()
|
|
||||||
ignored = ('keymap', 'sequence_map', 'mousemap', 'map', 'mouse_map')
|
|
||||||
changed_opts = [
|
|
||||||
f for f in sorted(defaults._fields)
|
|
||||||
if f not in ignored and getattr(opts, f) != getattr(defaults, f)
|
|
||||||
]
|
|
||||||
field_len = max(map(len, changed_opts)) if changed_opts else 20
|
|
||||||
fmt = '{{:{:d}s}}'.format(field_len)
|
|
||||||
for f in changed_opts:
|
|
||||||
print(title(fmt.format(f)), getattr(opts, f))
|
|
||||||
|
|
||||||
compare_mousemaps(opts.mousemap, default_opts.mousemap)
|
|
||||||
final_, initial_ = opts.keymap, default_opts.keymap
|
|
||||||
final: ShortcutMap = {(k,): v for k, v in final_.items()}
|
|
||||||
initial: ShortcutMap = {(k,): v for k, v in initial_.items()}
|
|
||||||
final_s, initial_s = map(flatten_sequence_map, (opts.sequence_map, default_opts.sequence_map))
|
|
||||||
final.update(final_s)
|
|
||||||
initial.update(initial_s)
|
|
||||||
compare_keymaps(final, initial)
|
|
||||||
|
|
||||||
|
|
||||||
def create_opts(args: CLIOptions, debug_config: bool = False, accumulate_bad_lines: Optional[List[BadLineType]] = None) -> KittyOpts:
|
|
||||||
from .config import load_config
|
from .config import load_config
|
||||||
config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
|
config = tuple(resolve_config(SYSTEM_CONF, defconf, args.config))
|
||||||
if debug_config:
|
|
||||||
print(version(add_rev=True))
|
|
||||||
print(' '.join(os.uname()))
|
|
||||||
if is_macos:
|
|
||||||
import subprocess
|
|
||||||
print(' '.join(subprocess.check_output(['sw_vers']).decode('utf-8').splitlines()).strip())
|
|
||||||
if os.path.exists('/etc/issue'):
|
|
||||||
with open('/etc/issue', encoding='utf-8', errors='replace') as f:
|
|
||||||
print(f.read().strip())
|
|
||||||
if os.path.exists('/etc/lsb-release'):
|
|
||||||
with open('/etc/lsb-release', encoding='utf-8', errors='replace') as f:
|
|
||||||
print(f.read().strip())
|
|
||||||
config = tuple(x for x in config if os.path.exists(x))
|
|
||||||
if config:
|
|
||||||
print(green('Loaded config files:'), ', '.join(config))
|
|
||||||
overrides = (a.replace('=', ' ', 1) for a in args.override or ())
|
overrides = (a.replace('=', ' ', 1) for a in args.override or ())
|
||||||
opts = load_config(*config, overrides=overrides, accumulate_bad_lines=accumulate_bad_lines)
|
opts = load_config(*config, overrides=overrides, accumulate_bad_lines=accumulate_bad_lines)
|
||||||
if debug_config:
|
|
||||||
if not is_macos:
|
|
||||||
print('Running under:', green('Wayland' if is_wayland(opts) else 'X11'))
|
|
||||||
compare_opts(opts)
|
|
||||||
return opts
|
return opts
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
143
kitty/debug_config.py
Normal file
143
kitty/debug_config.py
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# vim:fileencoding=utf-8
|
||||||
|
# License: GPLv3 Copyright: 2021, Kovid Goyal <kovid at kovidgoyal.net>
|
||||||
|
|
||||||
|
import os
|
||||||
|
from functools import partial
|
||||||
|
from typing import Callable, Dict, Generator, Iterable, Set, Tuple
|
||||||
|
|
||||||
|
from .cli import green, title, version
|
||||||
|
from .conf.utils import KeyAction
|
||||||
|
from .constants import is_macos, is_wayland
|
||||||
|
from .options.types import Options as KittyOpts, defaults
|
||||||
|
from .options.utils import MouseMap
|
||||||
|
from .types import MouseEvent, SingleKey
|
||||||
|
from .typing import SequenceMap
|
||||||
|
|
||||||
|
ShortcutMap = Dict[Tuple[SingleKey, ...], KeyAction]
|
||||||
|
|
||||||
|
|
||||||
|
def mod_to_names(mods: int) -> Generator[str, None, None]:
|
||||||
|
from .fast_data_types import (
|
||||||
|
GLFW_MOD_ALT, GLFW_MOD_CAPS_LOCK, GLFW_MOD_CONTROL, GLFW_MOD_HYPER,
|
||||||
|
GLFW_MOD_META, GLFW_MOD_NUM_LOCK, GLFW_MOD_SHIFT, GLFW_MOD_SUPER
|
||||||
|
)
|
||||||
|
modmap = {'shift': GLFW_MOD_SHIFT, 'alt': GLFW_MOD_ALT, 'ctrl': GLFW_MOD_CONTROL, ('cmd' if is_macos else 'super'): GLFW_MOD_SUPER,
|
||||||
|
'hyper': GLFW_MOD_HYPER, 'meta': GLFW_MOD_META, 'num_lock': GLFW_MOD_NUM_LOCK, 'caps_lock': GLFW_MOD_CAPS_LOCK}
|
||||||
|
for name, val in modmap.items():
|
||||||
|
if mods & val:
|
||||||
|
yield name
|
||||||
|
|
||||||
|
|
||||||
|
def print_shortcut(key_sequence: Iterable[SingleKey], action: KeyAction, print: Callable) -> None:
|
||||||
|
from .fast_data_types import glfw_get_key_name
|
||||||
|
keys = []
|
||||||
|
for key_spec in key_sequence:
|
||||||
|
names = []
|
||||||
|
mods, is_native, key = key_spec
|
||||||
|
names = list(mod_to_names(mods))
|
||||||
|
if key:
|
||||||
|
kname = glfw_get_key_name(0, key) if is_native else glfw_get_key_name(key, 0)
|
||||||
|
names.append(kname or f'{key}')
|
||||||
|
keys.append('+'.join(names))
|
||||||
|
|
||||||
|
print('\t', ' > '.join(keys), action)
|
||||||
|
|
||||||
|
|
||||||
|
def print_shortcut_changes(defns: ShortcutMap, text: str, changes: Set[Tuple[SingleKey, ...]], print: Callable) -> None:
|
||||||
|
if changes:
|
||||||
|
print(title(text))
|
||||||
|
|
||||||
|
for k in sorted(changes):
|
||||||
|
print_shortcut(k, defns[k], print)
|
||||||
|
|
||||||
|
|
||||||
|
def compare_keymaps(final: ShortcutMap, initial: ShortcutMap, print: Callable) -> None:
|
||||||
|
added = set(final) - set(initial)
|
||||||
|
removed = set(initial) - set(final)
|
||||||
|
changed = {k for k in set(final) & set(initial) if final[k] != initial[k]}
|
||||||
|
print_shortcut_changes(final, 'Added shortcuts:', added, print)
|
||||||
|
print_shortcut_changes(initial, 'Removed shortcuts:', removed, print)
|
||||||
|
print_shortcut_changes(final, 'Changed shortcuts:', changed, print)
|
||||||
|
|
||||||
|
|
||||||
|
def flatten_sequence_map(m: SequenceMap) -> ShortcutMap:
|
||||||
|
ans: Dict[Tuple[SingleKey, ...], KeyAction] = {}
|
||||||
|
for key_spec, rest_map in m.items():
|
||||||
|
for r, action in rest_map.items():
|
||||||
|
ans[(key_spec,) + (r)] = action
|
||||||
|
return ans
|
||||||
|
|
||||||
|
|
||||||
|
def compare_mousemaps(final: MouseMap, initial: MouseMap, print: Callable) -> None:
|
||||||
|
added = set(final) - set(initial)
|
||||||
|
removed = set(initial) - set(final)
|
||||||
|
changed = {k for k in set(final) & set(initial) if final[k] != initial[k]}
|
||||||
|
|
||||||
|
def print_mouse_action(trigger: MouseEvent, action: KeyAction) -> None:
|
||||||
|
names = list(mod_to_names(trigger.mods)) + [f'b{trigger.button+1}']
|
||||||
|
when = {-1: 'repeat', 1: 'press', 2: 'doublepress', 3: 'triplepress'}.get(trigger.repeat_count, trigger.repeat_count)
|
||||||
|
grabbed = 'grabbed' if trigger.grabbed else 'ungrabbed'
|
||||||
|
print('\t', '+'.join(names), when, grabbed, action)
|
||||||
|
|
||||||
|
def print_changes(defns: MouseMap, changes: Set[MouseEvent], text: str) -> None:
|
||||||
|
if changes:
|
||||||
|
print(title(text))
|
||||||
|
for k in sorted(changes):
|
||||||
|
print_mouse_action(k, defns[k])
|
||||||
|
|
||||||
|
print_changes(final, added, 'Added mouse actions:')
|
||||||
|
print_changes(initial, removed, 'Removed mouse actions:')
|
||||||
|
print_changes(final, changed, 'Changed mouse actions:')
|
||||||
|
|
||||||
|
|
||||||
|
def compare_opts(opts: KittyOpts, print: Callable) -> None:
|
||||||
|
from .config import load_config
|
||||||
|
print()
|
||||||
|
print('Config options different from defaults:')
|
||||||
|
default_opts = load_config()
|
||||||
|
ignored = ('keymap', 'sequence_map', 'mousemap', 'map', 'mouse_map')
|
||||||
|
changed_opts = [
|
||||||
|
f for f in sorted(defaults._fields)
|
||||||
|
if f not in ignored and getattr(opts, f) != getattr(defaults, f)
|
||||||
|
]
|
||||||
|
field_len = max(map(len, changed_opts)) if changed_opts else 20
|
||||||
|
fmt = '{{:{:d}s}}'.format(field_len)
|
||||||
|
for f in changed_opts:
|
||||||
|
print(title(fmt.format(f)), str(getattr(opts, f)))
|
||||||
|
|
||||||
|
compare_mousemaps(opts.mousemap, default_opts.mousemap, print)
|
||||||
|
final_, initial_ = opts.keymap, default_opts.keymap
|
||||||
|
final: ShortcutMap = {(k,): v for k, v in final_.items()}
|
||||||
|
initial: ShortcutMap = {(k,): v for k, v in initial_.items()}
|
||||||
|
final_s, initial_s = map(flatten_sequence_map, (opts.sequence_map, default_opts.sequence_map))
|
||||||
|
final.update(final_s)
|
||||||
|
initial.update(initial_s)
|
||||||
|
compare_keymaps(final, initial, print)
|
||||||
|
|
||||||
|
|
||||||
|
def debug_config(opts: KittyOpts) -> str:
|
||||||
|
from io import StringIO
|
||||||
|
out = StringIO()
|
||||||
|
p = partial(print, file=out)
|
||||||
|
p(version(add_rev=True))
|
||||||
|
p(' '.join(os.uname()))
|
||||||
|
if is_macos:
|
||||||
|
import subprocess
|
||||||
|
p(' '.join(subprocess.check_output(['sw_vers']).decode('utf-8').splitlines()).strip())
|
||||||
|
if os.path.exists('/etc/issue'):
|
||||||
|
with open('/etc/issue', encoding='utf-8', errors='replace') as f:
|
||||||
|
p(f.read().strip())
|
||||||
|
if os.path.exists('/etc/lsb-release'):
|
||||||
|
with open('/etc/lsb-release', encoding='utf-8', errors='replace') as f:
|
||||||
|
p(f.read().strip())
|
||||||
|
if not is_macos:
|
||||||
|
p('Running under:' + green('Wayland' if is_wayland() else 'X11'))
|
||||||
|
if opts.config_paths:
|
||||||
|
p(green('Loaded config files:'))
|
||||||
|
p(' ', '\n '.join(opts.config_paths))
|
||||||
|
if opts.config_overrides:
|
||||||
|
p(green('Loaded config overrides:'))
|
||||||
|
p(' ', '\n '.join(opts.config_overrides))
|
||||||
|
compare_opts(opts, p)
|
||||||
|
return out.getvalue()
|
||||||
@ -310,9 +310,6 @@ def _main() -> None:
|
|||||||
os.chdir(os.path.expanduser('~'))
|
os.chdir(os.path.expanduser('~'))
|
||||||
cli_opts, rest = parse_args(args=args, result_class=CLIOptions)
|
cli_opts, rest = parse_args(args=args, result_class=CLIOptions)
|
||||||
cli_opts.args = rest
|
cli_opts.args = rest
|
||||||
if cli_opts.debug_config:
|
|
||||||
create_opts(cli_opts, debug_config=True)
|
|
||||||
return
|
|
||||||
if cli_opts.detach:
|
if cli_opts.detach:
|
||||||
if cli_opts.session == '-':
|
if cli_opts.session == '-':
|
||||||
from .session import PreReadSession
|
from .session import PreReadSession
|
||||||
|
|||||||
@ -3280,6 +3280,9 @@ map('Reset the terminal',
|
|||||||
only="macos"
|
only="macos"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
map('Debug kitty configuration',
|
||||||
|
'debug_config kitty_mod+f6 debug_config'
|
||||||
|
)
|
||||||
|
|
||||||
map('Send arbitrary text on key presses',
|
map('Send arbitrary text on key presses',
|
||||||
'send_text ctrl+shift+alt+h send_text all Hello World',
|
'send_text ctrl+shift+alt+h send_text all Hello World',
|
||||||
|
|||||||
2
kitty/options/types.py
generated
2
kitty/options/types.py
generated
@ -804,6 +804,8 @@ defaults.map = [
|
|||||||
KeyDefinition(True, KeyAction('set_background_opacity', ('default',)), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=100),)),
|
KeyDefinition(True, KeyAction('set_background_opacity', ('default',)), 1024, False, 97, (SingleKey(mods=0, is_native=False, key=100),)),
|
||||||
# reset_terminal
|
# reset_terminal
|
||||||
KeyDefinition(False, KeyAction('clear_terminal', ('reset', True)), 1024, False, 57349, ()),
|
KeyDefinition(False, KeyAction('clear_terminal', ('reset', True)), 1024, False, 57349, ()),
|
||||||
|
# debug_config
|
||||||
|
KeyDefinition(False, KeyAction('debug_config'), 1024, False, 57369, ()),
|
||||||
]
|
]
|
||||||
if is_macos:
|
if is_macos:
|
||||||
defaults.map.append(KeyDefinition(False, KeyAction('copy_to_clipboard'), 8, False, 99, ()))
|
defaults.map.append(KeyDefinition(False, KeyAction('copy_to_clipboard'), 8, False, 99, ()))
|
||||||
|
|||||||
@ -42,8 +42,7 @@ from .types import MouseEvent, ScreenGeometry, WindowGeometry
|
|||||||
from .typing import BossType, ChildType, EdgeLiteral, TabType, TypedDict
|
from .typing import BossType, ChildType, EdgeLiteral, TabType, TypedDict
|
||||||
from .utils import (
|
from .utils import (
|
||||||
color_as_int, get_primary_selection, load_shaders, log_error, open_cmd,
|
color_as_int, get_primary_selection, load_shaders, log_error, open_cmd,
|
||||||
open_url, parse_color_set, read_shell_environment, sanitize_title,
|
open_url, parse_color_set, sanitize_title, set_primary_selection
|
||||||
set_primary_selection
|
|
||||||
)
|
)
|
||||||
|
|
||||||
MatchPatternType = Union[Pattern[str], Tuple[Pattern[str], Optional[Pattern[str]]]]
|
MatchPatternType = Union[Pattern[str], Tuple[Pattern[str], Optional[Pattern[str]]]]
|
||||||
@ -902,27 +901,7 @@ class Window:
|
|||||||
def show_scrollback(self) -> None:
|
def show_scrollback(self) -> None:
|
||||||
text = self.as_text(as_ansi=True, add_history=True, add_wrap_markers=True)
|
text = self.as_text(as_ansi=True, add_history=True, add_wrap_markers=True)
|
||||||
data = self.pipe_data(text, has_wrap_markers=True)
|
data = self.pipe_data(text, has_wrap_markers=True)
|
||||||
|
get_boss().display_scrollback(self, data['text'], data['input_line_number'])
|
||||||
def prepare_arg(x: str) -> str:
|
|
||||||
x = x.replace('INPUT_LINE_NUMBER', str(data['input_line_number']))
|
|
||||||
x = x.replace('CURSOR_LINE', str(data['cursor_y']))
|
|
||||||
x = x.replace('CURSOR_COLUMN', str(data['cursor_x']))
|
|
||||||
return x
|
|
||||||
|
|
||||||
cmd = list(map(prepare_arg, get_options().scrollback_pager))
|
|
||||||
if not os.path.isabs(cmd[0]):
|
|
||||||
import shutil
|
|
||||||
exe = shutil.which(cmd[0])
|
|
||||||
if not exe:
|
|
||||||
env = read_shell_environment(get_options())
|
|
||||||
if env and 'PATH' in env:
|
|
||||||
exe = shutil.which(cmd[0], path=env['PATH'])
|
|
||||||
if exe:
|
|
||||||
cmd[0] = exe
|
|
||||||
bdata: Union[str, bytes, None] = data['text']
|
|
||||||
if isinstance(bdata, str):
|
|
||||||
bdata = bdata.encode('utf-8')
|
|
||||||
get_boss().display_scrollback(self, bdata, cmd)
|
|
||||||
|
|
||||||
def paste_bytes(self, text: Union[str, bytes]) -> None:
|
def paste_bytes(self, text: Union[str, bytes]) -> None:
|
||||||
# paste raw bytes without any processing
|
# paste raw bytes without any processing
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user