]> git.rmz.io Git - dotfiles.git/blob - weechat/ruby/colorizer.rb
zsh: tick function to wait a while for a task
[dotfiles.git] / weechat / ruby / colorizer.rb
1 # vim: set noet nosta sw=4 ts=4 :
2 #
3 # Colorizer
4 # Michael B. Hix <m@hix.io>
5 # http://code.hix.io/projects/colorizer
6 #
7 # Color certain parts of text in certain buffers based on rules.
8 #
9
10 #
11 # Options:
12 #
13 # plugins.var.ruby.colorizer.buffer_regex
14 # Buffers with names matching this regex are colorized. All buffers are
15 # colorized if this option is empty.
16 #
17 # plugins.var.ruby.colorizer.rule.count
18 # This is the maximum number of rules to load.
19 #
20 # plugins.var.ruby.colorizer.rule.X
21 # X is zero or a positive integer. Rules are strings consisting of a regular
22 # expression followed immediately by a slash and a Weechat color name. The
23 # regular expressions are case-insensitive.
24 #
25 # Text matching the regular expression is colored with the given color. The
26 # last match "wins" and overlapping matches are not detected.
27 #
28 # For example: "strelka|mongrel2/lightgreen"
29 #
30
31 #
32 # Changelog:
33 #
34 # 0.1: Initial release.
35 # 0.2: Add compatibility with new weechat_print modifier data (WeeChat >= 2.9).
36 # 0.3: Fix the compatibility checker
37
38 SCRIPT_NAME = 'colorizer'
39 SCRIPT_AUTHOR = 'Michael B. Hix'
40 SCRIPT_DESC = 'Colorize text in buffers based on rules.'
41 SCRIPT_VERSION = '0.3'
42 SCRIPT_LICENSE = 'BSD'
43
44 # A default coloring rule.
45 #
46 DEFAULT_RULE = {
47 :value => '',
48 :description => 'A colorizing rule of the form: <regular_expression>/<weechat_color_name> Empty rules are ignored.',
49 }.freeze
50
51 # Configuration defaults are supplied and set for the user if they're not already set.
52 #
53 DEFAULTS = {
54 'rule.0' => DEFAULT_RULE,
55 'rule.1' => DEFAULT_RULE,
56 'rule.2' => DEFAULT_RULE,
57 'rule.3' => DEFAULT_RULE,
58 'rule.4' => DEFAULT_RULE,
59 'rule.count' => {
60 :value => 10,
61 :description => 'The maximum number of rules to look for in your config.',
62 },
63 'buffer_regex' => {
64 :value => '',
65 :description => 'Only colorize text in buffers with names that match this regex. Leaving this empty matches all buffer names.',
66 },
67 }.freeze
68
69 ########################################################################
70 ### I N I T
71 ########################################################################
72
73 def weechat_init
74 Weechat.register SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, '', ''
75
76 Weechat.hook_modifier( 'weechat_print', 'colorize_cb', '' )
77
78 DEFAULTS.each_pair do |option, opts|
79 value = opts[:value]
80 description = opts[:description]
81
82 cur_value = Weechat.config_get_plugin( option )
83
84 if cur_value.nil? || cur_value.empty?
85 Weechat.config_set_plugin( option, value.to_s )
86 end
87
88 Weechat.config_set_desc_plugin( option, description )
89 end
90
91 parse_config
92
93 Weechat.hook_config( "plugins.var.ruby.#{SCRIPT_NAME}.*", 'config_cb', '' )
94
95 return Weechat::WEECHAT_RC_OK
96 end
97
98 ################################################################################
99 ### U T I L I T I E S
100 ################################################################################
101
102 # Provide a way to print legible stack traces.
103 #
104 def pp_error( e, message = '' )
105 return unless e.is_a? Exception
106 unless message.nil? or message.empty?
107 Weechat.print( '', '%s%s' % [Weechat.prefix('error'), message] )
108 end
109 Weechat.print( '', '%s%s: %s' % [Weechat.prefix( 'error' ), SCRIPT_NAME, e.to_s] )
110 e.backtrace.each do |line|
111 Weechat.print( '', '%s%s' % [Weechat.prefix( 'error' ), line] )
112 end
113 end
114
115 # Re-build rules and any regular expressions when the config changes.
116 #
117 def parse_config
118 rules = {}
119 count = Weechat::config_get_plugin( 'rule.count' ).to_i ||
120 DEFAULTS['rule.count']
121
122 count.times do |i|
123 key = "rule.#{i}"
124 next unless Weechat::config_is_set_plugin( key )
125
126 conf = Weechat::config_get_plugin( key )
127 regex,color,_ = conf.split( /(?<!\\)\//, 3 )
128
129 next if regex.nil? or regex.empty? or color.nil? or color.empty?
130
131 begin
132 rules[/(#{regex})/i] = color
133 rescue Exception => e
134 pp_error( e, 'There was a problem with rule %d:' % [i] )
135 end
136 end
137
138 @rules = rules
139
140 begin
141 @buffer_regex = /#{Weechat::config_get_plugin( 'buffer_regex' )}/i
142 rescue Exception => e
143 pp_error( e, 'There was a problem with buffer_regex:' )
144 end
145 end
146
147 ################################################################################
148 ### C A L L B A C K S
149 ################################################################################
150
151 # Handle configuration changes.
152 #
153 def config_cb( data, option, value )
154 parse_config
155 return Weechat::WEECHAT_RC_OK
156 end
157
158 # Handle message printing.
159 #
160 def colorize_cb( data, modifier, modifier_data, message )
161 if modifier_data.start_with?('0x')
162 # WeeChat >= 2.9
163 buffer, tags = modifier_data.split( ';' )
164 buffer_name = Weechat.buffer_get_string(buffer, 'name')
165 else
166 # WeeChat <= 2.8
167 plugin, buffer_name, tags = modifier_data.split( ';' )
168 end
169
170 return message unless @buffer_regex =~ buffer_name
171
172 reset = Weechat.color( 'reset' )
173 @rules.each do |reg, color_str|
174 color = Weechat.color( color_str )
175 message.gsub!( reg, '%s\1%s' % [color,reset] )
176 end
177
178 return message
179 end
180
181 __END__
182 __LICENSE__
183
184 Copyright (c) 2014 Michael B. Hix
185 All rights reserved.
186
187 Redistribution and use in source and binary forms, with or without
188 modification, are permitted provided that the following conditions are met:
189
190 1. Redistributions of source code must retain the above copyright notice,
191 this list of conditions and the following disclaimer.
192
193 2. Redistributions in binary form must reproduce the above copyright notice,
194 this list of conditions and the following disclaimer in the documentation
195 and/or other materials provided with the distribution.
196
197 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
198 AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
199 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
200 ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
201 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
202 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
203 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
204 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
205 CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
206 ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
207 POSSIBILITY OF SUCH DAMAGE.