Skip to content

Instantly share code, notes, and snippets.

@Dav1dde
Created December 31, 2012 17:27
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Dav1dde/4421444 to your computer and use it in GitHub Desktop.
Save Dav1dde/4421444 to your computer and use it in GitHub Desktop.
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