[Suggestion] Option to "Always search "Normal" by default"
-
I have an issue. I have hundreds of script files open at one time, and frequently use both Normal and Regular Expression w/ “Replace in Files”. If I forget to disable Regular Expression and use the Replace in Files function, I run the risk of corrupting hundreds of scripts. I’ve done this on multiple occasions… Instead of replacing, say [Test], I replace all letters T E and S in all scripts, and this is undoable. All scripts automatically save, and since the file was written to, it cannot be undone. This makes it a major hazard and I need to continually do a double-click which mode is enabled before hitting the Replace in Files button.
I would like an option to have the Normal radio button always defaulted whenever the Find window opened to prevent this from happening.
-
I’ve never personally had that problem, since I just always leave Regular Expression mode on (so to replace the literal
[Test]
, I would have\\[Test\\]
in the FIND). But I can see how that would be a problem if you were to switch back and forth between the two modes frequently.But the Community of Notepad++ users cannot change the codebase for you: See the FAQ: Feature Request or Bug Report
-
@PeterJones said in [Suggestion] Option to "Always search "Normal" by default":
just always leave Regular Expression mode on
@Cariboudjan You could follow this suggestion and for normal searches add
\Q
to the start of the Find what data. I don’t know if that helps you; it is also something to remember to do (like changing the Search mode is something you forget). -
An editor I used to use had a “settings” section where the “Find/Replace” dialog screen was replicated, and you could set it up the way you wanted your defaults to be on the real “Find/Replace” window. Very smart, very intuitive. If this becomes a real feature-request, that might be valuable as a suggestion.
-
Attached is a variant on a script I use to set the states of the controls on the Find window how I want them to be set when I invoke the find command.
The idea behind this script is that you’d replace the default keybinding for Ctrl+f from the native find command to instead run the script.
When the script is run, it will open the Find window and set the Search mode to Normal, as well as some other things (which should be easy to spot in the code, and remove if desired).
More information on installing and using scripts with Notepad++ via the PythonScript plugin is found HERE.
Here’s the code listing for the script I call
FindWithDefaultOptionsSet.py
:# -*- coding: utf-8 -*- from __future__ import print_function # references: # https://community.notepad-plus-plus.org/topic/23793 from Npp import * import inspect import os import sys from ctypes import ( create_unicode_buffer, WinDLL, ) from ctypes.wintypes import ( HWND, LPARAM, UINT, WPARAM, ) LRESULT = LPARAM #------------------------------------------------------------------------------- python2 = True if sys.version_info.major == 2 else False user32 = WinDLL('user32') BM_CLICK = 0x00F5 BM_GETCHECK = 0x00F0 BST_CHECKED = 1 SW_SHOW = 5 SW_HIDE = 0 WM_NEXTDLGCTL = 0x28 SendMessage = user32.SendMessageW SendMessage.restype = LRESULT SendMessage.argtypes = [ HWND, UINT, WPARAM, LPARAM ] #------------------------------------------------------------------------------- # ids from find window controls, see # https://github.com/notepad-plus-plus/notepad-plus-plus/blob/master/PowerEditor/src/ScintillaComponent/FindReplaceDlg_rc.h : IDFINDWHAT = 1601 IDNORMAL = 1625 IDWHOLEWORD = 1603 IDMATCHCASE = 1604 IDC_BACKWARDDIRECTION = 1722 #------------------------------------------------------------------------------- class HwndUtility(object): def __init__(self): pass def set_control_text(self, hwnd, string): if python2 and isinstance(string, str): string = unicode(string, 'utf-8') return user32.SetWindowTextW(hwnd, string) def get_control_text(self, hwnd): length = user32.GetWindowTextLengthW(hwnd) ubuff = create_unicode_buffer(length + 1) user32.GetWindowTextW(hwnd, ubuff, length + 1) return ubuff.value.encode('utf-8') if python2 else ubuff.value def check_checkbox(self, hwnd, check_not_uncheck=True): if self.is_control_enabled(hwnd): currently_checked = self._is_checkbox_or_radio_checked(hwnd) if check_not_uncheck and currently_checked: return True elif not check_not_uncheck and not currently_checked: return True else: return self.press_button(hwnd) return False def is_checkbox_checked(self, hwnd): return self._is_checkbox_or_radio_checked(hwnd) def set_radio(self, hwnd): return self.check_checkbox(hwnd) def is_radio_set(self, hwnd): return self._is_checkbox_or_radio_checked(hwnd) def press_button(self, hwnd): return True if SendMessage(hwnd, BM_CLICK, 0, 0) == 0 else False def is_control_enabled(self, hwnd): return True if user32.IsWindowEnabled(hwnd) == 1 else False def set_dialog_control_focus(self, hwnd, dialog_hwnd): # see https://devblogs.microsoft.com/oldnewthing/20040804-00/?p=38243 return True if SendMessage(dialog_hwnd, WM_NEXTDLGCTL, WPARAM(hwnd), LPARAM(True)) == 0 else False def make_visible(self, hwnd, show=True): user32.ShowWindow(hwnd, SW_SHOW if show else SW_HIDE) # functions meant for internal use only by this class: def _is_checkbox_or_radio_checked(self, hwnd): # internal function; external should use is_checkbox_checked() or is_radio_set() return True if SendMessage(hwnd, BM_GETCHECK, 0, 0) == BST_CHECKED else False #------------------------------------------------------------------------------- def get_word_at_caret_or_selection(): retval = '' (sel_start, sel_end) = (editor.getSelectionStart(), editor.getSelectionEnd()) if editor.getSelections() == 1 and sel_start != sel_end: retval = editor.getTextRange(sel_start, sel_end) else: start_of_word_pos = editor.wordStartPosition(editor.getCurrentPos(), True) end_of_word_pos = editor.wordEndPosition(start_of_word_pos, True) if start_of_word_pos != end_of_word_pos: retval = editor.getTextRange(start_of_word_pos, end_of_word_pos) editor.setSelection(end_of_word_pos, start_of_word_pos) return retval #------------------------------------------------------------------------------- class FWDOS(object): def __init__(self): self.debug = True if 1 else False if self.debug: pass #console.show() #console.clear() self.this_script_name = inspect.getframeinfo(inspect.currentframe()).filename.split(os.sep)[-1].rsplit('.', 1)[0] self.this_script_path_without_ext = inspect.getframeinfo(inspect.currentframe()).filename.rsplit('.', 1)[0] # activate the find tab of the find window notepad.menuCommand(MENUCOMMAND.SEARCH_FIND) # this could cause the word at caret or any active selection to be put in the find-what box # (best practice: set Preferences > Searching > Don't fill find field... to UNTICKED) find_window_hwnd = user32.FindWindowExW(None, None, u'#32770', u'Find') findWhat_edit_hwnd = user32.GetDlgItem(find_window_hwnd, IDFINDWHAT) normalSearchMode_radio_hwnd = user32.GetDlgItem(find_window_hwnd, IDNORMAL) wholeWord_checkbox_hwnd = user32.GetDlgItem(find_window_hwnd, IDWHOLEWORD) matchCase_checkbox_hwnd = user32.GetDlgItem(find_window_hwnd, IDMATCHCASE) backwardDirection_checkbox_hwnd = user32.GetDlgItem(find_window_hwnd, IDC_BACKWARDDIRECTION) text_to_set_for_findWhat = get_word_at_caret_or_selection() hu = HwndUtility() hu.press_button(normalSearchMode_radio_hwnd) hu.check_checkbox(matchCase_checkbox_hwnd, False) hu.check_checkbox(wholeWord_checkbox_hwnd, False) hu.check_checkbox(backwardDirection_checkbox_hwnd, False) hu.set_control_text(findWhat_edit_hwnd, text_to_set_for_findWhat) hu.set_dialog_control_focus(findWhat_edit_hwnd, find_window_hwnd) def print(self, *args): if self.debug: print(self.__class__.__name__ + ':', *args) #------------------------------------------------------------------------------- if __name__ == '__main__': FWDOS()
-
-
@Alan-Kilborn said in [Suggestion] Option to "Always search "Normal" by default":
An editor I used to use had a “settings” section where the “Find/Replace” dialog screen was replicated, and you could set it up the way you wanted your defaults to be on the real “Find/Replace” window. Very smart, very intuitive. If this becomes a real feature-request, that might be valuable as a suggestion.
This is excellent. Thank you. I’ve added it as a keyboard shortcut to replace Ctrl+F.
I noticed that the Find in Files process takes about 4-5x longer than usual with this new script. Is there a reason why?
-
A related note which may be of interest…
When I invoke Replace, I like to have whatever I’m finding pre-set as my replacement data. Why? Because often I only want to tweak slightly what I currently have. Perhaps think about it in terms of writing code and wanting to give a variable a slightly better name.
This (auto-copy of Find what to Replace with) was actually a feature request for Notepad++ that got suspended to see if it is wanted by other users. That’s the kiss-of-death meaning “not going to be implemented”.
You can read more about the feature request HERE and about the suspension HERE.
Anyway, I shared a script HERE for copying Find what text to Replace with when Replace is invoked. That script is very similar to the
FindWithDefaultOptionsSet.py
script appearing above in this thread.For my personal use when Replace is invoked, for “safety” I also like to set the Search mode to Normal and check the boxes for Match whole word only and Match case, which is demonstrated in an inverse sense in the
FindWithDefaultOptionsSet.py
script. -
@Cariboudjan said in [Suggestion] Option to “Always search “Normal” by default”:
I noticed that the Find in Files process takes about 4-5x longer than usual with this new script. Is there a reason why?
(Strangely, I didn’t notice this trailing comment of @Cariboudjan 's before now…)
The answer is that the script has nothing to do with Notepad++'s Find in Files function, so you need to look elsewhere for why something might be different about it.
All the script does is open (or switch input focus to) the Find window and set the state of some controls on that window. Draw your own conclusions about how that can impact a Find in Files action (…it can’t).