select / delete string between quote?

Sing
2011-08-17
2013-01-25
  • Sing
    Sing
    2011-08-17

    Can someone help writing scripts for selecting and deleting string between quotes?
    I miss this function from vim.

     
  • Select a string between quotes (based on the current cursor position)

    editor.searchAnchor()
    start = editor.searchPrev(0, '"')
    end = editor.searchNext(0, '"')
    if end == -1:
        end = editor.getLength()
    
    editor.setSelection(start + 1, end)
    

    If there isn't a quote before the cursor, then the selection will start at the beginning of the document, if there isn't a quote after the cursor, then the selection will end at the end of the document.

    Deletion is very similar

    editor.searchAnchor()
    start = editor.searchPrev(0, '"')
    end = editor.searchNext(0, '"')
    if end == -1:
        end = editor.getLength()
    
    editor.setTarget(start + 1, end)
    editor.replaceTarget('')
    editor.gotoPos(start + 1)
    

    To change to single quotes, just change the

    '"'
    

    to

    "'"
    

    .

    Cheers,
    Dave.
    PS. Sorry for the delay in reply - I've had a very busy week!

     
  • Sing
    Sing
    2011-08-24

    @Dave

    Thanks a lot. I enhanced the code you given, so that it with auto detect the nearest quote for selection / deletion, so I can assign only one shortcut for selecting different types of quote.
    I post the code at the bottom of this post for other users who may also want it.
    This is my first python script. It will detect the wrong quote in some case, but it is enough for normal use. I may make more enhancement  to it when I have time.

    And I have few questions:
    1) the "searchPrev()" and "searchNext()" will move the cursor, so during searching quotes, the screen will flash several times. Is there any way to search without affecting the cursor?

    2) How can I move my function "searchQuotePos()" to a file and include it on other script?
    I tried "from Npp import *" and also "import Npp" from the "Context-Help", but it doesn't work. Now, I have to put the same function on 3 files.

    3) This question is no about the select between quotes script, but also related to Python script.
    I use the script you wrote (as below) in https://sourceforge.net/projects/notepad-plus/forums/forum/331753/topic/3817403
    to redefine a word's characters when a tab is clicked.
    But i found that the "Highlight Matching Tag" function of Notepad++ itself will reset the wordchars to default randomly.
    I have tell Don about this bug, but seems he did not quite understand  what I said.
    So i want to know is there a way to set the wordchars before each word selection?

    Details please view the thread:
    https://sourceforge.net/projects/notepad-plus/forums/forum/331753/topic/4620546?message=10605047
    https://sourceforge.net/projects/notepad-plus/forums/forum/331753/topic/4620546?message=10606102
    https://sourceforge.net/projects/notepad-plus/forums/forum/331753/topic/4620546?message=10608949

    def set_word_chars(args):
        editor.setWordChars('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789.')
    notepad.callback(set_word_chars, [NOTIFICATION.BUFFERACTIVATED])
    

    search quote's position function:

    def searchQuotePos():
        curr_pos = editor.getCurrentPos()
        max_pos = editor.getLength()
        editor.searchAnchor()
        start = {};
        end = {};
        start["dq"] = editor.searchPrev(0, '"')
        end["dq"] = editor.searchNext(0, '"')
        start["sq"] = editor.searchPrev(0, "'")
        end["sq"] = editor.searchNext(0, "'")
        start["p"] = editor.searchPrev(0, '(')
        end["p"] = editor.searchNext(0, ')')
        start["b"] = editor.searchPrev(0, '{')
        end["b"] = editor.searchNext(0, '}')
        start["s"] = editor.searchPrev(0, '[')
        end["s"] = editor.searchNext(0, ']')
        start["a"] = editor.searchPrev(0, '<')
        end["a"] = editor.searchNext(0, '>')
        prev_pos = 0;
        prev_type = '';
        for k, v in start.iteritems():
            if v != -1 and v >= prev_pos:
                prev_type = k
                prev_pos = v
        next_pos = max_pos;
        next_type = '';
        for k, v in end.iteritems():
            if v != -1 and v <= next_pos:
                next_type = k
                next_pos = v
        final_type = prev_type;
        if prev_type != next_type:  
            diff_next = next_pos - curr_pos;
            diff_prev = curr_pos - prev_pos;
            if diff_next < diff_prev:
                final_type = next_type
        pos = {};
        pos['start'] = start[final_type]
        pos['end'] = end[final_type]
    
        return pos
    

    select between quotes:

    pos = searchQuotePos();
    editor.setSelection(pos['start'] + 1, pos['end'])
    

    select between quotes (including the quotes itself):

    pos = searchQuotePos();
    editor.setSelection(pos['start'], pos['end'] + 1)
    

    delete between quotes:

    pos = searchQuotePos();
    editor.setTarget(pos['start'] + 1, pos['end'])
    editor.replaceTarget('')
    editor.gotoPos(pos['start']+ 1)
    
     
  • 1. See the documentation on editor.findText()  (SCI_FINDTEXT)

    2. You need to save your function in a separate file, with from Npp import *; at the top, then in the code where you want to use your function, do import mycodefile  (where your file is called mycodefile.py).  Then to use your function, you just need pos = mycodefile.searchQuotePos()

    If you do from mycodefile import *;, then you won't need the mycodefile. prefix.

    3. I'm not sure - I've tried the script and notice a similar behaviour, with word chars being reset far too often.  I think this is a bug in N++, or possibly scintilla, or possibly a plugin.  Just narrowing it down is a bit of a challenge :) 

    As for resetting the wordchars before a selection is made, you could look to register a callback for one of the other events.  Look at the documentation for the NOTIFICATION enum to see what events are available from scintilla.

    Dave.

     
  • Sing
    Sing
    2011-08-26

    Could you please give me the structure of the object returned by Editor.pymlsearch?
    I tried obj.start() and obj.start, but error occur.

    BTW, I looked into NOTIFICATION, but seems there is no way to detect selection action. sigh…

     
  • Sing
    Sing
    2011-08-26

    oh………my mistake, I can use the match object  now.