Compare commits

...

125 Commits

Author SHA1 Message Date
d41f82c771 Update submodules 2025-06-29 18:49:21 +09:00
c77fa00f98 Fix pyenv 2025-06-21 18:28:35 +09:00
da8cc2b511 Update submodules 2025-05-19 22:16:31 +09:00
ef9c4afff3 Update submodules 2025-04-30 21:43:41 +09:00
9dcf45baa5 Update submodules 2025-04-17 21:28:52 +09:00
4ac2c06595 Merge branch 'main' of git.zander.im:Zander671/zsh-config 2025-03-18 22:53:43 +09:00
4935fdbf15 Update submodules 2025-03-18 22:53:29 +09:00
ffb23c98fc Remove ros2 stuff 2025-03-18 22:53:12 +09:00
8bc2b5efe5 Update aliases 2025-03-01 21:42:25 -08:00
2ff695ea43 Undo last commit 2025-02-26 15:09:46 -08:00
b784c01fc2 Source $EAT_SHELL_INTEGRATION_DIR/zsh 2025-02-26 14:48:24 -08:00
cd640456b1 Update submodules 2025-02-24 21:54:04 -08:00
6b7760784a Use the new server-eval-args-left 2025-02-24 19:10:33 -08:00
74d4fab26a Fix the last commit 2025-02-22 03:50:38 -08:00
645a6858b6 Fix tramp creating random files 2025-02-22 03:49:54 -08:00
1af11843ad Fix last commit 2025-02-20 19:28:55 -08:00
743332253a More bat stuff 2025-02-20 19:24:56 -08:00
f4526ea7a7 Fix bat in distrobox 2025-02-20 18:48:41 -08:00
b2e82b80d3 Improve distrobox detection 2025-02-18 13:13:15 -08:00
c06a7bffee Fix last commit 2025-02-18 06:25:44 -08:00
b8c898b3cc Some container stuff 2025-02-18 06:25:06 -08:00
5ff2811927 (Even x3) more changes to distrobox stuff 2025-02-17 21:27:08 -08:00
8579ba568b (Even even) more stuff for distrobox 2025-02-17 02:21:03 -08:00
5ed7f948ef Fix the last commit 2025-02-17 02:09:01 -08:00
4d0a221db4 Change editor for distrobox (again) 2025-02-17 02:07:08 -08:00
d20b129666 More stuff for older versions 2025-02-17 01:57:44 -08:00
b5c3ea0edb Make emacs-bookmark.zsh work on older versions of zsh 2025-02-17 01:10:03 -08:00
7c85a1d3ee (Even) more ros2 stuff 2025-02-17 00:50:44 -08:00
c3a8204ad2 Update lazy-ros2.zsh 2025-02-17 00:13:11 -08:00
5fae0b7ece Fix formatting 2025-02-17 00:05:33 -08:00
cfae639ad5 A few more compatability things 2025-02-16 23:58:26 -08:00
db749437ee More distrobox changes 2025-02-16 23:13:58 -08:00
4a3a91dd9c Add some more distrobox stuff 2025-02-16 23:06:32 -08:00
f21f778bd5 Alias doas to sudo if doas is not installed 2025-02-16 20:53:51 -08:00
ed1ccdcaec Add conditions to some init stuff 2025-02-16 20:52:45 -08:00
e6fdd25097 Remove debug statements 2025-02-15 22:43:00 -08:00
58da9200fc Merge branch 'main' of git.zander.im:Zander671/zsh-config 2025-02-15 22:41:31 -08:00
b57afeec32 Fix ros2 stuff 2025-02-15 22:41:04 -08:00
9962c7159b Update submodules 2025-02-12 11:24:44 -08:00
4348e98b97 Speed up the ros2 stuff 2025-02-11 03:29:15 -08:00
b85772067d Add init file timings and lazy load ros2 stuff 2025-02-10 23:26:27 -08:00
561596711f Add pyenv support 2025-01-27 03:00:17 -08:00
ca65659782 Move zsh-autosuggestions 2024-11-03 11:19:41 -08:00
c58ea7b136 Change to a more reliable emacs communication method 2024-11-03 10:30:31 -08:00
1b290bcf23 Fix debuginfod.sh 2024-11-02 09:22:27 -07:00
dfd7dddf75 Remove call to dirname(1) 2024-11-02 08:16:03 -07:00
d1d2422485 Add .local/share to $FPATH 2024-11-02 08:07:43 -07:00
50389ec227 Fix something with eza 2024-10-22 07:21:44 -07:00
03d7b3e1cf The temp fix stopped working 2024-10-21 05:32:43 -07:00
96ace6e0e8 Update submodules 2024-09-17 05:32:07 -07:00
d61e758c1c Clean up init.zsh 2024-09-10 02:16:14 -07:00
a16907ed82 Update submodules 2024-09-10 02:13:25 -07:00
6cf3c3c740 Add file offset support to emacs-bookmark.zsh 2024-09-08 14:47:51 -07:00
79695758a5 Fix emacs-bookmark.zsh (again) 2024-08-30 14:06:11 -07:00
aab934f5a1 Update emacs-bookmark.zsh 2024-08-27 18:39:17 -07:00
38f0a9fc2b Update emacs-bookmark.zsh 2024-08-27 18:36:33 -07:00
9abe05ccfe Update after bmrm 2024-08-27 11:34:24 -07:00
181dd2d533 Add auto-updating of bookmarks 2024-08-27 11:28:29 -07:00
06c33df30d Remove bookmark.zsh 2024-08-26 10:37:03 -07:00
db347d3f5c Finish fixing (hopefully) emacs-bookmark.zsh 2024-08-26 10:34:50 -07:00
8d3ef4b4e4 Update emacs-bookmark.zsh 2024-08-24 17:01:23 -04:00
7f7aa9def4 Update emacs-bookmark.zsh 2024-08-21 01:26:09 -04:00
9b90c216f3 Update emacs-bookmark.zsh 2024-08-20 00:37:48 -04:00
f22d24b042 Update emacs-bookmark.zsh 2024-08-18 11:42:48 -07:00
b39f4ce968 Update submodules 2024-08-17 11:52:15 -07:00
b67571bd7a Remove old ssh stuff in early-init.zsh 2024-08-07 15:07:07 -07:00
edddc6ece7 Update submodules 2024-08-06 20:37:39 -07:00
d958a4552d Update submodules 2024-08-01 01:01:06 -08:00
3d8c339eb8 Update submodules 2024-07-07 22:29:07 -07:00
1dc95bf2fd Merge branch 'main' of git.zander.im:Zander671/zsh-config 2024-07-07 22:28:41 -07:00
34d70ea469 Update submodules 2024-06-08 17:24:06 -07:00
0bdab76bba Update submodules 2024-05-14 14:42:57 -07:00
02b3a5ff58 Remove dired alias 2024-05-12 19:21:37 -07:00
c030bd1ab7 Switch to river 2024-04-28 21:14:14 -07:00
4ccf5cb65d Add gd alias 2024-04-20 16:10:03 -07:00
c05f963d1b Merge branch 'main' of git.zander.im:Zander671/zsh-config 2024-03-27 03:04:20 -07:00
5149ce5797 Change sudo stuff 2024-03-27 02:54:07 -07:00
bc925168c3 Update .gitmodules 2024-03-27 02:10:53 -07:00
99c08d92be Change to fast-syntax-highlighting 2024-03-27 01:56:49 -07:00
b65379da0b Update submodules 2024-03-27 01:46:25 -07:00
3f8ddf76c3 Update submodules 2024-03-13 02:14:29 -07:00
c94d82c571 Fix newlines in filenames in emacs-bookmark.zsh 2024-03-10 18:11:29 -07:00
8459b7e1ac Add extra confirmation to emacs-bookmark.zsh 2024-03-10 06:32:19 -07:00
bf92e25100 Add completions to emacs-bookmark.zsh 2024-03-10 06:12:51 -07:00
c971f1b6e8 Change to emacs-bookmark.zsh 2024-03-10 05:54:07 -07:00
40900a9973 Update submodules 2024-03-08 19:30:47 -08:00
bda1af923b Clean up init.zsh 2024-03-04 22:44:22 -08:00
c3f012d74a Update early-init.zsh 2024-02-29 19:39:12 -08:00
da4f9d56d3 Fix ssh in early-init.zsh 2024-02-26 15:53:18 -08:00
99e303e4c7 Update submodules 2024-01-28 14:17:29 -08:00
07c828a78e Edit cowsay and fortune conditions 2024-01-12 15:26:00 -08:00
6a35848f7a Add fzf to README.md 2024-01-12 15:09:49 -08:00
f0146c7e30 Fix formatting in README.md 2024-01-12 15:08:07 -08:00
0351cace86 Update docs and add an option for graphical login 2024-01-12 15:05:09 -08:00
a17ad2dc3c Add -a to emacsclient aliases 2024-01-09 21:35:32 -08:00
3079b878eb Clean up gcm and gcam 2024-01-09 15:30:33 -08:00
bb0b1ede16 Add some dired aliases and functions 2024-01-09 15:15:45 -08:00
0464d98f61 Update submodules 2023-12-22 21:30:56 -08:00
68d322bcc5 Update submodules 2023-12-12 00:45:54 -08:00
462d775b4a Add histignorespace 2023-11-28 04:18:41 -08:00
e1e5d46397 Update submodules 2023-11-27 21:06:41 -08:00
f485222a35 Update ledger 2023-11-21 04:30:25 -08:00
309b32e515 Reorganize files 2023-11-21 04:04:09 -08:00
f1e1c5ddb3 Change desktop to wayland 2023-11-14 20:42:33 -08:00
09cb14327a Add ledger stuff 2023-11-07 19:42:16 -08:00
0782847c63 Fix trash-cli 2023-10-30 22:50:04 -07:00
000057b2c4 Add trash-cli 2023-10-30 22:46:28 -07:00
7525f80708 Enable rc_quotes 2023-10-30 20:49:20 -07:00
6d1873b6cd Make clip alias work on wayland 2023-10-30 00:39:26 -07:00
11d6c98b03 Update submodules 2023-10-29 02:43:07 -07:00
436e8154dd Fix bat man paging 2023-10-20 15:12:45 -07:00
4fd80a7b6b Fix arch.zsh 2023-10-15 22:39:36 -07:00
a2e439d61f Make 'n' alias run emacsclient 2023-10-15 15:27:04 -07:00
75408901c0 Improve emacs aliases 2023-09-30 21:40:00 -07:00
e7f9937b52 Update SSH_AUTH_SOCK 2023-09-29 13:01:53 -07:00
e92030f555 Update early-init.alexanders-desktop.zsh 2023-09-29 10:43:04 -07:00
28873a2dbd Update submodules 2023-09-29 03:27:14 -07:00
b6f387bb53 Update local/early-init.alexanders-portable.zsh 2023-09-29 03:26:53 -07:00
c1e3dc4b8f Change to emacs 2023-09-27 16:34:49 -07:00
37f663c57d Removed dots command 2023-09-15 14:59:31 -07:00
aca4f1d814 Added early-init.alexanders-portable.zsh 2023-09-15 14:58:52 -07:00
481ff81c65 Make machine specific config better 2023-09-15 14:55:47 -07:00
8f63b3227b Fix for emacs vterm 2023-09-12 03:06:00 -07:00
767a63e810 Update submodules 2023-09-10 03:40:34 -07:00
94c1c60820 Change exa to eza 2023-09-10 03:40:05 -07:00
13 changed files with 572 additions and 172 deletions

8
.gitmodules vendored
View File

@ -2,10 +2,6 @@
path = plugins/zsh-history-substring-search
url = https://github.com/zsh-users/zsh-history-substring-search.git
ignore = untracked
[submodule "zsh-syntax-highlighting"]
path = plugins/zsh-syntax-highlighting
url = https://github.com/zsh-users/zsh-syntax-highlighting.git
ignore = untracked
[submodule "zsh-autosuggestions"]
path = plugins/zsh-autosuggestions
url = https://github.com/zsh-users/zsh-autosuggestions.git
@ -18,3 +14,7 @@
path = plugins/fzf-tab
url = https://github.com/Aloxaf/fzf-tab.git
ignore = dirty
[submodule "fast-syntax-highlighting"]
path = plugins/fast-syntax-highlighting
url = https://github.com/zdharma-continuum/fast-syntax-highlighting.git
ignore = untracked

View File

@ -4,8 +4,10 @@ This is my personal zsh configuraton.
### Requirements
* [starship](https://github.com/starship/starship) - a pretty and fast prompt
* [direnv](https://github.com/direnv/direnv)* - runs on cd, safely set enviroment
* [exa](https://github.com/ogham/exa)* - better ls
* [eza](https://github.com/eza-community/eza)* - better ls
* [bat](https://github.com/sharkdp/bat)* - better cat, less, man, etc.
* [trash-cli](https://github.com/andreafrancia/trash-cli)* - safer deletion
* [fzf](https://github.com/junegunn/fzf)* - better auto-complete
(* = optional)
@ -24,13 +26,48 @@ source "${ZSH_CONFIG_DIR}/init.zsh"
* ZSH_BOOKMARK_DIR: Bookmark directory (default: ~/.cache/zsh/bookmarks)
* ZSH_BOOKMARK_LS: If true, run `ls` after jumping to a bookmark (default:
true)
* ZSH_USER_DIR: Directory containing configuration files (see below, default:
~/.zsh.d)
* ZSH_GRAPHICAL_LOGIN: Whether or not to enable starting a graphical session
when a login shell is started (default: true)
### Aliases
I use a lot of aliases. Because a lot of the aliases are only enabled if the
corresponding piece of software is installed (see above), it is hard to give a
full list. Therefore you should think of the following list as a guide and read
`init.zsh` if you want a full list.
* `ls`: eza --git -F
* `la`: eza --git -Fa
* `l`: eza --git -Fl
* `ll`: eza --git -Fla
* `cat`: bat --paging=never
* `pcat`: bat -pp
* `ncat`: bat -pp --color=never
* `e`: emacsclient -a nvim -nw
* `n`: emacsclient -a nvim -nw
* `emacs`: emacsclient -a nvim -nw
* `d`: *start dired in either the current or provided directory*
* `dired`: *start dired in either the current or provided directory*
* `se`: sudoedit
* `mv`: mv -i
* `cp`: cp -i
* `rm`: *disabled if trash-cli is installed*
* `tp`: trash-put
* `trr`: trash-restore
* `trl`: trash-list
* `tre`: trash-empty
* `trm`: trash-rm
* `gt`: git status
* `ga`: git add
* `gaa`: git add -A
* `gc`: git commit
* `gf`: git fetch
* `gu`: git pull
* `gp`: git push
* `gcm`: *git commit -m, but treat all following args as the message (like echo)*
* `gacm`: *git commit -am, but treat all following args as the message (like echo)*
### Configuration
To configure, create `~/.zsh.d` (or set ZSH_USER_DIR as described above). The
create either of the option files `init.zsh` and `early-init.zsh`. The former is
run in the middle of startup, after most plugins have been initialized, but
before ones related to command history, auto-complete, etc. The latter is run as
the first thing in the configuration file (after `autoload -U compinit &&
compinit`).
Previous versions of this configuration supported files that were not under
version control to be run during initialization of the shell. However the
current version does not support this. Configuring the shell requires editing
either `init.zsh` or `early-init.zsh`.

View File

@ -1,3 +1,6 @@
# Arch specific config options
export DEBUGINFOD_URLS="https://debuginfod.archlinux.org"
function () {
emulate -L sh
source "/etc/profile.d/debuginfod.sh"
}
source "/usr/share/doc/pkgfile/command-not-found.zsh"

View File

@ -1,73 +0,0 @@
# A simple bookmark system
# $ZSH_BOOKMARK_DIR must be defined
# Create bookmark directory if it does not exist
[ ! -d "${ZSH_BOOKMARK_DIR}" ] && mkdir -p "${ZSH_BOOKMARK_DIR}"
function __zsh_list_bookmarks {
/bin/ls "${ZSH_BOOKMARK_DIR}"
}
function __zsh_check_bookmark_name {
! [[ "${1}" == *'/'* ]]
}
function _bookmarks {
for file in "${ZSH_BOOKMARK_DIR}/"*; do
compadd "${file#"${ZSH_BOOKMARK_DIR}/"}"
done
}
# bm <bookmark>
function bm {
# With no args, list all bookmarks
[ "${#}" -eq 0 ] && { __zsh_list_bookmarks; return }
# Otherwise, goto the bookmark in argv[1]
__zsh_check_bookmark_name "${1}" || { echo "No such bookmark: '${1}'!"; return 1 }
[ -L "${ZSH_BOOKMARK_DIR}/${1}" ] || { echo "No such bookmark: '${1}'!"; return 1 }
[ -e "${ZSH_BOOKMARK_DIR}/${1}" ] || { echo "The bookmark '${1}' refers to a non-existant file!"; return 1 }
cd -P "${ZSH_BOOKMARK_DIR}/${1}"
[[ -v ZSH_BOOKMARK_LS ]] && "${ZSH_BOOKMARK_LS}" && ls
}
function _bm {
_arguments '::bookmark:_bookmarks'
}
compdef _bm bm
# bmadd [name] [dir]
function bmadd {
# With no args, add pwd
[ "${#}" -eq 0 ] && { bmadd "$(basename "${PWD}")" "${PWD}"; return }
# With one arg, add pwd as argv[1]
[ "${#}" -eq 1 ] && { bmadd "${1}" "${PWD}"; return }
local real_path="$(realpath "${2}")"
local bm_name="${1}"
__zsh_check_bookmark_name "${bm_name}" || { echo "Invalid bookmark: '${1}'!"; return 1 }
if [ -L "${ZSH_BOOKMARK_DIR}/${bm_name}" ]; then
echo "A bookmark with the name '${bm_name}' already exists!"
local reply
read -q 'reply?Overwrite? [y/N] '
printf '\n'
[[ "${reply}" =~ '[yY]' ]] || return 1
fi
ln -nfs "${real_path}" "${ZSH_BOOKMARK_DIR}/${bm_name}"
echo "Created bookmark '${bm_name}'"
}
function _bmadd {
_arguments ':name' '::directory:_directories'
}
compdef _bmadd bmadd
# bmrm <name>
function bmrm {
[ "${#}" -eq 0 ] && { echo "usage: bmrm <name>"; return 1 }
__zsh_check_bookmark_name "${1}" || { echo "No bookmark with the name '${1}' exists!"; return 1 }
[ -L "${ZSH_BOOKMARK_DIR}/${1}" ] || { echo "No bookmark with the name '${1}' exists!"; return 1 }
local reply
read -q 'reply?Really delete? [y/N] '
printf '\n'
[[ "${reply}" =~ '[yY]' ]] || return 1
/bin/rm "${ZSH_BOOKMARK_DIR}/${1}"
echo "Deleted bookmark '${1}'"
}
function _bmrm {
_arguments ':bookmark:_bookmarks'
}
compdef _bmrm bmrm

16
early-init.zsh Normal file
View File

@ -0,0 +1,16 @@
# Some extra environment variables
export PATH="${HOME}/.local/bin:${PATH}"
# Because I use zsh to start graphical sessions
[[ -v ZSH_GRAPHICAL_LOGIN ]] || ZSH_GRAPHICAL_LOGIN=true
if [[ -o login ]] && [[ "${ZSH_GRAPHICAL_LOGIN}" = 'true' ]] ; then
export LC_ALL=en_US.UTF-8
eval "$(gnome-keyring-daemon --start 2>/dev/null)"
export SSH_AUTH_SOCK="${XDG_RUNTIME_DIR}/gcr/ssh"
export SSH_ASKPASS=/usr/lib/seahorse/ssh-askpass
if ! [[ -v WAYLAND_DISPLAY ]] && [ "${XDG_VTNR}" -eq 1 ]; then
source "${HOME}/.config/river/river-env.sh"
exec river
fi
fi

300
emacs-bookmark.zsh Normal file
View File

@ -0,0 +1,300 @@
# Emacs-based bookmark system
autoload colors && colors
zmodload -F zsh/stat b:zstat
zmodload zsh/datetime
zmodload zsh/mapfile
local __bm_bookmark_cache=()
let __bm_last_read_time=-1
function __bm_offset_to_row_col {
let off="${2}"
let row=1
let col=0
for line in "${(@f)mapfile[${1}]}"; do
let len="${#line}"
if (( off > len )); then
off='off - (len + 1)'
if (( off <= 0 )); then
(( len == 0 )) && col=0 || col='len - 1'
break
fi
row+=1
else
col='off'
off=0
break;
fi
done <"${1}"
if (( off > 0 )); then
row+=-1
fi
printf '%d\0%d' "${row}" "${col}"
}
function __bm_find_user_emacs_dir {
[[ -f "${HOME}/.emacs.d/var/bookmark-default.el" ]] &&
{ printf '%s' "${HOME}/.emacs.d/var/bookmark-default.el"; return 0 }
[[ -f "${HOME}/.emacs.d/bookmark-default.el" ]] &&
{ printf '%s' "${HOME}/.emacs.d/bookmark-default.el"; return 0 }
[[ -f "${HOME}/.config/emacs/var/bookmark-default.el" ]] &&
{ printf '%s' "${HOME}/.config/emacs/var/bookmark-default.el"; return 0 }
[[ -f "${HOME}/.config/emacs/bookmark-default.el" ]] &&
{ printf '%s' "${HOME}/.config/emacs/bookmark-default.el"; return 0 }
[[ -f "${XDG_CONFIG_HOME}/emacs/var/bookmark-default.el" ]] &&
{ printf '%s' "${XDG_CONFIG_HOME}/emacs/var/bookmark-default.el"; return 0 }
[[ -f "${XDG_CONFIG_HOME}/emacs/bookmark-default.el" ]] &&
{ printf '%s' "${XDG_CONFIG_HOME}/emacs/bookmark-default.el"; return 0 }
printf 'Could not discover Emacs bookmark file! Please set $BM_MODE to
"daemon" or define $BM_BOOKMARK_PATH!\n'
return 1
}
BM_BOOKMARK_PATH="${BM_BOOKMARK_PATH:-"$(__bm_find_user_emacs_dir)"}"
function __bm_hash_dirs {
# First empty the hash table
hash -dr
# Then add the hash dirs
for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do
local name="${__bm_bookmark_cache[${i}]://=/}"
hash -d "${name}=${__bm_bookmark_cache[${i} + 2]}"
done
}
function __bm_update_bookmark_list {
__bm_last_read_time="${EPOCHSECONDS}"
local args
local script
case "${BM_MODE}" in
'daemon')
script=$(<<'EOF'
(progn
(require 'server)
(dolist (entry (server-eval-at
"server"
'(when (boundp 'bookmark-alist)
bookmark-alist)))
(let ((path (alist-get 'filename (cdr entry) ""))
(pos (alist-get 'position (cdr entry) 1)))
(princ (format "%s\0%s\0%s\0%s\0" (car entry) path
(expand-file-name path) pos)))))
EOF
)
;;
''|'emacs')
args="--insert=${BM_BOOKMARK_PATH}"
script=$(<<'EOF'
(progn
(dolist (entry (read (current-buffer)))
(let ((path (alist-get 'filename (cdr entry) ""))
(pos (alist-get 'position (cdr entry) 1)))
(princ (format "%s\0%s\0%s\0%s\0" (car entry) path
(expand-file-name path) pos)))))
EOF
)
;;
*)
printf 'Unknown value for $BM_MODE: "%s"\n' "${BM_MODE}"
return 1
;;
esac
__bm_bookmark_cache=(${(0)"$(command emacs --batch ${args} --eval "${script}")"})
__bm_hash_dirs
}
function __bm_bookmark_location {
local parts=(${(s:/:)"${2}"})
local bm_name="${parts[1]}"
local rest_arr=(${parts:1})
local rest="${(j:/:)rest_arr}"
for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do
if [[ "${bm_name}" = "${__bm_bookmark_cache[${i}]}" ]]; then
__bm_res=("${__bm_bookmark_cache[${i} + 2]}"
"${__bm_bookmark_cache[${i} + 3]}"
"${rest}")
return 0
fi
done
__bm_res=()
return 1
}
function __bm_list_bookmarks {
for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do
local name="${__bm_bookmark_cache[${i}]}"
local pretty_path="${__bm_bookmark_cache[${i} + 1]}"
local abs_path="${__bm_bookmark_cache[${i} + 2]}"
local print_color=""
if [[ -d "${abs_path}" ]]; then
print_color="${bold_color}${fg[blue]}"
fi
printf "${print_color}%s${reset_color} => %s\n" \
"${name}" "${pretty_path}"
done
}
function _bookmarks {
for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do
compadd -q "${__bm_bookmark_cache[${i}]}"
done
}
alias lsbm="__bm_update_bookmark_list && __bm_list_bookmarks"
function bm {
__bm_update_bookmark_list || \
{ printf 'Updating bookmark list failed!\n'; return 1 }
(( ${#} == 0 )) && { __bm_list_bookmarks; return }
local __bm_res
__bm_bookmark_location __bm_res "${1}"
local bm_loc="${__bm_res[1]}"
local target="${__bm_res[1]}/${__bm_res[3]}"
if (( ${#__bm_res} != 0 )) && [[ -e "${bm_loc}" ]]; then
if [[ -d "${target}" ]]; then
cd "${target}"
[[ "${BM_CWD_LS}" == 'true' ]] && ls || true
elif [[ -e "${bm_loc}" ]]; then
let offset="${__bm_res[2]}"
local rowcol=(${(0)"$(__bm_offset_to_row_col "${bm_loc}" "${offset}")"})
${=EDITOR} "+${rowcol[1]}:${rowcol[2]}" "${bm_loc}"
else
printf 'Bookmark exists, but trailing path doesn'"'"'t: "%s"\n' \
"${(q)__bm_res[3]}"
return 1
fi
else
printf 'No such bookmark: "%s"\n' "${(q)1}"
return 1
fi
}
function _bm {
(( "${CURRENT}" == 2 )) || return
local arg="${(Q)words[${CURRENT}]}"
if ! [[ "${arg}" == */* ]]; then
for ((i = 1; i < ${#__bm_bookmark_cache}; i+=4)); do
compadd -q -S '/' -- "${__bm_bookmark_cache[${i}]}"
done
else
local __bm_res
__bm_bookmark_location __bm_res "${arg}"
if [[ -d "${__bm_res[1]}" ]]; then
local parts=(${(s:/:)__bm_res[3]})
local bm="${${(s:/:)${arg}}[1]}"
local subdir="${(j:/:)parts[1,-2]}"
local search="${parts[${#parts}]}"
if ((${#parts} > 0)) && [[ "${arg}" == */ ]]; then
subdir="${subdir}/${search}"
subdir="${subdir#/}"
search=""
fi
local pre_path="${__bm_res[1]}/${subdir}/"
local raw_arg="${words[${CURRENT}]}"
local prefix="${${(s:/:)${raw_arg}}[1]}/${subdir}"
if ! [[ -z "${subdir}" ]]; then
prefix+='/'
fi
compset -P "${(b)prefix}"
for file in "${pre_path}"*; do
compadd -W "${pre_path}" -f "${file:t}"
done
fi
fi
}
compdef _bm bm
function bmadd {
if [[ "${1}" = '-h' ]]; then
printf 'usage: bmadd [PATH] [NAME]\n'
return 0
fi
[[ "${1}" = '--' ]] && shift 1
local name
local loc
case "${#}" in
0)
loc="${PWD}"
name="${PWD:t}"
;;
1)
loc="${1}"
name="${1:t}"
;;
*)
loc="${1}"
name="${2}"
;;
esac
__bm_update_bookmark_list
local __bm_res
if __bm_bookmark_location __bm_res "${name}" >/dev/null; then
printf 'Bookmark "%s" already exists. Overwrite it? [y/N] ' "${(q)name}"
read -q
let ans=${?}
printf '\n'
(( ${ans} != 0 )) && return 1
fi
local res="$(emacsclient --eval \
"(let* ((loc (pop server-eval-args-left))
(name (pop server-eval-args-left))
(res (with-temp-buffer
(set-visited-file-name loc t nil)
(bookmark-set name)
(set-buffer-modified-p nil)))
(inhibit-message t))
(bookmark-save)
res)" "${loc}" "${name}")"
[[ "${res}" = 'nil' ]] && printf 'Added bookmark "%s"\n' "${(q)name}" \
|| { printf '%s\n' "${res}"; return 1 }
__bm_update_bookmark_list
}
function _bmadd {
_arguments ':file:_files' ':name'
}
compdef _bmadd bmadd
function bmrm {
if [[ "${1}" = '-h' ]]; then
printf 'usage: bmrm [NAME]\n'
return 0
fi
[[ "${1}" = '--' ]] && shift 1
if (( ${#} < 1 )); then
printf 'usage: bmrm [NAME]\n'
return 1
fi
__bm_update_bookmark_list
local __bm_res
__bm_bookmark_location __bm_res "${1}" >/dev/null || \
{ printf 'No such bookmark: "%s"\n' "${1}"; return 1 }
printf 'Really delete "%s"? [y/N] ' "${(q)1}"
if read -q; then
printf '\n'
local res="$(emacsclient --eval \
"(let* ((res (bookmark-delete (pop server-eval-args-left)))
(inhibit-message t))
(bookmark-save)
res)" "${1}")"
[[ "${res}" = 'nil' ]] && printf 'Deleted bookmark "%s"\n' "${(q)1}" \
|| { printf '%s\n' "${res}"; return 1 }
__bm_update_bookmark_list
else
printf '\n'
return 1
fi
}
function _bmrm {
_arguments ':bookmark:_bookmarks'
}
compdef _bmrm bmrm
function __bm_precmd_hook {
# Auto reload
if [[ "${BM_AUTO_RELOAD}" == true ]] &&
(( ${__bm_last_read_time} < $(zstat +mtime "${BM_BOOKMARK_PATH}") )); then
__bm_update_bookmark_list
fi
}
(( ${precmd_functions[(I)__bm_precmd_hook]} )) ||
precmd_functions+=(__bm_precmd_hook)
__bm_update_bookmark_list

277
init.zsh
View File

@ -1,6 +1,10 @@
# Main zsh config file
zmodload zsh/datetime
let __init_zsh_start="${EPOCHREALTIME}"
# Enable completions
FPATH="${HOME}/.local/share/zsh/site-functions:${FPATH}"
autoload -U compinit && compinit
# Some utility stuff
@ -13,88 +17,191 @@ function load_plugin {
function cmd_exists {
hash "${1}" >/dev/null 2>&1
}
# User configuration file
[[ -v ZSH_USER_DIR ]] || ZSH_USER_DIR="${HOME}/.zsh.d"
# source_user_file <name>
function source_user_file {
[ -e "${ZSH_USER_DIR}/${1}" ] && source "${ZSH_USER_DIR}/${1}"
local machine_specific="${ZSH_CONFIG_DIR}/${1}.${HOST}.zsh"
local default="${ZSH_CONFIG_DIR}/${1}.zsh"
if [ -e "${machine_specific}" ]; then
source "${machine_specific}"
elif [ -e "${default}" ]; then
source "${default}"
fi
}
# Load user early init file
source_user_file "early-init.zsh"
source_user_file "early-init"
# Load distrobox early init file
local is_in_distrobox=false
if [[ -e /run/.containerenv ]] && cmd_exists distrobox-host-exec; then
is_in_distrobox=true
local ctenv=("${(@f)"$(</run/.containerenv)"}")
for line in ${ctenv}; do
if [[ "${line}" == 'name='* ]]; then
export DISTROBOX_MY_NAME="${(Q)${line:5}}"
if [[ -d "${HOME}/src/compat/${DISTROBOX_MY_NAME}" ]]; then
export DISTROBOX_MY_COMPAT="${HOME}/src/compat/${DISTROBOX_MY_NAME}"
local init_file="${DISTROBOX_MY_COMPAT}/early-init.zsh"
[[ -e "${init_file}" ]] && source "${init_file}"
fi
break
fi
done
fi
# Some options
setopt autocd extendedglob rm_star_silent completealiases
setopt autocd extendedglob rm_star_silent completealiases rc_quotes histignorespace
unsetopt beep notify
# Some general, random configuration
# History stuff
if [[ -v INSIDE_EMACS ]]; then
() {
emulate -L zsh
set -o rematchpcre
if [[ "${HISTFILE}" =~ '^~([^/]*)($|/.*)' ]]; then
local user="${match[1]}"
local rest="${match[2]}"
if [[ -z "${user}" ]]; then
HISTFILE="${HOME}${rest}"
else
HISTFILE="${userdirs[${user}]}"
fi
fi
}
fi
[ ! -d "${HISTFILE:h}" ] && mkdir -p "${HISTFILE:h}"
[ -v HISTFILE ] || HISTFILE="${HOME}/.cache/zsh/history"
[ ! -d "$(dirname "${HISTFILE}")" ] && mkdir -p "$(dirname "${HISTFILE}")"
HISTSIZE=1000
SAVEHIST=10000
# Tools for graphical sessions
export BROWSER=mullvad-browser
export READER=zathura
alias clip="xclip -selection clipboard"
if [[ -v WAYLAND_DISPLAY ]]; then
function clip {
(( ${#} >= 1 )) && (cat "${@}" | wl-copy) || wl-copy
}
else
alias clip="xclip -selection clipboard"
fi
# I mess this up a lot
alias cd..="cd .."
# Make xargs, sudo, etc. understand aliases
alias xargs='xargs '
cmd_exists sudo && alias sudo='sudo '
cmd_exists doas && alias doas='doas '
if cmd_exists doas; then
__zsh_sudo_cmd=doas
alias sudo='doas '
alias doas='doas '
alias sudoedit="doas $EDITOR "
alias se="doas $EDITOR "
else
__zsh_sudo_cmd=sudo
alias sudo='sudo '
alias se='sudoedit '
alias doas='sudo '
fi
# Neovim stuff
# Emacs and Neovim stuff
if [[ -v NVIM ]]; then
export EDITOR=nvr
alias n=nvr
alias nvim=nvr
alias e=nvr
alias emacs=nvr
elif [[ "${is_in_distrobox}" == true ]]; then
if [[ -v INSIDE_EMACS ]]; then
[[ -z "${XDG_RUNTIME_DIR}" ]] && \
export XDG_RUNTIME_DIR="/run/user/${UID}"
export EDITOR='distrobox-host-exec emacsclient -a nvim '
alias emacs='distrobox-host-exec emacsclient -a nvim '
else
export EDITOR='distrobox-host-exec emacsclient -a nvim -c '
alias emacs='distrobox-host-exec emacsclient -a nvim -c '
fi
alias n='emacs '
alias e='emacs '
elif [[ -v INSIDE_EMACS ]]; then
export EDITOR='emacsclient'
alias e='emacsclient '
alias emacs='emacsclient '
alias n='emacsclient '
alias nvim='emacsclient '
else
export EDITOR=nvim
alias n=nvim
export EDITOR='emacsclient -a nvim -nw'
# Because I keep using n by mistake
alias emacs="${EDITOR} "
alias n=emacs
alias e=emacs
alias nvim=emacs
fi
export VISUAL="${EDITOR}"
alias se=sudoedit
# Make SBCL *slightly* less frustrating to use on the command line
alias sbcl='rlwrap -pblue -q "\"" sbcl'
# Safer file functions
local rm_confirm_flag='-i'
uname | grep -i linux >/dev/null && rm_confirm_flag='-I'
alias rm="rm ${rm_confirm_flag}"
alias cp="cp -i"
alias mv="mv -i"
# Ledger stuff
alias ldg='ledger -f "${HOME}/finance/finances.ledger"'
# Trash put for safety
if cmd_exists trash-put; then
alias rm='echo "rm: I''m unsafe! Don''t use me."; false'
alias tp=trash-put
alias trr=trash-restore
alias trl=trash-list
alias tre=trash-empty
alias trm=trash-rm
else
local rm_confirm_flag='-i'
uname | grep -i linux >/dev/null && rm_confirm_flag='-I'
alias rm="rm ${rm_confirm_flag}"
fi
# Enable mouse support in less
export LESS="--mouse"
# Bat configuration
local bat_exec
if cmd_exists bat; then
bat_exec=bat
elif cmd_exists batcat; then
bat_exec=batcat;
alias bat=batcat
fi
if ! [[ -z "${bat_exec}" ]]; then
# Pager
export PAGER="bat --paging=always"
export PAGER="${bat_exec} --paging=always"
# Less syntax highlighting in interactive shells
alias less="bat --paging=always"
alias less="${bat_exec} --paging=always"
# Use bat instead of cat
alias cat="bat --paging=never"
alias pcat="bat -pp"
alias ncat="bat -pp --color=never"
alias cat="${bat_exec} --paging=never"
alias pcat="${bat_exec} -pp"
alias ncat="${bat_exec} -pp --color=never"
# Bat as man pager
export MANPAGER="zsh -c 'col -bx | bat -l man -p --paging=always'"
export MANROFFOPT="-c"
if [[ "${bat_exec}" = (bat|*/bat) ]]; then
export MANPAGER="zsh -c 'col -bx | ${bat_exec} -l man --paging=always --style=plain'"
export MANROFFOPT="-c"
fi
fi
unset bat_exec
# Exa configuration
if cmd_exists exa; then
alias ls="exa --git -F"
alias la="ls -a"
alias l="ls -l"
alias ll="ls -al"
# Eza configuration
# Don't define an alias if ls is already an alias
if cmd_exists eza && ! alias ls >/dev/null; then
alias ls="eza --git -F=auto"
fi
alias la="ls -a"
alias l="ls -l"
alias ll="ls -al"
# Delta configuration
if cmd_exists delta; then
@ -108,61 +215,31 @@ alias ga="git add"
alias gaa="git add -A"
alias gco="git commit"
gcm() {
local args="${@}"
git commit -m "${args}"
git commit -m "${${@}}"
}
alias gca="git commit -a"
gcam() {
local args="${@}"
git commit -am "${args}"
git commit -am "${${@}}"
}
alias gp="git push"
alias gu="git pull"
alias gf="git fetch"
alias gt="git status"
# Dotfile management
[ -v ZSH_MANAGE_DOTFILES_REPO ] || ZSH_MANAGE_DOTFILES_REPO="${HOME}/src/dotfiles"
function dots {
local args=("--git-dir=${ZSH_MANAGE_DOTFILES_REPO}" '--work-tree=/' '--bare')
if (( ${#} == 0 )); then
(cd /
for file in $(git ${args} ls-files); do
printf '%s\t%s\t\e[38;2;255;255;0m%s\e[m\n' \
"$(git ${args} -c color.status=always status -s "${file}" | sed "s#${file}##")" \
"/${file}" \
"$(git ${args} log --max-count=1 --format='%s' "${file}")"
done) | column -t -T2 --separator=" "
else
git ${args} "${@}"
fi
}
compdef -e "words[1]=(git '--git-dir=${HOME}/src/dotfiles' --work-tree=/ --bare); service=git; (( CURRENT+=3 )); _git" dots
alias gd="git diff"
# Sudo last line with <Esc><Esc>
sudo-command-line() {
[[ -z $BUFFER ]] && zle up-history
if [[ $BUFFER == sudo\ * ]]; then
LBUFFER="${LBUFFER#sudo }"
elif [[ $BUFFER == $EDITOR\ * ]]; then
LBUFFER="${LBUFFER#$EDITOR }"
LBUFFER="sudoedit $LBUFFER"
elif [[ $BUFFER == sudoedit\ * ]]; then
LBUFFER="${LBUFFER#sudoedit }"
LBUFFER="$EDITOR $LBUFFER"
if [[ $BUFFER == ${__zsh_sudo_cmd}\ * ]]; then
LBUFFER="${LBUFFER#${__zsh_sudo_cmd} }"
else
LBUFFER="sudo $LBUFFER"
LBUFFER="${__zsh_sudo_cmd} ${LBUFFER}"
fi
}
zle -N sudo-command-line
bindkey -M vicmd "^f" sudo-command-line
bindkey -M viins "^f" sudo-command-line
# Autosuggestions
load_plugin zsh-autosuggestions
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
bindkey '^ ' autosuggest-accept
# Use vi mode
bindkey -v
# Fast switch of modes
@ -177,7 +254,7 @@ function overwrite-mode {
zle -N overwrite-mode
# Fancy prompt (starship)
eval "$(starship init zsh)"
cmd_exists starship && eval "$(starship init zsh)"
# Change cursor shape for different vi modes.
function __zsh_vim_key_prompt_handler {
SPACESHIP_CHAR_SYMBOL=""
@ -223,10 +300,28 @@ if cmd_exists direnv; then
eval "$(direnv hook zsh)"
fi
# Pyenv
if cmd_exists pyenv; then
export PYENV_ROOT="${HOME}/.pyenv"
[[ -d "${PYENV_ROOT/bin}" ]] && export PATH="${PYENV_ROOT}/bin:${PATH}"
eval "$(pyenv init - zsh)"
eval "$(pyenv virtualenv-init - zsh)"
__zsh_fix_pyenv_prompt() {
if [[ -v _OLD_VIRTUAL_PS1 ]]; then
PS1="${_OLD_VIRTUAL_PS1}"
unset _OLD_VIRTUAL_PS1
fi
}
precmd_functions+=(__zsh_fix_pyenv_prompt)
fi
# Bookmarks
[ -v ZSH_BOOKMARK_DIR ] || ZSH_BOOKMARK_DIR="${HOME}/.cache/zsh/bookmarks"
[ -v ZSH_BOOKMARK_LS ] || ZSH_BOOKMARK_LS=true
source "${ZSH_CONFIG_DIR}/bookmark.zsh"
if cmd_exists emacs; then
[[ -v BM_CWD_LS ]] || BM_CWD_LS=true
[[ -v BM_MODE ]] || BM_MODE=daemon
[[ -v BM_AUTO_RELOAD ]] || BM_AUTO_RELOAD=true
source "${ZSH_CONFIG_DIR}/emacs-bookmark.zsh"
fi
# Platform specific stuff
[ -f /usr/bin/pacman ] && source "${ZSH_CONFIG_DIR}/arch.zsh"
@ -239,8 +334,8 @@ zstyle ':completion:*:git-checkout:*' sort false
zstyle ':completion:*:descriptions' format '[%d]'
# Set list-colors to enable filename colorizing
zstyle ':completion:*' list-colors ${(s.:.)LS_COLORS}
# Preview directory's content with exa when completing cd
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'exa -1 --color=always $realpath'
# Preview directory's content with eza when completing cd
zstyle ':fzf-tab:complete:cd:*' fzf-preview 'eza -1 --color=always $realpath'
# Remove the '.' prefix at the start of every completion
zstyle ':fzf-tab:*' prefix ''
# Switch groups
@ -248,8 +343,19 @@ zstyle ':fzf-tab:*' switch-group 'ctrl-h' 'ctrl-l'
# Toggle selected for all visible entries
zstyle ':fzf-tab:*' fzf-bindings 'ctrl-a:toggle-all'
# Autosuggestions
load_plugin zsh-autosuggestions
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
bindkey '^ ' autosuggest-accept
# Load user init file
source_user_file 'local.zsh'
source_user_file 'local'
# Load distrobox normal init file
if [[ -v DISTROBOX_MY_COMPAT ]] && \
[[ -f "${DISTROBOX_MY_COMPAT}/init.zsh" ]]; then
source "${DISTROBOX_MY_COMPAT}/init.zsh"
fi
# THE FOLLOWING PLUGINS MUST COME LAST
@ -257,16 +363,16 @@ source_user_file 'local.zsh'
load_plugin zsh-completions
# Syntax highlighting
load_plugin zsh-syntax-highlighting
load_plugin fast-syntax-highlighting
# History substring search
load_plugin zsh-history-substring-search
bindkey '^[[A' history-substring-search-up
bindkey '^[[B' history-substring-search-down
bindkey '^k' history-substring-search-up
bindkey '^j' history-substring-search-down
bindkey -M vicmd '^k' history-substring-search-up
bindkey -M vicmd '^j' history-substring-search-down
#bindkey '^k' history-substring-search-up
#bindkey '^j' history-substring-search-down
#bindkey -M vicmd '^k' history-substring-search-up
#bindkey -M vicmd '^j' history-substring-search-down
bindkey -M vicmd 'k' history-substring-search-up
bindkey -M vicmd 'j' history-substring-search-down
bindkey -M emacs '^P' history-substring-search-up
@ -277,10 +383,21 @@ HISTORY_SUBSTRING_SEARCH_PREFIXED="true"
HISTORY_SUBSTRING_SEARCH_HIGHLIGHT_FOUND=""
setopt histignoredups
# Run fortune and cowsay if we are not in nvim or ssh
if cmd_exists fortune && cmd_exists cowsay; then
[[ -v NVIM ]] || [[ -v SSH_CLIENT ]] || [[ -v INSIDE_EMACS ]] || \
fortune | cowsay -felephant-in-snake -n
fi
# [[ -v EAT_SHELL_INTEGRATION_DIR ]] && source "${EAT_SHELL_INTEGRATION_DIR}/zsh"
# Clean up internal functions
unfunction load_plugin
unfunction cmd_exists
unfunction source_user_file
unset is_in_distrobox
# Run fortune and cowsay if we are not in nvim
[[ -v NVIM ]] || fortune | cowsay -felephant-in-snake -n
let ZSH_INIT_TIME="$(( EPOCHREALTIME - __init_zsh_start ))"
function zsh-init-time {
printf 'Zsh initialization took: %05fms\n' "$(( ZSH_INIT_TIME * 1000 ))"
}