From 5dbcc8bd6c1c9188195b748911a0b00cca24cfd6 Mon Sep 17 00:00:00 2001 From: Po Lu Date: Fri, 2 Jun 2023 15:41:54 +0800 Subject: [PATCH] Improve CC Mode support for text conversion * lisp/progmodes/cc-cmds.el (c-post-text-conversion): New function. * lisp/progmodes/cc-mode.el (c-initialize-cc-mode): Add it as the `post-texxt-conversion-hook'. * lisp/simple.el (post-text-conversion-hook): New hook. (analyze-text-conversion): Run it until success before trying post insert functions. --- lisp/progmodes/cc-cmds.el | 35 +++++++++++++++++++++++++++++++++++ lisp/progmodes/cc-mode.el | 5 ++++- lisp/simple.el | 16 +++++++++++++--- 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/lisp/progmodes/cc-cmds.el b/lisp/progmodes/cc-cmds.el index 4c2340bfc2c..15b103a081f 100644 --- a/lisp/progmodes/cc-cmds.el +++ b/lisp/progmodes/cc-cmds.el @@ -5144,6 +5144,41 @@ details." (goto-char here) (delete-char 1)))) + + +;; Text conversion support. + +(defun c-post-text-conversion () + "Notice that the character `last-command-event' has been inserted. +If said character is an electric character such as `*' or `{', delete +it, then call the appropriate CC Mode function to electrically insert +it again." + (cond ((eq last-command-event ?#) + (delete-char -1) + (c-electric-pound nil) t) + ((memq last-command-event '(?{ ?})) + (delete-char -1) + (c-electric-brace nil) t) + ((memq last-command-event '(?\( ?\))) + (delete-char -1) + (c-electric-paren nil) t) + ((eq last-command-event ?*) + (delete-char -1) + (c-electric-star nil) t) + ((eq last-command-event ?/) + (delete-char -1) + (c-electric-slash nil) t) + ((memq last-command-event '(?\; ?,)) + (delete-char -1) + (c-electric-semi&comma nil) t) + ((eq last-command-event ?:) + (delete-char -1) + (c-electric-colon nil) t) + ((memq last-command-event '(?> ?<)) + (delete-char -1) + (c-electric-lt-gt nil) t))) + + (cc-provide 'cc-cmds) diff --git a/lisp/progmodes/cc-mode.el b/lisp/progmodes/cc-mode.el index 11a1d3fe6c2..1364117bdc8 100644 --- a/lisp/progmodes/cc-mode.el +++ b/lisp/progmodes/cc-mode.el @@ -251,7 +251,10 @@ control). See \"cc-mode.el\" for more info." (when (fboundp 'electric-indent-local-mode) (add-hook 'electric-indent-mode-hook 'c-electric-indent-mode-hook) (add-hook 'electric-indent-local-mode-hook - 'c-electric-indent-local-mode-hook))) + 'c-electric-indent-local-mode-hook)) + ;; Set up text conversion, for Emacs >= 30.0 + (when (boundp 'post-text-conversion-hook) + (add-hook 'post-text-conversion-hook #'c-post-text-conversion))) ;; Will try initialization hooks again if they failed. (put 'c-initialize-cc-mode initprop c-initialization-ok)))) diff --git a/lisp/simple.el b/lisp/simple.el index 698458c4bc7..d23e2e20c62 100644 --- a/lisp/simple.el +++ b/lisp/simple.el @@ -10980,7 +10980,6 @@ If the buffer doesn't exist, create it first." ;; Text conversion support. See textconv.c for more details about ;; what this is. - ;; Actually in textconv.c. (defvar text-conversion-edits) @@ -10988,6 +10987,12 @@ If the buffer doesn't exist, create it first." (defvar electric-pair-preserve-balance) (declare-function electric-pair-analyze-conversion "elec-pair.el") +(defvar-local post-text-conversion-hook nil + "Hook run after text is inserted by an input method. +Each function in this list is run until one returns non-nil. +When run, `last-command-event' is bound to the last character +that was inserted by the input method.") + (defun analyze-text-conversion () "Analyze the results of the previous text conversion event. @@ -11007,7 +11012,10 @@ For each insertion: - Run `post-self-insert-functions' for the last character of any inserted text so that modes such as `electric-pair-mode' - can work." + can work. + + - Run `post-text-conversion-hook' with `last-command-event' set + to the last character of any inserted text to finish up." (interactive) ;; The list must be processed in reverse. (dolist (edit (reverse text-conversion-edits)) @@ -11041,7 +11049,9 @@ For each insertion: (funcall auto-fill-function))))) (goto-char (nth 2 edit)) (let ((last-command-event end)) - (run-hooks 'post-self-insert-hook))) + (unless (run-hook-with-args-until-success + 'post-text-conversion-hook) + (run-hooks 'post-self-insert-hook)))) ;; Process this deletion before point. (nth 2 edit) is the ;; text which was deleted. Input methods typically prefer ;; to edit words instead of deleting characters off their -- 2.39.2