commit 24c4bc108da43afe1ea52782202bd62648eed89a (HEAD, refs/remotes/origin/master) Author: Juri Linkov Date: Mon Sep 9 21:33:10 2024 +0300 * src/xdisp.c (note_tab_bar_highlight): Remove fallback for help_echo_string. Don't use TAB_BAR_ITEM_CAPTION as the default value when TAB_BAR_ITEM_HELP is not specified (bug#73050). diff --git a/src/xdisp.c b/src/xdisp.c index f9a10267bad..18834c6b781 100644 --- a/src/xdisp.c +++ b/src/xdisp.c @@ -15155,8 +15155,6 @@ note_tab_bar_highlight (struct frame *f, int x, int y) help_echo_object = help_echo_window = Qnil; help_echo_pos = -1; help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_HELP); - if (NILP (help_echo_string)) - help_echo_string = AREF (f->tab_bar_items, prop_idx + TAB_BAR_ITEM_CAPTION); } #endif /* HAVE_WINDOW_SYSTEM */ commit 466db35877281ce2d5c2a5804e16d9401017d766 Author: Eshel Yaron Date: Mon Sep 9 19:43:21 2024 +0200 ; Revise new command 'project-find-file-in-root' * lisp/progmodes/project.el (project-find-file-in-root): Call 'find-file' directly, not via 'call-interactively'. Move interactive behavior to 'interactive' spec. diff --git a/lisp/progmodes/project.el b/lisp/progmodes/project.el index ce2960c248b..ab884935a77 100644 --- a/lisp/progmodes/project.el +++ b/lisp/progmodes/project.el @@ -1070,17 +1070,16 @@ using a command like `project-find-file'." filename)) ;;;###autoload -(defun project-find-file-in-root () - "Call `find-file' with the current project root as `default-directory'. - -Unlike `project-find-file', this doesn't provide completion over the -entire file tree. - -This is equivalent to running `project-any-command' with `find-file'." - (interactive) - (let* ((pr (project-current t)) - (default-directory (project-root pr))) - (call-interactively #'find-file))) +(defun project-find-file-in-root (filename) + "Edit file FILENAME. + +Interactively, prompt for FILENAME, defaulting to the root directory of +the current project." + (declare (interactive-only find-file)) + (interactive (list (read-file-name "Find file in root: " + (project-root (project-current t)) nil + (confirm-nonexistent-file-or-buffer)))) + (find-file filename t)) ;;;###autoload (defun project-find-file (&optional include-all) commit 7d7aa65f63db78c5732f1580213fc3767b767a4a Author: Michael Albinus Date: Mon Sep 9 15:35:55 2024 +0200 ; Fix last change diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 1d9e2c4df04..5834b496e1b 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1516,8 +1516,9 @@ calling HANDLER.") ;; so .... here we are. ;;;###tramp-autoload(require 'cl-lib) ;;;###tramp-autoload -(cl-defstruct (tramp-file-name (:type list) :named) - method user domain host port localname hop) +(progn + (cl-defstruct (tramp-file-name (:type list) :named) + method user domain host port localname hop)) (tramp--with-startup (function-put #'tramp-file-name-method 'tramp-suppress-trace t) commit d33d8c089b909b1fa64a799146557fcb68096269 Author: Michael Albinus Date: Mon Sep 9 15:22:35 2024 +0200 Silence compiler error * lisp/net/tramp.el (tramp-file-name*): Embed `function-put' calls with `tramp--with-startup'. (tramp-active-command-completion-p) * lisp/net/tramp-cache.el (tramp-get-hash-table): Remove declare form. Add `tramp-suppress-trace' function property. diff --git a/lisp/net/tramp-cache.el b/lisp/net/tramp-cache.el index 2d9d58b51ac..a5bdacb4d91 100644 --- a/lisp/net/tramp-cache.el +++ b/lisp/net/tramp-cache.el @@ -131,7 +131,7 @@ details see the info pages." If it doesn't exist yet, it is created and initialized with matching entries of `tramp-connection-properties'. If KEY is `tramp-cache-undefined', don't create anything, and return nil." - (declare (tramp-suppress-trace t)) + ;; (declare (tramp-suppress-trace t)) (unless (eq key tramp-cache-undefined) (or (gethash key tramp-cache-data) (let ((hash @@ -144,6 +144,11 @@ If KEY is `tramp-cache-undefined', don't create anything, and return nil." (tramp-set-connection-property key (nth 1 elt) (nth 2 elt))))) hash)))) +;; We cannot use the `declare' form for `tramp-suppress-trace' in +;; autoloaded functions, because the tramp-loaddefs.el generation +;; would fail. +(function-put #'tramp-get-hash-table 'tramp-suppress-trace t) + ;;;###tramp-autoload (defun tramp-get-file-property (key file property &optional default) "Get the PROPERTY of FILE from the cache context of KEY. diff --git a/lisp/net/tramp.el b/lisp/net/tramp.el index 709f6458e83..1d9e2c4df04 100644 --- a/lisp/net/tramp.el +++ b/lisp/net/tramp.el @@ -1516,17 +1516,18 @@ calling HANDLER.") ;; so .... here we are. ;;;###tramp-autoload(require 'cl-lib) ;;;###tramp-autoload -(progn - (cl-defstruct (tramp-file-name (:type list) :named) - method user domain host port localname hop)) +(cl-defstruct (tramp-file-name (:type list) :named) + method user domain host port localname hop) -(function-put #'tramp-file-name-method 'tramp-suppress-trace t) -(function-put #'tramp-file-name-user 'tramp-suppress-trace t) -(function-put #'tramp-file-name-domain 'tramp-suppress-trace t) -(function-put #'tramp-file-name-host 'tramp-suppress-trace t) -(function-put #'tramp-file-name-port 'tramp-suppress-trace t) -(function-put #'tramp-file-name-localname 'tramp-suppress-trace t) -(function-put #'tramp-file-name-hop 'tramp-suppress-trace t) +(tramp--with-startup + (function-put #'tramp-file-name-method 'tramp-suppress-trace t) + (function-put #'tramp-file-name-user 'tramp-suppress-trace t) + (function-put #'tramp-file-name-domain 'tramp-suppress-trace t) + (function-put #'tramp-file-name-host 'tramp-suppress-trace t) + (function-put #'tramp-file-name-port 'tramp-suppress-trace t) + (function-put #'tramp-file-name-localname 'tramp-suppress-trace t) + (function-put #'tramp-file-name-hop 'tramp-suppress-trace t) + (function-put #'make-tramp-file-name 'tramp-suppress-trace t)) ;;;###tramp-autoload (defconst tramp-null-hop @@ -2715,11 +2716,16 @@ They are completed by `M-x TAB' only if the current buffer is remote." (defun tramp-active-command-completion-p (_symbol _buffer) "A predicate for Tramp interactive commands. They are completed by `M-x TAB' only if there's an active connection or buffer." - (declare (tramp-suppress-trace t)) + ;; (declare (tramp-suppress-trace t)) (or (and (hash-table-p tramp-cache-data) (not (zerop (hash-table-count tramp-cache-data)))) (tramp-list-remote-buffers))) +;; We cannot use the `declare' form for `tramp-suppress-trace' in +;; autoloaded functions, because the tramp-loaddefs.el generation +;; would fail. +(function-put #'tramp-active-command-completion-p 'tramp-suppress-trace t) + (defun tramp-connectable-p (vec-or-filename) "Check if it is possible to connect the remote host without side-effects. This is true, if either the remote host is already connected, or if we are commit 21ff61372bf272711514f4c6508f20a5d8ab23ea Author: Mattias Engdegård Date: Mon Sep 9 10:27:50 2024 +0200 * etc/emacs_lldb.py (Lisp_Object): Recognise Lisp_Sub_Char_Table diff --git a/etc/emacs_lldb.py b/etc/emacs_lldb.py index 8393fccf467..4055b0f42eb 100644 --- a/etc/emacs_lldb.py +++ b/etc/emacs_lldb.py @@ -71,7 +71,7 @@ class Lisp_Object: "PVEC_SQLITE": "struct Lisp_Sqlite", "PVEC_CLOSURE": "struct Lisp_Vector", "PVEC_CHAR_TABLE": "struct Lisp_Vector", - "PVEC_SUB_CHAR_TABLE": "void", + "PVEC_SUB_CHAR_TABLE": "struct Lisp_Sub_Char_Table", "PVEC_RECORD": "struct Lisp_Vector", "PVEC_FONT": "struct font", "PVEC_NORMAL_VECTOR": "struct Lisp_Vector", commit 87daaaf9a463720f2ec80201d8f1e41aa29bd7ce Author: Mattias Engdegård Date: Mon Sep 9 10:23:46 2024 +0200 Speed up LLDB support for debugging Emacs * etc/emacs_lldb.py (Lisp_Object): Perform some numeric operations in Python instead of invoking LLDB for evaluation. Add lots of caches. diff --git a/etc/emacs_lldb.py b/etc/emacs_lldb.py index 219361faffd..8393fccf467 100644 --- a/etc/emacs_lldb.py +++ b/etc/emacs_lldb.py @@ -104,62 +104,103 @@ def init_unsigned(self): # the pvec_type enumerator if the object is a vector-like, as a # string. def init_lisp_types(self): - t = self.eval(f"(enum Lisp_Type)" - f"((EMACS_INT) {self.unsigned} " - f"& (1 << GCTYPEBITS) - 1)") - self.lisp_type = enumerator_name(t) + GCTYPEBITS = self.unsigned_const('GCTYPEBITS') + self.lisp_type = self.tag_name(self.unsigned + & ((1 << GCTYPEBITS) - 1)) if self.lisp_type == "Lisp_Vectorlike": self.pvec_type = "PVEC_NORMAL_VECTOR" vector = self.get_lisp_pointer("struct Lisp_Vector") size = vector.GetValueForExpressionPath("->header.size") size = size.GetValueAsUnsigned() - pseudo = self.eval(f"{size} & PSEUDOVECTOR_FLAG") - if pseudo.GetValueAsUnsigned() != 0: - typ = self.eval( - f"(enum pvec_type) (({size} " - f"& More_Lisp_Bits::PVEC_TYPE_MASK) " - f">> More_Lisp_Bits::PSEUDOVECTOR_AREA_BITS)") - self.pvec_type = enumerator_name(typ) + PSEUDOVECTOR_FLAG = self.unsigned_const('PSEUDOVECTOR_FLAG') + if size & PSEUDOVECTOR_FLAG: + PVEC_TYPE_MASK = self.unsigned_const( + 'More_Lisp_Bits::PVEC_TYPE_MASK') + PSEUDOVECTOR_AREA_BITS = self.unsigned_const( + 'More_Lisp_Bits::PSEUDOVECTOR_AREA_BITS') + pvec = (size & PVEC_TYPE_MASK) >> PSEUDOVECTOR_AREA_BITS + self.pvec_type = self.pvec_name(pvec) # Initialize self.untagged according to lisp_type and pvec_type. def init_values(self): - if self.lisp_type == "Lisp_Symbol": + lt = self.lisp_type + if lt == "Lisp_Symbol": offset = self.get_lisp_pointer("char").GetValueAsUnsigned() - self.untagged = self.eval(f"(struct Lisp_Symbol *)" - f" ((char *) &lispsym + {offset})", - True) - elif self.lisp_type == "Lisp_String": - self.untagged = self.get_lisp_pointer("struct Lisp_String", True) - elif self.lisp_type == "Lisp_Vectorlike": + self.untagged = self.eval( + f"(struct Lisp_Symbol *)((char *)&lispsym + {offset})") + elif lt == "Lisp_String": + self.untagged = self.get_lisp_pointer("struct Lisp_String") + elif lt == "Lisp_Vectorlike": c_type = Lisp_Object.pvec2type[self.pvec_type] - self.untagged = self.get_lisp_pointer(c_type, True) - elif self.lisp_type == "Lisp_Cons": - self.untagged = self.get_lisp_pointer("struct Lisp_Cons", True) - elif self.lisp_type == "Lisp_Float": - self.untagged = self.get_lisp_pointer("struct Lisp_Float", True) - elif self.lisp_type in ("Lisp_Int0", "Lisp_Int1"): - self.untagged = self.eval(f"((EMACS_INT) {self.unsigned}) " - f">> (GCTYPEBITS - 1)", True) - elif self.lisp_type == "Lisp_Type_Unused0": + self.untagged = self.get_lisp_pointer(c_type) + elif lt == "Lisp_Cons": + self.untagged = self.get_lisp_pointer("struct Lisp_Cons") + elif lt == "Lisp_Float": + self.untagged = self.get_lisp_pointer("struct Lisp_Float") + elif lt in ("Lisp_Int0", "Lisp_Int1"): + GCTYPEBITS = self.unsigned_const('GCTYPEBITS') + x = self.unsigned >> (GCTYPEBITS - 1) + self.untagged = self.eval(f"(EMACS_INT){x})") + elif lt == "Lisp_Type_Unused0": self.untagged = self.unsigned else: assert False, f"Unknown Lisp type {self.lisp_type}" + # Get a numeric constant (unsigned). + const_cache = {} + def unsigned_const(self, name): + val = self.const_cache.get(name) + if val is None: + frame = self.tagged.GetFrame() + val = frame.EvaluateExpression(name).GetValueAsUnsigned() + self.const_cache[name] = val + return val + + # Get the name of a Lisp_Object tag value, like "Lisp_String". + tag_cache = {} + def tag_name(self, tag): + name = self.tag_cache.get(tag) + if name is None: + frame = self.tagged.GetFrame() + val = frame.EvaluateExpression(f"(enum Lisp_Type){tag}") + name = enumerator_name(val) + self.tag_cache[tag] = name + return name + + # Get the name of a pseudovector type tag, like "PVEC_HASH_TABLE". + pvec_cache = {} + def pvec_name(self, pvec): + name = self.pvec_cache.get(pvec) + if name is None: + frame = self.tagged.GetFrame() + val = frame.EvaluateExpression(f"(enum pvec_type){pvec}") + name = enumerator_name(val) + self.pvec_cache[pvec] = name + return name + # Evaluate EXPR in the context of the current frame. - def eval(self, expr, make_var=False): - frame = self.tagged.GetFrame() - if make_var: - return frame.EvaluateExpression(expr) - options = lldb.SBExpressionOptions() - options.SetSuppressPersistentResult(True) - return frame.EvaluateExpression(expr, options) + eval_cache = {} + def eval(self, expr): + val = self.eval_cache.get(expr) + if val is None: + frame = self.tagged.GetFrame() + val = frame.EvaluateExpression(expr) + self.eval_cache[expr] = val + return val # Return an SBValue for this object denoting a pointer of type # TYP*. - def get_lisp_pointer(self, typ, make_var=False): - return self.eval(f"({typ}*) (((EMACS_INT) " - f"{self.unsigned}) & VALMASK)", - make_var) + lisp_ptr_cache = {} + def get_lisp_pointer(self, typ): + uns = self.unsigned + ptr = self.lisp_ptr_cache.get((uns, typ)) + if ptr is None: + VALMASK = self.unsigned_const('VALMASK') + frame = self.tagged.GetFrame() + ptr = frame.EvaluateExpression( + f"({typ}*)(EMACS_INT){uns & VALMASK}") + self.lisp_ptr_cache[(uns, typ)] = ptr + return ptr # If this is a Lisp_String, return an SBValue for its string data. # Return None otherwise. commit 95371fa754260199a6ea3428721270a89c341928 Author: Mattias Engdegård Date: Sat Sep 7 16:05:07 2024 +0200 ; * lisp/emacs-lisp/chart.el (chart--directory-size): Simpler regexp The empty regexp matches any string. diff --git a/lisp/emacs-lisp/chart.el b/lisp/emacs-lisp/chart.el index 2ca9b64be33..3acf2588f24 100644 --- a/lisp/emacs-lisp/chart.el +++ b/lisp/emacs-lisp/chart.el @@ -649,7 +649,7 @@ SORT-PRED if desired." "Compute total size of files in directory DIR and its subdirectories. DIR is assumed to be a directory, verified by the caller." (let ((size 0)) - (dolist (file (directory-files-recursively dir "." t)) + (dolist (file (directory-files-recursively dir "" t)) (let ((fsize (nth 7 (file-attributes file)))) (if (> fsize 0) (setq size commit 9a1de38528a6a7bc8dcd283d430e2f69ce3fcae4 Author: Mattias Engdegård Date: Sat Sep 7 11:44:08 2024 +0200 ; * src/json.c: refactor: clean out development detritus * src/json.c (enum ParseEndBehavior): Remove. (json_parse): Simplify, moving most code to the callers. diff --git a/src/json.c b/src/json.c index 21066d21328..eb2fa0472c8 100644 --- a/src/json.c +++ b/src/json.c @@ -1668,43 +1668,10 @@ json_parse_value (struct json_parser *parser, int c) } } -enum ParseEndBehavior - { - PARSEENDBEHAVIOR_CheckForGarbage, - PARSEENDBEHAVIOR_MovePoint - }; - static Lisp_Object -json_parse (struct json_parser *parser, - enum ParseEndBehavior parse_end_behavior) +json_parse (struct json_parser *parser) { - int c = json_skip_whitespace (parser); - - Lisp_Object result = json_parse_value (parser, c); - - switch (parse_end_behavior) - { - case PARSEENDBEHAVIOR_CheckForGarbage: - c = json_skip_whitespace_if_possible (parser); - if (c >= 0) - json_signal_error (parser, Qjson_trailing_content); - break; - case PARSEENDBEHAVIOR_MovePoint: - { - ptrdiff_t byte = (PT_BYTE + parser->input_current - parser->input_begin - + parser->additional_bytes_count); - ptrdiff_t position; - if (NILP (BVAR (current_buffer, enable_multibyte_characters))) - position = byte; - else - position = PT + parser->point_of_current_line + parser->current_column; - - SET_PT_BOTH (position, byte); - break; - } - } - - return result; + return json_parse_value (parser, json_skip_whitespace (parser)); } DEFUN ("json-parse-string", Fjson_parse_string, Sjson_parse_string, 1, MANY, @@ -1748,10 +1715,12 @@ usage: (json-parse-string STRING &rest ARGS) */) const unsigned char *begin = SDATA (string); json_parser_init (&p, conf, begin, begin + SBYTES (string), NULL, NULL); record_unwind_protect_ptr (json_parser_done, &p); + Lisp_Object result = json_parse (&p); - return unbind_to (count, - json_parse (&p, - PARSEENDBEHAVIOR_CheckForGarbage)); + if (json_skip_whitespace_if_possible (&p) >= 0) + json_signal_error (&p, Qjson_trailing_content); + + return unbind_to (count, result); } DEFUN ("json-parse-buffer", Fjson_parse_buffer, Sjson_parse_buffer, @@ -1809,9 +1778,17 @@ usage: (json-parse-buffer &rest args) */) json_parser_init (&p, conf, begin, end, secondary_begin, secondary_end); record_unwind_protect_ptr (json_parser_done, &p); + Lisp_Object result = json_parse (&p); + + ptrdiff_t byte = (PT_BYTE + p.input_current - p.input_begin + + p.additional_bytes_count); + ptrdiff_t position = (NILP (BVAR (current_buffer, + enable_multibyte_characters)) + ? byte + : PT + p.point_of_current_line + p.current_column); + SET_PT_BOTH (position, byte); - return unbind_to (count, - json_parse (&p, PARSEENDBEHAVIOR_MovePoint)); + return unbind_to (count, result); } void