Merge pull request #373 from vkbo/search_replace

Search/Replace Fix
This commit is contained in:
Veronica K. Berglyd Olsen
2020-07-27 20:28:49 +02:00
committed by GitHub
+48 -21
View File
@@ -79,6 +79,7 @@ class GuiDocEditor(QTextEdit):
self.wordCount = 0 self.wordCount = 0
self.paraCount = 0 self.paraCount = 0
self.lastEdit = 0 self.lastEdit = 0
self.lastFind = None
self.bigDoc = False self.bigDoc = False
self.doReplace = False self.doReplace = False
self.nonWord = "\"'" self.nonWord = "\"'"
@@ -89,7 +90,7 @@ class GuiDocEditor(QTextEdit):
self.typSQOpen = self.mainConf.fmtSingleQuotes[0] self.typSQOpen = self.mainConf.fmtSingleQuotes[0]
self.typSQClose = self.mainConf.fmtSingleQuotes[1] self.typSQClose = self.mainConf.fmtSingleQuotes[1]
# Core Elements # Core Elements and Signals
self.qDocument = self.document() self.qDocument = self.document()
self.qDocument.contentsChange.connect(self._docChange) self.qDocument.contentsChange.connect(self._docChange)
@@ -685,6 +686,7 @@ class GuiDocEditor(QTextEdit):
triggers the syntax highlighter. triggers the syntax highlighter.
""" """
self.lastEdit = time() self.lastEdit = time()
self.lastFind = None
if not self.docChanged: if not self.docChanged:
self.setDocumentChanged(True) self.setDocumentChanged(True)
if not self.wcTimer.isActive(): if not self.wcTimer.isActive():
@@ -1170,19 +1172,21 @@ class GuiDocEditor(QTextEdit):
""" """
theCursor = self.textCursor() theCursor = self.textCursor()
if theCursor.hasSelection(): if theCursor.hasSelection():
selText = theCursor.selectedText() self.docSearch.setSearchText(theCursor.selectedText())
else: else:
selText = "" self.docSearch.setSearchText(None)
self.docSearch.setSearchText(selText)
self.updateDocMargins() self.updateDocMargins()
return return
def _beginReplace(self): def _beginReplace(self):
"""Opens the replace line of the search bar and sets the replace """Opens the replace line of the search bar and sets the find
text. text if a selection has been made, and resets the replace text.
""" """
self._beginSearch() theCursor = self.textCursor()
if theCursor.hasSelection():
self.docSearch.setSearchText(theCursor.selectedText())
self.docSearch.setReplaceText("") self.docSearch.setReplaceText("")
self.updateDocMargins()
return return
def _findNext(self, isBackward=False): def _findNext(self, isBackward=False):
@@ -1215,7 +1219,11 @@ class GuiDocEditor(QTextEdit):
QTextCursor.End if isBackward else QTextCursor.Start QTextCursor.End if isBackward else QTextCursor.Start
) )
self.setTextCursor(theCursor) self.setTextCursor(theCursor)
self.find(searchFor, findOpt) wasFound = self.find(searchFor, findOpt)
if wasFound:
theCursor = self.textCursor()
self.lastFind = (theCursor.selectionStart(), theCursor.selectionEnd())
return return
@@ -1225,32 +1233,48 @@ class GuiDocEditor(QTextEdit):
next automatically when done. next automatically when done.
""" """
if not self.docSearch.isVisible(): if not self.docSearch.isVisible():
# The search tool is not active, so we activate it.
self._beginSearch() self._beginSearch()
return return
theCursor = self.textCursor() theCursor = self.textCursor()
if not theCursor.hasSelection(): if not theCursor.hasSelection():
# We have no text selected at all, so just make this a
# regular find next call.
self._findNext() self._findNext()
return return
if self.lastFind is None and theCursor.hasSelection():
# If we have a selection but no search, it may have been the
# text we triggered the search with, in which case we search
# again from the beginning of that selection to make sure we
# have a valid result.
sPos = theCursor.selectionStart()
theCursor.clearSelection()
theCursor.setPosition(sPos)
self.setTextCursor(theCursor)
self._findNext()
theCursor = self.textCursor()
if self.lastFind is None:
# In case the above didn't find a result, we give up here.
return
searchFor = self.docSearch.getSearchText() searchFor = self.docSearch.getSearchText()
replWith = self.docSearch.getReplaceText() replWith = self.docSearch.getReplaceText()
selText = theCursor.selectedText()
if searchFor.strip() == "":
return
if self.docSearch.doMatchCap: if self.docSearch.doMatchCap:
replWith = transferCase(selText, replWith) replWith = transferCase(theCursor.selectedText(), replWith)
# Double check that we have a real match in case this is called # Make sure the selected text was selected by an actual find
# on a regular word selection and not on a search match # call, and not the user.
if not self.docSearch.isCaseSense: try:
isMatch = searchFor.lower() == selText.lower() isFind = self.lastFind[0] == theCursor.selectionStart()
else: isFind &= self.lastFind[1] == theCursor.selectionEnd()
isMatch = searchFor == selText except:
isFind = False
if isMatch: if isFind:
theCursor.beginEditBlock() theCursor.beginEditBlock()
theCursor.removeSelectedText() theCursor.removeSelectedText()
theCursor.insertText(replWith) theCursor.insertText(replWith)
@@ -1260,6 +1284,8 @@ class GuiDocEditor(QTextEdit):
logger.verbose("Replaced occurrence of '%s' with '%s' on line %d" % ( logger.verbose("Replaced occurrence of '%s' with '%s' on line %d" % (
searchFor, replWith, theCursor.blockNumber() searchFor, replWith, theCursor.blockNumber()
)) ))
else:
logger.error("The selected text is not a search result, skipping replace")
self._findNext() self._findNext()
@@ -1530,7 +1556,8 @@ class GuiDocEditSearch(QFrame):
""" """
if not self.isVisible(): if not self.isVisible():
self.setVisible(True) self.setVisible(True)
self.searchBox.setText(theText) if theText is not None:
self.searchBox.setText(theText)
self.searchBox.setFocus() self.searchBox.setFocus()
if self.isRegEx: if self.isRegEx:
self._alertSearchValid(True) self._alertSearchValid(True)