diff --git a/.Brewfile.ignore b/.Brewfile.ignore new file mode 100644 index 0000000..cbede01 --- /dev/null +++ b/.Brewfile.ignore @@ -0,0 +1,6 @@ +# Add package names here to ignore them in Brewfile updates. +# One package per line. +# Example: +# iterm2 +# wget +orbstack diff --git a/.githooks/pre-commit b/.githooks/pre-commit new file mode 120000 index 0000000..7bbabda --- /dev/null +++ b/.githooks/pre-commit @@ -0,0 +1 @@ +githooks.sh \ No newline at end of file diff --git a/.githooks/pre-commit.d/05-check-brewfile b/.githooks/pre-commit.d/05-check-brewfile new file mode 100755 index 0000000..2e51b81 --- /dev/null +++ b/.githooks/pre-commit.d/05-check-brewfile @@ -0,0 +1,20 @@ +#!/usr/bin/env bash + +# Check if Brewfile needs updating +if [[ "$(uname)" != "Darwin" ]]; then + exit 0 +fi + +# We use the script we just created +UPDATE_SCRIPT="bin/macos/update_brewfile" + +if [[ -x "$UPDATE_SCRIPT" ]]; then + # Run in dry-run mode and see if there's output + DIFF_OUTPUT=$("$UPDATE_SCRIPT" --dry-run 2>/dev/null) + if [[ "$DIFF_OUTPUT" == *"Changes detected"* ]]; then + echo "⚠️ Brewfile is out of sync with your installed packages." + echo " Run '$UPDATE_SCRIPT' to synchronize it." + echo "" + # We don't fail the commit, just warn. + fi +fi diff --git a/AGENTS.md b/AGENTS.md index 753a6e3..57825fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -10,17 +10,24 @@ locations, but also installs dependencies in various ways. I primarily target Debian Linux-based (Debian, Ubuntu, and Kali Linux) systems as well as MacOS. Other platforms are lower priorities. Shell scripts ending in `.sh` should use only POSIX features unless there is a shebang line at the -beginning suggesting a different shell will be used. +beginning suggesting a different shell will be used. In particular, those +in directories with names like bash might use those shells. `zsh` and `fish` are the key interactive shells to be configured, but `bash` may also be used at times. ## Project Structure -* `bin/`: Contains executable scripts that should be available in the shell's `PATH`. -* `dotfiles/`: Contains configuration files (dotfiles) to be symlinked into the home directory. -* `packages/`: Contains lists of packages to be installed by the `install.sh` script. Each file in this directory corresponds to a package set. -* `install.sh`: The main installation script that sets up the environment, symlinks dotfiles, and installs packages. +* `bin/`: Contains executable scripts symlinked to `~/bin/`. Subdirectories like `macos/`, `restic/`, and `setup/` are included. +* `dotfiles/`: Contains configuration files (dotfiles) symlinked to the home directory. +* `dotfile_overlays/`: Each directory within is symlinked to the home directory, allowing for modular or git-submodule-based configurations. +* `local_dotfiles/`: If present, its contents are symlinked to the home directory (ignored by git). +* `packages/`: Contains lists of packages (one per line) for different environments or toolsets. +* `keys/`: Contains SSH keys (`ssh/`), GPG keys (`gpg/`), and a `known_hosts` file to be installed/merged. +* `skeltools/`: Internal utilities used by the installation scripts. +* `sysctl/` and `udev/`: Linux system configuration files. +* `Brewfile`: Homebrew package list for macOS environments. +* `install.sh`: The primary installation script for symlinking and basic setup. ## Notes on Security Issues @@ -43,18 +50,20 @@ If making changes that affects how the user installs the tools, update ### Adding a new dotfile 1. Place the new dotfile in the `dotfiles/` directory. -2. The `install.sh` script will automatically symlink it to the home directory. +2. Alternatively, use `dotfile_overlays/` if the dotfile belongs to a specific group or submodule. +3. The `install.sh` script will automatically symlink it to the home directory. ### Adding a new script to `bin/` -1. Add the new script to the `bin/` directory. +1. Add the new script to the `bin/` directory (or an appropriate subdirectory). 2. Ensure the script is executable (`chmod +x`). ### Adding a new package 1. Identify the appropriate package list in the `packages/` directory (e.g., `packages/cli`, `packages/kali`). -2. Add the new package name to the list. +2. Add the new package name to the list (one per line). 3. If a new package set is required, create a new file in the `packages/` directory. +4. For macOS-specific packages, also consider adding them to the `Brewfile`. ### Platform-specific changes diff --git a/Brewfile b/Brewfile index 1a0b116..0e953f1 100644 --- a/Brewfile +++ b/Brewfile @@ -66,9 +66,7 @@ brew "zlib" brew "zsh-syntax-highlighting" brew "sass/sass/migrator" brew "sass/sass/sass" -cask "claude-code" cask "codeql" -cask "cryptomator" cask "cyberduck" cask "font-fira-code-nerd-font" cask "font-fira-mono-nerd-font" @@ -77,7 +75,6 @@ cask "font-hack-nerd-font" cask "font-inconsolata-nerd-font" cask "font-symbols-only-nerd-font" cask "font-terminess-ttf-nerd-font" -cask "gcloud-cli" cask "ghidra" cask "gimp" cask "github" @@ -85,7 +82,6 @@ cask "iterm2" cask "macfuse" cask "meld" cask "mitmproxy" -cask "orbstack" cask "raycast" cask "rectangle" cask "scroll-reverser" @@ -93,9 +89,18 @@ cask "temurin" cask "veracrypt" cask "zulu@17" +def is_corp? + # Check for MDM enrollment (Enrolled via DEP: Yes) + `profiles status -type enrollment 2>/dev/null`.include?("Enrolled via DEP: Yes") +end + # non-corp -if ENV['USER'] != "davidtomaschik" +if !is_corp? brew "bazel" brew "openssh" + cask "claude-code" + cask "cryptomator" + cask "gcloud-cli" cask "google-cloud-sdk" + cask "orbstack" end diff --git a/README.md b/README.md index c73cb51..5e92d77 100644 --- a/README.md +++ b/README.md @@ -1,16 +1,24 @@ ### About ### This is a repository of configuration files that I like to have on all the -machines that I use. I can just clone the repository and run "repo/setup.sh" -and get most things setup the way I like them. +machines that I use. For new systems, you can bootstrap by running the +included `clone.sh` script: + +```bash +curl -L https://raw.githubusercontent.com/Matir/skel/master/clone.sh | bash +``` + +Alternatively, you can manually clone the repository and run `./install.sh`. This started just as dotfiles, but expanded to include SSH keys, GPG keys, -packages I like installed, and an ever-growing setup script. There are various +and an ever-growing setup script. There are various options to install just parts of it, such as on a machine where I only have a user account but no root. -This now uses [git-crypt](https://github.com/AGWA/git-crypt) to protect -`private_dotfiles` for things I don't want to splash all over the internet. :) +This environment supports using `dotfile_overlays/` or `local_dotfiles/` to +manage machine-specific or private configurations. You can use +[git-crypt](https://github.com/AGWA/git-crypt) on these overlay directories +for things you don't want to splash all over the internet. :) I still wouldn't check in anything terribly sensitive, like private keys. ### Usefulness ### @@ -44,16 +52,30 @@ sudo apt-get install xbindkeys xdotool After installation, the functionality will be enabled automatically on your next login. +On macOS, you can install the recommended packages using the included `Brewfile`: + +```bash +brew bundle install +``` + +### Packages ### + +The `packages/` directory contains lists of recommended packages. You can +manually install a set (e.g., on a Debian-based system) using: + +```bash +grep -v "^#" packages/cli | xargs sudo apt-get install -y +``` + ``` BASEDIR: Where the skel framework is installed. Defaults to $HOME/.skel MINIMAL: Don't do things that require git clones or installation of anything - not included in my .skel. (Defaults to 0, installs everything.) + not included in my .skel. (e.g., skips vim-plug, TPM) (Defaults to 0) INSTALL_KEYS: Install GnuPG and SSH keys. SSH keys are placed in authorized_keys. (Defaults to 1, installs keys.) TRUST_ALL_KEYS: Allow all keys to be used for SSH login, versus a small subset. -INSTALL_PKGS: Install common packages, if on a Debian-like system. - (Defaults to opposite of $MINIMAL.) -SAVE: Save the install options to ${BASEDIR}/installed-prefs +VERBOSE: Enable verbose output during installation. (Defaults to 0) +SAVE: Save the install options to ${BASEDIR}/.installed-prefs ``` ### TODO ### diff --git a/bin/macos/update_brewfile b/bin/macos/update_brewfile new file mode 100755 index 0000000..9a6af7e --- /dev/null +++ b/bin/macos/update_brewfile @@ -0,0 +1,156 @@ +#!/usr/bin/env python3 + +import os +import subprocess +import re +import sys +import argparse +import difflib + +# Regex to match brew/cask/tap/mas lines +PKG_RE = re.compile(r'^\s*(brew|cask|tap|mas)\s+["\']([^"\']+)["\'](.*)$') + +def get_repo_root(): + try: + root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'], + stderr=subprocess.STDOUT).decode().strip() + return root + except subprocess.CalledProcessError: + return os.getcwd() + +def get_ignore_list(repo_root): + ignore = set() + paths = [ + os.path.join(repo_root, '.Brewfile.ignore'), + os.path.expanduser('~/.Brewfile.ignore'), + os.path.expanduser('~/.config/homebrew/ignore') + ] + for path in paths: + if os.path.exists(path): + with open(path) as f: + for line in f: + line = line.split('#')[0].strip() + if line: + ignore.add(line) + return ignore + +def get_current_packages(): + """Runs brew bundle dump and returns lines.""" + try: + output = subprocess.check_output(['brew', 'bundle', 'dump', '--file=-'], + stderr=subprocess.DEVNULL).decode() + return output.splitlines() + except subprocess.CalledProcessError: + print("Error: 'brew bundle dump' failed. Is homebrew installed?", file=sys.stderr) + sys.exit(1) + +def parse_brewfile(content): + """ + Parses Brewfile content. + Returns: + - conditional_pkgs: set of (type, name) + - preserved_footer: string (everything from first conditional onwards) + """ + lines = content.splitlines() + conditional_pkgs = set() + + # Find the start of the first conditional block + first_conditional_idx = -1 + in_conditional = 0 + + for i, line in enumerate(lines): + stripped = line.strip() + if stripped.startswith(('if ', 'unless ', 'case ')) and not stripped.endswith('; end'): + if first_conditional_idx == -1: + # Look back for comments that might belong to this block + j = i - 1 + while j >= 0 and (lines[j].strip().startswith('#') or not lines[j].strip()): + j -= 1 + first_conditional_idx = j + 1 + in_conditional += 1 + + if in_conditional > 0: + match = PKG_RE.match(line) + if match: + conditional_pkgs.add((match.group(1), match.group(2))) + + if stripped == 'end' or stripped.endswith('; end'): + in_conditional -= 1 + + if first_conditional_idx == -1: + return set(), "" + + footer = "\n".join(lines[first_conditional_idx:]) + return conditional_pkgs, footer + +def main(args): + repo_root = get_repo_root() + brewfile_path = os.path.join(repo_root, 'Brewfile') + + if not os.path.exists(brewfile_path): + print(f"Error: Brewfile not found at {brewfile_path}", file=sys.stderr) + sys.exit(1) + + with open(brewfile_path) as f: + old_content = f.read() + + conditional_pkgs, footer = parse_brewfile(old_content) + ignore_list = get_ignore_list(repo_root) + + dumped_lines = get_current_packages() + + new_unconditional_lines = [] + + for line in dumped_lines: + match = PKG_RE.match(line) + if match: + pkg_type, pkg_name = match.group(1), match.group(2) + if pkg_name in ignore_list: + continue + if (pkg_type, pkg_name) in conditional_pkgs: + continue + + # If it's not a package line (e.g. comment from dump), we can skip or keep + if line.strip(): + new_unconditional_lines.append(line) + + # Sort lines by type (tap, brew, cask, mas) then name + def sort_key(line): + match = PKG_RE.match(line) + if not match: return (4, line) + order = {'tap': 0, 'brew': 1, 'cask': 2, 'mas': 3} + return (order.get(match.group(1), 4), match.group(2)) + + new_unconditional_lines.sort(key=sort_key) + + # Build new content + new_content = "\n".join(new_unconditional_lines) + if footer: + if new_unconditional_lines: + new_content += "\n\n" + new_content += footer.strip() + "\n" + else: + new_content += "\n" + + if new_content == old_content: + print("Brewfile is already up to date.") + else: + if args.dry_run: + print("Changes detected (dry run):") + diff = difflib.unified_diff( + old_content.splitlines(keepends=True), + new_content.splitlines(keepends=True), + fromfile='Brewfile (original)', + tofile='Brewfile (new)' + ) + sys.stdout.writelines(diff) + else: + with open(brewfile_path, 'w') as f: + f.write(new_content) + print("Brewfile updated.") + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description="Update Brewfile while preserving conditionals.") + parser.add_argument("--dry-run", action="store_true", help="Show changes without applying them.") + args = parser.parse_args() + main(args) diff --git a/dotfiles/config/gemini/settings.json b/dotfiles/config/gemini/settings.json new file mode 100644 index 0000000..8d8424a --- /dev/null +++ b/dotfiles/config/gemini/settings.json @@ -0,0 +1,15 @@ +{ + "editor": { + "mode": "vim" + }, + "context": { + "includeFiles": [ + "/usr/local/google/home/davidtomaschik/.skel/GEMINI.md", + "/usr/local/google/home/davidtomaschik/.skel/AGENTS.md" + ] + }, + "experimental": { + "skills": true, + "planMode": true + } +} \ No newline at end of file diff --git a/dotfiles/config/mise/config.toml b/dotfiles/config/mise/config.toml index 392867f..33f298c 100644 --- a/dotfiles/config/mise/config.toml +++ b/dotfiles/config/mise/config.toml @@ -9,6 +9,7 @@ uv_venv_auto = true [tools] age = "latest" +age-plugin-yubikey = "latest" usage = "latest" uv = "latest" diff --git a/dotfiles/config/starship.toml b/dotfiles/config/starship.toml index c167349..1cfa5e5 100644 --- a/dotfiles/config/starship.toml +++ b/dotfiles/config/starship.toml @@ -39,3 +39,15 @@ disabled = true [kubernetes] disabled = false detect_folders = ["k8s"] + +[custom.gemini_context] +description = "Displays the current Gemini CLI context" +when = "test -n \"$GEMINI_CLI_HOME\"" +command = """ +context_dir=\"${XDG_CONFIG_HOME:-$HOME/.config}/gemini\" +if [[ \"$GEMINI_CLI_HOME\" == $context_dir/* ]]; then + basename \"$GEMINI_CLI_HOME\" +fi +""" +style = "bold blue" +format = "♊[$output](blue) " diff --git a/dotfiles/shenv b/dotfiles/shenv index c04c04c..645bcb3 100755 --- a/dotfiles/shenv +++ b/dotfiles/shenv @@ -97,31 +97,87 @@ export EARTHLY_SSH_AUTH_SOCK="" # Handle SSH_AUTH_SOCK for tmux consistency _SSH_AUTH_LINK="${HOME}/.ssh/ssh_auth_sock" -if [ -z "${SSH_AUTH_SOCK:-}" ] || [ ! -S "${SSH_AUTH_SOCK}" ] ; then - # Try to find a working GPG agent SSH socket if no agent is set or current is broken - if command -v gpgconf >/dev/null 2>&1; then - _GPG_SSH_SOCK=$(gpgconf --list-dirs agent-ssh-socket 2>/dev/null) - fi - # Fallback to common paths if gpgconf fails or isn't present - if [ -z "${_GPG_SSH_SOCK}" ] || [ ! -S "${_GPG_SSH_SOCK}" ]; then - _GPG_SSH_SOCK="${GNUPGHOME:-$HOME/.gnupg}/S.gpg-agent.ssh" - [ -S "$_GPG_SSH_SOCK" ] || _GPG_SSH_SOCK="/run/user/$(id -u)/gnupg/S.gpg-agent.ssh" - fi - if [ -S "${_GPG_SSH_SOCK}" ] ; then - export SSH_AUTH_SOCK="$_GPG_SSH_SOCK" +# Helper to check if a path is our link or points to it +_is_link_path() { + [ -z "$1" ] && return 1 + [ "$1" = "${_SSH_AUTH_LINK}" ] && return 0 + if [ -L "$1" ] && command -v readlink >/dev/null 2>&1; then + _T=$(readlink "$1") + # Handle relative symlinks + case "${_T}" in /*) ;; *) _T="$(dirname "$1")/${_T}" ;; esac + [ "${_T}" = "${_SSH_AUTH_LINK}" ] && return 0 fi - unset _GPG_SSH_SOCK + return 1 +} + +_CANDIDATE="" + +# 1. If current environment has a valid socket that is NOT our link, it's a prime candidate (e.g. SSH forwarding). +if [ -S "${SSH_AUTH_SOCK:-}" ] && ! _is_link_path "${SSH_AUTH_SOCK}"; then + _CANDIDATE="${SSH_AUTH_SOCK}" fi -# If we have a valid socket but it's not our stable link, sync the link and use it. -# This ensures tmux (using the static path) always finds the most recent agent. -if [ -S "${SSH_AUTH_SOCK:-}" ] && [ "${SSH_AUTH_SOCK}" != "${_SSH_AUTH_LINK}" ] ; then - [ -d "$(dirname "${_SSH_AUTH_LINK}")" ] || mkdir -p "$(dirname "${_SSH_AUTH_LINK}")" - ln -sf "${SSH_AUTH_SOCK}" "${_SSH_AUTH_LINK}" +# 2. If no candidate yet, or we're currently using the link, try to find the "real" system agent. +if [ -z "${_CANDIDATE}" ] || _is_link_path "${SSH_AUTH_SOCK:-}"; then + _FOUND="" + if [ "$(uname)" = "Darwin" ]; then + _FOUND=$(launchctl getenv SSH_AUTH_SOCK 2>/dev/null) + elif command -v systemctl >/dev/null 2>&1; then + # Query systemd socket units directly to avoid environment overrides. + for _u in ssh-agent.socket openssh-agent.socket gcr-ssh-agent.socket gpg-agent-ssh.socket; do + _P=$(systemctl --user show "${_u}" -p Listen 2>/dev/null | cut -d= -f2- | cut -d' ' -f1) + if [ -S "${_P}" ]; then + _FOUND="${_P}" + break + fi + done + # Fallback to systemd environment + if [ -z "${_FOUND}" ] || _is_link_path "${_FOUND}"; then + _FOUND=$(systemctl --user show-environment 2>/dev/null | grep "^SSH_AUTH_SOCK=" | cut -d= -f2-) + fi + fi + + if [ -S "${_FOUND}" ] && ! _is_link_path "${_FOUND}"; then + _CANDIDATE="${_FOUND}" + fi +fi + +# 3. Last resort: search common paths if we still don't have a valid candidate. +if [ ! -S "${_CANDIDATE}" ]; then + _U=$(id -u) + for _p in "/run/user/${_U}/keyring/ssh" "/run/user/${_U}/ssh-agent.socket" "/run/user/${_U}/openssh_agent" "/run/user/${_U}/gnupg/S.gpg-agent.ssh"; do + if [ -S "${_p}" ] && ! _is_link_path "${_p}"; then + _CANDIDATE="${_p}" + break + fi + done + if [ -z "${_CANDIDATE}" ]; then + # Build search path list based on what actually exists + _SEARCH="" + for _d in "/run/user/${_U}" /tmp; do [ -d "${_d}" ] && _SEARCH="${_SEARCH} ${_d}"; done + if [ -n "${_SEARCH}" ]; then + _CANDIDATE=$(find ${_SEARCH} -maxdepth 2 -type s -name 'agent.*' 2>/dev/null | grep -F -v "${_SSH_AUTH_LINK}" | head -n 1) + fi + fi +fi + +# 4. Sync the stable link if we found a valid "real" socket. +if [ -S "${_CANDIDATE}" ] && ! _is_link_path "${_CANDIDATE}"; then + mkdir -p "$(dirname "${_SSH_AUTH_LINK}")" + ln -sf "${_CANDIDATE}" "${_SSH_AUTH_LINK}" + export SSH_AUTH_SOCK="${_SSH_AUTH_LINK}" + # Update systemd if present to keep everything in sync + if command -v systemctl >/dev/null 2>&1; then + systemctl --user set-environment SSH_AUTH_SOCK="${_SSH_AUTH_LINK}" 2>/dev/null + fi +elif [ -S "${_SSH_AUTH_LINK}" ]; then + # If we found nothing better but the link is valid, use it. export SSH_AUTH_SOCK="${_SSH_AUTH_LINK}" fi -unset _SSH_AUTH_LINK + +unset _SSH_AUTH_LINK _CANDIDATE _FOUND _T _P _U _u _SEARCH _d +unset -f _is_link_path # Setup XDG-like dirs on MacOS # Based on https://leebyron.com/til/mac-xdg/ diff --git a/dotfiles/vim/pack/matir/opt/.keep b/dotfiles/vim/pack/matir/opt/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/dotfiles/vim/pack/matir/start/.keep b/dotfiles/vim/pack/matir/start/.keep deleted file mode 100644 index e69de29..0000000 diff --git a/dotfiles/weechat/alias.conf b/dotfiles/weechat/alias.conf deleted file mode 100644 index 069fc02..0000000 --- a/dotfiles/weechat/alias.conf +++ /dev/null @@ -1,41 +0,0 @@ -# -# weechat -- alias.conf -# - -[cmd] -AAWAY = "allserv /away" -AME = "allchan /me" -AMSG = "allchan /msg *" -ANICK = "allserv /nick" -BEEP = "print -beep" -BYE = "quit" -C = "buffer clear" -CHAT = "dcc chat" -CL = "buffer clear" -CLOSE = "buffer close" -EXIT = "quit" -IG = "ignore" -J = "join" -K = "kick" -KB = "kickban" -LEAVE = "part" -M = "msg" -MSGBUF = "command -buffer $1 * /input send $2-" -MUB = "unban *" -N = "names" -Q = "query" -REDRAW = "window refresh" -SAY = "msg *" -SIGNOFF = "quit" -T = "topic" -UB = "unban" -UMODE = "mode $nick" -V = "command core version" -W = "who" -WC = "window merge" -WI = "whois" -WII = "whois $1 $1" -WW = "whowas" - -[completion] -MSGBUF = "%(buffers_plugins_names)" diff --git a/dotfiles/weechat/aspell.conf b/dotfiles/weechat/aspell.conf deleted file mode 100644 index c3d12dc..0000000 --- a/dotfiles/weechat/aspell.conf +++ /dev/null @@ -1,20 +0,0 @@ -# -# weechat -- aspell.conf -# - -[color] -misspelled = lightred -suggestions = default - -[check] -commands = "ame,amsg,away,command,cycle,kick,kickban,me,msg,notice,part,query,quit,topic" -default_dict = "" -during_search = off -enabled = off -real_time = off -suggestions = -1 -word_min_length = 2 - -[dict] - -[option] diff --git a/dotfiles/weechat/charset.conf b/dotfiles/weechat/charset.conf deleted file mode 100644 index 99a90d5..0000000 --- a/dotfiles/weechat/charset.conf +++ /dev/null @@ -1,11 +0,0 @@ -# -# weechat -- charset.conf -# - -[default] -decode = "iso-8859-1" -encode = "" - -[decode] - -[encode] diff --git a/dotfiles/weechat/exec.conf b/dotfiles/weechat/exec.conf deleted file mode 100644 index 39f1929..0000000 --- a/dotfiles/weechat/exec.conf +++ /dev/null @@ -1,11 +0,0 @@ -# -# weechat -- exec.conf -# - -[command] -default_options = "" -purge_delay = 0 - -[color] -flag_finished = lightred -flag_running = lightgreen diff --git a/dotfiles/weechat/irc.conf b/dotfiles/weechat/irc.conf deleted file mode 100644 index 18ecd46..0000000 --- a/dotfiles/weechat/irc.conf +++ /dev/null @@ -1,377 +0,0 @@ -# -# weechat -- irc.conf -# - -[look] -buffer_open_before_autojoin = on -buffer_open_before_join = off -buffer_switch_autojoin = on -buffer_switch_join = on -color_nicks_in_names = off -color_nicks_in_nicklist = off -color_nicks_in_server_messages = on -color_pv_nick_like_channel = on -ctcp_time_format = "%a, %d %b %Y %T %z" -display_away = local -display_ctcp_blocked = on -display_ctcp_reply = on -display_ctcp_unknown = on -display_host_join = on -display_host_join_local = on -display_host_quit = on -display_join_message = "329,332,333,366" -display_old_topic = on -display_pv_away_once = on -display_pv_back = on -highlight_channel = "$nick" -highlight_pv = "$nick" -highlight_server = "$nick" -highlight_tags_restrict = "irc_privmsg,irc_notice" -item_channel_modes_hide_args = "k" -item_display_server = buffer_plugin -item_nick_modes = on -item_nick_prefix = on -join_auto_add_chantype = off -msgbuffer_fallback = current -new_channel_position = none -new_pv_position = none -nick_completion_smart = speakers -nick_mode = prefix -nick_mode_empty = off -nicks_hide_password = "nickserv" -notice_as_pv = auto -notice_welcome_redirect = on -notice_welcome_tags = "" -notify_tags_ison = "notify_message" -notify_tags_whois = "notify_message" -part_closes_buffer = on -pv_buffer = independent -pv_tags = "notify_private" -raw_messages = 256 -server_buffer = merge_with_core -smart_filter = on -smart_filter_delay = 5 -smart_filter_join = on -smart_filter_join_unmask = 30 -smart_filter_mode = "+" -smart_filter_nick = on -smart_filter_quit = on -temporary_servers = off -topic_strip_colors = off - -[color] -input_nick = lightcyan -item_channel_modes = default -item_lag_counting = default -item_lag_finished = yellow -item_nick_modes = default -message_join = green -message_quit = red -mirc_remap = "1,-1:darkgray" -nick_prefixes = "q:lightred;a:lightcyan;o:lightgreen;h:lightmagenta;v:yellow;*:lightblue" -notice = green -reason_quit = default -topic_current = default -topic_new = white -topic_old = default - -[network] -autoreconnect_delay_growing = 2 -autoreconnect_delay_max = 600 -ban_mask_default = "*!$ident@$host" -channel_encode = off -colors_receive = on -colors_send = on -lag_check = 60 -lag_max = 1800 -lag_min_show = 500 -lag_reconnect = 0 -lag_refresh_interval = 1 -notify_check_ison = 1 -notify_check_whois = 5 -sasl_fail_unavailable = on -send_unknown_commands = off -whois_double_nick = off - -[msgbuffer] - -[ctcp] - -[ignore] - -[server_default] -addresses = "" -anti_flood_prio_high = 2 -anti_flood_prio_low = 2 -autoconnect = off -autojoin = "" -autoreconnect = on -autoreconnect_delay = 10 -autorejoin = off -autorejoin_delay = 30 -away_check = 0 -away_check_max_nicks = 25 -capabilities = "" -command = "" -command_delay = 0 -connection_timeout = 60 -ipv6 = on -local_hostname = "" -msg_kick = "" -msg_part = "WeeChat ${info:version}" -msg_quit = "WeeChat ${info:version}" -nicks = "Matir,Matir~,Matir[]" -nicks_alternate = on -notify = "" -password = "" -proxy = "" -realname = "" -sasl_fail = continue -sasl_key = "" -sasl_mechanism = plain -sasl_password = "" -sasl_timeout = 15 -sasl_username = "" -ssl = off -ssl_cert = "" -ssl_dhkey_size = 2048 -ssl_fingerprint = "" -ssl_priorities = "NORMAL" -ssl_verify = on -username = "matir" - -[server] -freenode.addresses = "chat.freenode.net/7000" -freenode.proxy -freenode.ipv6 -freenode.ssl = on -freenode.ssl_cert = "%h/certs/freenode-matir.pem" -freenode.ssl_priorities -freenode.ssl_dhkey_size -freenode.ssl_fingerprint -freenode.ssl_verify = on -freenode.password -freenode.capabilities -freenode.sasl_mechanism -freenode.sasl_username -freenode.sasl_password -freenode.sasl_key -freenode.sasl_timeout -freenode.sasl_fail -freenode.autoconnect = on -freenode.autoreconnect -freenode.autoreconnect_delay -freenode.nicks = "Matir,Matir~" -freenode.nicks_alternate -freenode.username -freenode.realname -freenode.local_hostname -freenode.command -freenode.command_delay -freenode.autojoin = "#kali-linux,#openvpn,#radare,#vulnhub,#offsec,#offtopicsec,##ctfcompetition,#dc404,#droidsec" -freenode.autorejoin -freenode.autorejoin_delay -freenode.connection_timeout -freenode.anti_flood_prio_high -freenode.anti_flood_prio_low -freenode.away_check -freenode.away_check_max_nicks -freenode.msg_kick -freenode.msg_part -freenode.msg_quit -freenode.notify -hak5.addresses = "irc.hak5.org/6697" -hak5.proxy -hak5.ipv6 -hak5.ssl = on -hak5.ssl_cert = "%h/certs/freenode-matir.pem" -hak5.ssl_priorities -hak5.ssl_dhkey_size -hak5.ssl_fingerprint -hak5.ssl_verify = off -hak5.password -hak5.capabilities -hak5.sasl_mechanism -hak5.sasl_username -hak5.sasl_password -hak5.sasl_key -hak5.sasl_timeout -hak5.sasl_fail -hak5.autoconnect = on -hak5.autoreconnect -hak5.autoreconnect_delay -hak5.nicks -hak5.nicks_alternate -hak5.username -hak5.realname -hak5.local_hostname -hak5.command -hak5.command_delay -hak5.autojoin = "#hak5,#pineapple,#ducky,#SDR,#lanturtle,#bashbunny" -hak5.autorejoin -hak5.autorejoin_delay -hak5.connection_timeout -hak5.anti_flood_prio_high -hak5.anti_flood_prio_low -hak5.away_check -hak5.away_check_max_nicks -hak5.msg_kick -hak5.msg_part -hak5.msg_quit -hak5.notify -rpisec.addresses = "irc.rpis.ec/6697" -rpisec.proxy -rpisec.ipv6 -rpisec.ssl = on -rpisec.ssl_cert -rpisec.ssl_priorities -rpisec.ssl_dhkey_size -rpisec.ssl_fingerprint -rpisec.ssl_verify = on -rpisec.password -rpisec.capabilities -rpisec.sasl_mechanism -rpisec.sasl_username -rpisec.sasl_password -rpisec.sasl_key -rpisec.sasl_timeout -rpisec.sasl_fail -rpisec.autoconnect = on -rpisec.autoreconnect -rpisec.autoreconnect_delay -rpisec.nicks -rpisec.nicks_alternate -rpisec.username -rpisec.realname -rpisec.local_hostname -rpisec.command -rpisec.command_delay -rpisec.autojoin = "#rpisec" -rpisec.autorejoin -rpisec.autorejoin_delay -rpisec.connection_timeout -rpisec.anti_flood_prio_high -rpisec.anti_flood_prio_low -rpisec.away_check -rpisec.away_check_max_nicks -rpisec.msg_kick -rpisec.msg_part -rpisec.msg_quit -rpisec.notify -overthewire.addresses = "ircs.overthewire.org/6697" -overthewire.proxy -overthewire.ipv6 -overthewire.ssl = on -overthewire.ssl_cert = "%h/certs/freenode-matir.pem" -overthewire.ssl_priorities -overthewire.ssl_dhkey_size -overthewire.ssl_fingerprint -overthewire.ssl_verify = on -overthewire.password -overthewire.capabilities -overthewire.sasl_mechanism -overthewire.sasl_username -overthewire.sasl_password -overthewire.sasl_key -overthewire.sasl_timeout -overthewire.sasl_fail -overthewire.autoconnect = on -overthewire.autoreconnect -overthewire.autoreconnect_delay -overthewire.nicks -overthewire.nicks_alternate -overthewire.username -overthewire.realname -overthewire.local_hostname -overthewire.command -overthewire.command_delay -overthewire.autojoin = "#wargames,#social,#amateria,#io" -overthewire.autorejoin -overthewire.autorejoin_delay -overthewire.connection_timeout -overthewire.anti_flood_prio_high -overthewire.anti_flood_prio_low -overthewire.away_check -overthewire.away_check_max_nicks -overthewire.msg_kick -overthewire.msg_part -overthewire.msg_quit -overthewire.notify -hackint.addresses = "irc.hackint.org/9999" -hackint.proxy -hackint.ipv6 -hackint.ssl = on -hackint.ssl_cert -hackint.ssl_priorities -hackint.ssl_dhkey_size -hackint.ssl_fingerprint -hackint.ssl_verify = on -hackint.password -hackint.capabilities -hackint.sasl_mechanism -hackint.sasl_username -hackint.sasl_password -hackint.sasl_key -hackint.sasl_timeout -hackint.sasl_fail -hackint.autoconnect = on -hackint.autoreconnect -hackint.autoreconnect_delay -hackint.nicks -hackint.nicks_alternate -hackint.username -hackint.realname -hackint.local_hostname -hackint.command -hackint.command_delay -hackint.autojoin -hackint.autorejoin -hackint.autorejoin_delay -hackint.connection_timeout -hackint.anti_flood_prio_high -hackint.anti_flood_prio_low -hackint.away_check -hackint.away_check_max_nicks -hackint.msg_kick -hackint.msg_part -hackint.msg_quit -hackint.notify -afternet.addresses = "irc.afternet.org/6697" -afternet.proxy -afternet.ipv6 -afternet.ssl = on -afternet.ssl_cert -afternet.ssl_priorities -afternet.ssl_dhkey_size -afternet.ssl_fingerprint -afternet.ssl_verify = on -afternet.password -afternet.capabilities -afternet.sasl_mechanism -afternet.sasl_username -afternet.sasl_password -afternet.sasl_key -afternet.sasl_timeout -afternet.sasl_fail -afternet.autoconnect = on -afternet.autoreconnect -afternet.autoreconnect_delay -afternet.nicks -afternet.nicks_alternate -afternet.username -afternet.realname -afternet.local_hostname -afternet.command -afternet.command_delay -afternet.autojoin = "#eevblog" -afternet.autorejoin -afternet.autorejoin_delay -afternet.connection_timeout -afternet.anti_flood_prio_high -afternet.anti_flood_prio_low -afternet.away_check -afternet.away_check_max_nicks -afternet.msg_kick -afternet.msg_part -afternet.msg_quit -afternet.notify diff --git a/dotfiles/weechat/letsencrypt.sh b/dotfiles/weechat/letsencrypt.sh deleted file mode 100755 index c381e63..0000000 --- a/dotfiles/weechat/letsencrypt.sh +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/bash - -# Update the weechat SSL key. Should be called from cron via sudo. - -eval WEEDIR="$(printf "~%q/.weechat/" "${SUDO_USER}")" -LIVEKEY="${WEEDIR}/ssl/relay.pem" - -certbot renew -q -cat /etc/letsencrypt/live/$(hostname -f)/{privkey,fullchain}.pem > \ - ${LIVEKEY} -chown ${SUDO_USER}:$(id -gn ${SUDO_USER}) ${LIVEKEY} -for fifo in ${WEEDIR}/weechat_fifo* ; do - echo '*/relay sslcertkey' > ${fifo} -done diff --git a/dotfiles/weechat/logger.conf b/dotfiles/weechat/logger.conf deleted file mode 100644 index 89fed53..0000000 --- a/dotfiles/weechat/logger.conf +++ /dev/null @@ -1,26 +0,0 @@ -# -# weechat -- logger.conf -# - -[look] -backlog = 20 - -[color] -backlog_end = default -backlog_line = default - -[file] -auto_log = on -flush_delay = 120 -info_lines = off -mask = "$plugin.$name.weechatlog" -name_lower_case = on -nick_prefix = "" -nick_suffix = "" -path = "%h/logs/" -replacement_char = "_" -time_format = "%Y-%m-%d %H:%M:%S" - -[level] - -[mask] diff --git a/dotfiles/weechat/plugins.conf b/dotfiles/weechat/plugins.conf deleted file mode 100644 index 8bb36fd..0000000 --- a/dotfiles/weechat/plugins.conf +++ /dev/null @@ -1,15 +0,0 @@ -# -# weechat -- plugins.conf -# - -[var] -fifo.fifo = "on" -guile.check_license = "off" -javascript.check_license = "off" -lua.check_license = "off" -perl.check_license = "off" -python.check_license = "off" -ruby.check_license = "off" -tcl.check_license = "off" - -[desc] diff --git a/dotfiles/weechat/relay.conf b/dotfiles/weechat/relay.conf deleted file mode 100644 index 296b06b..0000000 --- a/dotfiles/weechat/relay.conf +++ /dev/null @@ -1,42 +0,0 @@ -# -# weechat -- relay.conf -# - -[look] -auto_open_buffer = on -raw_messages = 256 - -[color] -client = cyan -status_active = lightblue -status_auth_failed = lightred -status_connecting = yellow -status_disconnected = lightred -status_waiting_auth = brown -text = default -text_bg = default -text_selected = white - -[network] -allow_empty_password = off -allowed_ips = "" -bind_address = "" -clients_purge_delay = 0 -compression_level = 6 -ipv6 = on -max_clients = 5 -password = "${sec.data.relay_password}" -ssl_cert_key = "%h/ssl/relay.pem" -ssl_priorities = "NORMAL:-VERS-SSL3.0" -websocket_allowed_origins = "" - -[irc] -backlog_max_minutes = 1440 -backlog_max_number = 256 -backlog_since_last_disconnect = on -backlog_since_last_message = off -backlog_tags = "irc_privmsg" -backlog_time_format = "[%H:%M] " - -[port] -ssl.weechat = 9001 diff --git a/dotfiles/weechat/script.conf b/dotfiles/weechat/script.conf deleted file mode 100644 index e1577d4..0000000 --- a/dotfiles/weechat/script.conf +++ /dev/null @@ -1,50 +0,0 @@ -# -# weechat -- script.conf -# - -[look] -columns = "%s %n %V %v %u | %d | %t" -diff_color = on -diff_command = "auto" -display_source = on -quiet_actions = on -sort = "p,n" -translate_description = on -use_keys = on - -[color] -status_autoloaded = cyan -status_held = white -status_installed = lightcyan -status_obsolete = lightmagenta -status_popular = yellow -status_running = lightgreen -status_unknown = lightred -text = default -text_bg = default -text_bg_selected = red -text_date = default -text_date_selected = white -text_delimiters = default -text_description = default -text_description_selected = white -text_extension = default -text_extension_selected = white -text_name = cyan -text_name_selected = lightcyan -text_selected = white -text_tags = brown -text_tags_selected = yellow -text_version = magenta -text_version_loaded = default -text_version_loaded_selected = white -text_version_selected = lightmagenta - -[scripts] -autoload = on -cache_expire = 1440 -download_timeout = 30 -hold = "" -path = "%h/script" -url = "http://weechat.org/files/plugins.xml.gz" -url_force_https = on diff --git a/dotfiles/weechat/sec.conf b/dotfiles/weechat/sec.conf deleted file mode 100644 index f89d2ac..0000000 --- a/dotfiles/weechat/sec.conf +++ /dev/null @@ -1,13 +0,0 @@ -# -# weechat -- sec.conf -# - -[crypt] -cipher = aes256 -hash_algo = sha256 -passphrase_file = "~/.weechat-passphrase" -salt = on - -[data] -__passphrase__ = on -relay_password = "D1FD30C08951B1A5BCBBB7EE6AAFB6AF9B86017B353182A1CA8826D5A98EB88E7E723591C544FC41A6913EA67E8764E50BDD8A5AD3D0A0" diff --git a/dotfiles/weechat/trigger.conf b/dotfiles/weechat/trigger.conf deleted file mode 100644 index a090b43..0000000 --- a/dotfiles/weechat/trigger.conf +++ /dev/null @@ -1,52 +0,0 @@ -# -# weechat -- trigger.conf -# - -[look] -enabled = on -monitor_strip_colors = off - -[color] -flag_command = lightgreen -flag_conditions = yellow -flag_post_action = lightblue -flag_regex = lightcyan -flag_return_code = lightmagenta -regex = white -replace = cyan -trigger = green -trigger_disabled = red - -[trigger] -beep.arguments = "" -beep.command = "/print -beep" -beep.conditions = "${tg_highlight} || ${tg_msg_pv}" -beep.enabled = on -beep.hook = print -beep.post_action = none -beep.regex = "" -beep.return_code = ok -cmd_pass.arguments = "5000|input_text_display;5000|history_add;5000|irc_command_auth" -cmd_pass.command = "" -cmd_pass.conditions = "" -cmd_pass.enabled = on -cmd_pass.hook = modifier -cmd_pass.post_action = none -cmd_pass.regex = "==^((/(msg|quote) +nickserv +(id|identify|register|ghost +[^ ]+|release +[^ ]+|regain +[^ ]+) +)|/oper +[^ ]+ +|/quote +pass +|/set +[^ ]*password[^ ]* +|/secure +(passphrase|decrypt|set +[^ ]+) +)(.*)==$1$.*+" -cmd_pass.return_code = ok -msg_auth.arguments = "5000|irc_message_auth" -msg_auth.command = "" -msg_auth.conditions = "" -msg_auth.enabled = on -msg_auth.hook = modifier -msg_auth.post_action = none -msg_auth.regex = "==^(.*(id|identify|register|ghost +[^ ]+|release +[^ ]+) +)(.*)==$1$.*+" -msg_auth.return_code = ok -server_pass.arguments = "5000|input_text_display;5000|history_add" -server_pass.command = "" -server_pass.conditions = "" -server_pass.enabled = on -server_pass.hook = modifier -server_pass.post_action = none -server_pass.regex = "==^(/(server|connect) .*-(sasl_)?password=)([^ ]+)(.*)==$1$.*4$5" -server_pass.return_code = ok diff --git a/dotfiles/weechat/weechat.conf b/dotfiles/weechat/weechat.conf deleted file mode 100644 index bdef861..0000000 --- a/dotfiles/weechat/weechat.conf +++ /dev/null @@ -1,595 +0,0 @@ -# -# weechat -- weechat.conf -# - -[debug] - -[startup] -command_after_plugins = "" -command_before_plugins = "" -display_logo = on -display_version = on -sys_rlimit = "" - -[look] -align_end_of_lines = message -bar_more_down = "++" -bar_more_left = "<<" -bar_more_right = ">>" -bar_more_up = "--" -bare_display_exit_on_input = on -bare_display_time_format = "%H:%M" -buffer_auto_renumber = on -buffer_notify_default = all -buffer_position = end -buffer_search_case_sensitive = off -buffer_search_force_default = off -buffer_search_regex = off -buffer_search_where = prefix_message -buffer_time_format = "%H:%M:%S" -color_basic_force_bold = off -color_inactive_buffer = on -color_inactive_message = on -color_inactive_prefix = on -color_inactive_prefix_buffer = on -color_inactive_time = off -color_inactive_window = on -color_nick_offline = off -color_pairs_auto_reset = 5 -color_real_white = off -command_chars = "" -command_incomplete = off -confirm_quit = off -confirm_upgrade = off -day_change = on -day_change_message_1date = "-- %a, %d %b %Y --" -day_change_message_2dates = "-- %%a, %%d %%b %%Y (%a, %d %b %Y) --" -eat_newline_glitch = off -emphasized_attributes = "" -highlight = "" -highlight_regex = "" -highlight_tags = "" -hotlist_add_conditions = "${buffer.num_displayed} == 0 && ${priority} >= 1" -hotlist_buffer_separator = ", " -hotlist_count_max = 0 -hotlist_count_min_msg = 2 -hotlist_names_count = 10000 -hotlist_names_length = 0 -hotlist_names_level = 14 -hotlist_names_merged_buffers = off -hotlist_prefix = "Act: " -hotlist_remove = merged -hotlist_short_names = on -hotlist_sort = group_time_asc -hotlist_suffix = "" -hotlist_unique_numbers = on -input_cursor_scroll = 20 -input_share = none -input_share_overwrite = off -input_undo_max = 32 -item_away_message = on -item_buffer_filter = "*" -item_buffer_zoom = "!" -item_mouse_status = "M" -item_time_format = "%H:%M" -jump_current_to_previous_buffer = on -jump_previous_buffer_when_closing = on -jump_smart_back_to_buffer = on -key_bind_safe = on -key_grab_delay = 800 -mouse = off -mouse_timer_delay = 100 -nick_color_force = "" -nick_color_hash = djb2 -nick_color_stop_chars = "_|[" -nick_prefix = "" -nick_suffix = "" -paste_auto_add_newline = on -paste_bracketed = on -paste_bracketed_timer_delay = 10 -paste_max_lines = 1 -prefix_action = " *" -prefix_align = right -prefix_align_max = 15 -prefix_align_min = 0 -prefix_align_more = "+" -prefix_align_more_after = on -prefix_buffer_align = right -prefix_buffer_align_max = 0 -prefix_buffer_align_more = "+" -prefix_buffer_align_more_after = on -prefix_error = "=!=" -prefix_join = "-->" -prefix_network = "--" -prefix_quit = "<--" -prefix_same_nick = "" -prefix_suffix = "|" -quote_nick_prefix = "<" -quote_nick_suffix = ">" -quote_time_format = "%H:%M:%S" -read_marker = line -read_marker_always_show = off -read_marker_string = "- " -save_config_on_exit = on -save_layout_on_exit = none -scroll_amount = 3 -scroll_bottom_after_switch = off -scroll_page_percent = 100 -search_text_not_found_alert = on -separator_horizontal = "-" -separator_vertical = "" -tab_width = 1 -time_format = "%a, %d %b %Y %T" -window_auto_zoom = off -window_separator_horizontal = on -window_separator_vertical = on -window_title = "irc" -word_chars_highlight = "!\u00A0,-,_,|,alnum" -word_chars_input = "!\u00A0,-,_,|,alnum" - -[palette] - -[color] -bar_more = lightmagenta -chat = default -chat_bg = default -chat_buffer = white -chat_channel = white -chat_day_change = cyan -chat_delimiters = green -chat_highlight = yellow -chat_highlight_bg = magenta -chat_host = cyan -chat_inactive_buffer = default -chat_inactive_window = default -chat_nick = lightcyan -chat_nick_colors = "cyan,magenta,green,brown,lightblue,default,lightcyan,lightmagenta,lightgreen,blue" -chat_nick_offline = default -chat_nick_offline_highlight = default -chat_nick_offline_highlight_bg = blue -chat_nick_other = cyan -chat_nick_prefix = green -chat_nick_self = white -chat_nick_suffix = green -chat_prefix_action = white -chat_prefix_buffer = brown -chat_prefix_buffer_inactive_buffer = default -chat_prefix_error = yellow -chat_prefix_join = lightgreen -chat_prefix_more = lightmagenta -chat_prefix_network = magenta -chat_prefix_quit = lightred -chat_prefix_suffix = green -chat_read_marker = magenta -chat_read_marker_bg = default -chat_server = brown -chat_tags = red -chat_text_found = yellow -chat_text_found_bg = lightmagenta -chat_time = default -chat_time_delimiters = brown -chat_value = cyan -chat_value_null = blue -emphasized = yellow -emphasized_bg = magenta -input_actions = lightgreen -input_text_not_found = red -item_away = yellow -nicklist_away = cyan -nicklist_group = green -separator = blue -status_count_highlight = magenta -status_count_msg = brown -status_count_other = default -status_count_private = green -status_data_highlight = lightmagenta -status_data_msg = yellow -status_data_other = default -status_data_private = lightgreen -status_filter = green -status_more = yellow -status_mouse = green -status_name = white -status_name_ssl = lightgreen -status_nicklist_count = default -status_number = yellow -status_time = default - -[completion] -base_word_until_cursor = on -command_inline = on -default_template = "%(nicks)|%(irc_channels)" -nick_add_space = on -nick_completer = ":" -nick_first_only = off -nick_ignore_chars = "[]`_-^" -partial_completion_alert = on -partial_completion_command = off -partial_completion_command_arg = off -partial_completion_count = on -partial_completion_other = off - -[history] -display_default = 5 -max_buffer_lines_minutes = 0 -max_buffer_lines_number = 4096 -max_commands = 100 -max_visited_buffers = 50 - -[proxy] - -[network] -connection_timeout = 60 -gnutls_ca_file = "~/.weechat/certs/ca-certificates.crt" -gnutls_handshake_timeout = 30 -proxy_curl = "" - -[plugin] -autoload = "*" -debug = off -extension = ".so,.dll" -path = "%h/plugins" -save_config_on_unload = on - -[bar] -input.color_bg = default -input.color_delim = cyan -input.color_fg = default -input.conditions = "" -input.filling_left_right = vertical -input.filling_top_bottom = horizontal -input.hidden = off -input.items = "[input_prompt]+(away),[input_search],[input_paste],input_text" -input.position = bottom -input.priority = 1000 -input.separator = off -input.size = 1 -input.size_max = 0 -input.type = window -nicklist.color_bg = default -nicklist.color_delim = cyan -nicklist.color_fg = default -nicklist.conditions = "${nicklist}" -nicklist.filling_left_right = vertical -nicklist.filling_top_bottom = columns_vertical -nicklist.hidden = on -nicklist.items = "buffer_nicklist" -nicklist.position = right -nicklist.priority = 200 -nicklist.separator = on -nicklist.size = 0 -nicklist.size_max = 0 -nicklist.type = window -status.color_bg = 0 -status.color_delim = cyan -status.color_fg = default -status.conditions = "" -status.filling_left_right = vertical -status.filling_top_bottom = horizontal -status.hidden = off -status.items = "[time],[buffer_plugin],buffer_number+:+buffer_name+(buffer_modes)+{buffer_nicklist_count}+buffer_zoom+buffer_filter,[lag],[hotlist],completion,scroll" -status.position = bottom -status.priority = 500 -status.separator = off -status.size = 2 -status.size_max = 0 -status.type = window -title.color_bg = 0 -title.color_delim = cyan -title.color_fg = default -title.conditions = "" -title.filling_left_right = vertical -title.filling_top_bottom = horizontal -title.hidden = off -title.items = "buffer_title" -title.position = top -title.priority = 500 -title.separator = off -title.size = 1 -title.size_max = 0 -title.type = window - -[layout] - -[notify] - -[filter] -irc_smart = on;*;irc_smart_filter;* - -[key] -ctrl-? = "/input delete_previous_char" -ctrl-A = "/input move_beginning_of_line" -ctrl-B = "/input move_previous_char" -ctrl-C_ = "/input insert \x1F" -ctrl-Cb = "/input insert \x02" -ctrl-Cc = "/input insert \x03" -ctrl-Ci = "/input insert \x1D" -ctrl-Co = "/input insert \x0F" -ctrl-Cv = "/input insert \x16" -ctrl-D = "/input delete_next_char" -ctrl-E = "/input move_end_of_line" -ctrl-F = "/input move_next_char" -ctrl-H = "/input delete_previous_char" -ctrl-I = "/input complete_next" -ctrl-J = "/input return" -ctrl-K = "/input delete_end_of_line" -ctrl-L = "/window refresh" -ctrl-M = "/input return" -ctrl-N = "/buffer +1" -ctrl-P = "/buffer -1" -ctrl-R = "/input search_text" -ctrl-Sctrl-U = "/input set_unread" -ctrl-T = "/input transpose_chars" -ctrl-U = "/input delete_beginning_of_line" -ctrl-W = "/input delete_previous_word" -ctrl-X = "/input switch_active_buffer" -ctrl-Y = "/input clipboard_paste" -meta-meta2-1~ = "/window scroll_top" -meta-meta2-23~ = "/bar scroll nicklist * b" -meta-meta2-24~ = "/bar scroll nicklist * e" -meta-meta2-4~ = "/window scroll_bottom" -meta-meta2-5~ = "/window scroll_up" -meta-meta2-6~ = "/window scroll_down" -meta-meta2-7~ = "/window scroll_top" -meta-meta2-8~ = "/window scroll_bottom" -meta-meta2-A = "/buffer -1" -meta-meta2-B = "/buffer +1" -meta-meta2-C = "/buffer +1" -meta-meta2-D = "/buffer -1" -meta-- = "/filter toggle @" -meta-/ = "/input jump_last_buffer_displayed" -meta-0 = "/buffer *10" -meta-1 = "/buffer *1" -meta-2 = "/buffer *2" -meta-3 = "/buffer *3" -meta-4 = "/buffer *4" -meta-5 = "/buffer *5" -meta-6 = "/buffer *6" -meta-7 = "/buffer *7" -meta-8 = "/buffer *8" -meta-9 = "/buffer *9" -meta-< = "/input jump_previously_visited_buffer" -meta-= = "/filter toggle" -meta-> = "/input jump_next_visited_buffer" -meta-OA = "/input history_global_previous" -meta-OB = "/input history_global_next" -meta-OC = "/input move_next_word" -meta-OD = "/input move_previous_word" -meta-OF = "/input move_end_of_line" -meta-OH = "/input move_beginning_of_line" -meta-Oa = "/input history_global_previous" -meta-Ob = "/input history_global_next" -meta-Oc = "/input move_next_word" -meta-Od = "/input move_previous_word" -meta2-15~ = "/buffer -1" -meta2-17~ = "/buffer +1" -meta2-18~ = "/window -1" -meta2-19~ = "/window +1" -meta2-1;3A = "/buffer -1" -meta2-1;3B = "/buffer +1" -meta2-1;3C = "/buffer +1" -meta2-1;3D = "/buffer -1" -meta2-1;3F = "/window scroll_bottom" -meta2-1;3H = "/window scroll_top" -meta2-1;5A = "/input history_global_previous" -meta2-1;5B = "/input history_global_next" -meta2-1;5C = "/input move_next_word" -meta2-1;5D = "/input move_previous_word" -meta2-1~ = "/input move_beginning_of_line" -meta2-200~ = "/input paste_start" -meta2-201~ = "/input paste_stop" -meta2-20~ = "/bar scroll title * -30%" -meta2-21~ = "/bar scroll title * +30%" -meta2-23;3~ = "/bar scroll nicklist * b" -meta2-23~ = "/bar scroll nicklist * -100%" -meta2-24;3~ = "/bar scroll nicklist * e" -meta2-24~ = "/bar scroll nicklist * +100%" -meta2-3~ = "/input delete_next_char" -meta2-4~ = "/input move_end_of_line" -meta2-5;3~ = "/window scroll_up" -meta2-5~ = "/window page_up" -meta2-6;3~ = "/window scroll_down" -meta2-6~ = "/window page_down" -meta2-7~ = "/input move_beginning_of_line" -meta2-8~ = "/input move_end_of_line" -meta2-A = "/input history_previous" -meta2-B = "/input history_next" -meta2-C = "/input move_next_char" -meta2-D = "/input move_previous_char" -meta2-F = "/input move_end_of_line" -meta2-G = "/window page_down" -meta2-H = "/input move_beginning_of_line" -meta2-I = "/window page_up" -meta2-Z = "/input complete_previous" -meta2-[E = "/buffer -1" -meta-_ = "/input redo" -meta-a = "/input jump_smart" -meta-b = "/input move_previous_word" -meta-d = "/input delete_next_word" -meta-f = "/input move_next_word" -meta-h = "/input hotlist_clear" -meta-jmeta-f = "/buffer -" -meta-jmeta-l = "/buffer +" -meta-jmeta-r = "/server raw" -meta-jmeta-s = "/server jump" -meta-j01 = "/buffer 1" -meta-j02 = "/buffer 2" -meta-j03 = "/buffer 3" -meta-j04 = "/buffer 4" -meta-j05 = "/buffer 5" -meta-j06 = "/buffer 6" -meta-j07 = "/buffer 7" -meta-j08 = "/buffer 8" -meta-j09 = "/buffer 9" -meta-j10 = "/buffer 10" -meta-j11 = "/buffer 11" -meta-j12 = "/buffer 12" -meta-j13 = "/buffer 13" -meta-j14 = "/buffer 14" -meta-j15 = "/buffer 15" -meta-j16 = "/buffer 16" -meta-j17 = "/buffer 17" -meta-j18 = "/buffer 18" -meta-j19 = "/buffer 19" -meta-j20 = "/buffer 20" -meta-j21 = "/buffer 21" -meta-j22 = "/buffer 22" -meta-j23 = "/buffer 23" -meta-j24 = "/buffer 24" -meta-j25 = "/buffer 25" -meta-j26 = "/buffer 26" -meta-j27 = "/buffer 27" -meta-j28 = "/buffer 28" -meta-j29 = "/buffer 29" -meta-j30 = "/buffer 30" -meta-j31 = "/buffer 31" -meta-j32 = "/buffer 32" -meta-j33 = "/buffer 33" -meta-j34 = "/buffer 34" -meta-j35 = "/buffer 35" -meta-j36 = "/buffer 36" -meta-j37 = "/buffer 37" -meta-j38 = "/buffer 38" -meta-j39 = "/buffer 39" -meta-j40 = "/buffer 40" -meta-j41 = "/buffer 41" -meta-j42 = "/buffer 42" -meta-j43 = "/buffer 43" -meta-j44 = "/buffer 44" -meta-j45 = "/buffer 45" -meta-j46 = "/buffer 46" -meta-j47 = "/buffer 47" -meta-j48 = "/buffer 48" -meta-j49 = "/buffer 49" -meta-j50 = "/buffer 50" -meta-j51 = "/buffer 51" -meta-j52 = "/buffer 52" -meta-j53 = "/buffer 53" -meta-j54 = "/buffer 54" -meta-j55 = "/buffer 55" -meta-j56 = "/buffer 56" -meta-j57 = "/buffer 57" -meta-j58 = "/buffer 58" -meta-j59 = "/buffer 59" -meta-j60 = "/buffer 60" -meta-j61 = "/buffer 61" -meta-j62 = "/buffer 62" -meta-j63 = "/buffer 63" -meta-j64 = "/buffer 64" -meta-j65 = "/buffer 65" -meta-j66 = "/buffer 66" -meta-j67 = "/buffer 67" -meta-j68 = "/buffer 68" -meta-j69 = "/buffer 69" -meta-j70 = "/buffer 70" -meta-j71 = "/buffer 71" -meta-j72 = "/buffer 72" -meta-j73 = "/buffer 73" -meta-j74 = "/buffer 74" -meta-j75 = "/buffer 75" -meta-j76 = "/buffer 76" -meta-j77 = "/buffer 77" -meta-j78 = "/buffer 78" -meta-j79 = "/buffer 79" -meta-j80 = "/buffer 80" -meta-j81 = "/buffer 81" -meta-j82 = "/buffer 82" -meta-j83 = "/buffer 83" -meta-j84 = "/buffer 84" -meta-j85 = "/buffer 85" -meta-j86 = "/buffer 86" -meta-j87 = "/buffer 87" -meta-j88 = "/buffer 88" -meta-j89 = "/buffer 89" -meta-j90 = "/buffer 90" -meta-j91 = "/buffer 91" -meta-j92 = "/buffer 92" -meta-j93 = "/buffer 93" -meta-j94 = "/buffer 94" -meta-j95 = "/buffer 95" -meta-j96 = "/buffer 96" -meta-j97 = "/buffer 97" -meta-j98 = "/buffer 98" -meta-j99 = "/buffer 99" -meta-k = "/input grab_key_command" -meta-l = "/window bare" -meta-m = "/mute mouse toggle" -meta-n = "/window scroll_next_highlight" -meta-p = "/window scroll_previous_highlight" -meta-r = "/input delete_line" -meta-s = "/mute aspell toggle" -meta-u = "/window scroll_unread" -meta-wmeta-meta2-A = "/window up" -meta-wmeta-meta2-B = "/window down" -meta-wmeta-meta2-C = "/window right" -meta-wmeta-meta2-D = "/window left" -meta-wmeta2-1;3A = "/window up" -meta-wmeta2-1;3B = "/window down" -meta-wmeta2-1;3C = "/window right" -meta-wmeta2-1;3D = "/window left" -meta-wmeta-b = "/window balance" -meta-wmeta-s = "/window swap" -meta-x = "/input zoom_merged_buffer" -meta-z = "/window zoom" -ctrl-_ = "/input undo" - -[key_search] -ctrl-I = "/input search_switch_where" -ctrl-J = "/input search_stop" -ctrl-M = "/input search_stop" -ctrl-R = "/input search_switch_regex" -meta2-A = "/input search_previous" -meta2-B = "/input search_next" -meta-c = "/input search_switch_case" - -[key_cursor] -ctrl-J = "/cursor stop" -ctrl-M = "/cursor stop" -meta-meta2-A = "/cursor move area_up" -meta-meta2-B = "/cursor move area_down" -meta-meta2-C = "/cursor move area_right" -meta-meta2-D = "/cursor move area_left" -meta2-1;3A = "/cursor move area_up" -meta2-1;3B = "/cursor move area_down" -meta2-1;3C = "/cursor move area_right" -meta2-1;3D = "/cursor move area_left" -meta2-A = "/cursor move up" -meta2-B = "/cursor move down" -meta2-C = "/cursor move right" -meta2-D = "/cursor move left" -@item(buffer_nicklist):K = "/window ${_window_number};/kickban ${nick}" -@item(buffer_nicklist):b = "/window ${_window_number};/ban ${nick}" -@item(buffer_nicklist):k = "/window ${_window_number};/kick ${nick}" -@item(buffer_nicklist):q = "/window ${_window_number};/query ${nick};/cursor stop" -@item(buffer_nicklist):w = "/window ${_window_number};/whois ${nick}" -@chat:Q = "hsignal:chat_quote_time_prefix_message;/cursor stop" -@chat:m = "hsignal:chat_quote_message;/cursor stop" -@chat:q = "hsignal:chat_quote_prefix_message;/cursor stop" - -[key_mouse] -@bar(input):button2 = "/input grab_mouse_area" -@bar(nicklist):button1-gesture-down = "/bar scroll nicklist ${_window_number} +100%" -@bar(nicklist):button1-gesture-down-long = "/bar scroll nicklist ${_window_number} e" -@bar(nicklist):button1-gesture-up = "/bar scroll nicklist ${_window_number} -100%" -@bar(nicklist):button1-gesture-up-long = "/bar scroll nicklist ${_window_number} b" -@chat(script.scripts):button1 = "/window ${_window_number};/script go ${_chat_line_y}" -@chat(script.scripts):button2 = "/window ${_window_number};/script go ${_chat_line_y};/script installremove -q ${script_name_with_extension}" -@chat(script.scripts):wheeldown = "/script down 5" -@chat(script.scripts):wheelup = "/script up 5" -@item(buffer_nicklist):button1 = "/window ${_window_number};/query ${nick}" -@item(buffer_nicklist):button1-gesture-left = "/window ${_window_number};/kick ${nick}" -@item(buffer_nicklist):button1-gesture-left-long = "/window ${_window_number};/kickban ${nick}" -@item(buffer_nicklist):button2 = "/window ${_window_number};/whois ${nick}" -@item(buffer_nicklist):button2-gesture-left = "/window ${_window_number};/ban ${nick}" -@bar:wheeldown = "/bar scroll ${_bar_name} ${_window_number} +20%" -@bar:wheelup = "/bar scroll ${_bar_name} ${_window_number} -20%" -@chat:button1 = "/window ${_window_number}" -@chat:button1-gesture-left = "/window ${_window_number};/buffer -1" -@chat:button1-gesture-left-long = "/window ${_window_number};/buffer 1" -@chat:button1-gesture-right = "/window ${_window_number};/buffer +1" -@chat:button1-gesture-right-long = "/window ${_window_number};/input jump_last_buffer" -@chat:ctrl-wheeldown = "/window scroll_horiz -window ${_window_number} +10%" -@chat:ctrl-wheelup = "/window scroll_horiz -window ${_window_number} -10%" -@chat:wheeldown = "/window scroll_down -window ${_window_number}" -@chat:wheelup = "/window scroll_up -window ${_window_number}" -@*:button3 = "/cursor go ${_x},${_y}" diff --git a/dotfiles/weechat/xfer.conf b/dotfiles/weechat/xfer.conf deleted file mode 100644 index 39ac5bd..0000000 --- a/dotfiles/weechat/xfer.conf +++ /dev/null @@ -1,39 +0,0 @@ -# -# weechat -- xfer.conf -# - -[look] -auto_open_buffer = on -progress_bar_size = 20 -pv_tags = "notify_private" - -[color] -status_aborted = lightred -status_active = lightblue -status_connecting = yellow -status_done = lightgreen -status_failed = lightred -status_waiting = lightcyan -text = default -text_bg = default -text_selected = white - -[network] -blocksize = 65536 -fast_send = on -own_ip = "" -port_range = "" -speed_limit = 0 -timeout = 300 - -[file] -auto_accept_chats = off -auto_accept_files = off -auto_accept_nicks = "" -auto_check_crc32 = off -auto_rename = on -auto_resume = on -convert_spaces = on -download_path = "%h/xfer" -upload_path = "~" -use_nick_in_filename = on diff --git a/dotfiles/zshenv b/dotfiles/zshenv index 2a64b12..171c1d6 100755 --- a/dotfiles/zshenv +++ b/dotfiles/zshenv @@ -10,7 +10,7 @@ if test -d ${HOME}/.local/bin ; then fi if [[ ! -o interactive || ! -t 0 ]]; then - if command -v mise >/dev/null 2>&1 ; then + if [[ "$PWD" != /google* ]] && command -v mise >/dev/null 2>&1 ; then eval "$(mise activate zsh --shims)" fi fi diff --git a/dotfiles/zshrc.d/gemini.zsh b/dotfiles/zshrc.d/gemini.zsh new file mode 100644 index 0000000..e3650b9 --- /dev/null +++ b/dotfiles/zshrc.d/gemini.zsh @@ -0,0 +1,168 @@ +# Gemini CLI Context Management + +# Base directory for Gemini contexts +export GEMINI_CONTEXT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gemini" + +# Ensure the base context directory exists +mkdir -p "$GEMINI_CONTEXT_DIR" + +# Template settings file +GEMINI_TEMPLATE_SETTINGS="${HOME}/.skel/dotfiles/config/gemini/settings.json" + +# Create a new Gemini context +gemini-context-create() { + if [ -z "$1" ]; then + echo "Usage: gemini-context-create " + return 1 + fi + + local context_name="$1" + local context_path="$GEMINI_CONTEXT_DIR/$context_name" + + if [[ "$context_name" =~ [/] ]]; then + echo "Error: Context name cannot contain slashes." + return 1 + fi + + if [ -d "$context_path" ]; then + echo "Error: Context '$context_name' already exists at $context_path" + return 1 + fi + + echo "Creating context '$context_name' at $context_path" + mkdir -p "$context_path/.gemini" + + if [ -f "$GEMINI_TEMPLATE_SETTINGS" ]; then + cp "$GEMINI_TEMPLATE_SETTINGS" "$context_path/.gemini/settings.json" + echo "Initialized with template settings." + else + echo "Warning: Template settings not found at $GEMINI_TEMPLATE_SETTINGS" + touch "$context_path/.gemini/settings.json" + fi + echo "Context '$context_name' created." +} + +# List available Gemini contexts +_gemini_context_list_internal() { + command ls "$GEMINI_CONTEXT_DIR" 2>/dev/null +} + +gemini-context-list() { + echo "Available Gemini contexts:" + local contexts=$(_gemini_context_list_internal) + if [ -z "$contexts" ]; then + echo " (No contexts found)" + return + fi + for context in $contexts; do + if [ -d "$GEMINI_CONTEXT_DIR/$context" ]; then + echo " $context" + fi + done +} + +# Use a specific Gemini context +gemini-context-use() { + local context_name + local quiet=0 + + if [ "$1" = "-q" ] || [ "$1" = "--quiet" ]; then + quiet=1 + shift + fi + + if [ -z "$1" ]; then + if command -v fzf >/dev/null; then + context_name=$(_gemini_context_list_internal | fzf --prompt="Select Gemini Context: ") + if [ -z "$context_name" ]; then + return 1 + fi + else + echo "Usage: gemini-context-use [-q] " + echo "fzf not found for interactive selection." + gemini-context-list + return 1 + fi + else + context_name="$1" + fi + + local context_path="$GEMINI_CONTEXT_DIR/$context_name" + + if [ ! -d "$context_path" ]; then + [[ "$quiet" -eq 0 ]] && echo "Error: Context '$context_name' not found at $context_path" + [[ "$quiet" -eq 0 ]] && gemini-context-list + return 1 + fi + + export GEMINI_CLI_HOME="$context_path" + [[ "$quiet" -eq 0 ]] && echo "Switched to Gemini context '$context_name' (GEMINI_CLI_HOME=$GEMINI_CLI_HOME)" +} + +# Edit a context's settings +gemini-context-edit() { + local context_name + if [ -z "$1" ]; then + if command -v fzf >/dev/null; then + context_name=$(_gemini_context_list_internal | fzf --prompt="Select Gemini Context to Edit: ") + if [ -z "$context_name" ]; then + return 1 + fi + else + echo "Usage: gemini-context-edit " + gemini-context-list + return 1 + fi + else + context_name="$1" + fi + + local context_path="$GEMINI_CONTEXT_DIR/$context_name" + local settings_file="$context_path/.gemini/settings.json" + + if [ ! -d "$context_path" ]; then + echo "Error: Context '$context_name' not found." + return 1 + fi + + if [ ! -f "$settings_file" ]; then + echo "Error: settings.json not found for context '$context_name'." + return 1 + fi + + ${EDITOR:-vim} "$settings_file" +} + +# Show the current Gemini context +gemini-context-current() { + if [ -n "$GEMINI_CLI_HOME" ]; then + local current_context=$(basename "$GEMINI_CLI_HOME") + if [ "$GEMINI_CONTEXT_DIR/$current_context" = "$GEMINI_CLI_HOME" ]; then + echo "Current Gemini context: $current_context" + else + echo "Current Gemini context: Custom" + fi + echo "GEMINI_CLI_HOME=$GEMINI_CLI_HOME" + else + echo "No Gemini context set, using default." + fi +} + +# Unset the current Gemini context +gemini-context-unset() { + unset GEMINI_CLI_HOME + echo "Unset Gemini context, reverted to default." +} + +# Alias for gemini-context-use +alias gemctx='gemini-context-use' + +# Zsh Completion for gemini-context-use and gemctx +_gemini_contexts() { + local contexts + contexts=($(_gemini_context_list_internal)) + _describe 'gemini contexts' contexts +} +compdef _gemini_contexts gemini-context-use +compdef _gemini_contexts gemctx +compdef _gemini_contexts gemini-context-edit diff --git a/install.sh b/install.sh index 657d86f..3baff84 100755 --- a/install.sh +++ b/install.sh @@ -225,6 +225,13 @@ install_main() { } install_dotfiles link_directory_contents "${BASEDIR}/bin" "${HOME}/bin" "" + + # macOS specific Homebrew bundle installation + if [[ "$(uname)" == "Darwin" ]] && have_command brew && [[ -f "${BASEDIR}/Brewfile" ]]; then + verbose "Checking Homebrew bundle..." + brew bundle install --file="${BASEDIR}/Brewfile" + fi + [[ "$INSTALL_KEYS" = 1 ]] && install_keys save_prefs cleanup