72

Я хочу отфильтровать файл, который я редактирую, в Sublime Text 2, чтобы строки содержали определенную строку, если возможно, включая регулярные выражения.

Рассмотрим следующий файл:

foo bar
baz
qux
quuux baz

При фильтрации по ba результат должен быть:

foo bar
baz
quuux baz

Как я могу это сделать?

4 ответа4

87

Sublime Text 2 - это расширяемый редактор с Python API. Вы можете создавать новые команды (называемые плагинами) и делать их доступными из пользовательского интерфейса.

Добавление базового плагина TextCommand для фильтрации

В Sublime Text 2 выберите Инструменты »Новый плагин и введите следующий текст:

import sublime, sublime_plugin

def filter(v, e, needle):
    # get non-empty selections
    regions = [s for s in v.sel() if not s.empty()]

    # if there's no non-empty selection, filter the whole document
    if len(regions) == 0:
        regions = [ sublime.Region(0, v.size()) ]

    for region in reversed(regions):
        lines = v.split_by_newlines(region)

        for line in reversed(lines):
            if not needle in v.substr(line):
                v.erase(e, v.full_line(line))

class FilterCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def done(needle):
            e = self.view.begin_edit()
            filter(self.view, e, needle)
            self.view.end_edit(e)

        cb = sublime.get_clipboard()
        sublime.active_window().show_input_panel("Filter file for lines containing: ", cb, done, None, None)

Сохранить как filter.py в ~/Library/Application Support/Sublime Text 2/Packages/User

Интеграция с пользовательским интерфейсом

Чтобы добавить этот плагин в меню « Правка» , выберите « Настройки» ... »Просмотреть пакеты и откройте папку« User ». Если файл с именем Main.sublime-menu не существует, создайте его. Добавьте или установите следующий текст в этот файл:

[
    {
        "id": "edit",
        "children":
        [
            {"id": "wrap"},
            { "command": "filter" }
        ]
    }
]

Это вставит вызов команды filter (по существу, filter преобразуется в FilterCommand().run(…) для вызова плагина и Filter для метки меню) чуть ниже команды wrap . Смотрите шаг 11 здесь для более подробного объяснения, почему это так.

Чтобы назначить сочетание клавиш, откройте и измените файл Default (OSX).sublime-keymap в OS X или эквивалент для других систем и введите следующее:

[  
    {   
        "keys": ["ctrl+shift+f"], "command": "filter"
    }  
]  

Это назначит ярлык F для этой команды.


Чтобы команда появилась в палитре команд, вам нужно создать файл с именем Default.sublime-commands (или отредактировать существующий) в папке User . Синтаксис похож на файл меню, который вы только что отредактировали:

[
    { "caption": "Filter Lines in File", "command": "filter" }
]

Несколько записей (заключенных в фигурные скобки) должны быть разделены запятыми.

 Скриншоты интеграции поведения и пользовательского интерфейса

Команда, как она реализована, отфильтрует все строки, являющиеся частью выделения (целые строки, а не только выделенные части) или, если выбор не существует, весь буфер для подстроки, введенной в поле ввода ( по умолчанию это - возможно бесполезный многострочный - буфер обмена) после запуска команды. Его можно легко расширить, например, для поддержки регулярных выражений или оставить только строки, не соответствующие определенному выражению.

Пункт меню

Команда в меню

Ввод палитры команд

Команда с другой меткой в палитре команд

редактор

Пользователь вводит текст для фильтрации файла с

Результат после выполнения команды

Добавление поддержки регулярных выражений

Чтобы добавить поддержку регулярных выражений, используйте вместо этого следующие сценарии и фрагменты:

filter.py:

import sublime, sublime_plugin, re

def matches(needle, haystack, is_re):
    if is_re:
        return re.match(needle, haystack)
    else:
        return (needle in haystack)

def filter(v, e, needle, is_re = False):
    # get non-empty selections
    regions = [s for s in v.sel() if not s.empty()]

    # if there's no non-empty selection, filter the whole document
    if len(regions) == 0:
        regions = [ sublime.Region(0, v.size()) ]

    for region in reversed(regions):
        lines = v.split_by_newlines(region)

        for line in reversed(lines):

            if not matches(needle, v.substr(line), is_re):
                v.erase(e, v.full_line(line))

class FilterCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def done(needle):
            e = self.view.begin_edit()
            filter(self.view, e, needle)
            self.view.end_edit(e)

        cb = sublime.get_clipboard()
        sublime.active_window().show_input_panel("Filter file for lines containing: ", cb, done, None, None)

class FilterUsingRegularExpressionCommand(sublime_plugin.TextCommand):
    def run(self, edit):
        def done(needle):
            e = self.view.begin_edit()
            filter(self.view, e, needle, True)
            self.view.end_edit(e)

        cb = sublime.get_clipboard()
        sublime.active_window().show_input_panel("Filter file for lines matching: ", cb, done, None, None)

Main.sublime-menu:

[
    {
        "id": "edit",
        "children":
        [
            {"id": "wrap"},
            { "command": "filter" },
            { "command": "filter_using_regular_expression" }
        ]
    }
]

Default (OSX).sublime-keymap:

[  
    {   
        "keys": ["ctrl+shift+f"], "command": "filter"
    },
    {
        "keys": ["ctrl+shift+option+f"], "command": "filter_using_regular_expression"
    }
]  

Вторая команда плагина, Filter Using Regular Expression, будет добавлена ниже пункта меню Filter .

Default.sublime-commands:

[
    { "caption": "Filter Lines in File", "command": "filter" },
    { "caption": "Filter Lines in File Using Regular Expression", "command": "filter_using_regular_expression" }
]
77

Существует также алгоритм фильтрации строк для бедного человека (или он ленивый?):

  1. Выберите интересующую строку
  2. Нажмите Alt+F3, чтобы перейти в режим нескольких курсоров во всех случаях
  3. Нажмите Control+L, чтобы выделить всю строку (на каждой строке курсора)
  4. Копировать-вставить выделение в другой буфер
46

Теперь есть плагин для фильтрации строк: https://github.com/davidpeckham/FilterLines
Это позволяет фильтровать и сворачивать код на основе строк или регулярных выражений.


Плагин Sublime Text Filter от Дэвида Пекхэма

12

Вы можете использовать встроенные возможности Sublime, чтобы сделать это от 3 до 7 нажатий клавиш (не включая регулярное выражение для сопоставления).

Шаг 1: мульти-выбрать все совпадающие строки

Вариант 1: чтобы выбрать несколько строк, содержащих подстроку

  1. Выберите интересующую вас строку.
  2. Нажмите Alt+F3, чтобы выбрать несколько событий.
  3. Нажмите Ctrl+L (Расширить выделение до строки).

Вариант 2: чтобы выбрать несколько строк, соответствующих регулярному выражению

  1. Нажмите Ctrl+F, чтобы открыть ящик поиска.
  2. Убедитесь, что сопоставление регулярных выражений включено (Alt+R для переключения).
  3. Введите регулярное выражение.
  4. Нажмите Alt+Enter, чтобы выбрать все совпадения.
  5. Нажмите Ctrl+L (Расширить выделение до строки).

Шаг 2: Сделайте что-нибудь с этими строками

Вариант 1: избавиться от всех не выделенных строк

  1. Нажмите Ctrl+C, чтобы скопировать.
  2. Нажмите Ctrl+A, чтобы выбрать все.
  3. Нажмите Ctrl+V, чтобы заменить выделение соответствующими линиями.

Вариант 2: Для того, чтобы избавиться от всех линий, которые выбраны

  1. Нажмите Ctrl+Shift+K (Удалить строку).

Вариант 3: Извлечь выделенные строки в новый файл

  1. Нажмите Ctrl+C, чтобы скопировать.
  2. Нажмите Ctrl+N, чтобы открыть новый файл.
  3. Нажмите Ctrl+V, чтобы вставить.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .