From cc2f6e2b1902e41526162ee0d80dbfba8326bf0c Mon Sep 17 00:00:00 2001 From: dgw Date: Sun, 1 Sep 2024 23:33:00 -0500 Subject: [PATCH] find: fix bolding when replacing inside a previous replacement Perform the replacement with an unformatted version of the substitute string, then create a display version with bolding added only after the matching line (if any) is found. Updated the corresponding test case. Also renamed some local vars in the `find` plugin file to make a bit more sense (but not too dramatic). --- sopel/builtins/find.py | 29 +++++++++++++++-------------- test/builtins/test_builtins_find.py | 4 +--- 2 files changed, 16 insertions(+), 17 deletions(-) diff --git a/sopel/builtins/find.py b/sopel/builtins/find.py index b51b3f957..67721d593 100644 --- a/sopel/builtins/find.py +++ b/sopel/builtins/find.py @@ -170,7 +170,7 @@ def findandreplace(bot, trigger): # only clean/format the new string if it's non-empty if new: - new = bold(escape_sequence_pattern.sub(decode_escape, new)) + new = escape_sequence_pattern.sub(decode_escape, new) # If g flag is given, replace all. Otherwise, replace once. if 'g' in flags: @@ -183,42 +183,43 @@ def findandreplace(bot, trigger): if 'i' in flags: regex = re.compile(re.escape(old), re.U | re.I) - def repl(s): - return re.sub(regex, new, s, count == 1) + def repl(line, subst): + return re.sub(regex, subst, line, count == 1) else: - def repl(s): - return s.replace(old, new, count) + def repl(line, subst): + return line.replace(old, subst, count) # Look back through the user's lines in the channel until you find a line # where the replacement works - new_phrase = None + new_line = new_display = None for line in history: if line.startswith("\x01ACTION"): me = True # /me command line = line[8:] else: me = False - replaced = repl(line) + replaced = repl(line, new) if replaced != line: # we are done - new_phrase = replaced + new_line = replaced + new_display = repl(line, bold(new)) break - if not new_phrase: + if not new_line: return # Didn't find anything # Save the new "edited" message. action = (me and '\x01ACTION ') or '' # If /me message, prepend \x01ACTION - history.appendleft(action + new_phrase) # history is in most-recent-first order + history.appendleft(action + new_line) # history is in most-recent-first order # output if not me: - new_phrase = 'meant to say: %s' % new_phrase + new_display = 'meant to say: %s' % new_display if trigger.group(1): - phrase = '%s thinks %s %s' % (trigger.nick, rnick, new_phrase) + msg = '%s thinks %s %s' % (trigger.nick, rnick, new_display) else: - phrase = '%s %s' % (trigger.nick, new_phrase) + msg = '%s %s' % (trigger.nick, new_display) - bot.say(phrase) + bot.say(msg) def decode_escape(match): diff --git a/test/builtins/test_builtins_find.py b/test/builtins/test_builtins_find.py index fee09f6c4..f7daaa1f2 100644 --- a/test/builtins/test_builtins_find.py +++ b/test/builtins/test_builtins_find.py @@ -102,8 +102,6 @@ def test_replace_the_replacement(bot, irc, user, channel): channel, user.nick, bold('eggs'), ), "PRIVMSG %s :%s meant to say: %s" % ( - channel, user.nick, bold(bold('bacon')), - # the test is accurate, even though the behavior here (doubled bold - # control characters) is less than ideal + channel, user.nick, bold('bacon'), ), )