diff options
| author | Wilfred Hughes | 2017-12-10 13:34:06 +0000 |
|---|---|---|
| committer | Wilfred Hughes | 2017-12-10 14:52:54 +0000 |
| commit | abd18254aec76b26e86ae27e91d2c916ec20cc46 (patch) | |
| tree | 9d346b42760ea3d0bec8224481d09f16a9df79ad | |
| parent | ab203e36d5f84a99b6d4b04f1a22ba028be750e3 (diff) | |
| download | emacs-abd18254aec76b26e86ae27e91d2c916ec20cc46.tar.gz emacs-abd18254aec76b26e86ae27e91d2c916ec20cc46.zip | |
Ensure that we can find definitions when buffer is narrowed
find-function-search-for-symbol will reuse the existing buffer if
we've already opened the file that contains this symbol. However, if
the user has narrowed that buffer, we can't find definitions outside
the narrowed area.
Instead, search the whole file to find definitions, and teach the help
buttons to widen if necessary.
* lisp/emacs-lisp/find-func.el (find-function-search-for-symbol):
Search the whole buffer for the target symbol.
* lisp/help-mode.el: Help buttons now widen the target buffer, if
narrowing is in effect and the target position is not in that range.
| -rw-r--r-- | lisp/emacs-lisp/find-func.el | 46 | ||||
| -rw-r--r-- | lisp/help-mode.el | 45 |
2 files changed, 56 insertions, 35 deletions
diff --git a/lisp/emacs-lisp/find-func.el b/lisp/emacs-lisp/find-func.el index 29c42f36938..84cc8bc9b72 100644 --- a/lisp/emacs-lisp/find-func.el +++ b/lisp/emacs-lisp/find-func.el | |||
| @@ -368,28 +368,30 @@ The search is done in the source for library LIBRARY." | |||
| 368 | (concat "\\\\?" | 368 | (concat "\\\\?" |
| 369 | (regexp-quote (symbol-name symbol)))))) | 369 | (regexp-quote (symbol-name symbol)))))) |
| 370 | (case-fold-search)) | 370 | (case-fold-search)) |
| 371 | (with-syntax-table emacs-lisp-mode-syntax-table | 371 | (save-restriction |
| 372 | (goto-char (point-min)) | 372 | (widen) |
| 373 | (if (if (functionp regexp) | 373 | (with-syntax-table emacs-lisp-mode-syntax-table |
| 374 | (funcall regexp symbol) | 374 | (goto-char (point-min)) |
| 375 | (or (re-search-forward regexp nil t) | 375 | (if (if (functionp regexp) |
| 376 | ;; `regexp' matches definitions using known forms like | 376 | (funcall regexp symbol) |
| 377 | ;; `defun', or `defvar'. But some functions/variables | 377 | (or (re-search-forward regexp nil t) |
| 378 | ;; are defined using special macros (or functions), so | 378 | ;; `regexp' matches definitions using known forms like |
| 379 | ;; if `regexp' can't find the definition, we look for | 379 | ;; `defun', or `defvar'. But some functions/variables |
| 380 | ;; something of the form "(SOMETHING <symbol> ...)". | 380 | ;; are defined using special macros (or functions), so |
| 381 | ;; This fails to distinguish function definitions from | 381 | ;; if `regexp' can't find the definition, we look for |
| 382 | ;; variable declarations (or even uses thereof), but is | 382 | ;; something of the form "(SOMETHING <symbol> ...)". |
| 383 | ;; a good pragmatic fallback. | 383 | ;; This fails to distinguish function definitions from |
| 384 | (re-search-forward | 384 | ;; variable declarations (or even uses thereof), but is |
| 385 | (concat "^([^ ]+" find-function-space-re "['(]?" | 385 | ;; a good pragmatic fallback. |
| 386 | (regexp-quote (symbol-name symbol)) | 386 | (re-search-forward |
| 387 | "\\_>") | 387 | (concat "^([^ ]+" find-function-space-re "['(]?" |
| 388 | nil t))) | 388 | (regexp-quote (symbol-name symbol)) |
| 389 | (progn | 389 | "\\_>") |
| 390 | (beginning-of-line) | 390 | nil t))) |
| 391 | (cons (current-buffer) (point))) | 391 | (progn |
| 392 | (cons (current-buffer) nil)))))))) | 392 | (beginning-of-line) |
| 393 | (cons (current-buffer) (point))) | ||
| 394 | (cons (current-buffer) nil))))))))) | ||
| 393 | 395 | ||
| 394 | (defun find-function-library (function &optional lisp-only verbose) | 396 | (defun find-function-library (function &optional lisp-only verbose) |
| 395 | "Return the pair (ORIG-FUNCTION . LIBRARY) for FUNCTION. | 397 | "Return the pair (ORIG-FUNCTION . LIBRARY) for FUNCTION. |
diff --git a/lisp/help-mode.el b/lisp/help-mode.el index 8bafa46aa97..1e1ae1126ca 100644 --- a/lisp/help-mode.el +++ b/lisp/help-mode.el | |||
| @@ -203,12 +203,18 @@ The format is (FUNCTION ARGS...).") | |||
| 203 | (help-C-file-name (indirect-function fun) 'fun))) | 203 | (help-C-file-name (indirect-function fun) 'fun))) |
| 204 | ;; Don't use find-function-noselect because it follows | 204 | ;; Don't use find-function-noselect because it follows |
| 205 | ;; aliases (which fails for built-in functions). | 205 | ;; aliases (which fails for built-in functions). |
| 206 | (let ((location | 206 | (let* ((location |
| 207 | (find-function-search-for-symbol fun type file))) | 207 | (find-function-search-for-symbol fun type file)) |
| 208 | (position (cdr location))) | ||
| 208 | (pop-to-buffer (car location)) | 209 | (pop-to-buffer (car location)) |
| 209 | (run-hooks 'find-function-after-hook) | 210 | (run-hooks 'find-function-after-hook) |
| 210 | (if (cdr location) | 211 | (if position |
| 211 | (goto-char (cdr location)) | 212 | (progn |
| 213 | ;; Widen the buffer if necessary to go to this position. | ||
| 214 | (when (or (< position (point-min)) | ||
| 215 | (> position (point-max))) | ||
| 216 | (widen)) | ||
| 217 | (goto-char position)) | ||
| 212 | (message "Unable to find location in file"))))) | 218 | (message "Unable to find location in file"))))) |
| 213 | 'help-echo (purecopy "mouse-2, RET: find function's definition")) | 219 | 'help-echo (purecopy "mouse-2, RET: find function's definition")) |
| 214 | 220 | ||
| @@ -219,6 +225,7 @@ The format is (FUNCTION ARGS...).") | |||
| 219 | (if (and file (file-readable-p file)) | 225 | (if (and file (file-readable-p file)) |
| 220 | (progn | 226 | (progn |
| 221 | (pop-to-buffer (find-file-noselect file)) | 227 | (pop-to-buffer (find-file-noselect file)) |
| 228 | (widen) | ||
| 222 | (goto-char (point-min)) | 229 | (goto-char (point-min)) |
| 223 | (if (re-search-forward | 230 | (if (re-search-forward |
| 224 | (format "^[ \t]*(\\(cl-\\)?define-compiler-macro[ \t]+%s" | 231 | (format "^[ \t]*(\\(cl-\\)?define-compiler-macro[ \t]+%s" |
| @@ -234,12 +241,18 @@ The format is (FUNCTION ARGS...).") | |||
| 234 | 'help-function (lambda (var &optional file) | 241 | 'help-function (lambda (var &optional file) |
| 235 | (when (eq file 'C-source) | 242 | (when (eq file 'C-source) |
| 236 | (setq file (help-C-file-name var 'var))) | 243 | (setq file (help-C-file-name var 'var))) |
| 237 | (let ((location (find-variable-noselect var file))) | 244 | (let* ((location (find-variable-noselect var file)) |
| 245 | (position (cdr location))) | ||
| 238 | (pop-to-buffer (car location)) | 246 | (pop-to-buffer (car location)) |
| 239 | (run-hooks 'find-function-after-hook) | 247 | (run-hooks 'find-function-after-hook) |
| 240 | (if (cdr location) | 248 | (if position |
| 241 | (goto-char (cdr location)) | 249 | (progn |
| 242 | (message "Unable to find location in file")))) | 250 | ;; Widen the buffer if necessary to go to this position. |
| 251 | (when (or (< position (point-min)) | ||
| 252 | (> position (point-max))) | ||
| 253 | (widen)) | ||
| 254 | (goto-char position)) | ||
| 255 | (message "Unable to find location in file")))) | ||
| 243 | 'help-echo (purecopy "mouse-2, RET: find variable's definition")) | 256 | 'help-echo (purecopy "mouse-2, RET: find variable's definition")) |
| 244 | 257 | ||
| 245 | (define-button-type 'help-face-def | 258 | (define-button-type 'help-face-def |
| @@ -248,12 +261,18 @@ The format is (FUNCTION ARGS...).") | |||
| 248 | (require 'find-func) | 261 | (require 'find-func) |
| 249 | ;; Don't use find-function-noselect because it follows | 262 | ;; Don't use find-function-noselect because it follows |
| 250 | ;; aliases (which fails for built-in functions). | 263 | ;; aliases (which fails for built-in functions). |
| 251 | (let ((location | 264 | (let* ((location |
| 252 | (find-function-search-for-symbol fun 'defface file))) | 265 | (find-function-search-for-symbol fun 'defface file)) |
| 266 | (position (cdr location))) | ||
| 253 | (pop-to-buffer (car location)) | 267 | (pop-to-buffer (car location)) |
| 254 | (if (cdr location) | 268 | (if position |
| 255 | (goto-char (cdr location)) | 269 | (progn |
| 256 | (message "Unable to find location in file")))) | 270 | ;; Widen the buffer if necessary to go to this position. |
| 271 | (when (or (< position (point-min)) | ||
| 272 | (> position (point-max))) | ||
| 273 | (widen)) | ||
| 274 | (goto-char position)) | ||
| 275 | (message "Unable to find location in file")))) | ||
| 257 | 'help-echo (purecopy "mouse-2, RET: find face's definition")) | 276 | 'help-echo (purecopy "mouse-2, RET: find face's definition")) |
| 258 | 277 | ||
| 259 | (define-button-type 'help-package | 278 | (define-button-type 'help-package |