6 Commits

7 changed files with 333 additions and 82 deletions

View File

@@ -24,7 +24,6 @@ quit-after-last-window-closed-delay = 5m
# macos-icon = custom-style
keybind = ctrl+shift+t=toggle_quick_terminal
keybind = ctrl+l=clear_screen
# Splits
keybind = super+j=goto_split:down

View File

@@ -5,7 +5,7 @@
# See https://wiki.hyprland.org/Configuring/Keywords/
$mainMod = SUPER # "Command/Windows" key as main modifier
# TODO: Use 'ALT' as window mod, need to change some tmux keybinds to do so.
$windowMod = CTRL ALT # Control + Option for window controls.
$windowMod = ALT # Control + Option for window controls.
$HYPER = ALT SHIFT SUPER CTRL
# See https://wiki.hyprland.org/Configuring/Keywords/
@@ -66,7 +66,7 @@ bindd = $mainMod, U, [U]nifi, exec,
bindd = $mainMod SHIFT, U, [U]ninstall desktop app, exec, $uninstallDesktop
bindd = $mainMod, V, Clipboard history, exec, $clipboardHistory
bindd = $mainMod, W, Close current window, killactive,
bindd = $mainMod SHIFT, W, Close all windows in active workspace, exec, $scripts/close-all-windows --active-workspace
bindd = $mainMod SHIFT, W, Close all windows in active workspace, exec, $scripts/close-windows --active-workspace
# Switch to workspaces with mainMod + [0-9]
bindd = $mainMod, 1, Switch to workspace [1], workspace, 1
@@ -142,7 +142,7 @@ bindd = $windowMod, 0, Move window to workspace 1[0], movetoworkspace, 10
bindd = $HYPER, J, Toggle split orientation, togglesplit # dwindle
bindd = $HYPER, L, [L]ock computer, exec, hyprlock
bindd = $HYPER, W, Close all windows, exec, $scripts/close-all-windows
bindd = $HYPER, W, Close all windows, exec, $scripts/close-windows --all
# Move active window to a workspace silently with HYPER + [0-9]
bindd = $HYPER, 1, Move window to workspace silent [1], movetoworkspacesilent, 1

View File

@@ -1,62 +0,0 @@
#!/usr/bin/env bash
usage() {
cat <<EOF
Close all windows for a workspace id, special workspace name, or all windows.
USAGE:
$ close-all-windows [OPTIONS] <ID (optional)>
OPTIONS:
-a | --active-workspace: Close all windows in the active workspace.
-s | --special <name>: The name of the special workspace.
-h | --help: Show this help page.
NOTE:
If no options or workspace id is passed in, it will close all windows in all workspaces.
EOF
}
special_flag="0"
workspace_name=""
workspace_id=""
windows=()
while [[ $# -gt 0 ]]; do
if [[ $1 =~ ^-s ]] || [[ $1 =~ ^--special ]]; then
shift
special_flag="1"
workspace_name=$1
elif [[ $1 =~ ^-h ]] || [[ $1 =~ ^--help ]]; then
usage && exit 0
elif [[ $1 =~ ^-a ]] || [[ $1 =~ ^--active-workspace ]]; then
workspace_id=$(hyprctl activeworkspace -j | jq -r '.id')
else
workspace_id=$1
fi
shift
done
if [[ $special_flag == "1" ]] && [[ -z $workspace_name ]]; then
echo -e "\n[ERROR]: must supply name of the special workspace.\n"
usage && exit 1
fi
if [[ -n $workspace_id ]]; then
windows+=($(hyprctl clients -j | jq -r ".[] | select(.workspace.id == $workspace_id) | .address"))
elif [[ -n $workspace_name ]]; then
windows+=($(hyprctl clients -j | jq -r ".[] | select(.workspace.name | contains(\"$workspace_name\")) | .address"))
else
windows+=($(hyprctl clients -j | jq -r ".[] | .address"))
fi
for w in ${windows[@]}; do
echo "Closing window address: $w"
hyprctl dispatch closewindow address:$w
done

132
env/.local/scripts/close-windows vendored Executable file
View File

@@ -0,0 +1,132 @@
#!/usr/bin/env bash
usage() {
cat <<EOF
Close window(s) by address or pattern mode.
USAGE:
$ $(basename ${BASH_SOURCE[0]}) [OPTIONS] [MODE] [ARG...]
MODE:
--all: Close all windows in all workspaces, any arguments are ignored.
-a | --active-workspace: Close all windows in the active workspace, any arguments are ignored.
-c | --class: Close all windows whose class contains one of the passed arguments.
-s | --special: Close all windows in special workspaces whose name matches on of the
passed in arguments, or if no arguments are supplied then it will close
all windows in all special workspaces.
OPTIONS:
--dry-run
-h | --help: Show this help page.
NOTES:
If a mode is selected all arguments are treated for that mode, meaning only one mode
runs. It does not work to mix modes / arguments.
If no modes are supplied then arguments are assumed to be window addresses and we will
close all supplied window addresses.
EOF
}
active_workspace_flag="0"
all_flag="0"
class_flag="0"
dry_run_flag="0"
special_flag="0"
args=()
addresses=()
while [[ $# -gt 0 ]]; do
if [[ $1 =~ ^-a ]] || [[ $1 =~ ^--active-workspace ]]; then
active_workspace_flag="1"
elif [[ $1 =~ ^--all ]]; then
all_flag="1"
elif [[ $1 =~ ^-c ]] || [[ $1 =~ ^--class ]]; then
class_flag="1"
elif [[ $1 =~ ^--dry-run ]]; then
dry_run_flag="1"
elif [[ $1 =~ ^-h ]] || [[ $1 =~ ^--help ]]; then
usage && exit 0
elif [[ $1 =~ ^-s ]] || [[ $1 =~ ^--special ]]; then
special_flag="1"
else
args+=($1)
fi
shift
done
log() {
if [[ $dry_run_flag == "1" ]]; then
echo "[DRY RUN]: $1"
else
echo "$1"
fi
}
_select_addresses() {
local property=$1
local pattern=$2
addresses+=("$(hyprctl clients -j | jq -r ".[] | select($property | contains(\"$pattern\")) | .address")")
}
get_special_addresses() {
# If no arguments, then we add the "special" to the pattern args, which will
# match all windows in any special workspace.
if [[ ${#args} == 0 ]]; then
args+=("special")
fi
for name in ${args[@]}; do
log "Fetching addresses for special: $name"
_select_addresses .workspace.name $name
done
}
close() {
log "Closing window address: $1"
if [[ $dry_run_flag == "0" ]]; then
hyprctl dispatch closewindow "address:$1"
fi
}
if [[ $active_workspace_flag == "1" ]]; then
# Set addresses to active workspace windows.
id=$(hyprctl activeworkspace -j | jq -r '.id')
log "Fetching addresses for active workspace: $id"
addresses+=("$(hyprctl clients -j | jq -r ".[] | select(.workspace.id == $id) | .address")")
elif [[ $all_flag == "1" ]]; then
# Set addresses to all window addresses.
addresses+=("$(hyprctl clients -j | jq -r ".[] | .address")")
elif [[ $class_flag == "1" ]]; then
# Set addresses to all windows containing the passed in classes.
for c in ${args[@]}; do
_select_addresses .class $c
done
elif [[ $special_flag == "1" ]]; then
# Set addresses to all windows in the passed in special workspaces.
get_special_addresses
else
# If no modes selected, then assume there were addresses passed in
# as args.
addresses=("$args")
fi
if [[ ${#addresses} == 0 ]]; then
log "No windows found."
exit 0
fi
for address in ${addresses[@]}; do
close $address
done

165
env/.local/scripts/window-table vendored Executable file
View File

@@ -0,0 +1,165 @@
#!/usr/bin/env bash
usage() {
cat <<EOF
Show a table with details about the currently active windows. You can choose a window and perform
an action depending on the option passed in.
USAGE:
$ $(basename ${BASH_SOURCE[0]}) [OPTIONS]
OPTIONS:
--launch: Launch in a new terminal window, user will be prompted what to do with selected window.
-c | --clip: Copy selected window's address to the system clipboard.
-x | --close: Close the selected window.
-f | --focus: Focus the selected window.
-i | --ignore: Ignore the selected window.
--show-window-class: Include window class in the table.
-h | --help: Show this page.
NOTES:
If using the 'launch' option then flags passed after the '--launch' flag will be passed into the
launched terminal, allowing you to launch with a specific mode turned on, any flags passed in prior to
'--launch' will be ignored.
EOF
}
window_class="com.ghostty.$(basename ${BASH_SOURCE[0]})"
window_padding_x="10"
clipboard_flag="0"
close_flag="0"
focus_flag="0"
ignore_flag="0"
launch_flag="0"
show_window_class_flag="0"
launch_args=()
rows=()
selected_value=""
window_data=$(hyprctl clients -j | jq 'sort_by(.workspace.name)')
while [[ $# -gt 0 ]]; do
if [[ $launch_flag == "1" ]]; then
launch_args+=("$1")
else
if [[ $1 =~ ^-c ]] || [[ $1 =~ ^--clip ]]; then
clipboard_flag="1"
elif [[ $1 =~ ^-x ]] || [[ $1 =~ ^--close ]]; then
close_flag="1"
elif [[ $1 =~ ^-f ]] || [[ $1 =~ ^--focus ]]; then
focus_flag="1"
elif [[ $1 =~ ^-h ]] || [[ $1 =~ ^--help ]]; then
usage && exit 0
elif [[ $1 =~ ^-i ]] || [[ $1 =~ ^--ignore ]]; then
ignore_flag="1"
elif [[ $1 =~ ^--launch ]]; then
launch_flag="1"
elif [[ $1 =~ ^--show-window-class ]]; then
show_window_class_flag="1"
fi
fi
shift
done
generate_rows() {
readarray -t addresses <<<"$(echo "$window_data" | jq -r '.[] | .address')"
readarray -t classes <<<$(echo "$window_data" | jq -r '.[] | .class')
readarray -t titles <<<$(echo "$window_data" | jq -r '.[] | .title')
readarray -t workspaces <<<$(echo "$window_data" | jq -r '.[] | .workspace.name')
# Zip into a new comma separated values
for i in "${!addresses[@]}"; do
if [[ $show_window_class_flag == "1" ]]; then
rows+=("${workspaces[i]}, ${titles[i]}, ${classes[i]}, ${addresses[i]}")
else
rows+=("${workspaces[i]}, ${titles[i]}, ${addresses[i]}")
fi
done
}
show_table_return_choice() {
local columns="Workspace, Title, Address"
local ret_column=3
if [[ $show_window_class_flag == "1" ]]; then
columns="Workspace, Title, Class, Address"
ret_column=4
fi
local ret=$(
printf '%s\n' "${rows[@]}" |
gum table --columns "$columns" --return-column $ret_column
)
# remove spaces and quotes from result.
ret=${ret//\"/}
ret=${ret// /}
echo "$ret"
}
ask_what_to_do_with_selection() {
choice=$(gum choose "Focus window" "Copy to clipboard" "Refresh" "Close window" "Quit")
echo "Choice: $choice"
if [[ $choice == "Quit" ]]; then
exit 0
elif [[ $choice == "Close window" ]]; then
close_flag="1"
elif [[ $choice == "Copy to clipboard" ]]; then
clipboard_flag="1"
elif [[ $choice == "Focus window" ]]; then
focus_flag="1"
elif [[ $choice == "Refresh" ]]; then
eval exec ${BASH_SOURCE[0]}
exit 0
fi
}
handle_selected_value() {
if [[ $ignore_flag == "1" ]]; then
echo "Ignore flag set, selection: '$selected_value'"
exit 0
elif [[ $clipboard_flag == "1" ]]; then
echo "Copying to clipboard, selection: $selected_value"
wl-copy $selected_value
exit 0
elif [[ $focus_flag == "1" ]]; then
echo "Focusing window, selection: $selected_value"
hyprctl dispatch focuswindow "address:$selected_value"
exit 0
elif [[ $close_flag == "1" ]]; then
echo "Closing window, selection: $selected_value"
hyprctl dispatch closewindow "address:$selected_value"
exit 0
fi
# TODO: Choose from list of what to do with the selected_value.
echo "No flag set, selection: '$selected_value'"
}
##################################################
# MAIN
##################################################
if [[ $launch_flag == "1" ]]; then
ghostty --class="$window_class" --window-padding-x="$window_padding_x" \
--keybind="q=quit" \
-e "${BASH_SOURCE[0]}" "${launch_args[@]}"
else
generate_rows
selected_value=$(show_table_return_choice)
if [[ -n $selected_value ]]; then
handle_selected_value
# If we got here then no flag was passed in initially on how to handle the
# selected window, so ask what they'd like to do. Then handle it.
echo "Asking what to do with selction."
ask_what_to_do_with_selection
[[ -n $selected_value ]] && handle_selected_value
# If you make it here, We just give up... Don't start an endless loop.
fi
fi

10
env/.tmux.conf vendored
View File

@@ -69,9 +69,10 @@ bind-key -r K kill-pane
# Use Shift-arrow keys to navigate windows.
bind -n S-Left previous-window
bind -n S-Right next-window
bind -n M-h previous-window
bind -n M-l next-window
bind C-l send-keys 'C-l'
bind h previous-window
bind l next-window
bind -n C-M-h previous-window
bind -n C-M-l next-window
bind f run-shell "tmux display-popup -E -w 80% -h 80% $SCRIPTS/tmux-sessionator"
bind-key -r C run-shell -b "~/.local/share/scripts/tmux-sessionator ~/.dotfiles"
@@ -155,5 +156,8 @@ set -gF window-status-separator "#[bg=#{@thm_bg},fg=#{@thm_overlay_0}]│"
set -g window-status-current-format " #I#{?#{!=:#{window_name},Window},: #W,} "
set -g window-status-current-style "bg=#{@thm_peach},fg=#{@thm_bg},bold"
unbind -n h
unbind -n l
# Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm'

39
gen
View File

@@ -1,6 +1,6 @@
#!/usr/bin/env bash
# Generates a new run file or webapp file.
# Generates a new run, webapp, or script file.
if [ -z "$DEV_ENV" ]; then
echo "env var DEV_ENV needs to be present"
@@ -10,6 +10,7 @@ fi
file=""
run="0"
webapp="0"
script="0"
while [[ $# -gt 0 ]]; do
echo "Arg: \"$1\""
@@ -18,6 +19,8 @@ while [[ $# -gt 0 ]]; do
run="1"
elif [[ "$1" == "webapp" ]]; then
webapp="1"
elif [[ "$1" == "script" ]]; then
script="1"
else
file="$1"
fi
@@ -26,22 +29,24 @@ done
log() { echo "$1"; }
generate-new-run() {
local dest="$DEV_ENV/runs/$file"
if [ -f "$dest" ]; then
fail_if_exists() {
if [[ -f $1 ]]; then
log "file exists: $dest"
exit 1
fi
}
generate_run() {
local dest="$DEV_ENV/runs/$file"
fail_if_exists $dest
log "Creating new run: $dest"
printf "#!/usr/bin/env bash\n\n" >$dest
printf "yay \${1:-\"-S --noconfirm\"} # packages\n" >>$dest
chmod +x $dest
}
generate-new-webapp() {
generate_webapp() {
local dest="$DEV_ENV/env/webapps/$file"
@@ -49,10 +54,7 @@ generate-new-webapp() {
dest="$dest.json"
fi
if [ -f "$dest" ]; then
log "dest exists: $dest"
exit 1
fi
fail_if_exists $dest
log "Creating new webapp: $dest"
@@ -64,6 +66,15 @@ generate-new-webapp() {
}
generate_script() {
local dest="$DEV_ENV/env/.local/scripts/$file"
fail_if_exists $dest
log "Creating new script: $dest"
printf "#!/usr/bin/env bash\n\n" >$dest
chmod +x $dest
echo $dest
}
############################## MAIN ##############################
if [[ -z "$file" ]]; then
@@ -72,10 +83,12 @@ if [[ -z "$file" ]]; then
fi
if [[ $run == "1" ]]; then
generate-new-run
generate_run
elif [[ $webapp == "1" ]]; then
generate-new-webapp
generate_webapp
elif [[ $script == "1" ]]; then
generate_script
else
log "Must supply either \"run\" or \"webapp\" option."
log "Must supply either \"run\", \"webapp\", or \"script\" option."
exit 1
fi