* lisp/progmodes/hideshow.el: Simplify mouse binding; Use lexical-binding

(hs-set-up-overlay, hs-adjust-block-beginning): Use non-nil default for
function variables, so `add-function` can be used on them.
(hs-toggle-hiding): Make it work for mouse bindings as well.
(hs-minor-mode-map): Use it for the mouse binding.
(hs-grok-mode-type): Use bound-and-true-p.
(hs-life-goes-on): Use `declare` for the debug spec.
(hs-mouse-toggle-hiding): Make it an obsolete alias.
This commit is contained in:
Stefan Monnier 2019-05-19 09:36:22 -04:00
parent 9199643ab2
commit d0e9113de9

View file

@ -1,4 +1,4 @@
;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks ;;; hideshow.el --- minor mode cmds to selectively display code/comment blocks -*- lexical-binding:t -*-
;; Copyright (C) 1994-2019 Free Software Foundation, Inc. ;; Copyright (C) 1994-2019 Free Software Foundation, Inc.
@ -37,7 +37,7 @@
;; hs-show-all C-c @ C-M-s ;; hs-show-all C-c @ C-M-s
;; hs-hide-level C-c @ C-l ;; hs-hide-level C-c @ C-l
;; hs-toggle-hiding C-c @ C-c ;; hs-toggle-hiding C-c @ C-c
;; hs-mouse-toggle-hiding [(shift mouse-2)] ;; hs-toggle-hiding [(shift mouse-2)]
;; hs-hide-initial-comment-block ;; hs-hide-initial-comment-block
;; ;;
;; Blocks are defined per mode. In c-mode, c++-mode and java-mode, they ;; Blocks are defined per mode. In c-mode, c++-mode and java-mode, they
@ -55,8 +55,7 @@
;; Then, add the following to your init file: ;; Then, add the following to your init file:
;; ;;
;; (load-library "hideshow") ;; (load-library "hideshow")
;; (add-hook 'X-mode-hook ; other modes similarly ;; (add-hook 'X-mode-hook #'hs-minor-mode) ; other modes similarly
;; (lambda () (hs-minor-mode 1)))
;; ;;
;; where X = {emacs-lisp,c,c++,perl,...}. You can also manually toggle ;; where X = {emacs-lisp,c,c++,perl,...}. You can also manually toggle
;; hideshow minor mode by typing `M-x hs-minor-mode'. After hideshow is ;; hideshow minor mode by typing `M-x hs-minor-mode'. After hideshow is
@ -181,8 +180,8 @@
;; (5) Hideshow interacts badly with Ediff and `vc-diff'. At the moment, the ;; (5) Hideshow interacts badly with Ediff and `vc-diff'. At the moment, the
;; suggested workaround is to turn off hideshow entirely, for example: ;; suggested workaround is to turn off hideshow entirely, for example:
;; ;;
;; (add-hook 'ediff-prepare-buffer-hook 'turn-off-hideshow) ;; (add-hook 'ediff-prepare-buffer-hook #'turn-off-hideshow)
;; (add-hook 'vc-before-checkin-hook 'turn-off-hideshow) ;; (add-hook 'vc-before-checkin-hook #'turn-off-hideshow)
;; ;;
;; In the case of `vc-diff', here is a less invasive workaround: ;; In the case of `vc-diff', here is a less invasive workaround:
;; ;;
@ -317,7 +316,7 @@ a block), `hs-hide-all', `hs-hide-block' and `hs-hide-level'.")
These commands include the toggling commands (when the result is to show These commands include the toggling commands (when the result is to show
a block), `hs-show-all' and `hs-show-block'.") a block), `hs-show-all' and `hs-show-block'.")
(defvar hs-set-up-overlay nil (defvar hs-set-up-overlay #'ignore
"Function called with one arg, OV, a newly initialized overlay. "Function called with one arg, OV, a newly initialized overlay.
Hideshow puts a unique overlay on each range of text to be hidden Hideshow puts a unique overlay on each range of text to be hidden
in the buffer. Here is a simple example of how to use this variable: in the buffer. Here is a simple example of how to use this variable:
@ -329,7 +328,7 @@ in the buffer. Here is a simple example of how to use this variable:
(count-lines (overlay-start ov) (count-lines (overlay-start ov)
(overlay-end ov)))))) (overlay-end ov))))))
(setq hs-set-up-overlay \\='display-code-line-counts) (setq hs-set-up-overlay #\\='display-code-line-counts)
This example shows how to get information from the overlay as well This example shows how to get information from the overlay as well
as how to set its `display' property. See `hs-make-overlay' and as how to set its `display' property. See `hs-make-overlay' and
@ -355,7 +354,7 @@ Use the command `hs-minor-mode' to toggle or set this variable.")
(define-key map "\C-c@\C-t" 'hs-hide-all) (define-key map "\C-c@\C-t" 'hs-hide-all)
(define-key map "\C-c@\C-d" 'hs-hide-block) (define-key map "\C-c@\C-d" 'hs-hide-block)
(define-key map "\C-c@\C-e" 'hs-toggle-hiding) (define-key map "\C-c@\C-e" 'hs-toggle-hiding)
(define-key map [(shift mouse-2)] 'hs-mouse-toggle-hiding) (define-key map [(shift mouse-2)] 'hs-toggle-hiding)
map) map)
"Keymap for hideshow minor mode.") "Keymap for hideshow minor mode.")
@ -410,7 +409,7 @@ element (using `match-beginning') before calling `hs-forward-sexp-func'.")
(defvar-local hs-block-end-regexp nil (defvar-local hs-block-end-regexp nil
"Regexp for end of block.") "Regexp for end of block.")
(defvar-local hs-forward-sexp-func 'forward-sexp (defvar-local hs-forward-sexp-func #'forward-sexp
"Function used to do a `forward-sexp'. "Function used to do a `forward-sexp'.
Should change for Algol-ish modes. For single-character block Should change for Algol-ish modes. For single-character block
delimiters -- ie, the syntax table regexp for the character is delimiters -- ie, the syntax table regexp for the character is
@ -418,7 +417,7 @@ either `(' or `)' -- `hs-forward-sexp-func' would just be
`forward-sexp'. For other modes such as simula, a more specialized `forward-sexp'. For other modes such as simula, a more specialized
function is necessary.") function is necessary.")
(defvar-local hs-adjust-block-beginning nil (defvar-local hs-adjust-block-beginning #'identity
"Function used to tweak the block beginning. "Function used to tweak the block beginning.
The block is hidden from the position returned by this function, The block is hidden from the position returned by this function,
as opposed to hiding it from the position returned when searching as opposed to hiding it from the position returned when searching
@ -575,10 +574,8 @@ and then further adjusted to be at the end of the line."
;; `p' is the point at the end of the block beginning, which ;; `p' is the point at the end of the block beginning, which
;; may need to be adjusted ;; may need to be adjusted
(save-excursion (save-excursion
(if hs-adjust-block-beginning (goto-char (funcall (or hs-adjust-block-beginning #'identity)
(goto-char (funcall hs-adjust-block-beginning
header-end)) header-end))
(goto-char header-end))
(setq p (line-end-position))) (setq p (line-end-position)))
;; `q' is the point at the end of the block ;; `q' is the point at the end of the block
(hs-forward-sexp mdata 1) (hs-forward-sexp mdata 1)
@ -657,9 +654,8 @@ If `hs-special-modes-alist' has information associated with the
current buffer's major mode, use that. current buffer's major mode, use that.
Otherwise, guess start, end and `comment-start' regexps; `forward-sexp' Otherwise, guess start, end and `comment-start' regexps; `forward-sexp'
function; and adjust-block-beginning function." function; and adjust-block-beginning function."
(if (and (boundp 'comment-start) (if (and (bound-and-true-p comment-start)
(boundp 'comment-end) (bound-and-true-p comment-end))
comment-start comment-end)
(let* ((lookup (assoc major-mode hs-special-modes-alist)) (let* ((lookup (assoc major-mode hs-special-modes-alist))
(start-elem (or (nth 1 lookup) "\\s("))) (start-elem (or (nth 1 lookup) "\\s(")))
(if (listp start-elem) (if (listp start-elem)
@ -677,8 +673,8 @@ function; and adjust-block-beginning function."
(substring c-start-regexp (substring c-start-regexp
0 (1- (match-end 0))) 0 (1- (match-end 0)))
c-start-regexp))) c-start-regexp)))
hs-forward-sexp-func (or (nth 4 lookup) 'forward-sexp) hs-forward-sexp-func (or (nth 4 lookup) #'forward-sexp)
hs-adjust-block-beginning (nth 5 lookup))) hs-adjust-block-beginning (or (nth 5 lookup) #'identity)))
(setq hs-minor-mode nil) (setq hs-minor-mode nil)
(error "%s Mode doesn't support Hideshow Minor Mode" (error "%s Mode doesn't support Hideshow Minor Mode"
(format-mode-line mode-name)))) (format-mode-line mode-name))))
@ -729,13 +725,12 @@ Return point, or nil if original point was not in a block."
"Evaluate BODY forms if variable `hs-minor-mode' is non-nil. "Evaluate BODY forms if variable `hs-minor-mode' is non-nil.
In the dynamic context of this macro, `inhibit-point-motion-hooks' In the dynamic context of this macro, `inhibit-point-motion-hooks'
and `case-fold-search' are both t." and `case-fold-search' are both t."
(declare (debug t))
`(when hs-minor-mode `(when hs-minor-mode
(let ((inhibit-point-motion-hooks t) (let ((inhibit-point-motion-hooks t)
(case-fold-search t)) (case-fold-search t))
,@body))) ,@body)))
(put 'hs-life-goes-on 'edebug-form-spec '(&rest form))
(defun hs-overlay-at (position) (defun hs-overlay-at (position)
"Return hideshow overlay at POSITION, or nil if none to be found." "Return hideshow overlay at POSITION, or nil if none to be found."
(let ((overlays (overlays-at position)) (let ((overlays (overlays-at position))
@ -895,24 +890,18 @@ The hook `hs-hide-hook' is run; see `run-hooks'."
(message "Hiding blocks ... done")) (message "Hiding blocks ... done"))
(run-hooks 'hs-hide-hook))) (run-hooks 'hs-hide-hook)))
(defun hs-toggle-hiding () (defun hs-toggle-hiding (&optional e)
"Toggle hiding/showing of a block. "Toggle hiding/showing of a block.
See `hs-hide-block' and `hs-show-block'." See `hs-hide-block' and `hs-show-block'.
Argument E should be the event that triggered this action."
(interactive) (interactive)
(hs-life-goes-on (hs-life-goes-on
(posn-set-point (event-end e))
(if (hs-already-hidden-p) (if (hs-already-hidden-p)
(hs-show-block) (hs-show-block)
(hs-hide-block)))) (hs-hide-block))))
(defun hs-mouse-toggle-hiding (e) (define-obsolete-function-alias 'hs-mouse-toggle-hiding #'hs-toggle-hiding "27.1")
"Toggle hiding/showing of a block.
This command should be bound to a mouse key.
Argument E is a mouse event used by `mouse-set-point'.
See `hs-hide-block' and `hs-show-block'."
(interactive "@e")
(hs-life-goes-on
(mouse-set-point e)
(hs-toggle-hiding)))
(defun hs-hide-initial-comment-block () (defun hs-hide-initial-comment-block ()
"Hide the first block of comments in a file. "Hide the first block of comments in a file.
@ -939,7 +928,7 @@ The value (hs . t) is added to `buffer-invisibility-spec'.
The main commands are: `hs-hide-all', `hs-show-all', `hs-hide-block', The main commands are: `hs-hide-all', `hs-show-all', `hs-hide-block',
`hs-show-block', `hs-hide-level' and `hs-toggle-hiding'. There is also `hs-show-block', `hs-hide-level' and `hs-toggle-hiding'. There is also
`hs-hide-initial-comment-block' and `hs-mouse-toggle-hiding'. `hs-hide-initial-comment-block'.
Turning hideshow minor mode off reverts the menu bar and the Turning hideshow minor mode off reverts the menu bar and the
variables to default values and disables the hideshow commands. variables to default values and disables the hideshow commands.
@ -957,7 +946,7 @@ Key bindings:
(hs-grok-mode-type) (hs-grok-mode-type)
;; Turn off this mode if we change major modes. ;; Turn off this mode if we change major modes.
(add-hook 'change-major-mode-hook (add-hook 'change-major-mode-hook
'turn-off-hideshow #'turn-off-hideshow
nil t) nil t)
(easy-menu-add hs-minor-mode-menu) (easy-menu-add hs-minor-mode-menu)
(set (make-local-variable 'line-move-ignore-invisible) t) (set (make-local-variable 'line-move-ignore-invisible) t)