Find is most useful paired with replace. Today you swap the current match for new text, turning search into find-and-replace and closing the chapter on a real editing power tool.
Replace the current search match with new text, moving the cursor past the replacement, and do nothing when there is no match.
Replace is what turns search from navigation into editing. The match you just found already carries everything a replacement needs - its position and its length - so replacing it is: delete that span, insert the new text where it stood, and move the cursor to the end of what you inserted. Because the replacement can be a different length than the match, letting the cursor land past the inserted text keeps it sensibly placed whether the word grew or shrank.
Two details make it robust. With no current match - nothing has been found yet,
or the match was cleared by an edit - there is nothing to replace, so it returns
false and leaves the buffer alone. And replacing consumes the match: it is an
edit, so it sets the dirty flag and clears the highlight, exactly the invalidation
rule from last lesson (you cannot re-replace a span you just changed). With find,
find-again in both directions, wrap-around, highlighting, and replace, the editor has
the search toolkit real ones ship. All that is left is the memory that lets you take
any of it back: undo.
func (e *Editor) ReplaceMatch(repl string) bool {if e.matchLen == 0 { return false } // nothing found to replaceoff := e.Buf.LineStart(e.matchRow) + e.matchCole.Buf.Delete(off, e.matchLen) // remove the old matche.Buf.Insert(off, repl) // drop the new text ine.Row, e.Col = e.Buf.PositionAt(off + len(repl))e.matchLen = 0; e.Dirty = true // consume the matchreturn true}