From 6574fa512aed92570d6d8db50cc1b7d67b6aea60 Mon Sep 17 00:00:00 2001 From: Greg Hendershott Date: Fri, 17 Nov 2023 14:35:54 -0500 Subject: [PATCH] Permit sexp commands in racket-hash-lang-mode when sexp hash-lang Previously I'd been too conservative. If a hash-lang uses sexps, we should be able to allow sexp-centric commands to work in racket-hash-lang-mode as well as racket-mode. --- racket-edit.el | 26 ++++++++++++++------------ racket-hash-lang.el | 25 +++++++++++++++++++++++-- racket-parens.el | 1 + racket-repl.el | 4 ++++ racket-stepper.el | 3 +++ racket-util.el | 15 ++++++++++++--- 6 files changed, 57 insertions(+), 17 deletions(-) diff --git a/racket-edit.el b/racket-edit.el index 3a0b07d3..dd82ac33 100644 --- a/racket-edit.el +++ b/racket-edit.el @@ -25,16 +25,16 @@ ;;; code folding (defun racket--for-all-tests (verb f) - ;; For this to work in `racket-hash-lang-mode', (a) we'd need to - ;; learn the test submodule spans from analysis of fully-expanded - ;; code (as we can do on the `pdb` branch with a sufficiently new - ;; Racket). And then, (b) we'd need to do the hiding ourselves, - ;; without `hs-minor-mode', which AFAICT demands regexps for block - ;; starts and ends. We'd want a "positional" not regexp flavor, - ;; which AFAIK we'd need to implement ourselves. + ;; For this to work in `racket-hash-lang-mode' for all hash-langs, + ;; (a) we'd need to learn the test submodule spans from analysis of + ;; fully-expanded code (as we can do on the `pdb` branch with a + ;; sufficiently new Racket). And then, (b) we'd need to do the + ;; hiding ourselves, without `hs-minor-mode', which AFAICT demands + ;; regexps for block starts and ends. We'd want a "positional" not + ;; regexp flavor, which AFAIK we'd need to implement ourselves. ;; - ;; TL;DR: For now require `racket-mode'. - (racket--assert-racket-mode) + ;; TL;DR: For now require `racket-sexp-edit-mode'. + (racket--assert-sexp-edit-mode) (unless (bound-and-true-p hs-minor-mode) (user-error "hs-minor-mode is not enabled")) (save-excursion @@ -82,7 +82,7 @@ At most one required module is listed per line. See also: `racket-trim-requires' and `racket-base-requires'." (interactive) - (racket--assert-racket-mode) + (racket--assert-sexp-edit-mode) (racket--tidy-requires '() #'ignore)) (defun racket--tidy-requires (add callback) @@ -166,7 +166,7 @@ Note: Currently this only helps change \"#lang racket\" to conversions, such as changing \"#lang typed/racket\" to \"#lang typed/racket/base\"." (interactive) - (racket--assert-racket-mode) + (racket--assert-sexp-edit-mode) (when (racket--buffer-start-re "^#lang.*? racket/base$") (user-error "Already using #lang racket/base. Nothing to change.")) (unless (racket--buffer-start-re "^#lang.*? racket$") @@ -277,7 +277,7 @@ The mechanism is similar to that used for Racket's \"Search Manuals\" feature. Today there exists no system-wide database of identifiers that are exported but not documented." (interactive) - (racket--assert-racket-mode) + (racket--assert-sexp-edit-mode) (let ((sym-at-point (thing-at-point 'symbol t))) (unless sym-at-point (user-error "There does not seem to be an identifier at point")) @@ -376,6 +376,7 @@ usual. For example: See also: `racket-unalign'." (interactive) + (racket--assert-sexp-edit-mode) (save-excursion (let ((listp (eq ?\( (char-syntax (char-after)))) (prev-line 0) @@ -399,6 +400,7 @@ See also: `racket-unalign'." Effectively does M-x `just-one-space' and `prog-indent-sexp' for each couple's value." (interactive) + (racket--assert-sexp-edit-mode) (save-excursion (let ((listp (eq ?\( (char-syntax (char-after))))) (racket--for-each-couple listp diff --git a/racket-hash-lang.el b/racket-hash-lang.el index 01a082b7..63f37f65 100644 --- a/racket-hash-lang.el +++ b/racket-hash-lang.el @@ -25,11 +25,19 @@ ("C-c C-t" ,#'racket-test) ("C-c C-l" ,#'racket-logger) ("C-c C-o" ,#'racket-profile) + ("M-C-x" racket-send-definition) + ("C-x C-e" racket-send-last-sexp) + ("C-c C-r" racket-send-region) ("C-c C-e f" ,#'racket-expand-file) + ("C-c C-e x" racket-expand-definition) + ("C-c C-e e" racket-expand-last-sexp) + ("C-c C-e r" racket-expand-region) ("C-c C-x C-f" ,#'racket-open-require-path) ("TAB" ,#'indent-for-tab-command) ;; ("C-c C-p" racket-cycle-paren-shapes) equivalent using paren-matches? ("M-C-y" ,#'racket-insert-lambda) + ("C-c C-f" racket-fold-all-tests) + ("C-c C-u" racket-unfold-all-tests) ("RET" ,#'newline-and-indent) ("C-M-b" ,#'racket-hash-lang-backward) ("C-M-f" ,#'racket-hash-lang-forward) @@ -46,9 +54,19 @@ ["in *shell* using `racket`" racket-racket]) ("Tests" ["in REPL" racket-test] - ["in *shell* using `raco test`" racket-raco-test]) + ["in *shell* using `raco test`" racket-raco-test] + "---" + ["Fold All" racket-fold-all-tests :active (racket--sexp-edit-mode-p)] + ["Unfold All" racket-unfold-all-tests :active (racket--sexp-edit-mode-p)]) + ("Eval" + ["Region" racket-send-region :active (and (region-active-p) (racket--sexp-edit-mode-p))] + ["Definition" racket-send-definition :active (racket--sexp-edit-mode-p)] + ["Last S-Expression" racket-send-last-sexp :active (racket--sexp-edit-mode-p)]) ("Macro Expand" - ["File" racket-expand-file]) + ["File" racket-expand-file] + ["Region" racket-expand-region :active (and (region-active-p) (racket--sexp-edit-mode-p))] + ["Definition" racket-expand-definition :active (racket--sexp-edit-mode-p)] + ["Last S-Expression" racket-expand-last-sexp :active (racket--sexp-edit-mode-p)]) ["Switch to REPL" racket-repl] ("Tools" ["Profile" racket-profile] @@ -59,6 +77,9 @@ ["Comment" comment-dwim] ["Insert λ" racket-insert-lambda] ["Indent Region" indent-region] + ["Cycle Paren Shapes" racket-cycle-paren-shapes :active (racket--sexp-edit-mode-p)] + ["Align" racket-align :active (racket--sexp-edit-mode-p)] + ["Unalign" racket-unalign :active (racket--sexp-edit-mode-p)] "---" ["Open Require Path" racket-open-require-path] ["Find Collection" racket-find-collection] diff --git a/racket-parens.el b/racket-parens.el index 1ecf2c04..3eb61520 100644 --- a/racket-parens.el +++ b/racket-parens.el @@ -137,6 +137,7 @@ This function is a suitable element for the list variable (defun racket-cycle-paren-shapes () "Cycle the sexpr among () [] {}." (interactive) + (racket--assert-sexp-edit-mode) (save-excursion (unless (eq ?\( (char-syntax (char-after))) (backward-up-list)) diff --git a/racket-repl.el b/racket-repl.el index b878aa3e..184aa988 100644 --- a/racket-repl.el +++ b/racket-repl.el @@ -954,11 +954,13 @@ see the results." (interactive "r") (unless (region-active-p) (user-error "No region")) + (racket--assert-edit-mode) (racket--send-region-to-repl start end)) (defun racket-send-definition () "Send the current definition to the Racket REPL." (interactive) + (racket--assert-sexp-edit-mode) (save-excursion (end-of-defun) (let ((end (point))) @@ -978,6 +980,7 @@ With a prefix argument (e.g. \\[universal-argument] \\[racket-send-last-sexp]), into the REPL, followed by a \"=>\" line, to distinguish it from the zero or more values to which it evaluates." (interactive "P") + (racket--assert-sexp-edit-mode) (racket--send-region-to-repl (racket--start-of-previous-expression) (point) prefix)) @@ -990,6 +993,7 @@ The eventual results are presented using the variable The expression may be either an at-expression or an s-expression." (interactive) + (racket--assert-sexp-edit-mode) (unless (racket--repl-session-id) (user-error "No REPL session available; run the file first")) (let ((beg (racket--start-of-previous-expression)) diff --git a/racket-stepper.el b/racket-stepper.el index 04bb5afb..b9ce42af 100644 --- a/racket-stepper.el +++ b/racket-stepper.el @@ -86,6 +86,7 @@ Uses Racket's `expand-once` in the namespace from the most recent (interactive "rP") (unless (region-active-p) (user-error "No region")) + (racket--assert-sexp-edit-mode) (racket-stepper--expand-text into-base (lambda () (cons start end)))) @@ -96,6 +97,7 @@ Uses Racket's `expand-once` in the namespace from the most recent Uses Racket's `expand-once` in the namespace from the most recent `racket-run'." (interactive "P") + (racket--assert-sexp-edit-mode) (racket-stepper--expand-text into-base (lambda () (save-excursion @@ -108,6 +110,7 @@ Uses Racket's `expand-once` in the namespace from the most recent Uses Racket's `expand-once` in the namespace from the most recent `racket-run'." (interactive "P") + (racket--assert-sexp-edit-mode) (racket-stepper--expand-text into-base (lambda () (save-excursion diff --git a/racket-util.el b/racket-util.el index 861b363e..8af8abbd 100644 --- a/racket-util.el +++ b/racket-util.el @@ -169,9 +169,18 @@ The \"project\" is determined by trying, in order: (user-error "%S works only in racket-mode or racket-hash-lang-mode edit buffers, or racket-repl-mode buffers" this-command))) -(defun racket--assert-racket-mode () - (unless (derived-mode-p 'racket-mode) - (user-error "%S works only in racket-mode edit buffers" +(defun racket--sexp-edit-mode-p () + "Either `racket-mode' or `racket-hash-lang-mode', provided the +latter has /not/ set the variable `forward-sexp-function' because +the hash-lang uses racket-grouping-position. In other words, when +`forward-sexp-function' is nil we may assume that the lang uses +s-expressions." + (and (racket--edit-mode-p) + (not forward-sexp-function))) + +(defun racket--assert-sexp-edit-mode () + (unless (racket--sexp-edit-mode-p) + (user-error "%S only works in racket-mode, or, racket-hash-lang-mode when the lang uses sexps" this-command))) (provide 'racket-util)