Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
105 changes: 58 additions & 47 deletions core/text/text_and_dictation.py
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ def format_phrase(m):
words = capture_to_words(m)
result = ""
for i, word in enumerate(words):
if i > 0 and needs_space_between(words[i - 1], word):
if i > 0 and actions.user.needs_space_between(words[i - 1], word):
result += " "
result += word
return result
Expand Down Expand Up @@ -296,47 +296,35 @@ def apply_formatting(m):
)


def omit_space_before(text: str) -> bool:
return not text or no_space_before.search(text)


def omit_space_after(text: str) -> bool:
return not text or no_space_after.search(text)


def needs_space_between(before: str, after: str) -> bool:
return not (omit_space_after(before) or omit_space_before(after))


# # TESTS, uncomment to enable
# assert needs_space_between("a", "break")
# assert needs_space_between("break", "a")
# assert needs_space_between(".", "a")
# assert needs_space_between("said", "'hello")
# assert needs_space_between("hello'", "said")
# assert needs_space_between("hello.", "'John")
# assert needs_space_between("John.'", "They")
# assert needs_space_between("paid", "$50")
# assert needs_space_between("50$", "payment")
# assert not needs_space_between("", "")
# assert not needs_space_between("a", "")
# assert not needs_space_between("a", " ")
# assert not needs_space_between("", "a")
# assert not needs_space_between(" ", "a")
# assert not needs_space_between("a", ",")
# assert not needs_space_between("'", "a")
# assert not needs_space_between("a", "'")
# assert not needs_space_between("and-", "or")
# assert not needs_space_between("mary", "-kate")
# assert not needs_space_between("$", "50")
# assert not needs_space_between("US", "$")
# assert not needs_space_between("(", ")")
# assert not needs_space_between("(", "e.g.")
# assert not needs_space_between("example", ")")
# assert not needs_space_between("example", '".')
# assert not needs_space_between("example", '."')
# assert not needs_space_between("hello'", ".")
# assert not needs_space_between("hello.", "'")
# assert actions.user.needs_space_between("a", "break")
# assert actions.user.needs_space_between("break", "a")
# assert actions.user.needs_space_between(".", "a")
# assert actions.user.needs_space_between("said", "'hello")
# assert actions.user.needs_space_between("hello'", "said")
# assert actions.user.needs_space_between("hello.", "'John")
# assert actions.user.needs_space_between("John.'", "They")
# assert actions.user.needs_space_between("paid", "$50")
# assert actions.user.needs_space_between("50$", "payment")
# assert not actions.user.needs_space_between("", "")
# assert not actions.user.needs_space_between("a", "")
# assert not actions.user.needs_space_between("a", " ")
# assert not actions.user.needs_space_between("", "a")
# assert not actions.user.needs_space_between(" ", "a")
# assert not actions.user.needs_space_between("a", ",")
# assert not actions.user.needs_space_between("'", "a")
# assert not actions.user.needs_space_between("a", "'")
# assert not actions.user.needs_space_between("and-", "or")
# assert not actions.user.needs_space_between("mary", "-kate")
# assert not actions.user.needs_space_between("$", "50")
# assert not actions.user.needs_space_between("US", "$")
# assert not actions.user.needs_space_between("(", ")")
# assert not actions.user.needs_space_between("(", "e.g.")
# assert not actions.user.needs_space_between("example", ")")
# assert not actions.user.needs_space_between("example", '".')
# assert not actions.user.needs_space_between("example", '."')
# assert not actions.user.needs_space_between("hello'", ".")
# assert not actions.user.needs_space_between("hello.", "'")

no_cap_after = re.compile(
r"""(
Expand Down Expand Up @@ -411,7 +399,9 @@ def pass_through(self, text):
self.before = text or self.before

def format(self, text, auto_cap=True):
if not self.force_no_space and needs_space_between(self.before, text):
if not self.force_no_space and actions.user.needs_space_between(
self.before, text
):
text = " " + text
self.force_no_space = False
if auto_cap:
Expand Down Expand Up @@ -498,30 +488,51 @@ def dictation_reformat_no_space():
"""Removes space before the last utterance"""
reformat_last_utterance(lambda s: s[1:] if s.startswith(" ") else s)

def omit_space_before(text: str) -> bool:
"""Test if dictated text needs space before"""
return bool(not text or no_space_before.search(text))

def omit_space_after(text: str) -> bool:
"""Test if dictated text needs space after"""
return bool(not text or no_space_after.search(text))

def needs_space_between(before: str, after: str) -> bool:
"""Test if two text strings need a space between them"""
return not (
actions.user.omit_space_after(before)
or actions.user.omit_space_before(after)
)

def dictation_replace(text: str) -> str:
"""Substitutions to be performed before inserting text using dictation_insert"""
return text.replace("“", '"').replace("”", '"')

def dictation_insert_raw(text: str):
"""Inserts text as-is, without invoking the dictation formatter."""
actions.user.dictation_insert(text, auto_cap=False)

def dictation_insert(text: str, auto_cap: bool = True) -> str:
def dictation_insert(text: str, auto_cap: bool = True):
"""Inserts dictated text, formatted appropriately."""
add_space_after = False
if settings.get("user.context_sensitive_dictation"):
# Peek left if we might need leading space or auto-capitalization;
# peek right if we might need trailing space. NB. We peek right
# BEFORE insertion to avoid breaking the undo-chain between the
# inserted text and the trailing space.
need_left = not omit_space_before(text) or (
need_left = not actions.user.omit_space_before(text) or (
auto_cap and text != auto_capitalize(text, "sentence start")[0]
)
need_right = not omit_space_after(text)
need_right = not actions.user.omit_space_after(text)
before, after = actions.user.dictation_peek(need_left, need_right)
dictation_formatter.update_context(before)
add_space_after = after is not None and needs_space_between(text, after)
add_space_after = after is not None and actions.user.needs_space_between(
text, after
)
text = dictation_formatter.format(text, auto_cap)
# Straighten curly quotes that were introduced to obtain proper
# spacing. The formatter context still has the original curly quotes
# so that future dictation is properly formatted.
text = text.replace("“", '"').replace("”", '"')
text = actions.user.dictation_replace(text)
actions.user.add_phrase_to_history(text)
actions.user.insert_between(text, " " if add_space_after else "")

Expand Down