0
0

init.lua 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
  1. local get_buf_dimensions = function(bufNumber)
  2. local windows = vim.api.nvim_list_wins()
  3. local height = 25
  4. local width = 80
  5. for _, window in pairs(windows) do
  6. if vim.api.nvim_win_get_buf(window) == bufNumber then
  7. height = vim.api.nvim_win_get_height(window)
  8. width = vim.api.nvim_win_get_width(window)
  9. end
  10. end
  11. return { width, height }
  12. end
  13. local get_column_width = function()
  14. return vim.opt.numberwidth:get() + 1 + 1
  15. end
  16. local main_display = {
  17. lines = { "Welcome to a new instance of", "the hyperextensible Vim-based text editor" },
  18. letters = {
  19. n = [[
  20. ███▄▄▄▄
  21. ███▀▀▀██▄
  22. ███ ███
  23. ███ ███
  24. ███ ███▀
  25. ███ ███
  26. ███ ███
  27. ▀█ █▀
  28. ]],
  29. e = [[
  30. ▄████████
  31. ███ ███
  32. ███ █▀
  33. ▄███▄▄▄
  34. ▀███▀▀▀
  35. ███ █▄
  36. ███ ███
  37. ██████████
  38. ]],
  39. o = [[
  40. ▄██████▄
  41. ███ ███
  42. ███ ███
  43. ███ ███
  44. ███ ███
  45. ███ ███
  46. ███ ███
  47. ▀██████▀
  48. ]],
  49. v = [[
  50. ▄█ █▄
  51. ███ ███
  52. ███ ███
  53. ███ ███
  54. ███ ███
  55. ███ ███
  56. ███ ███
  57. ▀██████▀
  58. ]],
  59. i = [[
  60. ▄█
  61. ███
  62. ███▌
  63. ███▌
  64. ███▌
  65. ███
  66. ███
  67. █▀
  68. ]],
  69. m = [[
  70. ▄▄▄▄███▄▄▄▄
  71. ▄██▀▀▀███▀▀▀██▄
  72. ███ ███ ███
  73. ███ ███ ███
  74. ███ ███ ███
  75. ███ ███ ███
  76. ███ ███ ███
  77. ▀█ ███ █▀
  78. ]]
  79. }
  80. }
  81. local first_display = function(bufNumber)
  82. local dimensions = get_buf_dimensions(bufNumber)
  83. local column_width = get_column_width()
  84. local virt_lines = {}
  85. local total_width = 0
  86. local total_lines = 0
  87. local get_letter_width = function(letter)
  88. local max_width = 0
  89. for _, line in pairs(vim.split(letter, "\n")) do
  90. max_width = math.max(max_width, vim.fn.strdisplaywidth(line))
  91. end
  92. return max_width
  93. end
  94. for _, letter in pairs(main_display.letters) do
  95. local max_width = get_letter_width(letter)
  96. local max_lines = #vim.split(letter, "\n")
  97. total_width = total_width + max_width
  98. total_lines = math.max(max_lines, total_lines)
  99. end
  100. total_lines = total_lines + 4
  101. while #virt_lines < (dimensions[2] / 2) - (total_lines / 2) do
  102. table.insert(virt_lines, {})
  103. end
  104. local left_padding = ""
  105. while left_padding:len() + column_width < (dimensions[1] / 2) - (total_width / 2) do
  106. left_padding = left_padding .. " "
  107. end
  108. table.insert(virt_lines,
  109. { { left_padding, "" }, { main_display.lines[1], "JxDashTextItalic" } })
  110. table.insert(virt_lines, {})
  111. local highlights = {
  112. "JxDashRed",
  113. "JxDashOrange",
  114. "JxDashGrey",
  115. "JxDashBurgundy",
  116. "JxDashYellow",
  117. "JxDashBlue",
  118. }
  119. local letters = {}
  120. math.randomseed(os.time())
  121. 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
  122. local letter_width = get_letter_width(letter)
  123. local letter_lines = {}
  124. for _, line in pairs(vim.split(letter, '\n')) do
  125. while vim.fn.strdisplaywidth(line) < letter_width do
  126. line = line .. ' '
  127. end
  128. table.insert(letter_lines, line)
  129. end
  130. table.insert(letters,
  131. { letter_lines, highlights[math.random(#highlights)] })
  132. end
  133. local line_count = 1
  134. while line_count < total_lines - 4 do
  135. table.insert(virt_lines, { { left_padding, "" }, })
  136. for _, letter in pairs(letters) do
  137. for index, line in pairs(letter[1]) do
  138. if index == line_count then
  139. table.insert(virt_lines[#virt_lines], { line, letter[2], })
  140. end
  141. end
  142. end
  143. line_count = line_count + 1
  144. end
  145. table.insert(virt_lines, {})
  146. local last_line = main_display.lines[2]
  147. while last_line:len() < total_width do
  148. last_line = " " .. last_line
  149. end
  150. table.insert(virt_lines,
  151. { { left_padding, "" }, { last_line, "JxDashTextItalic" } })
  152. return virt_lines
  153. end
  154. local second_display = function(_)
  155. local virt_lines = {}
  156. local content = vim.fn.split(io.popen(
  157. '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)')
  158. :read(
  159. "a*"), '\n')
  160. local match_lines = {}
  161. for index, line in pairs(content) do
  162. if line:match('^[ -]+-[ -]+$') then
  163. table.insert(match_lines, index)
  164. end
  165. end
  166. return virt_lines
  167. end
  168. return {
  169. setup = function()
  170. local namespace = vim.api.nvim_create_namespace('jxdash')
  171. local group = vim.api.nvim_create_augroup('JxDashStartup',
  172. { clear = true })
  173. local candidate = function()
  174. return vim.api.nvim_buf_get_name(0) == ''
  175. and vim.g.read_from_stdin == nil
  176. and vim.api.nvim_get_mode().mode == 'n'
  177. and vim.bo.filetype == ""
  178. end
  179. local erase = function(bufNumber)
  180. for _, mark in pairs(vim.api.nvim_buf_get_extmarks(bufNumber, namespace, 0, -1, {})) do
  181. vim.api.nvim_buf_del_extmark(bufNumber,
  182. namespace,
  183. mark[1])
  184. end
  185. end
  186. local draw = function(buffer, display)
  187. if candidate() ~= true then
  188. return {}
  189. end
  190. if vim.b.jxdash then
  191. erase(buffer)
  192. end
  193. local id = vim.api.nvim_buf_set_extmark(buffer, namespace, 0, 0,
  194. { strict = false, virt_text_pos = "overlay", virt_lines = display })
  195. vim.b.jxdash = true
  196. return id
  197. end
  198. local assignKillCallback = function(bufNumber)
  199. vim.api.nvim_create_autocmd(
  200. { "BufHidden" },
  201. {
  202. once = true,
  203. group = group,
  204. buffer = bufNumber,
  205. callback = function(args)
  206. if (vim.b.jxdash) then
  207. vim.schedule(function()
  208. vim.api.nvim_buf_delete(args.buf,
  209. { force = false })
  210. end)
  211. end
  212. end
  213. })
  214. end
  215. local assignExitCallback = function(bufNumber)
  216. vim.api.nvim_create_autocmd(
  217. { "TextChanged", "TextChangedI", "TextChangedP", "TextChangedT" },
  218. {
  219. once = true,
  220. group = group,
  221. buffer = bufNumber,
  222. callback = function(args)
  223. vim.b.jxdash = false
  224. erase(args.buf)
  225. end
  226. })
  227. end
  228. local assignRedrawCallback = function(bufNumber)
  229. vim.api.nvim_create_autocmd(
  230. { "WinResized", "BufEnter" },
  231. {
  232. group = group,
  233. callback = function(_)
  234. local bufferDetails = vim.fn.getbufinfo(bufNumber)[1]
  235. if (bufferDetails == nil or vim.b.jxdash == nil) then
  236. return
  237. end
  238. if (bufferDetails.hidden ~= 1) then
  239. draw(bufNumber, first_display(bufNumber))
  240. end
  241. end
  242. })
  243. end
  244. vim.api.nvim_create_autocmd({ 'UIEnter', }, {
  245. group = group,
  246. once = true,
  247. callback = function(args)
  248. -- Insert a space and undo it to erase previous contents without
  249. -- marking buffer as modified
  250. vim.api.nvim_feedkeys(
  251. vim.api.nvim_replace_termcodes("i <Esc>u", true,
  252. false,
  253. true), "n", false)
  254. draw(args.buf, first_display(args.buf))
  255. vim.schedule(function()
  256. vim.api.nvim_create_autocmd({ 'BufAdd' },
  257. {
  258. group = group,
  259. callback = function(subArgs)
  260. draw(subArgs.buf,
  261. second_display())
  262. vim.schedule(function()
  263. assignExitCallback(subArgs.buf)
  264. end)
  265. end
  266. })
  267. end)
  268. vim.schedule(function()
  269. assignExitCallback(args.buf)
  270. assignKillCallback(args.buf)
  271. assignRedrawCallback(args.buf)
  272. end)
  273. end
  274. })
  275. end
  276. }