-
Notifications
You must be signed in to change notification settings - Fork 0
/
filter.py
117 lines (89 loc) · 4.59 KB
/
filter.py
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
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
import functools
import re
import sublime
import sublime_plugin
SETTINGS = "Loggity.sublime-settings"
LOCAL_SETTINGS = 'Loggity Local.sublime-settings'
LOG_START_PATTERN = "\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{6}"
def match_log(log, pattern, use_regex, case_sensitive):
if use_regex:
return pattern.search(log) is not None
else:
if not case_sensitive:
log = log.lower()
return log.find(pattern) >= 0
class LoggityFilterIncludingStringCommand(sublime_plugin.WindowCommand):
def run(self):
sublime.active_window().run_command("loggity_filter", {"invert_search": False})
class LoggityFilterExcludingStringCommand(sublime_plugin.WindowCommand):
def run(self):
sublime.active_window().run_command("loggity_filter", {"invert_search": True})
class LoggityFilterIncludingRegexCommand(sublime_plugin.WindowCommand):
def run(self):
sublime.active_window().run_command("loggity_filter", {"invert_search": False, "use_regex": True})
class LoggityFilterExcludingRegexCommand(sublime_plugin.WindowCommand):
def run(self):
sublime.active_window().run_command("loggity_filter", {"invert_search": True, "use_regex": True})
class LoggityFilterCommand(sublime_plugin.WindowCommand):
def run(self, invert_search=False, use_regex=False):
settings = sublime.load_settings(SETTINGS)
local_settings = sublime.load_settings(LOCAL_SETTINGS)
search_text = local_settings.get('latest_search', '')
prompt = "Filter logs {} {}: ".format('not matching' if invert_search else 'matching', 'regex' if use_regex else 'string')
self.invert_search = invert_search
self.use_regex = use_regex
sublime.active_window().show_input_panel(prompt, search_text, self.on_select, None, None)
def on_select(self, term):
if self.window.active_view():
local_settings = sublime.load_settings(LOCAL_SETTINGS)
local_settings.set('latest_search', term)
sublime.save_settings(LOCAL_SETTINGS)
self.window.active_view().run_command("loggity_filter_view", {"term": term, "invert_search":self.invert_search, "use_regex": self.use_regex})
class LoggityFilterViewCommand(sublime_plugin.TextCommand):
def run(self, edit, term, invert_search=False, use_regex=False):
sublime.status_message('Filtering...')
settings = sublime.load_settings(SETTINGS)
case_sensitive = settings.get('case_sensitive_search', True)
self.filter_to_new_buffer(edit, term, use_regex, case_sensitive, invert_search)
sublime.status_message('')
def filter_to_new_buffer(self, edit, term, use_regex, case_sensitive, invert_search):
prog = re.compile(LOG_START_PATTERN)
if use_regex:
term_pattern = re.compile(term, re.IGNORECASE if not case_sensitive else 0)
else:
if not case_sensitive:
term = term.lower()
term_pattern = term
region = sublime.Region(0, self.view.size())
lines = (self.view.substr(r) for r in self.view.split_by_newlines(region))
log = ""
output = ""
for line in lines:
# Aggregate lines until we find a new timestamp start
if prog.match(line):
# If we found a new log start pattern, parse the previous accumulated data
if match_log(log, term_pattern, use_regex, case_sensitive) ^ invert_search:
output += log
log = ""
log += line + "\n"
if len(log) > 0:
if match_log(log, term_pattern, use_regex, case_sensitive) ^ invert_search:
output += log
# Write the result to a new window
results_view = self.view.window().new_file()
results_view.set_name('Filter Results {} {}'.format("not matching" if invert_search else "matching", term))
results_view.set_scratch(True)
results_view.settings().set('word_wrap', self.view.settings().get('word_wrap'))
results_view.run_command(
'append', {'characters': output, 'force': True,
'scroll_to_end': False})
if results_view.size() > 0:
results_view.set_syntax_file(self.view.settings().get('syntax'))
else:
message = ('Filtering logs for "%s" %s\n\n0 matches\n'
% (term,
'(case-sensitive)' if case_sensitive else
'(not case-sensitive)'))
results_view.run_command(
'append', {'characters': message, 'force': True,
'scroll_to_end': False})