-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathtoxic_typer.py
212 lines (180 loc) · 6.93 KB
/
toxic_typer.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
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
from pynput.keyboard import Controller, Key, Listener
from typing import Union
# mapping shortcut keys
KEYS_MAP = {
"Right Ctrl": Key.ctrl_r,
"Esc": Key.esc,
"Right Shift": Key.shift_r,
}
# defining modes
MODES = ["normal", "ace-editor"]
# Defining main logic
class TOXICTyper:
def __init__(
self,
mode: Union[str, int] = MODES[0],
shortcut_key: str = "Right Ctrl",
line_break: bool = True,
remove_everything: bool = False,
remove_auto_brackets: bool = False,
) -> None:
self.typer = Controller()
self.listener = None
self.tab_listener = None
self.__modes = MODES
self.__keys_map = KEYS_MAP
self.__line_break = line_break
self.__remove_everything = remove_everything
self.__remove_auto_brackets = remove_auto_brackets
self.set_mode(mode)
self.ctrl_pressed = False
self.set_shortcut_key(shortcut_key)
self.tabs = None
self.text_widgets = [] # Add timestamp for debouncing
# Tab changing logic
def set_tabs(self, notebook):
self.tabs = notebook
def add_text_widget(self, text_widget):
self.text_widgets.append(text_widget)
def get_selected_tab_content(self):
if self.tabs is not None:
try:
current_tab_index = self.tabs.index(self.tabs.select())
if 0 <= current_tab_index < len(self.text_widgets):
text_widget = self.text_widgets[current_tab_index]
return text_widget.get("1.0", "end-1c")
except Exception as e:
print(f"Error getting tab content: {e}")
return None
def change_tab(self, index):
if self.tabs is None:
return
try:
tab_count = len(self.tabs.tabs())
if 0 <= index < tab_count: # Validate index is within bounds
self.tabs.select(index)
print(f"Switched to Tab {index+1}")
else:
print(f"Tab {index+1} does not exist. Available tabs: {tab_count}")
except Exception as e:
print(f"Error switching tabs: {e}")
def tab_change(self, key):
try:
# Handle Left Ctrl key press
if key == Key.ctrl_l:
self.ctrl_pressed = True
return
# Handle Left Ctrl key release
if hasattr(key, 'name') and key.name == 'ctrl_l':
self.ctrl_pressed = False
return
# Handle arrow keys when Ctrl is pressed
if self.ctrl_pressed:
if key == Key.right:
if self.tabs is not None:
current_index = self.tabs.index(self.tabs.select())
self.change_tab(current_index + 1) # Next tab
elif key == Key.left:
if self.tabs is not None:
current_index = self.tabs.index(self.tabs.select())
self.change_tab(current_index - 1) # Previous tab
except Exception as e:
print(f"Error in tab_change: {e}")
# typer trigger logic
def on_release(self, key):
if key == self.__shortcut_key:
self.paste_from_clipboard()
elif key == Key.ctrl_l:
self.ctrl_pressed = False
# typing logic
def paste_from_clipboard(self):
print("Pasting from clipboard using mode:", self.__mode)
text = self.get_selected_tab_content()
if text is None:
print("No text available in the selected tab")
return
# typer configuration logics
if self.__remove_everything:
with self.typer.pressed(Key.ctrl):
self.typer.tap("a")
self.typer.tap(Key.backspace)
if self.__mode == "ace-editor":
textlines = text.split("\n")
for line in textlines:
with self.typer.pressed(Key.alt):
self.typer.tap(Key.backspace)
self.typer.type(line)
if self.__line_break:
self.typer.tap(Key.enter)
else:
self.typer.type(text)
if self.__remove_auto_brackets:
with self.typer.pressed(Key.ctrl):
with self.typer.pressed(Key.shift):
self.typer.tap(Key.end)
self.typer.tap(Key.backspace)
# mode logic
def set_mode(self, mode):
if mode in self.__modes or (isinstance(mode, int) and mode < len(self.__modes)):
if isinstance(mode, int):
mode = self.__modes[mode]
self.__mode = mode
print("Mode set to:", mode)
else:
raise Exception("Invalid mode:", mode)
# shortcut key logic
def set_shortcut_key(self, key):
if key in self.__keys_map.keys():
self.__shortcut_key = self.__keys_map[key]
print("Shortcut key set to:", key)
else:
raise Exception("Invalid shortcut key:", key)
def set_line_break(self, line_break):
self.__line_break = bool(line_break)
print("Line break set to:", bool(line_break))
def set_remove_everything(self, remove_everything):
self.__remove_everything = bool(remove_everything)
print("Remove everything set to:", bool(remove_everything))
def set_remove_auto_brackets(self, remove_auto_brackets):
self.__remove_auto_brackets = bool(remove_auto_brackets)
print("Remove auto brackets set to:", bool(remove_auto_brackets))
# start typer logic
def start(self):
if self.listener:
self.listener.stop()
self.listener = Listener(on_release=self.on_release)
self.listener.start()
# Start the tab listener
self.tab_listener = Listener(on_press=self.tab_change)
self.tab_listener.start()
# typer stoppping logic
def stop(self):
if self.listener:
self.listener.stop()
self.listener = None
if self.tab_listener:
self.tab_listener.stop()
self.tab_listener = None
@property
def mode(self):
return self.__mode
@property
def modes(self):
return self.__modes
@property
def shortcut_key(self):
for key, value in self.__keys_map.items():
if value == self.__shortcut_key:
return key
@property
def shortcut_keys(self):
return list(self.__keys_map.keys())
@property
def line_break(self):
return self.__line_break
@property
def remove_everything(self):
return self.__remove_everything
@property
def remove_auto_brackets(self):
return self.__remove_auto_brackets