]> git.rmz.io Git - dotfiles.git/blob - weechat/python/text_item.py
4b63a8158a626241cc581b9801a8dfe348f709cf
[dotfiles.git] / weechat / python / text_item.py
1 # -*- coding: utf-8 -*-
2 #
3 # Copyright (c) 2012-2016 by nils_2 <weechatter@arcor.de>
4 #
5 # add a plain text or evaluated content to item bar
6 #
7 # This program is free software; you can redistribute it and/or modify
8 # it under the terms of the GNU General Public License as published by
9 # the Free Software Foundation; either version 3 of the License, or
10 # (at your option) any later version.
11 #
12 # This program is distributed in the hope that it will be useful,
13 # but WITHOUT ANY WARRANTY; without even the implied warranty of
14 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 # GNU General Public License for more details.
16 #
17 # You should have received a copy of the GNU General Public License
18 # along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #
20 # 2016-12-12: nils_2, (freenode.#weechat)
21 # 0.6 : fix problem with multiple windows (reported by Ram-Z)
22 #
23 # 2016-09-15: nils_2, (freenode.#weechat)
24 # 0.5 : add /help text (suggested by gb)
25 #
26 # 2014-05-19: nils_2, (freenode.#weechat)
27 # 0.4 : evaluate content of item (suggested by FlashCode)
28 #
29 # 2013-06-27: nils_2, (freenode.#weechat)
30 # 0.3 : fix: bug with root bar
31 #
32 # 2013-01-25: nils_2, (freenode.#weechat)
33 # 0.2 : make script compatible with Python 3.x
34 #
35 # 2012-12-23: nils_2, (freenode.#weechat)
36 # 0.1 : initial release
37 #
38 # requires: WeeChat version 0.3.0
39 #
40 # Development is currently hosted at
41 # https://github.com/weechatter/weechat-scripts
42
43 try:
44 import weechat,re
45
46 except Exception:
47 print("This script must be run under WeeChat.")
48 print("Get WeeChat now at: http://www.weechat.org/")
49 quit()
50
51 SCRIPT_NAME = "text_item"
52 SCRIPT_AUTHOR = "nils_2 <weechatter@arcor.de>"
53 SCRIPT_VERSION = "0.6"
54 SCRIPT_LICENSE = "GPL"
55 SCRIPT_DESC = "add a plain text or evaluated content to item bar"
56
57 # regexp to match ${color} tags
58 regex_color=re.compile('\$\{([^\{\}]+)\}')
59
60 hooks = {}
61
62 # ================================[ hooks ]===============================
63 def add_hook(signal, item):
64 global hooks
65 # signal already exists?
66 if signal in hooks:
67 return
68 hooks[item] = weechat.hook_signal(signal, "bar_item_update", "")
69
70 def unhook(hook):
71 global hooks
72 if hook in hooks:
73 weechat.unhook(hooks[hook])
74 del hooks[hook]
75
76 def toggle_refresh(pointer, name, value):
77 option_name = name[len('plugins.var.python.' + SCRIPT_NAME + '.'):] # get optionname
78
79 # option was removed? remove bar_item from struct!
80 if not weechat.config_get_plugin(option_name):
81 ptr_bar = weechat.bar_item_search(option_name)
82 if ptr_bar:
83 weechat.bar_item_remove(ptr_bar)
84 return weechat.WEECHAT_RC_OK
85 else:
86 return weechat.WEECHAT_RC_OK
87
88 # check if option is new or simply changed
89 if weechat.bar_item_search(option_name):
90 weechat.bar_item_update(option_name)
91 else:
92 weechat.bar_item_new(option_name,'update_item',option_name)
93
94 weechat.bar_item_update(option_name)
95 return weechat.WEECHAT_RC_OK
96
97 # ================================[ items ]===============================
98 def create_bar_items():
99 ptr_infolist_option = weechat.infolist_get('option','','plugins.var.python.' + SCRIPT_NAME + '.*')
100
101 if not ptr_infolist_option:
102 return
103
104 while weechat.infolist_next(ptr_infolist_option):
105 option_full_name = weechat.infolist_string(ptr_infolist_option, 'full_name')
106 option_name = option_full_name[len('plugins.var.python.' + SCRIPT_NAME + '.'):] # get optionname
107
108 if weechat.bar_item_search(option_name):
109 weechat.bar_item_update(option_name)
110 else:
111 weechat.bar_item_new(option_name,'update_item',option_name)
112 weechat.bar_item_update(option_name)
113
114 weechat.infolist_free(ptr_infolist_option)
115
116 def update_item (data, item, window):
117 if not data:
118 return ""
119
120 # window empty? root bar!
121 if not window:
122 window = weechat.current_window()
123
124 value = weechat.config_get_plugin(data)
125
126 if value:
127 value = check_buffer_type(window, data, value)
128 else:
129 return ""
130
131 if not value:
132 return ""
133
134 return substitute_colors(value,window)
135
136 # update item
137 def bar_item_update(signal, callback, callback_data):
138 ptr_infolist_option = weechat.infolist_get('option','','plugins.var.python.' + SCRIPT_NAME + '.*')
139
140 if not ptr_infolist_option:
141 return
142
143 while weechat.infolist_next(ptr_infolist_option):
144 option_full_name = weechat.infolist_string(ptr_infolist_option, 'full_name')
145 option_name = option_full_name[len('plugins.var.python.' + SCRIPT_NAME + '.'):] # get optionname
146
147 # check if item exists in a bar and if we have a hook for it
148 if weechat.bar_item_search(option_name) and option_name in hooks:
149 weechat.bar_item_update(option_name)
150
151 weechat.infolist_free(ptr_infolist_option)
152 return weechat.WEECHAT_RC_OK
153
154
155 # ================================[ subroutines ]===============================
156 def substitute_colors(text,window):
157 if int(version) >= 0x00040200:
158 bufpointer = weechat.window_get_pointer(window,"buffer")
159 return weechat.string_eval_expression(text, {"buffer": bufpointer}, {}, {})
160 # return weechat.string_eval_expression(text,{},{},{})
161 # substitute colors in output
162 return re.sub(regex_color, lambda match: weechat.color(match.group(1)), text)
163
164 def check_buffer_type(window, data, value):
165 bufpointer = weechat.window_get_pointer(window,"buffer")
166 if bufpointer == "":
167 return ""
168
169 value = value.split(' ', 1)
170 if len(value) <= 1:
171 return ""
172
173 # format is : buffer_type (channel,server,private,all) | signal (e.g: buffer_switch)
174 channel_type_and_signal = value[0]
175 if channel_type_and_signal.find('|') >= 0:
176 channel_type = channel_type_and_signal[0:channel_type_and_signal.find("|")]
177 signal_type = channel_type_and_signal[channel_type_and_signal.find("|")+1:]
178 unhook(data)
179 add_hook(signal_type, data)
180 else:
181 channel_type = value[0]
182
183 value = value[1]
184
185 if channel_type == 'all' or weechat.buffer_get_string(bufpointer,'localvar_type') == channel_type:
186 return value
187 return ""
188
189 # ================================[ main ]===============================
190 if __name__ == "__main__":
191 if weechat.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC,'',''):
192 weechat.hook_command(SCRIPT_NAME,SCRIPT_DESC,
193 '',
194 'How to use:\n'
195 '===========\n'
196 'Template:\n'
197 '/set plugins.var.python.text_item.<item_name> <type>|<signal> <${color:name/number}><text>\n\n'
198 ' type : all, channel, server, private\n'
199 ' (you can use: /buffer localvar)\n\n'
200 ' signal (eg.): buffer_switch, buffer_closing, print, \n'
201 ' (for a list of all possible signals, see API doc weechat_hook_signal())\n\n'
202 'Example:\n'
203 '=======\n'
204 'creates an option for a text item named "nick_text". The item will be created for "channel" buffers. '
205 'The text displayed in the status-bar is "Nicks:" (yellow colored!):\n'
206 ' /set plugins.var.python.text_item.nick_text "channel ${color:yellow}Nicks:"\n\n'
207 'now you have to add the item "nick_text" to the bar.items (use auto-completion or iset.pl!)\n'
208 ' /set weechat.bar.status.items nick_text\n\n'
209 'creates an option to display the terminal width and height in an item bar. item will be updated on signal "signal_sigwinch"\n'
210 ' /set plugins.var.python.text_item.dimension "all|signal_sigwinch width: ${info:term_width} height: ${info:term_height}"\n',
211 '',
212 '',
213 '')
214 version = weechat.info_get("version_number", "") or 0
215 create_bar_items()
216 weechat.hook_config( 'plugins.var.python.' + SCRIPT_NAME + '.*', 'toggle_refresh', '' )