diff --git a/.config/X11/xinitrc b/.config/X11/xinitrc index c1bcf4e..5112c32 100644 --- a/.config/X11/xinitrc +++ b/.config/X11/xinitrc @@ -28,4 +28,4 @@ else . "$HOME/.xprofile" fi -exec dwm +exec /usr/bin/dbus-launch --sh-syntax --exit-with-session dwm diff --git a/.config/X11/xprofile b/.config/X11/xprofile index b616e11..5551e6b 100644 --- a/.config/X11/xprofile +++ b/.config/X11/xprofile @@ -3,6 +3,7 @@ # This file is sourced when launching a DM from startx/xinit # session launch +eval $(dbus-launch --sh-syntax --exit-with-session) xss-lock -- slock & redshift & diff --git a/.config/aliasrc b/.config/aliasrc index 908a6e8..d984523 100644 --- a/.config/aliasrc +++ b/.config/aliasrc @@ -21,3 +21,4 @@ alias abcde='abcde -c $XDG_CONFIG_HOME/abcde/config' alias abook='abook --config $XDG_CONFIG_HOME/abook/abookrc --datafile "$XDG_DATA_HOME"/abook/addressbook' alias pip-upgrade="pip freeze --user | cut -d'=' -f1 | xargs -n1 pip install -U" alias wget="wget --hsts-file=$XDG_CACHE_HOME/wget-hsts" +alias irssi="irssi --config=$XDG_CONFIG_HOME/irssi/config --home=$XDG_DATA_HOME/irssi" diff --git a/.config/gnupg/gpg-agent.conf b/.config/gnupg/gpg-agent.conf index 52cbff2..8c29806 100644 --- a/.config/gnupg/gpg-agent.conf +++ b/.config/gnupg/gpg-agent.conf @@ -1,3 +1,5 @@ allow-preset-passphrase default-cache-ttl 604800 max-cache-ttl 604800 + +pinentry-program /usr/bin/pinentry diff --git a/.config/irssi/config.template b/.config/irssi/config.template new file mode 100644 index 0000000..ae4dea8 --- /dev/null +++ b/.config/irssi/config.template @@ -0,0 +1,366 @@ +servers = ( + { address = "irc.dal.net"; chatnet = "DALnet"; port = "6667"; }, + { + address = "ssl.efnet.org"; + chatnet = "EFNet"; + port = "9999"; + use_tls = "yes"; + }, + { + address = "irc.esper.net"; + chatnet = "EsperNet"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + }, + { + address = "chat.freenode.net"; + chatnet = "Freenode"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + }, + { + address = "irc.gamesurge.net"; + chatnet = "GameSurge"; + port = "6667"; + }, + { + address = "eu.irc6.net"; + chatnet = "IRCnet"; + port = "6667"; + use_tls = "yes"; + }, + { address = "open.ircnet.net"; chatnet = "IRCnet"; port = "6667"; }, + { + address = "irc.ircsource.net"; + chatnet = "IRCSource"; + port = "6667"; + }, + { address = "irc.netfuze.net"; chatnet = "NetFuze"; port = "6667"; }, + { + address = "irc.oftc.net"; + chatnet = "OFTC"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + }, + { + address = "irc.quakenet.org"; + chatnet = "QuakeNet"; + port = "6667"; + }, + { + address = "irc.rizon.net"; + chatnet = "Rizon"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + }, + { address = "silc.silcnet.org"; chatnet = "SILC"; port = "706"; }, + { + address = "irc.undernet.org"; + chatnet = "Undernet"; + port = "6667"; + }, + { + address = "irc.libera.chat"; + chatnet = "LiberaChat"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + autoconnect = "yes"; + }, + { + address = "irc.epiknet.org"; + chatnet = "Epinet"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + }, + { + address = "irc.epiknet.org"; + chatnet = "EpikNet"; + port = "6697"; + use_tls = "yes"; + tls_verify = "yes"; + } +); + +chatnets = { + DALnet = { + type = "IRC"; + max_kicks = "4"; + max_msgs = "20"; + max_whois = "30"; + }; + EFNet = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "4"; + max_whois = "1"; + }; + EsperNet = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "4"; + max_whois = "1"; + }; + Freenode = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "4"; + max_whois = "1"; + }; + GameSurge = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "1"; + max_whois = "1"; + }; + IRCnet = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "1"; + max_whois = "1"; + }; + IRCSource = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "4"; + max_whois = "1"; + }; + NetFuze = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "1"; + max_whois = "1"; + }; + OFTC = { type = "IRC"; max_kicks = "1"; max_msgs = "1"; max_whois = "1"; }; + QuakeNet = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "1"; + max_whois = "1"; + }; + Rizon = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "1"; + max_whois = "1"; + }; + SILC = { type = "SILC"; }; + Undernet = { + type = "IRC"; + max_kicks = "1"; + max_msgs = "1"; + max_whois = "1"; + }; + LiberaChat = { + type = "IRC"; + sasl_mechanism = "PLAIN"; + sasl_username = "swytch"; + }; + EpikNet = { type = "IRC"; }; +}; + +channels = ( + { name = "#lobby"; chatnet = "EsperNet"; autojoin = "No"; }, + { name = "#freenode"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "Freenode"; autojoin = "No"; }, + { name = "#gamesurge"; chatnet = "GameSurge"; autojoin = "No"; }, + { name = "#irssi"; chatnet = "IRCNet"; autojoin = "No"; }, + { name = "#ircsource"; chatnet = "IRCSource"; autojoin = "No"; }, + { name = "#netfuze"; chatnet = "NetFuze"; autojoin = "No"; }, + { name = "#oftc"; chatnet = "OFTC"; autojoin = "No"; }, + { name = "silc"; chatnet = "SILC"; autojoin = "No"; }, + { name = "#gentoo"; chatnet = "LiberaChat"; }, + { name = "#gentoo-fr"; chatnet = "LiberaChat"; }, + { name = "#neovim"; chatnet = "LiberaChat"; }, + { name = "#git"; chatnet = "LiberaChat"; }, + { name = "#coq"; chatnet = "LiberaChat"; }, + { name = "#18-25"; chatnet = "EpikNet"; }, + { name = "#irssi"; chatnet = "LiberaChat"; } +); + +aliases = { + ATAG = "WINDOW SERVER"; + ADDALLCHANS = "SCRIPT EXEC foreach my \\$channel (Irssi::channels()) { Irssi::command(\"CHANNEL ADD -auto \\$channel->{visible_name} \\$channel->{server}->{tag} \\$channel->{key}\")\\;}"; + B = "BAN"; + BACK = "AWAY"; + BANS = "BAN"; + BYE = "QUIT"; + C = "CLEAR"; + CALC = "EXEC - if command -v bc >/dev/null 2>&1\\; then printf '%s=' '$*'\\; echo '$*' | bc -l\\; else echo bc was not found\\; fi"; + CHAT = "DCC CHAT"; + DATE = "TIME"; + DEHIGHLIGHT = "DEHILIGHT"; + DESCRIBE = "ACTION"; + DHL = "DEHILIGHT"; + EXEMPTLIST = "MODE $C +e"; + EXIT = "QUIT"; + GOTO = "SCROLLBACK GOTO"; + HIGHLIGHT = "HILIGHT"; + HL = "HILIGHT"; + HOST = "USERHOST"; + INVITELIST = "MODE $C +I"; + J = "JOIN"; + K = "KICK"; + KB = "KICKBAN"; + KN = "KNOCKOUT"; + LAST = "LASTLOG"; + LEAVE = "PART"; + M = "MSG"; + MUB = "UNBAN *"; + N = "NAMES"; + NMSG = "^MSG"; + P = "PART"; + Q = "QUERY"; + RESET = "SET -default"; + RUN = "SCRIPT LOAD"; + SAY = "MSG *"; + SB = "SCROLLBACK"; + SBAR = "STATUSBAR"; + SIGNOFF = "QUIT"; + SV = "MSG * Irssi $J ($V) - https://irssi.org"; + T = "TOPIC"; + UB = "UNBAN"; + UMODE = "MODE $N"; + UNSET = "SET -clear"; + W = "WHO"; + WC = "WINDOW CLOSE"; + WG = "WINDOW GOTO"; + WJOIN = "JOIN -window"; + WI = "WHOIS"; + WII = "WHOIS $0 $0"; + WL = "WINDOW LIST"; + WN = "WINDOW NEW HIDDEN"; + WQUERY = "QUERY -window"; + WW = "WHOWAS"; +}; + +statusbar = { + + items = { + + barstart = "{sbstart}"; + barend = "{sbend}"; + + topicbarstart = "{topicsbstart}"; + topicbarend = "{topicsbend}"; + + time = "{sb $Z}"; + user = "{sb {sbnickmode $cumode}$N{sbmode $usermode}{sbaway $A}}"; + + window = "{sb $winref:$tag/$itemname{sbmode $M}}"; + window_empty = "{sb $winref{sbservertag $tag}}"; + + prompt = "{prompt $[.15]itemname}"; + prompt_empty = "{prompt $winname}"; + + topic = " $topic"; + topic_empty = " Irssi v$J - https://irssi.org"; + + lag = "{sb Lag: $0-}"; + act = "{sb Act: $0-}"; + more = "-- more --"; + }; + + default = { + + window = { + + disabled = "no"; + type = "window"; + placement = "bottom"; + position = "1"; + visible = "active"; + + items = { + barstart = { priority = "100"; }; + time = { }; + user = { }; + window = { }; + window_empty = { }; + lag = { priority = "-1"; }; + act = { priority = "10"; }; + more = { priority = "-1"; alignment = "right"; }; + barend = { priority = "100"; alignment = "right"; }; + }; + }; + + window_inact = { + + type = "window"; + placement = "bottom"; + position = "1"; + visible = "inactive"; + + items = { + barstart = { priority = "100"; }; + window = { }; + window_empty = { }; + more = { priority = "-1"; alignment = "right"; }; + barend = { priority = "100"; alignment = "right"; }; + }; + }; + + prompt = { + + type = "root"; + placement = "bottom"; + position = "100"; + visible = "always"; + + items = { + prompt = { priority = "-1"; }; + prompt_empty = { priority = "-1"; }; + input = { priority = "10"; }; + }; + }; + + topic = { + + type = "root"; + placement = "top"; + position = "1"; + visible = "always"; + + items = { + topicbarstart = { priority = "100"; }; + topic = { }; + topic_empty = { }; + topicbarend = { priority = "100"; alignment = "right"; }; + }; + }; + }; +}; +settings = { + core = { + real_name = "DavidJ"; + user_name = "swytch"; + nick = "swytch"; + timestamp_format = "%H:%M:%S"; + }; + "fe-text" = { actlist_sort = "refnum"; }; + "fe-common/core" = { theme = "elf"; }; +}; +hilights = ( { text = "swytch"; nick = "yes"; word = "yes"; } ); +windows = { + 1 = { immortal = "yes"; name = "(status)"; level = "ALL"; }; + 2 = { name = "hilight"; sticky = "yes"; }; +}; +mainwindows = { + 1 = { + first_line = "12"; + lines = "39"; + first_column = "0"; + columns = "191"; + }; + 2 = { + first_line = "1"; + lines = "11"; + first_column = "0"; + columns = "191"; + }; +}; diff --git a/.config/ncmpcpp/config b/.config/ncmpcpp/config index f03266e..5efb1a6 100644 --- a/.config/ncmpcpp/config +++ b/.config/ncmpcpp/config @@ -400,7 +400,7 @@ song_columns_list_format = (6f)[green]{NE} (30)[white]{t|f:Title} (7f)[green]{l} #statusbar_visibility = yes # ## Show the "Connected to ..." message on startup -#connected_message_on_startup = yes +connected_message_on_startup = no # #titles_visibility = yes # diff --git a/.config/nvim/after/ftplugin/tex.lua b/.config/nvim/after/ftplugin/tex.lua index 03263b5..f04c922 100644 --- a/.config/nvim/after/ftplugin/tex.lua +++ b/.config/nvim/after/ftplugin/tex.lua @@ -1,9 +1,15 @@ -- Author : swytch -- Created : Monday Oct. 04, 2021 16:09:13 CET -- License : GPLv3 --- Description : tex fietype config +-- Description : tex filetype config +local opt = vim.opt +local g = vim.g + +opt.formatoptions = "trq1jp" +opt.tabstop = 4 + -- Caps utils.map("i", "AA", "À") utils.map("i", "CC", "Ç") diff --git a/.config/nvim/init.lua b/.config/nvim/init.lua index 0666dca..23d4c4e 100644 --- a/.config/nvim/init.lua +++ b/.config/nvim/init.lua @@ -3,9 +3,9 @@ -- License : GPLv3 -- Description : neovim configuration file -require("globals") -- ./lua/globals.lua -require("utils") -- ./lua/utils.lua -require("settings") -- ./lua/settings.lua -require("plugins") -- ./lua/plugins.lua -require("maps") -- ./lua/maps.lua -require("statusline") -- ./lua/statusline.lua +require("globals") -- ./lua/globals.lua +require("utils") -- ./lua/utils.lua +require("settings") -- ./lua/settings.lua +require("plugin.packer") -- ./lua/plugin/packer.lua +require("maps") -- ./lua/maps.lua +require("statusline") -- ./lua/statusline.lua diff --git a/.config/nvim/lua/maps.lua b/.config/nvim/lua/maps.lua index 0764807..afba301 100644 --- a/.config/nvim/lua/maps.lua +++ b/.config/nvim/lua/maps.lua @@ -26,3 +26,7 @@ utils.map("n", "tl", "Telescope live_grep") -- colorscheme utils.map("n", "", "lua require(\"astronomy\").toggle_variant()") + +-- snippets +utils.map("i", "", "luasnip-next-choice", {}) +utils.map("s", "", "luasnip-next-choice", {}) diff --git a/.config/nvim/lua/plugin/cmp.lua b/.config/nvim/lua/plugin/cmp.lua index c620fec..863282b 100644 --- a/.config/nvim/lua/plugin/cmp.lua +++ b/.config/nvim/lua/plugin/cmp.lua @@ -7,10 +7,6 @@ local cmp = require("cmp") local luasnip = require("luasnip") local cmp_autopairs = require('nvim-autopairs.completion.cmp') -local t = function(str) - return vim.api.nvim_replace_termcodes(str, true, true, true) -end - local check_backspace = function() local line, col = unpack(vim.api.nvim_win_get_cursor(0)) return col ~= 0 and @@ -27,18 +23,20 @@ cmp.setup { }, sources = { { name = "path" }, - { name = "buffer" }, + { name = "luasnip" }, { name = "nvim_lsp" }, + { name = "buffer" }, { name = "nvim_lua" }, - { name = "treesitter" }, { name = "calc" }, { name = "spell" }, + { name = "treesitter" }, }, formatting = { format = function(entry, vim_item) vim_item.menu = ({ nvim_lsp = "[lsp]", nvim_lua = "[nvim]", + luasnip = "[snip]", path = "[path]", buffer = "[buff]", calc = "[calc]", diff --git a/.config/nvim/lua/plugin/luasnip.lua b/.config/nvim/lua/plugin/luasnip.lua new file mode 100644 index 0000000..9531bf0 --- /dev/null +++ b/.config/nvim/lua/plugin/luasnip.lua @@ -0,0 +1,491 @@ +-- Author : swytch +-- Created : Friday Nov. 19, 2021 23:27:24 CET +-- License : GPLv3 +-- Description : luasnip config file + +local ls = require("luasnip") +-- some shorthands... +local s = ls.snippet +local sn = ls.snippet_node +local t = ls.text_node +local i = ls.insert_node +local f = ls.function_node +local c = ls.choice_node +local d = ls.dynamic_node +local l = require("luasnip.extras").lambda +local r = require("luasnip.extras").rep +local p = require("luasnip.extras").partial +local m = require("luasnip.extras").match +local n = require("luasnip.extras").nonempty +local dl = require("luasnip.extras").dynamic_lambda +local fmt = require("luasnip.extras.fmt").fmt +local fmta = require("luasnip.extras.fmt").fmta +local types = require("luasnip.util.types") +local conds = require("luasnip.extras.expand_conditions") + +-- Every unspecified option will be set to the default. +ls.config.set_config({ + history = true, + -- Update more often, :h events for more info. + updateevents = "TextChanged,TextChangedI", + ext_opts = { + [types.choiceNode] = { + active = { + virt_text = { { "choiceNode", "Comment" } }, + }, + }, + }, + -- treesitter-hl has 100, use something higher (default is 200). + ext_base_prio = 200, + -- minimal increase in priority. + ext_prio_increase = 1, + enable_autosnippets = true, +}) + +-- args is a table, where 1 is the text in Placeholder 1, 2 the text in +-- placeholder 2,... +local function copy(args) + return args[1] +end + +-- 'recursive' dynamic snippet. Expands to some text followed by itself. +local rec_ls +rec_ls = function() + return sn( + nil, + c(1, { + -- Order is important, sn(...) first would cause infinite loop of expansion. + t(""), + sn(nil, { t({ "", "", "\t\\item " }), i(1), d(2, rec_ls, {}) }), + }) + ) +end + +-- complicated function for dynamicNode. +local function jdocsnip(args, _, old_state) + local nodes = { + t({ "/**", " * " }), + i(1, "A short Description"), + t({ "", "" }), + } + + -- These will be merged with the snippet; that way, should the snippet be updated, + -- some user input eg. text can be referred to in the new snippet. + local param_nodes = {} + + if old_state then + nodes[2] = i(1, old_state.descr:get_text()) + end + param_nodes.descr = nodes[2] + + -- At least one param. + if string.find(args[2][1], ", ") then + vim.list_extend(nodes, { t({ " * ", "" }) }) + end + + local insert = 2 + for indx, arg in ipairs(vim.split(args[2][1], ", ", true)) do + -- Get actual name parameter. + arg = vim.split(arg, " ", true)[2] + if arg then + local inode + -- if there was some text in this parameter, use it as static_text for this new snippet. + if old_state and old_state[arg] then + inode = i(insert, old_state["arg" .. arg]:get_text()) + else + inode = i(insert) + end + vim.list_extend( + nodes, + { t({ " * @param " .. arg .. " " }), inode, t({ "", "" }) } + ) + param_nodes["arg" .. arg] = inode + + insert = insert + 1 + end + end + + if args[1][1] ~= "void" then + local inode + if old_state and old_state.ret then + inode = i(insert, old_state.ret:get_text()) + else + inode = i(insert) + end + + vim.list_extend( + nodes, + { t({ " * ", " * @return " }), inode, t({ "", "" }) } + ) + param_nodes.ret = inode + insert = insert + 1 + end + + if vim.tbl_count(args[3]) ~= 1 then + local exc = string.gsub(args[3][2], " throws ", "") + local ins + if old_state and old_state.ex then + ins = i(insert, old_state.ex:get_text()) + else + ins = i(insert) + end + vim.list_extend( + nodes, + { t({ " * ", " * @throws " .. exc .. " " }), ins, t({ "", "" }) } + ) + param_nodes.ex = ins + insert = insert + 1 + end + + vim.list_extend(nodes, { t({ " */" }) }) + + local snip = sn(nil, nodes) + -- Error on attempting overwrite. + snip.old_state = param_nodes + return snip +end + +-- Make sure to not pass an invalid command, as io.popen() may write over nvim-text. +local function bash(_, _, command) + local file = io.popen(command, "r") + local res = {} + for line in file:lines() do + table.insert(res, line) + end + return res +end + +-- Returns a snippet_node wrapped around an insert_node whose initial +-- text value is set to the current date in the desired format. +local date_input = function(args, state, fmt) + local fmt = fmt or "%Y-%m-%d" + return sn(nil, i(1, os.date(fmt))) +end + +ls.snippets = { + -- When trying to expand a snippet, luasnip first searches the tables for + -- each filetype specified in 'filetype' followed by 'all'. + -- If ie. the filetype is 'lua.c' + -- - luasnip.lua + -- - luasnip.c + -- - luasnip.all + -- are searched in that order. + all = { + -- trigger is fn. + s("fn", { + -- Simple static text. + t("//Parameters: "), + -- function, first parameter is the function, second the Placeholders + -- whose text it gets as input. + f(copy, 2), + t({ "", "function " }), + -- Placeholder/Insert. + i(1), + t("("), + -- Placeholder with initial text. + i(2, "int foo"), + -- Linebreak + t({ ") {", "\t" }), + -- Last Placeholder, exit Point of the snippet. EVERY 'outer' SNIPPET NEEDS Placeholder 0. + i(0), + t({ "", "}" }), + }), + s("class", { + -- Choice: Switch between two different Nodes, first parameter is its position, second a list of nodes. + c(1, { + t("public "), + t("private "), + }), + t("class "), + i(2), + t(" "), + c(3, { + t("{"), + -- sn: Nested Snippet. Instead of a trigger, it has a position, just like insert-nodes. !!! These don't expect a 0-node!!!! + -- Inside Choices, Nodes don't need a position as the choice node is the one being jumped to. + sn(nil, { + t("extends "), + i(1), + t(" {"), + }), + sn(nil, { + t("implements "), + i(1), + t(" {"), + }), + }), + t({ "", "\t" }), + i(0), + t({ "", "}" }), + }), + -- Use a dynamic_node to interpolate the output of a + -- function (see date_input above) into the initial + -- value of an insert_node. + s("novel", { + t("It was a dark and stormy night on "), + d(1, date_input, {}, "%A, %B %d of %Y"), + t(" and the clocks were striking thirteen."), + }), + -- Parsing snippets: First parameter: Snippet-Trigger, Second: Snippet body. + -- Placeholders are parsed into choices with 1. the placeholder text(as a snippet) and 2. an empty string. + -- This means they are not SELECTed like in other editors/Snippet engines. + ls.parser.parse_snippet( + "lspsyn", + "Wow! This ${1:Stuff} really ${2:works. ${3:Well, a bit.}}" + ), + + -- When wordTrig is set to false, snippets may also expand inside other words. + ls.parser.parse_snippet( + { trig = "te", wordTrig = false }, + "${1:cond} ? ${2:true} : ${3:false}" + ), + + -- When regTrig is set, trig is treated like a pattern, this snippet will expand after any number. + ls.parser.parse_snippet({ trig = "%d", regTrig = true }, "A Number!!"), + -- Using the condition, it's possible to allow expansion only in specific cases. + s("cond", { + t("will only expand in c-style comments"), + }, { + condition = function(line_to_cursor, matched_trigger, captures) + -- optional whitespace followed by // + return line_to_cursor:match("%s*//") + end, + }), + -- there's some built-in conditions in "luasnip.extras.expand_conditions". + s("cond2", { + t("will only expand at the beginning of the line"), + }, { + condition = conds.line_begin, + }), + -- The last entry of args passed to the user-function is the surrounding snippet. + s( + { trig = "a%d", regTrig = true }, + f(function(_, snip) + return "Triggered with " .. snip.trigger .. "." + end, {}) + ), + -- It's possible to use capture-groups inside regex-triggers. + s( + { trig = "b(%d)", regTrig = true }, + f(function(_, snip) + return "Captured Text: " .. snip.captures[1] .. "." + end, {}) + ), + s({ trig = "c(%d+)", regTrig = true }, { + t("will only expand for even numbers"), + }, { + condition = function(line_to_cursor, matched_trigger, captures) + return tonumber(captures[1]) % 2 == 0 + end, + }), + -- Use a function to execute any shell command and print its text. + s("bash", f(bash, {}, "ls")), + -- Short version for applying String transformations using function nodes. + s("transform", { + i(1, "initial text"), + t({ "", "" }), + -- lambda nodes accept an l._1,2,3,4,5, which in turn accept any string transformations. + -- This list will be applied in order to the first node given in the second argument. + l(l._1:match("[^i]*$"):gsub("i", "o"):gsub(" ", "_"):upper(), 1), + }), + s("transform2", { + i(1, "initial text"), + t("::"), + i(2, "replacement for e"), + t({ "", "" }), + -- Lambdas can also apply transforms USING the text of other nodes: + l(l._1:gsub("e", l._2), { 1, 2 }), + }), + s({ trig = "trafo(%d+)", regTrig = true }, { + -- env-variables and captures can also be used: + l(l.CAPTURE1:gsub("1", l.TM_FILENAME), {}), + }), + -- Set store_selection_keys = "" (for example) in your + -- luasnip.config.setup() call to access TM_SELECTED_TEXT. In + -- this case, select a URL, hit Tab, then expand this snippet. + s("link_url", { + t(''), + i(1), + t(""), + i(0), + }), + -- Shorthand for repeating the text in a given node. + s("repeat", { i(1, "text"), t({ "", "" }), r(1) }), + -- Directly insert the ouput from a function evaluated at runtime. + s("part", p(os.date, "%Y")), + -- use matchNodes to insert text based on a pattern/function/lambda-evaluation. + s("mat", { + i(1, { "sample_text" }), + t(": "), + m(1, "%d", "contains a number", "no number :("), + }), + -- The inserted text defaults to the first capture group/the entire + -- match if there are none + s("mat2", { + i(1, { "sample_text" }), + t(": "), + m(1, "[abc][abc][abc]"), + }), + -- It is even possible to apply gsubs' or other transformations + -- before matching. + s("mat3", { + i(1, { "sample_text" }), + t(": "), + m( + 1, + l._1:gsub("[123]", ""):match("%d"), + "contains a number that isn't 1, 2 or 3!" + ), + }), + -- `match` also accepts a function, which in turn accepts a string + -- (text in node, \n-concatted) and returns any non-nil value to match. + -- If that value is a string, it is used for the default-inserted text. + s("mat4", { + i(1, { "sample_text" }), + t(": "), + m(1, function(text) + return (#text % 2 == 0 and text) or nil + end), + }), + -- The nonempty-node inserts text depending on whether the arg-node is + -- empty. + s("nempty", { + i(1, "sample_text"), + n(1, "i(1) is not empty!"), + }), + -- dynamic lambdas work exactly like regular lambdas, except that they + -- don't return a textNode, but a dynamicNode containing one insertNode. + -- This makes it easier to dynamically set preset-text for insertNodes. + s("dl1", { + i(1, "sample_text"), + t({ ":", "" }), + dl(2, l._1, 1), + }), + -- Obviously, it's also possible to apply transformations, just like lambdas. + s("dl2", { + i(1, "sample_text"), + i(2, "sample_text_2"), + t({ "", "" }), + dl(3, l._1:gsub("\n", " linebreak ") .. l._2, { 1, 2 }), + }), + -- Alternative printf-like notation for defining snippets. It uses format + -- string with placeholders similar to the ones used with Python's .format(). + s( + "fmt1", + fmt("To {title} {} {}.", { + i(2, "Name"), + i(3, "Surname"), + title = c(1, { t("Mr."), t("Ms.") }), + }) + ), + -- To escape delimiters use double them, e.g. `{}` -> `{{}}`. + -- Multi-line format strings by default have empty first/last line removed. + -- Indent common to all lines is also removed. Use the third `opts` argument + -- to control this behaviour. + s( + "fmt2", + fmt( + [[ + foo({1}, {3}) {{ + return {2} * {4} + }} + ]], + { + i(1, "x"), + r(1), + i(2, "y"), + r(2), + } + ) + ), + -- Empty placeholders are numbered automatically starting from 1 or the last + -- value of a numbered placeholder. Named placeholders do not affect numbering. + s( + "fmt3", + fmt("{} {a} {} {1} {}", { + t("1"), + t("2"), + a = t("A"), + }) + ), + -- The delimiters can be changed from the default `{}` to something else. + s( + "fmt4", + fmt("foo() { return []; }", i(1, "x"), { delimiters = "[]" }) + ), + -- `fmta` is a convenient wrapper that uses `<>` instead of `{}`. + s("fmt5", fmta("foo() { return <>; }", i(1, "x"))), + -- By default all args must be used. Use strict=false to disable the check + s( + "fmt6", + fmt("use {} only", { t("this"), t("not this") }, { strict = false }) + ), + }, + tex = { + -- rec_ls is self-referencing. That makes this snippet 'infinite' eg. have as many + -- \item as necessary by utilizing a choiceNode. + s("ls", { + t({ "\\begin{itemize}", "\t\\item " }), + i(1), + t({ "" }), + d(2, rec_ls, {}), + t({ "", "\\end{itemize}" }), + }), + s("frm", { + t({ "\\begin{" }), + i(1), + t({ "}[" }), + i(2), + t({ "]{" }), + f(copy, 1), + t({ ":" }), + i(3, "foo"), + t({ "}", "\t" }), + i(0), + t({ "", "\\end{" }), + f(copy, 1), + t({ "}" }), + }), + s("rmk", { + t({ "\\begin{rmk}" }), + t({ "", "\t" }), + i(1), + t({ "", "\\end{" }), + i(0), + }), + + }, +} + +-- autotriggered snippets have to be defined in a separate table, luasnip.autosnippets. +ls.autosnippets = { + all = { + s("autotrigger", { + t("autosnippet"), + }), + }, +} + +-- in a lua file: search lua-, then c-, then all-snippets. +ls.filetype_extend("lua", { "c" }) +-- in a cpp file: search c-snippets, then all-snippets only (no cpp-snippets!!). +ls.filetype_set("cpp", { "c" }) + +--[[ +-- Beside defining your own snippets you can also load snippets from "vscode-like" packages +-- that expose snippets in json files, for example . +-- Mind that this will extend `ls.snippets` so you need to do it after your own snippets or you +-- will need to extend the table yourself instead of setting a new one. +]] + +require("luasnip/loaders/from_vscode").load({ include = { "python" } }) -- Load only python snippets +-- The directories will have to be structured like eg. (include +-- a similar `package.json`) +require("luasnip/loaders/from_vscode").load({ paths = { "./my-snippets" } }) -- Load snippets from my-snippets folder + +-- You can also use lazy loading so you only get in memory snippets of languages you use +require("luasnip/loaders/from_vscode").lazy_load() -- You can pass { paths = "./my-snippets/"} as well diff --git a/.config/nvim/lua/plugins.lua b/.config/nvim/lua/plugin/packer.lua similarity index 91% rename from .config/nvim/lua/plugins.lua rename to .config/nvim/lua/plugin/packer.lua index d9b0148..e966282 100644 --- a/.config/nvim/lua/plugins.lua +++ b/.config/nvim/lua/plugin/packer.lua @@ -68,14 +68,18 @@ return require("packer").startup(function() use { "hrsh7th/nvim-cmp", requires = { - "L3MON4D3/LuaSnip", + { + "L3MON4D3/LuaSnip", + config = function() require("plugin.luasnip") end + }, + "saadparwaiz1/cmp_luasnip", "hrsh7th/cmp-nvim-lsp", "hrsh7th/cmp-nvim-lua", "hrsh7th/cmp-buffer", "hrsh7th/cmp-path", "hrsh7th/cmp-calc", "ray-x/cmp-treesitter", - "f3fora/cmp-spell" + "f3fora/cmp-spell", }, config = function() require("plugin.cmp") end } diff --git a/.config/sxhkd/sxhkdrc b/.config/sxhkd/sxhkdrc index 3687558..c608cfa 100644 --- a/.config/sxhkd/sxhkdrc +++ b/.config/sxhkd/sxhkdrc @@ -58,10 +58,13 @@ super + shift + {h,j,k,l} player {prev,stop,toggle,next} super + shift + m - $TERMINAL -g 128x32 -c "floating" -e $MUSIC_PLAYER + $TERMINAL -g 128x32 -c "floating" -e $MUSIC_CLIENT super + shift + n - $TERMINAL -g 128x32 -c "floating" -e neomutt + $TERMINAL -g 128x32 -c "floating" -e tsession "mail" "$MAIL_CLIENT" + +super + shift + i + $TERMINAL -g 128x32 -c "floating" -e tsession "mail" "$IRC_CLIENT" super + shift + t $TERMINAL -g 128x32 -c "floating" -e tremc diff --git a/.config/tmux/tmux.conf b/.config/tmux/tmux.conf new file mode 100644 index 0000000..eac9399 --- /dev/null +++ b/.config/tmux/tmux.conf @@ -0,0 +1,81 @@ +# +# +# Adapated from the work of Nicholas Marriott. Public domain. +# + +# Some tweaks to the status line +# set -g status-right "$SHELL" +# set -g window-status-current-style "underscore" + +set-option -g status-style bg=color0 # bg=bg1, fg=fg1 + +set-option -g status-left "\ +#[fg=color8, bg=color7]#{?client_prefix,#[bg=color9],} ❐ #S " + +set-option -g status-right "\ +#[fg=color7, bg=color8] %b. %d \ +#[fg=color10] ( %I:%M%p )" + +set-window-option -g window-status-current-format "\ +#[fg=color7, bg=color8] #I* \ +#[fg=color7, bg=color0, bold] #W " + +set-window-option -g window-status-format "\ +#[fg=color7, bg=color8] #I \ +#[fg=color7, bg=color0, bold] #W " + +# Set the history limit so we get lots of scrollback. +setw -g history-limit 50000000 + +# If running inside tmux ($TMUX is set), then change the status line to red +%if #{TMUX} +set -g status-bg red +%endif + +# Enable RGB colour if running in xterm(1) +set-option -sa terminal-overrides ",xterm*:Tc" + +# Change the default $TERM to tmux-256color +set -g default-terminal "tmux-256color" + +# No bells at all +set -g bell-action none + +# Keep windows around after they exit +# set -g remain-on-exit on + +# Change the prefix key to C-a +unbind C-b +set -g prefix C-a +bind C-a send-prefix + +# Turn the mouse on, but without copy mode dragging +# set -g mouse on +# unbind -n MouseDrag1Pane +# unbind -Tcopy-mode MouseDrag1Pane + +# Some extra key bindings to select higher numbered windows +bind F1 selectw -t:10 +bind F2 selectw -t:11 +bind F3 selectw -t:12 +bind F4 selectw -t:13 +bind F5 selectw -t:14 +bind F6 selectw -t:15 +bind F7 selectw -t:16 +bind F8 selectw -t:17 +bind F9 selectw -t:18 +bind F10 selectw -t:19 +bind F11 selectw -t:20 +bind F12 selectw -t:21 + +# A key to toggle between smallest and largest sizes if a window is visible in +# multiple places +bind F set -w window-size + +# Keys to toggle monitoring activity in a window and the synchronize-panes option +bind m set monitor-activity +bind y set synchronize-panes\; display 'synchronize-panes #{?synchronize-panes,on,off}' + +# Session loading +bind i source-file $XDG_CONFIG_HOME/tmux/irssi.session +bind l source-file $XDG_CONFIG_HOME/tmux/latex.session diff --git a/.config/zsh/.zprofile b/.config/zsh/.zprofile index a072d61..bd0ee81 100644 --- a/.config/zsh/.zprofile +++ b/.config/zsh/.zprofile @@ -31,4 +31,6 @@ export EDITOR="nvim" export TERMINAL="st" export READER="zathura" export BROWSER="firefox" -export MUSIC_PLAYER="ncmpcpp" +export IRC_CLIENT="irssi" +export MAIL_CLIENT="neomutt" +export MUSIC_CLIENT="ncmpcpp" diff --git a/.config/zsh/.zshrc b/.config/zsh/.zshrc index 7588c43..6b444b6 100644 --- a/.config/zsh/.zshrc +++ b/.config/zsh/.zshrc @@ -3,6 +3,7 @@ # Reset tty for gpg export GPG_TTY=$(tty) +gpg-connect-agent updatestartuptty /bye >/dev/null # Enable colors and change prompt: autoload -U colors && colors diff --git a/.local/bin/maker b/.local/bin/maker index 6189d5b..1637334 100755 --- a/.local/bin/maker +++ b/.local/bin/maker @@ -11,15 +11,15 @@ ###################################################################### -headers_list="$(ls | grep '.h$')" -sources_list="$(ls | grep '.cp*$')" +headers_list="$(ls | grep '\.hp*$')" +sources_list="$(ls | grep '\.cp*$')" modules_list="$(printf "\n$sources_list" | sed 's/\.cp*//g' | tr '\n' ' ')" targets_list="$(printf "\n$sources_list" | sed 's/\.cp*/\.o/g' | tr '\n' ' ')" get_compiler(){ for source_ in "$sources_list"; do case "$source_" in - *.cpp) comp="g++" && return;; + *.cpp) comp="g++";; *.c) comp="gcc";; esac done diff --git a/.local/bin/tsession b/.local/bin/tsession new file mode 100755 index 0000000..a631648 --- /dev/null +++ b/.local/bin/tsession @@ -0,0 +1,9 @@ +#! /usr/bin/env sh + +session="$1" +cmd="$2" + +tmux new -s $session -d +tmux send-keys -t $session "exec $cmd" C-m +tmux attach -t $session + diff --git a/.local/share/irssi/default.theme b/.local/share/irssi/default.theme new file mode 100644 index 0000000..79b1af5 --- /dev/null +++ b/.local/share/irssi/default.theme @@ -0,0 +1,295 @@ +# When testing changes, the easiest way to reload the theme is with /RELOAD. +# This reloads the configuration file too, so if you did any changes remember +# to /SAVE it first. Remember also that /SAVE overwrites the theme file with +# old data so keep backups :) + +# TEMPLATES: + +# The real text formats that irssi uses are the ones you can find with +# /FORMAT command. Back in the old days all the colors and texts were mixed +# up in those formats, and it was really hard to change the colors since you +# might have had to change them in tens of different places. So, then came +# this templating system. + +# Now the /FORMATs don't have any colors in them, and they also have very +# little other styling. Most of the stuff you need to change is in this +# theme file. If you can't change something here, you can always go back +# to change the /FORMATs directly, they're also saved in these .theme files. + +# So .. the templates. They're those {blahblah} parts you see all over the +# /FORMATs and here. Their usage is simply {name parameter1 parameter2}. +# When irssi sees this kind of text, it goes to find "name" from abstracts +# block below and sets "parameter1" into $0 and "parameter2" into $1 (you +# can have more parameters of course). Templates can have subtemplates. +# Here's a small example: +# /FORMAT format hello {colorify {underline world}} +# abstracts = { colorify = "%G$0-%n"; underline = "%U$0-%U"; } +# When irssi expands the templates in "format", the final string would be: +# hello %G%Uworld%U%n +# ie. underlined bright green "world" text. +# and why "$0-", why not "$0"? $0 would only mean the first parameter, +# $0- means all the parameters. With {underline hello world} you'd really +# want to underline both of the words, not just the hello (and world would +# actually be removed entirely). + +# COLORS: + +# You can find definitions for the color format codes in docs/formats.txt. + +# There's one difference here though. %n format. Normally it means the +# default color of the terminal (white mostly), but here it means the +# "reset color back to the one it was in higher template". For example +# if there was /FORMAT test %g{foo}bar, and foo = "%Y$0%n", irssi would +# print yellow "foo" (as set with %Y) but "bar" would be green, which was +# set at the beginning before the {foo} template. If there wasn't the %g +# at start, the normal behaviour of %n would occur. If you _really_ want +# to use the terminal's default color, use %N. + +############################################################################# + +# default foreground color (%N) - -1 is the "default terminal color" +default_color = "-1"; + +# print timestamp/servertag at the end of line, not at beginning +info_eol = "false"; + +# these characters are automatically replaced with specified color +# (dark grey by default) +replaces = { "[]=" = "%K$*%n"; }; + +abstracts = { + ## + ## generic + ## + + # text to insert at the beginning of each non-message line + line_start = "%B-%n!%B-%n "; + + # timestamp styling, nothing by default + timestamp = "$*"; + + # any kind of text that needs hilighting, default is to bold + hilight = "%_$*%_"; + + # any kind of error message, default is bright red + error = "%R$*%n"; + + # channel name is printed + channel = "%_$*%_"; + + # nick is printed + nick = "%_$*%_"; + + # nick host is printed + nickhost = "[$*]"; + + # server name is printed + server = "%_$*%_"; + + # some kind of comment is printed + comment = "[$*]"; + + # reason for something is printed (part, quit, kick, ..) + reason = "{comment $*}"; + + # mode change is printed ([+o nick]) + mode = "{comment $*}"; + + ## + ## channel specific messages + ## + + # highlighted nick/host is printed (joins) + channick_hilight = "%C$*%n"; + chanhost_hilight = "{nickhost %c$*%n}"; + + # nick/host is printed (parts, quits, etc.) + channick = "%c$*%n"; + chanhost = "{nickhost $*}"; + + # highlighted channel name is printed + channelhilight = "%c$*%n"; + + # ban/ban exception/invite list mask is printed + ban = "%c$*%n"; + + ## + ## messages + ## + + # the basic styling of how to print message, $0 = nick mode, $1 = nick + msgnick = "%K<%n$0$1-%K>%n %|"; + + # message from you is printed. "ownnick" specifies the styling of the + # nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the + # whole line. + + # Example1: You want the message text to be green: + # ownmsgnick = "{msgnick $0 $1-}%g"; + # Example2.1: You want < and > chars to be yellow: + # ownmsgnick = "%Y{msgnick $0 $1-%Y}%n"; + # (you'll also have to remove <> from replaces list above) + # Example2.2: But you still want to keep <> grey for other messages: + # pubmsgnick = "%K{msgnick $0 $1-%K}%n"; + # pubmsgmenick = "%K{msgnick $0 $1-%K}%n"; + # pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n"; + # ownprivmsgnick = "%K{msgnick $*%K}%n"; + # privmsgnick = "%K{msgnick %R$*%K}%n"; + + # $0 = nick mode, $1 = nick + ownmsgnick = "{msgnick $0 $1-}"; + ownnick = "%_$*%n"; + + # public message in channel, $0 = nick mode, $1 = nick + pubmsgnick = "{msgnick $0 $1-}"; + pubnick = "%N$*%n"; + + # public message in channel meant for me, $0 = nick mode, $1 = nick + pubmsgmenick = "{msgnick $0 $1-}"; + menick = "%Y$*%n"; + + # public highlighted message in channel + # $0 = highlight color, $1 = nick mode, $2 = nick + pubmsghinick = "{msgnick $1 $0$2-%n}"; + + # channel name is printed with message + msgchannel = "%K:%c$*%n"; + + # private message, $0 = nick, $1 = host + privmsg = "[%R$0%K(%r$1-%K)%n] "; + + # private message from you, $0 = "msg", $1 = target nick + ownprivmsg = "[%r$0%K(%R$1-%K)%n] "; + + # own private message in query + ownprivmsgnick = "{msgnick $*}"; + ownprivnick = "%_$*%n"; + + # private message in query + privmsgnick = "{msgnick %R$*%n}"; + + ## + ## Actions (/ME stuff) + ## + + # used internally by this theme + action_core = "%_ * $*%n"; + + # generic one that's used by most actions + action = "{action_core $*} "; + + # own action, both private/public + ownaction = "{action $*}"; + + # own action with target, both private/public + ownaction_target = "{action_core $0}%K:%c$1%n "; + + # private action sent by others + pvtaction = "%_ (*) $*%n "; + pvtaction_query = "{action $*}"; + + # public action sent by others + pubaction = "{action $*}"; + + + ## + ## other IRC events + ## + + # whois + whois = "%# $[8]0 : $1-"; + + # notices + ownnotice = "[%r$0%K(%R$1-%K)]%n "; + notice = "%K-%M$*%K-%n "; + pubnotice_channel = "%K:%m$*"; + pvtnotice_host = "%K(%m$*%K)"; + servernotice = "%g!$*%n "; + + # CTCPs + ownctcp = "[%r$0%K(%R$1-%K)] "; + ctcp = "%g$*%n"; + + # wallops + wallop = "%_$*%n: "; + wallop_nick = "%n$*"; + wallop_action = "%_ * $*%n "; + + # netsplits + netsplit = "%R$*%n"; + netjoin = "%C$*%n"; + + # /names list + names_prefix = ""; + names_nick = "[%_$0%_$1-] "; + names_nick_op = "{names_nick $*}"; + names_nick_halfop = "{names_nick $*}"; + names_nick_voice = "{names_nick $*}"; + names_users = "[%g$*%n]"; + names_channel = "%G$*%n"; + + # DCC + dcc = "%g$*%n"; + dccfile = "%_$*%_"; + + # DCC chat, own msg/action + dccownmsg = "[%r$0%K($1-%K)%n] "; + dccownnick = "%R$*%n"; + dccownquerynick = "%_$*%n"; + dccownaction = "{action $*}"; + dccownaction_target = "{action_core $0}%K:%c$1%n "; + + # DCC chat, others + dccmsg = "[%G$1-%K(%g$0%K)%n] "; + dccquerynick = "%G$*%n"; + dccaction = "%_ (*dcc*) $*%n %|"; + + ## + ## statusbar + ## + + # default background for all statusbars. You can also give + # the default foreground color for statusbar items. + sb_background = "%4%w"; + window_border = "%4%w"; + + # default backround for "default" statusbar group + #sb_default_bg = "%4"; + # background for prompt / input line + sb_prompt_bg = "%n"; + # background for info statusbar + sb_info_bg = "%8"; + # background for topicbar (same default) + #sb_topic_bg = "%4"; + + # text at the beginning of statusbars. "sb" already puts a space there, + # so we don't use anything by default. + sbstart = ""; + # text at the end of statusbars. Use space so that it's never + # used for anything. + sbend = " "; + + topicsbstart = "{sbstart $*}"; + topicsbend = "{sbend $*}"; + + prompt = "[$*] "; + + sb = " %c[%n$*%c]%n"; + sbmode = "(%c+%n$*)"; + sbaway = " (%GzZzZ%n)"; + sbservertag = ":$0 (change with ^X)"; + sbnickmode = "$0"; + + # activity in statusbar + + # ',' separator + sb_act_sep = "%c$*"; + # normal text + sb_act_text = "%c$*"; + # public message + sb_act_msg = "%W$*"; + # hilight + sb_act_hilight = "%M$*"; + # hilight with specified color, $0 = color, $1 = text + sb_act_hilight_color = "$0$1-%n"; +}; diff --git a/.local/share/irssi/elf.theme b/.local/share/irssi/elf.theme new file mode 100644 index 0000000..5f7a257 --- /dev/null +++ b/.local/share/irssi/elf.theme @@ -0,0 +1,498 @@ +# When testing changes, the easiest way to reload the theme is with /RELOAD. +# This reloads the configuration file too, so if you did any changes remember +# to /SAVE it first. Remember also that /SAVE overwrites the theme file with +# old data so keep backups :) + +# TEMPLATES: + +# The real text formats that irssi uses are the ones you can find with +# /FORMAT command. Back in the old days all the colors and texts were mixed +# up in those formats, and it was really hard to change the colors since you +# might have had to change them in tens of different places. So, then came +# this templating system. + +# Now the /FORMATs don't have any colors in them, and they also have very +# little other styling. Most of the stuff you need to change is in this +# theme file. If you can't change something here, you can always go back +# to change the /FORMATs directly, they're also saved in these .theme files. + +# So .. the templates. They're those {blahblah} parts you see all over the +# /FORMATs and here. Their usage is simply {name parameter1 parameter2}. +# When irssi sees this kind of text, it goes to find "name" from abstracts +# block below and sets "parameter1" into $0 and "parameter2" into $1 (you +# can have more parameters of course). Templates can have subtemplates. +# Here's a small example: +# /FORMAT format hello {colorify {underline world}} +# abstracts = { colorify = "%G$0-%n"; underline = "%U$0-%U"; } +# When irssi expands the templates in "format", the final string would be: +# hello %G%Uworld%U%n +# ie. underlined bright green "world" text. +# and why "$0-", why not "$0"? $0 would only mean the first parameter, +# $0- means all the parameters. With {underline hello world} you'd really +# want to underline both of the words, not just the hello (and world would +# actually be removed entirely). + +# COLORS: + +# You can find definitions for the color format codes in docs/formats.txt. + +# There's one difference here though. %n format. Normally it means the +# default color of the terminal (white mostly), but here it means the +# "reset color back to the one it was in higher template". For example +# if there was /FORMAT test %g{foo}bar, and foo = "%Y$0%n", irssi would +# print yellow "foo" (as set with %Y) but "bar" would be green, which was +# set at the beginning before the {foo} template. If there wasn't the %g +# at start, the normal behaviour of %n would occur. If you _really_ want +# to use the terminal's default color, use %N. + +############################################################################# + +# default foreground color (%N) - -1 is the "default terminal color" +default_color = "-1"; + +# these characters are automatically replaced with specified color +# (dark grey by default) +replaces = { }; + +abstracts = { + ## + ## generic + ## + + # text to insert at the beginning of each non-message line + line_start = "%B-%r!%B-%n"; + + # timestamp styling, nothing by default + timestamp = "%w$*%n"; + + # any kind of text that needs hilighting, default is to bold + #hilight = "%W$*%n"; + hilight = "%_$*%_"; + + # any kind of error message, default is bright red + error = "%r$*%n"; + infomessage = "%GInfo:%n $*"; + acknowledgedmessage = "%gAcknowledged:%n $*"; + warningmessage = "%yWarning:%n $*"; + errormessage = "%rError:%n $*"; + attentionmessage = "%YAttention:%n $*"; + channelmessage = "%BChannel:%n $*"; + usermessage = "%CUser:%n $*"; + + # channel name is printed + channel = "%B$*%n"; + + # nick is printed + nick = "%c$*%c%n"; + + # nick host is printed + nickhost = "%B[%c$*%B]%n"; + + # server name is printed + server = "%b$*%n"; + + # some kind of comment is printed + comment = "$*"; + + # reason for something is printed (part, quit, kick, ..) + reason = "(%c{comment $*}%n)"; + + # mode change is printed ([+o nick]) + mode = "[%B{comment $*}%n]"; + + ## + ## channel specific messages + ## + + # highlighted nick/host is printed (joins) + channick_hilight = "%C$*%n"; + chanhost_hilight = "{nickhost %c$*%n}"; + + # nick/host is printed (parts, quits, etc.) + channick = "%c$*%n"; + chanhost = "{nickhost $*}"; + + # highlighted channel name is printed + channelhilight = "%c$*%n"; + + # ban/ban exception/invite list mask is printed + ban = "%c$*%n"; + + ## + ## messages + ## + + # the basic styling of how to print message, $0 = nick mode, $1 = nick + msgnick = "$0$1- %|"; + + # message from you is printed. "msgownnick" specifies the styling of the + # nick ($0 part in msgnick) and "ownmsgnick" specifies the styling of the + # whole line. + + # Example1: You want the message text to be green: + # ownmsgnick = "{msgnick $0 $1-}%g"; + # Example2.1: You want < and > chars to be yellow: + # ownmsgnick = "%Y{msgnick $0 $1-%Y}%n"; + # (you'll also have to remove <> from replaces list above) + # Example2.2: But you still want to keep <> grey for other messages: + # pubmsgnick = "%K{msgnick $0 $1-%K}%n"; + # pubmsgmenick = "%K{msgnick $0 $1-%K}%n"; + # pubmsghinick = "%K{msgnick $1 $0$2-%n%K}%n"; + # ownprivmsgnick = "%K{msgnick $*%K}%n"; + # privmsgnick = "%K{msgnick %R$*%K}%n"; + + # $0 = nick mode, $1 = nick + ownmsgnick = "{msgnick $0 $1-}"; + ownnick = "%Y$*%n"; + + # public message in channel, $0 = nick mode, $1 = nick + pubmsgnick = "{msgnick $0 $1-}"; + pubnick = "%N$*%n"; + + # public message in channel meant for me, $0 = nick mode, $1 = nick + pubmsgmenick = "{msgnick $0 $1-}"; + menick = "%R$*%n"; + + # public highlighted message in channel + # $0 = highlight color, $1 = nick mode, $2 = nick + pubmsghinick = "{msgnick $1 $0$2-%n}"; + + # channel name is printed with message + msgchannel = "%K:%c$*%n"; + + # private message, $0 = nick, $1 = host + privmsg = "%w[%R$0%w ]%n "; + + # private message from you, $0 = "msg", $1 = target nick + ownprivmsg = "%w[%R$1%w ]%n "; + + # own private message in query + ownprivmsgnick = "{msgnick $*}"; + ownprivnick = "%R$*%n"; + + # private message in query + privmsgnick = "{msgnick %R$*%n}"; + + ## + ## Actions (/ME stuff) + ## + + # used internally by this theme + action_core = "%b * $*%n"; + + # generic one that's used by most actions + action = "{action_core $*} "; + + # own action, both private/public + ownaction = "{action $*}"; + + # own action with target, both private/public + ownaction_target = "{action_core $0}%K:%c$1%n "; + + # private action sent by others + pvtaction = "%b (*) $*%n "; + pvtaction_query = "{action $*}"; + + # public action sent by others + pubaction = "{action $*}"; + + + ## + ## other IRC events + ## + + # whois + whois = " $[8]0 : $1-"; + + # notices + ownnotice = "[%r$0%K(%R$1-%K)]%n "; + notice = "%K-%M$*%K-%n "; + pubnotice_channel = "%K:%m$*%n"; + pvtnotice_host = "%K(%m$*%K)%n"; + servernotice = "%g!$*%n "; + + # CTCPs + ownctcp = "[%r$0%K(%R$1-%K)] "; + ctcp = "%g$*%n"; + + # wallops + wallop = "%r$*%n: "; + wallop_nick = "%n$*"; + wallop_action = "%r * $*%n "; + + # netsplits + netsplit = "%r$*%n"; + netjoin = "%C$*%n"; + + # /names list + names_prefix = " %w-%c-%C-%n| "; + names_nick = "[%_$0%_$1-] "; + names_nick_op = "{names_nick $*}"; + names_nick_halfop = "{names_nick $*}"; + names_nick_voice = "{names_nick $*}"; + names_users = "[%g$*%n]"; + names_channel = "%y$*%n"; + + # DCC + dcc = "%g$*%n"; + dccfile = "%r$*%n"; + + # DCC chat, own msg/action + dccownmsg = "[%r$0%K($1-%K)%n] "; + dccownnick = "%R$*%n"; + dccownaction = "{action $*}"; + dccownaction_target = "{action_core $0}%K:%c$1%n "; + + # DCC chat, others + dccmsg = "[%G$1-%K(%g$0%K)%n] "; + dccquerynick = "%G$*%n"; + dccaction = "%r (*dcc*) $*%n %|"; + + ## + ## statusbar + ## + + # default background for all statusbars + sb_background = "%Y"; + + # default backround for "default" statusbar group + #sb_default_bg = "%4"; + # background for prompt / input line + sb_prompt_bg = ""; + # background for info statusbar + sb_info_bg = ""; + # background for topicbar (same default) + sb_topic_bg = "%w"; + + # text at the beginning of statusbars. sb-item already puts + # space there,so we don't use anything by default. + sbstart = ""; + # text at the end of statusbars. Use space so that it's never + # used for anything. + sbend = " "; + + prompt = "[$*]: "; + + sb = " %c[%n$*%c]%n"; + sbmode = "(%c+%n$*)"; + sbaway = " (%GzZzZ%n)"; + sbservertag = ":$0 (change with ^X)"; + + # activity in statusbar + + # ',' separator + sb_act_sep = "%c$*"; + # normal text + sb_act_text = "%c$*"; + # public message + sb_act_msg = "%r$*"; + # hilight + sb_act_hilight = "%R$*"; + # hilight with specified color, $0 = color, $1 = text + sb_act_hilight_color = "$0$1-%n"; + + sb_lightbar_bg = "%c"; + lightbar_selected_item = "%W$0%n"; + lightbar_hilighted_item = "%Y$0%n"; + lightbar_activated_item = "%C$0%n"; + +}; +formats = { + "fe-common/irc" = { + notice_server = "%w{servernotice $[-10]0}$1"; + no_netsplits = "{errormessage There are no net splits}"; + ircnet_added = "{acknowledgedmessage Ircnet $0 saved}"; + ircnet_removed = "{acknowledgedmessage Ircnet $0 removed}"; + ircnet_not_found = "{errormessage Ircnet $0 not found}"; + joinerror_toomany = "{errormessage Cannot join to channel {channel $0} (You have joined to too many channels)}"; + joinerror_full = "{errormessage Cannot join to channel {channel $0} (Channel is full)}"; + joinerror_invite = "{errormessage Cannot join to channel {channel $0} (You must be invited)}"; + joinerror_banned = "{errormessage Cannot join to channel {channel $0} (You are banned)}"; + joinerror_bad_key = "{errormessage Cannot join to channel {channel $0} (Bad channel key)}"; + joinerror_bad_mask = "{errormessage Cannot join to channel {channel $0} (Bad channel mask)}"; + joinerror_unavail = "{errormessage Cannot join to channel {channel $0} (Channel is temporarily unavailable)}"; + joinerror_duplicate = "{errormessage Channel {channel $0} already exists - cannot create it}"; + channel_rejoin = "{errormessage Channel {channel $0} is temporarily unavailable, this is normally because of netsplits. Irssi will now automatically try to rejoin back to this channel until the join is successful. Use /RMREJOINS command if you wish to abort this.}"; + inviting = "{channelmessage Inviting {nick $0} to {channel $1}}"; + channel_created = "{channelmessage Channel {channelhilight $0} created $1}"; + url = "{channelmessage Home page for {channelhilight $0}: $1}"; + topic = "{channelmessage Topic for {channelhilight $0}: $1}"; + no_topic = "{channelmessage No topic set for {channelhilight $0}}"; + topic_info = "{channelmessage Topic set by {nick $0} {comment $1}}"; + chanmode_change = "{channelmessage mode/{channelhilight $0} {mode $1} by {nick $2}}"; + server_chanmode_change = "{channelmessage {netsplit ServerMode}/{channelhilight $0} {mode $1} by {nick $2}}"; + bantype = "{acknowledgedmessage Ban type changed to {channel $0}}"; + no_bans = "{infomessage No bans in channel {channel $0}}"; + no_invitelist = "{infomessage Invite list is empty in channel {channel $0}}"; + no_such_channel = "{errormessage {channel $0}: No such channel}"; + channel_synced = "{channelmessage Join to {channel $0} was synced in {hilight $1} secs}"; + usermode_change = "{usermessage Mode change {mode $0} for user {nick $1}}"; + user_mode = "{acknowledgedmessage Your user mode is {mode $0}}"; + away = "{acknowledgedmessage You have been marked as being away}"; + unaway = "{acknowledgedmessage You are no longer marked as being away}"; + nick_away = "{warningmessage {nick $0} is away: $1}"; + no_such_nick = "{errormessage {nick $0}: No such nick/channel}"; + nick_in_use = "{errormessage Nick {nick $0} is already in use}"; + nick_unavailable = "{errormessage Nick {nick $0} is temporarily unavailable}"; + your_nick_owned = "{infomessage Your nick is owned by {nick $3} {comment $1@$2}}"; + whois_not_found = "{errormessage There is no such nick $0}"; + own_notice = "{ownnotice notice $0}$1"; + own_action = "{ownaction $[-12]0}$1"; + own_action_target = "{ownaction_target $[-14]0}$1"; + own_ctcp = "{ownctcp ctcp $0}$1 $2"; + notice_public = "{notice $0{pubnotice_channel $1}}$2"; + notice_private = "{notice $0}$2"; + action_private = "{pvtaction $0}$2"; + action_private_query = "{pvtaction_query $0}$2"; + action_public = "{pubaction \00311$[-12]0%n}$1"; + action_public_channel = "{pubaction \00311$[-11]0 %m({msgchannel $1})%n}$2"; + kill = "{attentionmessage You were {error killed} by {nick $0} {nickhost $1} {reason $2} {comment Path: $3}}"; + kill_server = "{attentionmessage You were {error killed} by {server $0} {reason $1} {comment Path: $2}}"; + unknown_mode = "{errormessage Unknown mode character $0}"; + not_chanop = "{errormessage You're not channel operator in {channel $0}}"; + silenced = "{acknowledgedmessage Silenced {nick $0}}"; + unsilenced = "{acknowledgedmessage Unsilenced {nick $0}}"; + default_event = "$1 [$0]"; + }; + "fe-common/core" = { + pubmsg = "{pubmsgnick $2 {pubnick \00313$[-13]0 %n| }}$1"; + pubmsg_channel = "{pubmsgnick $3 {pubnick \00313$[-13]0} %n| %m({msgchannel $1})%n}$2"; + line_start = " %w-%c-%C-%n| %n"; + line_start_irssi = " {line_start}%n| %rIrssi: %n"; + servertag = "[%b$0%n]"; + refnum_too_low = "{errormessage Window number must be greater than 1}"; + error_server_sticky = "{errormessage Window's server is sticky and it cannot be changed without -unsticky option}"; + set_server_sticky = "{acknowledgedmessage Window's server set sticky}"; + unset_server_sticky = "{acknowledgedmessage Window's server isn't sticky anymore}"; + window_level = "{acknowledgedmessage Window level is now $0}"; + windows_layout_saved = "{infomessage Layout of windows is now remembered next time you start irssi}"; + windows_layout_reset = "{infomessage Layout of windows reset to defaults}"; + looking_up = "{infomessage Looking up {server $0}}"; + connecting = "{infomessage Connecting to {server $0} [$1] port {hilight $2}}"; + connection_established = "{infomessage Connection to {server $0} established}"; + cant_connect = "{errormessage Unable to connect server {server $0} port {hilight $1} {reason $2}}"; + connection_lost = "{errormessage Connection lost to {server $0}}"; + lag_disconnected = "{warningmessage No PONG reply from server {server $0} in $1 seconds, disconnecting}"; + disconnected = "{infomessage Disconnected from {server $0} {reason $1}}"; + server_quit = "{infomessage Disconnecting from server {server $0}: {reason $1}}"; + unknown_server_tag = "{errormessage Unknown server tag {server $0}}"; + no_connected_servers = "{errormessage Not connected to any servers}"; + server_reconnect_removed = "{acknowledgedmessage Removed reconnection to server {server $0} port {hilight $1}}"; + server_reconnect_not_found = "{errormessage Reconnection tag {server $0} not found}"; + setupserver_added = "{acknowledgedmessage Server {server $0} saved}"; + setupserver_removed = "{acknowledgedmessage Server {server $0} removed}"; + setupserver_not_found = "{errormessage Server {server $0} not found}"; + your_nick = "{infomessage Your nickname is {nick $0}}"; + join = "%b---> {channick_hilight $0} {chanhost_hilight $1} has joined {channel $2}"; + part = "%b<--- {channick $0} {chanhost $1} has left {channel $2} {reason $3}"; + kick = "%R!!!!%n {channick $0} was kicked from {channel $1} by {nick $2} {reason $3}"; + quit = "%b<<-- {channick $0} {chanhost $1} has quit {reason $2}"; + quit_once = "%b<<-- {channel $3} {channick $0} {chanhost $1} has quit {reason $2}"; + invite = "{attentionmessage {nick $0} invites you to {channel $1}}"; + not_invited = "{errormessage You have not been invited to a channel!}"; + new_topic = "{channelmessage {nick $0} changed the topic of {channel $1} to: $2}"; + topic_unset = "{channelmessage Topic unset by {nick $0} on {channel $1}}"; + your_nick_changed = "{acknowledgedmessage You're now known as {nick $1}}"; + nick_changed = "{usermessage %r*** %n{channick $0} is now known as {channick_hilight $1}}"; + not_in_channels = "{errormessage You are not on any channels}"; + names_prefix = " %w-%c-%C-%n| "; + chansetup_not_found = "{errormessage Channel {channel $0} not found}"; + chansetup_added = "{acknowledgedmessage Channel {channel $0} saved}"; + chansetup_removed = "{acknowledgedmessage Channel {channel $0} removed}"; + own_msg = "{ownmsgnick $2 {ownnick $[-13]0}%n |}%y$1"; + own_msg_channel = "{ownmsgnick $3 {ownnick $[-13]0}%n | %m({msgchannel $1})%y}$2"; + own_msg_private = "{ownprivmsg msg $[-13]0}$1"; + own_msg_private_query = "{ownprivmsgnick {ownprivnick $[-14]2}%n |}$1"; + pubmsg_me = "{pubmsgmenick $2{menick $[-13]0}%R | }$1"; + pubmsg_me_channel = "{pubmsgmenick $3 {menick $[-13]0}%R | %m({msgchannel $1})%R}$2"; + pubmsg_hilight = "{pubmsghinick $0 $3 $[-14]1}$2"; + pubmsg_hilight_channel = "{pubmsghinick $0 $4 $[-14]1{msgchannel $2}}$3"; + msg_private = "{privmsg $[-13]0}$2"; + msg_private_query = "{privmsgnick $[-14]0%n |}$2"; + no_msgs_got = "{errormessage You have not received a message from anyone yet}"; + no_msgs_sent = "{errormessage You have not sent a message to anyone yet}"; + query_start = "{attentionmessage Starting query in {server $1} with {nick $0}}"; + query_stop = "{acknowledgedmessage Closing query with {nick $0}}"; + no_query = "{errormessage No query with {nick $0}}"; + query_server_changed = "{acknowledgedmessage Query with {nick $0} changed to server {server $1}}"; + query_move_notify = "{errormessage Query with {nick $0} is already created to window $1, use \"/WINDOW ITEM MOVE $0\" to move it to this window}"; + hilight_not_found = "{errormessage Highlight not found: $0}"; + hilight_removed = "{acknowledgedmessage Highlight removed: $0}"; + alias_added = "{acknowledgedmessage Alias $0 added}"; + alias_removed = "{acknowledgedmessage Alias $0 removed}"; + alias_not_found = "{errormessage No such alias: $0}"; + log_opened = "{infomessage Log file {hilight $0} opened}"; + log_closed = "{infomessage Log file {hilight $0} closed}"; + log_create_failed = "{errormessage Couldn't create log file {hilight $0}: $1}"; + log_locked = "{warningmessage Log file {hilight $0} is locked, probably by another running Irssi}"; + log_not_open = "{errormessage Log file {hilight $0} not open}"; + log_started = "{infomessage Started logging to file {hilight $0}}"; + log_stopped = "{infomessage Stopped logging to file {hilight $0}}"; + windowlog_file = "{acknowledgedmessage Window LOGFILE set to $0}"; + windowlog_file_logging = "{errormessage Can't change window's logfile while log is on}"; + no_away_msgs = "{infomessage No new messages in awaylog}"; + away_msgs = "{attentionmessage {hilight $1} new messages in awaylog:}"; + module_already_loaded = "{warningmessage Module {hilight $0/$1} already loaded}"; + module_not_loaded = "{errormessage Module {hilight $0/$1} is not loaded}"; + module_load_error = "{errormessage Error loading module {hilight $0/$1}: $2}"; + module_invalid = "{errormessage {hilight $0/$1} isn't Irssi module}"; + module_loaded = "{infomessage Loaded module {hilight $0/$1}}"; + module_unloaded = "{infomessage Unloaded module {hilight $0/$1}}"; + command_unknown = "{errormessage Unknown command: $0}"; + command_ambiguous = "{errormessage Ambiguous command: $0}"; + option_unknown = "{errormessage Unknown option: $0}"; + option_ambiguous = "{errormessage Ambiguous option: $0}"; + option_missing_arg = "{errormessage Missing required argument for: $0}"; + not_enough_params = "{errormessage Not enough parameters given}"; + not_connected = "{errormessage Not connected to server}"; + not_joined = "{errormessage Not joined to any channel}"; + chan_not_found = "{errormessage Not joined to such channel}"; + chan_not_synced = "{errormessage Channel not fully synchronized yet, try again after a while}"; + illegal_proto = "{errormessage Command isn't designed for the chat protocol of the active server}"; + not_good_idea = "{warningmessage Doing this is not a good idea. Add -YES if you really mean it}"; + theme_saved = "{infomessage Theme saved to $0}"; + theme_save_failed = "{errormessage Error saving theme to $0: $1}"; + theme_not_found = "{errormessage Theme {hilight $0} not found}"; + theme_changed = "{acknowledgedmessage Using now theme {hilight $0} ($1)}"; + window_theme = "{acknowledgedmessage Using theme {hilight $0} in this window}"; + window_theme_default = "{errormessage No theme is set for this window}"; + window_theme_changed = "{acknowledgedmessage Using now theme {hilight $0} ($1) in this window}"; + window_theme_removed = "{acknowledgedmessage Removed theme from this window}"; + ignored = "{acknowledgedmessage Ignoring {hilight $1} from {nick $0}}"; + unignored = "{acknowledgedmessage Unignored {nick $0}}"; + ignore_not_found = "{errormessage {nick $0} is not being ignored}"; + ignore_no_ignores = "{errormessage There are no ignores}"; + unknown_chat_protocol = "{errormessage Unknown chat network: $0 (create it with /IRCNET ADD)}"; + not_toggle = "{errormessage Value must be either ON, OFF or TOGGLE}"; + perl_error = "{errormessage Perl error: $0}"; + bind_unknown_id = "{errormessage Unknown bind action: $0}"; + config_saved = "{infomessage Saved configuration to file $0}"; + config_reloaded = "{acknowledgedmessage Reloaded configuration}"; + config_modified = "{warningmessage Configuration file was modified since irssi was last started - do you want to overwrite the possible changes?}"; + set_unknown = "{errormessage Unknown setting $0}"; + set_not_boolean = "{errormessage Setting {hilight $0} isn't boolean, use /SET}"; + translation_not_found = "{errormessage Error opening translation table file $0: $1}"; + translation_file_error = "{errormessage Error parsing translation table file $0}"; + talking_in = ""; + timestamp = "{timestamp %%H:%%M:%%S} "; + }; + "fe-text" = { + lastlog_too_long = "{warningmessage /LASTLOG would print $0 lines. If you really want to print all these lines use -force option.}"; + window_too_small = "{errormessage Not enough room to resize this window}"; + cant_hide_last = "{errormessage You can't hide the last window}"; + cant_hide_sticky_windows = "{errormessage You can't hide sticky windows (use /WINDOW STICK OFF)}"; + cant_show_sticky_windows = "{errormessage You can't show sticky windows (use /WINDOW STICK OFF)}"; + window_not_sticky = "{errormessage Window is not sticky}"; + window_set_sticky = "{acknowledgedmessage Window set sticky}"; + window_unset_sticky = "{acknowledgedmessage Window is not sticky anymore}"; + window_scroll = "{acknowledgedmessage Window scroll mode is now $0}"; + window_scroll_unknown = "{errormessage Unknown scroll mode $0, must be ON, OFF or DEFAULT}"; + }; + "fe-common/perl" = { + script_not_found = "{errormessage Script {hilight $0} not found}"; + script_not_loaded = "{infomessage Script {hilight $0} is not loaded}"; + script_loaded = "{infomessage Loaded script {hilight $0}}"; + script_unloaded = "{acknowledgedmessage Unloaded script {hilight $0}}"; + no_scripts_loaded = "{infomessage No scripts are loaded}"; + }; +}; diff --git a/.local/share/irssi/scripts/autorun/hilightwin.pl b/.local/share/irssi/scripts/autorun/hilightwin.pl new file mode 100644 index 0000000..5f49f81 --- /dev/null +++ b/.local/share/irssi/scripts/autorun/hilightwin.pl @@ -0,0 +1,85 @@ +# +# Print hilighted messages & private messages to window named "hilight" for +# irssi 0.7.99 by Timo Sirainen +# +# Modded a tiny bit by znx to stop private messages entering the hilighted +# window (can be toggled) and to put up a timestamp. +# +# Changed a little by rummik to optionally show network name. Enable with +# `/set hilightwin_show_network on` +# + +use strict; +use Irssi; +use POSIX; +use vars qw($VERSION %IRSSI); + +$VERSION = "1.00"; +%IRSSI = ( + authors => "Timo \'cras\' Sirainen, Mark \'znx\' Sangster, Kimberly \'rummik\' Zick", + contact => "tss\@iki.fi, znxster\@gmail.com, git\@zick.kim", + name => "hilightwin", + description => "Print hilighted messages to window named \"hilight\"", + license => "Public Domain", + url => "http://irssi.org/", + changed => "Thu Apr 6 15:30:25 EDT 2017" +); + +sub is_ignored { + my ($dest) = @_; + + my @ignore = split(' ', Irssi::settings_get_str('hilightwin_ignore_targets')); + return 0 if (!@ignore); + + my %targets = map { $_ => 1 } @ignore; + + return 1 if exists($targets{"*"}); + return 1 if exists($targets{$dest->{target}}); + + if ($dest->{server}) { + my $tag = $dest->{server}->{tag}; + return 1 if exists($targets{$tag . "/*"}); + return 1 if exists($targets{$tag . "/" . $dest->{target}}); + } + + return 0; +} + +sub sig_printtext { + my ($dest, $text, $stripped) = @_; + + my $opt = MSGLEVEL_HILIGHT; + my $shownetwork = Irssi::settings_get_bool('hilightwin_show_network'); + + if(Irssi::settings_get_bool('hilightwin_showprivmsg')) { + $opt = MSGLEVEL_HILIGHT|MSGLEVEL_MSGS; + } + + if( + ($dest->{level} & ($opt)) && + ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0 && + (!is_ignored($dest)) + ) { + my $window = Irssi::window_find_name('hilight'); + + if ($dest->{level} & MSGLEVEL_PUBLIC) { + $text = $dest->{target}.": ".$text; + $text = $dest->{server}->{tag} . "/" . $text if ($shownetwork); + } elsif ($shownetwork) { + $text = $dest->{server}->{tag} . ": " . $text; + } + $text =~ s/%/%%/g; + $window->print($text, MSGLEVEL_CLIENTCRAP) if ($window); + } +} + +my $window = Irssi::window_find_name('hilight'); +Irssi::print("Create a window named 'hilight'") if (!$window); + +Irssi::settings_add_bool('hilightwin','hilightwin_showprivmsg',1); +Irssi::settings_add_str('hilightwin', 'hilightwin_ignore_targets', ''); +Irssi::settings_add_bool('hilightwin','hilightwin_show_network', 0); + +Irssi::signal_add('print text', 'sig_printtext'); + +# vim:set ts=4 sw=4 et: diff --git a/.local/share/irssi/scripts/autorun/splitlong.pl b/.local/share/irssi/scripts/autorun/splitlong.pl new file mode 100644 index 0000000..3c8a355 --- /dev/null +++ b/.local/share/irssi/scripts/autorun/splitlong.pl @@ -0,0 +1,60 @@ +# /set splitlong_max_length +# specifies the maximum length of a msg, automatically chosen when set to "0" +# default: 0 +# +# /set splitlong_line_start +# /set splitlong_line_end +# self-explanatory +# defaults: "... ", " ..." +### +use strict; +use vars qw($VERSION %IRSSI); + +use Irssi 20011001; + +$VERSION = "0.20"; +%IRSSI = ( + authors => "Bjoern \'fuchs\' Krombholz", + contact => "bjkro\@gmx.de", + name => "splitlong", + license => "Public Domain", + description => "Split overlong PRIVMSGs to msgs with length allowed by ircd", + changed => "Wed Jun 25 00:17:00 CET 2003", + changes => "Actually the real 0.19 (now 0.20), but upload didn't work some month ago, target problem fixed..." +); + +sub sig_command_msg { + my ($cmd, $server, $winitem) = @_; + my ( $param, $target,$data) = $cmd =~ /^(-\S*\s)?(\S*)\s(.*)/; + + my $maxlength = Irssi::settings_get_int('splitlong_max_length'); + my $lstart = Irssi::settings_get_str('splitlong_line_start'); + my $lend = Irssi::settings_get_str('splitlong_line_end'); + + if ($maxlength == 0) { + # 497 = 510 - length(":" . "!" . " PRIVMSG " . " :"); + $maxlength = 497 - length($server->{nick} . $server->{userhost} . $target); + } + my $maxlength2 = $maxlength - length($lend); + + if (length($data) > ($maxlength)) { + my @spltarr; + + while (length($data) > ($maxlength2)) { + my $pos = rindex($data, " ", $maxlength2); + push @spltarr, substr($data, 0, ($pos < ($maxlength/10 + 4)) ? $maxlength2 : $pos) . $lend; + $data = $lstart . substr($data, ($pos < ($maxlength/10 + 4)) ? $maxlength2 : $pos+1); + } + + push @spltarr, $data; + foreach (@spltarr) { + Irssi::signal_emit("command msg", "$target $_", $server, $winitem); + } + Irssi::signal_stop(); + } +} + +Irssi::settings_add_int('misc', 'splitlong_max_length', 0); +Irssi::settings_add_str('misc', 'splitlong_line_start', "... "); +Irssi::settings_add_str('misc', 'splitlong_line_end', " ..."); +Irssi::command_bind('msg', 'sig_command_msg'); diff --git a/.local/share/irssi/scripts/autorun/tmux-nicklist-portable.pl b/.local/share/irssi/scripts/autorun/tmux-nicklist-portable.pl new file mode 100644 index 0000000..e0c6920 --- /dev/null +++ b/.local/share/irssi/scripts/autorun/tmux-nicklist-portable.pl @@ -0,0 +1,432 @@ +# based on the nicklist.pl script +################################################################################ +# tmux_nicklist.pl +# This script integrates tmux and irssi to display a list of nicks in a +# vertical right pane with 20% width. Right now theres no configuration +# or setup, simply initialize the script with irssi and by default you +# will get the nicklist for every channel(customize by altering +# the regex in /set nicklist_channel_re) +# +# /set nicklist_channel_re +# * only show on channels matching this regular expression +# +# /set nicklist_max_users +# * only show when the channel has so many users or less (0 = always) +# +# /set nicklist_smallest_main +# * only show when main window is larger than this (0 = always) +# +# /set nicklist_pane_width +# * width of the nicklist pane +# +# /set nicklist_color +# * colourise the nicks in the nicklist (required nickcolor script +# with get_nick_color2 and debug_ansicolour functions) +# +# /set nicklist_gone_sort +# * sort away people below +# +# It supports mouse scrolling and the following keys: +# k/up arrow: up one line +# j/down arrow: down one line +# u/pageup: up 50% lines +# d/pagedown: down 50% lines +# gg: go to top +# G: go to bottom +# +# For better integration, unrecognized sequences will be sent to irssi and +# its pane will be focused. +# +# to toggle the nicklist if it is in the way you can make a key binding: +# /bind meta-Z /script exec Irssi::Script::tmux_nicklist_portable::toggle_nicklist +################################################################################ + +use strict; +use warnings; +use IO::Handle; +use IO::Select; +use POSIX; +use File::Temp qw/ :mktemp /; +use File::Basename; +our $VERSION = '0.1.8'; +our %IRSSI = ( + authors => 'Thiago de Arruda', + contact => 'tpadilha84@gmail.com', + name => 'tmux-nicklist', + description => 'displays a list of nicks in a separate tmux pane', + license => 'WTFPL', +); + +# "other" prefixes by danielg4 +# added 'd' and 'u' navigation as in vim, by @gerardbm (github) + +{ package Irssi::Nick } + +if ($#ARGV == -1) { +require Irssi; + +my $enabled = 0; +my $nicklist_toggle = 1; +my $script_path = __FILE__; +my $tmpdir; +my $fifo_path; +my $fifo; +my $just_launched; +my $resize_timer; + +sub enable_nicklist { + return if ($enabled); + $tmpdir = mkdtemp Irssi::get_irssi_dir()."/nicklist-XXXXXXXX"; + $fifo_path = "$tmpdir/fifo"; + POSIX::mkfifo($fifo_path, 0600) or die "can't mkfifo $fifo_path: $!"; + my $cmd = "perl $script_path $fifo_path $ENV{TMUX_PANE}"; + my $width = Irssi::settings_get_int('nicklist_pane_width'); + system('tmux', 'split-window', '-dh', '-l', $width, '-t', $ENV{TMUX_PANE}, $cmd); + open_fifo(); + Irssi::timeout_remove($just_launched) if defined $just_launched; + $just_launched = Irssi::timeout_add_once(300, sub { $just_launched = undef; }, ''); +} + +sub open_fifo { + # The next system call will block until the other pane has opened the pipe + # for reading, so synchronization is not an issue here. + open $fifo, ">", $fifo_path or do { + if ($! == 4) { + Irssi::timeout_add_once(300, \&open_fifo, ''); + $enabled = -1 unless $enabled; + return; + } + die "can't open $fifo_path: $!"; + }; + $fifo->autoflush(1); + if ($enabled < -1) { + $enabled = 1; + disable_nicklist(); + } elsif ($enabled == -1) { + $enabled = 1; + reset_nicklist("enabled"); + } else { + $enabled = 1; + } +} + +sub disable_nicklist { + return unless ($enabled); + if ($enabled > 0) { + print $fifo "EXIT\n"; + close $fifo; + $fifo = undef; + unlink $fifo_path; + rmdir $tmpdir; + } + $enabled--; +} + +sub reset_nicklist { + my $event = shift; + my $active = Irssi::active_win(); + my $channel = $active->{active}; + return disable_nicklist unless $channel && ref $channel; + if ($event =~ /^nick/) { + # check if that nick event is for the current channel/nicklist + my ($event_channel) = @_; + return unless $channel->{_irssi} == $event_channel->{_irssi}; + } + my ($colourer, $ansifier); + if (Irssi::settings_get_bool('nicklist_color')) { + for my $script (sort map { my $z = $_; $z =~ s/::$//; $z } grep { /^nickcolor|nm/ } keys %Irssi::Script::) { + if ($colourer = "Irssi::Script::$script"->can('get_nick_color2')) { + $ansifier = "Irssi::Script::$script"->can('debug_ansicolour'); + last; + } + } + } + my $channel_pattern = Irssi::settings_get_str('nicklist_channel_re'); + { local $@; + $channel_pattern = eval { qr/$channel_pattern/ }; + $channel_pattern = qr/(?!)/ if $@; + } + my $smallest_main = Irssi::settings_get_int('nicklist_smallest_main'); + if (!$nicklist_toggle + || !$channel || !ref($channel) + || !$channel->isa('Irssi::Channel') + || !$channel->{'names_got'} + || $channel->{'name'} !~ $channel_pattern + || ($smallest_main && $channel->window->{width} < $smallest_main)) { + disable_nicklist; + } else { + my %colour; + my @nicks = $channel->nicks(); + my $max_nicks = Irssi::settings_get_int('nicklist_max_users'); + if ($max_nicks && @nicks > $max_nicks) { + disable_nicklist; + } else { + enable_nicklist; + return unless $enabled > 0; + foreach my $nick (sort { $a->{_irssi} <=> $b->{_irssi} } @nicks) { + $colour{$nick->{nick}} = ($ansifier && $colourer) ? $ansifier->($colourer->($active->{active}{server}{tag}, $channel->{name}, $nick->{nick}, 0)) : ''; + } + print($fifo "BEGIN\n"); + my $gone_sort = Irssi::settings_get_bool('nicklist_gone_sort'); + my $prefer_real; + if (exists $Irssi::Script::{'realnames::'}) { + my $code = "Irssi::Script::realnames"->can('use_realnames'); + $prefer_real = $code && $code->($channel); + } + my $_real = sub { + my $nick = shift; + $prefer_real && length $nick->{'realname'} ? $nick->{'realname'} : $nick->{'nick'} + }; + foreach my $nick (sort {($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':$a->{'other'}>32?'0':'4').($gone_sort?($a->{'gone'}?1:0):'').lc($_real->($a)) + cmp ($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':$b->{'other'}>32?'0':'4').($gone_sort?($b->{'gone'}?1:0):'').lc($_real->($b))} @nicks) { + my $colour = $colour{$nick->{nick}} || "\e[39m"; + $colour = "\e[37m" if $nick->{'gone'}; + print($fifo "NICK"); + if ($nick->{'op'}) { + print($fifo "\e[32m\@$colour".$_real->($nick)."\e[39m"); + } elsif ($nick->{'halfop'}) { + print($fifo "\e[34m%$colour".$_real->($nick)."\e[39m"); + } elsif ($nick->{'voice'}) { + print($fifo "\e[33m+$colour".$_real->($nick)."\e[39m"); + } elsif ($nick->{'other'}>32) { + print($fifo "\e[31m".(chr $nick->{'other'})."$colour".$_real->($nick)."\e[39m"); + } else { + print($fifo " $colour".$_real->($nick)."\e[39m"); + } + print($fifo "\n"); + } + print($fifo "END\n"); + } + } +} + +sub toggle_nicklist { + if ($enabled) { + $nicklist_toggle = undef + } else { + $nicklist_toggle = 1; + } + reset_nicklist("toggle"); +} + +sub switch_channel { + print $fifo "SWITCH_CHANNEL\n" if $fifo; + &reset_nicklist; +} + +sub resized_timed { + Irssi::timeout_remove($resize_timer) if defined $resize_timer; + return if defined $just_launched; + $resize_timer = Irssi::timeout_add_once(1100, \&resized, ''); + #resized(); +} +sub resized { + $resize_timer = undef; + return if defined $just_launched; + return unless $enabled >= 0; + disable_nicklist; + Irssi::timeout_add_once(200, sub{reset_nicklist("terminal resized")}, ''); +} +sub UNLOAD { + disable_nicklist; +} + +Irssi::settings_add_str('tmux_nicklist', 'nicklist_channel_re', '.*'); +Irssi::settings_add_int('tmux_nicklist', 'nicklist_max_users', 0); +Irssi::settings_add_int('tmux_nicklist', 'nicklist_smallest_main', 0); +Irssi::settings_add_int('tmux_nicklist', 'nicklist_pane_width', 13); +Irssi::settings_add_bool('tmux_nicklist', 'nicklist_color', 1); +Irssi::settings_add_bool('tmux_nicklist', 'nicklist_gone_sort', 0); +Irssi::signal_add_last('window item changed', sub{switch_channel("window item changed",@_)}); +Irssi::signal_add_last('window changed', sub{switch_channel("window changed",@_)}); +Irssi::signal_add_last('channel joined', sub{switch_channel("channel joined",@_)}); +Irssi::signal_add('nicklist new', sub{reset_nicklist("nicklist new",@_)}); +Irssi::signal_add('nicklist remove', sub{reset_nicklist("nicklist remove",@_)}); +Irssi::signal_add('nicklist changed', sub{reset_nicklist("nicklist changed",@_)}); +Irssi::signal_add_first('nick mode changed', sub{reset_nicklist("nick mode changed",@_)}); +Irssi::signal_add('gui exit', \&disable_nicklist); +Irssi::signal_add_last('terminal resized', \&resized_timed); + +} else { +my $fifo_path = $ARGV[0]; +my $irssi_pane = $ARGV[1]; +# array to store the current channel nicknames +my @nicknames = (); + +# helper functions for manipulating the terminal +# escape sequences taken from +# http://www.tldp.org/HOWTO/Bash-Prompt-HOWTO/x361.html +sub enable_mouse { print "\e[?1000h"; } +# recognized sequences +my $MOUSE_SCROLL_DOWN="\e[Ma"; +my $MOUSE_SCROLL_UP="\e[M`"; +my $ARROW_DOWN="\e[B"; +my $ARROW_UP="\e[A"; +my $DOWN="j"; +my $UP="k"; +my $PAGE_DOWN="\e[6~"; +my $PAGE_UP="\e[5~"; +my $PAGE_DOWN_D="d"; +my $PAGE_UP_U="u"; +my $GO_TOP="gg"; +my $GO_BOTTOM="G"; + +my $current_line = 0; +my $sequence = ''; +my ($rows, $cols); + +sub term_size { + split ' ', `stty size`; +} + +sub redraw { + my $last_nick_idx = @nicknames; + my $last_idx = $current_line + $rows; + # normalize last visible index + if ($last_idx > ($last_nick_idx)) { + $last_idx = $last_nick_idx; + } + # redraw visible nicks + for my $i (reverse 1..$rows) { + print "\e[$i;1H\e[K"; + my $idx = $current_line + $i - 1; + if ($idx < $last_idx) { + my $z = 0; my $col = $cols; + for (split /(\e\[(?:\d|;|:|\?|\s)*.)/, $nicknames[$idx]) { + if ($z ^= 1) { + print +(substr $_, 0, $col) if $col > 0; + $col -= length; + } else { + print + } + } + } + } +} + +sub move_down { + $sequence = ''; + my $count = int $_[0]; + my $nickcount = $#nicknames; + return if ($nickcount <= $rows); + if ($count == -1) { + $current_line = $nickcount - $rows + 1; + redraw; + return; + } + my $visible = $nickcount - $current_line - $count + 1; + if ($visible > $rows) { + $current_line += $count; + redraw; + } elsif (($visible + $count) > $rows) { + # scroll the maximum we can + $current_line = $nickcount - $rows + 1; + redraw; + } +} + +sub move_up { + $sequence = ''; + my $count = int $_[0]; + if ($count == -1) { + $current_line = 0; + redraw; + return; + } + return if ($current_line == 0); + $count = 1 if $count == 0; + $current_line -= $count; + $current_line = 0 if $current_line < 0; + redraw; +} + +$SIG{INT} = 'IGNORE'; + +STDOUT->autoflush(1); +# setup terminal so we can listen for individual key presses without echo +`stty -icanon -echo`; + +# open named pipe and setup the 'select' wrapper object for listening on both +# fds(fifo and sdtin) +open my $fifo, "<", $fifo_path or die "can't open $fifo_path: $!"; +my $select = IO::Select->new(); +my @ready; +$select->add($fifo); +$select->add(\*STDIN); + +enable_mouse; +system('tput', 'smcup'); +print "\e[?7l"; #system('tput', 'rmam'); +system('tput', 'civis'); +MAIN: { + while (@ready = $select->can_read) { + foreach my $fd (@ready) { + ($rows, $cols) = term_size; + if ($fd == $fifo) { + while (<$fifo>) { + my $line = $_; + if ($line =~ /^BEGIN/) { + @nicknames = (); + } elsif ($line =~ /^SWITCH_CHANNEL/) { + $current_line = 0; + } elsif ($line =~ /^NICK(.+)$/) { + push @nicknames, $1; + } elsif ($line =~ /^END$/) { + redraw; + last; + } elsif ($line =~ /^EXIT$/) { + last MAIN; + } + } + } else { + my $key = ''; + sysread(STDIN, $key, 1); + $sequence .= $key; + if ($MOUSE_SCROLL_DOWN =~ /^\Q$sequence\E/) { + if ($MOUSE_SCROLL_DOWN eq $sequence) { + move_down 3; + # mouse scroll has two more bytes that I dont use here + # so consume them now to avoid sending unwanted bytes to + # irssi + sysread(STDIN, $key, 2); + } + } elsif ($MOUSE_SCROLL_UP =~ /^\Q$sequence\E/) { + if ($MOUSE_SCROLL_UP eq $sequence) { + move_up 3; + sysread(STDIN, $key, 2); + } + } elsif ($ARROW_DOWN =~ /^\Q$sequence\E/) { + move_down 1 if ($ARROW_DOWN eq $sequence); + } elsif ($ARROW_UP =~ /^\Q$sequence\E/) { + move_up 1 if ($ARROW_UP eq $sequence); + } elsif ($DOWN =~ /^\Q$sequence\E/) { + move_down 1 if ($DOWN eq $sequence); + } elsif ($UP =~ /^\Q$sequence\E/) { + move_up 1 if ($UP eq $sequence); + } elsif ($PAGE_DOWN =~ /^\Q$sequence\E/) { + move_down $rows/2 if ($PAGE_DOWN eq $sequence); + } elsif ($PAGE_UP =~ /^\Q$sequence\E/) { + move_up $rows/2 if ($PAGE_UP eq $sequence); + } elsif ($PAGE_DOWN_D =~ /^\Q$sequence\E/) { + move_down $rows/2 if ($PAGE_DOWN_D eq $sequence); + } elsif ($PAGE_UP_U =~ /^\Q$sequence\E/) { + move_up $rows/2 if ($PAGE_UP_U eq $sequence); + } elsif ($GO_BOTTOM =~ /^\Q$sequence\E/) { + move_down -1 if ($GO_BOTTOM eq $sequence); + } elsif ($GO_TOP =~ /^\Q$sequence\E/) { + move_up -1 if ($GO_TOP eq $sequence); + } else { + # Unrecognized sequences will be send to irssi and its pane + # will be focused + system('tmux', 'send-keys', '-t', $irssi_pane, $sequence); + system('tmux', 'select-pane', '-t', $irssi_pane); + $sequence = ''; + } + } + } + } +} + +close $fifo; + +}