diff --git a/gen-go-code.py b/gen-go-code.py index c784d0961..a261bb0b8 100755 --- a/gen-go-code.py +++ b/gen-go-code.py @@ -4,6 +4,7 @@ import bz2 import io import json +import kitty.constants as kc import os import re import struct @@ -13,27 +14,24 @@ import tarfile from contextlib import contextmanager, suppress from functools import lru_cache from itertools import chain -from typing import Any, BinaryIO, Dict, Iterator, List, Optional, Sequence, Set, TextIO, Tuple, Union - -import kitty.constants as kc from kittens.tui.operations import Mode from kittens.tui.spinners import spinners from kitty.cli import ( - CompletionSpec, - GoOption, - go_options_for_seq, - parse_option_spec, + CompletionSpec, GoOption, go_options_for_seq, parse_option_spec, serialize_as_go_string, ) from kitty.conf.generate import gen_go_code from kitty.conf.types import Definition -from kitty.guess_mime_type import text_mimes +from kitty.guess_mime_type import known_extensions, text_mimes from kitty.key_encoding import config_mod_map from kitty.key_names import character_key_name_aliases, functional_key_name_aliases from kitty.options.types import Options from kitty.rc.base import RemoteCommand, all_command_names, command_for_name from kitty.remote_control import global_options_spec from kitty.rgb import color_names +from typing import ( + Any, BinaryIO, Dict, Iterator, List, Optional, Sequence, Set, TextIO, Tuple, Union, +) changed: List[str] = [] @@ -673,6 +671,10 @@ def generate_textual_mimetypes() -> str: for k in text_mimes: ans.append(f' "{serialize_as_go_string(k)}": true,') ans.append('}') + ans.append('var KnownExtensions = map[string]string{') + for k, v in known_extensions.items(): + ans.append(f' ".{serialize_as_go_string(k)}": "{serialize_as_go_string(v)}",') + ans.append('}') return '\n'.join(ans) diff --git a/tools/utils/mimetypes.go b/tools/utils/mimetypes.go index b6d01d2f8..d1027bcca 100644 --- a/tools/utils/mimetypes.go +++ b/tools/utils/mimetypes.go @@ -11,6 +11,8 @@ import ( "os" "path/filepath" "strings" + + "golang.org/x/sys/unix" ) var _ = fmt.Print @@ -52,6 +54,11 @@ var UserMimeMap = (&Once[map[string]string]{Run: func() map[string]string { return ans }}).Get +func is_rcfile(path string) bool { + name := filepath.Base(path) + return strings.HasSuffix(name, "rc") && !strings.Contains(name, ".") +} + func GuessMimeType(filename string) string { ext := filepath.Ext(filename) mime_with_parameters := UserMimeMap()[ext] @@ -62,7 +69,14 @@ func GuessMimeType(filename string) string { only_once.Do(set_builtins) mime_with_parameters = builtin_types_map[ext] if mime_with_parameters == "" { - mime_with_parameters = builtin_types_map[strings.ToLower(ext)] + lext := strings.ToLower(ext) + mime_with_parameters = builtin_types_map[lext] + if mime_with_parameters == "" { + mime_with_parameters = KnownExtensions[lext] + } + if mime_with_parameters == "" && is_rcfile(filename) { + mime_with_parameters = "text/plain" + } if mime_with_parameters == "" { return "" } @@ -74,3 +88,24 @@ func GuessMimeType(filename string) string { } return ans } + +func GuessMimeTypeWithFileSystemAccess(filename string) string { + is_dir, is_exe := false, false + s, err := os.Stat(filename) + if err == nil { + is_dir = s.IsDir() + if !is_dir && s.Mode().Perm()&0o111 != 0 && unix.Access(filename, unix.X_OK) == nil { + is_exe = true + } + } + if is_dir { + return "inode/directory" + } + mt := GuessMimeType(filename) + if mt == "" { + if is_exe { + mt = "inode/executable" + } + } + return mt +}