Skip to content

Commit

Permalink
Added edit paragraph actions and commands (talonhub#1432)
Browse files Browse the repository at this point in the history
Co-authored-by: Nicholas Riley <com-github@sabi.net>
  • Loading branch information
AndreasArvidsson and nriley authored Jul 6, 2024
1 parent 4e4bfe8 commit 73bb39e
Show file tree
Hide file tree
Showing 2 changed files with 125 additions and 5 deletions.
15 changes: 10 additions & 5 deletions core/edit/edit.talon
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ select all: edit.select_all()
select line: edit.select_line()
select line start: user.select_line_start()
select line end: user.select_line_end()
select block: edit.select_paragraph()

select left: edit.extend_left()
select right: edit.extend_right()
Expand All @@ -66,6 +67,7 @@ clear all: user.delete_all()
clear line: edit.delete_line()
clear line start: user.delete_line_start()
clear line end: user.delete_line_end()
clear block: edit.delete_paragraph()
clear left: edit.delete()
clear right: user.delete_right()

Expand Down Expand Up @@ -109,6 +111,7 @@ copy all: user.copy_all()
copy line: user.copy_line()
copy line start: user.copy_line_start()
copy line end: user.copy_line_end()
copy block: user.copy_paragraph()
copy word: user.copy_word()
copy word left: user.copy_word_left()
copy word right: user.copy_word_right()
Expand All @@ -133,6 +136,7 @@ cut all: user.cut_all()
cut line: user.cut_line()
cut line start: user.cut_line_start()
cut line end: user.cut_line_end()
cut block: user.cut_paragraph()
cut word: user.cut_word()
cut word left: user.cut_word_left()
cut word right: user.cut_word_right()
Expand All @@ -157,11 +161,12 @@ cut word right: user.cut_word_right()
edit.paste()
key(enter)
paste match: edit.paste_match_style()
(pace | paste) all: user.paste_all()
(pace | paste) line: user.paste_line()
(pace | paste) line start: user.paste_line_start()
(pace | paste) line end: user.paste_line_end()
(pace | paste) word: user.paste_word()
(pace | paste) [to] all: user.paste_all()
(pace | paste) [to] line: user.paste_line()
(pace | paste) [to] line start: user.paste_line_start()
(pace | paste) [to] line end: user.paste_line_end()
(pace | paste) [to] block: user.paste_paragraph()
(pace | paste) [to] word: user.paste_word()

# Duplication
clone that: edit.selection_clone()
Expand Down
115 changes: 115 additions & 0 deletions core/edit/edit_paragraph.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
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()

def paste_paragraph():
"""Paste to paragraph under the cursor"""
actions.edit.select_paragraph()
actions.edit.paste()


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() != ""

0 comments on commit 73bb39e

Please sign in to comment.