forked from davidpeckham/sublime-filterlines
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathfilter.py
More file actions
99 lines (84 loc) · 4.26 KB
/
filter.py
File metadata and controls
99 lines (84 loc) · 4.26 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
import functools
import itertools
import re
import sublime
import sublime_plugin
settings_path = 'Filter Lines.sublime-settings'
class PromptFilterToLinesCommand(sublime_plugin.WindowCommand):
def run(self, search_type = 'string', invert_search = False):
self._run(search_type, "filter_to_lines", "Filter", invert_search)
def _run(self, search_type, filter_command, filter_verb, invert_search):
self.load_settings()
self.filter_command = filter_command
self.search_type = search_type
self.invert_search = invert_search
if search_type == 'string':
prompt = "%s to lines %s: " % (filter_verb, 'not containing' if self.invert_search else 'containing')
else:
prompt = "%s to lines %s: " % (filter_verb, 'not matching' if self.invert_search else 'matching')
if not self.search_text:
view = self.window.active_view()
first = view.sel()[0] # first region (or point)
region = first if first.size() else view.word(first.begin())
word = view.substr(region)
self.search_text = word
sublime.active_window().show_input_panel(prompt, self.search_text, self.on_search_text_entered, None, None)
def on_search_text_entered(self, search_text):
self.search_text = search_text
self.save_settings()
if self.window.active_view():
self.window.active_view().run_command(self.filter_command, {
"needle": self.search_text, "search_type": self.search_type, "invert_search": self.invert_search })
def load_settings(self):
self.settings = sublime.load_settings(settings_path)
self.search_text = ""
if self.settings.get('preserve_search', True):
self.search_text = self.settings.get('latest_search', '')
def save_settings(self):
if self.settings.get('preserve_search', True):
self.settings.set('latest_search', self.search_text)
class FilterToLinesCommand(sublime_plugin.TextCommand):
def run(self, edit, needle, search_type, invert_search):
settings = sublime.load_settings(settings_path)
flags = self.get_search_flags(search_type, settings)
lines = itertools.groupby(self.view.find_all(needle, flags), self.view.line)
lines = [l for l, _ in lines]
self.line_numbers = settings.get('line_numbers', False)
self.new_tab = settings.get('create_new_tab', True)
self.invert_search = invert_search ^ (not self.new_tab)
self.show_filtered_lines(edit, lines)
def get_search_flags(self, search_type, settings):
flags = 0
if search_type == 'string':
flags = sublime.LITERAL
if not settings.get('case_sensitive_string_search', False):
flags = flags | sublime.IGNORECASE
elif search_type == 'regex':
if not settings.get('case_sensitive_regex_search', False):
flags = sublime.IGNORECASE
return flags
def show_filtered_lines(self, edit, lines):
if self.invert_search:
filtered_line_numbers = [self.view.rowcol(line.begin())[0] for line in lines]
lines = self.view.lines(sublime.Region(0, self.view.size()))
for line_number in reversed(filtered_line_numbers):
del lines[line_number]
if self.new_tab:
text = '\n'.join([self.prepare_output_line(l) for l in lines]);
self.create_new_tab(text)
else:
for line in reversed(lines):
self.view.erase(edit, self.view.full_line(line))
def create_new_tab(self, text):
results_view = self.view.window().new_file()
results_view.set_name('Filter Results')
results_view.set_scratch(True)
results_view.settings().set('word_wrap', self.view.settings().get('word_wrap'))
results_view.run_command('append', {'characters': text, 'force': True, 'scroll_to_end': False})
results_view.set_syntax_file(self.view.settings().get('syntax'))
def prepare_output_line(self, line):
if self.line_numbers and not self.invert_search:
line_number = self.view.rowcol(line.begin())[0]
return '%5d: %s' % (line_number, self.view.substr(line))
else:
return self.view.substr(line)