Skip to content

editor.research() and editor.search() won't search backwards #323

Open

Description

@alankilborn

Under PS 3.0.16.0 (and 2.0.0.0 as well), editor.research() and editor.search() won't search backwards, i.e., when the startPosition argument is greater than the endPosition argument. It return no matches in such a case.

Here is a script which demonstrates the problem, when the script is executed to act upon its own code as input data in the active editor tab in N++:

# -*- coding: utf-8 -*-
from __future__ import print_function

from Npp import *

pos1 = 0; pos2 = editor.getLength()  # forward search, i.e., pos1 < pos2
(pos1, pos2) = (pos2, pos1)  # swap to do backward search

matches = []
editor.research('a', lambda m: matches.append(m.span(0)), 0, pos1, pos2)
print('research:', matches[0]) if len(matches) > 0 else print('research: no matches')

# show that editor.findText() works fine either forward or backward:
ft_pos_tup = editor.findText(FINDOPTION.REGEXP, pos1, pos2, 'a')
print('ft_pos_tup:|{T}|'.format(T=ft_pos_tup))

To see the problem, run the script as written. To see that the script logic works for a forward search, comment out the "swap" line. Note that a call to editor.findText() is included to show that it works correctly for either backward or forward searches.

Activity

  1. pryrt commented on Jan 23, 2024

    @pryrt
    Contributor

    And in case there's confusion as to why it matters whether a search is done forward or backward: it's the same reason that saved diff scripts are executed from the end to the beginning: a change early in the document can change the line number later in the document, so some changes work better when going backward -- this is especially true with .search and .research and their callbacks -- since callbacks can do things like run menu commands on sections of text.

    When I developed this script, I had to resort to doing a loop of 1-match calls to .research() and manually track my start position. When I tried just a single call to do multiple matches, it got confused. But if I could have run it backward, it would have prevented the growing text from confusing .research(), and I could have done it as one call rather than a loop of calls.

  2. alankilborn commented on Jan 23, 2024

    @alankilborn
    Author

    why it matters whether a search is done forward or backward

    Well, I didn't think we'd have to justify a backward search ... :-)

    My use case is that I'm searching for a specific string/regex either forward or backward from the current caret position.
    While I can certainly write compensating code, I'd rather just have an intuitive library call do the work for me.
    There's nothing in the PS docs for these functions that require startPosition be less than endPosition.

  3. alankilborn commented on Jan 24, 2024

    @alankilborn
    Author

    Workaround:

    Insert the following code right after matches = [] in the script above:

    if pos1 > pos2:  # workaround!
        __ = editor.findText(FINDOPTION.REGEXP, pos1, pos2, 'a')
        if __ is not None:
            (pos1, pos2) = __
            # pos1 will now be LESS than pos1 so editor.research() will succeed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions