From 95c7ababc3db862590826699bb5aac4db65c59b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?P=C5=99emysl=20Janouch?= Date: Fri, 28 Oct 2016 04:58:29 +0200 Subject: [PATCH] degesch: add a "fancy-prompt" plugin So that the client looks at least a tiny bit decent if needed. --- plugins/degesch/fancy-prompt.lua | 97 ++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) create mode 100644 plugins/degesch/fancy-prompt.lua diff --git a/plugins/degesch/fancy-prompt.lua b/plugins/degesch/fancy-prompt.lua new file mode 100644 index 0000000..c0611f3 --- /dev/null +++ b/plugins/degesch/fancy-prompt.lua @@ -0,0 +1,97 @@ +-- +-- fancy-prompt.lua: the fancy multiline prompt you probably want +-- +-- Copyright (c) 2016, Přemysl Janouch +-- +-- Permission to use, copy, modify, and/or distribute this software for any +-- purpose with or without fee is hereby granted, provided that the above +-- copyright notice and this permission notice appear in all copies. +-- +-- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +-- WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +-- MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY +-- SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +-- WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION +-- OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN +-- CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +-- +-- Beware that it is a hack and only goes about 90% of the way, which is why +-- this functionality is only available as a plugin in the first place +-- (well, and also for customizability). +-- +-- The biggest problem is that the way we work with Readline is incompatible +-- with multiline prompts, and normal newlines just don't work. This is being +-- circumvented by using an overflowing single-line prompt with a specially +-- crafted character in the rightmost column that prevents the bar's background +-- from spilling all over the last line. +-- +-- There is also a problem with C-r search rendering not clearing out the +-- background but to really fix that mode, we'd have to fully reimplement it +-- since its alternative prompt very often gets overriden by accident anyway. + +local prompt = degesch.hook_prompt (function (hook) + local current = degesch.current_buffer + local chan = current.channel + local s = current.server + + local current_n = 0 + local active = "" + for i, buffer in ipairs (degesch.buffers) do + if buffer == current then + current_n = i + elseif buffer.new_messages_count ~= buffer.new_unimportant_count then + if active ~= "" then active = active .. "," end + if buffer.highlighted then active = active .. "!" end + active = active .. i + end + end + if active ~= "" then active = "(" .. active .. ")" end + local x = current_n .. ":" .. current.name + if chan then + local param = "" + for mode, param in pairs (chan.param_modes) do + param = param .. " +" .. mode .. " " .. param + end + local modes = chan.no_param_modes .. param:sub (2) + if modes ~= "" then x = x .. "(+" .. modes .. ")" end + if chan.users_len ~= 0 then x = x .. "{" .. chan.users_len .. "}" end + end + if current.hide_unimportant then x = x .. "" end + + local lines, cols = degesch.get_screen_size () + x = x .. " " .. active .. string.rep (" ", cols) + + -- Cut off extra characters and apply formatting, including the hack. + -- Note that this doesn't count with full-width or zero-width characters. + local overflow = utf8.offset (x, cols - 1) + if overflow then x = x:sub (1, overflow) end + x = "\x01\x1b[0;4;1;38;5;16m\x1b[48;5;255m\x02" .. + x .. "\x01\x1b[0;4;1;7;38;5;255m\x02 \x01\x1b[0;1m\x02" + + local user_prefix = function (chan, user) + for i, chan_user in ipairs (chan.users) do + if chan_user.user == user then return chan_user.prefixes end + end + return "" + end + if s then + x = x .. "[" + local state = s.state + if state == "disconnected" or state == "connecting" then + x = x .. "(" .. state .. ")" + elseif state ~= "registered" then + x = x .. "(unregistered)" + else + local user, modes = s.user, s.user_mode + if chan then x = x .. user_prefix (chan, user) end + x = x .. user.nickname + if modes ~= "" then x = x .. "(" .. modes .. ")" end + end + x = x .. "] " + else + -- There needs to be at least one character so that the cursor + -- doesn't get damaged by our hack in that last column + x = x .. "> " + end + return x +end)