diff --git a/kittens/ask/get_line.go b/kittens/ask/get_line.go index 679c299fc..f814db368 100644 --- a/kittens/ask/get_line.go +++ b/kittens/ask/get_line.go @@ -9,6 +9,7 @@ import ( "path/filepath" "time" + "github.com/kovidgoyal/kitty/kittens/choose_files" "github.com/kovidgoyal/kitty/tools/tui/loop" "github.com/kovidgoyal/kitty/tools/tui/readline" "github.com/kovidgoyal/kitty/tools/utils" @@ -16,13 +17,16 @@ import ( var _ = fmt.Print -func get_line(o *Options) (result string, err error) { +func get_line(o *Options, complete_file_names bool) (result string, err error) { lp, err := loop.New(loop.NoAlternateScreen, loop.NoRestoreColors) if err != nil { return } cwd, _ := os.Getwd() ropts := readline.RlInit{Prompt: o.Prompt} + if complete_file_names { + ropts.Completer = choose_files.FilePromptCompleter(nil) + } if o.Name != "" { base := filepath.Join(utils.CacheDir(), "ask") ropts.HistoryPath = filepath.Join(base, o.Name+".history.json") diff --git a/kittens/ask/main.go b/kittens/ask/main.go index cdd95dc39..46f966d83 100644 --- a/kittens/ask/main.go +++ b/kittens/ask/main.go @@ -50,7 +50,13 @@ func main(_ *cli.Command, o *Options, args []string) (rc int, err error) { result.Response = pw case "line": show_message(o.Message) - result.Response, err = get_line(o) + result.Response, err = get_line(o, false) + if err != nil { + return 1, err + } + case "file": + show_message(o.Message) + result.Response, err = get_line(o, true) if err != nil { return 1, err } diff --git a/kittens/ask/main.py b/kittens/ask/main.py index 0ca73ff5f..6ac5c8080 100644 --- a/kittens/ask/main.py +++ b/kittens/ask/main.py @@ -11,7 +11,7 @@ from ..tui.handler import result_handler def option_text() -> str: return '''\ --type -t -choices=line,yesno,choices,password +choices=line,yesno,choices,password,file default=line Type of input. Defaults to asking for a line of text. diff --git a/kittens/choose_files/main.go b/kittens/choose_files/main.go index 7678ff3c8..555a07162 100644 --- a/kittens/choose_files/main.go +++ b/kittens/choose_files/main.go @@ -776,7 +776,7 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) { lp.ColorSchemeChangeNotifications() handler := Handler{lp: lp, err_chan: make(chan error, 8), msg_printer: message.NewPrinter(utils.LanguageTag()), spinner: tui.NewSpinner("dots")} handler.rl = readline.New(lp, readline.RlInit{ - Prompt: "> ", ContinuationPrompt: ". ", Completer: handler.complete_save_prompt, + Prompt: "> ", ContinuationPrompt: ". ", Completer: FilePromptCompleter(handler.state.CurrentDir), }) if err = handler.set_state_from_config(conf, opts); err != nil { return 1, err diff --git a/kittens/choose_files/save-file.go b/kittens/choose_files/save-file.go index 4f90db91a..4a3075040 100644 --- a/kittens/choose_files/save-file.go +++ b/kittens/choose_files/save-file.go @@ -13,51 +13,62 @@ import ( var _ = fmt.Print -func (h *Handler) complete_save_prompt(before_cursor, after_cursor string) *cli.Completions { - path := before_cursor - prefix := "" - if idx := strings.Index(path, string(os.PathSeparator)); idx > -1 { - prefix = filepath.Dir(path) + string(os.PathSeparator) - } - dir := "" - if path == "" { - path = h.state.CurrentDir() - dir = path - } else { - if !filepath.IsAbs(path) { - path = filepath.Join(h.state.CurrentDir(), path) - } - dir = filepath.Dir(path) - if strings.HasSuffix(before_cursor, string(os.PathSeparator)) { - dir = path - } - } - entries, err := os.ReadDir(dir) - if err != nil { - return nil - } - ans := cli.NewCompletions() - dirs := ans.AddMatchGroup("Directories") - dirs.IsFiles = true - dirs.NoTrailingSpace = true - files := ans.AddMatchGroup("Files") - files.IsFiles = true - files.NoTrailingSpace = true - leading, _ := filepath.Rel(dir, path) - if leading == "." { - leading = "" - } - for _, e := range entries { - word := e.Name() - if leading == "" || strings.HasPrefix(word, leading) { - collection := utils.IfElse(e.Type().IsDir(), dirs, files) - if prefix != "" { - word = prefix + word +func FilePromptCompleter(getcwd func() string) func(string, string) *cli.Completions { + if getcwd == nil { + getcwd = func() string { + ans, err := os.Getwd() + if err != nil { + ans = "." } - collection.Matches = append(collection.Matches, &cli.Match{Word: word}) + return ans } } - return ans + return func(before_cursor, after_cursor string) *cli.Completions { + path := before_cursor + prefix := "" + if idx := strings.Index(path, string(os.PathSeparator)); idx > -1 { + prefix = filepath.Dir(path) + string(os.PathSeparator) + } + dir := "" + if path == "" { + path = getcwd() + dir = path + } else { + if !filepath.IsAbs(path) { + path = filepath.Join(getcwd(), path) + } + dir = filepath.Dir(path) + if strings.HasSuffix(before_cursor, string(os.PathSeparator)) { + dir = path + } + } + entries, err := os.ReadDir(dir) + if err != nil { + return nil + } + ans := cli.NewCompletions() + dirs := ans.AddMatchGroup("Directories") + dirs.IsFiles = true + dirs.NoTrailingSpace = true + files := ans.AddMatchGroup("Files") + files.IsFiles = true + files.NoTrailingSpace = true + leading, _ := filepath.Rel(dir, path) + if leading == "." { + leading = "" + } + for _, e := range entries { + word := e.Name() + if leading == "" || strings.HasPrefix(word, leading) { + collection := utils.IfElse(e.Type().IsDir(), dirs, files) + if prefix != "" { + word = prefix + word + } + collection.Matches = append(collection.Matches, &cli.Match{Word: word}) + } + } + return ans + } } func (h *Handler) current_save_file_path() string {