1
0
Fork 0
mirror of https://github.com/SeriousBug/dotfiles synced 2025-12-07 05:22:34 -06:00

Compare commits

...

No commits in common. "1617781d4927c2325074f8606f8eeef972477342" and "3bf9ba331858069b7f7c2e43dc7d5140f8239d96" have entirely different histories.

51 changed files with 2210 additions and 116 deletions

1
.claude/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
settings.local.json

View file

@ -0,0 +1,29 @@
---
name: dotter-docs
description: Reference Dotter documentation
---
# Dotter Docs
## Instructions
Reference the files in `dotter.wiki` when you need information on how to use Dotter.
dotter.wiki
├── 1.-Getting-Started.md
├── 2.-Symbolic-links-and-Templates.md
├── 3.-Packages-and-`local.toml`.md
├── 4.-Complex-Target.md
├── 5.-Builtins,-Helpers,-and-Settings.md
├── 6.-Miscellaneous-features.md
├── FAQ-&-Troubleshooting.md
└── Home.md
## Examples
Find how to install:
```
rg -C4 'install'
```

@ -0,0 +1 @@
Subproject commit 9195aa11bbe843e4607c3974c442942377fd5995

1
.dotter/.gitignore vendored
View file

@ -1 +0,0 @@
cache

View file

@ -1,4 +0,0 @@
[symlinks]
"bottom/bottom.toml" = "/home/kaan/.config/bottom/bottom.toml"
[templates]

View file

@ -1,17 +1,64 @@
[helpers]
[default]
depends = ["bottom", "git"]
[default.files]
[bottom.files]
"bottom/bottom.toml" = "~/.config/bottom/bottom.toml"
[git]
depends = []
[git.files]
"git/gitconfig" = "~/.gitconfig"
"git/gitignore" = "~/.gitignore"
[default.variables]
[git.variables]
[nvim]
depends = []
[nvim.files]
"nvim/init.lua" = "~/.config/nvim/init.lua"
"nvim/lazy-lock.json" = "~/.config/nvim/lazy-lock.json"
"nvim/lua/config/lazy.lua" = "~/.config/nvim/lua/config/lazy.lua"
"nvim/lua/plugins/mini-surround.lua" = "~/.config/nvim/lua/plugins/mini-surround.lua"
[nvim.files."nvim/lua/plugins/hop.lua"]
target = "~/.config/nvim/lua/plugins/hop.lua"
type = "symbolic"
[nvim.variables]
[fish]
depends = []
[fish.files]
"fish/config.fish" = "~/.config/fish/config.fish"
"fish/fish_plugins" = "~/.config/fish/fish_plugins"
"fish/completions" = "~/.config/fish/completions"
"fish/conf.d" = "~/.config/fish/conf.d"
# Note: fish/functions is managed directly as a directory symlink in setup.sh
[fish.variables]
[zellij]
depends = []
[zellij.files]
"zellij/config.kdl" = "~/.config/zellij/config.kdl"
[zellij.variables]
[htop]
depends = []
[htop.files]
"htop/htoprc" = "~/.config/htop/htoprc"
[htop.variables]
[asdf]
depends = []
[asdf.files]
"asdf/.tool-versions" = "~/.tool-versions"
[asdf.variables]
[settings]
default_target_type = "automatic"

View file

@ -1,6 +0,0 @@
includes = []
packages = ["default"]
[files]
[variables]

View file

@ -1,2 +0,0 @@
#!/usr/bin/env bash
./scripts/asdf.install.sh

5
.gitignore vendored Normal file
View file

@ -0,0 +1,5 @@
# Dotter cache files
.dotter/local.toml
.dotter/cache.toml
.dotter/cache/
.dotter/user_vars.sh

3
.gitmodules vendored Normal file
View file

@ -0,0 +1,3 @@
[submodule ".claude/skills/dotter/dotter.wiki"]
path = .claude/skills/dotter/dotter.wiki
url = https://github.com/SuperCuber/dotter.wiki.git

16
CLAUDE.md Normal file
View file

@ -0,0 +1,16 @@
# Dotfiles Configuration Notes
## Dotter Template Handling
Dotter automatically treats files with `{{` as templates. For files that contain `{{` in their code (like Lua tables), disable templating by setting `type = "symbolic"` in `.dotter/global.toml`.
**Example:**
```toml
[nvim.files."nvim/lua/plugins/hop.lua"]
target = "~/.config/nvim/lua/plugins/hop.lua"
type = "symbolic"
```
## Directory Symlinks in setup.sh
For directories where programs create new files that should be tracked (e.g., fish's `funcsave` command), use the `ensure_dir_symlink` function in `setup.sh` instead of Dotter. This symlinks the entire directory so dynamically created files are automatically tracked in the repository.

35
README.md Normal file
View file

@ -0,0 +1,35 @@
# Dotfiles
Personal dotfiles and configuration managed with [Dotter](https://github.com/SuperCuber/dotter). Feel free to use this as inspiration or fork it for your own setup.
## Setup
Run the setup script to install dependencies via Homebrew and deploy configurations:
```bash
./setup.sh
```
### Options
- `--reset` - Reset configuration and re-prompt for all variables
- `--force-deploy` - Force deployment even if files already exist
- `--skip-brew` - Skip Homebrew package installation
### Installed Packages
The setup script installs the following packages via Homebrew:
- dotter, fish, dust, eza, gh, htop, go, jq, lazygit, neovim, asdf, bat, pandoc, ripgrep, zoxide, zellij, p7zip
**macOS only:**
- font-fira-code-nerd-font, orbstack, iterm2, rectangle-pro, maccy
## Included Configurations
- Git
- Neovim
- Fish shell
- Zellij
- Htop
- ASDF

2
asdf/.tool-versions Normal file
View file

@ -0,0 +1,2 @@
nodejs 22.11.0
golang 1.25.1

BIN
bootstrap

Binary file not shown.

View file

@ -1,2 +0,0 @@
[flags]
group_processes = true

View file

@ -0,0 +1,7 @@
complete --command fisher --exclusive --long help --description "Print help"
complete --command fisher --exclusive --long version --description "Print version"
complete --command fisher --exclusive --condition __fish_use_subcommand --arguments install --description "Install plugins"
complete --command fisher --exclusive --condition __fish_use_subcommand --arguments update --description "Update installed plugins"
complete --command fisher --exclusive --condition __fish_use_subcommand --arguments remove --description "Remove installed plugins"
complete --command fisher --exclusive --condition __fish_use_subcommand --arguments list --description "List installed plugins matching regex"
complete --command fisher --exclusive --condition "__fish_seen_subcommand_from update remove" --arguments "(fisher list)"

334
fish/conf.d/done.fish Normal file
View file

@ -0,0 +1,334 @@
# MIT License
# Copyright (c) 2016 Francisco Lourenço & Daniel Wehner
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
if not status is-interactive
exit
end
set -g __done_version 1.19.3
function __done_run_powershell_script
set -l powershell_exe (command --search "powershell.exe")
if test $status -ne 0
and command --search wslvar
set -l powershell_exe (wslpath (wslvar windir)/System32/WindowsPowerShell/v1.0/powershell.exe)
end
if string length --quiet "$powershell_exe"
and test -x "$powershell_exe"
set cmd (string escape $argv)
eval "$powershell_exe -Command $cmd"
end
end
function __done_windows_notification -a title -a message
if test "$__done_notify_sound" -eq 1
set soundopt "<audio silent=\"false\" src=\"ms-winsoundevent:Notification.Default\" />"
else
set soundopt "<audio silent=\"true\" />"
end
__done_run_powershell_script "
[Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom.XmlDocument, ContentType = WindowsRuntime] | Out-Null
[Windows.UI.Notifications.ToastNotification, Windows.UI.Notifications, ContentType = WindowsRuntime] | Out-Null
\$toast_xml_source = @\"
<toast>
$soundopt
<visual>
<binding template=\"ToastText02\">
<text id=\"1\">$title</text>
<text id=\"2\">$message</text>
</binding>
</visual>
</toast>
\"@
\$toast_xml = New-Object Windows.Data.Xml.Dom.XmlDocument
\$toast_xml.loadXml(\$toast_xml_source)
\$toast = New-Object Windows.UI.Notifications.ToastNotification \$toast_xml
[Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier(\"fish\").Show(\$toast)
"
end
function __done_get_focused_window_id
if type -q lsappinfo
lsappinfo info -only bundleID (lsappinfo front | string replace 'ASN:0x0-' '0x') | cut -d '"' -f4
else if test -n "$SWAYSOCK"
and type -q jq
swaymsg --type get_tree | jq '.. | objects | select(.focused == true) | .id'
else if test -n "$HYPRLAND_INSTANCE_SIGNATURE"
hyprctl activewindow | awk 'NR==1 {print $2}'
else if begin
test "$XDG_SESSION_DESKTOP" = gnome; and type -q gdbus
end
gdbus call --session --dest org.gnome.Shell --object-path /org/gnome/Shell --method org.gnome.Shell.Eval 'global.display.focus_window.get_id()'
else if type -q xprop
and test -n "$DISPLAY"
# Test that the X server at $DISPLAY is running
and xprop -grammar >/dev/null 2>&1
xprop -root 32x '\t$0' _NET_ACTIVE_WINDOW | cut -f 2
else if uname -a | string match --quiet --ignore-case --regex microsoft
__done_run_powershell_script '
Add-Type @"
using System;
using System.Runtime.InteropServices;
public class WindowsCompat {
[DllImport("user32.dll")]
public static extern IntPtr GetForegroundWindow();
}
"@
[WindowsCompat]::GetForegroundWindow()
'
else if set -q __done_allow_nongraphical
echo 12345 # dummy value
end
end
function __done_is_tmux_window_active
set -q fish_pid; or set -l fish_pid %self
# find the outermost process within tmux
# ppid != "tmux" -> pid = ppid
# ppid == "tmux" -> break
set tmux_fish_pid $fish_pid
while set tmux_fish_ppid (ps -o ppid= -p $tmux_fish_pid | string trim)
# remove leading hyphen so that basename does not treat it as an argument (e.g. -fish), and return only
# the actual command and not its arguments so that basename finds the correct command name.
# (e.g. '/usr/bin/tmux' from command '/usr/bin/tmux new-session -c /some/start/dir')
and ! string match -q "tmux*" (basename (ps -o command= -p $tmux_fish_ppid | string replace -r '^-' '' | string split ' ')[1])
set tmux_fish_pid $tmux_fish_ppid
end
# tmux session attached and window is active -> no notification
# all other combinations -> send notification
tmux list-panes -a -F "#{session_attached} #{window_active} #{pane_pid}" | string match -q "1 1 $tmux_fish_pid"
end
function __done_is_screen_window_active
string match --quiet --regex "$STY\s+\(Attached" (screen -ls)
end
function __done_is_process_window_focused
# Return false if the window is not focused
if set -q __done_allow_nongraphical
return 1
end
if set -q __done_kitty_remote_control
kitty @ --password="$__done_kitty_remote_control_password" ls | jq -e ".[].tabs[] | select(any(.windows[]; .is_self)) | .is_focused" >/dev/null
return $status
end
set __done_focused_window_id (__done_get_focused_window_id)
if test "$__done_sway_ignore_visible" -eq 1
and test -n "$SWAYSOCK"
string match --quiet --regex "^true" (swaymsg -t get_tree | jq ".. | objects | select(.id == "$__done_initial_window_id") | .visible")
return $status
else if test -n "$HYPRLAND_INSTANCE_SIGNATURE"
and test $__done_initial_window_id = (hyprctl activewindow | awk 'NR==1 {print $2}')
return $status
else if test "$__done_initial_window_id" != "$__done_focused_window_id"
return 1
end
# If inside a tmux session, check if the tmux window is focused
if type -q tmux
and test -n "$TMUX"
__done_is_tmux_window_active
return $status
end
# If inside a screen session, check if the screen window is focused
if type -q screen
and test -n "$STY"
__done_is_screen_window_active
return $status
end
return 0
end
function __done_humanize_duration -a milliseconds
set -l seconds (math --scale=0 "$milliseconds/1000" % 60)
set -l minutes (math --scale=0 "$milliseconds/60000" % 60)
set -l hours (math --scale=0 "$milliseconds/3600000")
if test $hours -gt 0
printf '%s' $hours'h '
end
if test $minutes -gt 0
printf '%s' $minutes'm '
end
if test $seconds -gt 0
printf '%s' $seconds's'
end
end
# verify that the system has graphical capabilities before initializing
if test -z "$SSH_CLIENT" # not over ssh
and count (__done_get_focused_window_id) >/dev/null # is able to get window id
set __done_enabled
end
if set -q __done_allow_nongraphical
and set -q __done_notification_command
set __done_enabled
end
if set -q __done_enabled
set -g __done_initial_window_id ''
set -q __done_min_cmd_duration; or set -g __done_min_cmd_duration 5000
set -q __done_exclude; or set -g __done_exclude '^git (?!push|pull|fetch)'
set -q __done_notify_sound; or set -g __done_notify_sound 0
set -q __done_sway_ignore_visible; or set -g __done_sway_ignore_visible 0
set -q __done_tmux_pane_format; or set -g __done_tmux_pane_format '[#{window_index}]'
set -q __done_notification_duration; or set -g __done_notification_duration 3000
function __done_started --on-event fish_preexec
set __done_initial_window_id (__done_get_focused_window_id)
end
function __done_ended --on-event fish_postexec
set -l exit_status $status
# backwards compatibility for fish < v3.0
set -q cmd_duration; or set -l cmd_duration $CMD_DURATION
if test $cmd_duration
and test $cmd_duration -gt $__done_min_cmd_duration # longer than notify_duration
and not __done_is_process_window_focused # process pane or window not focused
# don't notify if command matches exclude list
for pattern in $__done_exclude
if string match -qr $pattern $argv[1]
return
end
end
# Store duration of last command
set -l humanized_duration (__done_humanize_duration "$cmd_duration")
set -l title "Done in $humanized_duration"
set -l wd (string replace --regex "^$HOME" "~" (pwd))
set -l message "$wd/ $argv[1]"
set -l sender $__done_initial_window_id
if test $exit_status -ne 0
set title "Failed ($exit_status) after $humanized_duration"
end
if test -n "$TMUX_PANE"
set message (tmux lsw -F"$__done_tmux_pane_format" -f '#{==:#{pane_id},'$TMUX_PANE'}')" $message"
end
if set -q __done_notification_command
eval $__done_notification_command
if test "$__done_notify_sound" -eq 1
echo -e "\a" # bell sound
end
else if set -q KITTY_WINDOW_ID
printf "\x1b]99;i=done:d=0;$title\x1b\\"
printf "\x1b]99;i=done:d=1:p=body;$message\x1b\\"
else if type -q terminal-notifier # https://github.com/julienXX/terminal-notifier
if test "$__done_notify_sound" -eq 1
# pipe message into terminal-notifier to avoid escaping issues (https://github.com/julienXX/terminal-notifier/issues/134). fixes #140
echo "$message" | terminal-notifier -title "$title" -sender "$__done_initial_window_id" -sound default
else
echo "$message" | terminal-notifier -title "$title" -sender "$__done_initial_window_id"
end
else if type -q osascript # AppleScript
# escape double quotes that might exist in the message and break osascript. fixes #133
set -l message (string replace --all '"' '\"' "$message")
set -l title (string replace --all '"' '\"' "$title")
if test "$__done_notify_sound" -eq 1
osascript -e "display notification \"$message\" with title \"$title\" sound name \"Glass\""
else
osascript -e "display notification \"$message\" with title \"$title\""
end
else if type -q notify-send # Linux notify-send
# set urgency to normal
set -l urgency normal
# use user-defined urgency if set
if set -q __done_notification_urgency_level
set urgency "$__done_notification_urgency_level"
end
# override user-defined urgency level if non-zero exitstatus
if test $exit_status -ne 0
set urgency critical
if set -q __done_notification_urgency_level_failure
set urgency "$__done_notification_urgency_level_failure"
end
end
notify-send --hint=int:transient:1 --urgency=$urgency --icon=utilities-terminal --app-name=fish --expire-time=$__done_notification_duration "$title" "$message"
if test "$__done_notify_sound" -eq 1
echo -e "\a" # bell sound
end
else if type -q notify-desktop # Linux notify-desktop
set -l urgency
if test $exit_status -ne 0
set urgency "--urgency=critical"
end
notify-desktop $urgency --icon=utilities-terminal --app-name=fish "$title" "$message"
if test "$__done_notify_sound" -eq 1
echo -e "\a" # bell sound
end
else if uname -a | string match --quiet --ignore-case --regex microsoft
__done_windows_notification "$title" "$message"
else # anything else
echo -e "\a" # bell sound
end
end
end
end
function __done_uninstall -e done_uninstall
# Erase all __done_* functions
functions -e __done_ended
functions -e __done_started
functions -e __done_get_focused_window_id
functions -e __done_is_tmux_window_active
functions -e __done_is_screen_window_active
functions -e __done_is_process_window_focused
functions -e __done_windows_notification
functions -e __done_run_powershell_script
functions -e __done_humanize_duration
# Erase __done variables
set -e __done_version
end

1
fish/conf.d/rustup.fish Normal file
View file

@ -0,0 +1 @@
source "$HOME/.cargo/env.fish"

52
fish/conf.d/sponge.fish Normal file
View file

@ -0,0 +1,52 @@
# Sponge version
set --global sponge_version 1.1.0
# Allow to repeat previous command by default
if not set --query --universal sponge_delay
set --universal sponge_delay 2
end
# Purge entries both after `sponge_delay` entries and on exit by default
if not set --query --universal sponge_purge_only_on_exit
set --universal sponge_purge_only_on_exit false
end
# Add default filters
if not set --query --universal sponge_filters
set --universal sponge_filters sponge_filter_failed sponge_filter_matched
end
# Don't filter out commands that already have been in the history by default
if not set --query --universal sponge_allow_previously_successful
set --universal sponge_allow_previously_successful true
end
# Consider `0` the only successful exit code by default
if not set --query --universal sponge_successful_exit_codes
set --universal sponge_successful_exit_codes 0
end
# No active regex patterns by default
if not set --query --universal sponge_regex_patterns
set --universal sponge_regex_patterns
end
# Attach event handlers
functions --query \
_sponge_on_prompt \
_sponge_on_preexec \
_sponge_on_postexec \
_sponge_on_exit
# Initialize empty state for the first run
function _sponge_install --on-event sponge_install
set --global _sponge_current_command ''
set --global _sponge_current_command_exit_code 0
set --global _sponge_current_command_previously_in_history false
end
# Clean up variables
function _sponge_uninstall --on-event sponge_uninstall
_sponge_clear_state
set --erase sponge_version
end

63
fish/conf.d/z.fish Normal file
View file

@ -0,0 +1,63 @@
if test -z "$Z_DATA"
if test -z "$XDG_DATA_HOME"
set -U Z_DATA_DIR "$HOME/.local/share/z"
else
set -U Z_DATA_DIR "$XDG_DATA_HOME/z"
end
set -U Z_DATA "$Z_DATA_DIR/data"
end
if test ! -e "$Z_DATA"
if test ! -e "$Z_DATA_DIR"
mkdir -p -m 700 "$Z_DATA_DIR"
end
touch "$Z_DATA"
end
if test -z "$Z_CMD"
set -U Z_CMD z
end
set -U ZO_CMD "$Z_CMD"o
if test ! -z $Z_CMD
function $Z_CMD -d "jump around"
__z $argv
end
end
if test ! -z $ZO_CMD
function $ZO_CMD -d "open target dir"
__z -d $argv
end
end
if not set -q Z_EXCLUDE
set -U Z_EXCLUDE "^$HOME\$"
else if contains $HOME $Z_EXCLUDE
# Workaround: migrate old default values to a regex (see #90).
set Z_EXCLUDE (string replace -r -- "^$HOME\$" '^'$HOME'$$' $Z_EXCLUDE)
end
# Setup completions once first
__z_complete
function __z_on_variable_pwd --on-variable PWD
__z_add
end
function __z_uninstall --on-event z_uninstall
functions -e __z_on_variable_pwd
functions -e $Z_CMD
functions -e $ZO_CMD
if test ! -z "$Z_DATA"
printf "To completely erase z's data, remove:\n" >/dev/stderr
printf "%s\n" "$Z_DATA" >/dev/stderr
end
set -e Z_CMD
set -e ZO_CMD
set -e Z_DATA
set -e Z_EXCLUDE
end

22
fish/config.fish Normal file
View file

@ -0,0 +1,22 @@
if status is-interactive
# Commands to run in interactive sessions can go here
end
eval ({{brew_path}}/bin/brew shellenv)
set -gx ASDF_DIR {{brew_path}}/opt/asdf/libexec
# ASDF configuration code
if test -z $ASDF_DATA_DIR
set _asdf_shims "$HOME/.asdf/shims"
else
set _asdf_shims "$ASDF_DATA_DIR/shims"
end
# Do not use fish_add_path (added in Fish 3.2) because it
# potentially changes the order of items in PATH
if not contains $_asdf_shims $PATH
set -gx --prepend PATH $_asdf_shims
end
set --erase _asdf_shims
zoxide init fish | source

4
fish/fish_plugins Normal file
View file

@ -0,0 +1,4 @@
jorgebucaran/fisher
franciscolourenco/done
jethrokuan/z
meaningful-ooo/sponge

174
fish/functions/__z.fish Normal file
View file

@ -0,0 +1,174 @@
function __z -d "Jump to a recent directory."
function __print_help -d "Print z help."
printf "Usage: $Z_CMD [-celrth] string1 string2...\n\n"
printf " -c --clean Removes directories that no longer exist from $Z_DATA\n"
printf " -d --dir Opens matching directory using system file manager.\n"
printf " -e --echo Prints best match, no cd\n"
printf " -l --list List matches and scores, no cd\n"
printf " -p --purge Delete all entries from $Z_DATA\n"
printf " -r --rank Search by rank\n"
printf " -t --recent Search by recency\n"
printf " -x --delete Removes the current directory from $Z_DATA\n"
printf " -h --help Print this help\n\n"
end
function __z_legacy_escape_regex
# taken from escape_string_pcre2 in fish
# used to provide compatibility with fish 2
for c in (string split '' $argv)
if contains $c (string split '' '.^$*+()?[{}\\|-]')
printf \\
end
printf '%s' $c
end
end
set -l options h/help c/clean e/echo l/list p/purge r/rank t/recent d/directory x/delete
argparse $options -- $argv
if set -q _flag_help
__print_help
return 0
else if set -q _flag_clean
__z_clean
printf "%s cleaned!\n" $Z_DATA
return 0
else if set -q _flag_purge
echo >$Z_DATA
printf "%s purged!\n" $Z_DATA
return 0
else if set -q _flag_delete
sed -i -e "\:^$PWD|.*:d" $Z_DATA
return 0
end
set -l typ
if set -q _flag_rank
set typ rank
else if set -q _flag_recent
set typ recent
end
set -l z_script '
function frecent(rank, time) {
dx = t-time
if( dx < 3600 ) return rank*4
if( dx < 86400 ) return rank*2
if( dx < 604800 ) return rank/2
return rank/4
}
function output(matches, best_match, common) {
# list or return the desired directory
if( list ) {
cmd = "sort -nr"
for( x in matches ) {
if( matches[x] ) {
printf "%-10s %s\n", matches[x], x | cmd
}
}
} else {
if( common ) best_match = common
print best_match
}
}
function common(matches) {
# find the common root of a list of matches, if it exists
for( x in matches ) {
if( matches[x] && (!short || length(x) < length(short)) ) {
short = x
}
}
if( short == "/" ) return
for( x in matches ) if( matches[x] && index(x, short) != 1 ) {
return
}
return short
}
BEGIN {
hi_rank = ihi_rank = -9999999999
}
{
if( typ == "rank" ) {
rank = $2
} else if( typ == "recent" ) {
rank = $3 - t
} else rank = frecent($2, $3)
if( $1 ~ q ) {
matches[$1] = rank
} else if( tolower($1) ~ tolower(q) ) imatches[$1] = rank
if( matches[$1] && matches[$1] > hi_rank ) {
best_match = $1
hi_rank = matches[$1]
} else if( imatches[$1] && imatches[$1] > ihi_rank ) {
ibest_match = $1
ihi_rank = imatches[$1]
}
}
END {
# prefer case sensitive
if( best_match ) {
output(matches, best_match, common(matches))
} else if( ibest_match ) {
output(imatches, ibest_match, common(imatches))
}
}
'
set -l qs
for arg in $argv
set -l escaped $arg
if string escape --style=regex '' >/dev/null 2>&1 # use builtin escape if available
set escaped (string escape --style=regex $escaped)
else
set escaped (__z_legacy_escape_regex $escaped)
end
# Need to escape twice, see https://www.math.utah.edu/docs/info/gawk_5.html#SEC32
set escaped (string replace --all \\ \\\\ $escaped)
set qs $qs $escaped
end
set -l q (string join '.*' $qs)
if set -q _flag_list
# Handle list separately as it can print common path information to stderr
# which cannot be captured from a subcommand.
command awk -v t=(date +%s) -v list="list" -v typ="$typ" -v q="$q" -F "|" $z_script "$Z_DATA"
return
end
set target (command awk -v t=(date +%s) -v typ="$typ" -v q="$q" -F "|" $z_script "$Z_DATA")
if test "$status" -gt 0
return
end
if test -z "$target"
printf "'%s' did not match any results\n" "$argv"
return 1
end
if set -q _flag_echo
printf "%s\n" "$target"
else if set -q _flag_directory
if test -n "$ZO_METHOD"
type -q "$ZO_METHOD"; and "$ZO_METHOD" "$target"; and return $status
echo "Cannot open with ZO_METHOD set to $ZO_METHOD"; and return 1
else if test "$OS" = Windows_NT
# Be careful, in msys2, explorer always return 1
type -q explorer; and explorer "$target"
return 0
echo "Cannot open file explorer"
return 1
else
type -q xdg-open; and xdg-open "$target"; and return $status
type -q open; and open "$target"; and return $status
echo "Not sure how to open file manager"; and return 1
end
else
pushd "$target"
end
end

View file

@ -0,0 +1,49 @@
function __z_add -d "Add PATH to .z file"
test -n "$fish_private_mode"; and return 0
for i in $Z_EXCLUDE
if string match -r $i $PWD >/dev/null
return 0 #Path excluded
end
end
set -l tmpfile (mktemp $Z_DATA.XXXXXX)
if test -f $tmpfile
set -l path (string replace --all \\ \\\\ $PWD)
command awk -v path=$path -v now=(date +%s) -F "|" '
BEGIN {
rank[path] = 1
time[path] = now
}
$2 >= 1 {
if( $1 == path ) {
rank[$1] = $2 + 1
time[$1] = now
}
else {
rank[$1] = $2
time[$1] = $3
}
count += $2
}
END {
if( count > 1000 ) {
for( i in rank ) print i "|" 0.9*rank[i] "|" time[i] # aging
}
else for( i in rank ) print i "|" rank[i] "|" time[i]
}
' $Z_DATA 2>/dev/null >$tmpfile
if test ! -z "$Z_OWNER"
chown $Z_OWNER:(id -ng $Z_OWNER) $tmpfile
end
#
# Don't use redirection here as it can lead to a race condition where $Z_DATA is clobbered.
# Note: There is a still a possible race condition where an old version of $Z_DATA is
# read by one instance of Fish before another instance of Fish writes its copy.
#
command mv $tmpfile $Z_DATA
or command rm $tmpfile
end
end

View file

@ -0,0 +1,11 @@
function __z_clean -d "Clean up .z file to remove paths no longer valid"
set -l tmpfile (mktemp $Z_DATA.XXXXXX)
if test -f $tmpfile
while read line
set -l path (string split '|' $line)[1]
test -d $path; and echo $line
end <$Z_DATA >$tmpfile
command mv -f $tmpfile $Z_DATA
end
end

View file

@ -0,0 +1,13 @@
function __z_complete -d "add completions"
complete -c $Z_CMD -a "(__z -l | string replace -r '^\\S*\\s*' '')" -f -k
complete -c $ZO_CMD -a "(__z -l | string replace -r '^\\S*\\s*' '')" -f -k
complete -c $Z_CMD -s c -l clean -d "Cleans out $Z_DATA"
complete -c $Z_CMD -s e -l echo -d "Prints best match, no cd"
complete -c $Z_CMD -s l -l list -d "List matches, no cd"
complete -c $Z_CMD -s p -l purge -d "Purges $Z_DATA"
complete -c $Z_CMD -s r -l rank -d "Searches by rank, cd"
complete -c $Z_CMD -s t -l recent -d "Searches by recency, cd"
complete -c $Z_CMD -s h -l help -d "Print help"
complete -c $Z_CMD -s x -l delete -d "Removes the current directory from $Z_DATA"
end

View file

@ -0,0 +1,5 @@
function _sponge_clear_state
set --erase --global _sponge_current_command
set --erase --global _sponge_current_command_exit_code
set --erase --global _sponge_current_command_previously_in_history
end

View file

@ -0,0 +1,3 @@
function _sponge_on_exit --on-event fish_exit
sponge_delay=0 _sponge_remove_from_history
end

View file

@ -0,0 +1,24 @@
function _sponge_on_postexec --on-event fish_postexec
set --global _sponge_current_command_exit_code $status
# Remove command from the queue if it's been added previously
if set --local index (contains --index -- $_sponge_current_command $_sponge_queue)
set --erase _sponge_queue[$index]
end
# Ignore empty commands
if test -n $_sponge_current_command
set --local command ''
# Run filters
for filter in $sponge_filters
if $filter \
$_sponge_current_command \
$_sponge_current_command_exit_code \
$_sponge_current_command_previously_in_history
set command $_sponge_current_command
break
end
end
set --prepend --global _sponge_queue $command
end
end

View file

@ -0,0 +1,16 @@
function _sponge_on_preexec --on-event fish_preexec \
--argument-names command
_sponge_clear_state
set --global _sponge_current_command $command
builtin history search --case-sensitive --exact --max=1 --null $command \
| read --local --null found_entries
# If a command is in the history and in the queue, ignore it, like if it wasnt in the history
if test (count $found_entries) -ne 0; and not contains $command $_sponge_queue
set --global _sponge_current_command_previously_in_history true
else
set --global _sponge_current_command_previously_in_history false
end
end

View file

@ -0,0 +1,5 @@
function _sponge_on_prompt --on-event fish_prompt
if test $sponge_purge_only_on_exit = false
_sponge_remove_from_history
end
end

View file

@ -0,0 +1,9 @@
function _sponge_remove_from_history
while test (count $_sponge_queue) -gt $sponge_delay
builtin history delete --case-sensitive --exact -- $_sponge_queue[-1]
set --erase _sponge_queue[-1]
end
builtin history save
end

240
fish/functions/fisher.fish Normal file
View file

@ -0,0 +1,240 @@
function fisher --argument-names cmd --description "A plugin manager for Fish"
set --query fisher_path || set --local fisher_path $__fish_config_dir
set --local fisher_version 4.4.5
set --local fish_plugins $__fish_config_dir/fish_plugins
switch "$cmd"
case -v --version
echo "fisher, version $fisher_version"
case "" -h --help
echo "Usage: fisher install <plugins...> Install plugins"
echo " fisher remove <plugins...> Remove installed plugins"
echo " fisher update <plugins...> Update installed plugins"
echo " fisher update Update all installed plugins"
echo " fisher list [<regex>] List installed plugins matching regex"
echo "Options:"
echo " -v, --version Print version"
echo " -h, --help Print this help message"
echo "Variables:"
echo " \$fisher_path Plugin installation path. Default: $__fish_config_dir" | string replace --regex -- $HOME \~
case ls list
string match --entire --regex -- "$argv[2]" $_fisher_plugins
case install update remove
isatty || read --local --null --array stdin && set --append argv $stdin
set --local install_plugins
set --local update_plugins
set --local remove_plugins
set --local arg_plugins $argv[2..-1]
set --local old_plugins $_fisher_plugins
set --local new_plugins
test -e $fish_plugins && set --local file_plugins (string match --regex -- '^[^\s]+$' <$fish_plugins | string replace -- \~ ~)
if ! set --query argv[2]
if test "$cmd" != update
echo "fisher: Not enough arguments for command: \"$cmd\"" >&2 && return 1
else if ! set --query file_plugins
echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1
end
set arg_plugins $file_plugins
end
for plugin in $arg_plugins
set plugin (test -e "$plugin" && realpath $plugin || string lower -- $plugin)
contains -- "$plugin" $new_plugins || set --append new_plugins $plugin
end
if set --query argv[2]
for plugin in $new_plugins
if contains -- "$plugin" $old_plugins
test "$cmd" = remove &&
set --append remove_plugins $plugin ||
set --append update_plugins $plugin
else if test "$cmd" = install
set --append install_plugins $plugin
else
echo "fisher: Plugin not installed: \"$plugin\"" >&2 && return 1
end
end
else
for plugin in $new_plugins
contains -- "$plugin" $old_plugins &&
set --append update_plugins $plugin ||
set --append install_plugins $plugin
end
for plugin in $old_plugins
contains -- "$plugin" $new_plugins || set --append remove_plugins $plugin
end
end
set --local pid_list
set --local source_plugins
set --local fetch_plugins $update_plugins $install_plugins
set --local fish_path (status fish-path)
echo (set_color --bold)fisher $cmd version $fisher_version(set_color normal)
for plugin in $fetch_plugins
set --local source (command mktemp -d)
set --append source_plugins $source
command mkdir -p $source/{completions,conf.d,themes,functions}
$fish_path --command "
if test -e $plugin
command cp -Rf $plugin/* $source
else
set temp (command mktemp -d)
set repo (string split -- \@ $plugin) || set repo[2] HEAD
if set path (string replace --regex -- '^(https://)?gitlab.com/' '' \$repo[1])
set name (string split -- / \$path)[-1]
set url https://gitlab.com/\$path/-/archive/\$repo[2]/\$name-\$repo[2].tar.gz
else
set url https://api.github.com/repos/\$repo[1]/tarball/\$repo[2]
end
echo Fetching (set_color --underline)\$url(set_color normal)
if command curl -q --silent -L \$url | command tar -xzC \$temp -f - 2>/dev/null
command cp -Rf \$temp/*/* $source
else
echo fisher: Invalid plugin name or host unavailable: \\\"$plugin\\\" >&2
command rm -rf $source
end
command rm -rf \$temp
end
set files $source/* && string match --quiet --regex -- .+\.fish\\\$ \$files
" &
set --append pid_list (jobs --last --pid)
end
wait $pid_list 2>/dev/null
for plugin in $fetch_plugins
if set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)] && test ! -e $source
if set --local index (contains --index -- "$plugin" $install_plugins)
set --erase install_plugins[$index]
else
set --erase update_plugins[(contains --index -- "$plugin" $update_plugins)]
end
end
end
for plugin in $update_plugins $remove_plugins
if set --local index (contains --index -- "$plugin" $_fisher_plugins)
set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
if contains -- "$plugin" $remove_plugins
for name in (string replace --filter --regex -- '.+/conf\.d/([^/]+)\.fish$' '$1' $$plugin_files_var)
emit {$name}_uninstall
end
printf "%s\n" Removing\ (set_color red --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~
set --erase _fisher_plugins[$index]
end
command rm -rf (string replace -- \~ ~ $$plugin_files_var)
functions --erase (string replace --filter --regex -- '.+/functions/([^/]+)\.fish$' '$1' $$plugin_files_var)
for name in (string replace --filter --regex -- '.+/completions/([^/]+)\.fish$' '$1' $$plugin_files_var)
complete --erase --command $name
end
set --erase $plugin_files_var
end
end
if set --query update_plugins[1] || set --query install_plugins[1]
command mkdir -p $fisher_path/{functions,themes,conf.d,completions}
end
for plugin in $update_plugins $install_plugins
set --local source $source_plugins[(contains --index -- "$plugin" $fetch_plugins)]
set --local files $source/{functions,themes,conf.d,completions}/*
if set --local index (contains --index -- $plugin $install_plugins)
set --local user_files $fisher_path/{functions,themes,conf.d,completions}/*
set --local conflict_files
for file in (string replace -- $source/ $fisher_path/ $files)
contains -- $file $user_files && set --append conflict_files $file
end
if set --query conflict_files[1] && set --erase install_plugins[$index]
echo -s "fisher: Cannot install \"$plugin\": please remove or move conflicting files first:" \n" "$conflict_files >&2
continue
end
end
for file in (string replace -- $source/ "" $files)
command cp -RLf $source/$file $fisher_path/$file
end
set --local plugin_files_var _fisher_(string escape --style=var -- $plugin)_files
set --query files[1] && set --universal $plugin_files_var (string replace -- $source $fisher_path $files | string replace -- ~ \~)
contains -- $plugin $_fisher_plugins || set --universal --append _fisher_plugins $plugin
contains -- $plugin $install_plugins && set --local event install || set --local event update
printf "%s\n" Installing\ (set_color --bold)$plugin(set_color normal) " "$$plugin_files_var | string replace -- \~ ~
for file in (string match --regex -- '.+/[^/]+\.fish$' $$plugin_files_var | string replace -- \~ ~)
source $file
if set --local name (string replace --regex -- '.+conf\.d/([^/]+)\.fish$' '$1' $file)
emit {$name}_$event
end
end
end
command rm -rf $source_plugins
if set --query _fisher_plugins[1]
set --local commit_plugins
for plugin in $file_plugins
contains -- (string lower -- $plugin) (string lower -- $_fisher_plugins) && set --append commit_plugins $plugin
end
for plugin in $_fisher_plugins
contains -- (string lower -- $plugin) (string lower -- $commit_plugins) || set --append commit_plugins $plugin
end
string replace --regex -- $HOME \~ $commit_plugins >$fish_plugins
else
set --erase _fisher_plugins
command rm -f $fish_plugins
end
set --local total (count $install_plugins) (count $update_plugins) (count $remove_plugins)
test "$total" != "0 0 0" && echo (string join ", " (
test $total[1] = 0 || echo "Installed $total[1]") (
test $total[2] = 0 || echo "Updated $total[2]") (
test $total[3] = 0 || echo "Removed $total[3]")
) plugin/s
case \*
echo "fisher: Unknown command: \"$cmd\"" >&2 && return 1
end
end
if ! set --query _fisher_upgraded_to_4_4
set --universal _fisher_upgraded_to_4_4
if functions --query _fisher_list
set --query XDG_DATA_HOME[1] || set --local XDG_DATA_HOME ~/.local/share
command rm -rf $XDG_DATA_HOME/fisher
functions --erase _fisher_{list,plugin_parse}
fisher update >/dev/null 2>/dev/null
else
for var in (set --names | string match --entire --regex '^_fisher_.+_files$')
set $var (string replace -- ~ \~ $$var)
end
functions --erase _fisher_fish_postexec
end
end

3
fish/functions/lgit.fish Normal file
View file

@ -0,0 +1,3 @@
function lgit --wraps=lazygit --description 'alias lgit lazygit'
lazygit $argv
end

3
fish/functions/ls.fish Normal file
View file

@ -0,0 +1,3 @@
function ls --wraps=eza --description 'alias ls eza'
eza $argv
end

3
fish/functions/lsl.fish Normal file
View file

@ -0,0 +1,3 @@
function lsl --wraps=eza --wraps='eza -l' --description 'alias lsl eza -l'
eza -l $argv
end

View file

@ -0,0 +1,11 @@
function sponge_filter_failed \
--argument-names command exit_code previously_in_history
if test $previously_in_history = true -a $sponge_allow_previously_successful = true
return 1
end
if contains $exit_code $sponge_successful_exit_codes
return 1
end
end

View file

@ -0,0 +1,11 @@
function sponge_filter_matched \
--argument-names command
for pattern in $sponge_regex_patterns
if string match --regex --quiet $pattern -- $command
return
end
end
return 1
end

14
git/.gitconfig Normal file
View file

@ -0,0 +1,14 @@
[core]
excludesFile = ~/.gitignore
[push]
autoSetupRemote = true
[user]
name = {{git_name}}
email = {{git_email}}
[filter "lfs"]
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
required = true
[init]
defaultBranch = main

2
git/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
.history/

View file

@ -1,34 +1,14 @@
[user]
email = kaan@bgenc.com
name = Kaan Barmore-Genc
[init]
defaultBranch = main
[pull]
rebase = true
[pager]
diff = delta
log = delta
reflog = delta
show = delta
[interactive]
diffFilter = delta --color-only
[delta]
features = side-by-side line-numbers decorations
whitespace-error-style = 22 reverse
[merge]
ff = no
[alias]
stat = status
[core]
editor = code --wait
[credential]
helper = store
excludesFile = ~/.gitignore
[push]
autoSetupRemote = true
[user]
name = {{ git_name }}
email = {{ git_email }}
[filter "lfs"]
required = true
clean = git-lfs clean -- %f
smudge = git-lfs smudge -- %f
process = git-lfs filter-process
[push]
autoSetupRemote = true
[submodule]
recurse = true
required = true
[init]
defaultBranch = main

2
git/gitignore Normal file
View file

@ -0,0 +1,2 @@
.history/

53
htop/htoprc Normal file
View file

@ -0,0 +1,53 @@
# Beware! This file is rewritten by htop when settings are changed in the interface.
# The parser is also very primitive, and not human-friendly.
htop_version=3.3.0
config_reader_min_version=3
fields=0 48 17 18 38 39 2 46 47 49 1
hide_kernel_threads=1
hide_userland_threads=0
hide_running_in_container=0
shadow_other_users=0
show_thread_names=0
show_program_path=1
highlight_base_name=0
highlight_deleted_exe=1
shadow_distribution_path_prefix=0
highlight_megabytes=1
highlight_threads=1
highlight_changes=0
highlight_changes_delay_secs=5
find_comm_in_cmdline=1
strip_exe_from_cmdline=1
show_merged_command=0
header_margin=1
screen_tabs=1
detailed_cpu_time=0
cpu_count_from_one=0
show_cpu_usage=1
show_cpu_frequency=0
update_process_names=0
account_guest_in_cpu_meter=0
color_scheme=0
enable_mouse=1
delay=15
hide_function_bar=0
header_layout=two_50_50
column_meters_0=LeftCPUs2 Memory Swap
column_meter_modes_0=1 1 1
column_meters_1=RightCPUs2 Tasks LoadAverage Uptime
column_meter_modes_1=1 2 2 2
tree_view=0
sort_key=46
tree_sort_key=0
sort_direction=-1
tree_sort_direction=1
tree_view_always_by_pid=0
all_branches_collapsed=0
screen:Main=PID USER PRIORITY NICE M_VIRT M_RESIDENT STATE PERCENT_CPU PERCENT_MEM TIME Command
.sort_key=PERCENT_CPU
.tree_sort_key=PID
.tree_view_always_by_pid=0
.tree_view=0
.sort_direction=-1
.tree_sort_direction=1
.all_branches_collapsed=0

2
nvim/init.lua Normal file
View file

@ -0,0 +1,2 @@
require("config.lazy")

5
nvim/lazy-lock.json Normal file
View file

@ -0,0 +1,5 @@
{
"hop.nvim": { "branch": "master", "commit": "08ddca799089ab96a6d1763db0b8adc5320bf050" },
"lazy.nvim": { "branch": "main", "commit": "85c7ff3711b730b4030d03144f6db6375044ae82" },
"mini.nvim": { "branch": "main", "commit": "94cae4660a8b2d95dbbd56e1fbc6fcfa2716d152" }
}

35
nvim/lua/config/lazy.lua Normal file
View file

@ -0,0 +1,35 @@
-- Bootstrap lazy.nvim
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
if not (vim.uv or vim.loop).fs_stat(lazypath) then
local lazyrepo = "https://github.com/folke/lazy.nvim.git"
local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath })
if vim.v.shell_error ~= 0 then
vim.api.nvim_echo({
{ "Failed to clone lazy.nvim:\n", "ErrorMsg" },
{ out, "WarningMsg" },
{ "\nPress any key to exit..." },
}, true, {})
vim.fn.getchar()
os.exit(1)
end
end
vim.opt.rtp:prepend(lazypath)
-- Make sure to setup `mapleader` and `maplocalleader` before
-- loading lazy.nvim so that mappings are correct.
-- This is also a good place to setup other settings (vim.opt)
vim.g.mapleader = " "
vim.g.maplocalleader = "\\"
-- Setup lazy.nvim
require("lazy").setup({
spec = {
-- import your plugins
{ import = "plugins" },
},
-- Configure any other settings here. See the documentation for more details.
-- colorscheme that will be used when installing plugins.
install = { colorscheme = { "habamax" } },
-- automatically check for plugin updates
checker = { enabled = true },
})

61
nvim/lua/plugins/hop.lua Normal file
View file

@ -0,0 +1,61 @@
return {
'smoka7/hop.nvim',
version = "*",
opts = {
keys = 'etovxqpdygfblzhckisuran'
},
config = function()
local hop = require('hop')
hop.setup()
local directions = require('hop.hint').HintDirection
vim.keymap.set('', '<C-F>', function ()
hop.hint_words({})
end, {remap=true})
vim.keymap.set('', '<C-f>', function ()
vim.api.nvim_echo({{" Enter letter: ", "Normal"}}, false, {})
local char = vim.fn.nr2char(vim.fn.getchar())
if not char:match('^[%w%p]$') then
vim.api.nvim_echo({{" Invalid input!", "ErrorMsg"}}, false, {})
return
end
vim.api.nvim_echo({}, false, {})
local pattern = '\\%(\\_^\\|[[:space:]{}.|><!@#$%^&*()-_+=`~;:,/?\\[\\]"\']\\)\\@<=[' .. char:lower() .. char:upper() .. ']'
hop.hint_patterns({}, pattern)
end, {remap=true})
vim.keymap.set('', 'f', function ()
hop.hint_char1({
direction = directions.AFTER_CURSOR,
current_line_only = true
})
end, {remap=true})
vim.keymap.set('', 'F', function ()
hop.hint_char1({
direction = directions.BEFORE_CURSOR,
current_line_only = true,
})
end, {remap=true})
vim.keymap.set('', 't', function ()
hop.hint_char1({
direction = directions.AFTER_CURSOR,
current_line_only = true,
hint_offset = -1,
})
end, {remap=true})
vim.keymap.set('', 'T', function ()
hop.hint_char1({
direction = directions.BEFORE_CURSOR,
current_line_only = true,
hint_offset = -1,
})
end, {remap=true})
end
}

View file

@ -0,0 +1,9 @@
return {
'nvim-mini/mini.nvim',
version = '*',
config = function()
require('mini.surround').setup()
end
}

View file

@ -1,61 +0,0 @@
#!/usr/bin/env bash
# Install
git clone https://github.com/asdf-vm/asdf.git ~/.asdf --branch v0.14.1
# Setup bash
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.bashrc
echo '. "$HOME/.asdf/completions/asdf.bash"' >> ~/.bashrc
# Setup fish
mkdir -p ~/.config/fish
echo 'set --export ASDF_DIR $HOME/.asdf'
echo 'source ~/.asdf/asdf.fish' >> ~/.config/fish/config.fish
mkdir -p ~/.config/fish/completions
ln -s ~/.asdf/completions/asdf.fish ~/.config/fish/completions
# Setup zsh
echo '. "$HOME/.asdf/asdf.sh"' >> ~/.zshrc
echo 'fpath=(${ASDF_DIR}/completions $fpath)' >> ~/.zshrc
echo 'autoload -Uz compinit && compinit' >> ~/.zshrc
# Activate asdf
. "$HOME/.asdf/asdf.sh"
# Install and activate asdf plugins
PLUGINS=(
"air"
"bat"
"bottom"
"bun"
"delta"
"dust"
"eza"
"fd"
"golang"
"jq"
"lazygit"
"neovim"
"nodejs"
"pnpm"
"ripgrep"
"xh"
)
for PLUGIN in "${PLUGINS[@]}"; do
asdf plugin add "$PLUGIN"
asdf install "$PLUGIN" latest
asdf global "$PLUGIN" latest
done
#git clone --depth=1 https://github.com/mattmc3/antidote.git ${ZDOTDIR:-~}/.antidote
# If Go is already installed on the system (e.g. Codespaces), the built-in
# install interferes with the asdf install.
unset GOPATH
unset GOROOT
echo "export GOPATH=$(go env GOPATH)" >> ~/.bashrc
echo "export GOROOT=$(go env GOROOT)" >> ~/.bashrc
echo "export GOPATH=$(go env GOPATH)" >> ~/.zshrc
echo "export GOROOT=$(go env GOROOT)" >> ~/.zshrc
echo "set --export GOPATH (go env GOPATH)" >> ~/.config/fish/config.fish
echo "set --export GOROOT (go env GOROOT)" >> ~/.config/fish/config.fish

273
setup.sh Executable file
View file

@ -0,0 +1,273 @@
#!/usr/bin/env bash
set -eo pipefail
# Function to manage directory symlinks
# Usage: ensure_dir_symlink <source_dir> <target_link> <force_flag>
# Args:
# source_dir: The actual directory to symlink to (must be absolute path)
# target_link: The symlink location to create
# force_flag: true/false - whether to force replacement if exists
ensure_dir_symlink() {
local source_dir="$1"
local target_link="$2"
local force_flag="$3"
# Expand tilde in paths
target_link="${target_link/#\~/$HOME}"
source_dir="${source_dir/#\~/$HOME}"
# Check if target exists
if [[ -e "$target_link" || -L "$target_link" ]]; then
# Check if it's already a symlink pointing to the right place
if [[ -L "$target_link" ]]; then
local current_target
current_target="$(readlink "$target_link")"
if [[ "$current_target" == "$source_dir" ]]; then
echo "$target_link already symlinked correctly"
return 0
else
# Symlink exists but points to wrong location
if [[ "$force_flag" == true ]]; then
echo "Replacing symlink $target_link (currently points to $current_target)"
rm "$target_link"
else
echo "⚠ Warning: $target_link exists but points to $current_target (expected $source_dir)"
echo " Run with --force-deploy to replace it"
return 0
fi
fi
else
# Path exists but is not a symlink
if [[ "$force_flag" == true ]]; then
echo "Replacing $target_link with symlink (was a regular file/directory)"
rm -rf "$target_link"
else
echo "⚠ Warning: $target_link exists but is not a symlink"
echo " Run with --force-deploy to replace it"
return 0
fi
fi
fi
# Create parent directory if needed
local parent_dir
parent_dir="$(dirname "$target_link")"
if [[ ! -d "$parent_dir" ]]; then
echo "Creating parent directory: $parent_dir"
mkdir -p "$parent_dir"
fi
# Create the symlink
echo "Creating symlink: $target_link -> $source_dir"
ln -s "$source_dir" "$target_link"
echo "✓ Successfully created symlink"
}
# Parse command line arguments
RESET_CONFIG=false
FORCE_DEPLOY=false
SKIP_BREW=false
for arg in "$@"; do
case $arg in
--reset)
RESET_CONFIG=true
echo "Resetting configuration (will re-prompt for all variables)..."
;;
--force-deploy)
FORCE_DEPLOY=true
echo "Force deployment mode enabled..."
;;
--skip-brew)
SKIP_BREW=true
echo "Skipping Homebrew package installation..."
;;
*)
echo "Unknown option: $arg"
echo "Usage: $0 [--reset] [--force-deploy] [--skip-brew]"
exit 1
;;
esac
done
echo "Setting up dotfiles environment..."
# Detect OS
OS="$(uname -s)"
if [[ "$SKIP_BREW" == false ]]; then
# Check if Homebrew is installed
if ! command -v brew &> /dev/null; then
echo "Homebrew is not installed. Please install it first:"
echo "https://brew.sh"
exit 1
fi
echo "Updating Homebrew..."
brew update
# Install packages (available on both macOS and Linux)
PACKAGES=(
dotter
fish
dust
eza
gh
htop
go
jq
lazygit
neovim
asdf
bat
pandoc
ripgrep
zoxide
zellij
p7zip
)
echo "Installing packages..."
for package in "${PACKAGES[@]}"; do
if brew list "$package" &>/dev/null; then
echo "$package already installed"
else
echo "Installing $package..."
brew install "$package"
fi
done
# Install casks on macOS only
if [[ "$OS" == "Darwin" ]]; then
echo "Installing macOS-specific casks..."
CASKS=(
iterm2
font-fira-code-nerd-font
orbstack
rectangle-pro
maccy
)
for cask in "${CASKS[@]}"; do
if brew list --cask "$cask" &>/dev/null; then
echo "$cask already installed"
else
echo "Installing $cask..."
brew install --cask "$cask"
fi
done
else
echo "Skipping macOS-specific casks (not on macOS)"
fi
fi
# Set up GitHub CLI authentication
if command -v gh &> /dev/null; then
if ! gh auth status &>/dev/null; then
echo ""
echo "GitHub CLI is installed but not authenticated."
echo "Please log in to GitHub CLI:"
gh auth login
else
echo "✓ GitHub CLI already authenticated"
fi
fi
# Configure Dotter
echo ""
echo "Configuring Dotter..."
# Path to user variables file
USER_VARS_FILE=".dotter/user_vars.sh"
# Source existing variables if not resetting
if [[ "$RESET_CONFIG" == false && -f "$USER_VARS_FILE" ]]; then
echo "Loading existing configuration..."
source "$USER_VARS_FILE"
fi
# Prompt for missing variables
if [[ -z "$GIT_NAME" ]]; then
read -p "Enter your Git user name: " GIT_NAME
fi
if [[ -z "$GIT_EMAIL" ]]; then
read -p "Enter your Git email: " GIT_EMAIL
fi
# Detect Homebrew path if not set
if [[ -z "$BREW_PATH" ]]; then
if [[ "$OS" == "Darwin" ]]; then
if [[ -d "/opt/homebrew" ]]; then
BREW_PATH="/opt/homebrew"
else
BREW_PATH="/usr/local"
fi
else
BREW_PATH="/home/linuxbrew/.linuxbrew"
fi
echo "Detected Homebrew path: $BREW_PATH"
fi
# Save variables to file
echo "Saving configuration..."
cat > "$USER_VARS_FILE" << EOF
# Dotter user variables
# This file is sourced by setup.sh to avoid re-prompting for values
# To reset and re-prompt for all values, run: ./setup.sh --reset
GIT_NAME="$GIT_NAME"
GIT_EMAIL="$GIT_EMAIL"
BREW_PATH="$BREW_PATH"
EOF
# Generate local.toml
echo "Generating Dotter configuration..."
cat > .dotter/local.toml << EOF
# Machine-specific Dotter configuration
# This file is generated by setup.sh
packages = ["git", "nvim", "fish", "zellij", "htop", "asdf"]
[variables]
git_name = "$GIT_NAME"
git_email = "$GIT_EMAIL"
brew_path = "$BREW_PATH"
EOF
# Deploy dotfiles
echo ""
echo "Deploying dotfiles..."
if [[ "$FORCE_DEPLOY" == true ]]; then
if dotter deploy -f -v; then
echo "✓ Dotfiles deployed successfully (forced)!"
else
echo "⚠ Dotter deployment failed."
fi
else
if dotter deploy -v; then
echo "✓ Dotfiles deployed successfully!"
else
echo "⚠ Dotter deployment failed. You may need to run 'dotter deploy -f' to force deployment."
fi
fi
# Manage directory symlinks (not handled by Dotter)
echo ""
echo "Setting up directory symlinks..."
DOTFILES_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
ensure_dir_symlink "$DOTFILES_DIR/fish/functions" "~/.config/fish/functions" "$FORCE_DEPLOY"
echo ""
echo "✓ Setup complete!"
echo ""
echo "Configuration saved to: $USER_VARS_FILE"
echo "To reconfigure, run: ./setup.sh --reset"
echo "To force deployment, run: ./setup.sh --force-deploy"
echo "To skip Homebrew packages, run: ./setup.sh --skip-brew"
echo ""
echo "Next steps:"
echo " 1. Consider setting fish as your default shell: chsh -s \$(which fish)"
echo " 2. Restart your terminal or source your new shell configuration"

532
zellij/config.kdl Normal file
View file

@ -0,0 +1,532 @@
keybinds clear-defaults=true {
locked {
bind "Ctrl g" { SwitchToMode "normal"; }
}
pane {
bind "left" { MoveFocus "left"; }
bind "down" { MoveFocus "down"; }
bind "up" { MoveFocus "up"; }
bind "right" { MoveFocus "right"; }
bind "c" { SwitchToMode "renamepane"; PaneNameInput 0; }
bind "d" { NewPane "down"; SwitchToMode "normal"; }
bind "e" { TogglePaneEmbedOrFloating; SwitchToMode "normal"; }
bind "f" { ToggleFocusFullscreen; SwitchToMode "normal"; }
bind "h" { MoveFocus "left"; }
bind "i" { TogglePanePinned; SwitchToMode "normal"; }
bind "j" { MoveFocus "down"; }
bind "k" { MoveFocus "up"; }
bind "l" { MoveFocus "right"; }
bind "n" { NewPane; SwitchToMode "normal"; }
bind "p" { SwitchFocus; }
bind "Ctrl p" { SwitchToMode "normal"; }
bind "r" { NewPane "right"; SwitchToMode "normal"; }
bind "s" { NewPane "stacked"; SwitchToMode "normal"; }
bind "w" { ToggleFloatingPanes; SwitchToMode "normal"; }
bind "z" { TogglePaneFrames; SwitchToMode "normal"; }
}
tab {
bind "left" { GoToPreviousTab; }
bind "down" { GoToNextTab; }
bind "up" { GoToPreviousTab; }
bind "right" { GoToNextTab; }
bind "1" { GoToTab 1; SwitchToMode "normal"; }
bind "2" { GoToTab 2; SwitchToMode "normal"; }
bind "3" { GoToTab 3; SwitchToMode "normal"; }
bind "4" { GoToTab 4; SwitchToMode "normal"; }
bind "5" { GoToTab 5; SwitchToMode "normal"; }
bind "6" { GoToTab 6; SwitchToMode "normal"; }
bind "7" { GoToTab 7; SwitchToMode "normal"; }
bind "8" { GoToTab 8; SwitchToMode "normal"; }
bind "9" { GoToTab 9; SwitchToMode "normal"; }
bind "[" { BreakPaneLeft; SwitchToMode "normal"; }
bind "]" { BreakPaneRight; SwitchToMode "normal"; }
bind "b" { BreakPane; SwitchToMode "normal"; }
bind "h" { GoToPreviousTab; }
bind "j" { GoToNextTab; }
bind "k" { GoToPreviousTab; }
bind "l" { GoToNextTab; }
bind "n" { NewTab; SwitchToMode "normal"; }
bind "r" { SwitchToMode "renametab"; TabNameInput 0; }
bind "s" { ToggleActiveSyncTab; SwitchToMode "normal"; }
bind "Ctrl t" { SwitchToMode "normal"; }
bind "x" { CloseTab; SwitchToMode "normal"; }
bind "tab" { ToggleTab; }
}
resize {
bind "left" { Resize "Increase left"; }
bind "down" { Resize "Increase down"; }
bind "up" { Resize "Increase up"; }
bind "right" { Resize "Increase right"; }
bind "+" { Resize "Increase"; }
bind "-" { Resize "Decrease"; }
bind "=" { Resize "Increase"; }
bind "H" { Resize "Decrease left"; }
bind "J" { Resize "Decrease down"; }
bind "K" { Resize "Decrease up"; }
bind "L" { Resize "Decrease right"; }
bind "h" { Resize "Increase left"; }
bind "j" { Resize "Increase down"; }
bind "k" { Resize "Increase up"; }
bind "l" { Resize "Increase right"; }
bind "Ctrl n" { SwitchToMode "normal"; }
}
move {
bind "left" { MovePane "left"; }
bind "down" { MovePane "down"; }
bind "up" { MovePane "up"; }
bind "right" { MovePane "right"; }
bind "h" { MovePane "left"; }
bind "Ctrl h" { SwitchToMode "normal"; }
bind "j" { MovePane "down"; }
bind "k" { MovePane "up"; }
bind "l" { MovePane "right"; }
bind "n" { MovePane; }
bind "p" { MovePaneBackwards; }
bind "tab" { MovePane; }
}
scroll {
bind "e" { EditScrollback; SwitchToMode "normal"; }
bind "s" { SwitchToMode "entersearch"; SearchInput 0; }
}
search {
bind "c" { SearchToggleOption "CaseSensitivity"; }
bind "n" { Search "down"; }
bind "o" { SearchToggleOption "WholeWord"; }
bind "p" { Search "up"; }
bind "w" { SearchToggleOption "Wrap"; }
}
session {
bind "a" {
LaunchOrFocusPlugin "zellij:about" {
floating true
move_to_focused_tab true
}
SwitchToMode "normal"
}
bind "c" {
LaunchOrFocusPlugin "configuration" {
floating true
move_to_focused_tab true
}
SwitchToMode "normal"
}
bind "Ctrl o" { SwitchToMode "normal"; }
bind "p" {
LaunchOrFocusPlugin "plugin-manager" {
floating true
move_to_focused_tab true
}
SwitchToMode "normal"
}
bind "s" {
LaunchOrFocusPlugin "zellij:share" {
floating true
move_to_focused_tab true
}
SwitchToMode "normal"
}
bind "w" {
LaunchOrFocusPlugin "session-manager" {
floating true
move_to_focused_tab true
}
SwitchToMode "normal"
}
}
shared_except "locked" {
bind "Alt left" { MoveFocusOrTab "left"; }
bind "Alt down" { MoveFocus "down"; }
bind "Alt up" { MoveFocus "up"; }
bind "Alt right" { MoveFocusOrTab "right"; }
bind "Alt +" { Resize "Increase"; }
bind "Alt -" { Resize "Decrease"; }
bind "Alt =" { Resize "Increase"; }
bind "Alt [" { PreviousSwapLayout; }
bind "Alt ]" { NextSwapLayout; }
bind "Alt f" { ToggleFloatingPanes; }
bind "Ctrl g" { SwitchToMode "locked"; }
bind "Alt h" { MoveFocusOrTab "left"; }
bind "Alt i" { MoveTab "left"; }
bind "Alt j" { MoveFocus "down"; }
bind "Alt k" { MoveFocus "up"; }
bind "Alt l" { MoveFocusOrTab "right"; }
bind "Alt n" { NewPane; }
bind "Alt o" { MoveTab "right"; }
bind "Alt p" { TogglePaneInGroup; }
bind "Alt Shift p" { ToggleGroupMarking; }
bind "Ctrl q" { Quit; }
}
shared_except "locked" "move" {
bind "Ctrl h" { SwitchToMode "move"; }
}
shared_except "locked" "session" {
bind "Ctrl o" { SwitchToMode "session"; }
}
shared_except "locked" "scroll" "search" "tmux" {
bind "Ctrl b" { SwitchToMode "tmux"; }
}
shared_except "locked" "scroll" "search" {
bind "Ctrl s" { SwitchToMode "scroll"; }
}
shared_except "locked" "tab" {
bind "Ctrl t" { SwitchToMode "tab"; }
}
shared_except "locked" "pane" {
bind "Ctrl p" { SwitchToMode "pane"; }
}
shared_except "locked" "resize" {
bind "Ctrl n" { SwitchToMode "resize"; }
}
shared_except "normal" "locked" "entersearch" {
bind "enter" { SwitchToMode "normal"; }
}
shared_except "normal" "locked" "entersearch" "renametab" "renamepane" {
bind "esc" { SwitchToMode "normal"; }
}
shared_among "pane" "tmux" {
bind "x" { CloseFocus; SwitchToMode "normal"; }
}
shared_among "scroll" "search" {
bind "PageDown" { PageScrollDown; }
bind "PageUp" { PageScrollUp; }
bind "left" { PageScrollUp; }
bind "down" { ScrollDown; }
bind "up" { ScrollUp; }
bind "right" { PageScrollDown; }
bind "Ctrl b" { PageScrollUp; }
bind "Ctrl c" { ScrollToBottom; SwitchToMode "normal"; }
bind "d" { HalfPageScrollDown; }
bind "Ctrl f" { PageScrollDown; }
bind "h" { PageScrollUp; }
bind "j" { ScrollDown; }
bind "k" { ScrollUp; }
bind "l" { PageScrollDown; }
bind "Ctrl s" { SwitchToMode "normal"; }
bind "u" { HalfPageScrollUp; }
}
entersearch {
bind "Ctrl c" { SwitchToMode "scroll"; }
bind "esc" { SwitchToMode "scroll"; }
bind "enter" { SwitchToMode "search"; }
}
renametab {
bind "esc" { UndoRenameTab; SwitchToMode "tab"; }
}
shared_among "renametab" "renamepane" {
bind "Ctrl c" { SwitchToMode "normal"; }
}
renamepane {
bind "esc" { UndoRenamePane; SwitchToMode "pane"; }
}
shared_among "session" "tmux" {
bind "d" { Detach; }
}
tmux {
bind "left" { MoveFocus "left"; SwitchToMode "normal"; }
bind "down" { MoveFocus "down"; SwitchToMode "normal"; }
bind "up" { MoveFocus "up"; SwitchToMode "normal"; }
bind "right" { MoveFocus "right"; SwitchToMode "normal"; }
bind "space" { NextSwapLayout; }
bind "\"" { NewPane "down"; SwitchToMode "normal"; }
bind "%" { NewPane "right"; SwitchToMode "normal"; }
bind "," { SwitchToMode "renametab"; }
bind "[" { SwitchToMode "scroll"; }
bind "Ctrl b" { Write 2; SwitchToMode "normal"; }
bind "c" { NewTab; SwitchToMode "normal"; }
bind "h" { MoveFocus "left"; SwitchToMode "normal"; }
bind "j" { MoveFocus "down"; SwitchToMode "normal"; }
bind "k" { MoveFocus "up"; SwitchToMode "normal"; }
bind "l" { MoveFocus "right"; SwitchToMode "normal"; }
bind "n" { GoToNextTab; SwitchToMode "normal"; }
bind "o" { FocusNextPane; }
bind "p" { GoToPreviousTab; SwitchToMode "normal"; }
bind "z" { ToggleFocusFullscreen; SwitchToMode "normal"; }
}
}
// Plugin aliases - can be used to change the implementation of Zellij
// changing these requires a restart to take effect
plugins {
about location="zellij:about"
compact-bar location="zellij:compact-bar"
configuration location="zellij:configuration"
filepicker location="zellij:strider" {
cwd "/"
}
plugin-manager location="zellij:plugin-manager"
session-manager location="zellij:session-manager"
status-bar location="zellij:status-bar"
strider location="zellij:strider"
tab-bar location="zellij:tab-bar"
welcome-screen location="zellij:session-manager" {
welcome_screen true
}
}
// Plugins to load in the background when a new session starts
// eg. "file:/path/to/my-plugin.wasm"
// eg. "https://example.com/my-plugin.wasm"
load_plugins {
}
web_client {
font "monospace"
}
// Use a simplified UI without special fonts (arrow glyphs)
// Options:
// - true
// - false (Default)
//
// simplified_ui true
// Choose the theme that is specified in the themes section.
// Default: default
//
// theme "dracula"
// Choose the base input mode of zellij.
// Default: normal
//
// default_mode "locked"
// Choose the path to the default shell that zellij will use for opening new panes
// Default: $SHELL
//
default_shell "fish"
// Choose the path to override cwd that zellij will use for opening new panes
//
// default_cwd "/tmp"
// The name of the default layout to load on startup
// Default: "default"
//
// default_layout "compact"
// The folder in which Zellij will look for layouts
// (Requires restart)
//
// layout_dir "/tmp"
// The folder in which Zellij will look for themes
// (Requires restart)
//
// theme_dir "/tmp"
// Toggle enabling the mouse mode.
// On certain configurations, or terminals this could
// potentially interfere with copying text.
// Options:
// - true (default)
// - false
//
// mouse_mode false
// Toggle having pane frames around the panes
// Options:
// - true (default, enabled)
// - false
//
// pane_frames false
// When attaching to an existing session with other users,
// should the session be mirrored (true)
// or should each user have their own cursor (false)
// (Requires restart)
// Default: false
//
// mirror_session true
// Choose what to do when zellij receives SIGTERM, SIGINT, SIGQUIT or SIGHUP
// eg. when terminal window with an active zellij session is closed
// (Requires restart)
// Options:
// - detach (Default)
// - quit
//
// on_force_close "quit"
// Configure the scroll back buffer size
// This is the number of lines zellij stores for each pane in the scroll back
// buffer. Excess number of lines are discarded in a FIFO fashion.
// (Requires restart)
// Valid values: positive integers
// Default value: 10000
//
// scroll_buffer_size 10000
// Provide a command to execute when copying text. The text will be piped to
// the stdin of the program to perform the copy. This can be used with
// terminal emulators which do not support the OSC 52 ANSI control sequence
// that will be used by default if this option is not set.
// Examples:
//
// copy_command "xclip -selection clipboard" // x11
// copy_command "wl-copy" // wayland
// copy_command "pbcopy" // osx
//
// copy_command "pbcopy"
// Choose the destination for copied text
// Allows using the primary selection buffer (on x11/wayland) instead of the system clipboard.
// Does not apply when using copy_command.
// Options:
// - system (default)
// - primary
//
// copy_clipboard "primary"
// Enable automatic copying (and clearing) of selection when releasing mouse
// Default: true
//
// copy_on_select true
// Path to the default editor to use to edit pane scrollbuffer
// Default: $EDITOR or $VISUAL
// scrollback_editor "/usr/bin/vim"
// A fixed name to always give the Zellij session.
// Consider also setting `attach_to_session true,`
// otherwise this will error if such a session exists.
// Default: <RANDOM>
//
// session_name "My singleton session"
// When `session_name` is provided, attaches to that session
// if it is already running or creates it otherwise.
// Default: false
//
// attach_to_session true
// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
// Options:
// - true (default)
// - false
//
// auto_layout false
// Whether sessions should be serialized to the cache folder (including their tabs/panes, cwds and running commands) so that they can later be resurrected
// Options:
// - true (default)
// - false
//
// session_serialization false
// Whether pane viewports are serialized along with the session, default is false
// Options:
// - true
// - false (default)
//
// serialize_pane_viewport false
// Scrollback lines to serialize along with the pane viewport when serializing sessions, 0
// defaults to the scrollback size. If this number is higher than the scrollback size, it will
// also default to the scrollback size. This does nothing if `serialize_pane_viewport` is not true.
//
// scrollback_lines_to_serialize 10000
// Enable or disable the rendering of styled and colored underlines (undercurl).
// May need to be disabled for certain unsupported terminals
// (Requires restart)
// Default: true
//
// styled_underlines false
// How often in seconds sessions are serialized
//
// serialization_interval 10000
// Enable or disable writing of session metadata to disk (if disabled, other sessions might not know
// metadata info on this session)
// (Requires restart)
// Default: false
//
// disable_session_metadata false
// Enable or disable support for the enhanced Kitty Keyboard Protocol (the host terminal must also support it)
// (Requires restart)
// Default: true (if the host terminal supports it)
//
// support_kitty_keyboard_protocol false
// Whether to make sure a local web server is running when a new Zellij session starts.
// This web server will allow creating new sessions and attaching to existing ones that have
// opted in to being shared in the browser.
// When enabled, navigate to http://127.0.0.1:8082
// (Requires restart)
//
// Note: a local web server can still be manually started from within a Zellij session or from the CLI.
// If this is not desired, one can use a version of Zellij compiled without
// `web_server_capability`
//
// Possible values:
// - true
// - false
// Default: false
//
// web_server false
// Whether to allow sessions started in the terminal to be shared through a local web server, assuming one is
// running (see the `web_server` option for more details).
// (Requires restart)
//
// Note: This is an administrative separation and not intended as a security measure.
//
// Possible values:
// - "on" (allow web sharing through the local web server if it
// is online)
// - "off" (do not allow web sharing unless sessions explicitly opt-in to it)
// - "disabled" (do not allow web sharing and do not permit sessions started in the terminal to opt-in to it)
// Default: "off"
//
// web_sharing "off"
// A path to a certificate file to be used when setting up the web client to serve the
// connection over HTTPs
//
// web_server_cert "/path/to/cert.pem"
// A path to a key file to be used when setting up the web client to serve the
// connection over HTTPs
//
// web_server_key "/path/to/key.pem"
/// Whether to enforce https connections to the web server when it is bound to localhost
/// (127.0.0.0/8)
///
/// Note: https is ALWAYS enforced when bound to non-local interfaces
///
/// Default: false
//
// enforce_https_for_localhost false
// Whether to stack panes when resizing beyond a certain size
// Default: true
//
// stacked_resize false
// Whether to show tips on startup
// Default: true
//
show_startup_tips false
// Whether to show release notes on first version run
// Default: true
//
// show_release_notes false
// Whether to enable mouse hover effects and pane grouping functionality
// default is true
// advanced_mouse_actions false
// The ip address the web server should listen on when it starts
// Default: "127.0.0.1"
// (Requires restart)
// web_server_ip "127.0.0.1"
// The port the web server should listen on when it starts
// Default: 8082
// (Requires restart)
// web_server_port 8082
// A command to run (will be wrapped with sh -c and provided the RESURRECT_COMMAND env variable)
// after Zellij attempts to discover a command inside a pane when resurrecting sessions, the STDOUT
// of this command will be used instead of the discovered RESURRECT_COMMAND
// can be useful for removing wrappers around commands
// Note: be sure to escape backslashes and similar characters properly
// post_command_discovery_hook "echo $RESURRECT_COMMAND | sed <your_regex_here>"