forked from plibither8/ulauncher-vscode-recent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmain.py
147 lines (122 loc) · 4.44 KB
/
main.py
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
import os
import os.path
import json
import pathlib
from types import prepare_class
from ulauncher.api.client.Extension import Extension
from ulauncher.api.client.EventListener import EventListener
from ulauncher.api.shared.event import (
KeywordQueryEvent,
ItemEnterEvent,
PreferencesEvent,
PreferencesUpdateEvent,
)
from ulauncher.api.shared.item.ExtensionResultItem import ExtensionResultItem
from ulauncher.api.shared.item.ExtensionSmallResultItem import ExtensionSmallResultItem
from ulauncher.api.shared.action.RenderResultListAction import RenderResultListAction
from ulauncher.api.shared.action.HideWindowAction import HideWindowAction
from ulauncher.api.shared.action.ExtensionCustomAction import ExtensionCustomAction
from fuzzywuzzy import process, fuzz
class Utils:
@staticmethod
def get_path(filename, from_home=False):
base_dir = pathlib.Path.home() if from_home else pathlib.Path(
__file__).parent.absolute()
return os.path.join(base_dir, filename)
class Code:
open_command_paths = ["/usr/bin/code", "/bin/code", "/snap/bin/code"]
def get_installed_path(self):
for path in self.open_command_paths:
if os.path.exists(path):
return path
return False
def is_installed(self):
return bool(self.installed_path)
def get_recents(self):
recents = []
storage = json.load(
open(Utils.get_path(".config/Code/storage.json", True), "r"))
openedPaths = storage["openedPathsList"]["entries"]
for path in openedPaths:
folder = "folderUri" in path
uri = path["folderUri"] if folder else path["fileUri"]
label = path["label"] if "label" in path else uri.split("/")[-1]
recents.append({
"folder": folder,
"uri": uri,
"label": label
})
return recents
def open_vscode(self, recent):
if not self.is_installed():
return
option = "--folder-uri" if recent["folder"] else "--file-uri"
os.system(f"{self.installed_path} {option} {recent['uri']}")
def __init__(self):
self.installed_path = self.get_installed_path()
class CodeExtension(Extension):
keyword = None
code = None
def __init__(self):
super(CodeExtension, self).__init__()
self.subscribe(KeywordQueryEvent, KeywordQueryEventListener())
self.subscribe(ItemEnterEvent, ItemEnterEventListener())
self.subscribe(PreferencesEvent, PreferencesEventListener())
self.subscribe(PreferencesUpdateEvent, PreferencesUpdateEventListener())
self.code = Code()
def get_ext_result_items(self, query):
query = query.lower() if query else ""
recents = self.code.get_recents()
items = []
data = []
label_matches = process.extract(query, choices=map(lambda c: c["label"], recents), limit=20, scorer=fuzz.partial_ratio)
uri_matches = process.extract(query, choices=map(lambda c: c["uri"], recents), limit=20, scorer=fuzz.partial_ratio)
for match in label_matches:
recent = next((c for c in recents if c["label"] == match[0]), None)
if (recent is not None and match[1] > 95):
data.append(recent)
for match in uri_matches:
recent = next((c for c in recents if c["uri"] == match[0]), None)
existing = next((c for c in data if c["uri"] == recent["uri"]), None)
if (recent is not None and existing is None):
data.append(recent)
for recent in data[:20]:
items.append(
ExtensionSmallResultItem(
icon=Utils.get_path(
f"images/{'folder' if recent['folder'] else 'file'}.svg"),
name=recent["label"],
on_enter=ExtensionCustomAction(recent),
)
)
return items
class KeywordQueryEventListener(EventListener):
def on_event(self, event, extension):
items = []
if not extension.code.is_installed():
items.append(
ExtensionResultItem(
icon=Utils.get_path("images/icon.svg"),
name="No VS Code?",
description="Can't find the VS Code's `code` command in your system :(",
highlightable=False,
on_enter=HideWindowAction(),
)
)
return RenderResultListAction(items)
argument = event.get_argument() or ""
items.extend(extension.get_ext_result_items(argument))
return RenderResultListAction(items)
class ItemEnterEventListener(EventListener):
def on_event(self, event, extension):
recent = event.get_data()
extension.code.open_vscode(recent)
class PreferencesEventListener(EventListener):
def on_event(self, event, extension):
extension.keyword = event.preferences["code_kw"]
class PreferencesUpdateEventListener(EventListener):
def on_event(self, event, extension):
if event.id == "code_kw":
extension.keyword = event.new_value
if __name__ == "__main__":
CodeExtension().run()