mirror of
https://github.com/kovidgoyal/kitty
synced 2026-07-04 13:42:33 +02:00
Implement file filters via dbus
This commit is contained in:
@@ -471,6 +471,7 @@ func (h *Handler) set_state_from_config(_ *Config, opts *Options) (err error) {
|
||||
h.state.filter_map = nil
|
||||
h.state.current_filter = ""
|
||||
if len(opts.FileFilter) > 0 {
|
||||
opts.FileFilter = utils.Uniq(opts.FileFilter)
|
||||
has_all_files := false
|
||||
fmap := make(map[string][]Filter)
|
||||
seen := utils.NewSet[string](len(opts.FileFilter))
|
||||
@@ -509,7 +510,7 @@ func (h *Handler) set_state_from_config(_ *Config, opts *Options) (err error) {
|
||||
var default_cwd string
|
||||
|
||||
func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
|
||||
write_output := func(selections []string, interrupted bool) {
|
||||
write_output := func(selections []string, interrupted bool, current_filter string) {
|
||||
payload := make(map[string]any)
|
||||
if err != nil {
|
||||
if opts.WriteOutputTo != "" {
|
||||
@@ -538,6 +539,9 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
|
||||
if opts.WriteOutputTo != "" {
|
||||
if opts.OutputFormat == "json" {
|
||||
payload["paths"] = selections
|
||||
if current_filter != "" {
|
||||
payload["current_filter"] = current_filter
|
||||
}
|
||||
b, _ := json.MarshalIndent(payload, "", " ")
|
||||
m = string(b)
|
||||
}
|
||||
@@ -603,22 +607,22 @@ func main(_ *cli.Command, opts *Options, args []string) (rc int, err error) {
|
||||
}
|
||||
err = lp.Run()
|
||||
if err != nil {
|
||||
write_output(nil, false)
|
||||
write_output(nil, false, "")
|
||||
return 1, err
|
||||
}
|
||||
ds := lp.DeathSignalName()
|
||||
if ds != "" {
|
||||
fmt.Println("Killed by signal: ", ds)
|
||||
lp.KillIfSignalled()
|
||||
write_output(nil, true)
|
||||
write_output(nil, true, "")
|
||||
return 1, nil
|
||||
}
|
||||
rc = lp.ExitCode()
|
||||
switch rc {
|
||||
case 0:
|
||||
write_output(handler.state.selections, false)
|
||||
write_output(handler.state.selections, false, handler.state.current_filter)
|
||||
default:
|
||||
write_output(nil, true)
|
||||
write_output(nil, true, "")
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -630,12 +630,51 @@ func (self *Portal) ReadAll(namespaces []string) (ReadAllType, *dbus.Error) {
|
||||
}
|
||||
|
||||
type vmap map[string]dbus.Variant
|
||||
type Filter_expression struct {
|
||||
Ftype uint32
|
||||
Val string
|
||||
}
|
||||
type Filter struct {
|
||||
Name string
|
||||
Expressions []Filter_expression
|
||||
}
|
||||
|
||||
func (f Filter) Equal(o Filter) bool {
|
||||
return f.Name == o.Name && slices.Equal(f.Expressions, o.Expressions)
|
||||
}
|
||||
|
||||
type ChooseFilesData struct {
|
||||
Title string
|
||||
Mode string
|
||||
Cwd string
|
||||
SuggestedSaveFileName, SuggestedSaveFilePath string
|
||||
Handle dbus.ObjectPath
|
||||
Filters []Filter
|
||||
}
|
||||
|
||||
func (c *ChooseFilesData) set_filters(options vmap) {
|
||||
if v, found := options["filters"]; found {
|
||||
v.Store(&c.Filters)
|
||||
}
|
||||
if v, found := options["current_filter"]; found {
|
||||
var x Filter
|
||||
if err := v.Store(&x); err == nil {
|
||||
idx := slices.IndexFunc(c.Filters, func(q Filter) bool { return x.Equal(q) })
|
||||
if idx > -1 {
|
||||
c.Filters = slices.Delete(c.Filters, idx, idx+1)
|
||||
}
|
||||
c.Filters = slices.Insert(c.Filters, 0, x)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func get_matching_filter(name string, all_filters []Filter) (dbus.Variant, bool) {
|
||||
for _, x := range all_filters {
|
||||
if x.Name == name {
|
||||
return dbus.MakeVariant(x), true
|
||||
}
|
||||
}
|
||||
return dbus.Variant{}, false
|
||||
}
|
||||
|
||||
func var_to_bool_or_false(v dbus.Variant) bool {
|
||||
@@ -666,9 +705,10 @@ func (self *Portal) Cleanup() {
|
||||
}
|
||||
|
||||
type ChooserResponse struct {
|
||||
Paths []string `json:"paths"`
|
||||
Error string `json:"error"`
|
||||
Interrupted bool `json:"interrupted"`
|
||||
Paths []string `json:"paths"`
|
||||
Error string `json:"error"`
|
||||
Interrupted bool `json:"interrupted"`
|
||||
Current_filter string `json:"current_filter"`
|
||||
}
|
||||
|
||||
func (self *Portal) run_file_chooser(cfd ChooseFilesData) (response uint32, result_dict vmap) {
|
||||
@@ -753,6 +793,11 @@ func (self *Portal) run_file_chooser(cfd ChooseFilesData) (response uint32, resu
|
||||
if cfd.Title != "" {
|
||||
args = append(args, "--title", cfd.Title)
|
||||
}
|
||||
for _, fs := range cfd.Filters {
|
||||
for _, exp := range fs.Expressions {
|
||||
args = append(args, "--file-filter", fmt.Sprintf("%s:%s:%s", utils.IfElse(exp.Ftype == 0, "glob", "mime"), exp.Val, fs.Name))
|
||||
}
|
||||
}
|
||||
args = append(args, "--write-pid-to", pid_path)
|
||||
args = append(args, utils.IfElse(cfd.Cwd == "", "~", cfd.Cwd))
|
||||
cmd := exec.Command(utils.KittyExe(), args...)
|
||||
@@ -801,6 +846,11 @@ func (self *Portal) run_file_chooser(cfd ChooseFilesData) (response uint32, resu
|
||||
return prefix + u.EscapedPath()
|
||||
}, result.Paths)
|
||||
result_dict = vmap{"uris": dbus.MakeVariant(uris)}
|
||||
if result.Current_filter != "" {
|
||||
if v, found := get_matching_filter(result.Current_filter, cfd.Filters); found {
|
||||
result_dict["current_filter"] = v
|
||||
}
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
@@ -817,6 +867,7 @@ func (options vmap) get_bytearray(name string) string {
|
||||
|
||||
func (self *Portal) OpenFile(handle dbus.ObjectPath, app_id string, parent_window string, title string, options vmap) (uint32, vmap, *dbus.Error) {
|
||||
cfd := ChooseFilesData{Title: title, Cwd: options.get_bytearray("current_folder"), Handle: handle}
|
||||
cfd.set_filters(options)
|
||||
dir_only := false
|
||||
if v, found := options["directory"]; found && var_to_bool_or_false(v) {
|
||||
dir_only = true
|
||||
@@ -840,6 +891,7 @@ func (self *Portal) SaveFile(handle dbus.ObjectPath, app_id string, parent_windo
|
||||
SuggestedSaveFileName: options.get_bytearray("current_name"),
|
||||
SuggestedSaveFilePath: options.get_bytearray("current_file")}
|
||||
multiple := false
|
||||
cfd.set_filters(options)
|
||||
if v, found := options["multiple"]; found && var_to_bool_or_false(v) {
|
||||
multiple = true
|
||||
}
|
||||
|
||||
@@ -158,6 +158,18 @@ func StableSort[T any](s []T, cmp func(a, b T) int) []T {
|
||||
return s
|
||||
}
|
||||
|
||||
func Uniq[T comparable](s []T) []T {
|
||||
seen := NewSet[T](len(s))
|
||||
ans := make([]T, 0, len(s))
|
||||
for _, x := range s {
|
||||
if !seen.Has(x) {
|
||||
seen.Add(x)
|
||||
ans = append(ans, x)
|
||||
}
|
||||
}
|
||||
return ans
|
||||
}
|
||||
|
||||
func sort_with_key[T any, C constraints.Ordered](stable bool, s []T, key func(a T) C) []T {
|
||||
type t struct {
|
||||
key C
|
||||
|
||||
Reference in New Issue
Block a user