]> git.eshelyaron.com Git - emacs.git/commitdiff
Simplify tempo.el a bit and use it in refactor.el
authorEshel Yaron <me@eshelyaron.com>
Mon, 17 Mar 2025 10:49:39 +0000 (11:49 +0100)
committerEshel Yaron <me@eshelyaron.com>
Mon, 17 Mar 2025 10:49:39 +0000 (11:49 +0100)
lisp/org/org-tempo.el
lisp/org/org.el
lisp/progmodes/refactor-elisp.el
lisp/progmodes/refactor.el
lisp/tempo.el

index 3716122723a22fa27e04abd207f85ef712a6422a..2718d30d6eb531bc626ad5c85b6d6a1297b2f69f 100644 (file)
@@ -81,8 +81,8 @@ Do not use \"I\" as a KEY, as it is reserved for expanding
 (defun org-tempo-setup ()
   "Setup tempo tags and match finder for the current buffer."
   (org-tempo--update-maybe)
-  (tempo-use-tag-list 'org-tempo-tags)
-  (setq-local tempo-match-finder "^ *\\(<[[:word:]]+\\)\\="))
+  (setq-local tempo-tags org-tempo-tags
+              tempo-match-finder "^ *\\(<[[:word:]]+\\)\\="))
 
 (defun org-tempo--keys ()
   "Return a list of all Org Tempo expansion strings, like \"<s\"."
index 71bd0d423c93e37c7b5075b4a8e7b654335292ac..d783e992df007156a4a0fa43dcd60a8693da3d32 100644 (file)
@@ -17282,7 +17282,7 @@ the place where a package like yasnippets can hook in.")
   "Hook for functions to attach themselves to TAB.
 See `org-ctrl-c-ctrl-c-hook' for more information.
 This hook runs after every other options for TAB have been exhausted, but
-before indentation and \t insertion takes place.")
+before indentation and literal tab insertion takes place.")
 
 (defvar org-metaleft-hook nil
   "Hook for functions attaching themselves to `M-left'.
index 9e41d07ba0ba7eb93bf97c8784599f9604ab397f..2fd23843859a4ddc6323509db7fd406a77a788aa 100644 (file)
                     (goto-char end)
                     (skip-chars-backward "[:blank:]\n")
                     (point)))
-             (newf (with-temp-buffer
-                     (insert-buffer-substring buf)
-                     (emacs-lisp-mode)
-                     (goto-char pos)
-                     (insert "\n\n(defun " new " (" vstr ")" "\n")
-                     (insert (string-trim (buffer-substring beg end)))
-                     (when (nth 4 (syntax-ppss)) (insert "\n"))
-                     (insert ")")
-                     (prog-indent-sexp 'defun)
-                     (buffer-substring pos (point)))))
+             (reg (string-trim (buffer-substring beg end))))
         `((,buf
            ;; Add `new' function definition at `pos'.
-           (,pos ,pos ,newf)
+           (,pos ,pos (l n n "(defun " ,new " (" ,vstr ")" n ,reg n% ")" ^))
            ;; Replace `beg'-`end' region with call to `new' function.
            (,beg ,end ,(concat "(" new (when bound " ") vstr ")"))))))))
 
index d02c4df2d10a3fe463d5a96de21e2e5204dc5dec..6a0fe315851d9db44b0f5682a7a576bcaaf7e0e8 100644 (file)
@@ -257,16 +257,10 @@ argument is the token corresponding to that text replacement.")
 (defun refactor--apply-replacements (reps)
   "Apply text replacements REPS in the current buffer."
   (pcase-dolist (`(,beg ,end ,str ,token) (sort reps :key #'cadr :reverse t))
-    (let ((source (current-buffer)))
-      (with-temp-buffer
-        (insert str)
-        (let ((temp (current-buffer)))
-          (with-current-buffer source
-            (save-excursion
-              (save-restriction
-                (narrow-to-region beg end)
-                (replace-buffer-contents temp)))
-            (run-hook-with-args 'refactor-replacement-functions token)))))))
+    (goto-char beg)
+    (delete-region beg end)
+    (tempo-insert-template str)
+    (run-hook-with-args 'refactor-replacement-functions token)))
 
 (defun refactor--find-edit-buffers (edits)
   (dolist (edit edits)
@@ -359,17 +353,10 @@ argument is the token corresponding to that text replacement.")
                                (?q (throw 'stop nil))
                                (?! (throw 'stop (cons 'all reps))))
                            (delete-overlay ov))
-                     (let ((source (current-buffer)))
-                       (with-temp-buffer
-                         (insert str)
-                         (let ((temp (current-buffer)))
-                           (with-current-buffer source
-                             (save-excursion
-                               (save-restriction
-                                 (narrow-to-region beg end)
-                                 (replace-buffer-contents temp)))
-                             (run-hook-with-args
-                              'refactor-replacement-functions token)))))))))
+                     (goto-char beg)
+                     (delete-region beg end)
+                     (tempo-insert-template str)
+                     (run-hook-with-args 'refactor-replacement-functions token)))))
               (setq reps (cdr reps)))
           (pcase-dolist (`(,_ ,_ ,_ ,_ . ,ov) reps)
             (when (overlayp ov) (delete-overlay ov)))))
index 5eccb180520197b0b95115822be2c9db2c135613..a016e1bd12d65e8a7a01cc359cc75a3b9ec4fa47 100644 (file)
@@ -127,11 +127,6 @@ argument).  If this variable is non-nil, the behavior is reversed.
 In Transient Mark mode, this option is unused."
   :type 'boolean)
 
-(defcustom tempo-show-completion-buffer t
-  "If non-nil, show a buffer with possible completions, when only
-a partial completion can be found."
-  :type 'boolean)
-
 ;;; Internal variables
 
 (defvar tempo-insert-string-functions nil
@@ -143,15 +138,6 @@ setting it to (upcase), for example.")
 (defvar tempo-tags nil
   "An association list with tags and corresponding templates.")
 
-(defvar-local tempo-local-tags '((tempo-tags . nil))
-  "A list of locally installed tag completion lists.
-It is an association list where the car of every element is a symbol
-whose variable value is a template list.  The cdr part, if non-nil,
-is a function or a regexp that defines the string to match.  See the
-documentation for the function `tempo-complete-tag' for more info.
-
-`tempo-tags' is always in the last position in this list.")
-
 (defvar-local tempo-collection nil
   "A collection of all the tags defined for the current buffer.")
 
@@ -277,101 +263,98 @@ The elements in ELEMENTS can be of several types:
                         (tempo-insert-template template-name
                                                (if tempo-insert-region
                                                    (not arg) arg))))
-    (and tag
-        (tempo-add-tag tag template-name taglist))
+    (when tag
+      (add-to-list (or taglist 'tempo-tags) (cons tag template-name)))
     command-name))
 
+(defvar tempo-on-region nil)
+
 ;;;
 ;;; tempo-insert-template
 
-(defun tempo-insert-template (template &optional on-region)
+;;;###autoload
+(defun tempo-insert-template (template &optional _)
   "Insert a template.
 TEMPLATE is the template to be inserted.  If ON-REGION is non-nil the
 `r' elements are replaced with the current region.  In Transient Mark
 mode, ON-REGION is ignored and assumed true if the region is active."
   (unwind-protect
-      (progn
-       (if (or (and transient-mark-mode
-                    mark-active))
-           (setq on-region t))
-       (and on-region
-            (set-marker tempo-region-start (min (mark) (point)))
-            (set-marker tempo-region-stop (max (mark) (point))))
-       (if on-region
-           (goto-char tempo-region-start))
+      (let ((tempo-on-region (use-region-p)))
+       (when tempo-on-region
+         (set-marker tempo-region-start (use-region-beginning))
+         (set-marker tempo-region-stop (use-region-end))
+          (goto-char tempo-region-start))
        (save-excursion
          (tempo-insert-mark (point-marker))
-          (mapc (lambda (elt)
-                  (tempo-insert elt on-region))
-               (if (symbolp template) (symbol-value template) template))
+          (if (symbolp template)
+              (apply #'tempo-insert (symbol-value template))
+            (tempo-insert template))
          (tempo-insert-mark (point-marker)))
        (tempo-forward-mark))
-    (tempo-forget-insertions)
-    (and transient-mark-mode
-        (deactivate-mark))))
+    (setq tempo-named-insertions nil)))
 
 ;;;
 ;;; tempo-insert
 
-(defun tempo-insert (element on-region)
-  "Insert a template ELEMENT.
-Insert one element from a template.  If ON-REGION is non-nil the `r'
-elements are replaced with the current region.
+(defun tempo-insert (&rest elements)
+  "Insert template ELEMENTS.
 
 See documentation for `tempo-define-template' for the kind of elements
 possible."
-  (pcase element
-    ((pred stringp) (tempo-process-and-insert-string element))
-    (`(p . ,rest) (tempo-insert-prompt-compat rest))
-    (`(P . ,rest) (let ((tempo-interactive t))
-                    (tempo-insert-prompt-compat rest)))
-    ;; (`(v ,name ,data) (tempo-save-named name nil data))
-    (`(r . ,rest) (if on-region
-                     (goto-char tempo-region-stop)
-                   (tempo-insert-prompt-compat rest)))
-    (`(r> . ,rest) (if on-region
-                       (progn
-                         (goto-char tempo-region-stop)
-                         (indent-region tempo-region-start
-                                        tempo-region-stop))
+  (dolist (element elements)
+    (pcase element
+      ((pred stringp) (tempo-process-and-insert-string element))
+      (`(p . ,rest) (tempo-insert-prompt-compat rest))
+      (`(P . ,rest) (let ((tempo-interactive t))
+                      (tempo-insert-prompt-compat rest)))
+      ;; (`(v ,name ,data) (tempo-save-named name nil data))
+      (`(r . ,rest) (if tempo-on-region
+                       (goto-char tempo-region-stop)
+                     (tempo-insert-prompt-compat rest)))
+      (`(r> . ,rest) (if tempo-on-region
+                         (progn
+                           (goto-char tempo-region-stop)
+                           (indent-region tempo-region-start
+                                          tempo-region-stop))
                        (tempo-insert-prompt-compat rest)))
-    (`(s ,name) (tempo-insert-named name))
-    (`(l . ,rest) (dolist (elt rest) (tempo-insert elt on-region)))
-    ('p (tempo-insert-mark (point-marker)))
-    ('r (if on-region
-           (goto-char tempo-region-stop)
-         (tempo-insert-mark (point-marker))))
-    ('r> (if on-region
-            (progn
-              (goto-char tempo-region-stop)
-              (indent-region tempo-region-start tempo-region-stop))
-          (tempo-insert-mark (point-marker))))
-    ('> (indent-according-to-mode))
-    ('& (if (not (or (= (current-column) 0)
-                    (save-excursion
-                      (re-search-backward
-                       "^\\s-*\\=" nil t))))
-           (insert "\n")))
-    ('% (if (not (or (eolp)
-                    (save-excursion
-                      (re-search-forward
-                       "\\=\\s-*$" nil t))))
-           (insert "\n")))
-    ('n (insert "\n"))
-    ('n> (insert "\n") (indent-according-to-mode))
-    ;; Bug: If the 'o is the first element in a template, strange
-    ;; things can happen when the template is inserted at the
-    ;; beginning of a line.
-    ('o (if (not (or on-region
-                    (eolp)
-                    (save-excursion
-                      (re-search-forward
-                       "\\=\\s-*$" nil t))))
-           (open-line 1)))
-    ('nil nil)
-    (_ (tempo-insert (or (tempo-is-user-element element)
-                        (eval element t))
-                    on-region))))
+      (`(s ,name) (tempo-insert-named name))
+      (`(l . ,rest) (dolist (elt rest) (tempo-insert elt)))
+      ('p (tempo-insert-mark (point-marker)))
+      ('r (if tempo-on-region
+             (goto-char tempo-region-stop)
+           (tempo-insert-mark (point-marker))))
+      ('r> (if tempo-on-region
+              (progn
+                (goto-char tempo-region-stop)
+                (indent-region tempo-region-start tempo-region-stop))
+            (tempo-insert-mark (point-marker))))
+      ('> (indent-according-to-mode))
+      ('^ (indent-region (car tempo-marks) (point)))
+      ('& (if (not (or (= (current-column) 0)
+                      (save-excursion
+                        (re-search-backward
+                         "^\\s-*\\=" nil t))))
+             (insert "\n")))
+      ('% (if (not (or (eolp)
+                      (save-excursion
+                        (re-search-forward
+                         "\\=\\s-*$" nil t))))
+             (insert "\n")))
+      ('n (insert "\n"))
+      ('n% (if (nth 4 (syntax-ppss)) (insert "\n") (message "nope")))
+      ('n> (insert "\n") (indent-according-to-mode))
+      ;; Bug: If the 'o is the first element in a template, strange
+      ;; things can happen when the template is inserted at the
+      ;; beginning of a line.
+      ('o (if (not (or tempo-on-region
+                      (eolp)
+                      (save-excursion
+                        (re-search-forward
+                         "\\=\\s-*$" nil t))))
+             (open-line 1)))
+      ('nil nil)
+      (_ (tempo-insert
+          (run-hook-with-args-until-success 'tempo-user-element-functions element))))))
 
 ;;;
 ;;; tempo-insert-prompt
@@ -422,20 +405,6 @@ never prompted."
      (t
       (tempo-insert-mark (point-marker))))))
 
-;;;
-;;; tempo-is-user-element
-
-(defun tempo-is-user-element (element)
-  "Try all the user-defined element handlers in `tempo-user-element-functions'."
-  (run-hook-with-args-until-success 'tempo-user-element-functions element))
-
-;;;
-;;; tempo-forget-insertions
-
-(defun tempo-forget-insertions ()
-  "Forget all the saved named insertions."
-  (setq tempo-named-insertions nil))
-
 ;;;
 ;;; tempo-save-named
 
@@ -475,14 +444,13 @@ processor."
          ((stringp insertion)
           (insert insertion))
          (t
-          (tempo-insert insertion nil)))))
-
+          (tempo-insert insertion)))))
 
 ;;;
 ;;; tempo-process-and-insert-string
 
 (defun tempo-process-and-insert-string (string)
-  "Insert a string from a template.
+  "Insert a STRING from a template.
 Run a string through the preprocessors in `tempo-insert-string-functions'
 and insert the results."
   (cond ((null tempo-insert-string-functions)
@@ -502,7 +470,7 @@ and insert the results."
 ;;; tempo-insert-mark
 
 (defun tempo-insert-mark (mark)
-  "Insert a mark `tempo-marks' while keeping it sorted."
+  "Add a MARK to `tempo-marks' while keeping it sorted."
   (cond ((null tempo-marks) (setq tempo-marks (list mark)))
        ((< mark (car tempo-marks)) (setq tempo-marks (cons mark tempo-marks)))
        (t (let ((lp tempo-marks))
@@ -547,79 +515,6 @@ and insert the results."
     (if prev-mark
        (goto-char prev-mark))))
 
-;;;
-;;; tempo-add-tag
-
-(defun tempo-add-tag (tag template &optional tag-list)
-  "Add a template tag.
-Add the TAG, that should complete to TEMPLATE to the list in TAG-LIST,
-or to `tempo-tags' if TAG-LIST is nil.  If TAG was already in the list,
-replace its template with TEMPLATE."
-
-  (interactive "sTag: \nCTemplate: ")
-  (if (null tag-list)
-      (setq tag-list 'tempo-tags))
-  (let ((entry (assoc tag (symbol-value tag-list))))
-    (if entry
-        ;; Tag is already in the list, assign a new template to it.
-        (setcdr entry template)
-      ;; Tag is not present in the list, add it with its template.
-      (set tag-list (cons (cons tag template) (symbol-value tag-list)))))
-  ;; Invalidate globally if we're modifying 'tempo-tags'.
-  (tempo-invalidate-collection (eq tag-list 'tempo-tags)))
-
-;;;
-;;; tempo-use-tag-list
-
-(defun tempo-use-tag-list (tag-list &optional completion-function)
-  "Install TAG-LIST to be used for template completion in the current buffer.
-TAG-LIST is a symbol whose variable value is a tag list created with
-`tempo-add-tag'.
-
-COMPLETION-FUNCTION is an obsolete option for specifying an optional
-function or string that is used by \\[tempo-complete-tag] to find a
-string to match the tag against.  It has the same definition as the
-variable `tempo-match-finder'.  In this version, supplying a
-COMPLETION-FUNCTION just sets `tempo-match-finder' locally."
-  (alist-set tag-list tempo-local-tags completion-function)
-  (if completion-function
-      (setq tempo-match-finder completion-function))
-  (tempo-invalidate-collection))
-
-;;;
-;;; tempo-invalidate-collection
-
-(defun tempo-invalidate-collection (&optional global)
-  "Mark the tag collection as obsolete.
-Whenever it is needed again it will be rebuilt.  If GLOBAL is non-nil,
-mark the tag collection of all buffers as obsolete, not just the
-current one."
-  (if global
-      (dolist (buffer (buffer-list))
-        (with-current-buffer buffer
-          (when (assq 'tempo-dirty-collection (buffer-local-variables))
-            (setq tempo-dirty-collection t))))
-    (setq tempo-dirty-collection t)))
-
-;;;
-;;; tempo-build-collection
-
-(defun tempo-build-collection ()
-  "Build a collection of all the tags and return it.
-If `tempo-dirty-collection' is nil, the old collection is reused."
-  (prog1
-      (or (and (not tempo-dirty-collection)
-              tempo-collection)
-         (setq tempo-collection
-               (apply #'append
-                       (mapcar (lambda (tag-list)
-                                       ; If the format for
-                                       ; tempo-local-tags changes,
-                                       ; change this
-                                 (eval (car tag-list) t))
-                              tempo-local-tags))))
-    (setq tempo-dirty-collection nil)))
-
 ;;;
 ;;; tempo-find-match-string
 
@@ -650,7 +545,7 @@ no match at all.
 If a single match is found, the corresponding template is expanded in
 place of the matching string."
   (interactive "*")
-  (let* ((collection (tempo-build-collection))
+  (let* ((collection tempo-tags)
         (match-info (tempo-find-match-string tempo-match-finder))
         (match-string (car match-info))
         (match-start (cdr match-info))
@@ -684,7 +579,7 @@ space bar, and looks something like this:
       (insert \" \")))"
 
   (interactive "*")
-  (let* ((collection (tempo-build-collection))
+  (let* ((collection tempo-tags)
         (match-info (tempo-find-match-string tempo-match-finder))
         (match-string (car match-info))
         (match-start (cdr match-info))