Skip to content

Commit

Permalink
Various fixes
Browse files Browse the repository at this point in the history
- Make it consistent that both pdb and the built-in check-syntax do
/not/ return a symbol for a definition site. Instead the front end can
use the coordinates to retrieve a string from the buffer as/when
needed.

- Make visiting modules work, not just for require forms, but also for
hash-lang lines. (I noticed this didn't work, when testing the
previous change, then realized it hadn't worked even before the
change.)

- Provide a better prompt for the rename command (show number of sites
and number of files that would be changed).
  • Loading branch information
greghendershott committed Mar 21, 2023
1 parent c58453c commit e8b6fc9
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 34 deletions.
13 changes: 13 additions & 0 deletions racket-util.el
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,19 @@ The \"project\" is determined by trying, in order:
(cdr (project-current nil dir)))
dir)))

(defun racket--property-bounds (pos prop)
(when-let (val (get-text-property pos prop))
(let* ((prev-pos (previous-single-property-change pos prop))
(prev-val (get-text-property prev-pos prop))
(next-pos (next-single-property-change pos prop))
(next-val (get-text-property (- next-pos 1) prop)))
(cons (if (equal val prev-val)
prev-pos
pos) ;pos is first char having prop val
(if (equal val next-val)
next-pos
pos))))) ;pos is last char having prop val

(provide 'racket-util)

;; racket-util.el ends here
19 changes: 17 additions & 2 deletions racket-visit.el
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,8 @@ The returned string has text properties:
\"racket-xp-def\" property if any from the buffer is applied to
the ENTIRE returned string. That way the caller can simply use
an index of 0 for `get-text-property'."
(when (racket--in-require-form-p)
(cond
((racket--in-require-form-p)
(save-excursion
(condition-case ()
(progn
Expand Down Expand Up @@ -62,7 +63,21 @@ The returned string has text properties:
(if relative-p 'relative 'absolute)
'racket-xp-def
(get-text-property 0 'racket-xp-def str)))))))
(scan-error nil)))))
(scan-error nil))))
;; An absolute modpath in a #lang line?
(t
(save-excursion
(condition-case ()
(progn
(forward-sexp 1)
(backward-sexp 1)
(when-let (mod (thing-at-point 'symbol t))
(forward-line 0)
(when (looking-at-p "#lang ")
(propertize mod
'racket-module-path
'absolute))))
(scan-error nil))))))

(defun racket--rkt-or-ss-path (path)
"Handle the situation of #575 where .rkt doesn't exist but .ss does."
Expand Down
69 changes: 41 additions & 28 deletions racket-xp.el
Original file line number Diff line number Diff line change
Expand Up @@ -456,7 +456,7 @@ or `racket-repl-describe'."
(racket--remove-overlays-in-buffer racket-xp-def-face
racket-xp-use-face)
(pcase def
(`(,kind ,_id ,(and uses `((,beg ,_end) . ,_)))
(`(,kind ,(and uses `((,beg ,_end) . ,_)))
(when (or (eq kind 'local)
racket-xp-highlight-imports-p)
(pcase (get-text-property beg 'racket-xp-use)
Expand All @@ -469,7 +469,7 @@ or `racket-repl-describe'."
(pcase use
(`(,def-beg ,def-end)
(pcase (get-text-property def-beg 'racket-xp-def)
(`(,kind ,_id ,uses)
(`(,kind ,uses)
(when (or (eq kind 'local)
racket-xp-highlight-imports-p)
(racket--add-overlay def-beg def-end racket-xp-def-face)
Expand Down Expand Up @@ -555,7 +555,7 @@ If point is instead on a definition, then go to its first use."
(pcase (get-text-property (point) 'racket-xp-use)
(`(,beg ,_end)
(pcase (get-text-property beg 'racket-xp-def)
(`(,_kind ,_id ,uses)
(`(,_kind ,uses)
(let* ((ix-this (seq-position uses (point)
(lambda (use pt)
(pcase use
Expand All @@ -568,7 +568,7 @@ If point is instead on a definition, then go to its first use."
(next (nth ix-next uses)))
(goto-char (car next))))))
(_ (pcase (get-text-property (point) 'racket-xp-def)
(`(,_kind ,_id ((,beg ,_end) . ,_)) (goto-char beg))))))
(`(,_kind ((,beg ,_end) . ,_)) (goto-char beg))))))

(defun racket-xp-next-use ()
"When point is on a use, go to the next, sibling use."
Expand All @@ -587,16 +587,15 @@ When pdb is available and finds rename sites, does a multi-file rename.
Otherwise does a rename only within the current file."
(interactive)
(let ((files-and-sites (racket--cmd/await nil
`(pdb-rename-sites
,(racket-file-name-front-to-back
(racket--buffer-file-name))
,(point)))))
(if files-and-sites
(racket-xp-rename-global files-and-sites)
(racket-xp-rename-local))))

(defun racket-xp-rename-local ()
(if-let (v (racket--cmd/await nil
`(pdb-rename-sites
,(racket-file-name-front-to-back
(racket--buffer-file-name))
,(point))))
(racket--xp-rename-global v)
(racket--xp-rename-local)))

(defun racket--xp-rename-local ()
(pcase-let*
(;; Try to get a def prop and a use prop at point
(def-prop (get-text-property (point) 'racket-xp-def))
Expand All @@ -605,17 +604,18 @@ Otherwise does a rename only within the current file."
(user-error "Not a definition or use")))
;; OK, we have one of the props. Use it to get the the other one.
(uses-prop (or uses-prop
(pcase-let ((`(,_kind ,_id ((,beg ,_end) . ,_)) def-prop))
(pcase-let ((`(,_kind ((,beg ,_end) . ,_)) def-prop))
(get-text-property beg 'racket-xp-use))))
(def-prop (or def-prop
(pcase-let ((`(,beg ,_end) uses-prop))
(get-text-property beg 'racket-xp-def))))
(`(,kind ,old-id ,uses-locs) def-prop)
(`(,kind ,uses-locs) def-prop)
(_ (unless (eq kind 'local)
(user-error "Can only rename local definitions, not imports")))
(old-id (racket--xp-def-or-use-name-at-point))
(def-loc uses-prop)
(locs (cons def-loc uses-locs))
(new-id (read-from-minibuffer (format "Rename %s to: " old-id)))
(new-id (read-from-minibuffer (format "Rename `%s' to: " old-id)))
(marker-pairs (mapcar (lambda (loc)
(let ((beg (make-marker))
(end (make-marker)))
Expand All @@ -637,9 +637,20 @@ Otherwise does a rename only within the current file."
(goto-char (marker-position point-marker))
(racket-xp-annotate)))

(defun racket-xp-rename-global (files-and-sites)
(let* ((new-id (read-from-minibuffer (format "Rename sites in %s file(s) to: "
(length files-and-sites)))))
(defun racket--xp-rename-global (files-and-sites)
(pcase-let*
((`(,num-files . ,num-sites)
(seq-reduce (lambda (ns file-and-sites)
(cons (+ (car ns) 1)
(+ (cdr ns) (length (cdr file-and-sites)))))
files-and-sites
(cons 0 0)))
(old-id (racket--xp-def-or-use-name-at-point))
(new-id (read-from-minibuffer (format "Rename `%s' at %s sites in %s file%s to: "
old-id
num-sites
num-files
(if (= num-files 1) "" "s")))))
(dolist (file-and-sites files-and-sites)
(let ((file (car file-and-sites))
(sites (cdr file-and-sites)))
Expand Down Expand Up @@ -672,6 +683,12 @@ Otherwise does a rename only within the current file."
(with-current-buffer (save-selected-window (find-file file))
(when racket-xp-mode (racket-xp-annotate)))))))

(defun racket--xp-def-or-use-name-at-point ()
(seq-some (lambda (prop)
(when-let (bounds (racket--property-bounds (point) prop))
(buffer-substring-no-properties (car bounds) (cdr bounds))))
'(racket-xp-use racket-xp-def)))

(defun racket--xp-forward-prop (prop amt)
"Move point to the next or previous occurrence of PROP, if any.
If moved, return the new position, else nil."
Expand Down Expand Up @@ -863,10 +880,6 @@ evaluation errors that won't be found merely from expansion -- or
(xref-make (buffer-substring beg end)
(xref-make-buffer-location (current-buffer)
(marker-position beg))))))
;; Annotated by dr/cs as imported module; visit the module
(pcase (get-text-property 0 'racket-xp-def str)
(`(import ,id . ,_)
(xref-backend-definitions 'racket-xref-module id)))
;; Something that, for whatever reason, drracket/check-syntax did
;; not annotate.
(pcase (racket--cmd/await nil `(def ,(racket-file-name-front-to-back
Expand All @@ -893,7 +906,7 @@ evaluation errors that won't be found merely from expansion -- or
;; Otherwise, we're out of luck because there exists no datbase of
;; references project-wide.
(or (pcase (get-text-property 0 'racket-xp-def str)
(`(,_any-kind ,_def ,uses)
(`(,_any-kind ,uses)
(mapcar (lambda (use)
(pcase-let ((`(,beg ,end) use))
(xref-make
Expand Down Expand Up @@ -1071,7 +1084,7 @@ manually."
(list 'racket-xp-doc
(list (racket-file-name-back-to-front path) anchor))))
;; old/classic check-syntax
(`(def/uses ,def-beg ,def-end ,req ,id ,uses)
(`(def/uses ,def-beg ,def-end ,req ,uses)
(let ((def-beg (copy-marker def-beg t))
(def-end (copy-marker def-end t))
(uses (mapcar (lambda (use)
Expand All @@ -1081,7 +1094,7 @@ manually."
uses)))
(put-text-property (marker-position def-beg)
(marker-position def-end)
'racket-xp-def (list req id uses))
'racket-xp-def (list req uses))
(dolist (use uses)
(pcase-let* ((`(,use-beg ,use-end) use))
(put-text-property (marker-position use-beg)
Expand Down Expand Up @@ -1119,7 +1132,7 @@ manually."
(put-text-property (marker-position def-beg)
(marker-position def-end)
'racket-xp-def
(list (if import-p 'import 'local) "" uses))))
(list (if import-p 'import 'local) uses))))
(`(use-site ,use-beg ,use-end ,import-p ,def-beg ,def-end)
(let ((def-beg (copy-marker def-beg t))
(def-end (copy-marker def-end t))
Expand Down
7 changes: 3 additions & 4 deletions racket/commands/check-syntax.rkt
Original file line number Diff line number Diff line change
Expand Up @@ -220,8 +220,7 @@
;; with one item per definition. The key is the definition position.
;; The value is the set of its uses' positions.
(hash-update! ht-defs/uses
(list (substring code-str def-beg def-end)
(match require-arrow?
(list (match require-arrow?
['module-lang 'module-lang]
[#t 'import]
[#f 'local])
Expand Down Expand Up @@ -355,10 +354,10 @@
(define defs/uses
(with-time/log 'defs/uses
(for/list ([(def uses) (in-hash ht-defs/uses)])
(match-define (list sym req def-beg def-end) def)
(match-define (list req def-beg def-end) def)
(list 'def/uses
def-beg def-end
req sym
req
(sort (set->list uses) < #:key car)))))
(define targets/tails
(for/list ([(target tails) (in-hash ht-tails)])
Expand Down

0 comments on commit e8b6fc9

Please sign in to comment.