greghendershott / racket-mode

Emacs major and minor modes for Racket: edit, REPL, check-syntax, debug, profile, and more.

Home Page:https://www.racket-mode.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Out of range error in narrowed buffer during redisplay using `racket-xp-mode`

nverno opened this issue · comments

During redisplay there are args-out-of-range errors when the source buffer is narrowed.

Steps to reproduce:

Using the following source with racket-xp-mode enabled, call narrow-to-defun in foo.

#lang racket

(define/contract (foo x)
  (-> string? string?)
  x)

Then, trigger redisplay, eg. modify and save the buffer.

At this point, I get a message

Error running timer: (args-out-of-range 1 53)

Or a backtrace with debug-on-error.

Package

metadata
(#s(package-desc racket-mode (20240301 1714) "Racket editing, REPL, and more"
                 ((emacs (25 1))) nil nil
                 "/home/noah/.emacs.d/elpa/racket-mode-20240301.1714"
                 ((:url . "https://www.racket-mode.com/")
                  (:maintainer "Greg Hendershott")
                  (:maintainers ("Greg Hendershott"))
                  (:authors
                   ("Greg Hendershott" .
                    "racket-mode-author@greghendershott.com"))
                  (:commit . "f803fa1ce5309ae074c12f1294bbbad8baf5a340"))
                 nil))
package-archives
(("melpa" . "https://melpa.org/packages/")
 ("gnu" . "https://elpa.gnu.org/packages/")
 ("nongnu" . "https://elpa.nongnu.org/nongnu/"))
racket--el-source-dir
"/home/noah/.emacs.d/elpa/racket-mode-20240301.1714/"
racket--rkt-source-dir
"/home/noah/.emacs.d/elpa/racket-mode-20240301.1714/racket/"

System values

emacs-version
"30.0.50"
major-mode
help-mode
system-type
gnu/linux
x-gtk-use-system-tooltips
t
display-graphic-p
t

Buffer values

after-change-functions
nil
before-change-functions
nil
completion-at-point-functions
(tags-completion-at-point-function)
eldoc-documentation-function
eldoc-documentation-default
font-lock-defaults
nil
pre-command-hook
(company-pre-command t)
post-command-hook
(company-post-command t)
post-self-insert-hook
(electric-indent-post-self-insert-function blink-paren-post-self-insert-function)
xref-backend-functions
(etags--xref-backend)

Racket Mode values

racket--cmd-open-p
t
racket-after-run-hook
nil
racket-back-end-configurations
((:directory "/" :racket-program nil :remote-source-dir nil
             :restart-watch-directories nil :windows nil))
racket-before-run-hook
(racket-ansi-color-context-reset)
racket-browse-url-function
browse-url
racket-command-timeout
10
racket-documentation-search-location
"https://docs.racket-lang.org/search/index.html?q=%s"
racket-error-context
medium
racket-expand-hiding
standard
racket-hash-lang-mode-hook
nil
racket-hash-lang-module-language-hook
nil
racket-hash-lang-token-face-alist
((constant . font-lock-constant-face) (error . error)
 (other . font-lock-doc-face) (keyword . font-lock-keyword-face)
 (hash-colon-keyword . racket-keyword-argument-face) (at . font-lock-doc-face))
racket-history-filter-regexp
"\\`\\s *\\'"
racket-imagemagick-props
nil
racket-images-inline
t
racket-images-keep-last
100
racket-images-system-viewer
"display"
racket-indent-curly-as-sequence
t
racket-indent-sequence-depth
0
racket-logger-config
((cm-accomplice . warning) (GC . info) (module-prefetch . warning)
 (optimizer . info) (racket/contract . error) (racket-mode-debugger . info)
 (sequence-specialization . info) (* . fatal))
racket-memory-limit
2048
racket-mode-hook
(nvp-racket-hook)
racket-module-forms
"\\s(\\(?:module[*+]?\\|library\\)"
racket-pretty-lambda
nil
racket-pretty-print
t
racket-program
"racket"
racket-repl-buffer-name-function
nil
racket-repl-command-file
"/home/noah/.emacs.d/racket-mode/repl.rkt"
racket-repl-history-directory
"/home/noah/.emacs.d/cache/"
racket-repl-mode-hook
(nvp-racket-repl-hook)
racket-sexp-comment-fade
0.5
racket-shell-or-terminal-function
racket-shell
racket-show-functions
(racket-show-pseudo-tooltip)
racket-smart-open-bracket-enable
nil
racket-submodules-to-run
((test) (main))
racket-use-repl-submit-predicate
nil
racket-xp-add-binding-faces
nil
racket-xp-after-change-refresh-delay
1
racket-xp-highlight-unused-regexp
"^[^_]"
racket-xp-mode-lighter
(:eval (racket--xp-mode-lighter))

Minor modes

enabled
((abbrev-mode) (auto-composition-mode) (auto-compression-mode)
 (auto-encryption-mode) (buffer-read-only) (column-number-mode) (company-mode)
 (company-quickhelp-local-mode) (company-quickhelp-mode)
 (company-statistics-mode) (delete-selection-mode) (electric-indent-mode)
 (file-name-shadow-mode) (font-lock-mode) (global-auto-revert-mode)
 (global-company-mode) (global-eldoc-mode) (global-font-lock-mode)
 (global-prettify-symbols-mode) (global-subword-mode) (isearch-fold-quotes-mode)
 (line-number-mode) (menu-bar-mode) (minibuffer-regexp-mode) (mouse-wheel-mode)
 (nvp-treesit-mode) (recentf-mode) (repeat-mode) (save-place-mode)
 (savehist-mode) (semantic-minor-modes-format) (server-mode) (show-paren-mode)
 (smartparens-global-mode) (smooth-scrolling-mode) (subword-mode)
 (transient-mark-mode) (treesit-inspect-mode) (vertico-mode) (windmove-mode)
 (winner-mode))
Disabled minor modes
disabled
((2C-mode) (ace-window-display-mode) (ace-window-mode) (anaconda-eldoc-mode)
 (anaconda-mode) (auto-compile-mode) (auto-compile-on-load-mode)
 (auto-compile-on-save-mode) (auto-fill-function) (auto-fill-mode)
 (auto-revert-mode) (auto-revert-tail-mode) (auto-save-mode)
 (auto-save-visited-mode) (avy-linum-mode) (blink-cursor-mode)
 (buffer-face-mode) (button-mode) (ccls-code-lens-mode)
 (cl-old-struct-compat-mode) (comint-fontify-input-mode) (company-search-mode)
 (compilation-minor-mode) (compilation-shell-minor-mode)
 (completion-in-region-mode) (consult-preview-at-point-mode) (context-menu-mode)
 (cursor-face-highlight-mode) (cursor-intangible-mode) (cursor-sensor-mode)
 (dash-fontify-mode) (defining-kbd-macro) (diff-auto-refine-mode)
 (diff-minor-mode) (dired-click-to-select-mode) (dired-hide-details-mode)
 (dired-isearch-filenames-mode) (display-line-numbers-mode) (display-time-mode)
 (doc-view-minor-mode) (doc-view-presentation-mode) (edebug-backtrace-mode)
 (edebug-mode) (eldoc-mode) (electric-layout-mode) (electric-pair-mode)
 (electric-quote-mode) (flycheck-mode) (flymake-mode) (geiser-autodoc-mode)
 (geiser-repl-autoeval-mode) (geiser-repl-superparen-mode)
 (geiser-smart-tab-mode) (global-dash-fontify-mode)
 (global-display-line-numbers-mode) (global-flycheck-mode) (global-hl-line-mode)
 (global-robe-mode) (global-semantic-highlight-edits-mode)
 (global-semantic-highlight-func-mode) (global-semantic-show-parser-state-mode)
 (global-semantic-show-unmatched-syntax-mode) (global-semantic-stickyfunc-mode)
 (global-superword-mode) (global-visual-line-mode) (gnus-dead-summary-mode)
 (gnus-undo-mode) (gorepl-minor-mode) (header-line-indent-mode)
 (highlight-quoted-mode) (hl-line-mode) (horizontal-scroll-bar-mode)
 (hs-minor-mode) (html-autoview-mode) (iedit-mode) (image-minor-mode)
 (indent-tabs-mode) (inf-ruby-minor-mode) (isearch-mode) (jit-lock-debug-mode)
 (leetcode--loading-mode) (leetcode-solution-mode) (lock-file-mode)
 (lost-selection-mode) (lsp-completion-mode) (lsp-diagnostics-mode)
 (lsp-headerline-breadcrumb-mode) (lsp-inlay-hints-mode)
 (lsp-installation-buffer-mode) (lsp-kotlin-lens-mode) (lsp-lens-mode)
 (lsp-managed-mode) (lsp-mode) (lsp-modeline-code-actions-mode)
 (lsp-modeline-diagnostics-mode) (lsp-modeline-workspace-status-mode)
 (lsp-semantic-tokens-mode) (lsp-signature-mode) (lsp-terraform-modules-mode)
 (macrostep-mode) (mail-abbrevs-mode) (markdown-live-preview-mode)
 (mc-hide-unmatched-lines-mode) (mml-mode) (modern-c++-font-lock-global-mode)
 (modern-c++-font-lock-mode) (modifier-bar-mode) (multiple-cursors-mode)
 (next-error-follow-minor-mode) (nvp-imenu-completion-mode)
 (nvp-leet-indirect-minor-mode) (nvp-leet-minor-mode) (nvp-leet-result-mode)
 (nvp-override-mode) (nvp-repl-minor-mode) (nvp-repl-source-minor-mode)
 (nvp-scratch-minor-mode) (nvp-trace-minor-mode) (nvp-treesit-minor-mode)
 (org-bullets-mode) (org-cdlatex-mode) (org-indent-mode)
 (org-list-checkbox-radio-mode) (org-noter-doc-mode) (org-noter-notes-mode)
 (org-src-mode) (org-table-follow-field-mode) (org-table-header-line-mode)
 (orgtbl-mode) (outline-minor-mode) (overwrite-mode)
 (paragraph-indent-minor-mode) (paredit-mode) (pdf-cache-prefetch-minor-mode)
 (pdf-misc-context-menu-minor-mode) (pdf-misc-menu-bar-minor-mode)
 (pdf-misc-minor-mode) (pdf-misc-size-indication-minor-mode)
 (pdf-view-auto-slice-minor-mode) (pdf-view-dark-minor-mode)
 (pdf-view-midnight-minor-mode) (pdf-view-printer-minor-mode)
 (pdf-view-themed-minor-mode) (prettify-symbols-mode)
 (racket-hash-lang-repl-mode) (racket-smart-open-bracket-mode) (racket-xp-mode)
 (read-extended-command-mode) (read-passwd-mode) (rectangle-mark-mode)
 (rectangular-region-mode) (robe-mode) (rspec-dired-mode) (rspec-mode)
 (rspec-verifiable-mode) (rustic-doc-mode) (semantic-highlight-edits-mode)
 (semantic-highlight-func-mode) (semantic-mode)
 (semantic-show-parser-state-mode) (semantic-show-unmatched-syntax-mode)
 (semantic-stickyfunc-mode) (sgml-electric-tag-pair-mode)
 (sh-electric-here-document-mode) (shell-dirtrack-mode)
 (shell-highlight-undef-mode) (show-smartparens-global-mode)
 (show-smartparens-mode) (size-indication-mode) (smartparens-global-strict-mode)
 (smartparens-mode) (smartparens-strict-mode) (superword-mode)
 (tab-bar-history-mode) (tab-bar-mode) (tablist-edit-column-minor-mode)
 (tablist-minor-mode) (temp-buffer-resize-mode) (text-scale-mode)
 (tool-bar-mode) (tooltip-mode) (transient-resume-mode) (treesit-explore-mode)
 (undelete-frame-mode) (url-handler-mode) (use-hard-newlines) (vc-dir-git-mode)
 (view-mode) (visible-mode) (visual-line-mode) (window-divider-mode)
 (xref-etags-mode) (yard-mode) (yas-global-mode) (yas-minor-mode))

Thanks for the report. It looks like there are a few issues related to narrowing.

  1. The one you reported.

    Fix: Temporarily widen before applying text properties.

  2. Even if that's fixed, the narrowed text is a program fragment that check-syntax will complain isn't valid Racket, e.g. say there's an #%app is undefined error.

    Fix: Always give check-syntax the full buffer, i.e. ignore any narrowing.

  3. What if you have narrowed to foo, have point on bar in the program below and press M-. a.k.a. M-x xref-find-definitions. Status quo that's another range error.

    Fix: ?? Instead should it widen -- discard your narrowing, so it can actually go to and show you bar? I think so, but I don't use use narrowing enough to know what's expected or best practice, so I'm curious what you think?

#lang racket

(define/contract (foo x)
  (-> string? string?)
  (bar x)) ;;;;;;;;;; <==== point on `bar` here

(define (bar x)
  x)

What if you have narrowed to foo, have point on bar in the program below and press M-. a.k.a. M-x xref-find-definitions. Status quo that's another range error.

I think this should be covered since you're using xref. The function xref--goto-char handles potential narrowing by consulting the variable widen-automatically, widening when permitted.

Hmm I saw it error in Emacs 28.2 (daily driver). Maybe this improved in 30. I can try build from source.

In any case, maybe it's fair to classify that as "not my problem to fix", instead that's up to xref, and it may in fact have improved this sometime after 28.2?

Oh you're right it does error on emacs 30 as well. I thought you were asking about how to handle the widening more generally. The following patch seems to fix the xref problem, letting xref decide whether to allow it or not depending on widen-automatically

=diff --git a/racket-xp.el b/racket-xp.el
index fc4c43b..9f32778 100644
--- a/racket-xp.el
+++ b/racket-xp.el
@@ -1084,9 +1084,11 @@ around at the first and last errors."
    (pcase (get-text-property 0 'racket-xp-use str)
      (`(,beg ,end)
       (list
-       (xref-make (buffer-substring beg end)
-                  (xref-make-buffer-location (current-buffer)
-                                             (marker-position beg))))))
+       (save-restriction
+         (widen)
+         (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 . ,_)
>

Thanks for the idea for xref!

Commit 483a1e7 seems to cover all the bases -- but just in my quick testing; so if it's convenient for you to try it, please let me know?

Otherwise I'll sleep on it, try to test a bit more myself, and merge within a few days.

It's working perfectly!

Merged; thanks for confirming, as well as for the xref idea!