35 KiB
Write man pages: man z4h
, man z4hssh
, etc.
Implement completions for z4h
.
Make z4h help
more useful.
Implement z4h bindkey
. z4h bindkey -l
should list bindings in a nice table with sections. All
widgets should have a human-readable description.
z4h bindkey -L [array]
should list all bindings in z4h bindkey
command format. If array
is
specified, it's filled with z4h bindkey
commands that can be passed through eval
. -r escseq
should allow binding raw escape sequences. By default should warn when something got unbound. Can be
turned off with -q
.
zh4 bindkey emacs,viins 'up','ctrl-p' z4h-up-local-history
vicmd
has ^P
bound to up-history
by default. It should probably use bound to the same thing
but with local history.
vicmd
has no bindings for global history. It should.
Add "Try it locally" to docs. Basically, create a directory and make it ZDOTDIR
.
Add z4h replicate [-f] [-b dir] [var=val]...
. It should have its own :z4h:replicate: files
style. Argument ZDOTDIR=$HOME
is implied. All zsh startup files that don't exist in the current
ZDOTDIR
should also not exist in the target. -b ''
disables backup. The default argument is
something like $ZDOTDIR/z4h-backup.date-time
. Files should be stored there with subdirectories all
the way from /
. -f
causes silent action, including backing up or deleting files. If not set,
z4h replicate
first prints the whole plan of what it's going to do (move this file here, copy that
file there, etc.) and asks for confirmation.
Add z4h uninstall
.
Add install
script that people can download and run. Should have a wizard inside.
Try to make this work:
zstyle ':completion:*:manuals' separate-sections true
zstyle ':completion:*:manuals.*' insert-sections true
man printf<tab>
should show:
1 printf -- general commands
3 printf -- library functions
3p printf -- library functions [POSIX]
Maybe this can be done by writing a custom completion function for man
and enabling it with
compdef
.
Install bat
.
Add options to z4h chsh
. Perhaps -v
so that it prints what your login and current shells are
and what it's going to do about it. Also add -r
or something to prevent the creation of
no-chsh
. Maybe -f
to ignore no-chsh
and to call chsh
even if it seems unnecessary.
Should return 0
if login shell is current shell or if it successfully changes it. Should return
1
if user says "no" and 2
on errors.
Move z4h chsh
to z4h-chsh
.
zcompile
autoloadable files.
Create fn
directory similarly to bin
. Add it to fpath
.
Add :z4h:fzf disable yes
. List: fzf
, fzf-bin
, fzf-tab
, powerlevel10k
, extra-completions
,
autosuggestions
, syntax-highlighting
. This disabled cloning and all usage.
Add :z4h:fzf update no
. The list is the same as for disable
plus z4h
.
Add :z4h:fzf git-clone-flags
and :z4h:fzf git-pull-flags
.
Add -f
to z4h clone
to force Z4H_UPDATE=1
behavior.
Add z4h download [-f] [-q] [-o file] url
that uses curl
or wget
. Respects Z4H_UPDATE
unless
-f
is specified.
Add z4h-recovery-shell
. Copy from https://github.com/zsh4humans/core/blob/master/init.zsh. Bind
it to something. Defend against builtins being overridden by functions or disabled.
Add _z4h_intro
. Copy from https://github.com/zsh4humans/core/blob/master/init.zsh.
Add _z4h_err
. Copy from https://github.com/zsh4humans/core/blob/master/init.zsh.
Add this:
zstyle :z4h: hidden-files [ignore|show|recurse]
If not ignore
, should set dotglob
, add -A
to ls
, make alt-down
and alt-f
show hidden
leaves. recurse
should make alt-down
and alt-f
recurse hidden directories.
Will need to find another example of modifying aliases in .zshrc
(currently it adds -A
to ls
).
Make cd <alt-f>
consistent with alt-down
.
Check if alt-f
works on alpine (busybox).
Add options I like directly to .zshrc
. They'll also serve as example. (Not sure if there are any
that aren't already set in z4h.zsh
.)
Check what happens when running sudo zsh
. Consider adding $USER
to $Z4H
.
Name all private functions like this: -z4h-foo-bar
.
Make -z4h-clone
(or rather -z4h-clone
) autoloadable.
Replace git pull
with git fetch origin $ref
followed by git reset --hard origin/$ref
. If the
latter fails, try git clean -df
and repeat git reset
. If the whole thing fails, try git clone
.
-z4h-clone
should print "installing" or "updating" based on the presence of the target directory.
It shouldn't produce additional output on success.
Restore "downloading z4h.zsh" message in .zshrc
.
Change the structure of $Z4H
to this:
.
├── bin
├── romkatv
│ └── zsh4humans
│ ├── fn
│ │ ├── -z4h-clone
│ │ └── z4h-help
│ ├── main.zsh # defines and calls _z4h_prelude, defines z4h, etc.
│ └── z4h.zsh # the same as $Z4H/z4h.zsh but could be newer version; not used
├── zsh-users
│ └── zsh-autosuggestions
└── z4h.zsh # downloaded by zshrc
z4h.zsh
is in fact a pure POSIX sh script. It looks like this:
if [ -e "$Z4H"/zsh4humans/main.zsh ]; then
. "$Z4H"/zsh4humans/main.zsh
return
fi
# git clone, curl or wget romkatv/zsh4humans
. "$Z4H"/zsh4humans/main.zsh
romkatv/zsh4humans
shouldn't be hard-coded but derived from $Z4H_URL
.
It's not very important to update this file. The only case where it executes to the end after the
initial installation is when z4h
self-update gets aborted in the very short time window where
romkatv/zsh4humans
is renamed. So it's OK to never update the root z4h.zsh
. But updating it
is also OK (cp
+ mv
should be easy enough).
Use src branch of powerlevel10k. When updating, use the following algorithm:
- if there is more than one
gitstatus/usrbin/gitstatusd-*
, nuke them all - rename
gitstatus/usrbin/gitstatusd-*
git pull
- rename
gitstatus/usrbin/gitstatusd-*
back - run
gitstatus/install
When initializing, check if there is exactly one gitstatus/usrbin/gitstatusd-*
. If not, nuke
all and run gitstatus/install
.
This way gitstatus/install
is called only when installing or updating, so it's ok if it runs
uname
(by the way, change gitstatus
to use uname -sm
). We also avoid downloading gitstatusd
when it doesn't change.
Try harder when looking for zsh. Check command zsh
, $SHELL
, /usr/local/bin/zsh
,
/usr/bin/zsh
, /bin/zsh
and ~/.zsh-bin/bin/zsh
, in this order.
Add -z4h-restart
(or z4h restart
?) and use it instead of plain exec $_z4h_exe
. This function
should check whether $_z4h_exe
is good before execing it.
$_z4h_exe -fc '[[ $ZSH_VERSION == (5.<4->*|<6->.*) ]]'
Maybe also check that zmodload zsh/zselect
and autoload add-zsh-hook
work.
If $_z4h_exe
is not good, try to find a good one. If there aren't any, install zsh-bin. If
everything fails, keep current prompt. Basically the same thing as _z4h_prelude
.
Use some kind of counter to detect exec loop during initialization.
Figure out how to allow customization of zsh-bin installation location. This should be defined with
zstyle
, so it won't be available when we actually need to install zsh-bin. Install it to $Z4H
,
exec
into zsh, and then move zsh-bin to its intended location.
Should it be allowed to put zsh-bin in $Z4H
? One problem with this is that chsh
becomes very
dangerous. OK in ssh though? Probably better to disallow putting zsh-bin under $XDG_CACHE_HOME
or ~/.cache
.
zstyle :z4h: zsh-installation-dir /usr/local ~/.local
zstyle :z4h:ssh zsh-installation-dir /usr/local ~/.local
If there is more than one option, ask the user to choose. Mark options that would require sudo
.
Make persist=1
option in zstyle :z4h:ssh files
the default and remove support for persist
.
Make LS_COLORS
less obnoxious on NTFS.
When main.zsh
is being sourced, traverse the stack to find .zshrc
and export ZDOTDIR
pointing
to its directory.
Remove all uses of $TTY
before z4h init
. Instead, check [[ -t 0 && -t 1 ]]
.
Add this:
zstyle :z4h:locale lang 'c' 'en_us' 'en_gb' 'en_*' '*'
zstyle :z4h:locale force no # if 'no', locale is changed only when encoding is not UTF-8
Set locale early in z4h install
.
Add this:
zstyle :z4h:fzf-tab channel stable
zstyle :z4h:syntax-highlighting channel dev
zstyle :z4h:powerlevel10k git-ref src
zstyle :z4h:fzf-tab:channel stable fca05e66d1c397cb5e72e8b185b1c3d1a0fc063d
zstyle :z4h:fzf-tab:channel dev master
If git-ref
is set, it wins. Otherwise commit is derived from channel
.
Remove ~/.zshrc
from master branch.
Add this:
z4h add-hook --after '*' --before 'foo*' --after 'foobar' preinit powerlevel10k _z4h-powerlevel10k-init arg1 arg2
z4h run-hooks preinit arg3 arg4
z4h preinit
- Ordering constraints are applied in the order they are specified.
z4h preinit
runsz4h run-hooks preinit
. It complains if executed for the second time.- The precmd hook runs
z4h postinit
if it hasn't run yet. This allows users to run it manually. - If
_z4h_powerlevel10k_init arg1 arg2
is not specified, it defaults topowerlevel10k
. - It's OK to use
-a
and-b
instead of--after
and--before
.
.zshrc
will look like this:
. "$Z4H"/z4h.zsh || return
z4h use zsh-syntax-highlighting
z4h use powerlevel10k
z4h install # installs and/or updates everything
z4h preinit # enables instant prompt, sources most things, sets parameters, etc.
z4h postinit # runs compinit and sources zsh-syntax-highlighting; called from precmd if not called called explicitly
z4h use foo
calls z4h-use-foo
, which in turn calls z4h add-hook
a few times and nothing else.
Add this:
if z4h use -t powerlevel10k; then # is powerlevel10k used?
...
fi
Add config presets:
. "$Z4H"/z4h.zsh || return
zstyle :z4h: config-version 1.0.0 # <==
z4h use zsh-syntax-highlighting
z4h use powerlevel10k
...
config-version
can be used by the core code to do things differently but its primary purpose is
to set default values of various parameters, styles, options, bindings, etc.
All z4h use
directives should be in .zshrc
. z4h install
and z4h preinit
should also be in
.zshrc
. Everything else should be in preset.
Make z4h ssh
use the same directories (ZDOTDIR
, Z4H
, etc.) as local.
Make setup and teardown configurable through zstyle
.
zstyle ':z4h:ssh:*' setup my-ssh-setup
function my-ssh-setup() {
local ssh_args=("$@")
z4h ssh-send-env FOO $foo
z4h ssh-send-env BAR
z4h ssh-eval 'baz=qux'
z4h ssh-send-file -f /foo/bar '$FOO/baz'
}
All these commands must be applied in the order they are listed. Remote code must be interpreted
by zsh (hence $FOO/baz
is OK without quotes).
ssh-send-file
should be able to send directories. The meaning of trailing slash in source and
destination
should be the same as in rsync
.
z4h ssh
should be able to send history and then to retrieve it. For retrieving there needs to
be teardown
hook similar to setup
.
z4h ssh
should perform setup and interactive connection with these SSH options:
-o 'ControlMaster auto' -o 'ControlPath ~/.ssh/control-master-%r@%h:%p' -o 'ControlPersist 10'
These can be overridden via zstyle.
Create zle-experimental-save-restore-cursor
branch in zsh
. Sync it to 5.8 and add fix-sigwinch
code on top. Guard the new code with ZLE_EXPERIMENTAL_SAVE_RESTORE_CURSOR
.
Create a patch from this commit and store it in zsh-bin
. Modify build
to apply the patch.
Set patchlevel to the commit hash from zle-experimental-save-restore-cursor
.
Add ZLE_EXPERIMENTAL_SAVE_RESTORE_CURSOR=1
to zsh4humans.
Add an option to specify the minimum required zsh version. It should also allow specifying that you really want zsh from zsh-bin and not some other zsh 5.8.
Add these straight to .zshrc
?
zstyle ':completion:*' sort false
zstyle ':completion:*' list-dirs-first true
It would be nice to add --group-directories-first
to ls
for consistency but it's tricky because
it's not POSIX.
Figure out if _approximate
matcher works and whether it's worth it.
Implement syntax highlighting of preview in z4h-fzf-history
with zsh-syntax-highlighting
. To do
this, start a companion zsh
(like in gitstatus), load zsh-syntax-highlighting
there (make sure
to disable widget wrapping as it's very slow) and communicate with it over pipes.
Replace this status message from z4h reset
:
z4h: cloning zsh4humans/powerlevel10k
With this:
z4h: cloning romkatv/powerlevel10k
Revamp vi bindings. See https://github.com/zsh-vi-more/vi-motions and https://github.com/softmoth/zsh-vim-mode.
Cursor shape changes should go to p10k?
When looking for zsh, check /etc/shells
.
If there are several zsh versions installed, pick the one from PATH
. If it's too old, pick
the latest latest from the rest.
When zsh-bin installs zsh, it should ask whether to add it to /etc/shells. By default it should do this only when the installation directory is world-readable.
If ZDOTDIR
is set and doesn't point to $HOME
when install
starts, ask whether to install to
$HOME
or $ZDOTDIR
. Backups should go under the same directory.
Create ~/.zshenv
with just setopt no_global_rcs
in it.
Add z4h use [-d] [-f] [module]...
where module
is one of the built-in things:
zsh-users/zsh-autosuggestions
, bindkey
, term-title
, etc.
Without -d
modules are added to _z4h_use_queue
. With -d
they are added to
_z4h_use_queue_d[-1]
. The latter is an array with nul separated lists as its elements.
On -f
it should install a precmd
hook called -z4h-precmd-$#_z4h_install_queue_d
that calls
${(0)_z4h_install_queue_d[${0#-z4h-precmd-}]}
, and call -z4h-use-rigi $_z4h_use_queue
.
-z4h-use-rigi
should be the same as the current -z4h-init
with a bunch of conditions added in:
if (( ${@[(Ie)zsh-users/zsh-autosuggestions]} )); then
...
fi
It should issue warnings (but not fail) for arguments it doesn't recognize.
Add this:
zstyle ':z4h:' preset rigi
Could support multiple values for preset "addons". Presets can be used by the core code to do things differently but its primary purpose is to set default values of various parameters, styles, options, bindings, etc.
z4h init
will simply call the preset function -- -z4h-init-rigi
. The latter will do this:
local -a mods=()
zstyle -T :z4h:zsh-users/zsh-autosuggestion install && mods+=zsh-autosuggestion
...
z4h install -f -- $mods
local -a mods=()
zstyle -T :z4h:compinit use && mods+=compinit
...
z4h use -d -- $mods
local -a mods=()
zstyle -T :z4h:zsh-users/zsh-autosuggestion use && mods+=zsh-autosuggestion
...
z4h use -f -- $mods
Use fc
to write history in z4h-stash-buffer
. Might need fc -p
.
Support this for local development:
zstyle ':z4h:romkatv/powerlevel10k' channel command ln -s ~/powerlevel10k
The command is called with an extra argument designating target directory.
Move the top of ~/.zshrc
to ~/.zshenv
. To make it work, z4h ssh
will need to start
interactive sh.
Move $ZDOTDIR
to ~/.zsh
, leave just ~/.zshenv
in the home directory. Also leave a symlink
form ~/.zshrc
to ~/.zsh/.zshrc
so that users and bad tools don't get confused.
When retrieving files in z4h ssh
and there is no base64 either on local or remote host, use this
for encoding:
od -t x1 -An -v | tr -d '[:space:]'
Decode with sysread
, followed by print -n -- ${buf//(#m)??/'\x'$MATCH}
. This can be done
while reading from the network to speed things up.
This encoding has 50% overhead compared to base64.
Make history over ssh more robust so that it never gets overwritten.
Protect scripts against rogue aliases as functions as described in the EXAMPLES section of
https://pubs.opengroup.org/onlinepubs/9699919799/utilities/command.html. Use unset -f
on
all builtins, too.
IFS='
'
'unset' '-f' 'unalias' '[' 'cat' ...
'unalias' '-a'
PATH="$(command -p getconf PATH):$PATH"
...
This can be broken only by function unset
.
There is a similar but different example at https://pubs.opengroup.org/onlinepubs/9699919799/utilities/env.html.
Add z4h pack
that produces install-z4h
file. It should be similar to the bootstrap script
created by z4h ssh
. It should be all ASCII. It should respect :z4h:pack:tag extra-files
and
similar. tag
is the value passed via optional -t tag
. Defaults to emty. This allows one to
define different file sets for different packs. By default the same set of files as sent by ssh
should be packed, plus all history files.
Support fzf
customization via zstyle
. Add nice support for bindings (including continuous
completion and query insertion via fake actions like z4h-accept-and-repeat
and
z4h-accept-query
). Also allow for low level overrides.
zstyle :z4h:expand-or-complete:fzf command my-fzf
zstyle :z4h:expand-or-complete:fzf bindings ctrl-u:kill-line
zstyle :z4h:expand-or-complete:fzf flags --no-exact
flags
and bindings
have the semantics of extra flags and bindings.
Extra flags should be added at the front of standard flags because the first flag wins.
All flags should be passed to the command (my-fzf
above) where users can munge them any way they
like. Use --foo=bar
syntax to make it easier to remove flags (one argument -- one flag).
Extra bindings could be added at the end of standard bindings because the last binding wins.
However, in order to handle fake actions such as z4h-accept-and-repeat
it'll probably be necessary
to resolve binding conflicts within z4h. The goal is to allow this syntax for disabling continuous
completion:
zstyle :z4h:expand-or-complete:fzf extra-bindings tab:ignore
ignore
could be any other legit action. The point is that by default tab
is bound to
z4h-accept-and-repeat
but we rebind it.
Support preview customization in fzf. At the very least allow changing the size (down to 0) of preview in history.
Ctrl+/ is a bad binding on some keyboard layouts. See #35.
run-help
has some issues with aliases. See
https://github.com/romkatv/zsh4humans/issues/35#issuecomment-657515701.
Currently find
for recursive completions is called with -xdev
. This should be customizable.
See https://github.com/romkatv/zsh4humans/issues/35#issuecomment-660477146.
Define command_not_found_handler
for more operating systems (similarly to how it's done for
Homebrew and Debian).
command_not_found_handler
should simultaneously use Homebrew and /usr/lib/command-not-found
if
both are available.
Make Alt+{Up,Left,Right}
work within fzf
. See this comment.
Colorize files in git completions the same way they are shown in git status
.
Propagate arguments of zsh -ic "..."
trhough exec
when switching to a different zsh.
Make run-help z4h source
work.
z4h ssh
should start login shell.
When doing exec $_z4h_exe
, preserve -l
.
Document binding syntax in z4h help bindkey
.
Make it safe to continue using an old shell after z4h has been updated in another shell.
Assuming that flock works, it can be done as follows. Rename Z4H
to Z4H_CACHE_DIR
in
~/.zshenv
. Within $Z4H_CACHE_DIR
store:
z4h.zsh
last-update-ts
no-chsh
snapshot-00000000
throughsnapshot-ffffffff
z4h.zsh
should point Z4H
to the latest snapshot. If there are none, it should create a unique
temporary snapshot which would later be transformed into a regular snapshot by main.zsh
.
Preferably this should be the same code path as in z4h update
.
Z4H_CACHE_DIR
should not propagate through zsh
the way Z4H
currently propagates. Z4H
should
still propagate. It seems like there shouldn't be a requirement that Z4H_CACHE_DIR
gets set to
the same value in the child shell created by z4h update
as in the parent.
main.zsh
should reader-flock its snapshot. If that fails due to the directory being deleted (see
below), it should exec zsh
.
Whenever main.zsh
creates a new snapshot, it should do this while holding a writer-flock on
$Z4H_CACHE_DIR
.
main.zsh
should scan the existing snapshots while holding a writer-flock on $Z4H_CACHE_DIR
and
delete all that can be writer-flocked.
On a system where flock always succeeds (WSL1, see https://github.com/Microsoft/WSL/issues/1927),
this would make matters much worse than currently thanks to main.zsh
thinking that all snapshots
are unused and deleting them. Special code is required in this case.
Make this:
% ls foo/..<TAB>
Complete to this:
% ls foo/../
However, ..
should never appear in the listing. In addition, this should work as before:
touch ..x
ls ..<TAB>
It should complete to ls ..x
.
The three minor issues with the integrated tmux that I've mentioned in https://github.com/romkatv/zsh4humans/issues/35#issuecomment-719639084 are here:
3a8eb6f08fb26ffdad79dae6f00c9a80ba30ecc0f0ee0a142322005f1d28710a */home/romka/notes/z4h-tmuw-issues.md
See if it's feasible to fix https://github.com/romkatv/powerlevel10k#horrific-mess-when-resizing-terminal-window by patching tmux.
kitty @ launch cat
doesn't work. See
https://github.com/romkatv/zsh4humans/issues/35#issuecomment-720134760.
new_os_window_with_cwd
doesn't work in Kitty. See
https://github.com/romkatv/zsh4humans/issues/35#issuecomment-720134760.
Make z4h ssh
work when the target machine doesn't have internet.
Implement z4h fetch
that on a local machine would be a wrapper around curl
/wget
and on a
remote machine would send a request via the marker to the local. Local machine would fetch the
file (via z4h fetch
, naturally) and upload it via ssh host 'cat >$dst.$$ && mv $dst.$$ $dst
.
The file should have error code, stderr and finally the file.
There is curl
in ~/.zshenv
. In order to deal with that, add one more condition to ~/.zshenv
:
if command -v z4h >/dev/null 2>&1; then
z4h fetch "$Z4H_URL"/z4h.zsh >"$Z4H"/z4h.zsh.$$
elif ...
fi
z4h
will be a function that can handle nothing but this command.
z4h fetch
should have a whitelist of URLs it can handle (for security).
Implement z4h clipboard-{cut,copy,paste}
that can work over ssh. Add this to .zshrc
:
# Should clipboard-related z4h commands on the local host use
# the OS clipboard ('system') or a file ('file')?
zstyle :z4h: clipboard system
# Allow remote hosts access to the clipboard of the client? If set to 'no',
# clipboard-related z4h functions on the remote host will use a file.
zstyle ':z4h:ssh:*' client-clipboard no
# Copy the current command line to clipboard.
z4h bindkey z4h-copy-bufer-to-clipboard Ctrl+X
alias x='z4h clipboard-copy' # write stdin to clipboard
alias c='z4h clipboard-copy' # write stdin to clipboard and to stdout
alias v='z4h clipboard-paste' # write clipboard to stdout
Add z4h {slurp,barf}
similar to z4h clipboard-{cut,copy,paste}
.
Make Ctrl+R display the preview right on the command line. Before opening it, set
BUFFER
to $'..\n\n\n'
so that it scrolls a bit.
Set TERM=screen-256color
by default. Make it easy to override it per-app and the default as well.
zstyle :z4h:terminfo: term screen-256color
zstyle :z4h:terminfo:ssh term screen-256color
zstyle :z4h:terminfo:sudo term screen-256color
These styles should be consulted only when using tmux with 256 colors.
Hm, those styles won't work because we need to define functions for all apps (ssh
, sudo
, etc.).
This, then?
zstyle :z4h:tmux term screen-256color
zstyle :z4h:tmux force-screen-256color ssh sudo
zstyle :z4h:tmux force-tmux-256color kak vi
Or maybe hook TRAPDEBUG
and use the first syntax?
Or do it like this:
zstyle :z4h: term-spec {ssh,sudo,docker}:{tmux-256color:screen-256color,alacritty:xterm-256color}
This isn't good. Figure out how to make it possible to add commands without wiping the default ones.
Profile tmux when printing a ton of data to the terminal and see if there is an easy way to speed it up (likely not).
$TTY
is not writable when doing something like this:
% sudo useradd -ms =zsh test
% sudo -iu test
% [[ -w $TTY ]] || echo 'not writable'
This breaks a bunch of things. For example, Tab doesn't work. To fix this, dup
one of
the standard file descriptors into _z4h_tty_fd
on startup and use it through the code instead of
$TTY
.
Change the way Up/Down work with multi-line commands. Pressing Up twice should always have the effect of fetching from history twice, whether the command line was empty or not to begin with.
Consider changing Up/Down so that it searches for individual words. There
is HISTORY_SUBSTRING_SEARCH_FUZZY=1
for it.
Add a banner to ~/.zshrc
that requires confirmation. Add the same banner to install
. When
the user consents during the installation, remove the banner from ~/.zshrc
.
The banner should say that this is bleeding edge, blah, blah.
Do not install zsh-bin if the only thing missing from the stock is terminfo. Also remove the
requirement for zsh/pcre
. Better yet, add a zstyle
for required modules.
The goal here is to avoid installing zsh-bin when using macOS Big Sur or having zsh from brew.
Make zsh-bin work like tmux -u
. That is, assume UTF-8 always. If there is no UTF-8 locale on the
machine (or maybe if the current locale is not UTF-8) require zsh-bin.
Make integrated tmux work with TERM=xterm-256color
.
Remove client-server architecture from the integrated tmux. Would be nice to put it in the same
process as zsh but it might make it more difficult to update tmux. For starters it's probably a good
idea to have zsh in one process and everything else in another (z4hd
).
Actually, maybe this is a bad idea. Maybe it's better to run z4hd
the way tmux
currently runs.
Just add version
to the socket name. The latter can be done right now, without any architectural
changes.
Add a special escape code to the integrated tmux that would allow identifying via a roundtrip to the TTY. Since other terminals won't reply, the logic should be like this:
- Write "are you integrated tmux".
- Write "where is cursor".
- Read the cursor positions. If a special response preceeds it, this is integrated tmux.
Add z4h [-r] output
that prints the output of the last command. With -r
the output is printed
without styling (no colors, etc.). Print a warning if the output has more than N
bytes (or
terminal lines?). N
should be configurable.
Implement this by printing a marker in preexec and another in precmd.
Complain if users override TERM
when using integrated tmux.
Figure out better key bindings for macOS.
If using iTerm2 with the default color scheme, change it to Tango Dark with dark-grey for black.
Do it in p10k configure
for now.
z4h ssh
should backup remote files to ~/zsh-backup/ssh
. Each file/directory just once. When
backing up, write a message to the tty saying so. Have a zstyle
to control this.
List ~/.tmux.conf
in ~/.zshrc
among the files to send over ssh.
Make it possible for users to tell which commit their zsh4humans is synced to.
Implement a benchmark that measures the startup time.
print 'print foo""bar; exit' | script -E never -qec "script -E never -f -T /tmp/timing -qe /tmp/script" /dev/null >/dev/null
Add a zstyle
to disable VTE integration.
Run recovery code from z4h.zsh
on precmd
to lower startup lag (perhaps by defining
-z4h-post-init
and later redefining it). This should also solve the problem with custom HISTFILE
-- just fc -R
it on recovery.
When using su blah -
with the source and the target users both having z4h with integrated tmux,
screen gets cleared unnecessarily. See https://github.com/romkatv/zsh4humans/issues/159. This can
be fixed by creating world-writable directory /tmp/z4h-tty
with world-writabable files in it.
The names of the files would be derived from $TTY
of tmux (both integrated and real) and the
content would have $TTY
, $_Z4H_TMUX
, etc. Note that $_Z4H_TMUX_CMD
may be unaccessible, so
some fallback would be needed. If $_Z4H_TMUX_CMD
is integrated tmux, then it should be OK to use
the integrated tmux from the target user provided that it's compatible. So some version would need
to be included in the file.
Disable builtin log
in v6.
Add an ability to set ZDOTDIR
for remote machines:
zstyle :z4h:ssh:some-host zdotdir '~/.config/zsh'
Consider setting the default value to something other than $HOME
. A naive solution will break
this:
sudo -su $USER
No one's gonna do that but there might be other ways of losing ZDOTDIR
even when it's exported.
Make the list of traversed directories in z4h-cd-down
configurable.
zstyle ':z4h:cd-down' dirs history descendants:. descendants:~ children:/
Could use better naming.
Make sure that the find
command that corresponds to descendants:~
prunes .
. Entries from
history can be filtered out at the end.
Add undo-repeat
action (or a better name) to fzf widgets. It should completely undo repeat
.
Great to bind on Shift+Tab.
Delete (uninstall) stuff that was installed with z4h install
and no longer has the corresponding
directive.
When generating a config in p10k under z4h, create trampoline files for more powerful terminals.
E.g., when generating .p10k-ascii-8color.zsh
, create all the other variants that don't exist yet.
Adjust the welcome message about tmux.
Add every .p10k*.zsh
variant that doesn't exist locally to z4h_ssh_receive_files
. The idea is to
pull configs that get generated remotely.
If there is no correct .p10k*.zsh
variant for the TTY but there are variants for less powerful
terminals, automatically create trampoline files.
If there is no correct .p10k*.zsh
variant for the TTY but there are variants for more powerful
terminals, print a message explaning why the configuration wizard is about to start. Maybe also
ask for other options? Maybe use a predefined simple config and print a message?
Create .tmux.conf
in the installer if there is no existing config and the user chooses
"always tmux".
Find a better solution w.r.t. functions docker
and sudo
.
Change the default values of :z4h:term-title:ssh
in v6 to these:
zstyle ':z4h:term-title:ssh' precmd ${${${Z4H_SSH##*:}//\%/%%}:-%m}': %~'
zstyle ':z4h:term-title:ssh' preexec ${${${Z4H_SSH##*:}//\%/%%}:-%m}': ${1//\%/%%}'
Make p10k display ${${${Z4H_SSH##*:}//\%/%%}:-%m}
instead of %m
in context
. Not sure how to
achieve this without making the default p10k configs more complex.
When replacing instant prompt with the real thing, it's not necessary to print ed
. Zsh will do it
on its own. Removing this ed
might reduce the magnitude of blinking. It also might make it
possible to get rid of the function call in PS1
.
Implement rzw (Roman's Zsh Widgets) in a separate repo.
# zwords has an even number of elements, all of which are indices into $PREBUFFER$BUFFER.
# All odd words (one-based) are whitespace.
# $zwords[2*izword-1] is the start position of the word the cursor is pointing to.
# $zwords[2*izword] is the end position.
# $zword is the actual word. It is technically redundant.
rzw-parse-buffer -a zwords -i izword -w zword
# Returns 1 if there are no non-whitespace words in $PREBUFFER$BUFFER.
# Otherwise returns 0 and sets the specified parameters to the current word, or
# the one before it if the current word is whitespace, or the one after it if
# there is no previous word.
rzw-get-prev-zword -s istart -e iend -w zword
# Finds the difference between two strings using Levenshtein distance.
#
# % rzw-string-diff -a parts -- 'sunday!' 'saturday'
# % printf '%-5s => %s\n' ${(qq)parts}
# 's' => 's'
# '' => 'at'
# 'u' => 'u'
# 'n' => 'r'
# 'day' => 'day'
# '!' => ''
#
# The default values of -m and -M are set like this:
#
# zstyle :rzw:WIDGET: string-diff-max-complexity 10000 1000000
#
# If only one value is set, the second defaults to it. If neither is set, the
# values default to 10000 and 1000000. TODO: verify that the second value is
# adequate.
#
# If -c is not specified, it is fetched like this:
#
# zstyle :rzw:WIDGET: string-diff-cache-file
#
# Which in turn defaults to this:
#
# ${XDG_CACHE_HOME:-$HOME/.cache}/rzw-string-diff-$OSTYPE-$CPUTYPE
rzw-string-diff -m 10000 -M 1000000 -c CACHE -a parts -- s1 s2
# Compile a C implementation of rzw-string-diff into CACHE (a file).
# Does nothing if CACHE is a readable and executable file.
#
# Refuses to create directories whose parent isn't owned by $USER.
# If -c is not specified, its value is resolved as described above.
rzw-string-diff -C -c CACHE
# Does nothing if istart lies outside of $BUFFER. Otherwise replaces the
# specified range with the specified content while keeping the cursor
# pointing to the same content as before.
rzw-replace-buffer -- istart iend content
# Returns 0 if the script is a valid body of a function with the current
# options, aliases, etc. Otherwise returns 1.
rzw-is-valid-script -- script
# Quotes the shell word to the left of the cursor with double or single quotes.
# Prefers quotes with the shorter result or double quotes if there is no
# difference. If already quoted, changes quotes. If there is an unterminated
# quote, terminates it and quotes the resulting word with the same kind of
# quotes. Keeps the cursor on the content it was pointing to before the widget
# was invoked.
# Replaces the shell word to the left of the cursor with the result of the
# specified transformation. Keeps the cursor on the content it was pointing to
# before the widget was invoked.
#
# Prior to the transformation the shell word is unquoted. Afterwards it is
# quoted while preferring the same kind of quoting that already existed prior
# to the transformation.
#
# bar => /foo/bar
# 'bar' => '/foo/bar'
# 'bar => '/foo/bar'
# $'b\x20r' => $'/foo/b r'
# $'b\141r' => $'/foo/bar'
#
# Note: Pass the original unquoted word as $2?
rzw-transform-prev-zword -- 'REPLY=${1:a}'
# Example
function convert-prev-zword-to-abolute-path() {
rzw-transform-prev-zword -- 'REPLY=${1:a}'
}
zle -N convert-prev-zword-to-abolute-path
bindkey '^A' convert-prev-zword-to-abolute-path
The buffer is always $PREBUFFER$BUFFER
and all buffer indices are within it.