Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Disable search option "in selection" constantly #14108

Closed
mididoc opened this issue Sep 6, 2023 · 110 comments
Closed

Disable search option "in selection" constantly #14108

mididoc opened this issue Sep 6, 2023 · 110 comments
Assignees
Labels

Comments

@mididoc
Copy link

mididoc commented Sep 6, 2023

Hi,
is there a way to disable the search 'in selection' option always?
we always search in whole document and this option disturbs our search,
since it is enabling by itself.
thanks for assistance.
cheers mike

@Yaron10
Copy link

Yaron10 commented Sep 6, 2023

@mididoc,

Good point.
I think the "In Selection" CheckBox should be enabled/disabled instead of checked/unchecked.
I suggested it a long time ago.

@mididoc
Copy link
Author

mididoc commented Sep 6, 2023

Yaron10,
thanks for confirming.
cheers mike

@mididoc
Copy link
Author

mididoc commented Sep 9, 2023

Hi,
is there perhaps a workaround for this,
cause this drives me nuts.
Thanks mike

@alankilborn
Copy link
Contributor

@mididoc said:

we always search in whole document and this option disturbs our search, since it is enabling by itself

I take this to mean that you are selecting a large (> 1024 bytes) of existing data, then pressing Ctrl+f to get that data into Find what, and then you are seeing In selection automatically checkmarked.

@alankilborn
Copy link
Contributor

@Yaron10 said:

I think the "In Selection" CheckBox should be enabled/disabled instead of checked/unchecked. I suggested it a long time ago.

Can you elaborate on what this means? If the checkbox is disabled, wouldn't there be situations where a user needs to checkmark it and they cannot because it is disabled? (There's something I'm not understanding here)

@mididoc
Copy link
Author

mididoc commented Sep 13, 2023

Hi @alankilborn and @Yaron10,
yes we always search in the whole document.
but even if we would search just in a selection, why is this checkbox enabled automaticly.
i can enable it by myself, if i want to search just in the selection.
either this automaticly enabling of the checkbox should be deleted completely,
or there should be an option in the settings, where the user may select if he wants this automaticly enableing of the checkbox or not.
cheers mike

@alankilborn
Copy link
Contributor

either this automaticly enabling of the checkbox should be deleted completely, or there should be an option in the settings

Well, the author of Notepad++ will have to decide on that.

In the meanwhile, a workaround to always uncheck In Selection could be made by modifying the script HERE and then tying execution of that script to Ctrl+f rather than running the default command. If you are interested in such a script modification, let me know.

@mididoc
Copy link
Author

mididoc commented Sep 13, 2023

In the meanwhile, a workaround to always uncheck In Selection could be made by modifying the script HERE and then tying execution of that script to Ctrl+f rather than running the default command. If you are interested in such a script modification, let me know.

Yes this would be really interesting, thanks.
cheers mike

@alankilborn
Copy link
Contributor

Here's the script. For its use and setting it up, see the previously referenced Community posting:

And/or the Community's PythonScripting starter FAQ:

Click to view the script
# -*- coding: utf-8 -*-
from __future__ import print_function

# references:
#  https://github.com/notepad-plus-plus/notepad-plus-plus/issues/14108
#  also 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
IDC_IN_SELECTION_CHECK = 1632

#-------------------------------------------------------------------------------

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)
        inSelection_checkbox_hwnd       = user32.GetDlgItem(find_window_hwnd, IDC_IN_SELECTION_CHECK)

        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.check_checkbox(inSelection_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()

@mididoc
Copy link
Author

mididoc commented Sep 13, 2023

Hi @alankilborn,
thanks lot for your script.
i have installed phytonscript plugin and created the script ProvidedScript.py with your script content in:
%AppData\Notepad++\Plugins\Config\PythonScript\scripts
the startup.py i found in %programx86\Notepad++\plugins\PythonScript\scripts
but now i'm getting stuck. do not know, how to make your script run automaticly on program start.
thanks for assistance
cheers mike

@alankilborn
Copy link
Contributor

There is nothing about "startup" for this script; thus you should have ignored any references to startup where you saw them in the general instructions. The startup stuff is only for scripts that don't run "on demand". This one runs "on demand", meaning when you are initiating a find action.

Thus, you'd remove the keybinding for the default Ctrl+f action, which is tied to Search > Find..., and replace it with running of the script. Thus, when you are done with the one-time setup, Ctrl+f will invoke the script. Details on keybinding of a script are in the Community FAQ link from earlier.

@mididoc
Copy link
Author

mididoc commented Sep 13, 2023

OK,
i have removed the standard keyshortcut ctrl+f to the search menu option.
instead i have created a shortcut ctrl+f to plugin command 'ProvidedScript'
but it is still not working:
search in selection checkbox is still enabled automaticly when a selection exists.
(same if i call the script by plugins/python script/providedscript.py.)
cheers mike

@Yaron10
Copy link

Yaron10 commented Sep 13, 2023

Hello @alankilborn & @mididoc,

@alankilborn,

If the checkbox is disabled, wouldn't there be situations where a user needs to checkmark it and they cannot because it is disabled?

The CheckBox should be disabled when there's no selection on WM_ACTIVATE, and enabled when there is one.
Let the user check it or uncheck it.

This approach is simpler and much more flexible IMO.
And I don't understand why there should be any issue.

I changed the behavior for my personal use a few years ago and I don't fully remember it now. :)
I see the following lines in my NppCommands.cpp.

		case IDM_SEARCH_FIND:
		case IDM_SEARCH_REPLACE:
		case IDM_SEARCH_MARK:
		{
			const int strSize = FINDREPLACE_MAXLENGTH;
			TCHAR str[strSize]{};

			const NppGUI & nppGui = (NppParameters::getInstance()).getNppGUI();
			if (nppGui._fillFindFieldWithSelected)
				_pEditView->getGenericSelectedText(str, strSize, nppGui._fillFindFieldSelectCaret);		// Move it here so that "In Selection" can be correctly enabled/disabled on "WM_ACTIVATE" (if there was no selection and "getGenericSelectedText()" has set one).

I also think that the "1024 bytes" factor is too sophisticated and unnecessarily complicates the implementation.
But I'm not sure this is directly related to the current issue.


@mididoc,

I do think the behavior in NPP should be changed.
For the time being - I hope @alankilborn should continue helping you with the script.

@alankilborn
Copy link
Contributor

alankilborn commented Sep 14, 2023

@mididoc said:

but it is still not working: search in selection checkbox is still enabled automaticly when a selection exists.

It works for me. Here's how I tested it:

  • I had the script open in a tab and I did a select-all (via pressing Ctrl+a) to get a large amount of text selected
  • I go to the Search menu and choose Find... and observe that when the Find window opens, In selection is checkmarked (this verifies correct default behavior and the script isn't involved at all)
  • I close the Find window
  • With all that text still selected, I run the script (either from the menu or from the bound keycombo), and observe that when the Find window opens, this time In selection checkbox is NOT checkmarked

@alankilborn
Copy link
Contributor

alankilborn commented Sep 14, 2023

@Yaron10 said:

The CheckBox should be disabled when there's no selection on WM_ACTIVATE, and enabled when there is one.
Let the user check it or uncheck it.

It could have been implemented this way from the start, but it wasn't, and now I (and I presume others) are used to the auto-checkmarking. At this point in the life of the software, it would be too disruptive to remove the auto-checkmarking.

I also think that the "1024 bytes" factor is too sophisticated...


Ideally what might be needed is a Preference setting -- on the Searching subpage -- (integer value) to control this size. If the size is set to zero, then automatic checkmarking of In selection will never occur. That would be easiest to develop but maybe not the best UI. Maybe two setting controls is better:

  • [checkbox] Enable automatic In selection checkmarking
  • Minimum size for automatic In selection checkmarking: [edit/integer]

The "min. size" setting would be below the "enable" and slightly indented to the right. The "min. size" setting would appear disabled/grayed if the "enable" checkbox is unchecked.

@mididoc
Copy link
Author

mididoc commented Sep 14, 2023

It works for me. Here's how I tested it:

* I had the script open in a tab and I did a select-all (via pressing Ctrl+a) to get a large amount of text selected

* I go to the _Search_ menu and choose _Find..._ and observe that when the _Find_ window opens, _In selection_ is checkmarked (this verifies correct default behavior and the script isn't involved at all)

* I close the _Find_ window

* With all that text still selected, I run the script (either from the menu or from the bound keycombo), and observe that when the _Find_ window opens, this time _In selection_ checkbox is NOT checkmarked

sorry, doing the same and still not working here.
it even autochecks when just ONE word is marked.
cheers mike

@mididoc
Copy link
Author

mididoc commented Sep 14, 2023

Ideally what might be needed is a Preference setting -- on the Searching subpage -- (integer value) to control this size. If the size is set to zero, then automatic checkmarking of In selection will never occur. That would be easiest to develop but maybe not the best UI. Maybe two setting controls is better:

* **[checkbox]** Enable automatic _In selection_ checkmarking

* Minimum size for automatic _In selection_ checkmarking: **[edit/integer]**

The "min. size" setting would be below the "enable" and slightly indented to the right. The "min. size" setting would appear disabled/grayed if the "enable" checkbox is unchecked.

this would be the ideal solution.
cheers mike

@alankilborn
Copy link
Contributor

@mididoc

(script) still not working here.
it even autochecks when just ONE word is marked.

Hmm, okay; sorry we couldn't get it working for you...

@alankilborn
Copy link
Contributor

@donho If you like the following proposal for a change to solve this issue (which has been a problem for more users), then I will try my hand at a PR for it:

New for the Preferences > Searching page, default settings shown:

image

@Yaron10
Copy link

Yaron10 commented Sep 14, 2023

@alankilborn,

It could have been implemented this way from the start, but it wasn't, and now I (and I presume others) are used to the auto-checkmarking. At this point in the life of the software, it would be too disruptive to remove the auto-checkmarking.

The user would only have to check it once.

@alankilborn
Copy link
Contributor

The user would only have to check it once.

That makes the presumption that a user always wants to search in selected text, which isn't true. If it was the case that user always wanted this, then logic for Fill Find Field... would have to change as it makes no sense to fill the find field with selected text and then only search selected text.

@mididoc
Copy link
Author

mididoc commented Sep 14, 2023

The user would only have to check it once.

That makes the presumption that a user always wants to search in selected text, which isn't true. If it was the case that user always wanted this, then logic for Fill Find Field... would have to change as it makes no sense to fill the find field with selected text and then only search selected text.

also, if this would be added to the preferences as an option, this disturbs nobody.
as alankilborn said the default case is NOT searching in a selection, it's searching in whole document.

@alankilborn
Copy link
Contributor

as alankilborn said the default case is NOT searching in a selection, it's searching in whole document.

The default case, due to history, should be searching in selection if selection is > 1024. If there is no selection, or selection is < 1024, searching should proceed from the caret position toward either the bottom or the top of the document.

@donho
Copy link
Member

donho commented Sep 14, 2023

I think the "In Selection" CheckBox should be enabled/disabled instead of checked/unchecked.
I suggested it a long time ago.

@Yaron10
The checkbox IS disabled when there's no selection.

@donho donho added the reject label Sep 14, 2023
@donho
Copy link
Member

donho commented Sep 14, 2023

This option won't be implemented.

@donho donho closed this as completed Sep 14, 2023
@mididoc
Copy link
Author

mididoc commented Sep 14, 2023

This option won't be implemented.

this is really a pitty cause alankilborn's proposel is exellent.

@Yaron10
Copy link

Yaron10 commented Sep 14, 2023

@alankilborn,

That makes the presumption that a user always wants to search in selected text, which isn't true.

It seems we still have a fundamental misunderstanding here.
If the user wants to search "In Selection" in the current tab or other tabs, they would only have to check it once.

I do see the advantage in auto-check/uncheck. But it has a major downside too.
We have @mididoc's issue which in his words "this drives me nuts".
And I often want to search "In Selection" in one tab, and "Entire Doc" in another.
The only option we currently have is selecting/unselecting which is extremely inconvenient.

@donho,

The checkbox IS disabled when there's no selection.

I meant that the CheckBox should be enabled/disabled only without programmatically checking/unchecking it.
Let the user check/uncheck it. This is much more flexible.

@mididoc
Copy link
Author

mididoc commented Sep 14, 2023

Hi again,
a bit sad but still here.
I have nothing against the option to search in a selection.
I only have something against, that the program decides if i search in a selection or not.
If the option is available if a selection exists, ofcourse otherwise it makes no sense.
But as said by others too, do not let the program decide in which manner i want to search.
We have a lot of software, and working long time professional on computers.
But i cannot remember any software, which decides the manner i want to search.
Sorry, if i still get stuck with this strange issue.
Think that the developers should not ignore the feedback of the users.
cheers mike

@donho
Copy link
Member

donho commented Sep 19, 2023

I don't know, that's why I'm asking. :-)

Let it be 1024 then. I think it's a reasonable value.

@donho
Copy link
Member

donho commented Sep 19, 2023

I don't think tooltips on static label controls work. Is there an alternative suggestion for how to do a tooltip here?

Let's do it on Edit control then.

@alankilborn
Copy link
Contributor

For those that wish to, a chance to offer any early feedback on the UI:

image

@mididoc
Copy link
Author

mididoc commented Sep 20, 2023

excellent.
cheers mike

@donho
Copy link
Member

donho commented Sep 20, 2023

@alankilborn

Please

  1. make the groupbox higher for separating 2 sections, and put the item in question on the top.
  2. enlarge the label and make it right aligned so all the translation could fit in it.

image

@alankilborn
Copy link
Contributor

It's a pity when localization needs have to drive UI design (placement, separation of controls) but it is not a problem for me to make the requested changes.

@donho
Copy link
Member

donho commented Sep 20, 2023

It's a pity when localization needs have to drive UI design (placement, separation of controls) but it is not a problem for me to make the requested changes.

Democracy is a compromised system, isn't it? ;)

@Yaron10
Copy link

Yaron10 commented Sep 20, 2023

Wouldn't Minimum size for auto-checking "In selection": be better? - This is the heart of the issue/setting.

@donho
Copy link
Member

donho commented Sep 20, 2023

Wouldn't Minimum size for auto-checking "In selection": be better? - This is the heart of the issue/setting.

+1

@alankilborn
Copy link
Contributor

Latest version of the UI:

image

Note that I streamlined the wording in the tooltip for a better "English flow".

@Serpens66
Copy link

Serpens66 commented Oct 2, 2023

Hi all,
I just wanted to let you know that I was going to report this "automatic enable" of this checkbox as bug, because it is also driving me crazy and caused alot of bugs in my code =( All the time it enables itself and I get wrong search and especially wrong "replace all" results =/

If I want to search in the selection, I will enable this checkbox myself, I don't want it to activate itself regardless of any circumstances.
I did not fully understand your discussion, but I hope it will be possible in the future for me to disable this "automatic enable" thing.

edit:
and it should be independent of the number of characters I have selected of course. If you will implement this "Minimum size for autochecking" then allow to put "0" into it for disabling autochecking or similar.
edit2:
for me the obvious way to solve it is to add a setting "automatically check -in selection- under some circumstances" yes/no. Case Solved.

@mididoc
Copy link
Author

mididoc commented Oct 2, 2023

Hi,
I would be very happy, if the update would be available ASAP.
This "automatic enable" thing really drives me nuts everyday when I'm editing.
Sorry,
cheers mike

@alankilborn
Copy link
Contributor

I would be very happy, if the update would be available ASAP.

Ha, yea, well we all want things quickly. :-)
You can try the executable from the PR if you'd like, while you're waiting for finalization.

@Yaron10
Copy link

Yaron10 commented Oct 2, 2023

@Serpens66 & @mididoc,

@alankilborn has kindly agreed to work on this issue.
We should be grateful. :)

@mididoc
Copy link
Author

mididoc commented Oct 2, 2023

I would be very happy, if the update would be available ASAP.

Ha, yea, well we all want things quickly. :-) You can try the executable from the PR if you'd like, while you're waiting for finalization.

Hi @alankilborn,
sorry, for my impatience.
What do you mean with 'executable from the PR'
Cheers mike

@mididoc
Copy link
Author

mididoc commented Oct 2, 2023

@alankilborn has kindly agreed to work on this issue.
We should be grateful. :)

ofcourse, i know that.
Cheers mike

@Yaron10
Copy link

Yaron10 commented Oct 2, 2023

@mididoc
Copy link
Author

mididoc commented Oct 6, 2023

@mididoc,

https://ci.appveyor.com/project/donho/notepad-plus-plus/builds/48174137

Hi Yaron10,

Thanks for the link.

Cheers mike

@alankilborn
Copy link
Contributor

@mididoc Click the job name for the N++ you are using, then on the next screen click Artifacts

@mididoc
Copy link
Author

mididoc commented Oct 7, 2023

@mididoc Click the job name for the N++ you are using, then on the next screen click Artifacts

Thanks @alankilborn .
Meanwhile I found this, too.

Works excellent now, thanks lot for the modification.

Cheers mike

@Yaron10
Copy link

Yaron10 commented Oct 8, 2023

@mididoc,

Sorry for the late reply. I wasn't by my PC.

@alankilborn,

👍
Thanks again.

donho pushed a commit to donho/notepad-plus-plus that referenced this issue Oct 20, 2023
Set value to 0 to disable auto-checking "In Selection" checkbox in Find dialog.
Set any value to define the length of selected characters to auto-check "In Selection" checkbox in Find dialog.
The default and maximum value is 1024.

Fix notepad-plus-plus#14108, fix notepad-plus-plus#13677, fix notepad-plus-plus#12639, close notepad-plus-plus#14175
@conky77
Copy link
Contributor

conky77 commented Oct 24, 2023

I created issue #14265 to suggest using &quot; instead of an apostrophe.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

7 participants