在 Notepad++ 中添加选择下一个匹配项(如 Sublime Text 中的 Ctrl + D)

在 Notepad++ 中添加选择下一个匹配项(如 Sublime Text 中的 Ctrl + D)

我正在寻找一种在开源 Notepad++ 中使用以下功能的方法。

在 SublimeText 中如果你按下Ctrl+ D(mac: cmd+D我认为) 会发生以下情况:

  • 如果没有选择,则光标位置将扩展以选择该单词。
  • 否则,还会选择该词的下一个出现位置(无需打开搜索弹出窗口)。

然后,您就可以选择多个可以更改的单词,并且您实际上已经看到了每个地方(而不是全选)。

有什么方法可以在 Notepad++ 中做到这一点吗(也许借助 Autohotkey)?

可选:在 Sublime 中,您还可以使用Ctrl+撤消每个+并使用+跳过一次出现。DCtrlUCtrlK

答案1

我从 Tony Brix 的链接中摘录了我认为最简单、最直接的方法(感谢 Tony)。它使用 NppExec 插件运行代码片段来添加每个热键。

笔记:有一个名为 NP++ 插件更好的多选,但在继续之前我无法让它工作,可能值得一看。

向 NP++ 添加多选下一个匹配的总结步骤

  1. 安装 NppExec 插件- 需要重启核电站
  2. 为每个你想要的热键添加一个脚本/片段
  3. 为每个脚本制作菜单项- 需要重启核电站
  4. 为菜单项提供组合键/热键

步骤 1:安装 NppExec 插件

此插件允许您直接通过控制台运行 N++ 脚本。对于那些不熟悉且急于安装的人,您可以通过选择安装 NppExec 插件。有关更多信息,请参阅NppExec github 自述文件

  1. 插件>插件管理从菜单中
  2. 搜索执行
  3. 勾选该框并点击安装(您需要重新启动 Notepad++)

第 2 步:为每个所需的热键添加代码片段

以下脚本为 NP++ 提供了 VSCode 的多编辑功能,分别为 addNext 和 skip 提供了两个不同的快捷方式。

注意冲突: Ctrl+D对我来说已经使用了,所以你可能也需要注意这一点。要么删除冲突,要么相应地调整为你的环境提供的热键。有关键映射,请访问设置>快捷方式映射器

添加下一个 Ctrl+D

NPP_CONSOLE 0
sci_sendmsg 2690  // SCI_TARGETWHOLEDOCUMENT
sci_sendmsg SCI_SETSEARCHFLAGS 0
sci_sendmsg 2688  // SCI_MULTIPLESELECTADDNEXT

在此处输入图片描述

添加下一个整个单词 Shift+ Ctrl+D

NPP_CONSOLE 0
sci_sendmsg 2690  // SCI_TARGETWHOLEDOCUMENT
sci_sendmsg SCI_SETSEARCHFLAGS SCFIND_WHOLEWORD
sci_sendmsg 2688  // SCI_MULTIPLESELECTADDNEXT

在此处输入图片描述

添加每个 Shift+ Ctrl+L

NPP_CONSOLE 0
sci_sendmsg 2690  // SCI_TARGETWHOLEDOCUMENT
sci_sendmsg SCI_GETSELECTIONEMPTY
if $(MSG_RESULT) == 1 then
  sci_sendmsg SCI_SETSEARCHFLAGS SCFIND_WHOLEWORD
else
  sci_sendmsg SCI_SETSEARCHFLAGS 0
endif
sci_sendmsg 2689  // SCI_MULTIPLESELECTADDEACH
sci_sendmsg 2689  // SCI_MULTIPLESELECTADDEACH

在此处输入图片描述

撤消添加下一个 Ctrl+U

NPP_CONSOLE 0
sci_sendmsg SCI_GETSELECTIONS
set n ~ $(MSG_RESULT) - 1
sci_sendmsg SCI_DROPSELECTIONN $(n)

在此处输入图片描述

跳过 Alt+ Ctrl+D

NPP_CONSOLE 0
sci_sendmsg SCI_SETSEARCHFLAGS SCFIND_NONE
sci_sendmsg 2688  // SCI_MULTIPLESELECTADDNEXT
sci_sendmsg SCI_GETSELECTIONS
set n ~ $(MSG_RESULT) - 2
sci_sendmsg SCI_DROPSELECTIONN $(n)

在此处输入图片描述

跳过整个单词 Alt+ Shift+ Ctrl+D

NPP_CONSOLE 0
sci_sendmsg SCI_SETSEARCHFLAGS SCFIND_NONE
sci_sendmsg 2688  // SCI_MULTIPLESELECTADDNEXT
sci_sendmsg SCI_GETSELECTIONS
set n ~ $(MSG_RESULT) - 2
sci_sendmsg SCI_DROPSELECTIONN $(n)

脚本和评论来自 bitagoras 于 2020-05-04 -源码

从控制台保存上述脚本/代码片段

  1. F6或者...从菜单中插件>执行>执行
  2. 粘贴在一个上面的简短“脚本”执行出现的框
  3. 可选但建议)按“确定”按钮进行测试运行
  4. 再次按下F6;之前的“脚本”被保留并显示在框中
  5. 节省并给它命名(每个脚本上方都有建议)
  6. 好的

速度提示:你需要对每个脚本重复这些步骤您要使用的脚本。除非您想先测试一个脚本,否则在进入下一步之前保存所有脚本会更快。

以上步骤由用户 Alan Kilborn 于 2020-05-21 总结源码

步骤 3:为每个脚本制作菜单项

当命名并保存一个或多个脚本时,必须将它们添加到菜单中,以便可以分配组合键。

速度提示:对所有添加的脚本重复上述步骤,然后按下好的以避免多次重启(除非您希望先测试一次)。

  1. 从菜单插件>执行>高级选项
  2. 在左下角,使用相关脚本下拉菜单选择脚本
  3. 点击添加/修改将其添加到左上角的菜单项列表中 注意“宏子菜单”中的“☑ 位置”是否启用(稍后您将需要它)。

添加菜单项后...点击好的然后应用这些更改重新启动记事本++。

步骤 4:为菜单项提供组合键/热键

  1. 重启后从主菜单启动,转到设置>快捷方式映射器>插件命令标签
  2. 按 NppExec 过滤并向下滚动直到看到新的脚本名称。
  3. 点击脚本你想要一个组合键,点击调整Ctrl,然后选择、AltShift和选定键的适当组合。

对需要组合键的所有脚本重复修改过程。

步骤 3 和 4,根据 PeterJones 的后续评论总结而成 -源码

回溯/如何消除错误

检查或确认已添加脚本的列表

  • 如果启用了宏复选框前往菜单
  • 如果复选框被禁用插件>执行

如果你犯了错误和/或决定删除脚本

  1. 插件>执行>高级选项
  2. 并选择要删除的项目,然后按删除按钮并退出菜单
  3. F6
  4. 选择脚本您想从中删除落下
  5. 节省选择删除选项...不是一个直观的步骤
  6. 点击删除按钮

以上内容与 PeterJones 在原始帖子中稍后发表的一两条评论一致

答案2

我在 Notepad++ 社区页面上找到了这个帖子:

https://notepad-plus-plus.org/community/topic/11360/multi-selection-and-multi-edit

他们正在使用python 脚本插件使用以下脚本创建此功能:

# this script implements the enhanced multi cursor edit functionality

def default_positions():
    return 0, editor.getLength()

def get_pos_of_bookmarks():
    npp_bookmark_marker_id_number = 24
    npp_bookmark_marker_mask = 1 << npp_bookmark_marker_id_number
    _start_position, _end_position = default_positions()
    
    line_nbr = editor.markerNext(_start_position, npp_bookmark_marker_mask)
    if line_nbr != -1:
        _start_position = editor.positionFromLine(line_nbr)
        line_nbr = editor.markerNext(line_nbr + 1, npp_bookmark_marker_mask)
        if line_nbr != -1:
            _end_position = editor.getLineEndPosition(line_nbr)
    return _start_position, _end_position

def get_pos_of_visible_lines():
    first_visible_line = editor.getFirstVisibleLine()
    _start_position = editor.positionFromLine(first_visible_line)
    lines_visible = editor.linesOnScreen()
    last_visible_line = editor.docLineFromVisible(first_visible_line+lines_visible)
    _end_position = editor.getLineEndPosition(last_visible_line)
    return _start_position, _end_position

def get_pos_of_selections():
    _start_position, _end_position = default_positions()
    if editor.getSelections() == 2:
        _start_position = editor.getSelectionNStart(0)
        _end_position = editor.getSelectionNEnd(1)
    return _start_position, _end_position


area_dict = {'a':default_positions,
             'b':get_pos_of_bookmarks,
             's':get_pos_of_selections,
             'v':get_pos_of_visible_lines}
    
editor.beginUndoAction()

def Main():
    _text = editor.getTextRange(editor.getSelectionNStart(0), editor.getSelectionNEnd(0))
    if len(_text) != 0:

        _current_position = editor.getCurrentPos()
        _current_line = editor.lineFromPosition(_current_position)
        _current_word_start_pos = editor.getLineSelStartPosition(_current_line)
        _current_word_end_pos = editor.getLineSelEndPosition(_current_line)

        find_flag = 2 # 0=DEFAULT, 2=WHOLEWORD 4=MATCHCASE 6=WHOLEWORD | MATCHCASE
        mode_options = ' 0=replace,  1=before,  2=afterwards\n'
        area_options = ' a=all, b=bookmarks, s=selected, v=visible'
        expected_results = [x+y for x in ['0','1','2'] for y in ['a','b','s','v']]
           
        result = notepad.prompt(mode_options + area_options, 'Choose the desired option', '0a')
        while result not in expected_results: 
            if result is None:
                return
            result = notepad.prompt(mode_options + area_options, 'Choose the desired option', '0a')

        chosen_mode, chosen_area = result
        area_start_position, area_end_position = area_dict[chosen_area]()
        
        if chosen_mode == '0': # replace whole string version
            editor.setEmptySelection(_current_position)       
            position_tuple = editor.findText(find_flag, area_start_position, area_end_position, _text)
            
            while position_tuple is not None:
                if _current_position not in position_tuple:
                    editor.addSelection(*position_tuple)
                position_tuple = editor.findText(find_flag, position_tuple[1], area_end_position, _text)
                    

        elif chosen_mode == '1': # insert before selected string version
            editor.setEmptySelection(_current_word_start_pos)
            position_tuple = editor.findText(find_flag, area_start_position, area_end_position, _text)
            
            while position_tuple is not None: 
                startpos, endpos = position_tuple
                if startpos != _current_position and endpos != _current_position:
                    editor.addSelection(startpos, startpos)
                else:
                    _current_word_start_pos, _current_word_end_pos = startpos, startpos
                position_tuple = editor.findText(find_flag, endpos, area_end_position, _text)


        elif chosen_mode == '2': # insert after selected string version
            editor.setEmptySelection(_current_word_end_pos)
            position_tuple = editor.findText(find_flag, area_start_position, area_end_position, _text)
            
            while position_tuple is not None: 
                startpos, endpos = position_tuple
                if startpos != _current_position and endpos != _current_position:
                    editor.addSelection(endpos, endpos)
                else:
                    _current_word_start_pos, _current_word_end_pos = endpos, endpos
                position_tuple = editor.findText(find_flag, endpos, area_end_position, _text)

                
        # now add the current selection
        editor.addSelection(_current_word_start_pos, _current_word_end_pos)

Main()
editor.endUndoAction()

答案3

您只需点击 即可F3继续搜索。

答案4

您现在可以使用搜索 > 查找 (Volatile) 下一个此功能。默认热键是CtrlAltF3

相关内容