Multi editing using Notepad++





  • @Prince-Patni

    The info on multi-editing, although not incorrect, for me is a bit “meh”. You still have to click each spot you want a new caret to appear; how hard is it to paste the desired text right after doing that and dispense with all of the “type it and watch it appear in n places” visual magic? More often than not, I already have the text in the clipboard…

    I have yet to see a great use for multi-editing as it is implemented in Notepad++. Maybe someone can convince me that it really is a great feature (by providing an example showing why).



  • @Alan-Kilborn said:

    convince me … by providing an example

    Convince you? Likely not. But I occasionally use the feature when I have a if/elseif/elseif… block (or select block, or similar) where I want to add the same thing in similar places, but haven’t yet typed it the first time to get it into the clipboard.

    It’s not a killer/must-have feature for me (because I could very easily type it the once, then use copy/paste to replicate to the other locations), but after learning the feature existed, I do occasionally use it.



  • @Alan-Kilborn

    You are right, the way multi-editing is implemented currently is not very useful - to much hassle to place the cursor at multiple locations and you could easily miss one location.

    But with the new Scintilla commands SCI_MULTIPLESELECTADDNEXT and SCI_MULTIPLESELECTADDEACH we got the missing features to enjoy the power of multi-editing. If you are sure you want to overtype all occurences of a certain string send SCI_MULTIPLESELECTADDEACH. If you know that the string only occurs in a few locations near by the cursor (e.g. an if..else...endif block) send SCI_MULTIPLESELECTADDNEXT multiple times. Of course a scripting plugin is needed to be able to send these commands to Scintilla.

    In this comment @dail posted some Lua code to emulate SCI_MULTIPLESELECTADDNEXT in Notepad++ versions prior to v7.7 (which introduced the Scintilla version necessary for the two commands mentioned above). I was able to modify it to create an emulator for SCI_MULTIPLESELECTADDEACH as well (maybe I found that code somewhere, too), here are the two functions:

    npp.AddShortcut("Selection Add Next", "", function()
      -- From SciTEBase.cxx
      local flags = SCFIND_WHOLEWORD -- can use 0
    
      editor:SetTargetRange(0, editor.TextLength)
      editor.SearchFlags = flags
    
      -- From Editor.cxx
      if editor.SelectionEmpty or not editor.MultipleSelection then
        local startWord = editor:WordStartPosition(editor.CurrentPos, true)
        local endWord   = editor:WordEndPosition(startWord, true)
    
        editor:SetSelection(startWord, endWord)
      else
        local i = editor.MainSelection
        local s = editor:textrange(editor.SelectionNStart[i], editor.SelectionNEnd[i])
        local searchRanges = {{editor.SelectionNEnd[i], editor.TargetEnd}, {editor.TargetStart, editor.SelectionNStart[i]}}
    
        for _, range in pairs(searchRanges) do
          editor:SetTargetRange(range[1], range[2])
    
          if editor:SearchInTarget(s) ~= -1 then
            editor:AddSelection(editor.TargetStart, editor.TargetEnd)
    
            -- To scroll main selection in sight
            editor:ScrollRange(editor.TargetStart, editor.TargetEnd)
    
            break
          end
        end
      end
    
      -- To turn on Notepad++ multi select markers
      editor:LineScroll(0, 1)
      editor:LineScroll(0, -1)
    end)
    
    
    npp.AddShortcut("Selection Add All", "", function()
      local flags     = SCFIND_WHOLEWORD -- can use 0
      local startWord = -1
      local endWord   = -1
      local s         = ""
    
      editor.SearchFlags = flags
    
      if editor.SelectionEmpty or not editor.MultipleSelection then
        startWord = editor:WordStartPosition(editor.CurrentPos, true)
        endWord   = editor:WordEndPosition(startWord, true)
    
        editor:SetSelection(startWord, endWord)
      else
        local i   = editor.MainSelection
    
        startWord = editor.SelectionNStart[i]
        endWord   = editor.SelectionNEnd[i]
      end
    
      s = editor:textrange(startWord, endWord)
    
      while true do
        editor:SetTargetRange(0, editor.TextLength)
    
        local i            = editor.MainSelection
        local searchRanges = {{editor.SelectionNEnd[i], editor.TargetEnd}, {editor.TargetStart, editor.SelectionNStart[i]}}
        local itemFound    = false
    
        for _, range in pairs(searchRanges) do
          editor:SetTargetRange(range[1], range[2])
    
          if editor:SearchInTarget(s) ~= -1 then
            editor:AddSelection(editor.TargetStart, editor.TargetEnd)
            itemFound = true
            break
          end
        end
    
        if editor.TargetStart == startWord and
           editor.TargetEnd   == endWord   or
           not itemFound                   then
          break
        end
      end
    
      -- To turn on Notepad++ multi select markers
      editor:LineScroll(0, 1)
      editor:LineScroll(0, -1)
    end)
    

Log in to reply