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 # macos-icon = custom-style
keybind = ctrl+shift+t=toggle_quick_terminal keybind = ctrl+shift+t=toggle_quick_terminal
keybind = ctrl+l=clear_screen
# Splits # Splits
keybind = super+j=goto_split:down keybind = super+j=goto_split:down

View File

@@ -5,7 +5,7 @@
# See https://wiki.hyprland.org/Configuring/Keywords/ # See https://wiki.hyprland.org/Configuring/Keywords/
$mainMod = SUPER # "Command/Windows" key as main modifier $mainMod = SUPER # "Command/Windows" key as main modifier
# TODO: Use 'ALT' as window mod, need to change some tmux keybinds to do so. # 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 $HYPER = ALT SHIFT SUPER CTRL
# See https://wiki.hyprland.org/Configuring/Keywords/ # 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 SHIFT, U, [U]ninstall desktop app, exec, $uninstallDesktop
bindd = $mainMod, V, Clipboard history, exec, $clipboardHistory bindd = $mainMod, V, Clipboard history, exec, $clipboardHistory
bindd = $mainMod, W, Close current window, killactive, 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] # Switch to workspaces with mainMod + [0-9]
bindd = $mainMod, 1, Switch to workspace [1], workspace, 1 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, J, Toggle split orientation, togglesplit # dwindle
bindd = $HYPER, L, [L]ock computer, exec, hyprlock 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] # Move active window to a workspace silently with HYPER + [0-9]
bindd = $HYPER, 1, Move window to workspace silent [1], movetoworkspacesilent, 1 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. # Use Shift-arrow keys to navigate windows.
bind -n S-Left previous-window bind -n S-Left previous-window
bind -n S-Right next-window bind -n S-Right next-window
bind -n M-h previous-window bind h previous-window
bind -n M-l next-window bind l next-window
bind C-l send-keys 'C-l' 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 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" 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-format " #I#{?#{!=:#{window_name},Window},: #W,} "
set -g window-status-current-style "bg=#{@thm_peach},fg=#{@thm_bg},bold" 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) # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf)
run '~/.tmux/plugins/tpm/tpm' run '~/.tmux/plugins/tpm/tpm'

39
gen
View File

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