zsh-workers
 help / color / mirror / code / Atom feed
From: Bart Schaefer <schaefer@brasslantern.com>
To: Zsh hackers list <zsh-workers@zsh.org>
Subject: zle hook conventions (was Re: bracket-paste-magic ...)
Date: Thu, 2 Jun 2016 00:06:00 -0700	[thread overview]
Message-ID: <160602000600.ZM14708@torch.brasslantern.com> (raw)
In-Reply-To: <20160519211458.GD8007@tarsus.local2>

On May 19,  9:14pm, Daniel Shahaf wrote:
}
} Bart Schaefer wrote on Sun, May 15, 2016 at 04:59:27 -0700:
} > Hence I also think that a plugin registry for the special zle hook
} > widgets ought to be implemented externally, and the plugins agree to
} > make use of it -- because if the plugins don't follow such a
} > convention then the user has to update .zshrc in lockstep with the
} > plugin installation anyway.
} 
} I don't follow your reasoning: whether .zshrc needs to be updated
} manually is orthogonal to how the plugin hooks into zle.

If you have two or more plugins referenced from .zshrc, and not all of
them follow the same convention for how to hook into zle, then any time
one of them changes the user has to make sure it hasn't now interfered
with the hooks of the others.

} It is about the mechanism used by zsh to find and run the code that
} _installs_ the zle hook, not about whether said installation is done
} by [...]

That's exactly my point: A convention no one uses is no better than no
convention at all, even if there's specialty C code instead of shell
code.

Further, an externally-defined convention can be made backward-compatible
to at least some older versions of zsh.

} I'm happy to keep this external, although if widgets shipped with zsh
} used this "external" plugin, it'd probably become de facto official.

Currently there aren't any functions shipped with zsh that would need
this.  The only references to the zle-* hooks in the shipped code are
tests for whether zle-line-init is currently in progress, not for using
any hooks to set up specific behavior.

Crudely sketched, I'm thinking of something like this:

    zmodload zsh/parameter || {
	print -u2 "Need parameter module for zle hooks"
	return 1
    }
    for hook in isearch-exit isearch-update \
		line-pre-redraw line-init line-finish \
		history-line-set keymap-select
    do
	function zle-$hook {
	    local -a hook_functions hook_widgets
	    local hook
	    # Values of these styles look like number:name
	    # and we run them in number order
	    # $funcstack is more reliable than $0
	    # Also, ksh_arrays is annoying
	    emulate zsh -c '
		zstyle -a $funcstack[2] functions hook_functions
		zstyle -a $funcstack[2] widgets hook_widgets
	    '
	    for hook in "${(@)${(@on)hook_functions}#*:}"
	    do
		"$hook" || return
	    done
	    for hook in "${@${(@on)hook_widgets}#*:}"
	    do
		zle "$hook" -Nw || return
	    done
	    return 0
	}
    done

    # This stuff with "is it a function or is it a widget?" is
    # another reason we didn't define internal arrays for this.
    # Maybe just require widgets, and discard the functions bit.

    add-zle-hook-function() {
	local -aU extant_hooks
	local hook="$1"
	shift
	zstyle -g extant_hooks "$hook" functions
	extant_hooks+=("$@")
	zstyle -- "$hook" functions "${extant_hooks[@]}"
	if [[ -z "${widgets[$hook]}" ]]; then
	    zle -N $hook
	fi
    }

    add-zle-hook-widget() {
	local -aU extant_hooks
	local hook="$1"
	shift
	zstyle -g extant_hooks "$hook" widgets
	extant_hooks+=("$@")
	zstyle -- "$hook" widgets "${extant_hooks[@]}"
	if [[ -z "${widgets[$hook]}" ]]; then
	    zle -N $hook
	fi
    }

Usage would be e.g. (inventing a function for example purposes):

    add-zle-hook-widget zle-line-pre-redraw 30:z-sy-h-redraw

If you leave out the number: prefix, it's assumed you don't care in
what order it executes, but it'll always be after the ones that do
have number prefixes.  Left up to the plugins to work out what number
they need/get.  Note you can call the same widget more than once by
adding it with two different numbers.


  reply	other threads:[~2016-06-02  7:06 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-05-06 20:53 bracket-paste-magic adds backslashes inside a quoted string if URL is pasted ("regression" compared to pre-5.1 url-quote-magic) Axel Beckert
2016-05-08 18:50 ` Bart Schaefer
2016-05-09 14:13   ` Vincent Lefevre
2016-05-09 15:41     ` Bart Schaefer
2016-05-10  8:58       ` Vincent Lefevre
2016-05-10 19:58         ` Bart Schaefer
2016-05-13  9:23           ` Vincent Lefevre
2016-05-13 11:06             ` Bart Schaefer
2016-05-13 12:19               ` Vincent Lefevre
2016-06-02  7:20                 ` undo problems/crashes (was Re: bracket-paste-magic ...) Bart Schaefer
2016-05-13 22:20               ` bracket-paste-magic adds backslashes inside a quoted string if URL is pasted ("regression" compared to pre-5.1 url-quote-magic) Daniel Shahaf
2016-05-14  1:33                 ` Mikael Magnusson
2016-05-14  3:00                   ` Daniel Shahaf
2016-05-15 11:59                     ` Bart Schaefer
2016-05-19 21:14                       ` Daniel Shahaf
2016-06-02  7:06                         ` Bart Schaefer [this message]
2016-06-03 20:40                           ` zle hook conventions (was Re: bracket-paste-magic ...) Daniel Shahaf
2016-06-03 22:51                             ` Bart Schaefer
2016-06-04 16:57                               ` Daniel Shahaf
2016-06-10 17:36                           ` Daniel Shahaf
2016-06-10 19:51                             ` Bart Schaefer

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=160602000600.ZM14708@torch.brasslantern.com \
    --to=schaefer@brasslantern.com \
    --cc=zsh-workers@zsh.org \
    /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 public inbox

	https://git.vuxu.org/mirror/zsh/

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).