-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathrofi-gister.py
More file actions
executable file
·116 lines (89 loc) · 4 KB
/
Copy pathrofi-gister.py
File metadata and controls
executable file
·116 lines (89 loc) · 4 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
#!/usr/bin/env python3
import os
import sys
import json
import csv
import io
import re
import configparser
from typing import Dict, Tuple, List
from subprocess import run, PIPE
# Read gists.list file
def process_gists(gists_def: Dict, gists_tree_loc: str) -> Tuple:
descs = [list(g['files'].keys())[0] + ': ' + g['description'] for g in gists_def]
locs = [os.path.join(gists_tree_loc, g['id'], list(g['files'].keys())[0]) for g in gists_def]
return(descs, locs)
# Create output for rofi dmenu
def serialize_gist_descs(gist_descs: List) -> str:
with io.StringIO() as o:
for desc in gist_descs:
o.write(desc + '\n')
options = o.getvalue()
return(options)
# Spawn selector menu
def rofi_gist_selector(gist_descs: List, gist_locs: List,
master_gist_descs: List, master_gist_locs: List) -> Tuple:
options_serialized = serialize_gist_descs(gist_descs)
# Open rofi window and get selection
rofi_proc = run(['rofi', '-dmenu', '-p', 'Gist', '-mesg', '<b>Alt+r</b>: sync | <b>Alt+s</b>: code search',
'-i', #'-no-custom',
'-format', 'i:s',
'-kb-custom-1', 'alt+r',
'-kb-custom-2', 'alt+s'],
stdout=PIPE, input=options_serialized, text=True)
rofi_output = rofi_proc.stdout
# Get index and selected text from selection
match = re.match(r"^(\-?[0-9]+):(.*)", rofi_output)
if match:
selected_index = int(match.group(1))
search_text = match.group(2)
else:
sys.exit(1)
# User selected an item, copy item to clipboard
if rofi_proc.returncode == 0 and selected_index >= 0:
selected_location = gist_locs[selected_index]
run(['xclip', '-selection', 'clipboard', selected_location])
# User requested sync, run gister.sh sync
elif rofi_proc.returncode == 10:
run([GISTER_PATH, 'sync'])
# User requested search, run gister.sh search and filter files list
elif rofi_proc.returncode == 11:
gister_proc = run([GISTER_PATH, 'search', search_text], stdout=PIPE, stderr=None, text=True)
results_lines = gister_proc.stdout.split('\n')
files = set()
for line in results_lines:
m = re.match(r"^([^:]*):", line)
if m:
file = m.group(1)
files.add(file)
# Spawn a new rofi menu with only the matching files
descs_filtered = [desc for (desc, loc) in zip(master_gist_descs, master_gist_locs) if loc in files]
locs_filtered = [loc for loc in master_gist_locs if loc in files]
return(descs_filtered, locs_filtered)
return(None, None)
def main() -> None:
# Read config file
try:
with open(os.path.join(os.environ['HOME'], '.rofi-gister'), 'r') as f:
config_data = f.read()
except FileNotFoundError:
config_data = '\n'
parser = configparser.ConfigParser()
parser.read_string('[config]\n' + config_data)
gists_dir = os.path.expanduser(parser.get('values', 'gists_dir', fallback='~/.gists'))
global GISTER_PATH
GISTER_PATH = os.path.expanduser(parser.get('values', 'gister_path', fallback='/usr/bin/gister'))
gists_desc_file = os.path.join(gists_dir, 'gists.list')
gists_tree_loc = os.path.join(gists_dir, 'tree')
# Read gister file and extract gist descriptions / locations
with open(gists_desc_file, 'r') as f:
gists_def = json.load(f)
gist_descs, gist_locs = process_gists(gists_def, gists_tree_loc)
master_gist_descs = gist_descs
master_gist_locs = gist_locs
gist_descs_filtered, gist_locs_filtered = rofi_gist_selector(gist_descs, gist_locs, master_gist_descs, master_gist_locs)
while gist_descs_filtered is not None:
gist_descs_filtered, gist_locs_filtered = rofi_gist_selector(gist_descs_filtered, gist_locs_filtered,
master_gist_descs, master_gist_locs)
if __name__=="__main__":
main()