Community
    • Login

    [Suggestion] Option to "Always search "Normal" by default"

    Scheduled Pinned Locked Moved General Discussion
    8 Posts 3 Posters 1.0k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • CariboudjanC
      Cariboudjan
      last edited by Cariboudjan

      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.

      PeterJonesP 1 Reply Last reply Reply Quote 0
      • PeterJonesP
        PeterJones @Cariboudjan
        last edited by PeterJones

        @Cariboudjan ,

        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

        Alan KilbornA 1 Reply Last reply Reply Quote 1
        • Alan KilbornA
          Alan Kilborn @PeterJones
          last edited by Alan Kilborn

          @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).

          1 Reply Last reply Reply Quote 1
          • Alan KilbornA
            Alan Kilborn
            last edited by

            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.

            CariboudjanC 1 Reply Last reply Reply Quote 2
            • Alan KilbornA
              Alan Kilborn
              last edited by Alan Kilborn

              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()
              
              1 Reply Last reply Reply Quote 2
              • Alan KilbornA Alan Kilborn referenced this topic on
              • CariboudjanC
                Cariboudjan @Alan Kilborn
                last edited by Cariboudjan

                @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?

                Alan KilbornA 1 Reply Last reply Reply Quote 1
                • Alan KilbornA
                  Alan Kilborn
                  last edited by Alan Kilborn

                  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.

                  1 Reply Last reply Reply Quote 1
                  • Alan KilbornA
                    Alan Kilborn @Cariboudjan
                    last edited by

                    @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).

                    1 Reply Last reply Reply Quote 0
                    • First post
                      Last post
                    The Community of users of the Notepad++ text editor.
                    Powered by NodeBB | Contributors