mirror of
https://github.com/Matir/skel.git
synced 2026-05-26 13:35:42 -07:00
Compare commits
39 Commits
2510f1ad87
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9770514d6a | ||
|
|
e1724c77f3 | ||
|
|
ecbc25e5ac | ||
|
|
ea33840ef6 | ||
|
|
1048775da3 | ||
|
|
c9af80bc5d | ||
|
|
d8b4991419 | ||
|
|
158d9f6e4e | ||
|
|
b1d1c42a02 | ||
|
|
f8ec9cc338 | ||
|
|
6e3c3dd269 | ||
|
|
77b8374871 | ||
|
|
4645682b5c | ||
|
|
75bdebb497 | ||
|
|
4e72b9b18c | ||
|
|
bd2c2287cd | ||
|
|
db2c02bd2d | ||
|
|
fec16225e4 | ||
|
|
fa6a878487 | ||
|
|
1804357162 | ||
|
|
202d871a59 | ||
|
|
467d916f33 | ||
|
|
6d2bfdbcea | ||
|
|
1d0a09c442 | ||
|
|
37c765ae29 | ||
|
|
41f8a49381 | ||
|
|
3f9c41d266 | ||
|
|
69e4b83652 | ||
|
|
74c2472dd2 | ||
|
|
ecc39344ca | ||
|
|
49a314e388 | ||
|
|
41293eb788 | ||
|
|
05798dcb67 | ||
|
|
4e1b263170 | ||
|
|
46c00c61be | ||
|
|
ce973d5bbf | ||
|
|
f326992306 | ||
|
|
7f76b24cb9 | ||
|
|
a5b08680c5 |
@@ -9,8 +9,9 @@ fi
|
||||
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)
|
||||
echo "🔍 Checking Brewfile synchronization..."
|
||||
# Run in dry-run mode with --add-only and see if there's output
|
||||
DIFF_OUTPUT=$("$UPDATE_SCRIPT" --dry-run --add-only 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."
|
||||
|
||||
@@ -10,7 +10,8 @@ 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.
|
||||
|
||||
39
Brewfile
39
Brewfile
@@ -1,5 +1,7 @@
|
||||
tap "dart-lang/dart"
|
||||
tap "holtwick/tap"
|
||||
tap "sass/sass"
|
||||
|
||||
brew "ack"
|
||||
brew "acme.sh"
|
||||
brew "age"
|
||||
@@ -7,18 +9,23 @@ brew "autoconf"
|
||||
brew "automake"
|
||||
brew "b2-tools"
|
||||
brew "bat"
|
||||
brew "binwalk"
|
||||
brew "cask"
|
||||
brew "ccache"
|
||||
brew "certbot"
|
||||
brew "cloudflared"
|
||||
brew "cmake"
|
||||
brew "colima"
|
||||
brew "devcontainer"
|
||||
brew "difftastic"
|
||||
brew "dfu-util"
|
||||
brew "difftastic"
|
||||
brew "direnv"
|
||||
brew "duck"
|
||||
brew "dust"
|
||||
brew "earthly"
|
||||
brew "esptool"
|
||||
brew "fish"
|
||||
brew "fq"
|
||||
brew "gh"
|
||||
brew "ghidra", link: false
|
||||
brew "git"
|
||||
@@ -27,33 +34,41 @@ brew "git-lfs"
|
||||
brew "gnupg"
|
||||
brew "go"
|
||||
brew "gradle"
|
||||
brew "hf"
|
||||
brew "holtwick/tap/bx"
|
||||
brew "htop"
|
||||
brew "httpie"
|
||||
brew "huggingface-cli"
|
||||
brew "hugo"
|
||||
brew "imagemagick"
|
||||
brew "john-jumbo"
|
||||
brew "jq"
|
||||
brew "kubeconform"
|
||||
brew "kubectx"
|
||||
brew "librsvg"
|
||||
brew "lima"
|
||||
brew "minikube"
|
||||
brew "mise"
|
||||
brew "mosh"
|
||||
brew "neovim"
|
||||
brew "ninja"
|
||||
brew "nmap"
|
||||
brew "protobuf"
|
||||
brew "ollama"
|
||||
brew "p7zip"
|
||||
brew "pipenv"
|
||||
brew "pipx"
|
||||
brew "pkgconf"
|
||||
brew "protobuf"
|
||||
brew "pwgen"
|
||||
brew "pwntools"
|
||||
brew "python@3.13"
|
||||
brew "qemu"
|
||||
brew "restic"
|
||||
brew "ripgrep"
|
||||
brew "ruby"
|
||||
brew "ruby@3.3"
|
||||
brew "rustup"
|
||||
brew "scroll-reverser"
|
||||
brew "sass/sass/migrator"
|
||||
brew "sass/sass/sass"
|
||||
brew "shellcheck"
|
||||
brew "smartmontools"
|
||||
brew "starship"
|
||||
@@ -64,8 +79,7 @@ brew "wget"
|
||||
brew "yt-dlp"
|
||||
brew "zlib"
|
||||
brew "zsh-syntax-highlighting"
|
||||
brew "sass/sass/migrator"
|
||||
brew "sass/sass/sass"
|
||||
|
||||
cask "codeql"
|
||||
cask "cyberduck"
|
||||
cask "font-fira-code-nerd-font"
|
||||
@@ -82,11 +96,13 @@ cask "iterm2"
|
||||
cask "macfuse"
|
||||
cask "meld"
|
||||
cask "mitmproxy"
|
||||
cask "processmonitor"
|
||||
cask "raycast"
|
||||
cask "rectangle"
|
||||
cask "scroll-reverser"
|
||||
cask "temurin"
|
||||
cask "veracrypt"
|
||||
cask "wezterm"
|
||||
cask "zulu@17"
|
||||
|
||||
def is_corp?
|
||||
@@ -94,13 +110,22 @@ def is_corp?
|
||||
`profiles status -type enrollment 2>/dev/null`.include?("Enrolled via DEP: Yes")
|
||||
end
|
||||
|
||||
if is_corp?
|
||||
brew "bazelisk", link: false
|
||||
end
|
||||
|
||||
# non-corp
|
||||
if !is_corp?
|
||||
brew "bazel"
|
||||
brew "bazelisk"
|
||||
brew "openssh"
|
||||
brew "virt-manager"
|
||||
|
||||
cask "claude-code"
|
||||
cask "cryptomator"
|
||||
cask "keepassxc"
|
||||
cask "gcloud-cli"
|
||||
cask "google-cloud-sdk"
|
||||
cask "keybase"
|
||||
cask "orbstack"
|
||||
cask "jordanbaird-ice"
|
||||
end
|
||||
|
||||
@@ -12,8 +12,17 @@ fi
|
||||
|
||||
trap "test -f ${FILENAME} && rm -f ${FILENAME}" EXIT
|
||||
|
||||
IOENGINE="libaio"
|
||||
DIRECT=1
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
IOENGINE="posixaio"
|
||||
# macOS doesn't support O_DIRECT in the same way, but fio's direct=1
|
||||
# handles it via F_NOCACHE if supported.
|
||||
DIRECT=1
|
||||
fi
|
||||
|
||||
fio --loops=5 --size=${BENCHMARK_SIZE} --filename=${FILENAME} \
|
||||
--stonewall --ioengine=libaio --direct=1 \
|
||||
--stonewall --ioengine=${IOENGINE} --direct=${DIRECT} \
|
||||
--name=Seqread --bs=1m --rw=read \
|
||||
--name=Seqwrite --bs=1m --rw=write \
|
||||
--name=512Kread --bs=512k --rw=randread \
|
||||
|
||||
@@ -1,6 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
CHROME_BINS="google-chrome-beta google-chrome"
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
CHROME_BINS="${CHROME_BINS} /Applications/Google\ Chrome\ Beta.app/Contents/MacOS/Google\ Chrome\ Beta /Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome"
|
||||
fi
|
||||
|
||||
for bin in ${CHROME_BINS} ; do
|
||||
if command -v ${bin} >/dev/null 2>&1 ; then
|
||||
CHROME=$(command -v ${bin})
|
||||
@@ -18,4 +22,4 @@ export HOME=${HOME}/.chrome-pentest
|
||||
mkdir -p ${HOME}
|
||||
|
||||
# Launch chrome for burp
|
||||
exec ${CHROME} --user-data-dir=${HOME}/chrome-pentest --proxy-server=127.0.0.1:8080
|
||||
exec "${CHROME}" --user-data-dir=${HOME}/chrome-pentest --proxy-server=127.0.0.1:8080
|
||||
|
||||
@@ -7,16 +7,69 @@ import sys
|
||||
import argparse
|
||||
import difflib
|
||||
|
||||
import tempfile
|
||||
|
||||
# Regex to match brew/cask/tap/mas lines
|
||||
PKG_RE = re.compile(r'^\s*(brew|cask|tap|mas)\s+["\']([^"\']+)["\'](.*)$')
|
||||
|
||||
def colorize_diff(lines):
|
||||
for line in lines:
|
||||
if line.startswith('+') and not line.startswith('+++'):
|
||||
yield f"\033[32m{line}\033[0m"
|
||||
elif line.startswith('-') and not line.startswith('---'):
|
||||
yield f"\033[31m{line}\033[0m"
|
||||
elif line.startswith('^'):
|
||||
yield f"\033[36m{line}\033[0m"
|
||||
else:
|
||||
yield line
|
||||
|
||||
class Entry:
|
||||
def sort_key(self): raise NotImplementedError()
|
||||
def to_lines(self): raise NotImplementedError()
|
||||
|
||||
class PackageEntry(Entry):
|
||||
def __init__(self, pkg_type, name, options, comments=None):
|
||||
self.pkg_type = pkg_type
|
||||
self.name = name
|
||||
self.options = options.strip()
|
||||
self.comments = comments or []
|
||||
|
||||
def sort_key(self):
|
||||
order = {'tap': 0, 'brew': 1, 'cask': 2, 'mas': 3}
|
||||
return (order.get(self.pkg_type, 4), self.name)
|
||||
|
||||
def to_lines(self):
|
||||
res = list(self.comments)
|
||||
pkg_line = f'{self.pkg_type} "{self.name}"'
|
||||
if self.options:
|
||||
if not self.options.startswith(','):
|
||||
pkg_line += ' '
|
||||
pkg_line += self.options
|
||||
res.append(pkg_line)
|
||||
return res
|
||||
|
||||
class TextEntry(Entry):
|
||||
def __init__(self, lines, is_header=True):
|
||||
self.lines = lines
|
||||
self.is_header = is_header
|
||||
|
||||
def sort_key(self):
|
||||
# Header is -1, Trailing is 5 (after all package types 0-4)
|
||||
return (-1 if self.is_header else 5, "")
|
||||
|
||||
def to_lines(self):
|
||||
return self.lines
|
||||
|
||||
def get_repo_root():
|
||||
script_dir = os.path.dirname(os.path.realpath(__file__))
|
||||
try:
|
||||
root = subprocess.check_output(['git', 'rev-parse', '--show-toplevel'],
|
||||
cwd=script_dir,
|
||||
stderr=subprocess.STDOUT).decode().strip()
|
||||
return root
|
||||
except subprocess.CalledProcessError:
|
||||
return os.getcwd()
|
||||
# If not in a git repo, go up 2 levels from script_dir (bin/macos/)
|
||||
return os.path.abspath(os.path.join(script_dir, '..', '..'))
|
||||
|
||||
def get_ignore_list(repo_root):
|
||||
ignore = set()
|
||||
@@ -34,11 +87,19 @@ def get_ignore_list(repo_root):
|
||||
ignore.add(line)
|
||||
return ignore
|
||||
|
||||
def get_current_packages():
|
||||
def get_current_packages(args):
|
||||
"""Runs brew bundle dump and returns lines."""
|
||||
env = os.environ.copy()
|
||||
env["HOMEBREW_NO_AUTO_UPDATE"] = "1"
|
||||
env["HOMEBREW_NO_INSTALL_CLEANUP"] = "1"
|
||||
env["HOMEBREW_NO_ENV_HINTS"] = "1"
|
||||
|
||||
cmd = ['brew', 'bundle', 'dump', '--file=-']
|
||||
if args.no_mas: cmd.append('--no-mas')
|
||||
if args.no_vscode: cmd.append('--no-vscode')
|
||||
|
||||
try:
|
||||
output = subprocess.check_output(['brew', 'bundle', 'dump', '--file=-'],
|
||||
stderr=subprocess.DEVNULL).decode()
|
||||
output = subprocess.check_output(cmd, env=env, stderr=subprocess.DEVNULL).decode()
|
||||
return output.splitlines()
|
||||
except subprocess.CalledProcessError:
|
||||
print("Error: 'brew bundle dump' failed. Is homebrew installed?", file=sys.stderr)
|
||||
@@ -48,8 +109,9 @@ def parse_brewfile(content):
|
||||
"""
|
||||
Parses Brewfile content.
|
||||
Returns:
|
||||
- entries: list of Entry objects
|
||||
- conditional_pkgs: set of (type, name)
|
||||
- preserved_footer: string (everything from first conditional onwards)
|
||||
- footer: string (everything from first conditional onwards)
|
||||
"""
|
||||
lines = content.splitlines()
|
||||
conditional_pkgs = set()
|
||||
@@ -60,7 +122,7 @@ def parse_brewfile(content):
|
||||
|
||||
for i, line in enumerate(lines):
|
||||
stripped = line.strip()
|
||||
if stripped.startswith(('if ', 'unless ', 'case ')) and not stripped.endswith('; end'):
|
||||
if stripped.startswith(('if ', 'unless ', 'case ', 'def ', 'begin ')) and not stripped.endswith('; end'):
|
||||
if first_conditional_idx == -1:
|
||||
# Look back for comments that might belong to this block
|
||||
j = i - 1
|
||||
@@ -77,13 +139,35 @@ def parse_brewfile(content):
|
||||
if stripped == 'end' or stripped.endswith('; end'):
|
||||
in_conditional -= 1
|
||||
|
||||
if first_conditional_idx == -1:
|
||||
return set(), ""
|
||||
unconditional_lines = lines[:first_conditional_idx] if first_conditional_idx != -1 else lines
|
||||
footer = "\n".join(lines[first_conditional_idx:]) if first_conditional_idx != -1 else ""
|
||||
|
||||
footer = "\n".join(lines[first_conditional_idx:])
|
||||
return conditional_pkgs, footer
|
||||
entries = []
|
||||
comment_buffer = []
|
||||
first_pkg_seen = False
|
||||
|
||||
for line in unconditional_lines:
|
||||
match = PKG_RE.match(line)
|
||||
if match:
|
||||
if not first_pkg_seen:
|
||||
if comment_buffer:
|
||||
entries.append(TextEntry(comment_buffer, is_header=True))
|
||||
comment_buffer = []
|
||||
first_pkg_seen = True
|
||||
entries.append(PackageEntry(match.group(1), match.group(2), match.group(3), comment_buffer))
|
||||
comment_buffer = []
|
||||
else:
|
||||
comment_buffer.append(line)
|
||||
|
||||
if comment_buffer:
|
||||
entries.append(TextEntry(comment_buffer, is_header=False))
|
||||
|
||||
return entries, conditional_pkgs, footer
|
||||
|
||||
def main(args):
|
||||
if sys.platform != "darwin":
|
||||
print(f"Warning: Running on {sys.platform}. Brewfile is primarily for macOS.", file=sys.stderr)
|
||||
|
||||
repo_root = get_repo_root()
|
||||
brewfile_path = os.path.join(repo_root, 'Brewfile')
|
||||
|
||||
@@ -94,39 +178,90 @@ def main(args):
|
||||
with open(brewfile_path) as f:
|
||||
old_content = f.read()
|
||||
|
||||
conditional_pkgs, footer = parse_brewfile(old_content)
|
||||
old_entries, conditional_pkgs, footer = parse_brewfile(old_content)
|
||||
ignore_list = get_ignore_list(repo_root)
|
||||
|
||||
dumped_lines = get_current_packages()
|
||||
|
||||
new_unconditional_lines = []
|
||||
old_pkg_map = {}
|
||||
for e in old_entries:
|
||||
if isinstance(e, PackageEntry):
|
||||
key = (e.pkg_type, e.name)
|
||||
if key not in old_pkg_map:
|
||||
old_pkg_map[key] = e
|
||||
|
||||
dumped_lines = get_current_packages(args)
|
||||
dumped_pkgs = []
|
||||
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:
|
||||
pkg_type, pkg_name, pkg_options = match.group(1), match.group(2), match.group(3)
|
||||
if pkg_name in ignore_list or (pkg_type, pkg_name) in conditional_pkgs:
|
||||
continue
|
||||
dumped_pkgs.append(PackageEntry(pkg_type, pkg_name, pkg_options))
|
||||
|
||||
# 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)
|
||||
new_entries = []
|
||||
for e in old_entries:
|
||||
if isinstance(e, TextEntry) and e.is_header:
|
||||
new_entries.append(e)
|
||||
|
||||
# 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))
|
||||
seen_in_new = set()
|
||||
added_count = 0
|
||||
removed_count = 0
|
||||
merged_count = 0
|
||||
|
||||
new_unconditional_lines.sort(key=sort_key)
|
||||
if args.add_only:
|
||||
for e in old_entries:
|
||||
if isinstance(e, PackageEntry):
|
||||
new_entries.append(e)
|
||||
seen_in_new.add((e.pkg_type, e.name))
|
||||
for d in dumped_pkgs:
|
||||
if (d.pkg_type, d.name) not in seen_in_new:
|
||||
new_entries.append(d)
|
||||
seen_in_new.add((d.pkg_type, d.name))
|
||||
added_count += 1
|
||||
else:
|
||||
for d in dumped_pkgs:
|
||||
key = (d.pkg_type, d.name)
|
||||
if key in seen_in_new: continue
|
||||
if key in old_pkg_map:
|
||||
merged = old_pkg_map[key]
|
||||
if not merged.options:
|
||||
merged.options = d.options
|
||||
new_entries.append(merged)
|
||||
merged_count += 1
|
||||
else:
|
||||
new_entries.append(d)
|
||||
added_count += 1
|
||||
seen_in_new.add(key)
|
||||
|
||||
# Build new content
|
||||
new_content = "\n".join(new_unconditional_lines)
|
||||
# Check for removals
|
||||
for key in old_pkg_map:
|
||||
if key not in seen_in_new:
|
||||
removed_count += 1
|
||||
|
||||
for e in old_entries:
|
||||
if isinstance(e, TextEntry) and not e.is_header:
|
||||
new_entries.append(e)
|
||||
|
||||
new_entries.sort(key=lambda x: x.sort_key())
|
||||
|
||||
output_lines = []
|
||||
last_type = None
|
||||
for e in new_entries:
|
||||
if isinstance(e, PackageEntry):
|
||||
if last_type and e.pkg_type != last_type:
|
||||
output_lines.append("")
|
||||
last_type = e.pkg_type
|
||||
|
||||
lines = e.to_lines()
|
||||
# If we just added a blank line, and the new lines start with one, skip the first new line
|
||||
if output_lines and output_lines[-1] == "" and lines and lines[0] == "":
|
||||
output_lines.extend(lines[1:])
|
||||
else:
|
||||
output_lines.extend(lines)
|
||||
|
||||
new_content = "\n".join(output_lines)
|
||||
if footer:
|
||||
if new_unconditional_lines:
|
||||
if output_lines and output_lines[-1].strip():
|
||||
new_content += "\n\n"
|
||||
new_content += footer.strip() + "\n"
|
||||
else:
|
||||
@@ -137,20 +272,33 @@ def main(args):
|
||||
else:
|
||||
if args.dry_run:
|
||||
print("Changes detected (dry run):")
|
||||
diff = difflib.unified_diff(
|
||||
diff = list(difflib.unified_diff(
|
||||
old_content.splitlines(keepends=True),
|
||||
new_content.splitlines(keepends=True),
|
||||
fromfile='Brewfile (original)',
|
||||
tofile='Brewfile (new)'
|
||||
)
|
||||
sys.stdout.writelines(diff)
|
||||
))
|
||||
if sys.stdout.isatty():
|
||||
sys.stdout.writelines(colorize_diff(diff))
|
||||
else:
|
||||
sys.stdout.writelines(diff)
|
||||
else:
|
||||
with open(brewfile_path, 'w') as f:
|
||||
f.write(new_content)
|
||||
dir_name = os.path.dirname(brewfile_path)
|
||||
with tempfile.NamedTemporaryFile('w', dir=dir_name, delete=False) as tf:
|
||||
tf.write(new_content)
|
||||
tempname = tf.name
|
||||
os.replace(tempname, brewfile_path)
|
||||
print("Brewfile updated.")
|
||||
|
||||
if args.verbose:
|
||||
print(f"Summary: {added_count} added, {removed_count} removed, {merged_count} kept/merged.")
|
||||
|
||||
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.")
|
||||
parser.add_argument("--add-only", action="store_true", help="Only add missing entries, do not remove existing ones.")
|
||||
parser.add_argument("--verbose", "-v", action="store_true", help="Print summary of changes.")
|
||||
parser.add_argument("--no-mas", action="store_true", help="Do not include Mac App Store apps.")
|
||||
parser.add_argument("--no-vscode", action="store_true", help="Do not include VSCode extensions.")
|
||||
args = parser.parse_args()
|
||||
main(args)
|
||||
|
||||
63
bin/quartz
Executable file
63
bin/quartz
Executable file
@@ -0,0 +1,63 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
# QUARTZ_DIR search logic
|
||||
if [ -z "${QUARTZ_DIR:-}" ]; then
|
||||
if [ -f "quartz.config.ts" ]; then
|
||||
QUARTZ_DIR="$PWD"
|
||||
elif [ -d "$HOME/Personal/notes-quartz" ]; then
|
||||
QUARTZ_DIR="$HOME/Personal/notes-quartz"
|
||||
elif [ -d "$HOME/Projects/notes-quartz" ]; then
|
||||
QUARTZ_DIR="$HOME/Projects/notes-quartz"
|
||||
else
|
||||
echo "Error: QUARTZ_DIR could not be found." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "$QUARTZ_DIR" ]; then
|
||||
echo "Error: QUARTZ_DIR '$QUARTZ_DIR' is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# NOTES_DIR search logic
|
||||
PARSE_NOTES_DIR=""
|
||||
# Use a copy of args to find -d/--directory
|
||||
ARGS=("$@")
|
||||
for ((i=0; i<${#ARGS[@]}; i++)); do
|
||||
if [[ "${ARGS[i]}" == "-d" || "${ARGS[i]}" == "--directory" ]]; then
|
||||
if [[ $((i+1)) -lt ${#ARGS[@]} ]]; then
|
||||
PARSE_NOTES_DIR="${ARGS[i+1]}"
|
||||
fi
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$PARSE_NOTES_DIR" ]; then
|
||||
NOTES_DIR="$PARSE_NOTES_DIR"
|
||||
elif [ -z "${NOTES_DIR:-}" ]; then
|
||||
if [ -d "$HOME/Notes" ]; then
|
||||
NOTES_DIR="$HOME/Notes"
|
||||
elif [ -d "$HOME/Personal/notes" ]; then
|
||||
NOTES_DIR="$HOME/Personal/notes"
|
||||
elif [ -d "$HOME/Projects/notes" ]; then
|
||||
NOTES_DIR="$HOME/Projects/notes"
|
||||
else
|
||||
echo "Error: NOTES_DIR could not be found." >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -d "$NOTES_DIR" ]; then
|
||||
echo "Error: NOTES_DIR '$NOTES_DIR' is not a directory." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cd "$QUARTZ_DIR"
|
||||
|
||||
# Run npx quartz
|
||||
# Following the prompt's structure but using NOTES_DIR for the flag
|
||||
# npx quartz ${argv[1]} --directory ${NOTES_DIR} "$@"
|
||||
# We use ${1:-} for argv[1] to handle cases with no arguments.
|
||||
npx quartz "${1:-}" --directory "$NOTES_DIR" "$@"
|
||||
@@ -5,8 +5,14 @@
|
||||
set -ue
|
||||
|
||||
TOOLS="flameshot scrot"
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
TOOLS="screencapture ${TOOLS}"
|
||||
fi
|
||||
|
||||
SCREENDIR=${SCREENDIR:-${HOME}/Pictures/Screenshots}
|
||||
SCROT_FORMAT="%F-%T.png"
|
||||
# Filename for screencapture
|
||||
FILE_NAME=$(date "+%Y-%m-%d-%H%M%S.png")
|
||||
|
||||
function default_screenshot_command {
|
||||
for tool in ${TOOLS} ; do
|
||||
@@ -41,10 +47,29 @@ function scrot_full_capture {
|
||||
scrot "${SCREENDIR}/${SCROT_FORMAT}"
|
||||
}
|
||||
|
||||
function mac_capture {
|
||||
local mode="${1}"
|
||||
local target="${SCREENDIR}/${FILE_NAME}"
|
||||
case "${mode}" in
|
||||
region)
|
||||
screencapture -i "${target}"
|
||||
;;
|
||||
window)
|
||||
screencapture -i -w "${target}"
|
||||
;;
|
||||
full)
|
||||
screencapture "${target}"
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
case "${CMD}" in
|
||||
region|window|full)
|
||||
mkdir -p "${SCREENDIR}"
|
||||
case "${TOOL}" in
|
||||
screencapture)
|
||||
mac_capture "${CMD}"
|
||||
;;
|
||||
flameshot)
|
||||
case "${CMD}" in
|
||||
region|window)
|
||||
|
||||
310
bin/update-authorized-keys
Executable file
310
bin/update-authorized-keys
Executable file
@@ -0,0 +1,310 @@
|
||||
#!/usr/bin/env bash
|
||||
|
||||
# update-authorized-keys - Manage ~/.ssh/authorized_keys from multiple sources
|
||||
#
|
||||
# BEHAVIOR:
|
||||
# 1. Collects SSH public keys from one or more source directories (default: ~/.ssh/authorized_keys.d).
|
||||
# 2. Skips empty files and files symlinked to /dev/null (masking).
|
||||
# 3. Deterministically concatenates keys into a "managed block" wrapped in markers:
|
||||
# # BEGIN UPDATE-AUTHORIZED-KEYS
|
||||
# # END UPDATE-AUTHORIZED-KEYS
|
||||
# 4. Deduplicates managed keys: if the same key (including options) is found in multiple files,
|
||||
# it is included once with a comment listing all source filenames.
|
||||
# 5. Preserves "manual" keys found in the target file outside the markers.
|
||||
# 6. Removes manual keys that exactly match a managed key (options + key data).
|
||||
# 7. Validates every proposed key individually using 'ssh-keygen -l -f'.
|
||||
# 8. Optionally validates the whole file with 'authorized-keys-test' if available.
|
||||
# 9. Displays a unified diff and prompts for confirmation before atomic replacement.
|
||||
# 10. Supports a --dry-run mode and a --self-test mode for verifying logic.
|
||||
|
||||
set -o nounset
|
||||
set -o errexit
|
||||
set -o pipefail
|
||||
|
||||
CLEANUP_FILES=()
|
||||
cleanup() {
|
||||
rm -rf "${CLEANUP_FILES[@]}"
|
||||
}
|
||||
trap cleanup EXIT
|
||||
|
||||
# Configuration
|
||||
DEFAULT_DIR="${HOME}/.ssh/authorized_keys.d"
|
||||
DEFAULT_TARGET="${HOME}/.ssh/authorized_keys"
|
||||
BEGIN_MARKER="# BEGIN UPDATE-AUTHORIZED-KEYS"
|
||||
END_MARKER="# END UPDATE-AUTHORIZED-KEYS"
|
||||
|
||||
# State
|
||||
SOURCE_DIRS=()
|
||||
TARGET_FILE="${DEFAULT_TARGET}"
|
||||
DRY_RUN=0
|
||||
|
||||
usage() {
|
||||
cat <<EOF
|
||||
Usage: $(basename "$0") [options]
|
||||
|
||||
Options:
|
||||
--dir DIR Primary directory for managed keys (default: ${DEFAULT_DIR})
|
||||
--extra-dir DIR Additional directory to scan for keys (can be repeated)
|
||||
--target FILE Target authorized_keys file (default: ${DEFAULT_TARGET})
|
||||
--dry-run Show changes and validate without modifying the target
|
||||
--self-test Run internal suite of tests to verify script logic
|
||||
--help Show this help message
|
||||
EOF
|
||||
}
|
||||
|
||||
run_self_test() {
|
||||
echo "Running self-test..."
|
||||
local test_root=$(mktemp -d)
|
||||
CLEANUP_FILES+=("${test_root}")
|
||||
|
||||
local d1="${test_root}/d1"
|
||||
local d2="${test_root}/d2"
|
||||
local target="${test_root}/target"
|
||||
mkdir -p "${d1}" "${d2}"
|
||||
|
||||
local key1="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIJ8XoR7N7X5XoR7N7X5XoR7N7X5XoR7N7X5XoR7N7X5X key1"
|
||||
local key2="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIL9YpS8O8Y6YpS8O8Y6YpS8O8Y6YpS8O8Y6YpS8O8Y6Y key2"
|
||||
local key_man="ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIM0ZqT9P9Z7ZqT9P9Z7ZqT9P9Z7ZqT9P9Z7ZqT9P9Z7Z manual"
|
||||
local long_opt="environment=\"VAR=VERY_LONG_VALUE_THAT_EXCEEDS_TWENTY_CHARS\""
|
||||
|
||||
echo "${key1}" > "${d1}/k1"
|
||||
echo "${key1}" > "${d2}/k1_dup"
|
||||
echo "${key2}" > "${d2}/k2"
|
||||
echo "${long_opt} ${key1}" > "${d1}/k1_long"
|
||||
echo "${long_opt} ${key2}" > "${d1}/k2_long"
|
||||
ln -s /dev/null "${d1}/masked"
|
||||
|
||||
cat <<EOF > "${target}"
|
||||
${key_man}
|
||||
${key1} # This should be removed as it's now managed
|
||||
EOF
|
||||
|
||||
echo "Executing script in test mode..."
|
||||
# Pipe "y" to handle the TTY check if we are not in a TTY during test
|
||||
echo "y" | "$0" --dir "${d1}" --extra-dir "${d2}" --target "${target}" > /dev/null
|
||||
|
||||
local content=$(cat "${target}")
|
||||
|
||||
echo -n "Check markers... "
|
||||
if [[ "${content}" == *"${BEGIN_MARKER}"* && "${content}" == *"${END_MARKER}"* ]]; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
|
||||
echo -n "Check managed deduplication... "
|
||||
if grep -q "Source: k1, k1_dup" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
|
||||
echo -n "Check long option deduplication (should NOT deduplicate different keys)... "
|
||||
if grep -q "k1_long" "${target}" && grep -q "k2_long" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
|
||||
echo -n "Check manual key preservation... "
|
||||
if grep -q "manual" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
|
||||
echo -n "Check manual key filtering... "
|
||||
local manual_count=$(grep -c "${key1}" "${target}")
|
||||
# key1 appears twice in managed block (once plain, once with long opt)
|
||||
# and it was in manual block. The manual one should be removed.
|
||||
# So we expect 2 occurrences in the final file (both in managed block).
|
||||
if [[ ${manual_count} -eq 2 ]]; then echo "OK"; else echo "FAIL (Found ${manual_count} occurrences, expected 2)"; exit 1; fi
|
||||
|
||||
echo -n "Check masking... "
|
||||
if ! grep -q "masked" "${target}"; then echo "OK"; else echo "FAIL"; exit 1; fi
|
||||
|
||||
echo "Self-test passed successfully!"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Parse arguments
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--dir)
|
||||
[[ -z "${2:-}" ]] && { echo "Error: --dir requires an argument" >&2; exit 1; }
|
||||
SOURCE_DIRS+=("$2"); shift 2 ;;
|
||||
--extra-dir)
|
||||
[[ -z "${2:-}" ]] && { echo "Error: --extra-dir requires an argument" >&2; exit 1; }
|
||||
SOURCE_DIRS+=("$2"); shift 2 ;;
|
||||
--target)
|
||||
[[ -z "${2:-}" ]] && { echo "Error: --target requires an argument" >&2; exit 1; }
|
||||
TARGET_FILE="$2"; shift 2 ;;
|
||||
--dry-run) DRY_RUN=1; shift ;;
|
||||
--self-test) run_self_test ;;
|
||||
--help) usage; exit 0 ;;
|
||||
*) echo "Unknown option: $1" >&2; usage; exit 1 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
if [[ ${#SOURCE_DIRS[@]} -eq 0 ]]; then
|
||||
SOURCE_DIRS+=("${DEFAULT_DIR}")
|
||||
fi
|
||||
|
||||
mkdir -p "$(dirname "${TARGET_FILE}")"
|
||||
TMP_FILE=$(mktemp)
|
||||
CLEANUP_FILES+=("${TMP_FILE}")
|
||||
|
||||
collect_keys() {
|
||||
local dirs=("${@}")
|
||||
for dir in "${dirs[@]}"; do
|
||||
if [[ ! -d "${dir}" ]]; then continue; fi
|
||||
# Use a glob to avoid parsing ls
|
||||
for file in "${dir}"/*; do
|
||||
[[ ! -e "${file}" ]] && continue
|
||||
[[ ! -f "${file}" || ! -s "${file}" ]] && continue
|
||||
if [[ -L "${file}" && "$(readlink "${file}")" == "/dev/null" ]]; then continue; fi
|
||||
while read -r line; do
|
||||
[[ -z "${line}" || "${line}" =~ ^[[:space:]]*# ]] && continue
|
||||
# Use a specific delimiter that is unlikely to be in the key or filename
|
||||
# If using tabs, ensure we only split on the first one in AWK
|
||||
printf "%s\t%s\n" "$(basename "${file}")" "${line}"
|
||||
done < "${file}"
|
||||
done
|
||||
done
|
||||
}
|
||||
|
||||
# Use a HEREDOC for the complex AWK script to avoid shell interpolation issues
|
||||
MANAGED_BLOCK=$(collect_keys "${SOURCE_DIRS[@]}" | awk -F'\t' '
|
||||
{
|
||||
# Splitting on the first tab manually to be robust
|
||||
tab_idx = index($0, "\t")
|
||||
source = substr($0, 1, tab_idx - 1)
|
||||
full_line = substr($0, tab_idx + 1)
|
||||
|
||||
# Signature detection: all options + key type + key data
|
||||
# (Excludes the comment at the end)
|
||||
n = split(full_line, parts, " ")
|
||||
sig = ""
|
||||
for (i=1; i<=n; i++) {
|
||||
sig = (sig == "" ? parts[i] : sig " " parts[i])
|
||||
# A key line is [options] <type> <base64> [comment]
|
||||
# We stop after the base64 part. Key types start with known prefixes.
|
||||
if (parts[i] ~ /^(ssh-|ecdsa-|sk-)/ && i < n) {
|
||||
sig = sig " " parts[i+1]
|
||||
break
|
||||
}
|
||||
}
|
||||
# Fallback if no key type found (should not happen with valid keys)
|
||||
if (sig == "") sig = full_line
|
||||
|
||||
if (!(sig in keys)) {
|
||||
keys[sig] = full_line
|
||||
order[++count] = sig
|
||||
}
|
||||
sources[sig] = (sources[sig] ? sources[sig] ", " : "") source
|
||||
}
|
||||
END {
|
||||
for (i=1; i<=count; i++) {
|
||||
sig = order[i]
|
||||
print "# Source: " sources[sig]
|
||||
print keys[sig]
|
||||
}
|
||||
}')
|
||||
|
||||
MANUAL_KEYS=""
|
||||
if [[ -f "${TARGET_FILE}" ]]; then
|
||||
MANUAL_KEYS=$(awk -v begin="${BEGIN_MARKER}" -v end="${END_MARKER}" '
|
||||
BEGIN { inside=0 }
|
||||
$0 == begin { inside=1; next }
|
||||
$0 == end { inside=0; next }
|
||||
!inside { print $0 }
|
||||
' "${TARGET_FILE}")
|
||||
fi
|
||||
|
||||
MANAGED_SIGS_TMP=$(mktemp)
|
||||
echo "${MANAGED_BLOCK}" | awk '/^[^#]/ {
|
||||
n = split($0, parts, " ")
|
||||
sig = ""
|
||||
for (i=1; i<=n; i++) {
|
||||
sig = (sig == "" ? parts[i] : sig " " parts[i])
|
||||
if (parts[i] ~ /^(ssh-|ecdsa-|sk-)/ && i < n) {
|
||||
sig = sig " " parts[i+1]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (sig != "") print sig
|
||||
}' > "${MANAGED_SIGS_TMP}"
|
||||
|
||||
FINAL_MANUAL_KEYS=$(echo "${MANUAL_KEYS}" | awk -v sigs_file="${MANAGED_SIGS_TMP}" '
|
||||
BEGIN {
|
||||
while ((getline line < sigs_file) > 0) {
|
||||
managed[line] = 1
|
||||
}
|
||||
close(sigs_file)
|
||||
}
|
||||
{
|
||||
if ($0 ~ /^[[:space:]]*$/ || $0 ~ /^[[:space:]]*#/) {
|
||||
print $0
|
||||
next
|
||||
}
|
||||
n = split($0, parts, " ")
|
||||
sig = ""
|
||||
for (i=1; i<=n; i++) {
|
||||
sig = (sig == "" ? parts[i] : sig " " parts[i])
|
||||
if (parts[i] ~ /^(ssh-|ecdsa-|sk-)/ && i < n) {
|
||||
sig = sig " " parts[i+1]
|
||||
break
|
||||
}
|
||||
}
|
||||
if (!(sig in managed)) {
|
||||
print $0
|
||||
}
|
||||
}')
|
||||
rm -f "${MANAGED_SIGS_TMP}"
|
||||
|
||||
{
|
||||
if [[ -n "${MANAGED_BLOCK}" ]]; then
|
||||
echo "${BEGIN_MARKER}"
|
||||
echo "${MANAGED_BLOCK}"
|
||||
echo "${END_MARKER}"
|
||||
fi
|
||||
echo "${FINAL_MANUAL_KEYS}"
|
||||
} > "${TMP_FILE}"
|
||||
|
||||
echo "Validating proposed changes..."
|
||||
VALID=1
|
||||
while read -r line; do
|
||||
[[ -z "${line}" || "${line}" =~ ^[[:space:]]*# ]] && continue
|
||||
if ! echo "${line}" | ssh-keygen -l -f - >/dev/null 2>&1; then
|
||||
echo "ERROR: Invalid SSH key detected: ${line}" >&2
|
||||
VALID=0
|
||||
fi
|
||||
done < "${TMP_FILE}"
|
||||
|
||||
if command -v authorized-keys-test >/dev/null 2>&1; then
|
||||
if ! authorized-keys-test "${TMP_FILE}"; then
|
||||
echo "ERROR: Proposed file failed authorized-keys-test." >&2
|
||||
VALID=0
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ ${VALID} -eq 0 ]]; then
|
||||
echo "Validation failed. Aborting." >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -f "${TARGET_FILE}" ]]; then
|
||||
diff -u "${TARGET_FILE}" "${TMP_FILE}" || true
|
||||
else
|
||||
echo "Target file does not exist. Proposed content:"
|
||||
cat "${TMP_FILE}"
|
||||
fi
|
||||
|
||||
if [[ ${DRY_RUN} -eq 1 ]]; then
|
||||
echo "Dry run complete. No changes made."
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [[ -t 0 ]]; then
|
||||
echo -n "Apply these changes to ${TARGET_FILE}? [y/N] "
|
||||
read -r response
|
||||
elif [[ ! -t 0 ]]; then
|
||||
# Read from pipe or file if provided
|
||||
if ! read -r response; then
|
||||
echo "Non-interactive shell detected and no input provided. Aborting."
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if [[ "${response}" =~ ^([yY][eE][sS]|[yY])$ ]]; then
|
||||
chmod 0600 "${TMP_FILE}"
|
||||
mv "${TMP_FILE}" "${TARGET_FILE}"
|
||||
echo "Changes applied successfully."
|
||||
else
|
||||
echo "Aborted."
|
||||
exit 1
|
||||
fi
|
||||
@@ -1,9 +1,6 @@
|
||||
# General aliases, should only be sourced in interactive shells
|
||||
# Try to keep in sync with ~/.config/fish/conf.d/aliases.fish
|
||||
|
||||
# Cryptsetup alias
|
||||
alias luksFormat='cryptsetup luksFormat --type=luks2 --pbkdf-memory=2560000 --pbkdf=argon2id -i 15000 -s 512 -h sha256 -c aes-xts-plain64'
|
||||
|
||||
# Timestamp in a machine-sortable form
|
||||
alias tstamp="date '+%Y%m%d-%H%M%S'"
|
||||
|
||||
@@ -13,12 +10,6 @@ alias mdcode="sed 's/^/ /'"
|
||||
# Intel format plz
|
||||
alias objdump="command objdump -M intel"
|
||||
|
||||
# Drop caches for swap issues
|
||||
alias drop_caches="echo 3 | sudo /usr/bin/tee /proc/sys/vm/drop_caches"
|
||||
|
||||
# dump acpi temperature
|
||||
alias gettemp='printf "%02.2f\n" "$(cat /sys/class/thermal/thermal_zone0/temp)e-3"'
|
||||
|
||||
# get git working directory
|
||||
alias gitroot="git rev-parse --show-toplevel"
|
||||
|
||||
@@ -31,20 +22,37 @@ alias ipy="ipython3 --no-banner"
|
||||
# Skip the header on bc
|
||||
alias bc="command bc -q"
|
||||
|
||||
# Get a decently readable df
|
||||
alias dfh="df -h -x tmpfs -x devtmpfs -x squashfs -x fuse -x efivarfs"
|
||||
|
||||
# Clear the GPG agent
|
||||
alias clear-gpg-agent="echo RELOADAGENT | gpg-connect-agent"
|
||||
|
||||
# Battery details
|
||||
alias bat-details='upower -i $(upower -e | grep battery)'
|
||||
|
||||
# Nvidia refresh rate
|
||||
alias nvidia-refresh-rate='nvidia-settings --display=:0 -q RefreshRate -t'
|
||||
|
||||
# Earthly ssh
|
||||
alias earthly='earthly --ssh-auth-sock ""'
|
||||
|
||||
# to clipboard
|
||||
alias toclip='xclip -selection clipboard'
|
||||
if [ "$(uname)" = "Linux" ]; then
|
||||
# Cryptsetup alias
|
||||
alias luksFormat='cryptsetup luksFormat --type=luks2 --pbkdf-memory=2560000 --pbkdf=argon2id -i 15000 -s 512 -h sha256 -c aes-xts-plain64'
|
||||
|
||||
# Drop caches for swap issues
|
||||
alias drop_caches="echo 3 | sudo /usr/bin/tee /proc/sys/vm/drop_caches"
|
||||
|
||||
# dump acpi temperature
|
||||
alias gettemp='printf "%02.2f\n" "$(cat /sys/class/thermal/thermal_zone0/temp)e-3"'
|
||||
|
||||
# Get a decently readable df
|
||||
alias dfh="df -h -x tmpfs -x devtmpfs -x squashfs -x fuse -x efivarfs"
|
||||
|
||||
# Battery details
|
||||
alias bat-details='upower -i $(upower -e | grep battery)'
|
||||
|
||||
# Nvidia refresh rate
|
||||
alias nvidia-refresh-rate='nvidia-settings --display=:0 -q RefreshRate -t'
|
||||
|
||||
# to clipboard
|
||||
alias toclip='xclip -selection clipboard'
|
||||
elif [ "$(uname)" = "Darwin" ]; then
|
||||
# Get a decently readable df
|
||||
alias dfh="df -h"
|
||||
|
||||
# to clipboard
|
||||
alias toclip='pbcopy'
|
||||
fi
|
||||
|
||||
4
dotfiles/bxignore
Normal file
4
dotfiles/bxignore
Normal file
@@ -0,0 +1,4 @@
|
||||
# Credentials
|
||||
.ssh
|
||||
Passwords.kdbx
|
||||
Passwords.kdbx.age
|
||||
@@ -1,6 +1,3 @@
|
||||
# Cryptsetup alias
|
||||
alias luksFormat 'cryptsetup luksFormat --type=luks2 --pbkdf-memory=2560000 --pbkdf=argon2id -i 15000 -s 512 -h sha256 -c aes-xts-plain64'
|
||||
|
||||
# Timestamp in a machine-sortable form
|
||||
alias tstamp "date '+%Y%m%d-%H%M%S'"
|
||||
|
||||
@@ -10,12 +7,6 @@ alias mdcode "sed 's/^/ /'"
|
||||
# Intel format plz
|
||||
alias objdump "command objdump -M intel"
|
||||
|
||||
# Drop caches for swap issues
|
||||
alias drop_caches "echo 3 | sudo /usr/bin/tee /proc/sys/vm/drop_caches"
|
||||
|
||||
# dump acpi temperature
|
||||
alias gettemp 'printf "%02.2f\n" (cat /sys/class/thermal/thermal_zone0/temp)e-3'
|
||||
|
||||
# get git working directory
|
||||
alias gitroot "git rev-parse --show-toplevel"
|
||||
|
||||
@@ -28,23 +19,40 @@ alias ipy "ipython3 --no-banner"
|
||||
# Skip the header on bc
|
||||
alias bc "command bc -q"
|
||||
|
||||
# Get a decently readable df
|
||||
alias dfh "df -h -x tmpfs -x devtmpfs -x squashfs -x fuse -x efivarfs"
|
||||
|
||||
# Clear the GPG agent
|
||||
alias clear-gpg-agent "echo RELOADAGENT | gpg-connect-agent"
|
||||
|
||||
# Battery details
|
||||
alias bat-details 'upower -i (upower -e | grep battery)'
|
||||
|
||||
# Nvidia refresh rate
|
||||
alias nvidia-refresh-rate 'nvidia-settings --display=:0 -q RefreshRate -t'
|
||||
|
||||
# Earthly ssh
|
||||
alias earthly 'earthly --ssh-auth-sock ""'
|
||||
|
||||
# to clipboard
|
||||
alias toclip 'xclip -selection clipboard'
|
||||
if test (uname) = "Linux"
|
||||
# Cryptsetup alias
|
||||
alias luksFormat 'cryptsetup luksFormat --type=luks2 --pbkdf-memory=2560000 --pbkdf=argon2id -i 15000 -s 512 -h sha256 -c aes-xts-plain64'
|
||||
|
||||
# Drop caches for swap issues
|
||||
alias drop_caches "echo 3 | sudo /usr/bin/tee /proc/sys/vm/drop_caches"
|
||||
|
||||
# dump acpi temperature
|
||||
alias gettemp 'printf "%02.2f\n" (cat /sys/class/thermal/thermal_zone0/temp)e-3'
|
||||
|
||||
# Get a decently readable df
|
||||
alias dfh "df -h -x tmpfs -x devtmpfs -x squashfs -x fuse -x efivarfs"
|
||||
|
||||
# Battery details
|
||||
alias bat-details 'upower -i (upower -e | grep battery)'
|
||||
|
||||
# Nvidia refresh rate
|
||||
alias nvidia-refresh-rate 'nvidia-settings --display=:0 -q RefreshRate -t'
|
||||
|
||||
# to clipboard
|
||||
alias toclip 'xclip -selection clipboard'
|
||||
else if test (uname) = "Darwin"
|
||||
# Get a decently readable df
|
||||
alias dfh "df -h"
|
||||
|
||||
# to clipboard
|
||||
alias toclip 'pbcopy'
|
||||
end
|
||||
|
||||
# On some systems, bat is batcat
|
||||
if not command -v bat >/dev/null 2>&1
|
||||
|
||||
95
dotfiles/config/fish/conf.d/gemini.fish
Normal file
95
dotfiles/config/fish/conf.d/gemini.fish
Normal file
@@ -0,0 +1,95 @@
|
||||
# Bridge to Gemini CLI Context Management (Zsh-backed)
|
||||
# This allows using the Zsh implementation from Fish to avoid dual maintenance.
|
||||
|
||||
# Ensure the base context directory exists
|
||||
if set -q XDG_CONFIG_HOME
|
||||
set -gx GEMINI_CONTEXT_DIR $XDG_CONFIG_HOME/gemini
|
||||
else
|
||||
set -gx GEMINI_CONTEXT_DIR $HOME/.config/gemini
|
||||
end
|
||||
mkdir -p "$GEMINI_CONTEXT_DIR"
|
||||
|
||||
# Path to the source of truth
|
||||
set -l gemini_zsh_script "$HOME/.skel/dotfiles/zshrc.d/gemini.zsh"
|
||||
|
||||
function _gemini_context_bridge
|
||||
# Check if Zsh script exists
|
||||
if not test -f "$gemini_zsh_script"
|
||||
echo "Error: Gemini Zsh script not found at $gemini_zsh_script"
|
||||
return 1
|
||||
end
|
||||
|
||||
# We use a temporary file to reliably pass the environment variable back
|
||||
set -l env_file (mktemp -t gemini_context.XXXXXX)
|
||||
|
||||
# Run zsh with -e (exit on error):
|
||||
# 1. Source the context manager
|
||||
# 2. Run the requested command with arguments
|
||||
# 3. Write the resulting GEMINI_CLI_HOME to the temp file
|
||||
command zsh -ec "
|
||||
source '$gemini_zsh_script'
|
||||
$argv
|
||||
echo \"\$GEMINI_CLI_HOME\" > '$env_file'
|
||||
"
|
||||
set -l zsh_status $status
|
||||
|
||||
# Only sync environment and clean up on success
|
||||
if test $zsh_status -eq 0
|
||||
set -l new_home (cat $env_file | string trim)
|
||||
if test -n "$new_home"
|
||||
set -gx GEMINI_CLI_HOME "$new_home"
|
||||
else
|
||||
set -e GEMINI_CLI_HOME
|
||||
end
|
||||
end
|
||||
|
||||
rm -f $env_file
|
||||
return $zsh_status
|
||||
end
|
||||
|
||||
# Wrapper functions
|
||||
function gemini-context-use
|
||||
_gemini_context_bridge "gemini-context-use $argv"
|
||||
end
|
||||
|
||||
function gemini-context-create
|
||||
_gemini_context_bridge "gemini-context-create $argv"
|
||||
end
|
||||
|
||||
function gemini-context-list
|
||||
_gemini_context_bridge "gemini-context-list $argv"
|
||||
end
|
||||
|
||||
function gemini-context-delete
|
||||
_gemini_context_bridge "gemini-context-delete $argv"
|
||||
end
|
||||
|
||||
function gemini-context-rename
|
||||
_gemini_context_bridge "gemini-context-rename $argv"
|
||||
end
|
||||
|
||||
function gemini-context-edit
|
||||
_gemini_context_bridge "gemini-context-edit $argv"
|
||||
end
|
||||
|
||||
function gemini-context-current
|
||||
_gemini_context_bridge "gemini-context-current $argv"
|
||||
end
|
||||
|
||||
function gemini-context-unset
|
||||
_gemini_context_bridge "gemini-context-unset $argv"
|
||||
end
|
||||
|
||||
# Aliases
|
||||
alias gemctx='gemini-context-use'
|
||||
|
||||
# Completion
|
||||
function _gemini_context_list
|
||||
zsh -c "source '$gemini_zsh_script'; _gemini_context_list_internal"
|
||||
end
|
||||
|
||||
complete -c gemini-context-use -f -a "(_gemini_context_list)"
|
||||
complete -c gemctx -f -a "(_gemini_context_list)"
|
||||
complete -c gemini-context-edit -f -a "(_gemini_context_list)"
|
||||
complete -c gemini-context-delete -f -a "(_gemini_context_list)"
|
||||
complete -c gemini-context-rename -f -a "(_gemini_context_list)"
|
||||
@@ -30,5 +30,10 @@ if status --is-interactive
|
||||
install_fisher
|
||||
end
|
||||
|
||||
# Want this at the bottom to put this path first
|
||||
# Want these at the bottom to put them first in PATH
|
||||
fish_add_path --move --path {$HOME}/bin
|
||||
if test (uname) = "Darwin"
|
||||
fish_add_path --move --path {$HOME}/bin/macos
|
||||
else if test (uname) = "Linux"
|
||||
fish_add_path --move --path {$HOME}/bin/linux
|
||||
end
|
||||
|
||||
@@ -10,7 +10,7 @@ uv_venv_auto = true
|
||||
[tools]
|
||||
age = "latest"
|
||||
usage = "latest"
|
||||
uv = "latest"
|
||||
uv = "0.11.8"
|
||||
|
||||
[hooks]
|
||||
postinstall = "mise sync python --uv"
|
||||
|
||||
@@ -51,3 +51,4 @@ fi
|
||||
"""
|
||||
style = "bold blue"
|
||||
format = "♊[$output](blue) "
|
||||
shell = ["/bin/sh", "-c"]
|
||||
|
||||
@@ -19,14 +19,17 @@
|
||||
[difftool]
|
||||
prompt = false
|
||||
|
||||
[difftool "difftastic"]
|
||||
cmd = difft "$LOCAL" "$REMOTE"
|
||||
|
||||
[alias]
|
||||
st = status
|
||||
last = log -1 HEAD
|
||||
# Thanks to
|
||||
# http://durdn.com/blog/2012/11/22/must-have-git-aliases-advanced-examples/
|
||||
logs = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate
|
||||
logs = log --pretty=format:"%C(yellow)%h%Cred%d %Creset%s%Cblue [%cn]" --decorate
|
||||
lg = log -p
|
||||
ll = log --pretty=format:"%C(yellow)%h%Cred%d\\ %Creset%s%Cblue\\ [%cn]" --decorate --numstat
|
||||
ll = log --pretty=format:"%C(yellow)%h%Cred%d %Creset%s%Cblue [%cn]" --decorate --numstat
|
||||
files = ls-files
|
||||
ls = ls-files
|
||||
lol = log --graph --pretty=format:'%C(yellow)%h%Creset %an: %s - %Creset %C(yellow)%d%Creset %Cblue(%cr)%Creset' --abbrev-commit --date=relative
|
||||
@@ -92,8 +95,12 @@
|
||||
process = git-lfs filter-process
|
||||
|
||||
[include]
|
||||
path = ~/.gitconfig.d/aliases
|
||||
path = ~/.gitconfig.d/override
|
||||
path = ~/.gitconfig.d/local
|
||||
|
||||
[includeIf "gitdir:~/personal/"]
|
||||
[includeIf "gitdir/i:~/personal/"]
|
||||
path = ~/.gitconfig.d/personal
|
||||
|
||||
[rerere]
|
||||
enabled = true
|
||||
|
||||
9
dotfiles/gitconfig.d/aliases
Normal file
9
dotfiles/gitconfig.d/aliases
Normal file
@@ -0,0 +1,9 @@
|
||||
[alias]
|
||||
commit-assumed = "!f() { \
|
||||
file=\"$1\"; \
|
||||
shift; \
|
||||
git update-index --no-assume-unchanged \"$file\" && \
|
||||
git add \"$file\" && \
|
||||
git commit \"$@\" && \
|
||||
git update-index --assume-unchanged \"$file\"; \
|
||||
}; f"
|
||||
102
dotfiles/shenv
102
dotfiles/shenv
@@ -15,6 +15,7 @@ export DEBEMAIL="david@systemoverlord.com"
|
||||
export DEBFULLNAME="David Tomaschik"
|
||||
export LESS="-MR"
|
||||
export QUOTING_STYLE="literal" # Coreutils quotes
|
||||
export HOMEBREW_NO_ENV_HINTS=1
|
||||
|
||||
# Fix gnome-terminal
|
||||
if [ "$TERM" = "xterm" ] && [ "$COLORTERM" = "gnome-terminal" ] ; then
|
||||
@@ -97,31 +98,91 @@ 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. fresh SSH login: sshd sets SSH_AUTH_SOCK to the raw forwarded socket before ssh/rc
|
||||
# rewrites it to the stable symlink; the shell inherits the original raw path).
|
||||
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. Only look for a system agent if the stable link is already broken. If the link is
|
||||
# valid (e.g. a tmux pane where SSH_AUTH_SOCK points to our symlink which ssh/rc just
|
||||
# updated to the forwarded socket), leave it alone — don't clobber it with a local agent.
|
||||
if [ -z "${_CANDIDATE}" ] && [ ! -S "${_SSH_AUTH_LINK}" ]; 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 candidate and the link is broken.
|
||||
if [ ! -S "${_CANDIDATE}" ] && [ ! -S "${_SSH_AUTH_LINK}" ]; 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/
|
||||
@@ -133,6 +194,9 @@ if [ "$(uname)" = "Darwin" ] ; then
|
||||
# Using id -u for better POSIX compatibility than $UID
|
||||
export XDG_RUNTIME_DIR="${XDG_RUNTIME_DIR:-$TMPDIR/runtime-$(id -u)}"
|
||||
export XDG_STATE_HOME="${XDG_STATE_HOME:-$HOME/.local/state}"
|
||||
export PATH="${HOME}/bin/macos:${PATH}"
|
||||
elif [ "$(uname)" = "Linux" ] ; then
|
||||
export PATH="${HOME}/bin/linux:${PATH}"
|
||||
fi
|
||||
|
||||
if test -e "$HOME/.localenv"; then
|
||||
|
||||
@@ -2,19 +2,19 @@
|
||||
|
||||
# Roughly based on this article:
|
||||
# https://werat.github.io/2017/02/04/tmux-ssh-agent-forwarding.html
|
||||
#
|
||||
# NOTE: this file is executed by sshd as a child process, NOT sourced by the
|
||||
# user's shell. Any variable assignments or exports here have no effect on the
|
||||
# shell environment the user will land in.
|
||||
|
||||
REMOTE_LINK="${HOME}/.ssh/ssh_auth_sock"
|
||||
|
||||
if [ -S "${SSH_AUTH_SOCK}" ] ; then
|
||||
SSH_REMOTE_AUTH_SOCK="${SSH_AUTH_SOCK}"
|
||||
export SSH_REMOTE_AUTH_SOCK
|
||||
# Always update the symlink to the latest session's socket.
|
||||
# This ensures that tmux (which uses the static path) always points to a
|
||||
# current agent.
|
||||
mkdir -p "$(dirname "${REMOTE_LINK}")"
|
||||
ln -sf "${SSH_AUTH_SOCK}" "${REMOTE_LINK}"
|
||||
SSH_AUTH_SOCK="${REMOTE_LINK}"
|
||||
export SSH_AUTH_SOCK
|
||||
fi
|
||||
|
||||
# if stdin is a tty, don't do the cookie step
|
||||
|
||||
@@ -45,7 +45,7 @@ set -g window-status-current-style fg=colour235,bg=colour33,bold
|
||||
set -g status-interval 60
|
||||
set -g status-left-length 30
|
||||
set -g status-left '/#h: #S/ '
|
||||
set -g status-right '#{?pane_title,/#{pane_title}/ ,}#(cut -d " " -f 1-3 /proc/loadavg)#[default] #[fg=colour166]%H:%M#[default]'
|
||||
set -g status-right '#{?pane_title,/#{pane_title}/ ,}#(uptime | rev | cut -d":" -f1 | rev | sed s/,//g)#[default] #[fg=colour166]%H:%M#[default]'
|
||||
|
||||
# Advanced mouse mode from http://tangledhelix.com/blog/2012/07/16/tmux-and-mouse-mode/
|
||||
# Toggle mouse on
|
||||
@@ -65,8 +65,9 @@ bind M \
|
||||
display 'Mouse: OFF'
|
||||
|
||||
# tmux X clipboard integration
|
||||
bind C-c run "tmux show-buffer | xsel -i -b"
|
||||
bind C-v run "tmux set-buffer -- \"$(xsel -o -b)\"; tmux paste-buffer"
|
||||
if-shell 'test "$(uname)" = "Darwin"' \
|
||||
'bind C-c run "tmux show-buffer | pbcopy"; bind C-v run "tmux set-buffer -- \"$(pbpaste)\"; tmux paste-buffer"' \
|
||||
'bind C-c run "tmux show-buffer | xsel -i -b"; bind C-v run "tmux set-buffer -- \"$(xsel -o -b)\"; tmux paste-buffer"'
|
||||
|
||||
# List of plugins
|
||||
set -g @plugin 'tmux-plugins/tpm'
|
||||
|
||||
@@ -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)"
|
||||
@@ -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]
|
||||
@@ -1,11 +0,0 @@
|
||||
#
|
||||
# weechat -- charset.conf
|
||||
#
|
||||
|
||||
[default]
|
||||
decode = "iso-8859-1"
|
||||
encode = ""
|
||||
|
||||
[decode]
|
||||
|
||||
[encode]
|
||||
@@ -1,11 +0,0 @@
|
||||
#
|
||||
# weechat -- exec.conf
|
||||
#
|
||||
|
||||
[command]
|
||||
default_options = ""
|
||||
purge_delay = 0
|
||||
|
||||
[color]
|
||||
flag_finished = lightred
|
||||
flag_running = lightgreen
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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]
|
||||
@@ -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]
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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"
|
||||
@@ -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
|
||||
@@ -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}"
|
||||
@@ -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
|
||||
@@ -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
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
# For interactive shells
|
||||
[[ -n "$ZSH_PROFILE" ]] && {
|
||||
zshrc_start_time=$(date +%s.%N)
|
||||
zmodload zsh/datetime
|
||||
zshrc_start_time=$EPOCHREALTIME
|
||||
zmodload zsh/zprof
|
||||
}
|
||||
HISTFILE=~/.zhistory
|
||||
@@ -184,6 +185,9 @@ have_command() {
|
||||
if test -d ${HOME}/.local/bin ; then
|
||||
export PATH="${HOME}/.local/bin:${PATH}"
|
||||
fi
|
||||
if test -d ${HOME}/.npm-packages/bin ; then
|
||||
export PATH="${HOME}/.npm-packages/bin:${PATH}"
|
||||
fi
|
||||
|
||||
# Source extras and aliases if interactive
|
||||
if [[ $- == *i* ]] ; then
|
||||
@@ -191,6 +195,15 @@ if [[ $- == *i* ]] ; then
|
||||
source_if_existing $HOME/.aliases.local
|
||||
# zsh-only-ism to avoid error if glob doesn't expand
|
||||
# specifically sets NULLGLOB for this one glob
|
||||
typeset -gA _deferred_comps
|
||||
compdef() {
|
||||
# Store the arguments: first arg is the function, the rest are the commands
|
||||
local func=$1
|
||||
shift
|
||||
for cmd in "$@"; do
|
||||
_deferred_comps[$cmd]=$func
|
||||
done
|
||||
}
|
||||
for file in $HOME/.zshrc.d/[a-zA-Z0-9]*.zsh(N) ; do
|
||||
source "$file"
|
||||
done
|
||||
@@ -205,19 +218,27 @@ if [[ $- == *i* ]] ; then
|
||||
zstyle ':completion:*' users root ${USER}
|
||||
# Modules after fpath
|
||||
autoload -Uz compinit
|
||||
for cmd func in "${(@kv)_deferred_comps}"; do
|
||||
compdef "$func" "$cmd"
|
||||
done
|
||||
|
||||
unset _deferred_comps
|
||||
|
||||
# Regenerate zcompdump if it's older than any file in fpath
|
||||
DUMPFILE="${ZDOTDIR:-$HOME}/.zcompdump"
|
||||
updated_files=(${^fpath}(N.om[1]))
|
||||
# Find the newest file across all fpath directories to detect edits/additions
|
||||
# (N.om[1]) = Null-glob, plain files only, sort by mtime, pick the first (newest)
|
||||
local newest_comp=(${^fpath}/*(N.om[1]))
|
||||
|
||||
if [[ ! -f "$DUMPFILE" || ( ${#updated_files} -gt 0 && "$updated_files[1]" -nt "$DUMPFILE" ) ]]; then
|
||||
compinit -i -D "$DUMPFILE"
|
||||
# Asynchronously compile the dump file
|
||||
{ zcompile "$DUMPFILE" } &!
|
||||
# If any completion file was modified, or dump doesn't exist, we might need to update.
|
||||
if [[ ! -f "$DUMPFILE" || ( -n "$newest_comp" && "$newest_comp" -nt "$DUMPFILE" ) ]]; then
|
||||
compinit -i -d "$DUMPFILE"
|
||||
# Asynchronously compile the dump file with an atomic rename
|
||||
{ zcompile "$DUMPFILE.zwc.tmp" "$DUMPFILE" && mv -f "$DUMPFILE.zwc.tmp" "$DUMPFILE.zwc" } &!
|
||||
else
|
||||
compinit -C -i -D "$DUMPFILE"
|
||||
compinit -C -i -d "$DUMPFILE"
|
||||
fi
|
||||
unset DUMPFILE updated_files
|
||||
unset DUMPFILE newest_comp
|
||||
autoload -Uz promptinit && promptinit
|
||||
# Virtualenvwrapper
|
||||
source_first_existing \
|
||||
@@ -267,8 +288,13 @@ if [ -x /usr/bin/ack-grep ] ; then
|
||||
alias ack='/usr/bin/ack-grep'
|
||||
fi
|
||||
|
||||
# I want this first always
|
||||
# I want these first always
|
||||
PATH="${HOME}/bin:${PATH}"
|
||||
if [[ "$(uname)" == "Darwin" ]]; then
|
||||
PATH="${HOME}/bin/macos:${PATH}"
|
||||
elif [[ "$(uname)" == "Linux" ]]; then
|
||||
PATH="${HOME}/bin/linux:${PATH}"
|
||||
fi
|
||||
|
||||
# Load any local settings
|
||||
source_if_existing $HOME/.zshrc.local
|
||||
@@ -292,9 +318,9 @@ fi
|
||||
typeset -U PATH
|
||||
|
||||
if [[ -n "$ZSH_PROFILE" ]]; then
|
||||
zshrc_end_time=$(date +%s.%N)
|
||||
elapsed_seconds=$(echo "$zshrc_end_time - $zshrc_start_time" | bc -l)
|
||||
elapsed_ms=$(printf "%.0f" "$(echo "$elapsed_seconds * 1000" | bc -l)")
|
||||
echo "zshrc done: ${elapsed_ms}ms"
|
||||
zshrc_end_time=$EPOCHREALTIME
|
||||
# Calculation in ms using zsh floating point math
|
||||
elapsed_ms=$(( (zshrc_end_time - zshrc_start_time) * 1000 ))
|
||||
printf "zshrc done: %.0fms\n" "$elapsed_ms"
|
||||
zprof
|
||||
fi
|
||||
|
||||
@@ -18,8 +18,15 @@ alert() {
|
||||
icon="error"
|
||||
fi
|
||||
|
||||
# Send the notification with the executed command
|
||||
notify-send --urgency=low -i "$icon" "Finished: '$@'"
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
# macOS notification
|
||||
local title="Finished: '$*'"
|
||||
local msg="Exit code: $ret"
|
||||
osascript -e "display notification \"$msg\" with title \"$title\""
|
||||
else
|
||||
# Send the notification with the executed command
|
||||
notify-send --urgency=low -i "$icon" "Finished: '$@'"
|
||||
fi
|
||||
|
||||
# Return the original exit code
|
||||
return $ret
|
||||
|
||||
@@ -1,7 +1,12 @@
|
||||
ANDROID_HOME=$HOME/Library/Android/sdk
|
||||
if [ "$(uname)" = "Darwin" ]; then
|
||||
ANDROID_HOME=$HOME/Library/Android/sdk
|
||||
else
|
||||
ANDROID_HOME=$HOME/Android/Sdk
|
||||
fi
|
||||
|
||||
if test -d $ANDROID_HOME ; then
|
||||
PATH=$PATH:$ANDROID_HOME/emulator:$ANDROID_HOME/platform-tools
|
||||
if test -d "${ANDROID_HOME}" ; then
|
||||
export ANDROID_HOME
|
||||
PATH="${PATH}:${ANDROID_HOME}/emulator:${ANDROID_HOME}/platform-tools"
|
||||
else
|
||||
unset ANDROID_HOME
|
||||
fi
|
||||
|
||||
@@ -6,7 +6,11 @@ if have_command nasm && have_command objdump ; then
|
||||
local TMPF=`mktemp`
|
||||
local bytes
|
||||
local byte
|
||||
$NASM -f elf -o $TMPF $1
|
||||
local format="elf"
|
||||
if [[ "$OSTYPE" == darwin* ]]; then
|
||||
format="macho64"
|
||||
fi
|
||||
$NASM -f $format -o $TMPF $1
|
||||
$OBJDUMP -M intel -d $TMPF | grep '^ ' | cut -f2 | while read -A bytes ; do
|
||||
for byte in $bytes ; do
|
||||
echo -n "\\\\x$byte"
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
function dumpenv {
|
||||
tr '\0' '\n' < /proc/${1}/environ
|
||||
if [ "$(uname)" = "Linux" ]; then
|
||||
tr '\0' '\n' < /proc/${1}/environ
|
||||
elif [ "$(uname)" = "Darwin" ]; then
|
||||
# macOS doesn't have /proc, use ps instead.
|
||||
# Note: this may truncate if environment is very large.
|
||||
ps -p ${1} -wwwe -o command= | tr ' ' '\n' | grep '='
|
||||
fi
|
||||
}
|
||||
|
||||
if test -x "/sbin/starship" ; then
|
||||
|
||||
@@ -7,7 +7,7 @@ export GEMINI_CONTEXT_DIR="${XDG_CONFIG_HOME:-$HOME/.config}/gemini"
|
||||
mkdir -p "$GEMINI_CONTEXT_DIR"
|
||||
|
||||
# Template settings file
|
||||
GEMINI_TEMPLATE_SETTINGS="${HOME}/.skel/dotfiles/config/gemini/settings.json"
|
||||
GEMINI_TEMPLATE_SETTINGS="${GEMINI_CONTEXT_DIR}/settings.json"
|
||||
|
||||
# Create a new Gemini context
|
||||
gemini-context-create() {
|
||||
@@ -19,8 +19,13 @@ gemini-context-create() {
|
||||
local context_name="$1"
|
||||
local context_path="$GEMINI_CONTEXT_DIR/$context_name"
|
||||
|
||||
if [[ "$context_name" =~ [/] ]]; then
|
||||
echo "Error: Context name cannot contain slashes."
|
||||
if [[ "$context_name" =~ [^a-zA-Z0-9_-] ]]; then
|
||||
echo "Error: Context name should only contain alphanumeric characters, underscores, or dashes."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "$context_name" == .* ]]; then
|
||||
echo "Error: Context name cannot start with a dot."
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -42,25 +47,90 @@ gemini-context-create() {
|
||||
echo "Context '$context_name' created."
|
||||
}
|
||||
|
||||
# List available Gemini contexts
|
||||
# List available Gemini contexts (directories only, containing .gemini)
|
||||
_gemini_context_list_internal() {
|
||||
command ls "$GEMINI_CONTEXT_DIR" 2>/dev/null
|
||||
local contexts
|
||||
# Use Zsh globbing: find directories containing a .gemini subdir
|
||||
contexts=($GEMINI_CONTEXT_DIR/*/.gemini(N/:h:t))
|
||||
[[ ${#contexts} -gt 0 ]] && print -l "${contexts[@]}"
|
||||
}
|
||||
|
||||
gemini-context-list() {
|
||||
echo "Available Gemini contexts:"
|
||||
local contexts=$(_gemini_context_list_internal)
|
||||
if [ -z "$contexts" ]; then
|
||||
local contexts=($(_gemini_context_list_internal))
|
||||
if [ ${#contexts} -eq 0 ]; then
|
||||
echo " (No contexts found)"
|
||||
return
|
||||
fi
|
||||
for context in $contexts; do
|
||||
if [ -d "$GEMINI_CONTEXT_DIR/$context" ]; then
|
||||
echo " $context"
|
||||
for context in "${contexts[@]}"; do
|
||||
if [ "$GEMINI_CLI_HOME" = "$GEMINI_CONTEXT_DIR/$context" ]; then
|
||||
echo " * $context (active)"
|
||||
else
|
||||
echo " $context"
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# Delete a Gemini context
|
||||
gemini-context-delete() {
|
||||
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 DELETE: ")
|
||||
[[ -z "$context_name" ]] && return 1
|
||||
else
|
||||
echo "Usage: gemini-context-delete <name>"
|
||||
return 1
|
||||
fi
|
||||
else
|
||||
context_name="$1"
|
||||
fi
|
||||
|
||||
local context_path="$GEMINI_CONTEXT_DIR/$context_name"
|
||||
if [ ! -d "$context_path" ]; then
|
||||
echo "Error: Context '$context_name' not found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if read -q "confirm?Are you sure you want to delete context '$context_name'? [y/N] "; then
|
||||
echo
|
||||
rm -rf "$context_path"
|
||||
echo "Context '$context_name' deleted."
|
||||
if [ "$GEMINI_CLI_HOME" = "$context_path" ]; then
|
||||
gemini-context-unset
|
||||
fi
|
||||
else
|
||||
echo "\nDeletion cancelled."
|
||||
fi
|
||||
}
|
||||
|
||||
# Rename a Gemini context
|
||||
gemini-context-rename() {
|
||||
if [ -z "$1" ] || [ -z "$2" ]; then
|
||||
echo "Usage: gemini-context-rename <old_name> <new_name>"
|
||||
return 1
|
||||
fi
|
||||
|
||||
local old_path="$GEMINI_CONTEXT_DIR/$1"
|
||||
local new_path="$GEMINI_CONTEXT_DIR/$2"
|
||||
|
||||
if [ ! -d "$old_path" ]; then
|
||||
echo "Error: Source context '$1' not found."
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ -d "$new_path" ]; then
|
||||
echo "Error: Destination context '$2' already exists."
|
||||
return 1
|
||||
fi
|
||||
|
||||
mv "$old_path" "$new_path"
|
||||
echo "Context '$1' renamed to '$2'."
|
||||
if [ "$GEMINI_CLI_HOME" = "$old_path" ]; then
|
||||
gemini-context-use -q "$2"
|
||||
fi
|
||||
}
|
||||
|
||||
# Use a specific Gemini context
|
||||
gemini-context-use() {
|
||||
local context_name
|
||||
@@ -89,14 +159,13 @@ gemini-context-use() {
|
||||
|
||||
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
|
||||
if [ ! -d "$context_path/.gemini" ]; then
|
||||
[[ "$quiet" -eq 0 ]] && echo "Error: '$context_name' is not a valid Gemini context (missing .gemini directory)."
|
||||
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)"
|
||||
[[ "$quiet" -eq 0 ]] && echo "Switched to Gemini context '$context_name'"
|
||||
}
|
||||
|
||||
# Edit a context's settings
|
||||
@@ -136,13 +205,12 @@ gemini-context-edit() {
|
||||
# Show the current Gemini context
|
||||
gemini-context-current() {
|
||||
if [ -n "$GEMINI_CLI_HOME" ]; then
|
||||
local current_context=$(basename "$GEMINI_CLI_HOME")
|
||||
local current_context=${GEMINI_CLI_HOME:t}
|
||||
if [ "$GEMINI_CONTEXT_DIR/$current_context" = "$GEMINI_CLI_HOME" ]; then
|
||||
echo "Current Gemini context: $current_context"
|
||||
else
|
||||
echo "Current Gemini context: Custom"
|
||||
echo "Current Gemini context: Custom ($GEMINI_CLI_HOME)"
|
||||
fi
|
||||
echo "GEMINI_CLI_HOME=$GEMINI_CLI_HOME"
|
||||
else
|
||||
echo "No Gemini context set, using default."
|
||||
fi
|
||||
@@ -157,12 +225,12 @@ gemini-context-unset() {
|
||||
# Alias for gemini-context-use
|
||||
alias gemctx='gemini-context-use'
|
||||
|
||||
# Zsh Completion for gemini-context-use and gemctx
|
||||
# Zsh Completion
|
||||
_gemini_contexts() {
|
||||
local contexts
|
||||
local -a 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
|
||||
|
||||
compdef _gemini_contexts gemini-context-use gemctx gemini-context-edit gemini-context-delete gemini-context-rename
|
||||
|
||||
|
||||
@@ -1,8 +1,20 @@
|
||||
test -f /usr/share/source-highlight/src-hilite-lesspipe.sh && \
|
||||
# Find src-hilite-lesspipe.sh
|
||||
_SRCHILITE=""
|
||||
for _p in /usr/share/source-highlight/src-hilite-lesspipe.sh /opt/homebrew/bin/src-hilite-lesspipe.sh /usr/local/bin/src-hilite-lesspipe.sh ; do
|
||||
if [ -f "$_p" ] ; then
|
||||
_SRCHILITE="$_p"
|
||||
break
|
||||
fi
|
||||
done
|
||||
|
||||
if [ -n "$_SRCHILITE" ] ; then
|
||||
function srcless {
|
||||
if [ $# -ne 1 ] ; then
|
||||
echo "$0 <what>" > /dev/stderr
|
||||
echo "Usage: srcless <file>" > /dev/stderr
|
||||
return 1
|
||||
fi
|
||||
/usr/share/source-highlight/src-hilite-lesspipe.sh $1 | less -R
|
||||
"$_SRCHILITE" "$1" | less -R
|
||||
}
|
||||
fi
|
||||
|
||||
unset _SRCHILITE _p
|
||||
|
||||
@@ -3,6 +3,17 @@
|
||||
# Skelify -- move a file to my .skel and setup symlinks
|
||||
|
||||
function skelify {
|
||||
local -A opts
|
||||
zparseopts -D -A opts -overlay:
|
||||
|
||||
local overlay_name="${opts[--overlay]}"
|
||||
local base_skel_dir="${HOME}/.skel/dotfiles"
|
||||
local extra_args=()
|
||||
if [[ -n "${overlay_name}" ]]; then
|
||||
base_skel_dir="${HOME}/.skel/dotfile_overlays/${overlay_name}"
|
||||
extra_args=(--overlay "${overlay_name}")
|
||||
fi
|
||||
|
||||
local target
|
||||
local whichdir
|
||||
local relhome
|
||||
@@ -10,16 +21,19 @@ function skelify {
|
||||
local fulltarget
|
||||
for target in $~@; do
|
||||
if test -d ${target} ; then
|
||||
skelify ${target}/* || return 1
|
||||
skelify "${extra_args[@]}" ${target}/* || return 1
|
||||
elif test -f ${target} ; then
|
||||
if ! whichdir=$(cd $(dirname $target) && pwd); then
|
||||
echo Could not find directory for $target >/dev/stderr
|
||||
return 1
|
||||
fi
|
||||
fname=$(basename ${target})
|
||||
relhome=${whichdir#${HOME}/}
|
||||
fulltarget="${whichdir}/${fname}"
|
||||
if [[ ${relhome} == ${whichdir} ]] ; then
|
||||
if [[ ${whichdir} == ${HOME} ]] ; then
|
||||
relhome=""
|
||||
elif [[ ${whichdir} == ${HOME}/* ]] ; then
|
||||
relhome=${whichdir#${HOME}/}
|
||||
else
|
||||
echo ${whichdir} is not in home >/dev/stderr
|
||||
return 1
|
||||
fi
|
||||
@@ -32,7 +46,7 @@ function skelify {
|
||||
return 1
|
||||
fi
|
||||
echo ${target}
|
||||
local skeldir="${HOME}/.skel/dotfiles/${relhome}"
|
||||
local skeldir="${base_skel_dir}/${relhome}"
|
||||
mkdir -p "${skeldir}"
|
||||
mv ${target} "${skeldir}/${fname}"
|
||||
ln -s "${skeldir}/${fname}" "${fulltarget}"
|
||||
|
||||
56
dotfiles/zshrc.d/util.zsh
Normal file
56
dotfiles/zshrc.d/util.zsh
Normal file
@@ -0,0 +1,56 @@
|
||||
# utility function to "open" a file
|
||||
o() {
|
||||
if [[ "$OSTYPE" == "darwin"* ]]; then
|
||||
open "$@"
|
||||
elif [[ "$OSTYPE" == "linux-gnu"* ]]; then
|
||||
xdg-open "$@"
|
||||
else
|
||||
echo "Unknown OS"
|
||||
fi
|
||||
}
|
||||
|
||||
# Copy from stdin to the system clipboard
|
||||
syscopy() {
|
||||
if command -v pbcopy >/dev/null 2>&1; then
|
||||
# macOS
|
||||
pbcopy "$@"
|
||||
elif command -v wl-copy >/dev/null 2>&1; then
|
||||
# Linux Wayland
|
||||
wl-copy "$@"
|
||||
elif command -v xclip >/dev/null 2>&1; then
|
||||
# Linux X11
|
||||
xclip -selection clipboard "$@"
|
||||
elif command -v xsel >/dev/null 2>&1; then
|
||||
# Linux X11 (alternative)
|
||||
xsel --clipboard --input "$@"
|
||||
elif command -v clip.exe >/dev/null 2>&1; then
|
||||
# Windows WSL
|
||||
clip.exe "$@"
|
||||
else
|
||||
echo "Error: No clipboard utility found. Please install pbcopy, wl-copy, xclip, or xsel." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
# Paste from the system clipboard to stdout
|
||||
syspaste() {
|
||||
if command -v pbpaste >/dev/null 2>&1; then
|
||||
# macOS
|
||||
pbpaste "$@"
|
||||
elif command -v wl-paste >/dev/null 2>&1; then
|
||||
# Linux Wayland
|
||||
wl-paste "$@"
|
||||
elif command -v xclip >/dev/null 2>&1; then
|
||||
# Linux X11
|
||||
xclip -selection clipboard -o "$@"
|
||||
elif command -v xsel >/dev/null 2>&1; then
|
||||
# Linux X11 (alternative)
|
||||
xsel --clipboard --output "$@"
|
||||
elif command -v powershell.exe >/dev/null 2>&1; then
|
||||
# Windows WSL
|
||||
powershell.exe -noprofile -command Get-Clipboard "$@"
|
||||
else
|
||||
echo "Error: No clipboard utility found. Please install pbpaste, wl-paste, xclip, or xsel." >&2
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
@@ -229,7 +229,7 @@ install_main() {
|
||||
# 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" --no-lock
|
||||
brew bundle install --file="${BASEDIR}/Brewfile"
|
||||
fi
|
||||
|
||||
[[ "$INSTALL_KEYS" = 1 ]] && install_keys
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
anthropic.claude-code
|
||||
bazelbuild.vscode-bazel
|
||||
dnut.rewrap-revived
|
||||
docker.docker
|
||||
formulahendry.code-runner
|
||||
github.vscode-codeql
|
||||
golang.go
|
||||
hverlin.mise-vscode
|
||||
kilocode.Kilo-Code
|
||||
ms-azuretools.vscode-containers
|
||||
ms-azuretools.vscode-docker
|
||||
ms-python.black-formatter
|
||||
|
||||
Reference in New Issue
Block a user