Je souhaite filtrer un fichier que je modifie dans Sublime Text 2, car les lignes contiennent une certaine chaîne, y compris, si possible, des expressions régulières.
Considérez le fichier suivant:
foo bar
baz
qux
quuux baz
Lorsque filtré pour ba
, le résultat devrait être:
foo bar
baz
quuux baz
Comment puis je faire ça?
Sublime Text 2 est un éditeur extensible avec un API Python . Vous pouvez créer de nouvelles commandes (appelées Plugins ) et les rendre disponibles à partir de l'interface utilisateur.
Dans Sublime Text 2, sélectionnez Outils "Nouveau plug-in et entrez le texte suivant:
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)
Enregistrer sous filter.py
dans ~/Library/Application Support/Sublime Text 2/Packages/User
Pour ajouter ce plugin au menu Éditer , sélectionnez Préférences… "Parcourir les packages et ouvrez le dossier User
. Si un fichier appelé Main.sublime-menu
n'existe pas, créez-le. Ajoutez ou définissez le texte suivant dans ce fichier:
[
{
"id": "edit",
"children":
[
{"id": "wrap"},
{ "command": "filter" }
]
}
]
Ceci insérera l'appel de commande filter
(essentiellement, filter
est transformé en FilterCommand().run(…)
pour l'appel du plug-in et Filtre pour le libellé de menu) juste en dessous de la commande wrap
. Voir étape 11 ici pour une explication plus détaillée pourquoi.
Pour attribuer un raccourci clavier, ouvrez et éditez le fichier Default (OSX).sublime-keymap
sous OS X, ou l’équivalent pour d’autres systèmes, puis entrez les informations suivantes:
[
{
"keys": ["ctrl+shift+f"], "command": "filter"
}
]
Cela assignera le raccourci ⌃⇧F à cette commande.
Pour que la commande apparaisse dans la palette Commandes , vous devez créer un fichier nommé Default.sublime-commands
(ou en modifier un existant) dans le dossier User
. La syntaxe est similaire à celle du fichier de menu que vous venez de modifier:
[
{ "caption": "Filter Lines in File", "command": "filter" }
]
Les entrées multiples (entre accolades) doivent être séparées par des virgules.
La commande, telle qu’elle est mise en œuvre, filtrera toutes les lignes qui font partie d’une sélection (les lignes entières, pas seulement les parties sélectionnées) ou, si aucune sélection n’existe, la mémoire tampon entière pour une sous-chaîne entrée dans le champ d’entrée ( La valeur par défaut est le presse-papiers éventuellement éventuellement multi-lignes) une fois la commande déclenchée. Il peut facilement être étendu, par exemple, à supporte les expressions régulières, ou ne laisse que des lignes ne correspondant pas à une certaine expression.
Pour ajouter la prise en charge des expressions régulières, utilisez plutôt les scripts et extraits suivants:
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"
}
]
Une deuxième commande de plug-in, Filtre utilisant une expression régulière , sera ajoutée sous le filtre entrée de menu.
Default.sublime-commands
:
[
{ "caption": "Filter Lines in File", "command": "filter" },
{ "caption": "Filter Lines in File Using Regular Expression", "command": "filter_using_regular_expression" }
]
Il existe également un algorithme de filtrage de lignes du pauvre ( (ou est-il paresseux?):
Il existe maintenant un plugin pour filtrer les lignes: https://github.com/davidpeckham/FilterLines
Il permet le filtrage et le repliement du code en fonction de chaînes ou d'expressions régulières.
Vous pouvez utiliser les fonctionnalités intégrées de Sublime pour le faire en 3 à 7 frappes de touches (sans inclure l'expression régulière à faire correspondre).
Option 1: Pour sélectionner plusieurs lignes avec une sous-chaîne
Option 2: pour sélectionner toutes les lignes correspondant à une expression rationnelle avec une sélection multiple
Option 1: pour supprimer toutes les lignes qui ne sont pas sélectionnées
Option 2: Pour supprimer toutes les lignes qui sont sélectionnées
Option 3: extraire les lignes sélectionnées dans un nouveau fichier