emacs-elpa-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[nongnu] elpa/racket-mode c1bcc33352 1/2: hash-lang: Add region behavior


From: ELPA Syncer
Subject: [nongnu] elpa/racket-mode c1bcc33352 1/2: hash-lang: Add region behavior to automatic pairs
Date: Thu, 30 Nov 2023 16:00:13 -0500 (EST)

branch: elpa/racket-mode
commit c1bcc33352b828385713db67e00fa9c92d4cda83
Author: Greg Hendershott <git@greghendershott.com>
Commit: Greg Hendershott <git@greghendershott.com>

    hash-lang: Add region behavior to automatic pairs
    
    Similar to electric-pairs-mode, when a region is active, wrap it with
    the pair.
    
    Although I don't want to go too far down the road on reinvented
    wheels, this seems like a basic nice thing to add without too much
    effort.
---
 racket-hash-lang.el | 177 ++++++++++++++++++++++++++++++----------------------
 1 file changed, 101 insertions(+), 76 deletions(-)

diff --git a/racket-hash-lang.el b/racket-hash-lang.el
index 620399cb57..f251f7d0d7 100644
--- a/racket-hash-lang.el
+++ b/racket-hash-lang.el
@@ -249,6 +249,7 @@ can contribute more colors; see the customization variable
               (append (list (cons 'racket-token t))
                       text-property-default-nonsticky))
   (add-hook 'post-self-insert-hook #'racket-hash-lang-post-self-insert nil t)
+  (add-hook 'self-insert-uses-region-functions 
#'racket-hash-lang-will-use-region nil t)
   (electric-pair-local-mode -1)
   (electric-indent-local-mode -1)
   (setq-local electric-indent-inhibit t)
@@ -565,82 +566,6 @@ that need be set."
   "Remove `racket--hash-lang-text-properties' from region BEG..END."
   (remove-list-of-text-properties beg end '(syntax-table racket-token)))
 
-;;; Pairs
-
-;; Because I can't see how to make electric-pair-mode work
-;; consistently -- including having it _not_ pair things like ' inside
-;; comments, strings, and especially our unique "text" token spans --
-;; I resorted to making a very simple alternative. It's not electric,
-;; just steam powered.
-
-(defvar-local racket-hash-lang-pairs nil
-  "Pairs of characters to insert automatically.
-
-The format of each item is
-
-  (open-char close-char . except-kinds)
-
-where except-kinds are symbols corresonding to lang lexer token
-kinds.
-
-This is initialized whenever a module language changes, using
-single-character values from the language's reported
-drracket:paren-matches and drracket:quote-matches.
-
-Paren matches are allowed for all token kinds. Quote matches are
-_not_ allowed in string, comment, or text tokens. For example a
-lang might supply \\=' as a quote-match, and you wouldn't want to
-type don\\='t in prose but get don\\='t\\='.
-
-You may customize this default initialization in
-`racket-hash-lang-module-language-hook'.")
-
-(defun racket--hash-lang-configure-pairs (parens quotes)
-  (let ((vs nil))
-    (dolist (p parens)
-      (let ((open (car p))
-            (close (cdr p)))
-        (when (and (= 1 (length open)) (= 1 (length close)))
-          (push (list (aref open 0) (aref close 0))
-                vs))))
-    (dolist (q quotes)
-      (when (= 1 (length q))
-        (push (list (aref q 0) (aref q 0) 'string 'comment 'text)
-              vs)))
-    (setq-local racket-hash-lang-pairs (reverse vs))))
-
-(defun racket-hash-lang-post-self-insert ()
-  "A value for `post-self-insert-hook'."
-  (cl-flet ((self-insert (char)
-                         (let ((racket-hash-lang-pairs nil) ;don't recur!
-                               (last-command-event char)
-                               (blink-matching-paren nil))
-                           (self-insert-command 1)
-                           (forward-char -1))))
-    (pcase (assq last-command-event racket-hash-lang-pairs)
-      (`(,_open ,close)
-       (self-insert close))
-      (`(,_open ,close . ,except-kinds)
-       (pcase-let ((`(,_beg ,_end (,kind . ,_))
-                    (racket--cmd/await
-                     nil
-                     `(hash-lang
-                       classify
-                       ,racket--hash-lang-id
-                       ,racket--hash-lang-generation
-                       ,(1- (point))))))
-         (unless (memq kind except-kinds)
-           (self-insert close)))))))
-
-(defun racket-hash-lang-delete-backward-char ()
-  "Delete previous character, and when between a pair, following character."
-  (interactive)
-  (pcase (assq (char-before) racket-hash-lang-pairs)
-    (`(,_open ,close . ,_ )
-     (when (eq close (char-after))
-       (delete-char 1))))
-  (delete-char -1))
-
 ;;; Indent
 
 (defun racket-hash-lang-indent-line-function ()
@@ -751,6 +676,106 @@ However other users don't need that, so we supply this
          (cnt (abs arg)))
     (racket-hash-lang-move dir cnt)))
 
+;;; Pairs
+
+;; Because I couldn't see how to make electric-pair-mode work
+;; consistently -- including having it _not_ pair things like ' inside
+;; tokens like comments, strings, text -- I resorted to making a very
+;; simple alternative. Not electric pairs, merely steam-powered.
+
+(defvar-local racket-hash-lang-pairs nil
+  "Pairs of characters to insert automatically.
+
+The format of each item is
+
+  (open-char close-char . except-kinds)
+
+where except-kinds are symbols corresonding to lang lexer token
+kinds.
+
+This is initialized whenever a module language changes, using
+single-character values from the language's reported
+drracket:paren-matches and drracket:quote-matches.
+
+Paren matches are allowed for all token kinds. Quote matches are
+_not_ allowed in string, comment, or text tokens. For example a
+lang might supply \\=' as a quote-match, and you wouldn't want to
+type don\\='t in prose but get don\\='t\\='.
+
+You may customize this default initialization in
+`racket-hash-lang-module-language-hook'.")
+
+(defun racket--hash-lang-configure-pairs (paren-matches quote-matches)
+  (let ((pairs nil))
+    (dolist (p paren-matches)
+      (let ((open (car p))
+            (close (cdr p)))
+        (when (and (= 1 (length open)) (= 1 (length close)))
+          (push (list (aref open 0) (aref close 0))
+                pairs))))
+    (dolist (q quote-matches)
+      (when (= 1 (length q))
+        (push (list (aref q 0) (aref q 0) 'string 'comment 'text)
+              pairs)))
+    (setq-local racket-hash-lang-pairs (reverse pairs))))
+
+(defun racket--hash-lang-lookup-pair ()
+  (pcase (assq last-command-event racket-hash-lang-pairs)
+    (`(,open ,close . ,except-kinds)
+     (if except-kinds
+         (pcase-let ((`(,_beg ,_end (,kind . ,_))
+                    (racket--cmd/await
+                     nil
+                     `(hash-lang
+                       classify
+                       ,racket--hash-lang-id
+                       ,racket--hash-lang-generation
+                       ,(1- (point))))))
+         (unless (memq kind except-kinds)
+           (cons open close)))
+       (cons open close)))))
+
+(defun racket-hash-lang-will-use-region ()
+  "A value for hook `self-insert-uses-region-functions'."
+  (and (use-region-p)
+       (racket--hash-lang-lookup-pair)
+       t))
+
+(defun racket--hash-lang-plain-self-insert (char)
+  "Use `self-insert-command' to insert CHAR without more pair checking."
+  (let ((racket-hash-lang-pairs nil)    ;don't recur!
+        (blink-matching-paren nil)
+        (last-command-event char))
+    (self-insert-command 1)))
+
+(defun racket-hash-lang-post-self-insert ()
+  "A value for hook `post-self-insert-hook'."
+  (pcase (racket--hash-lang-lookup-pair)
+    (`(,open-char . ,close-char)
+     (if (use-region-p)
+         (if (<= (point) (mark))
+             (save-excursion
+               (goto-char (mark))
+               (racket--hash-lang-plain-self-insert close-char))
+           (save-excursion
+             (let ((end (point)))
+               (delete-char -1)       ;delete open-char at end
+               (goto-char (mark))
+               (racket--hash-lang-plain-self-insert open-char)
+               (goto-char end)
+               (racket--hash-lang-plain-self-insert close-char))))
+       (save-excursion
+         (racket--hash-lang-plain-self-insert close-char))))))
+
+(defun racket-hash-lang-delete-backward-char ()
+  "Delete previous character, and when between a pair, following character."
+  (interactive)
+  (pcase (assq (char-before) racket-hash-lang-pairs)
+    (`(,_open ,close . ,_ )
+     (when (eq close (char-after))
+       (delete-char 1))))
+  (delete-char -1))
+
 ;;; Fill
 
 (defun racket-hash-lang-C-M-q-dwim (&optional prefix)



reply via email to

[Prev in Thread] Current Thread [Next in Thread]