aboutsummaryrefslogtreecommitdiff
path: root/plugins
diff options
context:
space:
mode:
authorPřemysl Janouch <p.janouch@gmail.com>2016-10-28 04:58:29 +0200
committerPřemysl Janouch <p.janouch@gmail.com>2016-10-28 12:53:18 +0200
commit95c7ababc3db862590826699bb5aac4db65c59b2 (patch)
treec7aa9b84edb02badf6500920b864d39286156f52 /plugins
parenta0d733fdb933363570a1d9f7f04b59b063099ddd (diff)
downloadxK-95c7ababc3db862590826699bb5aac4db65c59b2.tar.gz
xK-95c7ababc3db862590826699bb5aac4db65c59b2.tar.xz
xK-95c7ababc3db862590826699bb5aac4db65c59b2.zip
degesch: add a "fancy-prompt" plugin
So that the client looks at least a tiny bit decent if needed.
Diffstat (limited to 'plugins')
-rw-r--r--plugins/degesch/fancy-prompt.lua97
1 files changed, 97 insertions, 0 deletions
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 <p.janouch@gmail.com>
+--
+-- 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 .. "<H>" 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)