aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWilfred Hughes2017-12-10 13:34:06 +0000
committerWilfred Hughes2017-12-10 14:52:54 +0000
commitabd18254aec76b26e86ae27e91d2c916ec20cc46 (patch)
tree9d346b42760ea3d0bec8224481d09f16a9df79ad
parentab203e36d5f84a99b6d4b04f1a22ba028be750e3 (diff)
downloademacs-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.el46
-rw-r--r--lisp/help-mode.el45
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