Bookmark by style



  • First post but a long time user.

    I often use NP++ for reviewing logs and I find it very easy to right-click and style all occurrences of certain text (e.g., IP addresses) without having to use the search dialog each time.

    What I was hoping to find is a way to bookmark all lines containing a specific style.

    Is there a way to do this?

    If not, could it be considered as an enhancement request?

    Thanks



  • @PhilBiggs said:

    Is there a way to do this?

    Not normally, no. But if you are willing to use the Pythonscript plugin, I’m sure we can get it accomplished. How about it?

    I’m thinking of a modification to some scripting/ideas found in these places previously:

    At first glance, these postings don’t work with “styles” but when you consider that (red)marking is just another “style”, you might start to see the applicability.

    Anyway, if you come back, let me know your enthusiasm for a scripted solution.

    could it be considered as an enhancement request?

    It’s probably a bit “special need” to be put into core Notepad++, but you can always make a feature request if you want.



  • Thanks for your reply, Alan.

    I take your point about it being a special need. In fact, it’s not something I need to do very often. I was just looking for a quicker (low click count) way to bookmark already identified lines, mostly so that I could then copy those and paste them into a new file for further examination/manipulation. After reading those other threads I can see that my use of Notepad++ is relatively unsophisticated.

    I really appreciate your offer but I figured that if it was something others could see value in, then they could support the idea here - or tell me the solution already existed.

    I certainly would not ask you to invest any of your time in producing a solution for my corner case.



  • @PhilBiggs said:

    I take your point about it being a special need

    This part is funny because most people don’t understand why their feature request isn’t the most valuable thing on the planet. Sure, there are some great new feature requests, but most are made by people that just don’t get why only they are trying to do something a certain way…

    I certainly would not ask you to invest any of your time in producing a solution for my corner case

    Thanks for protecting my time! :)

    But really, from those above links, it is really 90% written already. Here’s why, with some background:

    Notepad++ has a feature where you can redmark text based upon a search expression. This is similar to what you do with “styling” text, except in your case the text is constant; it isn’t a variable expression like it can be with redmarking (and regular-expressions).

    Often people want to be able to copy their marked search results to the clipboard, and often want to do so on a whole-line basis. It may surprise you to know that currently in Notepad++ there is no way to do the former, and the latter while possible has some limitations.

    That limitation is that if a search expression results in matches that span multiple lines, only the FIRST line of the match is bookmarked. Thus for individuals that need to copy ALL of these matched lines (via Search > Bookmark > Copy Bookmarked Lines), they are out of luck.

    So if we haven’t had a TL;DR and you are still with me, what the script found in one of the links above tries to do is to overcome this limitation by searching for all redmarked text and then bookmark all of the lines that have any redmarking on them at all. Well, since redmarking is just another type of “style” (indeed, in Notepad++ it is kind of a “sixth” style (see the last entry on the Search > Jump Up (or Down) menu), it truly is easy to extend the existing script to cover all styles.

    I haven’t written the script yet, but I was thinking it might have a user-interface like this when you run it:

    Imgur

    What one would do is to select a style (or styles), like so:

    Imgur

    And click OK to execute.

    Any thoughts from the OP or anyone else on this?



  • Since I don’t use the highlight provided by Style #1 - #5 all that much, I went back to refamiliarize myself with how they work. I noticed something odd. If I highlight (select) some text and apply a style to it, the style highlighting will do matches in both full words and inside other words, see here:

    Imgur

    This made me suspicious so I opened the Find window and ticked Match whole words only and then cleared out my styling and then did it again. I got a different result:

    Imgur

    This sort of makes me uncomfortable. :P



  • Can that be remedied with the Settings=>Preferences=>Highlighting=>“Use Find dialog settings” checkbox being unchecked?

    For instance when I do your experiment with that box unchecked and the above 2 boxes from that settings (Match Case, Match whole word only") checked, it performs as expected styling the only two “highlight” words, not the “highlighting” word. When I instead check the “Use Find dialog settings” checkbox, the above 2 checkboxes are automatically unchecked and in my Find dialog, they are unchecked as well and then styling performs as in your graphic (selecting all 3 instances, including the “highlight” portion of the “highlighting” word.

    Cheers.



  • @Michael-Vincent

    Interesting.

    Here’s what it looks like when I do my case #1 from above:

    Imgur

    And here’s for my case #2:

    Imgur



  • I should note I have the “Enable” checkbox under “Smart Highlighting” always checked.



  • @Michael-Vincent said:

    I should note I have the “Enable” checkbox under “Smart Highlighting” always checked.

    Yes, but I guess my point was that I DON’T and still the “styling” is following the Find settings anyway (of course “styling” isn’t “Smart Highlighting”… so maybe it is moot).



  • Okay, then… well, here is the script I mentioned earlier; finished it over lunchtime today. Instructions for interacting with it are pretty much found in the two screenshots a bit up in this thread. Enjoy.

    import re
    
    def main():
    
        MARK_BOOKMARK = 24  # N++ normal bookmark marker number; identifier pulled from N++ source code
    
        # identifiers pulled from N++ source code:
        SCE_UNIVERSAL_FOUND_STYLE_EXT1 = 25  # N++ style 1 indicator number
        SCE_UNIVERSAL_FOUND_STYLE_EXT2 = 24  # N++ style 2 indicator number
        SCE_UNIVERSAL_FOUND_STYLE_EXT3 = 23  # N++ style 3 indicator number
        SCE_UNIVERSAL_FOUND_STYLE_EXT4 = 22  # N++ style 4 indicator number
        SCE_UNIVERSAL_FOUND_STYLE_EXT5 = 21  # N++ style 5 indicator number
        SCE_UNIVERSAL_FOUND_STYLE = 31  # N++ red-"mark" feature highlighting style indicator number
    
        def is_line_bookmarked(line_nbr): return (editor.markerGet(line_nbr) & (1 << MARK_BOOKMARK)) != 0
    
        def highlight_indicator_range_tups_generator(indicator_number):
            if editor.indicatorEnd(indicator_number, 0) == 0: return
            indicator_end_pos = 0  # set special value to key a check the first time thru the while loop
            while True:
                if indicator_end_pos == 0 and editor.indicatorValueAt(indicator_number, 0) == 1:
                    indicator_start_pos = 0
                else:
                    indicator_start_pos = editor.indicatorEnd(indicator_number, indicator_end_pos)
                indicator_end_pos = editor.indicatorEnd(indicator_number, indicator_start_pos)
                if indicator_start_pos == indicator_end_pos: break  # no more matches
                yield (indicator_start_pos, indicator_end_pos)
    
        user_input = notepad.prompt('Select style(s) you want to bookmark lines of:',
            '',
            '[   ] Style #1      [   ] Style #2\r\n[   ] Style #3      [   ] Style #4\r\n[   ] Style #5      [   ] Redmark\r\n\r\n[   ] CLEAR bookmarks instead of setting, for items chosen')
        if user_input == None: return
        if len(user_input) == 0: return
        user_input = re.sub(r'\s{4,}', '\r\n', user_input)
        ui_choices_list = user_input.splitlines()
        selected = ''
        for uic in ui_choices_list:
            m = re.search(r'[([^]]+)]', uic)
            if m and m.group(1) != ' ' * len(m.group(1)):
                selected += uic
        if len(selected) == 0: return
    
        indicator_number_list = []
        if '1' in selected: indicator_number_list.append(SCE_UNIVERSAL_FOUND_STYLE_EXT1)
        if '2' in selected: indicator_number_list.append(SCE_UNIVERSAL_FOUND_STYLE_EXT2)
        if '3' in selected: indicator_number_list.append(SCE_UNIVERSAL_FOUND_STYLE_EXT3)
        if '4' in selected: indicator_number_list.append(SCE_UNIVERSAL_FOUND_STYLE_EXT4)
        if '5' in selected: indicator_number_list.append(SCE_UNIVERSAL_FOUND_STYLE_EXT5)
        if 'red' in selected.lower(): indicator_number_list.append(SCE_UNIVERSAL_FOUND_STYLE)
        clearing_not_setting = True if 'clear' in selected.lower() else False
    
        at_least_1_match_of_style = False
        at_least_1_bookmark_change_made = False
    
        for indic_number in indicator_number_list:
    
            for (styled_start_pos, styled_end_pos) in highlight_indicator_range_tups_generator(indic_number):
    
                at_least_1_match_of_style = True
    
                bookmark_start_line = editor.lineFromPosition(styled_start_pos)
                bookmark_end_line = editor.lineFromPosition(styled_end_pos)
    
                for bm_line in range(bookmark_start_line, bookmark_end_line + 1):
    
                    if clearing_not_setting:
                        if is_line_bookmarked(bm_line):
                            editor.markerDelete(bm_line, MARK_BOOKMARK)
                            at_least_1_bookmark_change_made = True
                    else:
                        if not is_line_bookmarked(bm_line):
                            editor.markerAdd(bm_line, MARK_BOOKMARK)
                            at_least_1_bookmark_change_made = True
    
        if at_least_1_match_of_style:
            if at_least_1_bookmark_change_made:
                notepad.messageBox('Lines with selected style(s) have been {}bookmarked.'.format('un' if clearing_not_setting else ''), '')
            else:
                notepad.messageBox('No changes in bookmarks made.', '')
        else:
            notepad.messageBox('No text found matching selected style(s).', '')
    
    main()
    

Log in to reply