fix(lint): fix all sonarcloud detected issues (#279)

* fix(ci): replace broad permissions with specific scopes in workflows

Replace read-all/write-all with minimum required permission scopes
across all GitHub Actions workflows to follow the principle of least
privilege (SonarCloud rule githubactions:S8234).

* fix(shell): use [[ instead of [ for conditional tests

Replace single brackets with double brackets in bash conditional
expressions across 14 files (28 changes). All scripts use bash
shebangs so [[ is safe everywhere (SonarCloud rule shelldre:S7688).

* fix(shell): add explicit return statements to functions

Add return 0 as the last statement in ~46 shell functions across
17 files that previously relied on implicit return codes
(SonarCloud rule shelldre:S7682).

* fix(shell): assign positional parameters to local variables

Replace direct $1/$2/$3 usage with named local variables in _log(),
msg(), msg_err(), msg_done(), msg_run(), msg_ok(), and array_diff()
(SonarCloud rule shelldre:S7679).

* fix(python): replace dict() constructor with literal

Use {} instead of dict() for empty dictionary initialization
(SonarCloud rule python:S7498).

* fix(shell): fix husky shebang and tolerate npm outdated exit code

* docs(shell): add function docstring comments

* fix(shell): fix heredoc indentation in x-sonarcloud

* feat(python): add ruff linter and formatter configuration

* fix(ci): align megalinter config with biome, ruff, and shfmt settings

* fix(ci): disable black and yaml-prettier in megalinter config

* chore(ci): update ruff-pre-commit to v0.15.0 and fix hook name

* fix(scripts): check for .git dir before skipping clone in install-fonts

* fix(shell): address code review issues in scripts and shared.sh

- Guard wezterm show-keys failure in create-wezterm-keymaps.sh
- Stop masking git failures with return 0 in install-cheat-purebashbible.sh
- Add missing shared.sh source in install-xcode-cli-tools.sh
- Replace exit 1 with return 1 in sourced shared.sh

* fix(scripts): address code review and security findings

- Guard wezterm show-keys failure in create-wezterm-keymaps.sh
- Stop masking git failures with return 0 in install-cheat-purebashbible.sh
- Add missing shared.sh source in install-xcode-cli-tools.sh
- Replace exit 1 with return 1 in sourced shared.sh
- Remove shell=True subprocess calls in x-git-largest-files.py

* style(shell): apply shfmt formatting and add args to pre-commit hook

* fix(python): suppress bandit false positives in x-git-largest-files

* fix(python): add nosemgrep suppression for check_output call

* feat(format): add prettier for YAML formatting

Install prettier, add .prettierrc.json config (200-char width, 2-space
indent, LF endings), .prettierignore, yarn scripts (lint:prettier,
fix:prettier, format:yaml), and pre-commit hook scoped to YAML files.

* style(yaml): apply prettier formatting

* fix(scripts): address remaining code review findings

- Python: use list comprehension to filter empty strings instead of
  slicing off the last element
- create-wezterm-keymaps: write to temp file and mv for atomic updates
- install-xcode-cli-tools: fix shellcheck source directive path

* fix(python): sort imports alphabetically in x-git-largest-files

* fix(lint): disable PYTHON_ISORT in MegaLinter, ruff handles it

* chore(git): add __pycache__ to gitignore

* fix(python): rename ambiguous variable l to line (E741)

* style: remove trailing whitespace and blank lines

* style(fzf): apply shfmt formatting

* style(shell): apply shfmt formatting

* docs(plans): add design documents

* style(docs): add language specifier to fenced code block

* feat(lint): add markdown-table-formatter to dev tooling

Add markdown-table-formatter as a dev dependency with yarn scripts
(lint:md-table, fix:md-table) and a local pre-commit hook to
automatically format markdown tables on commit.
This commit is contained in:
2026-02-07 19:01:02 +02:00
committed by GitHub
parent cff3d1dd8a
commit 6d72003446
86 changed files with 1264 additions and 425 deletions

View File

@@ -93,13 +93,13 @@ expand-main:
# Note that not all layouts respond to this command.
increase-main:
mod: mod1
key: ','
key: ","
# Decrease the number of windows in the main pane.
# Note that not all layouts respond to this command.
decrease-main:
mod: mod1
key: '.'
key: "."
# General purpose command for custom layouts.
# Functionality is layout-dependent.

View File

@@ -150,6 +150,7 @@ commit()
git commit -a -m "$commitMessage"
}
# Run Laravel scheduler in a loop
scheduler()
{
while :; do

View File

@@ -7,65 +7,67 @@ To be used with a companion fish function like this:
"""
from __future__ import print_function
import json
import os
import signal
import subprocess
import sys
import traceback
BASH = 'bash'
BASH = "bash"
FISH_READONLY = [
'PWD', 'SHLVL', 'history', 'pipestatus', 'status', 'version',
'FISH_VERSION', 'fish_pid', 'hostname', '_', 'fish_private_mode'
"PWD",
"SHLVL",
"history",
"pipestatus",
"status",
"version",
"FISH_VERSION",
"fish_pid",
"hostname",
"_",
"fish_private_mode",
]
IGNORED = [
'PS1', 'XPC_SERVICE_NAME'
]
IGNORED = ["PS1", "XPC_SERVICE_NAME"]
def ignored(name):
if name == 'PWD': # this is read only, but has special handling
if name == "PWD": # this is read only, but has special handling
return False
# ignore other read only variables
if name in FISH_READONLY:
return True
if name in IGNORED or name.startswith("BASH_FUNC"):
return True
if name.startswith('%'):
return True
return False
return name.startswith("%")
def escape(string):
# use json.dumps to reliably escape quotes and backslashes
return json.dumps(string).replace(r'$', r'\$')
return json.dumps(string).replace(r"$", r"\$")
def escape_identifier(word):
return escape(word.replace('?', '\\?'))
return escape(word.replace("?", "\\?"))
def comment(string):
return '\n'.join(['# ' + line for line in string.split('\n')])
return "\n".join(["# " + line for line in string.split("\n")])
def gen_script():
# Use the following instead of /usr/bin/env to read environment so we can
# deal with multi-line environment variables (and other odd cases).
env_reader = "%s -c 'import os,json; print(json.dumps({k:v for k,v in os.environ.items()}))'" % (sys.executable)
args = [BASH, '-c', env_reader]
env_reader = f"{sys.executable} -c 'import os,json; print(json.dumps({{k:v for k,v in os.environ.items()}}))'"
args = [BASH, "-c", env_reader]
output = subprocess.check_output(args, universal_newlines=True)
old_env = output.strip()
pipe_r, pipe_w = os.pipe()
if sys.version_info >= (3, 4):
os.set_inheritable(pipe_w, True)
command = 'eval $1 && ({}; alias) >&{}'.format(
env_reader,
pipe_w
)
args = [BASH, '-c', command, 'bass', ' '.join(sys.argv[1:])]
os.set_inheritable(pipe_w, True)
command = f"eval $1 && ({env_reader}; alias) >&{pipe_w}"
args = [BASH, "-c", command, "bass", " ".join(sys.argv[1:])]
p = subprocess.Popen(args, universal_newlines=True, close_fds=False)
os.close(pipe_w)
with os.fdopen(pipe_r) as f:
@@ -73,9 +75,7 @@ def gen_script():
alias_str = f.read()
if p.wait() != 0:
raise subprocess.CalledProcessError(
returncode=p.returncode,
cmd=' '.join(sys.argv[1:]),
output=new_env + alias_str
returncode=p.returncode, cmd=" ".join(sys.argv[1:]), output=new_env + alias_str
)
new_env = new_env.strip()
@@ -89,41 +89,41 @@ def gen_script():
continue
v1 = old_env.get(k)
if not v1:
script_lines.append(comment('adding %s=%s' % (k, v)))
script_lines.append(comment(f"adding {k}={v}"))
elif v1 != v:
script_lines.append(comment('updating %s=%s -> %s' % (k, v1, v)))
script_lines.append(comment(f"updating {k}={v1} -> {v}"))
# process special variables
if k == 'PWD':
script_lines.append('cd %s' % escape(v))
if k == "PWD":
script_lines.append(f"cd {escape(v)}")
continue
else:
continue
if k == 'PATH':
value = ' '.join([escape(directory)
for directory in v.split(':')])
if k == "PATH": # noqa: SIM108
value = " ".join([escape(directory) for directory in v.split(":")])
else:
value = escape(v)
script_lines.append('set -g -x %s %s' % (k, value))
script_lines.append(f"set -g -x {k} {value}")
for var in set(old_env.keys()) - set(new_env.keys()):
script_lines.append(comment('removing %s' % var))
script_lines.append('set -e %s' % var)
script_lines.append(comment(f"removing {var}"))
script_lines.append(f"set -e {var}")
script = '\n'.join(script_lines)
script = "\n".join(script_lines)
alias_lines = []
for line in alias_str.splitlines():
_, rest = line.split(None, 1)
k, v = rest.split("=", 1)
alias_lines.append("alias " + escape_identifier(k) + "=" + v)
alias = '\n'.join(alias_lines)
alias = "\n".join(alias_lines)
return script + '\n' + alias
return script + "\n" + alias
script_file = os.fdopen(3, 'w')
script_file = os.fdopen(3, "w")
if not sys.argv[1:]:
print('__bass_usage', file=script_file, end='')
print("__bass_usage", file=script_file, end="")
sys.exit(0)
try:
@@ -131,8 +131,8 @@ try:
except subprocess.CalledProcessError as e:
sys.exit(e.returncode)
except Exception:
print('Bass internal error!', file=sys.stderr)
raise # traceback will output to stderr
print("Bass internal error!", file=sys.stderr)
raise # traceback will output to stderr
except KeyboardInterrupt:
signal.signal(signal.SIGINT, signal.SIG_DFL)
os.kill(os.getpid(), signal.SIGINT)

View File

@@ -8,8 +8,8 @@ function fisher --argument-names cmd --description "A plugin manager for Fish"
echo "fisher, version $fisher_version"
case "" -h --help
echo "Usage: fisher install <plugins...> Install plugins"
echo " fisher remove <plugins...> Remove installed plugins"
echo " fisher uninstall <plugins...> Remove installed plugins (alias)"
echo " fisher remove <plugins...> Remove installed plugins"
echo " fisher uninstall <plugins...> Remove installed plugins (alias)"
echo " fisher update <plugins...> Update installed plugins"
echo " fisher update Update all installed plugins"
echo " fisher list [<regex>] List installed plugins matching regex"
@@ -41,7 +41,7 @@ function fisher --argument-names cmd --description "A plugin manager for Fish"
echo "fisher: \"$fish_plugins\" file not found: \"$cmd\"" >&2 && return 1
end
set arg_plugins $file_plugins
else if test "$cmd" = install && ! set --query old_plugins[1]
else if test "$cmd" = install && ! set --query old_plugins[1]
set --append arg_plugins $file_plugins
end

View File

@@ -58,4 +58,3 @@ fish_pager_color_progress 737994
fish_pager_color_prefix f4b8e4
fish_pager_color_completion c6d0f5
fish_pager_color_description 737994

View File

@@ -58,4 +58,3 @@ fish_pager_color_progress 6e738d
fish_pager_color_prefix f5bde6
fish_pager_color_completion cad3f5
fish_pager_color_description 6e738d

View File

@@ -58,4 +58,3 @@ fish_pager_color_progress 6c7086
fish_pager_color_prefix f5c2e7
fish_pager_color_completion cdd6f4
fish_pager_color_description 6c7086

View File

@@ -13,32 +13,37 @@
if [[ $- =~ i ]]; then
# To use custom commands instead of find, override _fzf_compgen_{path,dir}
if ! declare -f _fzf_compgen_path >/dev/null; then
_fzf_compgen_path() {
if ! declare -f _fzf_compgen_path > /dev/null; then
_fzf_compgen_path()
{
echo "$1"
command find -L "$1" \
-name .git -prune -o -name .hg -prune -o -name .svn -prune -o \( -type d -o -type f -o -type l \) \
-a -not -path "$1" -print 2>/dev/null | sed 's@^\./@@'
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
}
fi
if ! declare -f _fzf_compgen_dir >/dev/null; then
_fzf_compgen_dir() {
if ! declare -f _fzf_compgen_dir > /dev/null; then
_fzf_compgen_dir()
{
command find -L "$1" \
-name .git -prune -o -name .hg -prune -o -name .svn -prune -o -type d \
-a -not -path "$1" -print 2>/dev/null | sed 's@^\./@@'
-a -not -path "$1" -print 2> /dev/null | sed 's@^\./@@'
}
fi
###########################################################
# To redraw line after fzf closes (printf '\e[5n')
bind '"\e[0n": redraw-current-line' 2>/dev/null
bind '"\e[0n": redraw-current-line' 2> /dev/null
__fzf_comprun() {
__fzf_comprun()
{
if [[ "$(type -t _fzf_comprun 2>&1)" = function ]]; then
_fzf_comprun "$@"
elif [[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; }; then
elif [[ -n "${TMUX_PANE-}" ]] && {
[[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]
}; then
shift
fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- "$@"
else
@@ -47,7 +52,8 @@ if [[ $- =~ i ]]; then
fi
}
__fzf_orig_completion() {
__fzf_orig_completion()
{
local l comp f cmd
while read -r l; do
if [[ "$l" =~ ^(.*\ -F)\ *([^ ]*).*\ ([^ ]*)$ ]]; then
@@ -63,7 +69,8 @@ if [[ $- =~ i ]]; then
done
}
_fzf_opts_completion() {
_fzf_opts_completion()
{
local cur prev opts
COMPREPLY=()
cur="${COMP_WORDS[COMP_CWORD]}"
@@ -112,18 +119,18 @@ if [[ $- =~ i ]]; then
--sync"
case "${prev}" in
--tiebreak)
COMPREPLY=($(compgen -W "length begin end index" -- "$cur"))
return 0
;;
--color)
COMPREPLY=($(compgen -W "dark light 16 bw" -- "$cur"))
return 0
;;
--history)
COMPREPLY=()
return 0
;;
--tiebreak)
COMPREPLY=($(compgen -W "length begin end index" -- "$cur"))
return 0
;;
--color)
COMPREPLY=($(compgen -W "dark light 16 bw" -- "$cur"))
return 0
;;
--history)
COMPREPLY=()
return 0
;;
esac
if [[ "$cur" =~ ^-|\+ ]]; then
@@ -134,7 +141,8 @@ if [[ $- =~ i ]]; then
return 0
}
_fzf_handle_dynamic_completion() {
_fzf_handle_dynamic_completion()
{
local cmd orig_var orig ret orig_cmd orig_complete
cmd="$1"
shift
@@ -142,15 +150,15 @@ if [[ $- =~ i ]]; then
orig_var="_fzf_orig_completion_$cmd"
orig="${!orig_var-}"
orig="${orig##*#}"
if [[ -n "$orig" ]] && type "$orig" >/dev/null 2>&1; then
if [[ -n "$orig" ]] && type "$orig" > /dev/null 2>&1; then
$orig "$@"
elif [[ -n "${_fzf_completion_loader-}" ]]; then
orig_complete=$(complete -p "$orig_cmd" 2>/dev/null)
orig_complete=$(complete -p "$orig_cmd" 2> /dev/null)
_completion_loader "$@"
ret=$?
# _completion_loader may not have updated completion for the command
if [[ "$(complete -p "$orig_cmd" 2>/dev/null)" != "$orig_complete" ]]; then
__fzf_orig_completion < <(complete -p "$orig_cmd" 2>/dev/null)
if [[ "$(complete -p "$orig_cmd" 2> /dev/null)" != "$orig_complete" ]]; then
__fzf_orig_completion < <(complete -p "$orig_cmd" 2> /dev/null)
if [[ "${__fzf_nospace_commands-}" = *" $orig_cmd "* ]]; then
eval "${orig_complete/ -F / -o nospace -F }"
else
@@ -161,7 +169,8 @@ if [[ $- =~ i ]]; then
fi
}
__fzf_generic_path_completion() {
__fzf_generic_path_completion()
{
local cur base dir leftover matches trigger cmd
cmd="${COMP_WORDS[0]}"
if [[ $cmd == \\* ]]; then
@@ -207,7 +216,8 @@ if [[ $- =~ i ]]; then
fi
}
_fzf_complete() {
_fzf_complete()
{
# Split arguments around --
local args rest str_arg i sep
args=("$@")
@@ -231,7 +241,7 @@ if [[ $- =~ i ]]; then
local cur selected trigger cmd post
post="$(caller 0 | awk '{print $2}')_post"
type -t "$post" >/dev/null 2>&1 || post=cat
type -t "$post" > /dev/null 2>&1 || post=cat
cmd="${COMP_WORDS[0]//[^A-Za-z0-9_=]/_}"
trigger=${FZF_COMPLETION_TRIGGER-'**'}
@@ -253,50 +263,59 @@ if [[ $- =~ i ]]; then
fi
}
_fzf_path_completion() {
_fzf_path_completion()
{
__fzf_generic_path_completion _fzf_compgen_path "-m" "" "$@"
}
# Deprecated. No file only completion.
_fzf_file_completion() {
_fzf_file_completion()
{
_fzf_path_completion "$@"
}
_fzf_dir_completion() {
_fzf_dir_completion()
{
__fzf_generic_path_completion _fzf_compgen_dir "" "/" "$@"
}
_fzf_complete_kill() {
_fzf_complete_kill()
{
_fzf_proc_completion "$@"
}
_fzf_proc_completion() {
_fzf_proc_completion()
{
_fzf_complete -m --header-lines=1 --preview 'echo {}' --preview-window down:3:wrap --min-height 15 -- "$@" < <(
command ps -eo user,pid,ppid,start,time,command 2>/dev/null ||
command ps -eo user,pid,ppid,time,args # For BusyBox
command ps -eo user,pid,ppid,start,time,command 2> /dev/null \
|| command ps -eo user,pid,ppid,time,args # For BusyBox
)
}
_fzf_proc_completion_post() {
_fzf_proc_completion_post()
{
awk '{print $2}'
}
_fzf_host_completion() {
_fzf_host_completion()
{
_fzf_complete +m -- "$@" < <(
command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2>/dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?%]') \
command cat <(command tail -n +1 ~/.ssh/config ~/.ssh/config.d/* /etc/ssh/ssh_config 2> /dev/null | command grep -i '^\s*host\(name\)\? ' | awk '{for (i = 2; i <= NF; i++) print $1 " " $i}' | command grep -v '[*?%]') \
<(command grep -oE '^[[a-z0-9.,:-]+' ~/.ssh/known_hosts | tr ',' '\n' | tr -d '[' | awk '{ print $1 " " $1 }') \
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') |
awk '{if (length($2) > 0) {print $2}}' | sort -u
<(command grep -v '^\s*\(#\|$\)' /etc/hosts | command grep -Fv '0.0.0.0') \
| awk '{if (length($2) > 0) {print $2}}' | sort -u
)
}
_fzf_var_completion() {
_fzf_var_completion()
{
_fzf_complete -m -- "$@" < <(
declare -xp | sed -En 's|^declare [^ ]+ ([^=]+).*|\1|p'
)
}
_fzf_alias_completion() {
_fzf_alias_completion()
{
_fzf_complete -m -- "$@" < <(
alias | sed -En 's|^alias ([^=]+).*|\1|p'
)
@@ -321,13 +340,14 @@ if [[ $- =~ i ]]; then
svn tar unzip zip"
# Preserve existing completion
__fzf_orig_completion < <(complete -p $d_cmds $a_cmds 2>/dev/null)
__fzf_orig_completion < <(complete -p $d_cmds $a_cmds 2> /dev/null)
if type _completion_loader >/dev/null 2>&1; then
if type _completion_loader > /dev/null 2>&1; then
_fzf_completion_loader=1
fi
__fzf_defc() {
__fzf_defc()
{
local cmd func opts orig_var orig def
cmd="$1"
func="$2"
@@ -354,22 +374,23 @@ if [[ $- =~ i ]]; then
unset cmd d_cmds a_cmds
_fzf_setup_completion() {
_fzf_setup_completion()
{
local kind fn cmd
kind=$1
fn=_fzf_${1}_completion
if [[ $# -lt 2 ]] || ! type -t "$fn" >/dev/null; then
if [[ $# -lt 2 ]] || ! type -t "$fn" > /dev/null; then
echo "usage: ${FUNCNAME[0]} path|dir|var|alias|host|proc COMMANDS..."
return 1
fi
shift
__fzf_orig_completion < <(complete -p "$@" 2>/dev/null)
__fzf_orig_completion < <(complete -p "$@" 2> /dev/null)
for cmd in "$@"; do
case "$kind" in
dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
var) __fzf_defc "$cmd" "$fn" "-o default -o nospace -v" ;;
alias) __fzf_defc "$cmd" "$fn" "-a" ;;
*) __fzf_defc "$cmd" "$fn" "-o default -o bashdefault" ;;
dir) __fzf_defc "$cmd" "$fn" "-o nospace -o dirnames" ;;
var) __fzf_defc "$cmd" "$fn" "-o default -o nospace -v" ;;
alias) __fzf_defc "$cmd" "$fn" "-a" ;;
*) __fzf_defc "$cmd" "$fn" "-o default -o bashdefault" ;;
esac
done
}

View File

@@ -4,7 +4,7 @@
# Auto-completion
# ---------------
# shellcheck source=completion.bash
[[ $- == *i* ]] && source "$HOME/.dotfiles/config/fzf/completion.bash" 2>/dev/null
[[ $- == *i* ]] && source "$HOME/.dotfiles/config/fzf/completion.bash" 2> /dev/null
# Key bindings
# ------------

View File

@@ -13,7 +13,8 @@
# Key bindings
# ------------
__fzf_select__() {
__fzf_select__()
{
local cmd opts
cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type f -print \
@@ -21,27 +22,32 @@ __fzf_select__() {
-o -type l -print 2> /dev/null | cut -b3-"}"
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse ${FZF_DEFAULT_OPTS-} ${FZF_CTRL_T_OPTS-} -m"
# shellcheck disable=SC2091 # Intentionally execute output of __fzfcmd
eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" |
while read -r item; do
eval "$cmd" | FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" \
| while read -r item; do
printf '%q ' "$item" # escape special chars
done
}
if [[ $- =~ i ]]; then
__fzfcmd() {
[[ -n "${TMUX_PANE-}" ]] && { [[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]; } &&
echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
__fzfcmd()
{
[[ -n "${TMUX_PANE-}" ]] && {
[[ "${FZF_TMUX:-0}" != 0 ]] || [[ -n "${FZF_TMUX_OPTS-}" ]]
} \
&& echo "fzf-tmux ${FZF_TMUX_OPTS:--d${FZF_TMUX_HEIGHT:-40%}} -- " || echo "fzf"
}
fzf-file-widget() {
fzf-file-widget()
{
local selected
selected="$(__fzf_select__ "$@")"
READLINE_LINE="${READLINE_LINE:0:$READLINE_POINT}$selected${READLINE_LINE:$READLINE_POINT}"
READLINE_POINT=$((READLINE_POINT + ${#selected}))
}
__fzf_cd__() {
__fzf_cd__()
{
local cmd opts dir
cmd="${FZF_ALT_C_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
-o -type d -print 2> /dev/null | cut -b3-"}"
@@ -53,16 +59,17 @@ if [[ $- =~ i ]]; then
) && printf 'builtin cd -- %q' "$dir"
}
__fzf_history__() {
__fzf_history__()
{
local output opts script
opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore ${FZF_DEFAULT_OPTS-} -n2..,.. --scheme=history --bind=ctrl-r:toggle-sort ${FZF_CTRL_R_OPTS-} +m --read0"
script='BEGIN { getc; $/ = "\n\t"; $HISTCOUNT = $ENV{last_hist} + 1 } s/^[ *]//; print $HISTCOUNT - $. . "\t$_" if !$seen{$_}++'
# shellcheck disable=SC2091 # Intentionally execute output of __fzfcmd
output=$(
set +o pipefail
builtin fc -lnr -2147483648 |
last_hist=$(HISTTIMEFORMAT='' builtin history 1) perl -n -l0 -e "$script" |
FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) --query "$READLINE_LINE"
builtin fc -lnr -2147483648 \
| last_hist=$(HISTTIMEFORMAT='' builtin history 1) perl -n -l0 -e "$script" \
| FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) --query "$READLINE_LINE"
) || return
READLINE_LINE=${output#*$'\t'}
if [[ -z "$READLINE_POINT" ]]; then

View File

@@ -52,4 +52,4 @@ keybindings:
prs: []
repoPaths: {}
pager:
diff: ''
diff: ""

View File

@@ -1,3 +1,3 @@
---
git_protocol: https
version: '1'
version: "1"

View File

@@ -1,4 +1,4 @@
#!/bin/env bash
#!/usr/bin/env bash
[ -z "$NVM_DIR" ] && export NVM_DIR="$HOME/.config/nvm"
[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh" # This loads nvm
[[ -z "$NVM_DIR" ]] && export NVM_DIR="$HOME/.config/nvm"
[[ -s "$NVM_DIR/nvm.sh" ]] && \. "$NVM_DIR/nvm.sh" # This loads nvm

View File

@@ -5,7 +5,7 @@
# shellcheck shell=bash
# Defaults
[ -z "$DOTFILES" ] && export DOTFILES="$HOME/.dotfiles"
[[ -z "$DOTFILES" ]] && export DOTFILES="$HOME/.dotfiles"
DOTFILES_CURRENT_SHELL=$(basename "$SHELL")
export DOTFILES_CURRENT_SHELL
@@ -15,7 +15,7 @@ VERBOSE="${VERBOSE:-0}"
DEBUG="${DEBUG:-0}"
# Enable debugging with DEBUG=1
[ "${DEBUG:-0}" -eq 1 ] && set -x
[[ "${DEBUG:-0}" -eq 1 ]] && set -x
# Detect the current shell
CURRENT_SHELL=$(ps -p $$ -ocomm= | awk -F/ '{print $NF}')
@@ -33,9 +33,10 @@ x-path-prepend()
;;
*)
echo "Unsupported shell: $CURRENT_SHELL"
exit 1
return 1
;;
esac
return 0
}
# Function to set environment variables based on the shell
@@ -52,9 +53,10 @@ x-set-env()
;;
*)
echo "Unsupported shell: $CURRENT_SHELL"
exit 1
return 1
;;
esac
return 0
}
# Explicitly set XDG folders, if not already set
@@ -74,7 +76,7 @@ x-path-prepend "$DOTFILES/local/bin"
x-path-prepend "$XDG_BIN_HOME"
# Custom completion paths
[ -z "$ZSH_CUSTOM_COMPLETION_PATH" ] && export ZSH_CUSTOM_COMPLETION_PATH="$XDG_CONFIG_HOME/zsh/completion"
[[ -z "$ZSH_CUSTOM_COMPLETION_PATH" ]] && export ZSH_CUSTOM_COMPLETION_PATH="$XDG_CONFIG_HOME/zsh/completion"
x-dc "$ZSH_CUSTOM_COMPLETION_PATH"
export FPATH="$ZSH_CUSTOM_COMPLETION_PATH:$FPATH"
@@ -83,7 +85,8 @@ if ! declare -f msg > /dev/null; then
# $1 - message (string)
msg()
{
[ "$VERBOSE" -eq 1 ] && msgr msg "$1"
local message="$1"
[[ "$VERBOSE" -eq 1 ]] && msgr msg "$message"
return 0
}
msg "msg was not defined, defined it now"
@@ -95,7 +98,8 @@ if ! declare -f msg_err > /dev/null; then
# $1 - error message (string)
msg_err()
{
msgr err "$1" >&2
local message="$1"
msgr err "$message" >&2
exit 1
}
fi
@@ -106,7 +110,8 @@ if ! declare -f msg_done > /dev/null; then
# $1 - message (string)
msg_done()
{
msgr "done" "$1"
local message="$1"
msgr "done" "$message"
return 0
}
fi
@@ -117,7 +122,8 @@ if ! declare -f msg_run > /dev/null; then
# $1 - message (string)
msg_run()
{
msgr run "$1"
local message="$1"
msgr run "$message"
return 0
}
fi
@@ -128,7 +134,8 @@ if ! declare -f msg_ok > /dev/null; then
# $1 - message (string)
msg_ok()
{
msgr ok "$1"
local message="$1"
msgr ok "$message"
return 0
}
fi
@@ -143,12 +150,16 @@ if ! declare -f array_diff > /dev/null; then
# Source: https://stackoverflow.com/a/42399479/594940
array_diff()
{
local result_var="$1"
local arr1_name="$2"
local arr2_name="$3"
# shellcheck disable=SC1083,SC2086
eval local ARR1=\(\"\${$2[@]}\"\)
eval local ARR1=\(\"\${${arr1_name}[@]}\"\)
# shellcheck disable=SC1083,SC2086
eval local ARR2=\(\"\${$3[@]}\"\)
eval local ARR2=\(\"\${${arr2_name}[@]}\"\)
local IFS=$'\n'
mapfile -t "$1" < <(comm -23 <(echo "${ARR1[*]}" | sort) <(echo "${ARR2[*]}" | sort))
mapfile -t "$result_var" < <(comm -23 <(echo "${ARR1[*]}" | sort) <(echo "${ARR2[*]}" | sort))
return 0
}
fi

View File

@@ -7,13 +7,13 @@ DEFAULT_NAME="main"
CURRENT_SESSION=$(tmux display-message -p "#{session_name}")
# Check that the session has a name
if [ "$CURRENT_SESSION" = "#{session_name}" ] || [ "$CURRENT_SESSION" = "0" ]; then
if [[ "$CURRENT_SESSION" = "#{session_name}" ]] || [[ "$CURRENT_SESSION" = "0" ]]; then
# Check if the default name is already in use
if tmux has-session -t "$DEFAULT_NAME" 2> /dev/null; then
# Query the user for a new name
echo "Session name '$DEFAULT_NAME' is already in use. Enter a new name:"
read -r NEW_NAME
while tmux has-session -t "$NEW_NAME" 2> /dev/null || [ -z "$NEW_NAME" ]; do
while tmux has-session -t "$NEW_NAME" 2> /dev/null || [[ -z "$NEW_NAME" ]]; do
echo "Name '$NEW_NAME' is invalid or already in use. Enter a new name:"
read -r NEW_NAME
done

View File

@@ -8,12 +8,14 @@
set -euo pipefail
# Fall back to native tmux session picker if sesh is not installed
if ! command -v sesh &>/dev/null; then
if ! command -v sesh &> /dev/null; then
tmux choose-tree -Zs
exit 0
fi
pick_with_gum() {
# Pick a sesh session using gum filter
pick_with_gum()
{
sesh list -i \
| gum filter \
--limit 1 \
@@ -22,6 +24,7 @@ pick_with_gum() {
--placeholder 'Pick a sesh' \
--height 50 \
--prompt='⚡'
return 0
}
FZF_COMMON_OPTS=(
@@ -40,15 +43,23 @@ FZF_COMMON_OPTS=(
--preview 'sesh preview {}'
)
pick_with_fzf_tmux() {
# Pick a sesh session using fzf-tmux popup
pick_with_fzf_tmux()
{
sesh list --icons | fzf-tmux -p 80%,70% "${FZF_COMMON_OPTS[@]}"
return 0
}
pick_with_fzf() {
# Pick a sesh session using fzf inline
pick_with_fzf()
{
sesh list --icons | fzf "${FZF_COMMON_OPTS[@]}"
return 0
}
pick_with_select() {
# Pick a sesh session using bash select menu
pick_with_select()
{
local sessions
mapfile -t sessions < <(sesh list)
if [[ ${#sessions[@]} -eq 0 ]]; then
@@ -64,11 +75,11 @@ pick_with_select() {
}
# Cascading tool detection
if command -v gum &>/dev/null; then
if command -v gum &> /dev/null; then
selection=$(pick_with_gum)
elif command -v fzf-tmux &>/dev/null; then
elif command -v fzf-tmux &> /dev/null; then
selection=$(pick_with_fzf_tmux)
elif command -v fzf &>/dev/null; then
elif command -v fzf &> /dev/null; then
selection=$(pick_with_fzf)
else
selection=$(pick_with_select)