Como eu posso filtrar um arquivo para linhas contendo uma string no Sublime Text 2?

72

Eu quero filtrar um arquivo que estou editando no Sublime Text 2 para que as linhas contenham uma determinada string, se possível incluindo expressões regulares.

Considere o seguinte arquivo:

foo bar
baz
qux
quuux baz

Quando filtrado por ba , o resultado deve ser:

foo bar
baz
quuux baz

Como posso fazer isso?

    
por Daniel Beck 22.07.2012 / 21:48

4 respostas

87

O Sublime Text 2 é um editor extensível com uma API do Python . Você pode criar novos comandos (chamados Plugins ) e disponibilizá-los a partir da interface do usuário.

Adicionando o plugin TextCommand básico de filtragem

Em Sublime Text 2, selecione Ferramentas »Novo plug-in e digite o seguinte texto:

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)

Salvar como filter.py em ~/Library/Application Support/Sublime Text 2/Packages/User

Integração com interface do usuário

Para adicionar este plugin ao menu Editar , selecione Preferências… »Procurar Pacotes e abra a pasta User . Se um arquivo chamado Main.sublime-menu não existir, crie-o. Adicione ou defina o seguinte texto ao arquivo:

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

Isso irá inserir a chamada de comando filter (essencialmente, filter é transformado em FilterCommand().run(…) para a chamada do plugin e Filter para o rótulo do menu) logo abaixo do comando wrap . Veja passo 11 aqui para mais explicação detalhada porque isso é.

Para atribuir um atalho de teclado, abra e edite o arquivo Default (OSX).sublime-keymap no OS X, ou o equivalente para outros sistemas, e digite o seguinte:

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

Isto irá atribuir o atalho F a este comando.

Para que o comando apareça na Paleta de Comandos , você precisa criar um arquivo chamado Default.sublime-commands (ou editar um existente) na pasta User . A sintaxe é semelhante ao arquivo de menu que você acabou de editar:

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

Várias entradas (colocadas entre chaves) precisam ser separadas por vírgulas.

Capturas de tela de integração de comportamento e interface do usuário

O comando, conforme implementado, filtrará todas as linhas que fazem parte de uma seleção (as linhas inteiras, não apenas as partes selecionadas) ou, se não houver seleção, todo o buffer, para uma subseqüência inserida na campo de entrada (o padrão é o - possivelmente inútil multi-linha - área de transferência) após o comando ser acionado. Pode ser facilmente estendido para, e. suporta expressões regulares ou apenas deixa linhas não correspondentes a uma determinada expressão.

Item de menu

Entradadapaletadecomandos

Editor

Adicionando suporte para expressões regulares

Para adicionar suporte a expressões regulares, use os seguintes scripts e snippets:

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"
    }
]  

Um segundo comando plugin, Filter Using Regular Expression será adicionado abaixo da entrada do menu Filter .

Default.sublime-commands :

[
    { "caption": "Filter Lines in File", "command": "filter" },
    { "caption": "Filter Lines in File Using Regular Expression", "command": "filter_using_regular_expression" }
]
    
por 22.07.2012 / 21:48
75

Existe também um algoritmo de filtragem de linha do homem pobre (ou é preguiçoso?):

  1. Selecione cadeia de interesse
  2. Pressione Alt + F3 para entrar no modo multi-cursor em todas as ocorrências
  3. Pressione Controlar + L para selecionar a linha inteira (em todas as linhas do cursor)
  4. Copiar e colar seleção para outro buffer
por 23.05.2013 / 14:29
46

Existe agora um plug-in para filtrar linhas: link
Permite filtragem e dobragem de código com base em strings ou expressões regulares.


    
por 22.05.2013 / 12:30
12

Você pode usar os recursos internos do Sublime para fazer isso em 3 a 7 toques de tecla (não incluindo o regex a ser correspondido).

Etapa 1: selecione várias linhas correspondentes

Opção 1: para selecionar múltiplas todas as linhas que contenham uma substring

  1. Selecione a string de interesse.
  2. Pressione Alt + F3 para selecionar todas as ocorrências.
  3. Pressione Ctrl + L (expandir seleção para linha).

Opção 2: para selecionar múltiplas todas as linhas que correspondem a um regexp

  1. Pressione Ctrl + F para abrir a gaveta Localizar.
  2. Certifique-se de que a correspondência da Expressão Regular esteja ativada ( Alt + R para alternar).
  3. Digite a expressão regular.
  4. Pressione Alt + Digite para selecionar todas as correspondências.
  5. Pressione Ctrl + L (expandir seleção para linha).

Etapa 2: faça algo com essas linhas

Opção 1: Livrar-se de todas as linhas que não são selecionadas

  1. Pressione Ctrl + C para copiar.
  2. Pressione Ctrl + A para selecionar todos.
  3. Pressione Ctrl + V para substituir a seleção pelas linhas correspondentes.

Opção 2: Livrar-se de todas as linhas que são selecionadas

  1. Pressione Ctrl + Deslocamento + K (Apagar linha).

Opção 3: extrair linhas selecionadas para um novo arquivo

  1. Pressione Ctrl + C para copiar.
  2. Pressione Ctrl + N para abrir um novo arquivo.
  3. Pressione Ctrl + V para colar.
por 13.12.2014 / 05:03