<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[In Selection' grayed out in the find/replace box  in Column Alt+shift select]]></title><description><![CDATA[<p dir="auto">Re: <a href="/topic/20586/in-selection-grayed-out-in-the-find-replace-box">'In Selection' grayed out in the find/replace box</a><br />
In Selection’ grayed out in the find/replace box<br />
Works fine for Select all BUT not for ALt+shift column selection</p>
<p dir="auto">Is this by design?</p>
]]></description><link>https://community.notepad-plus-plus.org/topic/22180/in-selection-grayed-out-in-the-find-replace-box-in-column-alt-shift-select</link><generator>RSS for Node</generator><lastBuildDate>Wed, 19 Aug 2026 12:53:06 GMT</lastBuildDate><atom:link href="https://community.notepad-plus-plus.org/topic/22180.rss" rel="self" type="application/rss+xml"/><pubDate>Thu, 25 Nov 2021 01:31:46 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to In Selection' grayed out in the find/replace box  in Column Alt+shift select on Mon, 29 Nov 2021 13:16:55 GMT]]></title><description><![CDATA[<p dir="auto">So this critical shortcoming in Notepad++ has come up many times before, and probably even more times than I list here:</p>
<ul>
<li><a href="https://community.notepad-plus-plus.org/topic/14644">https://community.notepad-plus-plus.org/topic/14644</a></li>
<li><a href="https://community.notepad-plus-plus.org/topic/15606">https://community.notepad-plus-plus.org/topic/15606</a></li>
<li><a href="https://community.notepad-plus-plus.org/topic/20519">https://community.notepad-plus-plus.org/topic/20519</a></li>
<li><a href="https://community.notepad-plus-plus.org/topic/20584">https://community.notepad-plus-plus.org/topic/20584</a></li>
<li><a href="https://community.notepad-plus-plus.org/topic/20586">https://community.notepad-plus-plus.org/topic/20586</a></li>
<li><a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/94" rel="nofollow ugc">https://github.com/notepad-plus-plus/notepad-plus-plus/issues/94</a></li>
<li><a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/760" rel="nofollow ugc">https://github.com/notepad-plus-plus/notepad-plus-plus/issues/760</a></li>
<li><a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/5113" rel="nofollow ugc">https://github.com/notepad-plus-plus/notepad-plus-plus/issues/5113</a></li>
<li><a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/8450" rel="nofollow ugc">https://github.com/notepad-plus-plus/notepad-plus-plus/issues/8450</a></li>
<li><a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/9584" rel="nofollow ugc">https://github.com/notepad-plus-plus/notepad-plus-plus/issues/9584</a></li>
<li><a href="https://github.com/notepad-plus-plus/notepad-plus-plus/issues/10012" rel="nofollow ugc">https://github.com/notepad-plus-plus/notepad-plus-plus/issues/10012</a></li>
</ul>
<p dir="auto">A few times before when I’ve seen such postings, I’ve thought about sharing my PythonScript method for solving it, but, well, sometimes you have something nice that works for you, but to share it you have to put more “shine” on it.  This time I’ve attempted to do that, and I’ve shared the cleaned-up script below.</p>
<p dir="auto">Aside: In my response to one of the Community threads above, I see that I promised to post something “soon”.  Well, that was back in January of 2021, so “soon” is relative. :-)</p>
<p dir="auto">The script works on multiple selection types:</p>
<ul>
<li>a normal single stream selection (but why? Just use Notepad++'s own <em>Replace All</em>)</li>
<li>column-block selection (the issue posed by the OP to this thread)</li>
<li>multiple stream selections (that have been selected with the “Multi-editing” feature of Notepad++ turned on):<br />
<img src="https://i.imgur.com/N5zwwUn.png" alt="Imgur" class=" img-fluid img-markdown" /></li>
</ul>
<p dir="auto">The script is fairly simple to use.  Make your selection(s) and then run the script.  You will be prompted through a series of dialog boxes to provide your parameters for the replacement operation:</p>
<ul>
<li>
<p dir="auto">specifying what you want to find:<br />
<img src="https://i.imgur.com/8PXi93j.png" alt="Imgur" class=" img-fluid img-markdown" /></p>
</li>
<li>
<p dir="auto">specifying what you want to replace the found matches with:<br />
<img src="https://i.imgur.com/VDuC9hq.png" alt="Imgur" class=" img-fluid img-markdown" /></p>
</li>
<li>
<p dir="auto">specifying other options, like case sensitivity, regular expression mode, etc.:<br />
<img src="https://i.imgur.com/nfJ9VS9.png" alt="Imgur" class=" img-fluid img-markdown" /><br />
To use the options, you put an <code>x</code> inside the brackets in front of an option you want to select; example to select case sensitivity:<br />
<img src="https://i.imgur.com/4Un1QP2.png" alt="Imgur" class=" img-fluid img-markdown" /></p>
</li>
</ul>
<p dir="auto">After everything has been specified, press OK and the replacement(s) will be made in the active selection(s).</p>
<p dir="auto">If you have chosen the “pre-replace-count-preview” option, you will get a prompt like this before the document text is changed:<br />
<img src="https://i.imgur.com/RaHN4Cy.png" alt="Imgur" class=" img-fluid img-markdown" /><br />
Choosing <code>Yes</code> from there will do the replacing without further prompt.<br />
Choosing <code>No</code> will result in an additional prompt:<br />
<img src="https://i.imgur.com/O8zO02Z.png" alt="Imgur" class=" img-fluid img-markdown" /></p>
<p dir="auto">If you have selected the “post-replacement-summary” option, after replacements have been made, you will see a box like this appear:<br />
<img src="https://i.imgur.com/fgDw9ML.png" alt="Imgur" class=" img-fluid img-markdown" /></p>
<p dir="auto">That’s it; here’s the listing for the script, <code>ReplaceAllInSelections.py</code>:</p>
<pre><code class="language-z"># -*- coding: utf-8 -*-

from Npp import *
import re
import inspect

class RAIS(object):

    def __init__(self):
        self.script_name = inspect.getframeinfo(inspect.currentframe()).filename.split('\\')[-1]
        self.remembered_find_regex_str = ''
        self.remembered_repl_regex_str = ''
        self.remembered_case_sens_setting = False
        self.remembered_whole_word_setting = False
        self.remembered_regex_setting = False
        self.remembered_pre_repl_preview_setting = False
        self.remembered_post_repl_summary_setting = False
        self.help_str = '''
        HELP

        pre-replace-preview : pops up a box BEFORE replacements are
        made, telling how many there will be; at that point there
        will be a way to cancel so that the replacements aren't
        made; and a way to leave the matches selected

        post-replace-summary : pops up a box after replacements are
        made, telling how many were made
        '''

    def mb(self, msg, flags=0, title=''):
        if len(title) == 0: title = self.script_name
        return notepad.messageBox(msg, title, flags)

    def custom_rereplace(self, find_what, replace_with, ignore_case_flag=0, max_num_of_replacements=0, start_end_pos_tup=None):
        # if start_end_pos_tup is None, replace will be done in all active selections
        leave_caret_here = None
        start_end_pos_tup_list = []
        if start_end_pos_tup == None:
            if editor.getSelectionEmpty():
                start_end_pos_tup_list.append((0, editor.getTextLength()))
                leave_caret_here = editor.getCurrentPos()
            else:
                for n in range(editor.getSelections()):
                    (s, e) = (editor.getSelectionNStart(n), editor.getSelectionNEnd(n))
                    append_it = True
                    if 1:
                        # prevent, e.g., a regex search for ^ from replacing "outside" a column-block's visual region
                        #  (could happen on empty lines inside the block)
                        if editor.getSelectionNAnchor(n) &lt;= editor.getSelectionNCaret(n):
                            if editor.getSelectionNAnchorVirtualSpace(n) &gt; 0: append_it = False
                        else:
                            if editor.getSelectionNCaretVirtualSpace(n) &gt; 0: append_it = False
                    if append_it: start_end_pos_tup_list.append((s, e))
                start_end_pos_tup_list.sort()
        else:
            start_end_pos_tup_list.append(start_end_pos_tup)
        running_offset = 0
        first = True
        if editor.selectionIsRectangle():
            # get out of column selection mode as it messes up trying to correctly set selections later
            editor.setEmptySelection(editor.getCurrentPos())
        for (s, e) in start_end_pos_tup_list:
            s_plus_ro = s + running_offset
            e_plus_ro = e + running_offset
            old_len = editor.getLength()
            editor.rereplace(find_what, replace_with, ignore_case_flag, s_plus_ro, e_plus_ro, max_num_of_replacements)
            new_len = editor.getLength()
            if leave_caret_here == None:
                new_sel_end = e_plus_ro + new_len - old_len
                if first:
                    editor.setSelection(new_sel_end, s_plus_ro)
                else:
                    editor.addSelection(new_sel_end, s_plus_ro)
            running_offset += new_len - old_len
            first = False
        if leave_caret_here != None: editor.setEmptySelection(leave_caret_here)

    def run(self):

        editor.setMultipleSelection(True)
        line_ending = ['\r\n', '\r', '\n'][editor.getEOLMode()]
        num_selections = editor.getSelections()
        # editor.getSelText() returns...:
        #  skinny caret rect block always returns ''
        #  non-skinny rect block returns line data separated by line-endings
        #  non-skinny rect block totally in virtual space returns only line-endings
        #   example: 3-line rect block in virtual space in windows file returns '\r\n\r\n\r\n'
        #  non-rect multiple-selection text is returned contiguously with no delimiters of any type between!
        if editor.selectionIsRectangle():
            if len(editor.getSelText()) &lt;= num_selections * len(line_ending):
                self.mb('No text in rectangular selection; nothing to do!')
                return
        else:
            if len(editor.getSelText()) == 0:
                if num_selections &gt; 1:
                    self.mb('No text in stream selections; nothing to do!')
                else:
                    self.mb('No selected text; nothing to do!')
                return

        find_regex_str = self.remembered_find_regex_str
        repl_regex_str = self.remembered_repl_regex_str
        opt_case_sens = 'x' if self.remembered_case_sens_setting else ' '
        opt_whole_word = 'x' if self.remembered_whole_word_setting else ' '
        opt_regex = 'x' if self.remembered_regex_setting else ' '
        opt_pre = 'x' if self.remembered_pre_repl_preview_setting else ' '
        opt_post = 'x' if self.remembered_post_repl_summary_setting else ' '

        input_stage = 'find'

        while True:  # loop to validate user input

            if input_stage == 'find':
                user_reply_to_find_query = notepad.prompt(
                    ' ' * 10 + 'Enter ? alone for help\r\nEnter FIND string:',
                    self.script_name, find_regex_str)
                if user_reply_to_find_query == None: return  # user cancel
                if len(user_reply_to_find_query) == 0: continue
                if user_reply_to_find_query == '?':
                    self.mb(self.help_str)
                    continue
                find_regex_str = user_reply_to_find_query
                input_stage = 'replace'

            if input_stage == 'replace':
                f = find_regex_str[:20]
                if f != find_regex_str: f += '...'
                user_reply_to_replace_query = notepad.prompt(
                    ' ' * 5 + 'FIND string = {}\r\nEnter REPLACE string:'.format(f),
                    self.script_name, repl_regex_str)
                if user_reply_to_replace_query == None:
                    input_stage = 'find'; continue  # go back to previous step
                if len(user_reply_to_replace_query) == 0:
                    ync = self.mb('Replace matches with nothing, effectively deleting them?\r\n\r\n'
                        'YES = yes, delete matches\r\nNO = prompt again for what to replace with\r\n'
                        'CANCEL = go back a step (to prompt for find expression)',
                        MESSAGEBOXFLAGS.YESNOCANCEL)
                    if ync == MESSAGEBOXFLAGS.RESULTCANCEL:
                        input_stage = 'find'; continue  # go back to previous step
                    elif ync == MESSAGEBOXFLAGS.RESULTNO:
                        continue  # repeat current step
                repl_regex_str = user_reply_to_replace_query
                input_stage = 'options'

            if input_stage == 'options':
                f = find_regex_str[:10]
                if f != find_regex_str: f += '...'
                r = repl_regex_str[:10]
                if r != repl_regex_str: r += '...'
                options_prompt = '[  {c}  ]match-case        ' + \
                    '[  {w}  ]whole-word        ' + \
                    '[  {re}  ]regular-expression' + \
                    '\r\n' + \
                    '[  {pre}  ]pre-replace-count-preview            ' + \
                    '[  {post}  ]post-replace-summary'
                options_prompt = options_prompt.format(
                    c=opt_case_sens, w=opt_whole_word, re=opt_regex, pre=opt_pre, post=opt_post)
                user_reply_to_options_query = notepad.prompt(
                        ' ' * 5 + \
                        'FIND string = {}     ' + \
                        'REPLACE string = {}' + \
                        '\r\n' + \
                        'Select OPTIONS:               ' + \
                        'Put any character inside the [ ] to select'.format(
                        f, r if len(r) &gt; 0 else 'NOTHING!'), self.script_name, options_prompt)
                if user_reply_to_options_query == None or len(user_reply_to_options_query) == 0:
                    # go back to previous step
                    input_stage = 'replace'
                    continue
                if re.sub(r'\\[[^]]+\\]', r'[]', options_prompt) != \
                        re.sub(r'\\[[^]]+\\]', r'[]', user_reply_to_options_query):
                    self.mb('Trouble parsing the options; please try again')
                    continue
                options_str = user_reply_to_options_query

            def check_option(opt):  # look in the [ ] boxes; return True if any non-space there
                m = re.search(r'\\[([^]]+)\\]' + opt, options_str)
                return True if m and m.group(1) != ' ' * len(m.group(1)) else False
            doing_case_sensitive = check_option('match-case')
            doing_whole_word = check_option('whole-word')
            doing_regex = check_option('regular-expression')
            doing_pre_replace_preview = check_option('pre-replace-count-preview')
            doing_post_replace_summary = check_option('post-replace-summary')

            self.remembered_find_regex_str = find_regex_str
            self.remembered_repl_regex_str = repl_regex_str
            self.remembered_case_sens_setting = doing_case_sensitive
            self.remembered_whole_word_setting = doing_whole_word
            self.remembered_regex_setting = doing_regex
            self.remembered_pre_repl_preview_setting = doing_pre_replace_preview
            self.remembered_post_repl_summary_setting = doing_post_replace_summary

            if doing_regex:
                try:
                    editor.research(find_regex_str, lambda _: None)  # test regex for validity
                except RuntimeError as r:
                    self.mb('Error in search regular expression:\r\n\r\n'
                        '{0}\r\n\r\n'
                        '{1}\r\n\r\n\r\n'
                        'Click OK to try entering your find expression again'.format(find_regex_str, str(r)))
                    input_stage = 'find'
                    continue

            break

        total_number_of_matches = 0

        if not doing_regex:
            find_regex_str = r'\Q' + find_regex_str + r'\E'
            # prevent problems with use of literal parenthesis characters in replace expression:
            repl_regex_str = re.sub(r'(?&lt;!\\)([()])', r'\\\1', repl_regex_str)  # replace parens with backslash-parens
        if doing_whole_word: find_regex_str = r'\b' + find_regex_str + r'\b'
        find_regex_str = '(?{}i)'.format('-' if doing_case_sensitive else '') + find_regex_str

        match_pos_span_tup_list = []
        def match_found_func(m): match_pos_span_tup_list.append(m.span(0))
        for n in range(editor.getSelections()):
            editor.research(find_regex_str, match_found_func, 0, editor.getSelectionNStart(n), editor.getSelectionNEnd(n))
        total_number_of_matches = len(match_pos_span_tup_list)
        if total_number_of_matches == 0:
            self.mb('No matches found for :\r\n\r\n{}'.format(self.remembered_find_regex_str))
            return

        if doing_pre_replace_preview:
            if self.mb('Make {tnom} replacement{s}?\r\n\r\n'
                    'Choose NO to not make the replacement{s} and see additional choices'.format(
                    tnom=total_number_of_matches, s='s' if total_number_of_matches &gt; 1 else ''),
                    MESSAGEBOXFLAGS.YESNO) == MESSAGEBOXFLAGS.RESULTNO:
                if self.mb('End script and leave the {tnom} match{es} {ms}selected?\r\n\r\n'
                        'Choosing NO will end and leave the original search range selected'.format(
                        tnom=total_number_of_matches,
                        es='es' if total_number_of_matches &gt; 1 else '',
                        ms='multi-' if total_number_of_matches &gt; 1 else ''),
                        MESSAGEBOXFLAGS.YESNO) == MESSAGEBOXFLAGS.RESULTYES:
                    first = True
                    # get out of column selection mode as it messes up trying to correctly set selections later
                    editor.setEmptySelection(match_pos_span_tup_list[0][0])
                    for (s, e) in match_pos_span_tup_list:
                        editor.setSelection(e, s) if first else editor.addSelection(e, s)
                        first = False
                return

        editor.beginUndoAction()
        self.custom_rereplace(find_regex_str, repl_regex_str)
        editor.endUndoAction()

        if not doing_pre_replace_preview and doing_post_replace_summary:
            self.mb('Replacements made: {}'.format(total_number_of_matches))

if __name__ == '__main__':
    try:
        rais
    except NameError:
        rais = RAIS()
    rais.run()
</code></pre>
]]></description><link>https://community.notepad-plus-plus.org/post/71694</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/71694</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Mon, 29 Nov 2021 13:16:55 GMT</pubDate></item><item><title><![CDATA[Reply to In Selection' grayed out in the find/replace box  in Column Alt+shift select on Mon, 29 Nov 2021 13:15:21 GMT]]></title><description><![CDATA[<p dir="auto"><em><strong>NOTE: I posted earlier in this thread, but unfortunately the code listing in that posting was affected by the forum bug whereby a backslash followed by a bracket (<code>[</code> or <code>]</code>) is not rendered correctly.  Because I can’t edit that posting to correct the problem, I deleted the posting in its entirety and am reposting it below, hopefully with the problem corrected…</strong></em></p>
]]></description><link>https://community.notepad-plus-plus.org/post/71693</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/71693</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Mon, 29 Nov 2021 13:15:21 GMT</pubDate></item><item><title><![CDATA[Reply to In Selection' grayed out in the find/replace box  in Column Alt+shift select on Thu, 25 Nov 2021 02:06:23 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/user/mrg9999" aria-label="Profile: mrg9999">@<bdi>mrg9999</bdi></a> said in <a href="/post/71576">In Selection' grayed out in the find/replace box in Column Alt+shift select</a>:</p>
<blockquote>
<p dir="auto">Is this by design?</p>
</blockquote>
<p dir="auto">Yes, you can’t do these operations on a column block.</p>
]]></description><link>https://community.notepad-plus-plus.org/post/71577</link><guid isPermaLink="true">https://community.notepad-plus-plus.org/post/71577</guid><dc:creator><![CDATA[Alan Kilborn]]></dc:creator><pubDate>Thu, 25 Nov 2021 02:06:23 GMT</pubDate></item></channel></rss>