Skip to content

Commit a63d9eb

Browse files
committed
refactor: remove redundant hyde-shell
TODO: make all scripts use [[ "${HYDE_SHELL_INIT}" -ne 1 ]] && eval "$(hyde-shell init)" this initiates hyde-shell if and only if it is not yet set.
1 parent 2eb0201 commit a63d9eb

File tree

10 files changed

+740
-1
lines changed

10 files changed

+740
-1
lines changed

Configs/.local/bin/hyde-shell

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,26 @@ HYDE_SCRIPTS_PATH="${HYDE_SCRIPTS_PATH:-${XDG_CONFIG_HOME:-$HOME/.config}/hyde/s
1717

1818
export BIN_DIR LIB_DIR SHARE_DIR PATH HYDE_SCRIPTS_PATH
1919

20+
initialized() {
21+
cat <<EOF
22+
HYDE_SHELL_INIT=1
23+
BIN_DIR="${BIN_DIR}"
24+
LIB_DIR="${LIB_DIR}"
25+
SHARE_DIR="${SHARE_DIR}"
26+
PATH=${PATH}
27+
HYDE_SCRIPTS_PATH=${HYDE_SCRIPTS_PATH}
28+
export BIN_DIR LIB_DIR SHARE_DIR PATH HYDE_SCRIPTS_PATH HYDE_SHELL_INIT
29+
EOF
30+
cat "${LIB_DIR}/hyde/globalcontrol.sh"
31+
}
32+
33+
# If args is init or --init, print initialization script
34+
if [[ "$1" == "init" || "$1" == "--init" ]]; then
35+
initialized
36+
exit 0
37+
else
38+
export HYDE_SHELL_INIT=1
39+
fi
2040
# shellcheck disable=SC1091
2141
if ! source "${LIB_DIR}/hyde/globalcontrol.sh"; then
2242
echo "Error: Could not load HyDE, broken installation?"
@@ -459,4 +479,4 @@ if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
459479
;;
460480
esac
461481

462-
fi
482+
fi
Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
1+
from pathlib import Path
2+
import argparse
3+
4+
class XDGPaths:
5+
def __init__(self):
6+
import os
7+
self.HOME = str(Path.home())
8+
self.xdg_cache = os.environ.get("XDG_CACHE_HOME", os.path.join(self.HOME, ".cache"))
9+
self.xdg_config = os.environ.get("XDG_CONFIG_HOME", os.path.join(self.HOME, ".config"))
10+
self.xdg_runtime = os.environ.get("XDG_RUNTIME_DIR", os.path.join(self.HOME, ".local/share"))
11+
self.xdg_data = os.environ.get("XDG_DATA_HOME", os.path.join(self.HOME, ".local/share"))
12+
self.CACHE_DIR = os.path.join(self.xdg_cache, "hyde")
13+
self.CONFIG_DIR = os.path.join(self.xdg_config, "hyde")
14+
self.RUNTIME_DIR = os.path.join(self.xdg_runtime, "hyde")
15+
self.DATA_DIR = os.path.join(self.xdg_data, "hyde")
16+
self.RECENT_FILE = os.path.join(self.CACHE_DIR, "landing/show_bookmarks.recent")
17+
self.RECENT_NUMBER = 5
18+
19+
class BookmarkManager:
20+
def __init__(self, xdg: XDGPaths):
21+
self.xdg = xdg
22+
23+
def find_bookmark_files(self):
24+
import os
25+
files = []
26+
# Firefox
27+
for root, dirs, filelist in os.walk(os.path.join(self.xdg.HOME, ".mozilla/firefox")):
28+
for file in filelist:
29+
if file == "places.sqlite":
30+
files.append(os.path.join(root, file))
31+
# Chromium/Brave/Chrome
32+
for path in [
33+
os.path.join(self.xdg.xdg_config, "BraveSoftware/Brave-Browser/Default/Bookmarks"),
34+
os.path.join(self.xdg.xdg_config, "chromium/Default/Bookmarks"),
35+
os.path.join(self.xdg.xdg_config, "google-chrome/Default/Bookmarks"),
36+
]:
37+
if os.path.exists(path):
38+
files.append(path)
39+
# Custom .lst files
40+
for path in [
41+
os.path.join(self.xdg.xdg_config, "hyde/bookmarks.lst"),
42+
]:
43+
if os.path.exists(path):
44+
files.append(path)
45+
return files
46+
47+
def read_firefox_bookmarks(self, places_file):
48+
import sqlite3
49+
import sys
50+
query = """
51+
SELECT b.title, p.url
52+
FROM moz_bookmarks AS b
53+
LEFT JOIN moz_places AS p ON b.fk = p.id
54+
WHERE b.type = 1 AND p.hidden = 0 AND b.title IS NOT NULL
55+
"""
56+
bookmarks = []
57+
try:
58+
conn = sqlite3.connect(places_file)
59+
for title, url in conn.execute(query):
60+
if not title:
61+
title = url
62+
bookmarks.append({"title": title, "url": url})
63+
conn.close()
64+
except Exception as e:
65+
print(f"Error reading Firefox bookmarks: {e}", file=sys.stderr)
66+
return bookmarks
67+
68+
def read_chromium_bookmarks(self, bookmarks_file):
69+
import json
70+
import sys
71+
bookmarks = []
72+
try:
73+
with open(bookmarks_file, "r") as f:
74+
data = json.load(f)
75+
for item in data.get("roots", {}).get("bookmark_bar", {}).get("children", []):
76+
if "url" in item:
77+
bookmarks.append({"title": item.get("name", item["url"]), "url": item["url"]})
78+
for item in data.get("roots", {}).get("other", {}).get("children", []):
79+
if "url" in item:
80+
bookmarks.append({"title": item.get("name", item["url"]), "url": item["url"]})
81+
except Exception as e:
82+
print(f"Error reading Chromium bookmarks: {e}", file=sys.stderr)
83+
return bookmarks
84+
85+
def read_custom_lst(self, lst_file):
86+
import sys
87+
bookmarks = []
88+
try:
89+
with open(lst_file, "r") as f:
90+
for line in f:
91+
line = line.strip()
92+
if not line or "|" not in line:
93+
continue
94+
title, url = [x.strip() for x in line.split("|", 1)]
95+
bookmarks.append({"title": title, "url": url})
96+
except Exception as e:
97+
print(f"Error reading custom bookmarks: {e}", file=sys.stderr)
98+
return bookmarks
99+
100+
def read_recent(self):
101+
import os
102+
import sys
103+
bookmarks = []
104+
if not os.path.exists(self.xdg.RECENT_FILE):
105+
return bookmarks
106+
try:
107+
with open(self.xdg.RECENT_FILE, "r") as f:
108+
for line in f:
109+
line = line.strip()
110+
if "|" in line:
111+
title, url = [x.strip() for x in line.split("|", 1)]
112+
bookmarks.append({"title": title, "url": url})
113+
except Exception as e:
114+
print(f"Error reading recent bookmarks: {e}", file=sys.stderr)
115+
return bookmarks
116+
117+
def save_recent(self, title, url):
118+
import os
119+
lines = [f"{title} | {url}"]
120+
if os.path.exists(self.xdg.RECENT_FILE):
121+
with open(self.xdg.RECENT_FILE, "r") as f:
122+
for line in f:
123+
line = line.strip()
124+
if line and line != lines[0]:
125+
lines.append(line)
126+
seen = set()
127+
unique_lines = []
128+
for line in lines:
129+
if line not in seen and line:
130+
unique_lines.append(line)
131+
seen.add(line)
132+
if len(unique_lines) >= self.xdg.RECENT_NUMBER:
133+
break
134+
os.makedirs(os.path.dirname(self.xdg.RECENT_FILE), exist_ok=True)
135+
with open(self.xdg.RECENT_FILE, "w") as f:
136+
for line in unique_lines:
137+
f.write(line + "\n")
138+
139+
def get_all_bookmarks(self, isCustom=True):
140+
files = self.find_bookmark_files()
141+
all_bookmarks = []
142+
for file in files:
143+
if file.endswith(".sqlite"):
144+
all_bookmarks.extend(self.read_firefox_bookmarks(file))
145+
elif file.endswith(".lst"):
146+
if isCustom:
147+
all_bookmarks.extend(self.read_custom_lst(file))
148+
else:
149+
all_bookmarks.extend(self.read_chromium_bookmarks(file))
150+
all_bookmarks.extend(self.read_recent())
151+
# Deduplicate by title and url, sort by title
152+
seen = set()
153+
unique_bookmarks = []
154+
for bm in all_bookmarks:
155+
key = (bm["title"], bm["url"])
156+
if key not in seen:
157+
unique_bookmarks.append(bm)
158+
seen.add(key)
159+
unique_bookmarks.sort(key=lambda x: x["title"].lower())
160+
return unique_bookmarks
161+
162+
def list_bookmarks(self, bookmarks):
163+
for idx, bm in enumerate(bookmarks, 1):
164+
print(f"{idx}) {bm['title']}")
165+
166+
def open_bookmark(self, url, browser=None):
167+
import subprocess
168+
if browser:
169+
subprocess.run([browser, url])
170+
else:
171+
subprocess.run(["xdg-open", url])
172+
173+
def open_by_selection(self, selection, bookmarks, browser=None):
174+
import sys
175+
# Parse index from selection string like '1) Title'
176+
try:
177+
index = int(selection.split(')', 1)[0].strip())
178+
bm = bookmarks[index - 1]
179+
self.save_recent(bm['title'], bm['url'])
180+
self.open_bookmark(bm['url'], browser)
181+
sys.exit()
182+
except Exception as e:
183+
print(f"Error: {e}", file=sys.stderr)
184+
185+
def main():
186+
parser = argparse.ArgumentParser(description="Bookmarks manager (feature parity with bookmarks.sh)")
187+
parser.add_argument('--browser', '-b', type=str, help='Set browser command (default: $BROWSER env or xdg-open)')
188+
parser.add_argument('--no-custom', action='store_true', help='Run without custom .lst bookmark files')
189+
parser.add_argument('--list', action='store_true', help='List bookmarks and exit')
190+
parser.add_argument('selection', nargs='?', type=str, help='Selected bookmark string from rofi (e.g. "1) Title")')
191+
args = parser.parse_args()
192+
193+
xdg = XDGPaths()
194+
manager = BookmarkManager(xdg)
195+
bookmarks = manager.get_all_bookmarks(isCustom=not args.no_custom)
196+
if args.selection:
197+
manager.open_by_selection(args.selection, bookmarks, args.browser)
198+
return
199+
manager.list_bookmarks(bookmarks)
200+
if args.list:
201+
import sys
202+
sys.exit(0)
203+
204+
if __name__ == "__main__":
205+
main()

Configs/.local/lib/hyde/globalcontrol.sh

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ export THEMES_DIR="${XDG_DATA_HOME}/themes"
2121

2222
#legacy hyde envs // should be deprecated
2323

24+
export scrDir="${LIB_DIR:-$HOME/.local/lib}/hyde"
2425
export confDir="${XDG_CONFIG_HOME:-$HOME/.config}"
2526
export hydeConfDir="$HYDE_CONFIG_HOME"
2627
export cacheDir="$HYDE_CACHE_HOME"
@@ -522,3 +523,11 @@ accepted_mime_types() {
522523
done
523524

524525
}
526+
527+
export -f get_hyprConf get_rofi_pos \
528+
is_hovered toml_write \
529+
get_hashmap get_aurhlpr \
530+
set_conf set_hash check_package \
531+
get_themes print_log \
532+
pkg_installed paste_string \
533+
extract_thumbnail accepted_mime_types
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#!/usr/bin/env bash
2+
3+
[[ "${HYDE_SHELL_INIT}" -ne 1 ]] && eval "$(hyde-shell init)"
4+
5+
# setup rofi configuration
6+
setup_rofi_config() {
7+
# font scale
8+
local font_scale="${ROFI_BOOKMARKS_SCALE}"
9+
[[ "${font_scale}" =~ ^[0-9]+$ ]] || font_scale=${ROFI_SCALE:-10}
10+
11+
# set font name
12+
local font_name=${ROFI_BOOKMARKS_FONT:-$ROFI_FONT}
13+
font_name=${font_name:-$(get_hyprConf "MENU_FONT")}
14+
font_name=${font_name:-$(get_hyprConf "FONT")}
15+
16+
# set rofi font override
17+
font_override="* {font: \"${font_name:-"JetBrainsMono Nerd Font"} ${font_scale}\";}"
18+
19+
# border settings
20+
local hypr_border=${hypr_border:-"$(hyprctl -j getoption decoration:rounding | jq '.int')"}
21+
local wind_border=$((hypr_border * 3 / 2))
22+
local elem_border=$((hypr_border == 0 ? 5 : hypr_border))
23+
24+
# border width
25+
local hypr_width=${hypr_width:-"$(hyprctl -j getoption general:border_size | jq '.int')"}
26+
r_override="window{border:${hypr_width}px;border-radius:${wind_border}px;}wallbox{border-radius:${elem_border}px;} element{border-radius:${elem_border}px;}"
27+
}
28+
29+
setup_rofi_config
30+
browser_name=$(basename "$(xdg-settings get default-web-browser)" .desktop)
31+
browser_name=${BROWSER:-${browser_name}}
32+
33+
rofi -modi "bookmarks:python $LIB_DIR/hyde/bookmarks.py \
34+
--list" -i \
35+
-theme-str "entry { placeholder: \" 🌐 Launch: ${browser_name} \";}" \
36+
-config "${ROFI_BOOKMARK_STYLE:-clipboard}" \
37+
-theme-str "${r_override}" \
38+
-theme-str "${font_override}" \
39+
-theme-str "window {width: 50%;}" \
40+
-show bookmarks

0 commit comments

Comments
 (0)