local get_buf_dimensions = function(bufNumber) local windows = vim.api.nvim_list_wins() local height = 25 local width = 80 for _, window in pairs(windows) do if vim.api.nvim_win_get_buf(window) == bufNumber then height = vim.api.nvim_win_get_height(window) width = vim.api.nvim_win_get_width(window) end end return { width, height } end local get_column_width = function() return vim.opt.numberwidth:get() + 1 + 1 end local main_display = { lines = { "Welcome to a new instance of", "the hyperextensible Vim-based text editor" }, letters = { n = [[ ███▄▄▄▄ ███▀▀▀██▄ ███ ███ ███ ███ ███ ███▀ ███ ███ ███ ███ ▀█ █▀ ]], e = [[ ▄████████ ███ ███ ███ █▀ ▄███▄▄▄ ▀███▀▀▀ ███ █▄ ███ ███ ██████████ ]], o = [[ ▄██████▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ▀██████▀ ]], v = [[ ▄█ █▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ▀██████▀ ]], i = [[ ▄█ ███ ███▌ ███▌ ███▌ ███ ███ █▀ ]], m = [[ ▄▄▄▄███▄▄▄▄ ▄██▀▀▀███▀▀▀██▄ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ███ ▀█ ███ █▀ ]] } } local first_display = function(bufNumber) local dimensions = get_buf_dimensions(bufNumber) local column_width = get_column_width() local virt_lines = {} local total_width = 0 local total_lines = 0 local get_letter_width = function(letter) local max_width = 0 for _, line in pairs(vim.split(letter, "\n")) do max_width = math.max(max_width, vim.fn.strdisplaywidth(line)) end return max_width end for _, letter in pairs(main_display.letters) do local max_width = get_letter_width(letter) local max_lines = #vim.split(letter, "\n") total_width = total_width + max_width total_lines = math.max(max_lines, total_lines) end total_lines = total_lines + 4 while #virt_lines < (dimensions[2] / 2) - (total_lines / 2) do table.insert(virt_lines, {}) end local left_padding = "" while left_padding:len() + column_width < (dimensions[1] / 2) - (total_width / 2) do left_padding = left_padding .. " " end table.insert(virt_lines, { { left_padding, "" }, { main_display.lines[1], "JxDashTextItalic" } }) table.insert(virt_lines, {}) local highlights = { "JxDashRed", "JxDashOrange", "JxDashGrey", "JxDashBurgundy", "JxDashYellow", "JxDashBlue", } local letters = {} math.randomseed(os.time()) for _, letter in pairs({ main_display.letters.n, main_display.letters.e, main_display.letters.o, main_display.letters.v, main_display.letters.i, main_display.letters.m, }) do local letter_width = get_letter_width(letter) local letter_lines = {} for _, line in pairs(vim.split(letter, '\n')) do while vim.fn.strdisplaywidth(line) < letter_width do line = line .. ' ' end table.insert(letter_lines, line) end table.insert(letters, { letter_lines, highlights[math.random(#highlights)] }) end local line_count = 1 while line_count < total_lines - 4 do table.insert(virt_lines, { { left_padding, "" }, }) for _, letter in pairs(letters) do for index, line in pairs(letter[1]) do if index == line_count then table.insert(virt_lines[#virt_lines], { line, letter[2], }) end end end line_count = line_count + 1 end table.insert(virt_lines, {}) local last_line = main_display.lines[2] while last_line:len() < total_width do last_line = " " .. last_line end table.insert(virt_lines, { { left_padding, "" }, { last_line, "JxDashTextItalic" } }) return virt_lines end local second_display = function(_) local virt_lines = {} local content = vim.fn.split(io.popen( 'fortune | cowsay -W 60 -f $(echo default bud-frogs bunny cower elephant flaming-sheep koala moofasa moose satanic sheep skeleton small three-eyes tux udder vader | paste -sd " " - | tr " " "\n" | shuf | head -n1)') :read( "a*"), '\n') local match_lines = {} for index, line in pairs(content) do if line:match('^[ -]+-[ -]+$') then table.insert(match_lines, index) end end return virt_lines end return { setup = function() local namespace = vim.api.nvim_create_namespace('jxdash') local group = vim.api.nvim_create_augroup('JxDashStartup', { clear = true }) local candidate = function() return vim.api.nvim_buf_get_name(0) == '' and vim.g.read_from_stdin == nil and vim.api.nvim_get_mode().mode == 'n' and vim.bo.filetype == "" end local erase = function(bufNumber) for _, mark in pairs(vim.api.nvim_buf_get_extmarks(bufNumber, namespace, 0, -1, {})) do vim.api.nvim_buf_del_extmark(bufNumber, namespace, mark[1]) end end local draw = function(buffer, display) if candidate() ~= true then return {} end if vim.b.jxdash then erase(buffer) end local id = vim.api.nvim_buf_set_extmark(buffer, namespace, 0, 0, { strict = false, virt_text_pos = "overlay", virt_lines = display }) vim.b.jxdash = true return id end local assignKillCallback = function(bufNumber) vim.api.nvim_create_autocmd( { "BufHidden" }, { once = true, group = group, buffer = bufNumber, callback = function(args) if (vim.b.jxdash) then vim.schedule(function() vim.api.nvim_buf_delete(args.buf, { force = false }) end) end end }) end local assignExitCallback = function(bufNumber) vim.api.nvim_create_autocmd( { "TextChanged", "TextChangedI", "TextChangedP", "TextChangedT" }, { once = true, group = group, buffer = bufNumber, callback = function(args) vim.b.jxdash = false erase(args.buf) end }) end local assignRedrawCallback = function(bufNumber) vim.api.nvim_create_autocmd( { "WinResized", "BufEnter" }, { group = group, callback = function(_) local bufferDetails = vim.fn.getbufinfo(bufNumber)[1] if (bufferDetails == nil or vim.b.jxdash == nil) then return end if (bufferDetails.hidden ~= 1) then draw(bufNumber, first_display(bufNumber)) end end }) end vim.api.nvim_create_autocmd({ 'UIEnter', }, { group = group, once = true, callback = function(args) -- Insert a space and undo it to erase previous contents without -- marking buffer as modified vim.api.nvim_feedkeys( vim.api.nvim_replace_termcodes("i u", true, false, true), "n", false) draw(args.buf, first_display(args.buf)) vim.schedule(function() vim.api.nvim_create_autocmd({ 'BufAdd' }, { group = group, callback = function(subArgs) draw(subArgs.buf, second_display()) vim.schedule(function() assignExitCallback(subArgs.buf) end) end }) end) vim.schedule(function() assignExitCallback(args.buf) assignKillCallback(args.buf) assignRedrawCallback(args.buf) end) end }) end }