-
-
Notifications
You must be signed in to change notification settings - Fork 10
/
Copy pathedit_paragraph.py
152 lines (130 loc) · 4.71 KB
/
edit_paragraph.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
from talon import Context, Module, actions
ctx = Context()
mod = Module()
@ctx.action_class("edit")
class EditActions:
def paragraph_start():
if extend_paragraph_start_with_success():
actions.edit.left()
def paragraph_end():
if extend_paragraph_end_with_success():
actions.edit.right()
def select_paragraph():
if is_line_empty():
return
# Search for start of paragraph
actions.edit.extend_paragraph_start()
actions.edit.left()
# Extend to end of paragraph
actions.edit.extend_paragraph_end()
def extend_paragraph_start():
# The reason for the wrapper function is a difference in function signature.
# The Talon action has no return value and the below function returns a boolean with success state.
extend_paragraph_start_with_success()
def extend_paragraph_end():
extend_paragraph_end_with_success()
def delete_paragraph():
actions.edit.select_paragraph()
# Remove selection
actions.edit.delete()
# Remove the empty line containing the cursor
actions.edit.delete()
# Remove leading or trailing empty line
actions.edit.delete_line()
@mod.action_class
class Actions:
def cut_paragraph():
"""Cut paragraph under the cursor"""
actions.edit.select_paragraph()
actions.edit.cut()
def copy_paragraph():
"""Copy paragraph under the cursor"""
actions.edit.select_paragraph()
actions.edit.copy()
actions.edit.select_none()
def paste_paragraph():
"""Paste to paragraph under the cursor"""
actions.edit.select_paragraph()
actions.edit.paste()
def paragraph_insert_up():
"""Insert paragraph above current paragraph"""
if extend_paragraph_start_with_success():
actions.edit.left()
actions.edit.line_insert_up()
actions.edit.line_insert_up()
def paragraph_insert_down():
"""Insert paragraph below current paragraph"""
if extend_paragraph_end_with_success():
actions.edit.right()
actions.edit.line_insert_down()
actions.edit.line_insert_down()
def paragraph_clone_up():
"""Create a new paragraph identical to the current paragraph above the current paragraph"""
actions.edit.select_paragraph()
text = actions.edit.selected_text()
if text.strip():
actions.edit.left()
actions.edit.line_insert_up()
actions.edit.line_insert_up()
actions.sleep("50ms")
actions.insert(text)
def paragraph_clone_down():
"""Create a new paragraph identical to the current paragraph below the current paragraph"""
actions.edit.select_paragraph()
text = actions.edit.selected_text()
if text.strip():
actions.edit.right()
actions.edit.line_insert_down()
actions.edit.line_insert_down()
actions.sleep("50ms")
actions.insert(text)
def is_line_empty() -> bool:
"""Check if the current line is empty. Return True if empty."""
actions.edit.extend_line_start()
text = actions.edit.selected_text().strip()
if text:
actions.edit.right()
return False
actions.edit.extend_line_end()
text = actions.edit.selected_text().strip()
if text:
actions.edit.left()
return False
return True
def extend_paragraph_start_with_success() -> bool:
"""Extend selection to the start of the paragraph. Return True if successful."""
actions.edit.extend_line_start()
text = actions.edit.selected_text()
length = len(text)
while True:
actions.edit.extend_up()
actions.edit.extend_line_start()
text = actions.edit.selected_text()
new_length = len(text)
if new_length == length:
break
line = text[: new_length - length].strip()
if not line:
actions.edit.extend_down()
break
length = new_length
return text.strip() != ""
def extend_paragraph_end_with_success() -> bool:
"""Extend selection to the end of the paragraph. Return True if successful."""
actions.edit.extend_line_end()
text = actions.edit.selected_text()
length = len(text)
while True:
actions.edit.extend_down()
actions.edit.extend_line_end()
text = actions.edit.selected_text()
new_length = len(text)
if new_length == length:
break
line = text[length:].strip()
if not line:
actions.edit.extend_line_start()
actions.edit.extend_left()
break
length = new_length
return text.strip() != ""