Skip to content

Commit

Permalink
Use macro-debugger stepper for expressions, too
Browse files Browse the repository at this point in the history
Simplify back end implementation.

Allow racket-expand-hiding policy to affect expression expansion, too.
  • Loading branch information
greghendershott committed Jan 24, 2024
1 parent 1dc17e3 commit a931610
Show file tree
Hide file tree
Showing 6 changed files with 154 additions and 158 deletions.
1 change: 1 addition & 0 deletions doc/generate.el
Original file line number Diff line number Diff line change
Expand Up @@ -190,6 +190,7 @@
racket-xp-highlight-unused-regexp
racket-xp-add-binding-faces
racket-documentation-search-location
racket-expand-hiding
"Hash lang variables"
racket-hash-lang-token-face-alist
racket-hash-lang-pairs
Expand Down
32 changes: 30 additions & 2 deletions doc/racket-mode.texi
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,7 @@ General variables
* racket-xp-highlight-unused-regexp::
* racket-xp-add-binding-faces::
* racket-documentation-search-location::
* racket-expand-hiding::
Hash lang variables
Expand Down Expand Up @@ -2816,8 +2817,8 @@ If the file is non-trivial and/or is not compiled to a .zo
bytecode file, then it might take many seconds before the
original form is displayed and you can start stepping.

With @kbd{C-u} also expands syntax from racket/base
-- which can result in very many expansion steps.
With @kbd{C-u} behaves as if @ref{racket-expand-hiding}
were 'disabled.

@node racket-expand-region
@subsection racket-expand-region
Expand All @@ -2829,6 +2830,9 @@ Expand the active region using @ref{racket-stepper-mode}.
Uses Racket's @code{expand-once} in the namespace from the most recent
@ref{racket-run}.

With @kbd{C-u} behaves as if @ref{racket-expand-hiding}
were 'disabled.

@node racket-expand-definition
@subsection racket-expand-definition

Expand All @@ -2839,6 +2843,9 @@ Expand the definition around point using @ref{racket-stepper-mode}.
Uses Racket's @code{expand-once} in the namespace from the most recent
@ref{racket-run}.

With @kbd{C-u} behaves as if @ref{racket-expand-hiding}
were 'disabled.

@node racket-expand-last-sexp
@subsection racket-expand-last-sexp

Expand All @@ -2849,6 +2856,9 @@ Expand the sexp before point using @ref{racket-stepper-mode}.
Uses Racket's @code{expand-once} in the namespace from the most recent
@ref{racket-run}.

With @kbd{C-u} behaves as if @ref{racket-expand-hiding}
were 'disabled.

@node Other
@section Other

Expand Down Expand Up @@ -2982,6 +2992,7 @@ Delete the ``compiled'' directories made by @ref{racket-mode-start-faster}.
* racket-xp-highlight-unused-regexp::
* racket-xp-add-binding-faces::
* racket-documentation-search-location::
* racket-expand-hiding::
@end menu

@node racket-program
Expand Down Expand Up @@ -3140,6 +3151,23 @@ after applying @code{url-hexify-string}. Apart from ``%s'', the
string should be a properly encoded URL@.
@end itemize

@node racket-expand-hiding
@subsection racket-expand-hiding

The macro hiding policy for commands like @ref{racket-expand-file}.

Although any macro-debugger/model/hiding-policies value may be
used, frequently used values include:

@itemize
@item
'standard
@item
'disabled
@item
(list 'custom hide-racket? hide-libs? hide-contracts? hide-phase1? rules)
@end itemize

@node Hash lang variables
@section Hash lang variables

Expand Down
69 changes: 34 additions & 35 deletions racket-stepper.el
Original file line number Diff line number Diff line change
Expand Up @@ -76,25 +76,25 @@ were \\='disabled."
(interactive "P")
(racket--assert-edit-mode)
(racket--save-if-changed)
(racket-stepper--start 'file
(racket--buffer-file-name)
(racket-stepper--start nil
no-hiding))

(defun racket-expand-region (start end &optional no-hiding)
(defun racket-expand-region (&optional no-hiding)
"Expand the active region using `racket-stepper-mode'.
Uses Racket's `expand-once` in the namespace from the most recent
`racket-run'.
With \\[universal-argument] behaves as if `racket-expand-hiding'
were \\='disabled."
(interactive "rP")
(interactive "P")
(unless (region-active-p)
(user-error "No region"))
(racket--assert-sexp-edit-mode)
(racket--assert-edit-mode)
(racket-stepper--expand-text no-hiding
(lambda ()
(cons start end))))
(cons (region-beginning)
(region-end)))))

(defun racket-expand-definition (&optional no-hiding)
"Expand the definition around point using `racket-stepper-mode'.
Expand Down Expand Up @@ -131,8 +131,7 @@ were \\='disabled."
(defun racket-stepper--expand-text (no-hiding get-region)
(pcase (funcall get-region)
(`(,beg . ,end)
(racket-stepper--start 'expr
(buffer-substring-no-properties beg end)
(racket-stepper--start (buffer-substring-no-properties beg end)
no-hiding))))

(defvar racket--stepper-repl-session-id nil
Expand All @@ -141,36 +140,36 @@ were \\='disabled."
May be nil for \"file\" stepping, but must be valid for \"expr\"
stepping.")

(defun racket-stepper--start (which str no-hiding)
(defun racket-stepper--start (expression-str no-hiding)
"Ensure buffer and issue initial command.
WHICH should be \"expr\" or \"file\".
STR should be the expression or pathname."
STR should be the expression or nil for file expansion."
(racket--assert-edit-mode)
(setq racket--stepper-repl-session-id (racket--repl-session-id))
(unless (or racket--stepper-repl-session-id
(eq which 'file))
(error "Only works when the edit buffer has a REPL buffer, and, you should racket-run first"))
;; Create buffer if necessary
(let ((name (racket--stepper-buffer-name)))
(unless (get-buffer name)
(with-current-buffer (get-buffer-create name)
(racket-stepper-mode)))
;; Give it a window if necessary
(unless (get-buffer-window name)
(pop-to-buffer (get-buffer name)))
;; Select the stepper window and insert
(select-window (get-buffer-window name))
(let ((inhibit-read-only t))
(delete-region (point-min) (point-max))
(insert "Starting macro expansion stepper... please wait...\n"))
(racket--cmd/async racket--stepper-repl-session-id
`(macro-stepper (,which . ,(if (eq which 'file)
(racket-file-name-front-to-back str)
str))
,(if no-hiding
'disable
racket-expand-hiding))
#'racket-stepper--insert)))
(unless (or (not expression-str)
racket--stepper-repl-session-id)
(error "Expression expansion only works when the edit buffer has a REPL buffer, and, you should racket-run first"))
(let ((path (racket-file-name-front-to-back (racket--buffer-file-name))))
;; Create buffer if necessary
(let ((name (racket--stepper-buffer-name)))
(unless (get-buffer name)
(with-current-buffer (get-buffer-create name)
(racket-stepper-mode)))
;; Give it a window if necessary
(unless (get-buffer-window name)
(pop-to-buffer (get-buffer name)))
;; Select the stepper window and insert
(select-window (get-buffer-window name))
(let ((inhibit-read-only t))
(delete-region (point-min) (point-max))
(insert "Starting macro expansion stepper... please wait...\n"))
(racket--cmd/async racket--stepper-repl-session-id
`(macro-stepper ,path
,expression-str
,(if no-hiding
'disable
racket-expand-hiding))
#'racket-stepper--insert))))

(defun racket-stepper--insert (nothing-or-steps)
(if (eq nothing-or-steps 'nothing)
Expand Down
2 changes: 1 addition & 1 deletion racket/command-server.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@
[`(no-op) #t]
[`(logger ,v) (channel-put logger-command-channel v)]
[`(check-syntax ,path-str ,code) (check-syntax path-str code)]
[`(macro-stepper ,str ,into-base?) (macro-stepper str into-base?)]
[`(macro-stepper ,path ,str ,pol) (macro-stepper path str pol)]
[`(macro-stepper/next ,what) (macro-stepper/next what)]
[`(module-names) (module-names)]
[`(requires/tidy ,reqs) (requires/tidy reqs)]
Expand Down
89 changes: 30 additions & 59 deletions racket/commands/macro.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -29,50 +29,36 @@
(define step-proc #f)
(define (nothing-step-proc _) 'nothing)

(define/contract (make-expr-stepper str)
(-> string? step-proc/c)
(unless (current-session-id)
(error 'make-expr-stepper "Does not work without a running REPL"))
(define step-num #f)
(define last-stx (string->namespace-syntax str))
(define/contract (step what) step-proc/c
(cond [(not step-num)
(set! step-num 0)
(list (cons 'original
(pretty-format-syntax last-stx)))]
[else
(define result
(let loop ()
(define this-stx (expand-once last-stx))
(cond [(equal? (syntax->datum last-stx)
(syntax->datum this-stx))
(cond [(eq? what 'all)
(list (cons 'final
(pretty-format-syntax this-stx)))]
[else (list)])]
[else
(set! step-num (add1 step-num))
(define step
(cons (~a step-num ": expand-once")
(diff-text (pretty-format-syntax last-stx)
(pretty-format-syntax this-stx)
#:unified 3)))
(set! last-stx this-stx)
(cond [(eq? what 'all) (cons step (loop))]
[else (list step)])])))
(match result
[(list) (list (cons 'final
(pretty-format-syntax last-stx)))]
[v v])]))
step)
(define/contract (macro-stepper path expression-str hiding-policy)
(-> (and/c path-string? complete-path?) any/c any/c
(list/c step/c))
(define-values (stx ns)
(cond
[(string? expression-str)
(unless (current-session-id)
(error 'macro-stepper "Does not work without a running REPL"))
(values (string->namespace-syntax expression-str)
(current-namespace))]
[else
(values (file->syntax path)
(make-base-namespace))]))
(set! step-proc
(make-stepper path stx ns hiding-policy))
(macro-stepper/next 'next))

(define/contract (make-file-stepper path elisp-policy)
(-> (and/c path-string? absolute-path?) any/c step-proc/c)
(assert-file-stepper-works)
(define stx (file->syntax path))
(define/contract (macro-stepper/next what) step-proc/c
(define v (step-proc what))
(match v
[(list (cons 'final _)) (set! step-proc nothing-step-proc)]
[_ (void)])
v)

(define/contract (make-stepper path stx ns elisp-hiding-policy)
(-> (and/c path-string? complete-path?) syntax? namespace? any/c
step-proc/c)
(assert-macro-debugger-stepper-works)
(define dir (path-only path))
(define ns (make-base-namespace))
(define policy (elisp-policy->policy elisp-policy))
(define policy (elisp-policy->policy elisp-hiding-policy))
(define predicate (policy->predicate policy))
(define raw-step (parameterize ([current-load-relative-directory dir]
[current-namespace ns])
Expand Down Expand Up @@ -108,6 +94,7 @@
(list (cons 'final step-last-after))])]))
step)


(define (elisp-policy->policy e)
;; See macro-debugger/model/hiding-policies.rkt):
;;
Expand Down Expand Up @@ -141,28 +128,12 @@
(pretty-format #:mode 'write before)
(pretty-format #:mode 'write after))]))

(define (assert-file-stepper-works)
(define (assert-macro-debugger-stepper-works)
(define step (stepper-text #'(module example racket/base 42)))
(unless (step 'next)
(error 'macro-debugger/stepper-text
"does not work in your version of Racket.\nPlease try an older or newer version.")))

(define/contract (macro-stepper what policy)
(-> (or/c (cons/c 'expr string?) (cons/c 'file path-string?)) any/c
(list/c step/c))
(set! step-proc
(match what
[(cons 'expr str) (make-expr-stepper str)]
[(cons 'file path) (make-file-stepper path policy)]))
(macro-stepper/next 'next))

(define/contract (macro-stepper/next what) step-proc/c
(define v (step-proc what))
(match v
[(list (cons 'final _)) (set! step-proc nothing-step-proc)]
[_ (void)])
v)

(define (diff-text before-text after-text #:unified [-U 3])
(define template "racket-mode-syntax-diff-~a")
(define (make-temporary-file-with-text str)
Expand Down

0 comments on commit a931610

Please sign in to comment.