Subject: Re: bug#41130: outline-mode: Add new commands like org-cycle and org=global-cycle

From: Tassilo Horn <[email-masked]>
Date: Wed, 13 May 2020 09:13:14 +0200

Stefan Kangas <[email-masked]> writes:

> Severity: wishlist
>
> Please consider adding two new commands to outline-mode similar to
> org-cycle and org=global-cycle.

I'm also very much in favor of this.  I think probably every user has
his own incarnation of such a command.

> These are the suggested key bindings:
>
> (define-key outline-minor-mode-map (kbd "C-<tab>") 'outline-cycle)
> (define-key outline-minor-mode-map (kbd "S-<tab>") 'outline-global-cycle)

Well, I think those shouldn't be commands in outline-minor-mode-map as
they should only be active when point is on an outline heading, no?  At
least that's the case with org-mode where TAB acts quite differently
depending on the context.

So that's my personal incarnation:

--8<---------------cut here---------------start------------->8---
(defmacro th/define-context-key (keymap key dispatch)
  "Define KEY in KEYMAP to execute according to DISPATCH.

DISPATCH is a form that is evaluated and should return the
command to be executed.

If DISPATCH returns nil, then the command normally bound to KEY
will be executed.

Example:

  (th/define-context-key hs-minor-mode-map
     (kbd \"<C-tab>\")
     (cond
      ((not (hs-already-hidden-p))
       'hs-hide-block)
      ((hs-already-hidden-p)
       'hs-show-block)))

This will make <C-tab> show a hidden block.  If the block is
shown, then it'll be hidden."
  (declare (indent 2))
  `(define-key ,keymap ,key
     `(menu-item "context-key" ignore
                 :filter ,(lambda (&optional ignored)
                            ,dispatch))))

(th/define-context-key outline-minor-mode-map (kbd "<tab>")
    (when (save-excursion
            (move-beginning-of-line 1)
            (looking-at-p outline-regexp))
      'outline-toggle-children))
--8<---------------cut here---------------end--------------->8---

Of course, outline-toggle-children is not exactly like org-cycle or
org-global-cycle but it gets the job done.

Bye,
Tassilo

PS: On a related note, I think there should be some standard facility
for defining keys depending on the context.  If Stefan hadn't shown me
the menu-item-with-:filter trick some years ago, I would probably not
found out myself.