Skip to content
This repository was archived by the owner on Apr 22, 2025. It is now read-only.
This repository was archived by the owner on Apr 22, 2025. It is now read-only.

I love marks but they could be better #101

@CRAG666

Description

@CRAG666

First of all, what an incredible plugin. I love this plugin, it has really changed my workflow too much.
Today I had enough free time so I started creating a script to manage and improve the brands a little.
The first thing I did was make add behave like vim would, with add add a mark but if it already exists then delete it, something like a togle. The second thing was to add a small dialog box to add a mark, this is just for convenience.

The other thing I added was a kind of which key, to know what brands I have available
Another very useful thing I did was remove marks from an active window if it has a registered trademark.

I leave you the script in case these ideas can be put in the core by default, in the meantime I will use this script

#!/bin/bash

json_file="$HOME/.config/hypr/scripts/marks.json"

if [[ ! -f "$json_file" ]]; then
	echo '{"marks": []}' >"$json_file"
fi

add_mark() {
	active=$(hyprctl activewindow -j)
	if [[ -z "$active" ]]; then
		echo "No active window detected."
		return
	fi

	address=$(echo "$active" | jq -r '.address')

	if jq -e --arg address "$address" '.marks[] | select(.address == $address)' "$json_file" >/dev/null 2>&1; then
		current_mark=$(jq -r --arg address "$address" '.marks[] | select(.address == $address).mark' "$json_file")
		hyprctl dispatch scroller:marksdelete "$current_mark"
		jq --arg address "$address" 'del(.marks[] | select(.address == $address))' "$json_file" >tmp.json && mv tmp.json "$json_file"
		return
	fi

	new_mark=$(yad --entry --title="Marks" --text="Insert Mark" --no-buttons --center)
	if [[ -z "$new_mark" ]]; then
		yad --text="Not valid input." --title="Error" --center --no-buttons --timeout=3
		return
	elif [[ ${#new_mark} -ne 1 ]]; then
		yad --text="Only one character allowed." --title="Error" --center --no-buttons --timeout=3
		return
	fi

	if jq -e --arg mark "$new_mark" '.marks[] | select(.mark == $mark)' "$json_file" >/dev/null 2>&1; then
		jq --arg mark "$new_mark" 'del(.marks[] | select(.mark == $mark))' "$json_file" >tmp.json && mv tmp.json "$json_file"
		hyprctl dispatch scroller:marksdelete "$new_mark"
	fi

	title=$(echo "$active" | jq -r '.initialTitle')

	jq --arg address "$address" --arg mark "$new_mark" --arg title "$title" \
		'.marks += [{"address": $address, "mark": $mark, "title": $title}]' "$json_file" >tmp.json && mv tmp.json "$json_file"
	hyprctl dispatch scroller:marksadd "$new_mark"
}

delete_mark() {
	address=$(hyprctl activewindow -j | jq -r '.address')

	if jq -e --arg address "$address" '.marks[] | select(.address == $address)' "$json_file" >/dev/null 2>&1; then
		mark=$(jq -r --arg address "$address" '.marks[] | select(.address == $address).mark' "$json_file")
		hyprctl dispatch scroller:marksdelete "$mark"
		jq --arg address "$address" 'del(.marks[] | select(.address == $address))' "$json_file" >tmp.json && mv tmp.json "$json_file"
	fi
}

show_marks() {
	data=$(jq -r '.marks[] | [.mark, .title] | @tsv' "$json_file" 2>/dev/null)
	if [[ -z "$data" ]]; then
		wtype -k escape
		return
	fi
	yad_args=()
	while IFS=$'\t' read -r mark title; do
		yad_args+=("$mark" "$title")
	done <<<"$data"
	selected=$(yad --list \
		--title="Marks" \
		--text="Select a mark:" \
		--no-buttons \
		--center \
		--width=500 \
		--height=950 \
		--column="Mark" \
		--column="Title" \
		"${yad_args[@]}")
	if [[ -n "$selected" ]]; then
		mark=$(echo "$selected" | awk -F'|' '{print $1}')
		hyprctl dispatch scroller:marksvisit "$mark"
	fi
	wtype -k escape
}

go_mark() {
	local mark=$1
	killall -9 yad 2>/dev/null
	hyprctl dispatch scroller:marksvisit "$mark"
}

clean_marks() {
	echo '{"marks": []}' >"$json_file"
}

show_help() {
	echo "Usage: $0 -t | -d | -s | -g <mark> | -c"
	echo "  -t        Toggle mark (Add or delete mark)"
	echo "  -d        Delete a mark in current window"
	echo "  -s        Show all marks"
	echo "  -g <mark> Go to a specific mark"
	echo "  -c        Clean all marks"
	exit 1
}

while getopts "tdsg:c" opt; do
	case "$opt" in
	t) add_mark ;;
	d) delete_mark ;;
	s) show_marks ;;
	g)
		if [[ -n $OPTARG ]]; then
			go_mark "$OPTARG"
		else
			echo "Error: -g requires a mark."
			exit 1
		fi
		;;
	c) clean_marks ;;
	*) show_help ;;
	esac
done

if [[ $OPTIND -eq 1 ]]; then
	show_help
fi

hyprconfig

bind = SUPER, m, exec, ~/.config/hypr/scripts/marks -t

bind = SUPER, apostrophe, exec, ~/.config/hypr/scripts/marks -s
bind = SUPER, apostrophe, submap, marksvisit

submap = marksvisit

bind = , a, exec, ~/.config/hypr/scripts/marks -g a
bind = , b, exec, ~/.config/hypr/scripts/marks -g b
bind = , c, exec, ~/.config/hypr/scripts/marks -g c
bind = , d, exec, ~/.config/hypr/scripts/marks -g d
bind = , e, exec, ~/.config/hypr/scripts/marks -g e
bind = , f, exec, ~/.config/hypr/scripts/marks -g f
bind = , g, exec, ~/.config/hypr/scripts/marks -g g
bind = , h, exec, ~/.config/hypr/scripts/marks -g h
bind = , i, exec, ~/.config/hypr/scripts/marks -g i
bind = , j, exec, ~/.config/hypr/scripts/marks -g j
bind = , k, exec, ~/.config/hypr/scripts/marks -g k
bind = , l, exec, ~/.config/hypr/scripts/marks -g l
bind = , m, exec, ~/.config/hypr/scripts/marks -g m
bind = , n, exec, ~/.config/hypr/scripts/marks -g n
bind = , o, exec, ~/.config/hypr/scripts/marks -g o
bind = , p, exec, ~/.config/hypr/scripts/marks -g p
bind = , q, exec, ~/.config/hypr/scripts/marks -g q
bind = , r, exec, ~/.config/hypr/scripts/marks -g r
bind = , s, exec, ~/.config/hypr/scripts/marks -g s
bind = , t, exec, ~/.config/hypr/scripts/marks -g t
bind = , u, exec, ~/.config/hypr/scripts/marks -g u
bind = , v, exec, ~/.config/hypr/scripts/marks -g v
bind = , w, exec, ~/.config/hypr/scripts/marks -g w
bind = , x, exec, ~/.config/hypr/scripts/marks -g x
bind = , y, exec, ~/.config/hypr/scripts/marks -g y
bind = , z, exec, ~/.config/hypr/scripts/marks -g z
bind = , a, submap, reset
bind = , b, submap, reset
bind = , c, submap, reset
bind = , d, submap, reset
bind = , e, submap, reset
bind = , f, submap, reset
bind = , g, submap, reset
bind = , h, submap, reset
bind = , i, submap, reset
bind = , j, submap, reset
bind = , k, submap, reset
bind = , l, submap, reset
bind = , m, submap, reset
bind = , n, submap, reset
bind = , o, submap, reset
bind = , p, submap, reset
bind = , q, submap, reset
bind = , r, submap, reset
bind = , s, submap, reset
bind = , t, submap, reset
bind = , u, submap, reset
bind = , v, submap, reset
bind = , w, submap, reset
bind = , x, submap, reset
bind = , y, submap, reset
bind = , z, submap, reset
bind = , escape, submap, reset

submap = reset

bind = SUPERSHIFT, M, exec, ~/.config/hypr/scripts/marks -c && hyprctl dispatch scroller:marksreset
```

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions