The find and change commands are tricky; there are many details that must be handled properly. This documentation describes the leo.py code. Previous versions of Leo used an inferior scheme. The following principles govern the leoFind class:
Initialization involves setting the self.c, self.p, self.in_headline, self.wrapping and self.s_ctrl ivars. Setting self.in_headline is tricky; we must be sure to retain the state of the outline pane until initialization is complete. Initializing the Find All and Change All commands is much easier because such initialization does not depend on the state of the Leo window.
Using Tk.Text widgets for both headlines and body text results in a huge simplification of the code. Indeed, the searching code does not know whether it is searching headline or body text. The search code knows only that self.s_ctrl is a Tk.Text widget that contains the text to be searched or changed and the insert and sel Tk attributes of self.search_text indicate the range of text to be searched. Searching headline and body text simultaneously is complicated. The selectNextPosition() method handles the many details involved by setting self.s_ctrl and its insert and sel attributes.
New in 4.3: - These are the names of leoFind ivars. (no more _flag hack). - There are no corresponding commander ivars to keep in synch (hurray!) - These ivars are inited (in the subclass by init) when this class is created. - These ivars are updated (in the subclass by update_ivars) just before doing any find. Initializing a wrapped search is tricky. The search() method will fail if p==wrapPosition and pos >= wrapPos. selectNextPosition() will fail if p == wrapPosition. We set wrapPos on entry, before the first search. We set wrapPosition in selectNextPosition after the first search fails. We also set wrapPosition on exit if the first search succeeds.
This routine performs a single batch change operation, updating the head or body string of p and leaving the result in s_ctrl. We update the body if we are changing the body text of c.currentVnode().
s_ctrl contains the found text on entry and contains the changed text on exit. pos and pos2 indicate the selection. The selection will never be empty. NB: we can not assume that self.p is visible.