Compare commits
82 Commits
a3e83e4844
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
316eefe916
|
|||
|
3a821d832b
|
|||
|
b291163a80
|
|||
|
2e2bad65a2
|
|||
|
c46b1c5ea1
|
|||
|
5f40b97e9a
|
|||
|
5599ce14d7
|
|||
|
4008bb543b
|
|||
|
d0abb14567
|
|||
|
9e18be760c
|
|||
|
04d3d6e87f
|
|||
|
526a37301a
|
|||
|
7dc9efc0e4
|
|||
|
9bc8b4b93f
|
|||
|
ead724b75b
|
|||
|
1c5beed613
|
|||
|
2dd1a80036
|
|||
|
4f2a74e546
|
|||
|
cb1821ba33
|
|||
|
5128d15251
|
|||
|
2b31632914
|
|||
|
27791acf50
|
|||
|
8aa76b3ee6
|
|||
|
6b866f5474
|
|||
|
4f6929bcce
|
|||
|
2495d835b4
|
|||
|
dda2ff640e
|
|||
|
87398bf712
|
|||
|
0a5b6d0767
|
|||
|
5b8f54b0cb
|
|||
|
ef5b2911bf
|
|||
|
768cb4ed4a
|
|||
|
f2ce78b6b3
|
|||
|
a3d2bf985c
|
|||
|
e8c5ec93f1
|
|||
|
ae52ba20d2
|
|||
|
ea2867fc9f
|
|||
|
7f83427749
|
|||
|
8a4029121e
|
|||
|
7c184ed11e
|
|||
|
8e8ef29b37
|
|||
|
d8859bc709
|
|||
|
65d99c40e8
|
|||
|
d28ef61694
|
|||
|
d5a95f9ce5
|
|||
|
723899d70f
|
|||
|
126ccb0c7a
|
|||
|
dadf344f2b
|
|||
|
f17cde7943
|
|||
|
a89ad407ba
|
|||
|
a26a899213
|
|||
|
6db1a710c6
|
|||
|
9c1e3f4679
|
|||
|
bb7ef3769d
|
|||
|
0534ec493e
|
|||
|
708daa10dc
|
|||
|
6bd13a9b56
|
|||
|
a34cdab694
|
|||
|
456f71d939
|
|||
|
2bceafeb4e
|
|||
|
af0d9e8fd1
|
|||
|
d57fbf0e66
|
|||
|
a23159e50d
|
|||
|
e8a8f9637a
|
|||
|
0e5baf5e36
|
|||
|
fced504674
|
|||
|
a49cbcae21
|
|||
|
9271a293cb
|
|||
|
2e4086500d
|
|||
|
ca15f2399e
|
|||
|
198069fac7
|
|||
|
4c12418b62
|
|||
|
5767210dce
|
|||
|
ddb279da7b
|
|||
|
07428c661d
|
|||
|
a7e4c2c770
|
|||
|
c09ed22389
|
|||
|
1f6fb2abf7
|
|||
|
b47c91bb5f
|
|||
|
fec954c30c
|
|||
|
372865f9c4
|
|||
|
3fb5b5f376
|
@@ -185,3 +185,6 @@ EXEC 01;92
|
||||
*.opus 00;36
|
||||
*.spx 00;36
|
||||
*.xspf 00;36
|
||||
|
||||
## Others
|
||||
*.pdf 01;95
|
||||
|
||||
@@ -4,21 +4,22 @@
|
||||
addIgnoredFile = off
|
||||
detachedHead = off
|
||||
[alias]
|
||||
# NOTE: git-zsh-autoload (./zsh-autoload.sh) is a small wrapper that
|
||||
# launches autoloadable zsh functions (.config/zsh/autoload/git/*) in
|
||||
# the right directory, as shell commands in git aliases are executed
|
||||
# from the top-level directory of the repository.
|
||||
# NOTE: git-external-script (./external-script.sh) is a small wrapper
|
||||
# that launches external scripts from the ./scripts/ collection in the
|
||||
# right directory, as shell commands in git aliases are executed from
|
||||
# the top-level directory of the repository.
|
||||
|
||||
abort = "!git-zsh-autoload abort"
|
||||
abort = "!git-external-script abort"
|
||||
autosquash = -c sequence.editor=/bin/true rebase -i --autosquash
|
||||
autofixup= autosquash
|
||||
branch-rename = "!git-external-script branch-rename"
|
||||
c = commit
|
||||
changes = flog HEAD...FETCH_HEAD
|
||||
checkout-worktree = "!git-zsh-autoload checkout-worktree"
|
||||
checkout-worktree = "!git-external-script checkout-worktree"
|
||||
cow = checkout-worktree
|
||||
co = checkout
|
||||
commit-last-msg = "!git-zsh-autoload commit-last-msg"
|
||||
continue = "!git-zsh-autoload continue"
|
||||
commit-last-msg = "!git-external-script commit-last-msg"
|
||||
continue = "!git-external-script continue"
|
||||
cont = continue
|
||||
clm = commit-last-msg
|
||||
last-msg = commit-last-msg
|
||||
@@ -28,27 +29,61 @@
|
||||
ft = fetch-tags-only
|
||||
filter-repo = !git-filter-repo
|
||||
fixes = log -1 --pretty=fixes
|
||||
glog = "!git-zsh-autoload glog"
|
||||
https-and-ssh = "!git-zsh-autoload https-and-ssh"
|
||||
glog = "!git-external-script glog"
|
||||
https-and-ssh = "!git-external-script https-and-ssh"
|
||||
ssh-and-https = https-and-ssh
|
||||
l = log
|
||||
last-changed = "!git-zsh-autoload last-changed"
|
||||
last-changed = "!git-external-script last-changed"
|
||||
ls = ls-files
|
||||
make-fork = "!git-zsh-autoload make-fork"
|
||||
make-fork = "!git-external-script make-fork"
|
||||
p = push
|
||||
perm-stash = "!git-zsh-autoload perm-stash"
|
||||
perm-stash = "!git-external-script perm-stash"
|
||||
root = rev-parse --show-toplevel
|
||||
signoff = rebase --signoff
|
||||
ss = stash
|
||||
ssync = "!git-zsh-autoload ssync"
|
||||
submodule-rm = "!git-zsh-autoload submodule-rm"
|
||||
track = "!git-zsh-autoload track"
|
||||
ssync = "!git-external-script ssync"
|
||||
submodule-rm = "!git-external-script submodule-rm"
|
||||
track = "!git-external-script track"
|
||||
branches = track
|
||||
[blame]
|
||||
date = short
|
||||
[branch]
|
||||
autosetuprebase = always
|
||||
sort = -committerdate
|
||||
[clone]
|
||||
filterSubmodules = yes
|
||||
[color "diff"]
|
||||
# Make all bold colors also bright. See diff_colors in git's diff.c
|
||||
oldMoved = bold brightmagenta
|
||||
oldMovedAlternative = bold brightblue
|
||||
newMoved = bold brightcyan
|
||||
newMovedAlternative = bold brightyellow
|
||||
oldBold = bold brightred
|
||||
newBold = bold brightgreen
|
||||
[color "decorate"]
|
||||
# Make all bold colors also bright. See decoration_colors in git's
|
||||
# log-tree.c
|
||||
branch = bold brightgreen
|
||||
remoteBranch = bold brightred
|
||||
tag = bold brightyellow
|
||||
stash = bold brightmagenta
|
||||
HEAD = bold brightcyan
|
||||
grafted = bold brightblue
|
||||
[color "grep"]
|
||||
# Make all bold colors also bright. See GREP_OPT_INIT in git's grep.h
|
||||
matchContext = bold brightred
|
||||
matchSelected = bold brightred
|
||||
[color "interactive"]
|
||||
# Make all bold colors also bright. See init_add_i_state in git's
|
||||
# add-interactive.c
|
||||
help = bold brightred
|
||||
prompt = bold brightblue
|
||||
error = bold brightred
|
||||
[color "remote"]
|
||||
# Make all bold colors also bright. See keywords in git's sideband.c
|
||||
warning = bold brightyellow
|
||||
success = bold brightgreen
|
||||
error = bold brightred
|
||||
[color "status"]
|
||||
added = 076
|
||||
untracked = 014
|
||||
@@ -65,9 +100,8 @@
|
||||
[core]
|
||||
abbrev = 12
|
||||
#pager = delta
|
||||
pager = diff-so-fancy \
|
||||
| less --tabs=8 --RAW-CONTROL-CHARS --quit-if-one-screen
|
||||
whitespace = trailing-spaces,space-before-tab,indent-with-non-tab
|
||||
pager = diff-so-fancy | less --tabs=8 --RAW-CONTROL-CHARS
|
||||
whitespace = trailing-spaces,space-before-tab,indent-with-non-tab,tabwidth=8
|
||||
[delta]
|
||||
navigate = true
|
||||
commit-decoration-style = bold yellow box
|
||||
@@ -100,6 +134,12 @@
|
||||
singleKey = true
|
||||
[log]
|
||||
follow = true
|
||||
# Make all colors bold and additionally use bright versions of
|
||||
# previously bold-only colors. See column_colors_ansi in git's color.c
|
||||
# used by graph.c
|
||||
graphColors = bold red,bold green,bold yellow,bold blue,bold magenta,bold cyan,bold brightred,bold brightgreen,bold brightyellow,bold brightblue,bold brightmagenta,bold brightcyan
|
||||
# Show all refs as decoration (e.g. also notes)
|
||||
initialDecorationSet = all
|
||||
[merge]
|
||||
conflictstyle = diff3
|
||||
log = true
|
||||
@@ -114,9 +154,9 @@
|
||||
[rebase]
|
||||
autostash = true
|
||||
[rerere]
|
||||
enabled = true
|
||||
enabled = false
|
||||
[status]
|
||||
submodulesummary = true
|
||||
submoduleSummary = true
|
||||
[submodule]
|
||||
fetchJobs = 0
|
||||
[trailer]
|
||||
@@ -125,5 +165,6 @@
|
||||
email = julian@druck.dev
|
||||
name = Julian Prein
|
||||
signingkey = C0A44F69F2E29F6586C86B96CA6B3A516FAC2555
|
||||
|
||||
[include]
|
||||
path = user.config
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2025 Julian Prein
|
||||
#
|
||||
# Meant to be used in git aliases to launch an autoloadable zsh function in the
|
||||
# correct directory.
|
||||
# Meant to be used by git aliases to easily launch an external script from the
|
||||
# ./scripts/ collection through its basename and in the correct directory (i.e.
|
||||
# GIT_PREFIX).
|
||||
|
||||
if [ $# -eq 0 ]; then
|
||||
printf >&2 "Usage: %s <function>\n" "$(basename "$0")"
|
||||
@@ -12,7 +13,7 @@ fi
|
||||
name="$1"
|
||||
shift
|
||||
|
||||
BASE="${XDG_CONFIG_HOME:-$HOME/.config}/zsh/autoload/git"
|
||||
BASE="$(dirname "$(realpath "$0")")/scripts"
|
||||
|
||||
# In git aliases, shell commands are executed from the top-level directory of
|
||||
# the repo. GIT_PREFIX contains the original directory relative to the
|
||||
@@ -36,18 +36,11 @@ set $TERM_CMD_FLAG
|
||||
# a single sprite cache on the GPU"[^1], so that startup is almost instant.
|
||||
#
|
||||
# For this to work best, launch one hidden "daemon" instance at startup so that
|
||||
# the kitty process is always running, even when no OS windows exists.
|
||||
#
|
||||
# NOTE: `--start-as hidden` needs kitty 0.42.0 or later.
|
||||
#
|
||||
# Additionally allow remote_control over a socket, so that kitty-cwd works.
|
||||
# the kitty process is always running, even when no OS windows exists. See the
|
||||
# daemon.sh script in .config/kitty.
|
||||
#
|
||||
# [^1]: kitty(1)
|
||||
exec --no-startup-id $TERMINAL \
|
||||
--start-as hidden \
|
||||
--detach \
|
||||
-o allow_remote_control=socket-only \
|
||||
--listen-on unix:/tmp/mykitty
|
||||
exec --no-startup-id kitty-daemon
|
||||
|
||||
# Multi monitor support
|
||||
exec_always --no-startup-id ~/.config/i3/monitor-setup.sh &
|
||||
@@ -86,6 +79,8 @@ bindsym $mod+Shift+v split horizontal
|
||||
bindsym $mod+f fullscreen toggle
|
||||
|
||||
# change container layout (stacked, tabbed, toggle split)
|
||||
#bindsym $mod+s layout stacking
|
||||
#bindsym $mod+w layout tabbed
|
||||
bindsym $mod+e layout toggle split
|
||||
|
||||
# toggle tiling / floating
|
||||
@@ -107,13 +102,15 @@ bindsym $mod+6 exec ~/.config/i3/multi-monitor-workspaces.sh -s 6
|
||||
bindsym $mod+7 exec ~/.config/i3/multi-monitor-workspaces.sh -s 7
|
||||
bindsym $mod+8 exec ~/.config/i3/multi-monitor-workspaces.sh -s 8
|
||||
bindsym $mod+9 exec ~/.config/i3/multi-monitor-workspaces.sh -s 9
|
||||
bindsym $mod+0 exec ~/.config/i3/multi-monitor-workspaces.sh -s 0
|
||||
bindsym $mod+0 exec ~/.config/i3/multi-monitor-workspaces.sh -s 10
|
||||
|
||||
# switch back to the previous workspace
|
||||
workspace_auto_back_and_forth yes
|
||||
bindsym $mod+Tab exec i3-msg workspace "$( \
|
||||
i3-msg -t get_workspaces | \
|
||||
jq -r '.[] | select(.focused).name')"
|
||||
bindsym $mod+Tab workspace back_and_forth
|
||||
|
||||
# switch workspaces forward and backward
|
||||
bindsym $mod+Next workspace next
|
||||
bindsym $mod+Prior workspace prev
|
||||
|
||||
# Switch visible workspaces (e.g. multi monitor setup)
|
||||
bindsym $mod+Shift+Tab exec i3-msg workspace "$( \
|
||||
@@ -131,7 +128,7 @@ bindsym $mod+Shift+6 exec ~/.config/i3/multi-monitor-workspaces.sh -m 6
|
||||
bindsym $mod+Shift+7 exec ~/.config/i3/multi-monitor-workspaces.sh -m 7
|
||||
bindsym $mod+Shift+8 exec ~/.config/i3/multi-monitor-workspaces.sh -m 8
|
||||
bindsym $mod+Shift+9 exec ~/.config/i3/multi-monitor-workspaces.sh -m 9
|
||||
bindsym $mod+Shift+0 exec ~/.config/i3/multi-monitor-workspaces.sh -m 0
|
||||
bindsym $mod+Shift+0 exec ~/.config/i3/multi-monitor-workspaces.sh -m 10
|
||||
|
||||
# move focused container and switch to workspace
|
||||
bindsym Mod1+Shift+1 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 1
|
||||
@@ -143,7 +140,7 @@ bindsym Mod1+Shift+6 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 6
|
||||
bindsym Mod1+Shift+7 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 7
|
||||
bindsym Mod1+Shift+8 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 8
|
||||
bindsym Mod1+Shift+9 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 9
|
||||
bindsym Mod1+Shift+0 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 0
|
||||
bindsym Mod1+Shift+0 exec ~/.config/i3/multi-monitor-workspaces.sh -ms 10
|
||||
|
||||
# reload the configuration file
|
||||
bindsym $mod+Shift+c reload
|
||||
|
||||
@@ -25,25 +25,12 @@ done
|
||||
shift $((OPTIND - 1))
|
||||
[ $# -gt 0 ] || usage
|
||||
|
||||
outputs="$(i3-msg -t get_outputs | jq -r '.[] | select(.active).name')"
|
||||
num_outs="$(printf "%s\n" "$outputs" | wc -l)"
|
||||
|
||||
if [ "$num_outs" -lt 2 ]; then
|
||||
# only one monitor
|
||||
workspace="$1"
|
||||
else
|
||||
name="$(i3-msg -t get_tree \
|
||||
| jq -r '.. | objects | select(.focused).output')"
|
||||
num="$(printf "%s\n" "$outputs" \
|
||||
| grep -Fxn "$name" \
|
||||
| cut -d: -f1)"
|
||||
num="$((num - 1))"
|
||||
|
||||
# Omit the number on the first monitor
|
||||
[ "$num" -gt 0 ] || num=
|
||||
|
||||
workspace="$num$1"
|
||||
fi
|
||||
# NOTE: See `strip-wsnames` in polybar config. With it every monitor has its own
|
||||
# 1-10 workspaces
|
||||
workspace="$1: $name"
|
||||
|
||||
if [ -z "$switch" ] && [ -z "$move" ]; then
|
||||
printf "%s\n" "$workspace"
|
||||
|
||||
34
.config/kitty/daemon.sh
Executable file
34
.config/kitty/daemon.sh
Executable file
@@ -0,0 +1,34 @@
|
||||
#!/bin/sh
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2025 Julian Prein
|
||||
#
|
||||
# Usage: kitty-daemon [GROUP_NAME]
|
||||
#
|
||||
# Daemonize kitty by launching one hidden instance that new invocations can use
|
||||
# to create new OS windows. This makes kitty startup a lot faster since all
|
||||
# windows can now share a single CPU process and GPU sprite cache. Additionally
|
||||
# allow remote_control over a socket, so that kitty-cwd works.
|
||||
#
|
||||
# To launch new invocations using the daemon created by this script use:
|
||||
#
|
||||
# kitty --single-instance
|
||||
#
|
||||
# You can pass an optional instance-group as first parameter. In that case use:
|
||||
#
|
||||
# kitty --single-instance --instance-group <NAME>
|
||||
#
|
||||
# NOTE: `--start-as hidden` needs kitty 0.42.0 or later.
|
||||
|
||||
TMP_DIR="${TMPDIR:-/tmp}/kitty.$USER"
|
||||
mkdir -p "$TMP_DIR"
|
||||
|
||||
name="kitty${1:+-$1}"
|
||||
|
||||
kitty \
|
||||
--single-instance \
|
||||
${1:+--instance-group "$1"} \
|
||||
--start-as hidden \
|
||||
--detach \
|
||||
--detached-log "$(mktemp -p "$TMP_DIR" "$name.XXXXXX.log")" \
|
||||
-o allow_remote_control=socket-only \
|
||||
--listen-on unix:"$TMP_DIR/$name.sock"
|
||||
@@ -2,22 +2,24 @@
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2025 Julian Prein
|
||||
#
|
||||
# Usage: kitty-cwd [GROUP_NAME]
|
||||
#
|
||||
# Print the current working directory of the focused kitty window. Returns 4 if
|
||||
# none exist or is focused.
|
||||
|
||||
# NOTE: the backticks are used for hacky line-continuation, taken from
|
||||
# https://stackoverflow.com/a/7729087/2092762c9
|
||||
kitten @ --to unix:/tmp/mykitty ls \
|
||||
| jq -er ".[]`
|
||||
` | select(.is_focused).tabs.[]`
|
||||
` | select(.is_focused).windows.[]`
|
||||
` | select(.is_focused).cwd"
|
||||
if [ -n "$KITTY_LISTEN_ON" ]; then
|
||||
socket_path="${KITTY_LISTEN_ON#unix:}"
|
||||
else
|
||||
socket_path="${TMPDIR:-/tmp}/kitty.$USER/kitty${1:+-$1}.sock"
|
||||
fi
|
||||
[ -e "$socket_path" ] || exit 1
|
||||
|
||||
# An alternative version that uses recursive descent to find focused objects
|
||||
# that also have a `.cwd` key:
|
||||
#
|
||||
# | jq -er "..`
|
||||
# ` | objects`
|
||||
# ` | select(.is_focused)`
|
||||
# ` | to_entries.[]`
|
||||
# ` | select(.key == \"cwd\").value"
|
||||
# NOTE: Unfortunately kitten-@-ls(1) is slow, so communicate with the socket
|
||||
# directly.
|
||||
printf '\eP@kitty-cmd{%s,%s,%s}\e\\' \
|
||||
'"cmd":"ls"' \
|
||||
'"version":[0,26,0]' \
|
||||
'"payload":{"match":"state:focused"}' \
|
||||
| nc -U -q0 "$socket_path" \
|
||||
| awk '{ print substr($0, 13, length($0) - 14) }' \
|
||||
| jq -er ".data | fromjson | .[].tabs.[].windows.[].cwd"
|
||||
|
||||
@@ -20,7 +20,7 @@
|
||||
#: <https://sw.kovidgoyal.net/kitty/kittens/choose-fonts/#font-spec-
|
||||
#: syntax>.
|
||||
|
||||
# font_size 11.0
|
||||
font_size 12.0
|
||||
|
||||
#: Font size (in pts).
|
||||
|
||||
@@ -630,7 +630,7 @@ mouse_hide_wait -1
|
||||
#: If empty (default) select_by_word_characters will be used for both
|
||||
#: directions.
|
||||
|
||||
# click_interval -1.0
|
||||
click_interval 0.4
|
||||
|
||||
#: The interval between successive clicks to detect double/triple
|
||||
#: clicks (in seconds). Negative numbers will use the system default
|
||||
@@ -1763,7 +1763,7 @@ close_on_child_death yes
|
||||
#: special value of ask means that kitty will ask before opening the
|
||||
#: link when clicked.
|
||||
|
||||
# shell_integration enabled
|
||||
shell_integration no-cursor
|
||||
|
||||
#: Enable shell integration on supported shells. This enables features
|
||||
#: such as jumping to previous prompts, browsing the output of the
|
||||
@@ -2521,7 +2521,8 @@ map kitty_mod+shift+backspace change_font_size all 0
|
||||
|
||||
#: Open URL
|
||||
|
||||
map kitty_mod+e open_url_with_hints
|
||||
# map kitty_mod+e open_url_with_hints
|
||||
map kitty_mod+f open_url_with_hints
|
||||
|
||||
#:: Open a currently visible URL using the keyboard. The program used
|
||||
#:: to open the URL is specified in open_url_with.
|
||||
|
||||
@@ -6,11 +6,17 @@
|
||||
# NOTE: the current file can be edited with `v` already, but this doesn't work
|
||||
# when reading from stdin
|
||||
# NOTE: ^P omits the "done" message
|
||||
# NOTE: '' jumps back to the previous position
|
||||
#
|
||||
# edit in vim without any ANSI SGR sequences (e.g. color)
|
||||
e noaction g|$no-ansi-sgr | nvim -\n
|
||||
# edit in vim without any ANSI escape sequences (e.g. color)
|
||||
e noaction g|$no-ansi | nvim -\n''
|
||||
# edit in vim while keeping them
|
||||
E noaction g|$nvim -\n
|
||||
E noaction g|$nvim -\n''
|
||||
# edit current screen in vim
|
||||
^E noaction |.no-ansi | nvim -\n
|
||||
|
||||
# copy whole file
|
||||
^Y noaction g|$xclip -selection clipboard\n''
|
||||
|
||||
#env
|
||||
# NOTE: Lines need a trailing space when concatenating
|
||||
|
||||
@@ -40,6 +40,7 @@ enable-ipc = true
|
||||
type = internal/i3
|
||||
pin-workspaces = true
|
||||
format = <label-state> <label-mode>
|
||||
strip-wsnames = true
|
||||
index-sort = true
|
||||
wrapping-scroll = false
|
||||
|
||||
|
||||
@@ -22,10 +22,11 @@ done
|
||||
if ! pgrep -ax polybar >/dev/null 2>&1; then
|
||||
# launch Polybar on every monitor
|
||||
# https://github.com/polybar/polybar/issues/763
|
||||
while read -r m; do
|
||||
export MONITOR="${m%%:*}"
|
||||
polybar --list-monitors \
|
||||
| cut -d: -f1 \
|
||||
| xargs -I'{}' -P0 \
|
||||
env MONITOR='{}' \
|
||||
polybar --reload -c "$BASE_DIR/config" main &
|
||||
done <<<"$(polybar --list-monitors)"
|
||||
|
||||
echo "Polybar launched..."
|
||||
else
|
||||
|
||||
@@ -361,10 +361,12 @@ bind S set -w synchronize-panes
|
||||
set -g remain-on-exit on
|
||||
if -F "#{>=:#{version},3.3}" {
|
||||
bind -n C-d if -F "#{pane_dead}" { kill-pane } { send }
|
||||
bind -n Escape if -F "#{pane_dead}" { kill-pane } { send }
|
||||
bind -n Enter if -F "#{pane_dead}" { respawn-pane } { send }
|
||||
} {
|
||||
# omitting the key argument was introduced in 3.3
|
||||
bind -n C-d if -F "#{pane_dead}" { kill-pane } { send C-d }
|
||||
bind -n Escape if -F "#{pane_dead}" { kill-pane } { send Escape }
|
||||
bind -n Enter if -F "#{pane_dead}" { respawn-pane } { send Enter }
|
||||
}
|
||||
|
||||
|
||||
@@ -37,18 +37,30 @@ setlocal showbreak=NONE
|
||||
" This is very hacky.
|
||||
|
||||
" Only if WinResized is supported
|
||||
if has('##WinResized')
|
||||
if exists('##WinResized')
|
||||
|
||||
augroup man_resized
|
||||
" The reload has to be delayed slightly, since with an `edit` directly in
|
||||
" the autocmd, the buffer will just be cleared? (TODO)
|
||||
" NOTE: One could add a wrapper function that checks for the existence of
|
||||
" already running timers similar to how it's done in the
|
||||
" highlight_current group (see autocommands.vim), but this feels
|
||||
" overkill here.
|
||||
au! WinResized <buffer> call timer_start(10, function("s:redraw_delayed"))
|
||||
au! WinResized <buffer> call s:redraw_man(v:event)
|
||||
augroup END
|
||||
|
||||
function s:redraw_man(event)
|
||||
if exists('w:disable_man_resizing')
|
||||
return
|
||||
endif
|
||||
|
||||
if exists('w:man_resizing_timer_id')
|
||||
call timer_stop(w:man_resizing_timer_id)
|
||||
endif
|
||||
|
||||
echo a:event
|
||||
|
||||
" TODO: make sure that a:event contains window number and that the width
|
||||
" actually changed with getwininfo()
|
||||
let w:man_resizing_timer_id = timer_start(10, function("s:redraw_delayed"))
|
||||
endfunction
|
||||
|
||||
" The function can't be redefined during the reload of the ftplugin (i.e.
|
||||
" triggered by `edit`), since it is currently executing (i.e. `edit`):
|
||||
"
|
||||
@@ -56,6 +68,8 @@ augroup END
|
||||
"
|
||||
if !exists("*s:redraw_delayed")
|
||||
function s:redraw_delayed(timer_id)
|
||||
unlet w:man_resizing_timer_id
|
||||
|
||||
" Try to keep the position as close as possible, since edit will move to
|
||||
" the start of the file
|
||||
" TODO: this should be more accurate
|
||||
@@ -72,5 +86,5 @@ endif
|
||||
" lines, messing up the whole buffer. Since this is distracting, turn it off.
|
||||
setlocal nowrap
|
||||
|
||||
endif " has('##WinResized')
|
||||
endif " exists('##WinResized')
|
||||
" ------------------------------------------------------------------------------
|
||||
|
||||
11
.config/vim/after/syntax/markdown.vim
Normal file
11
.config/vim/after/syntax/markdown.vim
Normal file
@@ -0,0 +1,11 @@
|
||||
" Either not at the start of the line, or otherwise not followed by a colon
|
||||
syntax match markdownFootnoteZero /\v(.@1<=\[\^0\])|(^\[\^0\]:@!)/ conceal cchar=⁰
|
||||
syntax match markdownFootnoteOne /\v(.@1<=\[\^1\])|(^\[\^1\]:@!)/ conceal cchar=¹
|
||||
syntax match markdownFootnoteTwo /\v(.@1<=\[\^2\])|(^\[\^2\]:@!)/ conceal cchar=²
|
||||
syntax match markdownFootnoteThree /\v(.@1<=\[\^3\])|(^\[\^3\]:@!)/ conceal cchar=³
|
||||
syntax match markdownFootnoteFour /\v(.@1<=\[\^4\])|(^\[\^4\]:@!)/ conceal cchar=⁴
|
||||
syntax match markdownFootnoteFive /\v(.@1<=\[\^5\])|(^\[\^5\]:@!)/ conceal cchar=⁵
|
||||
syntax match markdownFootnoteSix /\v(.@1<=\[\^6\])|(^\[\^6\]:@!)/ conceal cchar=⁶
|
||||
syntax match markdownFootnoteSeven /\v(.@1<=\[\^7\])|(^\[\^7\]:@!)/ conceal cchar=⁷
|
||||
syntax match markdownFootnoteEight /\v(.@1<=\[\^8\])|(^\[\^8\]:@!)/ conceal cchar=⁸
|
||||
syntax match markdownFootnoteNine /\v(.@1<=\[\^9\])|(^\[\^9\]:@!)/ conceal cchar=⁹
|
||||
@@ -3,6 +3,9 @@ setlocal colorcolumn+=51
|
||||
setlocal textwidth=72
|
||||
" Spell checking always enabled
|
||||
setlocal spell spelllang=en
|
||||
" Disable C-indentation as it messes up formatting of paragraphs containing
|
||||
" parentheses
|
||||
setlocal nocindent
|
||||
|
||||
" Disable gutentags as it seems to regenerate the entire tags file when editing
|
||||
" git-commits...
|
||||
@@ -17,3 +20,27 @@ let g:gutentags_enabled = 0
|
||||
" When aborting a commit I usually use :cq which I can't when committing through
|
||||
" fugitive. Abbreviate it to something that works.
|
||||
cabbrev <buffer> cq %d <Bar> x
|
||||
|
||||
" Fold file listings (staged, unstaged, untracked, ...) and diff
|
||||
setlocal foldmethod=syntax
|
||||
|
||||
" Unfold staged files and diff. inspired by:
|
||||
" https://vi.stackexchange.com/questions/4050/how-to-search-for-pattern-in-certain-syntax-regions/27008#27008
|
||||
if has("patch-8.2.0915") || has("nvim-0.7.0")
|
||||
|
||||
function s:open_fold(group, content)
|
||||
" Find line containing `content` that is highlighted with `group`
|
||||
let l:line_nr = search(a:content, "n", 0, 0, { ->
|
||||
\ synstack('.', col('.'))
|
||||
\ ->map('synIDattr(v:val, "name")')
|
||||
\ ->match(a:group) < 0 })
|
||||
if l:line_nr <= 0
|
||||
return
|
||||
endif
|
||||
execute l:line_nr->string() .. "foldopen"
|
||||
endfunction
|
||||
|
||||
call s:open_fold("gitcommitSelected", "Changes to be committed:")
|
||||
call s:open_fold("gitcommitDiff", "diff --")
|
||||
|
||||
endif " has("patch-8.2.0915") || has("nvim-0.7.0")
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
" Turn on line-wrapping
|
||||
setlocal wrap
|
||||
" Disable C-indentation as it messes up formatting of paragraphs containing
|
||||
" parentheses
|
||||
setlocal nocindent
|
||||
|
||||
" Fold by sections
|
||||
function! MdSectionFold()
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
" Turn on line-wrapping
|
||||
setlocal wrap
|
||||
" Disable C-indentation as it messes up formatting of paragraphs containing
|
||||
" parentheses
|
||||
setlocal nocindent
|
||||
|
||||
" Close the quickfix window after a cursor movement
|
||||
let g:vimtex_quickfix_autoclose_after_keystrokes = 1
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
" Disable C-indentation as it messes up formatting of paragraphs containing
|
||||
" parentheses
|
||||
setlocal nocindent
|
||||
|
||||
" Don't highlight Unicode table separator (e.g. vertical box drawing character).
|
||||
" See vimrc.d/looks.vim for w:ignore_non_ascii_chars
|
||||
if vimwiki#vars#get_syntaxlocal('rxTableSep') !~ '[\d0-\d127]'
|
||||
|
||||
@@ -15,8 +15,10 @@ endfor
|
||||
" needs vim >= 8.1.1719 to support features like popup and text property as well
|
||||
" as nodejs.
|
||||
if ((has('patch-8.1.1719') || has('nvim')) && executable('node'))
|
||||
let g:coc_global_extensions =
|
||||
\ ['coc-clangd', 'coc-sh', 'coc-pyright', 'coc-vimtex', 'coc-vimlsp', 'coc-json']
|
||||
let g:coc_global_extensions = [
|
||||
\ 'coc-clangd', 'coc-sh', 'coc-pyright', 'coc-vimtex',
|
||||
\ 'coc-vimlsp', 'coc-json', 'coc-go'
|
||||
\ ]
|
||||
let g:coc_config_home = $XDG_CONFIG_HOME .. "/vim"
|
||||
packadd coc.nvim
|
||||
endif
|
||||
@@ -24,10 +26,13 @@ endif
|
||||
" ctags
|
||||
if (executable('ctags'))
|
||||
packadd vim-gutentags
|
||||
" Don't index these folders
|
||||
let g:gutentags_ctags_exclude = [
|
||||
\ 'node_modules/*',
|
||||
\ '.git/*',
|
||||
\ 'build/*'
|
||||
\ 'build/*',
|
||||
\ 'venv/*',
|
||||
\ '__pycache__/*'
|
||||
\]
|
||||
endif
|
||||
|
||||
@@ -36,6 +41,12 @@ if (exists("g:loaded_tmux_navigator"))
|
||||
let g:tmux_navigator_disable_when_zoomed = 1
|
||||
endif
|
||||
|
||||
if (get(g:, 'loaded_fzf_vim'))
|
||||
let g:fzf_vim = {}
|
||||
" Use location list instead of quickfix list
|
||||
let g:fzf_vim.listproc = { list -> fzf#vim#listproc#location(list) }
|
||||
endif
|
||||
|
||||
if (get(g:, 'loaded_vimwiki'))
|
||||
" Use vertical box drawing character as table separator
|
||||
call vimwiki#vars#set_syntaxlocal('rxTableSep', '│')
|
||||
@@ -45,4 +56,6 @@ if exists("g:loaded_nrrw_rgn")
|
||||
" Open narrow window above or to the left of the current window (default
|
||||
" is topleft). See :h aboveleft etc.
|
||||
let g:nrrw_topbot_leftright = 'aboveleft'
|
||||
" Leave one more line of padding when the window is small
|
||||
let g:nrrw_rgn_pad = 1
|
||||
endif
|
||||
|
||||
@@ -6,10 +6,6 @@ if !exists('g:did_coc_loaded')
|
||||
finish
|
||||
endif
|
||||
|
||||
" Some servers have issues with backup files, see #649.
|
||||
set nobackup
|
||||
set nowritebackup
|
||||
|
||||
" Always show the signcolumn, otherwise it would shift the text each time
|
||||
" diagnostics appear/become resolved.
|
||||
set signcolumn=yes
|
||||
@@ -68,7 +64,7 @@ endif
|
||||
|
||||
" Make <CR> to accept selected completion item or notify coc.nvim to format
|
||||
" <C-g>u starts a new undo break, please make your own choice.
|
||||
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#pum#confirm()
|
||||
inoremap <silent><expr> <CR> coc#pum#visible() ? coc#_select_confirm()
|
||||
\: "\<C-g>u\<CR>\<c-r>=coc#on_enter()\<CR>"
|
||||
|
||||
" Use `[g` and `]g` to navigate diagnostics
|
||||
|
||||
@@ -119,6 +119,15 @@ if (exists('g:loaded_gitgutter'))
|
||||
" lines have been changed.
|
||||
set foldtext=gitgutter#fold#foldtext()
|
||||
endif
|
||||
" Use the number column for the signcolumn (e.g. gitgutter, lsp diagnostics),
|
||||
" but don't fallback to 'auto' when &number is off
|
||||
" TODO: install autocommand to set signcolumn to yes when number is turned off
|
||||
" (and back to number when turned back on)
|
||||
if &number
|
||||
set signcolumn=number
|
||||
else
|
||||
set signcolumn=yes
|
||||
endif
|
||||
|
||||
" Netrw
|
||||
" Use tree style listing
|
||||
|
||||
@@ -91,40 +91,56 @@ elseif (has('terminal'))
|
||||
nmap <leader><CR> <Cmd>terminal<CR>
|
||||
endif
|
||||
|
||||
" Plugin specific bindings
|
||||
if (get(g:, 'loaded_fzf'))
|
||||
nmap <leader>f <Cmd>Files<CR>
|
||||
nmap <leader>j <Cmd>Lines<CR>
|
||||
nmap <leader>/ <Cmd>Lines<CR>
|
||||
nmap <leader>h <Cmd>Helptags<CR>
|
||||
" TODO: fix this?
|
||||
if (get(g:, 'loaded_gutentags') || 1)
|
||||
nmap <leader>t <Cmd>Tags<CR>
|
||||
nmap <leader>bt <Cmd>BTags<CR>
|
||||
endif
|
||||
nmap <leader>ff <Cmd>Files<CR>
|
||||
nmap <leader>fj <Cmd>Lines<CR>
|
||||
nmap <leader>f/ <Cmd>Lines<CR>
|
||||
nmap <leader>fh <Cmd>Helptags<CR>
|
||||
nmap <leader>ft <Cmd>Tags<CR>
|
||||
nmap <leader>fbt <Cmd>BTags<CR>
|
||||
" git files that `git status` lists
|
||||
nmap <leader>fgf <Cmd>GFiles?<CR>
|
||||
" 'git log (log?)' and 'git log buffer '
|
||||
map <leader>fgll <Cmd>Commits<CR>
|
||||
map <leader>fglb <Cmd>BCommits<CR>
|
||||
" TODO: <leader>fglb should restrict the log to all staged files when called
|
||||
" in .git/COMMIT_EDITMSG, maybe with an ftplugin?
|
||||
endif
|
||||
|
||||
" Search for selected text.
|
||||
" Modified from https://vim.fandom.com/wiki/Search_for_visually_selected_text
|
||||
function! GetVisualSelection()
|
||||
let l:old_reg = getreg('"')
|
||||
let l:old_regtype = getregtype('"')
|
||||
" Modified version of:
|
||||
" https://vim.fandom.com/wiki/Search_for_visually_selected_text
|
||||
" and https://github.com/neovim/neovim/blob/08847a9ea15a/runtime/lua/vim/_defaults.lua#L73-L79
|
||||
function! GetVisualSelection(escape = "", byteescape = 'n')
|
||||
let l:save_reg = getreginfo('"')
|
||||
norm gvy
|
||||
let l:sel = getreg('"')
|
||||
call setreg('"', l:old_reg, l:old_regtype)
|
||||
call setreg('"', l:save_reg)
|
||||
|
||||
let l:sel = l:sel->escape(a:escape)
|
||||
for l:char in a:byteescape
|
||||
let l:sel = l:sel->substitute('\'..l:char, '\\'..l:char, 'g')
|
||||
endfor
|
||||
|
||||
return l:sel
|
||||
endfunction
|
||||
|
||||
vmap * /\V<C-R>=escape(GetVisualSelection(),'/\')<CR><CR>
|
||||
vmap # ?\V<C-R>=escape(GetVisualSelection(),'?\')<CR><CR>
|
||||
" In case these do not exist already (At the time of writing only Neovim adds
|
||||
" mappings for these)
|
||||
if maparg('*', 'v', 0, 1) == {}
|
||||
vmap * /\V<C-R>=GetVisualSelection('/\')<CR><CR>
|
||||
vmap # ?\V<C-R>=GetVisualSelection('?\')<CR><CR>
|
||||
endif
|
||||
|
||||
" Extended `*`. Starts vim search (without jump) and ripgrep
|
||||
nmap <leader>* :let @/ = '\<' . expand('<cword>') . '\>' <bar>
|
||||
\ set hlsearch <bar>
|
||||
\ Rg \b<C-R>=expand('<cword>')<CR>\b<CR>
|
||||
vmap <leader>* :<C-U>let @/ = "\\V<C-R>=escape(escape(GetVisualSelection(), '\'), '"\')<CR>" <bar>
|
||||
" TODO: pass --multiline to rg when multiple lines selected
|
||||
" TODO: Use ^ and $ anchors in visual-line mode
|
||||
vmap <leader>* :<C-U>let @/ = "\\V<C-R>=escape(GetVisualSelection('\'), '"\')<CR>" <bar>
|
||||
\ set hlsearch <bar>
|
||||
\ Rg <C-R>=escape(GetVisualSelection(), '.\[]<bar>*+?{}^$()')<CR><CR>
|
||||
\ Rg <C-R>=GetVisualSelection('.\[]<bar>*+?{}^$()', 'nt')<CR><CR>
|
||||
nmap <leader>g* :let @/ = expand('<cword>') <bar>
|
||||
\ set hlsearch <bar>
|
||||
\ Rg <C-R>=expand('<cword>')<CR><CR>
|
||||
@@ -136,7 +152,8 @@ vmap <leader>/ <Esc><leader>v/
|
||||
|
||||
" Select last pasted text in same visual mode as it was selected (v, V, or ^V)
|
||||
" Taken from: https://vim.fandom.com/wiki/Selecting_your_pasted_text
|
||||
nnoremap <expr> gp '`[' . strpart(getregtype(), 0, 1) . '`]'
|
||||
" TODO: I want the gp default back - find new mapping
|
||||
" nnoremap <expr> gp '`[' . strpart(getregtype(), 0, 1) . '`]'
|
||||
|
||||
" Git bindings
|
||||
|
||||
@@ -153,10 +170,9 @@ nmap <leader>grc :let subject=system('git show -s --date=short --pretty="format:
|
||||
nmap <leader>gso :r!git config --get user.name<CR>:r!git config --get user.email<CR>I<<ESC>A><ESC>kJISigned-off-by: <ESC>
|
||||
|
||||
" Add, stash or checkout the current file
|
||||
" TODO: Conflict with <leader>gf
|
||||
"nmap <leader>gfa <Cmd>!git add -- %<CR>
|
||||
"nmap <leader>gfs <Cmd>!git stash -- %<CR>
|
||||
"nmap <leader>gfu <Cmd>!git checkout -- %<CR>
|
||||
nmap <leader>gfa <Cmd>!git add -- %<CR>
|
||||
nmap <leader>gfs <Cmd>!git stash -- %<CR>
|
||||
nmap <leader>gfu <Cmd>!git checkout -- %<CR>
|
||||
|
||||
if exists('g:loaded_fugitive')
|
||||
" Interactive `git status`
|
||||
@@ -165,6 +181,8 @@ if exists('g:loaded_fugitive')
|
||||
nmap <leader>gcc <Cmd>G commit<CR>
|
||||
" Amend the current commit and open the message in a split
|
||||
nmap <leader>gca <Cmd>G commit --amend<CR>
|
||||
" Commit with the last commit message as template
|
||||
nmap <leader>gclm <Cmd>G commit-last-msg<CR>
|
||||
" Move to root of directory
|
||||
nmap <leader>gcd <Cmd>Gcd<CR>
|
||||
" git blame in scroll bound vertical split (only the commit hashes, see
|
||||
@@ -191,19 +209,12 @@ if exists('g:loaded_gitgutter')
|
||||
xmap ih <Plug>(GitGutterTextObjectInnerVisual)
|
||||
xmap ah <Plug>(GitGutterTextObjectOuterVisual)
|
||||
" Same for hunk navigation bindings + center line
|
||||
" TODO: <leader>[h to jump between **all** hunks across all modified
|
||||
" files. (similar to `add -p`)
|
||||
nmap [h <Plug>(GitGutterPrevHunk)zz
|
||||
nmap ]h <Plug>(GitGutterNextHunk)zz
|
||||
endif
|
||||
|
||||
if (get(g:, 'loaded_fzf'))
|
||||
" git files that `git status` lists
|
||||
nmap <leader>gf <Cmd>GFiles?<CR>
|
||||
" 'git log (log?)' and 'git log buffer '
|
||||
map <leader>gll <Cmd>Commits<CR>
|
||||
map <leader>glb <Cmd>BCommits<CR>
|
||||
" TODO: <leader>glb should restrict the log to all staged files when called
|
||||
" in .git/COMMIT_EDITMSG, maybe with an ftplugin?
|
||||
endif
|
||||
|
||||
" Y should behave like D & C does
|
||||
nnoremap Y y$
|
||||
@@ -441,7 +452,7 @@ vnoremap <leader><C-L> gu
|
||||
" `ExpandVisualSelection(1)` which results in a block selection that spans over
|
||||
" all other TODOs as well.
|
||||
function! ExpandVisualSelection(direction)
|
||||
let l:sel = escape(GetVisualSelection(), '\')
|
||||
let l:sel = GetVisualSelection('\')
|
||||
normal gv
|
||||
|
||||
" Move the cursor onto the side of the selection that points in the
|
||||
|
||||
@@ -50,14 +50,24 @@ if (get(g:, 'loaded_fzf'))
|
||||
endif
|
||||
endif
|
||||
|
||||
" Get red from my colorscheme
|
||||
let s:red = {}
|
||||
if exists("*onedark#GetColors")
|
||||
let s:red = onedark#GetColors()->get("red", {})
|
||||
endif
|
||||
let s:red_cterm = s:red->get("cterm", "red")
|
||||
let s:red_gui = s:red->get("gui", "red")
|
||||
|
||||
" Highlight trailing whitespaces
|
||||
if match(&listchars, 'trail: \@!') > -1 && match(&listchars, '\vtab:( +)@!') > -1
|
||||
" Use foreground for coloring if tabs and trailing spaces are displayed
|
||||
" as non-space characters
|
||||
highlight TrailingWhitespace ctermfg=red guifg=red
|
||||
execute "highlight TrailingWhitespace ctermfg=" .. s:red_cterm
|
||||
\ .. " guifg=" .. s:red_gui
|
||||
else
|
||||
" Background otherwise
|
||||
highlight TrailingWhitespace ctermbg=red guibg=red
|
||||
execute "highlight TrailingWhitespace ctermbg=" .. s:red_cterm
|
||||
\ .. " guibg=" .. s:red_gui
|
||||
endif
|
||||
augroup HighlightTrailingWhitespace
|
||||
au!
|
||||
@@ -74,8 +84,10 @@ let g:spl_special_chars = {
|
||||
\ 'fr': 'àâæçèéêëîïôœùûüÿÀÂÆÇÈÉÊËÎÏÔŒÙÛÜŸ',
|
||||
\ }
|
||||
|
||||
" Highlight non-ASCII characters in the red used by my color scheme "OneDark"
|
||||
highlight NonASCIIChars ctermfg=white guifg=white ctermbg=204 guibg=#e06c75
|
||||
" Highlight non-ASCII characters in red
|
||||
execute "highlight NonASCIIChars ctermfg=white guifg=white "
|
||||
\ .. "ctermbg=" .. s:red_cterm .. " guibg=" .. s:red_gui
|
||||
|
||||
" Do not highlight special characters that are valid in the respective spelllang
|
||||
function! HighlightNonASCIIChars()
|
||||
if exists('w:non_ascii_match_id')
|
||||
|
||||
26
.config/zsh/autoload/git/git-branch-rename
Executable file
26
.config/zsh/autoload/git/git-branch-rename
Executable file
@@ -0,0 +1,26 @@
|
||||
#!/usr/bin/env zsh
|
||||
# SPDX-License-Identifier: MIT
|
||||
# Copyright (c) 2025 Julian Prein
|
||||
#
|
||||
# Rename a branch locally and on a given remote.
|
||||
|
||||
emulate -L zsh -o err_return -o no_unset
|
||||
|
||||
if (( # < 2 || # > 3 )); then
|
||||
printf >&2 "Usage: %s OLD NEW [REMOTE]\n" "${0:t}"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local old new remote
|
||||
old="$1"
|
||||
new="$2"
|
||||
remote="${3:-origin}"
|
||||
|
||||
if ! git remote -v | awk '{ print $1 }' | uniq | grep -q "$remote"; then
|
||||
printf >&2 "Remote '%s' does not exist\n" "$remote"
|
||||
return 1
|
||||
fi
|
||||
|
||||
git checkout-worktree "$old" <<EOF
|
||||
git branch -m "$new" && git push -u && git push -d "$remote" "$old"
|
||||
EOF
|
||||
@@ -31,11 +31,13 @@
|
||||
|
||||
emulate -L zsh -o err_return -o no_unset
|
||||
|
||||
local REPO_NAME WORKTREE_PATH
|
||||
local git_dir cwd_offset REPO_NAME WORKTREE_PATH
|
||||
# Use the folder name of the main working tree to make calls from another
|
||||
# temporary working tree possible
|
||||
REPO_NAME="${${${$(git rev-parse --git-dir):A}%%/.git*}:t}"
|
||||
WORKTREE_PATH="$(mktemp -d -p "" "worktree.XXX.$REPO_NAME.${1//\//_}")"
|
||||
git_dir="${$(git rev-parse --git-dir):A}"
|
||||
[[ $git_dir == */.git/modules/* ]] || git_dir="${git_dir%%/.git*}"
|
||||
REPO_NAME="${git_dir:t}"
|
||||
WORKTREE_PATH="$(mktemp -d -p "" "wtree.$REPO_NAME.${1//\//_}.XXX")"
|
||||
|
||||
local errc ret=0
|
||||
git worktree add "$WORKTREE_PATH" "$@" || ret=$?
|
||||
@@ -47,11 +49,27 @@ fi
|
||||
|
||||
trap '
|
||||
errc=$?
|
||||
<&2 printf "Exiting abnormally. Check and possibly remove '$WORKTREE_PATH' manually.\n"
|
||||
printf >&2 "Exiting abnormally. Check and possibly remove \"%s\" manually.\n" "'"$WORKTREE_PATH"'"
|
||||
return $errc
|
||||
' INT QUIT TERM EXIT
|
||||
|
||||
cwd_offset="${${PWD#$(git rev-parse --show-toplevel)}#/}"
|
||||
pushd -q "$WORKTREE_PATH"
|
||||
until [[ -d $cwd_offset || -z $cwd_offset ]]; do
|
||||
cwd_offset="${cwd_offset:h}"
|
||||
done
|
||||
[[ -z $cwd_offset ]] || cd "$cwd_offset"
|
||||
|
||||
# Discard some environment variables that were set by git when calling this
|
||||
# script through an alias.
|
||||
#
|
||||
# Is set for submodules and will confuse git in the subshell
|
||||
unset GIT_DIR
|
||||
# Not sure if this can bring any issues, but better be safe
|
||||
unset GIT_PREFIX
|
||||
# TODO: Do we want to unset this too? Could have been set on purpose by the user
|
||||
# and not git. Maybe only for the subshell via `env`?
|
||||
#unset GIT_EXEC_PATH
|
||||
|
||||
"$SHELL" && errc=$? || errc=$?
|
||||
(( !errc )) || echo "shell exited with $errc"
|
||||
@@ -59,7 +77,7 @@ pushd -q "$WORKTREE_PATH"
|
||||
# Restart the shell (forcefully interactive) until the worktree is removed
|
||||
until [[ ! -e "$WORKTREE_PATH" ]] || git worktree remove "$WORKTREE_PATH"; do
|
||||
[[ -t 0 ]] ||
|
||||
>&2 printf "Dropping into interactive shell to resolve conflicts\n"
|
||||
printf >&2 "Dropping into interactive shell to resolve conflicts\n"
|
||||
"$SHELL" -i && errc=$? || errc=$?
|
||||
(( !errc )) || echo "shell exited with $errc"
|
||||
done
|
||||
|
||||
@@ -1,6 +1,20 @@
|
||||
#!/usr/bin/env zsh
|
||||
|
||||
git for-each-ref --format='%(upstream),%(refname)' refs/heads refs/remotes \
|
||||
local idx="${@[(ei)--help]}"
|
||||
local flags_end="${@[(ei)--]}"
|
||||
if (( idx < flags_end )); then
|
||||
printf "Usage: $0 [--all] [REMOTE]..."
|
||||
return 0
|
||||
fi
|
||||
|
||||
idx="${@[(ei)--all]}"
|
||||
if (( idx < flags_end )); then
|
||||
# Replace --all flag with empty string. Will be replaced with
|
||||
# refs/remotes/ later so that all remotes are listed
|
||||
set -- "${@[1,$((idx-1))]}" "" "${@[$((idx+1)),-1]}"
|
||||
fi
|
||||
|
||||
git for-each-ref --format='%(upstream),%(refname)' refs/heads "${@/#/refs/remotes/}" \
|
||||
| sort -d \
|
||||
| sed -Ez '
|
||||
s:(^|\n|,)refs/(heads|remotes/):\1:g
|
||||
@@ -8,9 +22,8 @@ git for-each-ref --format='%(upstream),%(refname)' refs/heads refs/remotes \
|
||||
s:,/:,:g
|
||||
s:(^|\n)([^,]+),\n\2:\1\2:g
|
||||
s:(^|\n)([^/,]*)([^\n]*\n\2(,|/))*:\n,\n&:g
|
||||
s:\n,\n+$:\n:
|
||||
' \
|
||||
| (echo remote,local; cat) \
|
||||
s:\n,\n+$:\n:' \
|
||||
| { echo remote,local; cat; } \
|
||||
| sed -E 's:(.*),(.*):\2,\1:g; s:^,: ,:; s:,$:, :' \
|
||||
| column -ts, \
|
||||
| sed '2d; 1{p;s/./―/g}'
|
||||
|
||||
@@ -105,6 +105,7 @@ local -A binds=(
|
||||
"end" "last"
|
||||
"ctrl-d" "half-page-down"
|
||||
"ctrl-u" "half-page-up"
|
||||
"ctrl-s" "toggle-sort"
|
||||
"ctrl-t" "toggle-track"
|
||||
# Keep the current line selected while deleting the query
|
||||
"bspace" "track-current+backward-delete-char"
|
||||
@@ -120,11 +121,11 @@ local -A binds=(
|
||||
# TODO: This assumes less to be used in core.pager
|
||||
"enter" "execute@$fzf_preview[patch] | $pager -+F@"
|
||||
# Preview stats
|
||||
"ctrl-s" "change-preview($fzf_preview[stat])"
|
||||
"ctrl-alt-s" "change-preview($fzf_preview[stat])"
|
||||
# Preview patch
|
||||
"ctrl-p" "change-preview($fzf_preview[patch])"
|
||||
"ctrl-alt-p" "change-preview($fzf_preview[patch])"
|
||||
# Files only
|
||||
"ctrl-f" "change-preview($fzf_preview[files_only])"
|
||||
"ctrl-alt-f" "change-preview($fzf_preview[files_only])"
|
||||
# For ctrl-space see below
|
||||
)
|
||||
|
||||
@@ -132,13 +133,21 @@ local -A binds=(
|
||||
# fzf_preview[stat] in this case). It does not really make sense to pass
|
||||
# it to `git log` but can be an indicator for the preview function
|
||||
|
||||
local color_brown=$'\e[38;5;144m'
|
||||
local color_grey=$'\e[38;5;59m'
|
||||
local header=""
|
||||
header+="${color_brown}Enter${color_grey}: fullscreen, "
|
||||
header+="${color_brown}C-y${color_grey}: yank hash, "
|
||||
header+="${color_brown}C-Space${color_grey}: cycle preview, "
|
||||
header+="${color_brown}C-A-[spf]${color_grey}: preview stats/patch/files"
|
||||
|
||||
local -a fzf_args=(
|
||||
# Understand ansi color escape sequences.
|
||||
"--ansi"
|
||||
# Expand the binds array in the format "key1:value1,key2:value2".
|
||||
"--bind" "${(@kj:,:)binds/(#m)*/$MATCH:$binds[$MATCH]}"
|
||||
# Display key-bindings in a sticky header
|
||||
"--header" $'\e[38;5;144mEnter\e[38;5;59m: fullscreen, \e[38;5;144mC-y\e[38;5;59m: yank hash, \e[38;5;144mC-Space\e[38;5;59m: cycle preview, \e[38;5;144mC-[spf]\e[38;5;59m: preview stats/patch/files'
|
||||
"--header" "$header"
|
||||
# Keep header above prompt line
|
||||
"--header-first"
|
||||
# Execute git show on the commit as preview.
|
||||
|
||||
@@ -128,7 +128,7 @@ fi
|
||||
# Use a reasonable time format
|
||||
alias date='env LC_TIME=tk_TM date'
|
||||
# List human readable sizes in order
|
||||
alias sizes='du -sch * | sort -h'
|
||||
alias sizes='() { du -sch ${1:-*} "${@[2,-1]}" | sort -h }'
|
||||
# Count number of occurrences for every line in stdin
|
||||
alias count='sort | uniq -c | sort -n'
|
||||
# Inspired by https://stackoverflow.com/a/54541337
|
||||
@@ -183,7 +183,7 @@ fi
|
||||
# Default flags
|
||||
add_flags ls --color=auto --group-directories-first -p -v
|
||||
add_flags grep --color=auto --exclude-dir=.git --exclude=tags
|
||||
add_flags cp -i
|
||||
add_flags cp -ia
|
||||
add_flags mv -i
|
||||
# Only add flags if rm is not aliased to a different command (e.g. trash).
|
||||
# NOTE: This also works if rm is not yet aliased.
|
||||
|
||||
1
.local/bin/git-external-script
Symbolic link
1
.local/bin/git-external-script
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.config/git/external-script.sh
|
||||
@@ -1 +0,0 @@
|
||||
../../.config/git/zsh-autoload.sh
|
||||
1
.local/bin/kitty-daemon
Symbolic link
1
.local/bin/kitty-daemon
Symbolic link
@@ -0,0 +1 @@
|
||||
../../.config/kitty/daemon.sh
|
||||
@@ -3,5 +3,26 @@
|
||||
# Copyright (c) 2025 Julian Prein
|
||||
#
|
||||
# Remove ANSI escape sequences.
|
||||
#
|
||||
# Additionally to the general form `\e[ -/]*[0-~]` this also tries to cover
|
||||
# sequences that are followed by additional bytes (e.g. CSI, OSC). This script
|
||||
# covers no C1 sequences.
|
||||
#
|
||||
# The patterns cover the following escape sequences (from top to bottom):
|
||||
# - CSI
|
||||
# - OSC, DCS, PM & APC
|
||||
# - SOS
|
||||
# - All remaining sequences
|
||||
#
|
||||
# See:
|
||||
# - https://en.wikipedia.org/wiki/ANSI_escape_code
|
||||
# - https://www.ecma-international.org/wp-content/uploads/ECMA-35_6th_edition_december_1994.pdf
|
||||
# - https://www.ecma-international.org/wp-content/uploads/ECMA-48_5th_edition_june_1991.pdf
|
||||
|
||||
env LC_ALL=C sed 's/\[[0-?]*[ -/]*[@-z]//g'
|
||||
env LC_ALL=C sed -E "$(printf "%b" \
|
||||
's/' \
|
||||
'\033\\[[0-?]*[ -/]*[@-~]' '|' \
|
||||
'\033[]P^_][\010-\015 -~]*\033\\\\' '|' \
|
||||
'\033X([^\033]|\033+[^\033X\\])*\033+\\\\' '|' \
|
||||
'\033[ -/]*[0-~]' \
|
||||
'//g')"
|
||||
|
||||
@@ -5,4 +5,4 @@
|
||||
# Remove ANSI SGR (Select Graphic Rendition) escape sequences, e.g. setting
|
||||
# color or bold font.
|
||||
|
||||
env LC_ALL=C sed 's/\[[0-?]*[ -/]*m//g'
|
||||
env LC_ALL=C sed "$(printf 's/\033\\[[0-?]*[ -/]*m//g')"
|
||||
|
||||
@@ -62,4 +62,119 @@ git diff --staged --name-only --diff-filter=AT $against \
|
||||
fi
|
||||
done
|
||||
[ "$abort" -eq 0 ] || die
|
||||
}
|
||||
} || exit
|
||||
|
||||
# Make sure that a deletion does not break any symlinks (including renaming a
|
||||
# file)
|
||||
# TODO: switch all these to null-terminated lines
|
||||
deleted_files="$(git diff-index --cached --name-only --diff-filter=D $against)"
|
||||
if [ -n "$deleted_files" ]; then
|
||||
# First, check for broken symlinks in the tree
|
||||
all_broken_links="$(find . -xtype l -exec stat -c '%N' '{}' '+')"
|
||||
|
||||
# NOTE: The cat could be replaced by instead adding the heredoc to the
|
||||
# `done` of the loop, but would make the code much less readable
|
||||
cat <<EOF \
|
||||
| while read -r deletion
|
||||
$deleted_files
|
||||
EOF
|
||||
do
|
||||
# As a first heuristic, check if there is a broken symlink with
|
||||
# a target with the same basename as the deleted file
|
||||
#
|
||||
# TODO: stat escapes quotes sometimes. Does everything work
|
||||
# then?
|
||||
possible_links="$(
|
||||
grep "[\"'/]$(
|
||||
basename "$deletion" \
|
||||
| sed 's/[.[^$*\\]/\\&/g'
|
||||
)[\"']\$" <<EOF
|
||||
$all_broken_links
|
||||
EOF
|
||||
)"
|
||||
[ -n "$possible_links" ] || continue
|
||||
|
||||
cat << EOF \
|
||||
| while read -r link
|
||||
$possible_links
|
||||
EOF
|
||||
do
|
||||
# TODO: this is probably quite brittle, depending on how
|
||||
# `stat` quotes source and target
|
||||
target="${link##* -> [\"\']}"
|
||||
target="${target%[\"\']}"
|
||||
source="${link%%[\"\'] -> *}"
|
||||
source="${source#[\"\']}"
|
||||
|
||||
if [ -z "${target##/*}" ]; then
|
||||
# absolute link
|
||||
if [ "$target" = "$PWD/$deletion" ]; then
|
||||
die "You broke the symlink $link"
|
||||
fi
|
||||
else
|
||||
# relative link
|
||||
target="$(realpath -m "$source/../$target")"
|
||||
if [ "$target" = "$PWD/$deletion" ]; then
|
||||
die "You broke the symlink $link"
|
||||
fi
|
||||
fi
|
||||
done || exit
|
||||
done || exit
|
||||
|
||||
# Second, check all symlinks in the index if they still point to the
|
||||
# deleted file
|
||||
all_links_in_index="$(
|
||||
git ls-files --format="%(objectmode) %(objectname) %(path)" \
|
||||
| grep '^120000'
|
||||
)"
|
||||
|
||||
cat <<EOF \
|
||||
| while read -r deletion
|
||||
$deleted_files
|
||||
EOF
|
||||
do
|
||||
# As a first heuristic, get all links in the tree with a target
|
||||
# with the same basename as the deleted file
|
||||
possible_links="$(
|
||||
cut -d' ' -f2 <<EOF \
|
||||
| git cat-file --batch \
|
||||
| grep -B1 "\(^\|/\)$(
|
||||
basename "$deletion" \
|
||||
| sed 's/[.[^$*\\]/\\&/g'
|
||||
)\$" \
|
||||
| paste - -
|
||||
$all_links_in_index
|
||||
EOF
|
||||
)"
|
||||
[ -n "$possible_links" ] || continue
|
||||
|
||||
cat << EOF \
|
||||
| while read -r link
|
||||
$possible_links
|
||||
EOF
|
||||
do
|
||||
target="${link#* }"
|
||||
source="$(
|
||||
grep -F "${link%% *}" <<EOF \
|
||||
| cut -d' ' -f3-
|
||||
$all_links_in_index
|
||||
EOF
|
||||
)"
|
||||
|
||||
if [ -z "${target##/*}" ]; then
|
||||
# absolute link
|
||||
if [ "$target" = "$PWD/$deletion" ]; then
|
||||
die "You broke the symlink \"$source\" -> \"$target\""
|
||||
fi
|
||||
else
|
||||
# relative link
|
||||
target="$(realpath -m "$source/../$target")"
|
||||
if [ "$target" = "$PWD/$deletion" ]; then
|
||||
die "You broke the symlink \"$source\" -> \"$target\""
|
||||
fi
|
||||
fi
|
||||
done || exit
|
||||
done || exit
|
||||
|
||||
# TODO: also check potential symlinks pointing to now empty directories
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user