all messages for Emacs-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Juri Linkov <juri@linkov.net>
To: Robert Cochran <robert-emacs@cochranmail.com>
Cc: emacs-devel@gnu.org
Subject: Re: [PATCH] tab-bar.el: add defcustoms for functions to call after opening and before closing
Date: Wed, 04 Dec 2019 01:19:58 +0200	[thread overview]
Message-ID: <87o8wpm15x.fsf@mail.linkov.net> (raw)
In-Reply-To: <87zhgawdk9.fsf@cochranmail.com> (Robert Cochran's message of "Mon, 02 Dec 2019 14:46:46 -0800")

> 1. Trying to make a single hook do two separate things (determining
> whether to prevent tab closing and tasks on tab close) just made things
> overly complicated. Tab close prevention has been split off into a new
> hook, `tab-bar-prevent-close-functions'.

Then better to have two hooks:
tab-bar-tab-prevent-close-functions,
tab-bar-tab-post-close-functions.

The first can be used not only for close prevention, but also
for other tasks when necessary.  But the primary hook for tasks
on closing the tab could be the post hook invoked after the tab is closed.
This helps to run tasks such as killing the buffers when no other
remaining tabs still use the buffers after closing the tab.

> 2. I realized that it's possible when creating a new tab to just delay
> the actual creation of the tab in the frame's tab list. This makes it
> possible to directly modify the tab passed in to
> tab-bar-tab-post-open-functions, ie `(setf (alist-get 'name tab) "New Name")`
> from within a hook function. This means it's not really
> necessary to make new accessors.

It would be better to run the hook after the tab is added to
the frame's tab list, not before.  This will widen the usability
of the hook.  For example, when display-buffer-in-tab from
(info "(gnus) Tabbed Interface") creates a new tab for Gnus Summary,
I want to use such a new hook to move a new tab to the predefined place
(to keep the same order of Summary tabs as groups are sorted in the
Group buffer).  When the hook will be called after a new tab is added
to the frame's tab list, it can be used to move a new tab automatically.

> New patch, as well as a file of examples for the new hooks, follow.
> Again, these new hooks still need to be documented in the manual,
> which I will be glad to do as soon as a design is nailed down.

Thanks for the new patch.  An additional comment below.

> +         (last-tab-p (= 1 (length tabs)))
> +         (prevent-close (run-hook-with-args-until-success
> +                         'tab-bar-tab-prevent-close-functions
> +                         (nth close-index tabs)
> +                         last-tab-p)))
> +
> +    (unless prevent-close
> +      (run-hook-with-args 'tab-bar-tab-pre-close-functions
> +                          (nth close-index tabs)
> +                          last-tab-p)
> +
> +      (if (= 1 (length tabs))
> +          (pcase tab-bar-close-last-tab-choice
> +            ('nil
> +             (signal 'user-error '("Attempt to delete the sole tab in a frame")))
> +            ('delete-frame
> +             (delete-frame))
> +            ('tab-bar-mode-disable
> +             (tab-bar-mode -1))
> +            ((pred functionp)
> +             ;; Give the handler function the full extent of the tab's
> +             ;; data, not just it's name and explicit-name flag.
> +             (funcall tab-bar-close-last-tab-choice (tab-bar--tab))))

There is the same condition '(= 1 (length tabs))' used twice.
This suggests that the code containing 'pcase tab-bar-close-last-tab-choice'
could be moved to a new function added to tab-bar-tab-pre-close-functions
by default.  It could check for '(= 1 (length tabs))', then does its pcase
and returns nil to prevent other code in tab-bar-close-tab from running.
This is just an optimization.

> (defun tab-ex/tab-has-unsaved-files (tab _lastp)
>   ;; Don't let the user close a tab if they have unsaved buffers, to
>   ;; make sure they don't lose track of unsaved buffers, for
>   ;; example. In this case, it doesn't matter if this tab is the last
>   ;; one or not.
>   (cl-loop for buffer in (tab-ex/tab-buffers tab)
>            always (and (with-current-buffer buffer buffer-file-name)
>                        (not (buffer-modified-p buffer)))))

Good example - some editors also prepend "*" to the tab name
of an unsaved file, and don't allow closing it without saving.



  reply	other threads:[~2019-12-03 23:19 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-11-08 19:57 [PATCH] tab-bar.el: add defcustoms for functions to call after opening and before closing Robert Cochran
2019-11-10 20:42 ` Juri Linkov
2019-12-02 22:46   ` Robert Cochran
2019-12-03 23:19     ` Juri Linkov [this message]
2019-12-04 20:29       ` Robert Cochran
2019-12-04 22:45         ` Juri Linkov
2019-12-05 23:05           ` Robert Cochran
2019-12-07 22:25             ` Juri Linkov
2019-12-11 18:32               ` Robert Cochran

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87o8wpm15x.fsf@mail.linkov.net \
    --to=juri@linkov.net \
    --cc=emacs-devel@gnu.org \
    --cc=robert-emacs@cochranmail.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/emacs.git
	https://git.savannah.gnu.org/cgit/emacs/org-mode.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.