Як я можу відфільтрувати файл для рядків, що містять рядок у Sublime Text 2?


74

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

Розглянемо наступний файл:

foo bar
baz
qux
quuux baz

При фільтруванні за baрезультатом має бути:

foo bar
baz
quuux baz

Як я можу це зробити?

Відповіді:


87

Sublime Text 2 - це розширюваний редактор з API Python . Ви можете створити нові команди (звані плагіни ) та зробити їх доступними з інтерфейсу користувача.

Додавання базового модуля фільтрації TextCommand

У піднесеному тексті 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(…)виклик плагіна та Фільтр для мітки меню) трохи нижче 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"
    }
]  

Друга команда плагіна " Фільтр за допомогою регулярного вираження" буде додана під меню " Фільтр ".

Default.sublime-commands:

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

2
Ви не хочете опублікувати це як пакет один день?
slhck

1
@slhck Хтось уже зробив (з відповідною атрибуцією), дивіться відповідь NovicePhysicist. З того, що я прочитав у коді, це було також покращено порівняно з цією відповіддю.
Даніель Бек

Класно, я цього не помічав!
slhck

Що це за тема, яку ви маєте з SublimeText, яка дає такі приємні кольори? Або це просто зміна кольору вікна?
pal4life

1
@ pal4life: Це називається Соляризоване (Світло) . Я думаю, що Sublime Text навіть постачається з ним. Я, можливо, встановив альтернативний варіант, тому кольори можуть не точно відповідати. Знімки екрана є в OS X, отже, звідки походить межа вікна та смуга заголовка.
Даніель Бек

83

Існує також алгоритм фільтрування лінійки бідолахи (або це лінь?):

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

2
Це майже найпростіше рішення. Браво!
gillytech

Дякую! Я вважаю за краще не встановлювати / вивчати інший плагін якомога більше - Alt + F3 є в моїй м’язовій пам’яті, тому вищенаведене рішення насправді не так далеко для мене.
Олоф Б'ярнасон

Ви можете замінити кроки 3 та 4 одним кроком: Ctrl + L.
Андрес Ріофріо

1
Приємне просте рішення! Я замінив би крок 3 з Ctrl-L на Home, Shift-End. Тому між випадками не виникає порожніх рядків.
jslap

4
Це змінило моє життя на краще. Ніколи більше ніколи не буде таким самим.
Shawson

49

Зараз є плагін для фільтрування ліній: https://github.com/davidpeckham/FilterLines
Він дозволяє фільтрувати та складати код на основі рядків або регулярних виразів.


Підвищений плагін для фільтру тексту від Девіда Пекхема


4
Щойно встановлений цей плагін - PERFECT для роботи. Візьме наявний файл, дозволяє ввести фільтр-фразу та розміщує результати на новій вкладці.
Нік

4
Погодився, дотепер я лише мріяв про те, щоб мати такий функціонал у своєму текстовому редакторі.
Michael12345

1
Цей плагін справді приголомшливий!
Девід

Прийшов сюди, тому що колега згадав щось про "Keep Keep Lines" для emacs та про те, наскільки це корисно. Навіть не знав, що мені потрібен цей плагін, абсолютно його люблю!
brandon927

14

Ви можете використовувати вбудовані можливості 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щоб вставити.

Це відмінний список команд!
чустар

Супер, але чи можна видалити порожні рядки після вставки?
Сергій Сеньков

1
@SergeySenkov Звичайно! (1) Натисніть Ctrl + F, щоб відкрити ящик "Знайти". (2) Переконайтеся, що параметр Regular Expression Match увімкнено (Alt + R для перемикання). (3) Введіть "\ n \ n +" (відповідає двом чи більше нових послідовних рядків). (4) Натисніть клавішу Alt + Enter для вибору кількох відповідностей. (5) Натисніть клавішу Enter, щоб замінити всі матчі одним новим рядком.
Андрес Ріофріо
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.