diff options
Diffstat (limited to 'plugins/xC/fancy-prompt.lua')
-rw-r--r-- | plugins/xC/fancy-prompt.lua | 105 |
1 files changed, 105 insertions, 0 deletions
diff --git a/plugins/xC/fancy-prompt.lua b/plugins/xC/fancy-prompt.lua new file mode 100644 index 0000000..8ec697a --- /dev/null +++ b/plugins/xC/fancy-prompt.lua @@ -0,0 +1,105 @@ +-- +-- fancy-prompt.lua: the fancy multiline prompt you probably want +-- +-- Copyright (c) 2016, Přemysl Eric Janouch <p@janouch.name> +-- +-- Permission to use, copy, modify, and/or distribute this software for any +-- purpose with or without fee is hereby granted. +-- +-- 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. + +xC.hook_prompt (function (hook) + local current = xC.current_buffer + local chan = current.channel + local s = current.server + + local bg_color = "255" + local current_n = 0 + local active = "" + for i, buffer in ipairs (xC.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 .. "!" + bg_color = "224" + end + active = active .. i + end + end + if active ~= "" then active = "(" .. active .. ")" end + local x = current_n .. ":" .. current.name + if chan and chan.users_len ~= 0 then + local params = "" + for mode, param in pairs (chan.param_modes) do + params = params .. " +" .. mode .. " " .. param + end + local modes = chan.no_param_modes .. params:sub (3) + if modes ~= "" then x = x .. "(+" .. modes .. ")" end + x = x .. "{" .. chan.users_len .. "}" + end + if current.hide_unimportant then x = x .. "<H>" end + + local lines, cols = xC.get_screen_size () + x = x .. " " .. active .. string.rep (" ", cols) + + -- Readline 7.0.003 seems to be broken and completely corrupts the prompt. + -- However 8.0.004 seems to be fine with these, as is libedit 20191231-3.1. + --x = x:gsub("[\128-\255]", "?") + + -- Cut off extra characters and apply formatting, including the hack. + -- FIXME: this doesn't count with full-width or zero-width characters. + -- We might want to export wcwidth() above term_from_utf8 somehow. + 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;" .. bg_color .. "m\x02" .. + x .. "\x01\x1b[0;4;1;7;38;5;" .. bg_color .. "m\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) |