# -*- coding: utf-8 -*- # # Copyright (C) 2011-2021 Sebastien Helleu # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by # the Free Software Foundation; either version 3 of the License, or # (at your option) any later version. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program. If not, see . # # # Browse WeeChat/plugins hdata in a dedicated buffer. # (this script requires WeeChat 0.3.6 or newer) # # History: # # 2021-11-04, Sebastien Helleu : # version 0.6: add support of hdata shared string, # reformat script with black # 2012-08-23, Sebastien Helleu : # version 0.5: add support of update in hdata # 2012-07-20, Sebastien Helleu : # version 0.4: add support of array size in hdata variables # 2012-01-02, Sebastien Helleu : # version 0.3: make script compatible with Python 3.x # 2011-12-19, Sebastien Helleu : # version 0.2: add hdata type "hashtable" # 2011-06-26, Sebastien Helleu : # version 0.1: initial version # SCRIPT_NAME = "hdata" SCRIPT_AUTHOR = "Sebastien Helleu " SCRIPT_VERSION = "0.6" SCRIPT_LICENSE = "GPL3" SCRIPT_DESC = "Browse WeeChat/plugins hdata" SCRIPT_COMMAND = "hdata" SCRIPT_BUFFER = "hdata" import_ok = True try: import weechat except ImportError: print("This script must be run under WeeChat.") print("Get WeeChat now at: http://www.weechat.org/") import_ok = False try: from operator import itemgetter except ImportError as message: print("Missing package(s) for %s: %s" % (SCRIPT_NAME, message)) import_ok = False hdata_buffer = "" hdata_current = ["list", "", ""] hdata_history = [] hdata_list = [] hdata_line = 0 hdata_history_line = [] def hdata_reset(): global hdata_current, hdata_history, hdata_list, hdata_line global hdata_history_line hdata_current = ["list", "", ""] hdata_history = [] hdata_list = [] hdata_line = 0 hdata_history_line = [] def hdata_buffer_input_cb(data, buffer, string): """Callback for input on hdata buffer.""" if string in ("q", "Q"): weechat.buffer_close(buffer) return weechat.WEECHAT_RC_OK def hdata_buffer_close_cb(data, buffer): """Callback for close of hdata buffer.""" global hdata_buffer hdata_buffer = "" hdata_reset() return weechat.WEECHAT_RC_OK def hdata_set_title(): """Set buffer title.""" global hdata_buffer, hdata_current_, hdata_history if len(hdata_history) > 3: history = ["..."] + hdata_history[-3:] else: history = hdata_history[:] history.reverse() weechat.buffer_set( hdata_buffer, "title", "Hdata: %s | History: %s" % (str(hdata_current), str(history)), ) def hdata_init_buffer(): """Initialize hdata buffer.""" global hdata_buffer, hdata_current hdata_buffer = weechat.buffer_search("python", SCRIPT_BUFFER) if not hdata_buffer: hdata_buffer = weechat.buffer_new( SCRIPT_BUFFER, "hdata_buffer_input_cb", "", "hdata_buffer_close_cb", "", ) if hdata_buffer: weechat.buffer_set(hdata_buffer, "type", "free") hdata_set_title() weechat.buffer_set(hdata_buffer, "key_bind_meta2-A", "/hdata **up") weechat.buffer_set(hdata_buffer, "key_bind_meta2-B", "/hdata **down") weechat.buffer_set(hdata_buffer, "key_bind_meta2-C", "/hdata **right") weechat.buffer_set(hdata_buffer, "key_bind_meta2-D", "/hdata **left") weechat.buffer_set(hdata_buffer, "key_bind_-", "/hdata **previous") weechat.buffer_set(hdata_buffer, "key_bind_+", "/hdata **next") weechat.buffer_set(hdata_buffer, "key_bind_meta-u", "/hdata **update") weechat.buffer_set( hdata_buffer, "key_bind_ctrl-L", "/hdata **refresh" ) weechat.buffer_set(hdata_buffer, "display", "1") def hdata_get_list(): """Get list of hdata or list of lists/vars in hdata.""" global hdata_current, hdata_list hdata_list = [] if hdata_current[0] == "list": # get list of hdata infolist = weechat.infolist_get("hook", "", "hdata") while weechat.infolist_next(infolist): hdata_list.append( { "name": weechat.infolist_string(infolist, "hdata_name"), "plugin": weechat.infolist_string(infolist, "plugin_name") or "weechat", "description": weechat.infolist_string( infolist, "description_nls" ), } ) weechat.infolist_free(infolist) else: # get content of a hdata hdata = weechat.hdata_get(hdata_current[1]) if hdata: list2 = [] list_lists = weechat.hdata_get_string(hdata, "list_keys") if list_lists: for name in list_lists.split(","): list2.append( { "name": name, "offset": "---", "type": "list", "update_allowed": 0, "array_size": -1, "hdata": "", "value": weechat.hdata_get_list(hdata, name), } ) list2 = sorted(list2, key=itemgetter("name")) hdata_list += list2 list2 = [] list_prevnext = [] var_prev = weechat.hdata_get_string(hdata, "var_prev") var_next = weechat.hdata_get_string(hdata, "var_next") list_vars = weechat.hdata_get_string(hdata, "var_keys") if list_vars: for var in list_vars.split(","): var_type = weechat.hdata_get_var_type_string(hdata, var) value = "" array_size = -1 if hdata_current[2]: array_size = weechat.hdata_get_var_array_size( hdata, hdata_current[2], var ) max_array_size = array_size if array_size >= 0 else 1 for i in range(0, max_array_size): index_var = "%d|%s" % (i, var) if value != "": value += "," if var_type == "char": value += str( weechat.hdata_char( hdata, hdata_current[2], index_var ) ) elif var_type == "integer": value += str( weechat.hdata_integer( hdata, hdata_current[2], index_var ) ) elif var_type == "long": value += str( weechat.hdata_long( hdata, hdata_current[2], index_var ) ) elif var_type in ("string", "shared_string"): value += weechat.hdata_string( hdata, hdata_current[2], index_var ) elif var_type == "pointer": value += weechat.hdata_pointer( hdata, hdata_current[2], index_var ) elif var_type == "time": value += str( weechat.hdata_time( hdata, hdata_current[2], index_var ) ) elif var_type == "hashtable": value += str( weechat.hdata_hashtable( hdata, hdata_current[2], index_var ) ) item = { "name": var, "offset": weechat.hdata_get_var_offset(hdata, var), "type": weechat.hdata_get_var_type_string(hdata, var), "array_size": array_size, "hdata": weechat.hdata_get_var_hdata(hdata, var), "update_allowed": weechat.hdata_update( hdata, "", {"__update_allowed": var} ), "value": value, "prevnext": 0, } if var == var_prev: item["prevnext"] = 1 list_prevnext.insert(0, item) elif var == var_next: item["prevnext"] = 1 list_prevnext.append(item) else: list2.append(item) list2 = sorted(list2, key=itemgetter("offset")) if list_prevnext: hdata_list += list_prevnext hdata_list += list2 def hdata_display(): global hdata_buffer, hdata_current, hdata_list, hdata_line if not hdata_list: hdata_get_list() if hdata_line >= len(hdata_list): hdata_line = 0 weechat.prnt_y( hdata_buffer, 0, 'Keys: left=back, right=select, "-"=previous, "+"=next, alt-u=update ' '| Actions: "q"=close buffer', ) weechat.prnt_y(hdata_buffer, 1, "") weechat.prnt_y( hdata_buffer, 3, "%s%s" % (weechat.color("240"), "─" * 300) ) line_num = 4 if hdata_current[0] == "list": fmt = "%s%-30s %-12s %s" weechat.prnt_y( hdata_buffer, 2, fmt % (weechat.color("white"), "Hdata", "Plugin", "Description"), ) for i, hdata in enumerate(hdata_list): if i == hdata_line: color = weechat.color("white,60") else: color = "" weechat.prnt_y( hdata_buffer, line_num, fmt % ( color, hdata["name"], hdata["plugin"], hdata["description"], ), ) line_num += 1 else: fmt = "%s%-34s %-5s %-13s %-1s %-5s %-30s %s" weechat.prnt_y( hdata_buffer, 2, fmt % ( weechat.color("white"), "Name", "Ofs", "Type", "W", "Array", "Hdata", "Value", ), ) colors = [ {"list": "brown", "prevnext": "green", "*": "chat"}, { "list": "yellow,60", "prevnext": "lightgreen,60", "*": "white,60", }, ] for i, var in enumerate(hdata_list): if i == hdata_line: colors2 = colors[1] else: colors2 = colors[0] if var["type"] == "list": color = colors2["list"] elif var["prevnext"]: color = colors2["prevnext"] else: color = colors2["*"] str_w = ( "W" if var["type"] != "list" and var["update_allowed"] else " " ) str_array_size = ( str(var["array_size"]) if var["array_size"] >= 0 else "" ) weechat.prnt_y( hdata_buffer, line_num, fmt % ( weechat.color(color), var["name"], var["offset"], var["type"], str_w, str_array_size, var["hdata"], var["value"], ), ) line_num += 1 def hdata_move(shift): """Move to another element in list.""" if hdata_current[0] == "hdata": pointer = weechat.hdata_move( weechat.hdata_get(hdata_current[1]), hdata_current[2], shift ) if pointer: hdata_current[2] = pointer hdata_get_list() hdata_set_title() hdata_display() def hdata_refresh(): global hdata_buffer hdata_get_list() weechat.buffer_clear(hdata_buffer) hdata_set_title() hdata_display() weechat.command(hdata_buffer, "/window refresh") def hdata_cmd_cb(data, buffer, args): """Callback for /hdata command.""" global hdata_buffer, hdata_current, hdata_history, hdata_list, hdata_line if not hdata_buffer: hdata_init_buffer() if hdata_buffer: if args.startswith("**"): if args == "**up": if hdata_line > 0: hdata_line -= 1 hdata_display() elif args == "**down": if hdata_line < len(hdata_list) - 1: hdata_line += 1 hdata_display() elif args == "**left": if len(hdata_history) > 0: hdata_current = hdata_history.pop() hdata_line = hdata_history_line.pop() hdata_get_list() weechat.buffer_clear(hdata_buffer) hdata_set_title() hdata_display() elif args == "**right": old_current = hdata_current[:] old_line = hdata_line move_ok = False if hdata_current[0] == "list": hdata = hdata_list[hdata_line] hdata_current = ["hdata", hdata["name"], ""] hdata_line = 0 move_ok = True else: var = hdata_list[hdata_line] if var["type"] == "list": if var["value"]: hdata_current[2] = var["value"] move_ok = True elif var["hdata"]: if var["value"]: if var["hdata"] != hdata_current[1]: hdata_line = 0 hdata_current[1] = var["hdata"] hdata_current[2] = var["value"] move_ok = True if move_ok: hdata_history.append(old_current) hdata_history_line.append(old_line) hdata_get_list() weechat.buffer_clear(hdata_buffer) hdata_set_title() hdata_display() elif args == "**previous": hdata_move(-1) elif args == "**next": hdata_move(+1) elif args == "**update": if hdata_list[hdata_line].get("update_allowed", 0): cmdline = ( "/hdata update %s" % weechat.string_remove_color( hdata_list[hdata_line]["value"], "" ) ) weechat.buffer_set(hdata_buffer, "input", cmdline) weechat.buffer_set( hdata_buffer, "input_pos", "%d" % len(cmdline) ) elif args == "**refresh": hdata_refresh() else: argv = args.split(" ", 1) if argv[0] == "update" and len(argv) > 1: if hdata_list[hdata_line].get("update_allowed", 0): weechat.hdata_update( weechat.hdata_get(hdata_current[1]), hdata_current[2], {hdata_list[hdata_line]["name"]: argv[1]}, ) hdata_refresh() else: hdata_display() return weechat.WEECHAT_RC_OK if __name__ == "__main__" and import_ok: if weechat.register( SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", "", ): weechat.hook_command( SCRIPT_COMMAND, "Browse WeeChat/plugins hdata in a dedicated buffer.", "", "", "", "hdata_cmd_cb", "", )