mirror of
https://github.com/kovidgoyal/kitty.git
synced 2026-09-05 09:18:33 +00:00
Merge branch 'fix/choose-files-shell-output' of https://github.com/M-Hassan-Raza/kitty
This commit is contained in:
commit
3f296b3213
4 changed files with 69 additions and 21 deletions
|
|
@ -854,18 +854,15 @@ func (h *Handler) set_state_from_config(conf *Config, opts *Options) (err error)
|
|||
var default_cwd string
|
||||
var use_light_colors bool
|
||||
|
||||
func quote_if_needed(x string) string {
|
||||
if s, err := shlex.Split(x); len(s) == 1 && err == nil && !strings.Contains(x, "$") {
|
||||
return x
|
||||
}
|
||||
return utils.QuoteStringForSH(x)
|
||||
func shell_output(selections []string) string {
|
||||
return strings.Join(utils.Map(shlex.Quote, selections), " ")
|
||||
}
|
||||
|
||||
func for_shell_relative(x string) string {
|
||||
if rel, is_under, err := utils.RelativeIfUnder(default_cwd, x, false); err == nil && is_under {
|
||||
x = rel
|
||||
}
|
||||
return quote_if_needed(x)
|
||||
return shlex.Quote(x)
|
||||
}
|
||||
|
||||
func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
|
||||
|
|
@ -912,7 +909,7 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
|
|||
var m string
|
||||
switch opts.OutputFormat {
|
||||
case "shell":
|
||||
m = strings.Join(utils.Map(quote_if_needed, selections), " ")
|
||||
m = shell_output(selections)
|
||||
case "shell-relative":
|
||||
m = strings.Join(utils.Map(for_shell_relative, selections), " ")
|
||||
case "text":
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#!/usr/bin/env python
|
||||
# License: GPLv3 Copyright: 2025, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import shlex
|
||||
import sys
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -249,12 +250,19 @@ def relative_path_if_possible(path: str, base: str) -> str:
|
|||
return path
|
||||
|
||||
|
||||
def format_selection_for_paste(paths: list[str], cwd: str, at_prompt: bool) -> str:
|
||||
items = []
|
||||
for path in paths:
|
||||
if cwd:
|
||||
path = relative_path_if_possible(path, cwd)
|
||||
if at_prompt:
|
||||
path = shlex.quote(path)
|
||||
items.append(path)
|
||||
return (' ' if at_prompt else '\n').join(items)
|
||||
|
||||
|
||||
@result_handler(has_ready_notification=True)
|
||||
def handle_result(args: list[str], data: dict[str, Any], target_window_id: int, boss: BossType) -> None:
|
||||
import shlex
|
||||
|
||||
from kitty.utils import shlex_split
|
||||
|
||||
paths: list[str] = data.get('paths', [])
|
||||
if not paths:
|
||||
boss.ring_bell_if_allowed()
|
||||
|
|
@ -263,16 +271,7 @@ def handle_result(args: list[str], data: dict[str, Any], target_window_id: int,
|
|||
if w is None:
|
||||
boss.ring_bell_if_allowed()
|
||||
return
|
||||
cwd = w.cwd_of_child
|
||||
items = []
|
||||
for path in paths:
|
||||
if cwd:
|
||||
path = relative_path_if_possible(path, cwd)
|
||||
if w.at_prompt and len(tuple(shlex_split(path))) > 1:
|
||||
path = shlex.quote(path)
|
||||
items.append(path)
|
||||
text = (' ' if w.at_prompt else '\n').join(items)
|
||||
w.paste_text(text)
|
||||
w.paste_text(format_selection_for_paste(paths, w.cwd_of_child, w.at_prompt))
|
||||
|
||||
|
||||
usage = '[directory to start choosing files in]'
|
||||
|
|
|
|||
36
kittens/choose_files/main_test.go
Normal file
36
kittens/choose_files/main_test.go
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
// License: GPLv3 Copyright: 2026, Kovid Goyal, <kovid at kovidgoyal.net>
|
||||
|
||||
package choose_files
|
||||
|
||||
import (
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"github.com/google/go-cmp/cmp"
|
||||
"github.com/kovidgoyal/kitty/tools/utils/shlex"
|
||||
)
|
||||
|
||||
func TestShellOutput(t *testing.T) {
|
||||
paths := []string{"simple", "a path", "a;command", "*.txt", "~root", "a>output", `a\b`, "it's"}
|
||||
actual, err := shlex.Split(shell_output(paths))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff(paths, actual); diff != "" {
|
||||
t.Fatalf("Shell output did not round-trip paths:\n%s", diff)
|
||||
}
|
||||
if q := shell_output([]string{"simple", "a/b"}); q != "simple a/b" {
|
||||
t.Fatalf("Shell-safe paths were unnecessarily quoted: %q", q)
|
||||
}
|
||||
|
||||
original_cwd := default_cwd
|
||||
default_cwd = t.TempDir()
|
||||
t.Cleanup(func() { default_cwd = original_cwd })
|
||||
relative, err := shlex.Split(for_shell_relative(filepath.Join(default_cwd, "a;command")))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if diff := cmp.Diff([]string{"a;command"}, relative); diff != "" {
|
||||
t.Fatalf("Shell-relative output did not round-trip the path:\n%s", diff)
|
||||
}
|
||||
}
|
||||
16
kitty_tests/choose_files.py
Normal file
16
kitty_tests/choose_files.py
Normal file
|
|
@ -0,0 +1,16 @@
|
|||
#!/usr/bin/env python
|
||||
# License: GPL v3 Copyright: 2026, Kovid Goyal <kovid at kovidgoyal.net>
|
||||
|
||||
import shlex
|
||||
|
||||
from .base import BaseTest
|
||||
|
||||
|
||||
class TestChooseFiles(BaseTest):
|
||||
def test_format_selection_for_paste(self) -> None:
|
||||
from kittens.choose_files.main import format_selection_for_paste
|
||||
|
||||
paths = ['/work/simple', '/work/a path', '/work/a;command', '/work/*.txt', '/work/~root', '/work/a>output', r'/work/a\b', "/work/it's"]
|
||||
text = format_selection_for_paste(paths, '/work', at_prompt=True)
|
||||
self.assertEqual(shlex.split(text), [path.removeprefix('/work/') for path in paths])
|
||||
self.assertEqual(format_selection_for_paste(paths[:2], '/work', at_prompt=False), 'simple\na path')
|
||||
Loading…
Add table
Add a link
Reference in a new issue