choose files: Add default mappings to choose a file and insert it into the terminal

This commit is contained in:
Kovid Goyal
2025-11-23 11:41:21 +05:30
parent 29d2796692
commit 37da04aad6
7 changed files with 79 additions and 15 deletions

View File

@@ -30,6 +30,17 @@ press :kbd:`Enter`. You can change the current directory by instead selecting a
directory and pressing the :kbd:`Tab` key. :kbd:`Shift+Tab` goes up one
directory level.
If you want to choose a file and insert it into your shell prompt at the
current cursor position, press :sc:`insert_chosen_file` for files or
:sc:`insert_chosen_directory` for directories. Similarly, to have a file
chosen in a command line, use, or example::
some-command $(kitten choose-file)
Note, that the above may not work in a complicated pipeline as it performs
terminal I/O and needs exclusive access to the ttyy device while choosing a
file.
Creating shortcuts to favorite/frequently used directories
------------------------------------------------------------

View File

@@ -772,18 +772,22 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
}
return
}
m := strings.Join(selections, "\n")
if opts.OutputFormat == "json" {
payload["paths"] = selections
if current_filter != "" {
payload["current_filter"] = current_filter
}
b, _ := json.MarshalIndent(payload, "", " ")
m = string(b)
payload["paths"] = selections
if current_filter != "" {
payload["current_filter"] = current_filter
}
fmt.Print(m)
if opts.WriteOutputTo != "" {
os.WriteFile(opts.WriteOutputTo, []byte(m), 0600)
if tui.RunningAsUI() {
fmt.Println(tui.KittenOutputSerializer()(payload))
} else {
m := strings.Join(selections, "\n")
if opts.OutputFormat == "json" {
b, _ := json.MarshalIndent(payload, "", " ")
m = string(b)
}
fmt.Print(m)
if opts.WriteOutputTo != "" {
os.WriteFile(opts.WriteOutputTo, []byte(m), 0600)
}
}
}

View File

@@ -2,10 +2,14 @@
# License: GPLv3 Copyright: 2025, Kovid Goyal <kovid at kovidgoyal.net>
import sys
from typing import Any
from kitty.conf.types import Definition
from kitty.constants import appname
from kitty.simple_cli_definitions import CONFIG_HELP, CompletionSpec
from kitty.typing_compat import BossType
from ..tui.handler import result_handler
definition = Definition(
'!kittens.choose_files',
@@ -123,6 +127,32 @@ egr() # }}}
def main(args: list[str]) -> None:
raise SystemExit('This must be run as kitten choose-files')
def relative_path_if_possible(path: str, base: str) -> str:
if not base or not path:
return path
from contextlib import suppress
from pathlib import Path
b = Path(base)
q = Path(path)
with suppress(ValueError):
return str(q.relative_to(b))
return path
@result_handler(has_ready_notification=True)
def handle_result(args: list[str], data: dict[str, Any], target_window_id: int, boss: BossType) -> None:
paths: list[str] = data.get('paths', [])
if not paths:
boss.ring_bell_if_allowed()
return
path = paths[0]
w = boss.window_id_map.get(target_window_id)
if w is not None:
cwd = w.cwd_of_child
if cwd:
path = relative_path_if_possible(path, cwd)
w.paste_text(path)
usage = '[directory to start choosing files in]'

View File

@@ -407,9 +407,7 @@ def handle_result(args: list[str], data: dict[str, Any], target_window_id: int,
if __name__ == '__main__':
# Run with kitty +kitten hints
ans = main(sys.argv)
if ans:
print(ans)
main(sys.argv)
elif __name__ == '__doc__':
cd = sys.cli_docs # type: ignore
cd['usage'] = usage

View File

@@ -4363,6 +4363,23 @@ map('Open selected path',
long_text='Select a path/filename and open it with the default open program.'
)
map('Insert chosen file',
'insert_chosen_file kitty_mod+p>c kitten choose-files',
long_text='''
Select a file using the :doc:`choose-files </kittens/choose-files>` kitten and insert
it into the terminal.
'''
)
map('Insert chosen directory',
'insert_chosen_directory kitty_mod+p>d kitten choose-files --mode=dir',
long_text='''
Select a directory using the :doc:`choose-files </kittens/choose-files>` kitten and insert
it into the terminal.
'''
)
map('Insert selected line',
'insert_selected_line kitty_mod+p>l kitten hints --type line --program -',
long_text='''

View File

@@ -929,6 +929,10 @@ defaults.map = [
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=102),), definition='kitten hints --type path --program -'),
# open_selected_path
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(mods=1, key=102),), definition='kitten hints --type path'),
# insert_chosen_file
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=99),), definition='kitten choose-files'),
# insert_chosen_directory
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=100),), definition='kitten choose-files --mode=dir'),
# insert_selected_line
KeyDefinition(is_sequence=True, trigger=SingleKey(mods=256, key=112), rest=(SingleKey(key=108),), definition='kitten hints --type line --program -'),
# insert_selected_word

View File

@@ -24,7 +24,7 @@ exec_kitty() {
is_wrapped_kitten() {
wrapped_kittens="clipboard icat hyperlinked_grep ask hints unicode_input ssh themes diff show_key transfer query_terminal"
wrapped_kittens="clipboard icat hyperlinked_grep ask hints unicode_input ssh themes diff show_key transfer query_terminal choose-files"
[ -n "$1" ] && {
case " $wrapped_kittens " in
*" $1 "*) printf "%s" "$1" ;;