summaryrefslogtreecommitdiff
path: root/plugins/xC/fancy-prompt.lua
diff options
context:
space:
mode:
authorPřemysl Eric Janouch <p@janouch.name>2021-08-06 16:12:15 +0200
committerPřemysl Eric Janouch <p@janouch.name>2021-08-06 16:43:59 +0200
commit50057d5149dda340b3b47aca4096f4a6ec66b9ee (patch)
tree79323d20b17c2c8e32942a1ac9b84d9da3041c6d /plugins/xC/fancy-prompt.lua
parent1f64710e795b0c5434d15813d4f1f568467ca087 (diff)
downloadxK-50057d5149dda340b3b47aca4096f4a6ec66b9ee.tar.gz
xK-50057d5149dda340b3b47aca4096f4a6ec66b9ee.tar.xz
xK-50057d5149dda340b3b47aca4096f4a6ec66b9ee.zip
Come up with sillier names for the binaries
I'm not entirely sure, but it looks like some people might not like jokes about the Holocaust. On a more serious note, the project has become more serious over the 7 or so years of its existence.
Diffstat (limited to 'plugins/xC/fancy-prompt.lua')
-rw-r--r--plugins/xC/fancy-prompt.lua105
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)