Commit 726bee45 authored by Ferus Castor's avatar Ferus Castor Committed by Sébastien Helleu

New script buffer_dmenu.py: list buffers in dmenu or rofi, change active window to selected buffer

parent 6cb4d04f
# -*- coding: utf-8 -*-
#
# Copyright (c) 2016 by Ferus Castor <ferus+weechat@airmail.cc>
#
# 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 <http://www.gnu.org/licenses/>.
#
# Select a buffer from dmenu or rofi
# To call externally (IE: from i3), enable weechat fifo and run:
# $ echo "core.weechat */buffer_dmenu" >> $(find ~/.weechat -type p)
#
# Optionally requires i3-py [py2] (or i3ipc [py3]) to focus weechat in i3
#
# History:
# 2017-05-03, Ferus
# version 0.1.1: fix argument error for config_set_plugin
# 2016-05-01, Ferus
# version 0.1: initial release - requires WeeChat ≥ 0.3.7
# TODO:
# Option to remove certain buffer types
# Implement `focus` for other window managers
# if buffer == currentbuffer: switch to previous buffer
#pylint: disable=I0011,W0603,W1401
SCRIPT_NAME = "buffer_dmenu"
SCRIPT_AUTHOR = "Ferus <ferus+weechat@airmail.cc>"
SCRIPT_VERSION = "0.1.1"
SCRIPT_LICENSE = "GPL3"
SCRIPT_DESC = "List buffers in dmenu (or rofi), changes active window to selected buffer"
SCRIPT_COMMAND = "buffer_dmenu"
import os
import sys
import subprocess
try:
import weechat as w
except ImportError as e:
print("This script must be run under WeeChat.")
exit(1)
try:
if sys.version_info[0] == 3:
import i3ipc as i3
else:
import i3
have_i3 = True
except ImportError as e:
have_i3 = False
settings = {"launcher": ("dmenu", "launcher to use (supported: dmenu/rofi)")
,"focus" : ("false", "whether to immediately focus the terminal after selecting buffer")
,"focus.wm" : ("i3", "wm focus logic to use (supported: i3)")
,"dmenu.command" : ("dmenu -b -i -l 20", "command used to call dmenu")
,"rofi.command" : ("rofi -p '# ' -dmenu -lines 10 -columns 8 -auto-select -mesg '<big>Pick a <b>buffer</b> to jump to:</big>'", "command used to call rofi")
,"title.regex" : ("WeeChat \d+\.\d+", "regex used to match weechat's title window")
}
def check_dmenu():
devnull = open(os.devnull)
retcode = subprocess.call(["which", "dmenu"], stdout=devnull, stderr=devnull)
return True if retcode == 0 else False
def check_rofi():
devnull = open(os.devnull)
retcode = subprocess.call(["which", "rofi"], stdout=devnull, stderr=devnull)
return True if retcode == 0 else False
def get_launcher():
launcher = w.config_get_plugin("launcher")
command = None
if launcher == "dmenu":
if check_dmenu():
command = w.config_get_plugin("dmenu.command")
elif launcher == "rofi":
if check_rofi():
command = w.config_get_plugin("rofi.command")
return command
def launch(options):
launcher = get_launcher()
if launcher:
call(launcher, options)
return True
def focus():
if w.config_string_to_boolean(w.config_get_plugin("focus")):
if w.config_get_plugin("focus.wm") == "i3":
focus_i3()
def focus_i3():
if have_i3:
regex = w.config_get_plugin("title.regex")
#py3
if sys.version_info[0] == 3:
i3conn = i3.Connection()
weechat = i3conn.get_tree().find_named(regex)[0]
weechat.command('focus')
#py2
else:
i3.focus(title=regex)
def call(command, options):
options = "\n".join(options).encode("utf-8")
w.hook_process_hashtable("sh"
,{"arg1": "-c","arg2": 'echo "{0}" | {1}'.format(options, command)}
,10 * 1000
,"launch_process_cb"
,""
)
process_output = ""
def launch_process_cb(data, command, rc, out, err):
global process_output
if out != "":
process_output += out
if int(rc) >= 0:
selected = process_output.decode("utf-8").strip("\n")
number, name = selected.split(":")
process_output = ""
switch_to_buffer(name)
focus()
return w.WEECHAT_RC_OK
def get_open_buffers():
buffers = []
infolist = w.infolist_get("buffer", "", "")
if infolist:
while w.infolist_next(infolist):
name = w.infolist_string(infolist, "name")
number = w.infolist_integer(infolist, "number")
_ = "{0}:{1}".format(number, name).decode("utf-8")
buffers.append(_)
w.infolist_free(infolist)
return buffers
def get_hotlist_buffers():
buffers = []
infolist = w.infolist_get("hotlist", "", "")
if infolist:
while w.infolist_next(infolist):
number = w.infolist_integer(infolist, "buffer_number")
buffer = w.infolist_pointer(infolist, "buffer_pointer")
name = w.buffer_get_string(buffer, "name")
_ = "{0}:{1}".format(number, name).decode("utf-8")
buffers.append(_)
w.infolist_free(infolist)
return buffers
def switch_to_buffer(buffer_name):
w.command("", "/buffer {0}".format(buffer_name))
def dmenu_cmd_cb(data, buffer, args):
""" Command /buffers_dmenu """
if args == "hotlist":
buffers = get_hotlist_buffers()
else:
buffers = get_open_buffers()
if not launch(buffers):
return w.WEECHAT_RC_ERROR
return w.WEECHAT_RC_OK
if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""):
version = w.info_get('version_number', '') or 0
for option, value in settings.items():
if not w.config_is_set_plugin(option):
w.config_set_plugin(option, value[0])
if int(version) >= 0x00030500:
w.config_set_desc_plugin(option, '{0} (default: "{1}")'.format(value[1], value[0]))
w.hook_command(SCRIPT_COMMAND
,"Show a list of all buffers in dmenu"
,"[hotlist]"
," hotlist: shows hotlist buffers only\n"
"\n"
"To call externally (IE: from i3), enable weechat fifo and run:\n"
" $ echo 'core.weechat */buffer_dmenu' >> $(find ~/.weechat -type p)\n"
"\n"
"To focus the terminal containing WeeChat for the following WM:\n"
" i3: requires i3-py [py2] (or i3ipc [py3]) from pip\n"
,""
,"dmenu_cmd_cb"
,""
)
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment