Created
December 31, 2012 17:27
-
-
Save Dav1dde/4421444 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import weechat as w | |
from collections import defaultdict | |
from itertools import chain | |
import sys | |
NAME = 'orderbuf' | |
DESC = 'Orders buffers like a boss. Orders by channel, server, prefixed channel, ' \ | |
'autojoin list and in reverse order.' | |
w.register(NAME, 'dav1d', '0.1', 'GPL', DESC, '', '') | |
class Buffer(object): | |
def __init__(self, name, short_name, plugin_name, server_name, number): | |
self.name = name | |
self.short_name = short_name | |
self.plugin_name = plugin_name | |
self.server_name = server_name | |
self.number = number | |
self._buffer_ptr = None | |
self._unprefixed_name = None | |
@property | |
def buffer_ptr(self): | |
if self._buffer_ptr is None: | |
self._buffer_ptr = w.buffer_search(self.plugin_name, | |
'.'.join((self.server_name, self.name))) | |
return self._buffer_ptr | |
@property | |
def unprefixed_name(self): | |
if self._unprefixed_name is None: | |
chantypes = w.info_get('irc_server_isupport_value', | |
','.join((self.server_name, 'CHANTYPES'))) | |
name = self.name | |
if name and name[0] in chantypes: | |
i = chantypes.find(name[0]) | |
name = name.lstrip(chantypes[i]) | |
self._unprefixed_name = name | |
return self._unprefixed_name | |
@classmethod | |
def from_ptr(cls, buffer_ptr): | |
name = w.infolist_string(buffer_ptr, "name") | |
short_name = w.infolist_string(buffer_ptr, "short_name") | |
plugin_name = w.infolist_string(buffer_ptr, "plugin_name") | |
server_name = "" | |
number = w.infolist_integer(buffer_ptr, "number") | |
if plugin_name == 'irc': | |
server_name, name = name.split('.', 1) | |
else: | |
server_name, name = name, "" | |
return cls(name, short_name, plugin_name, server_name, number) | |
def __str__(self): | |
return 'Buffer({self.name!r}, {self.short_name!r}, {self.plugin_name!r}, ' \ | |
'{self.server_name!r}, {self.number!r})'.format(self=self) | |
def __repr__(self): | |
return self.__str__() | |
class Compare(object): | |
@staticmethod | |
def server_channel(buf): | |
return (buf.server_name, buf.unprefixed_name) | |
@staticmethod | |
def server_prefixed_channel(buf): | |
return (buf.server_name, buf.name) | |
@staticmethod | |
def channel(buf): | |
return (buf.unprefixed_name, buf.server_name) | |
@staticmethod | |
def prefixed_channel(buf): | |
return (buf.name, buf.server_name) | |
@staticmethod | |
def autojoin(buf): | |
aj_channels = w.config_string(w.config_get('irc.server.{}.autojoin'.format(buf.server_name))) | |
index = aj_channels.find(buf.name) | |
index = index if index >= 0 else sys.maxint | |
return (buf.server_name, index, buf.unprefixed_name) | |
CMP_MODES = {'sc' : Compare.server_channel, | |
'spc' : Compare.server_prefixed_channel, | |
'c' : Compare.channel, | |
'cp' : Compare.prefixed_channel, | |
'sa' : Compare.autojoin} | |
def get_all_buffers(): | |
buffers = list() | |
buffer_ptr = w.infolist_get("buffer", "", "") | |
while w.infolist_next(buffer_ptr): | |
buffers.append(Buffer.from_ptr(buffer_ptr)) | |
w.infolist_free(buffer_ptr) | |
return buffers | |
def groupby(iterable, key=lambda x: x): | |
result = defaultdict(list) | |
for item in iterable: | |
result[key(item)].append(item) | |
return result | |
def order_buffers(buffers, mode=Compare.server_channel, reverse_channel=False, | |
reverse_server=False, start_pos=2): | |
buffers = sorted((buf for buf in buffers if buf.number >= start_pos), key=lambda x: x.server_name) | |
if mode in (Compare.server_channel, Compare.server_prefixed_channel, Compare.autojoin): | |
servers = sorted(groupby(buffers, key=lambda x: x.server_name).iteritems(), reverse=reverse_server) | |
buffers = chain.from_iterable(sorted(v, key=mode, reverse=reverse_channel) for k,v in servers) | |
else: | |
buffers = [buf for buf in sorted(buffers, key=mode, reverse=reverse_channel or reverse_server)] | |
for i, buf in enumerate(buffers, start=start_pos): | |
w.buffer_set(buf.buffer_ptr, 'number', str(i)) | |
def order_buffers_cmd(data, buffer, args): | |
args = [arg.lower() for arg in args.split()] # no complex args, otherwise shlex | |
mode = Compare.server_channel | |
start_pos = 2 | |
reverse_channel = False | |
reverse_server = False | |
for arg in args: | |
if arg in CMP_MODES: | |
mode = CMP_MODES[arg] | |
elif arg.isdigit(): | |
start_pos = int(arg) | |
elif arg == 'reverse': | |
reverse_channel = True | |
reverse_server = True | |
elif arg == 'reverse_channel': | |
reverse_channel = True | |
elif arg == 'reverse_server': | |
reverse_server = True | |
else: | |
w.prnt(buffer, 'Unknown argument: "{}"'.format(arg)) | |
return w.WEECHAT_RC_ERROR | |
order_buffers(get_all_buffers(), mode, reverse_channel, reverse_server, start_pos) | |
return w.WEECHAT_RC_OK | |
w.hook_command(NAME, DESC, '<position> || mode || reverse || reverse_server', | |
'<position>: start at position (default: 2)\n' | |
'mode : - sc: sorts channels by servername and afterwards by channelname (default)\n' | |
' - spc: same as `sc` except that channel prefixes aren\'t removed\n' | |
' - c: sorts by channel name (ignoring servername)\n' | |
' - pc: same as `c` except channel prefixes aren\'t removed\n' | |
' - sa: sorts by server and afterwards by its autojoin list\n' | |
'reverse : sorts channels and servers in reversed order\n' | |
'reverse_channel: sorts channels in reversed order\n' | |
'reverse_server : sorts servers in reversed order', | |
'sc|spc|c|pc|sa|reverse|reverse_channel|reverse_server|%*', 'order_buffers_cmd', '') |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment