summaryrefslogtreecommitdiff
path: root/nix_archive/files
diff options
context:
space:
mode:
Diffstat (limited to 'nix_archive/files')
-rw-r--r--nix_archive/files/nvim/fzf_no_linenum.diff24
-rw-r--r--nix_archive/files/nvim/init.vim368
-rw-r--r--nix_archive/files/nvim/local/autoload/Juliana.vim46
-rw-r--r--nix_archive/files/nvim/mini_completion_no_title.diff0
-rw-r--r--nix_archive/files/nvim/mini_starter_picture.diff288
5 files changed, 726 insertions, 0 deletions
diff --git a/nix_archive/files/nvim/fzf_no_linenum.diff b/nix_archive/files/nvim/fzf_no_linenum.diff
new file mode 100644
index 0000000..bed26be
--- /dev/null
+++ b/nix_archive/files/nvim/fzf_no_linenum.diff
@@ -0,0 +1,24 @@
+diff --git a/autoload/fzf/vim.vim b/autoload/fzf/vim.vim
+index 67945c3..ccfe729 100755
+--- a/autoload/fzf/vim.vim
++++ b/autoload/fzf/vim.vim
+@@ -789,7 +789,7 @@ endfunction
+
+ function! fzf#vim#_format_buffer(b)
+ let name = bufname(a:b)
+- let line = exists('*getbufinfo') ? getbufinfo(a:b)[0]['lnum'] : 0
++ "let line = exists('*getbufinfo') ? getbufinfo(a:b)[0]['lnum'] : 0
+ let fullname = empty(name) ? '' : fnamemodify(name, ":p:~:.")
+ let dispname = empty(name) ? '[No Name]' : name
+ let flag = a:b == bufnr('') ? s:blue('%', 'Conditional') :
+@@ -797,8 +797,8 @@ function! fzf#vim#_format_buffer(b)
+ let modified = getbufvar(a:b, '&modified') ? s:red(' [+]', 'Exception') : ''
+ let readonly = getbufvar(a:b, '&modifiable') ? '' : s:green(' [RO]', 'Constant')
+ let extra = join(filter([modified, readonly], '!empty(v:val)'), '')
+- let target = empty(name) ? '' : (line == 0 ? fullname : fullname.':'.line)
+- return s:rstrip(printf("%s\t%d\t[%s] %s\t%s\t%s", target, line, s:yellow(a:b, 'Number'), flag, dispname, extra))
++ let target = empty(name) ? '' : (fullname)
++ return s:rstrip(printf("%s\t[%s] %s\t%s\t%s", target, s:yellow(a:b, 'Number'), flag, dispname, extra))
+ endfunction
+
+ function! s:sort_buffers(...)
diff --git a/nix_archive/files/nvim/init.vim b/nix_archive/files/nvim/init.vim
new file mode 100644
index 0000000..7a1d5bc
--- /dev/null
+++ b/nix_archive/files/nvim/init.vim
@@ -0,0 +1,368 @@
+" Basic settings.
+set number
+set noshowmode
+set signcolumn=yes
+set updatetime=250
+set scrolloff=5
+
+" Change directory based on current file.
+if !empty($NIX_SHELL)
+ " Attempt to conflict less with plugins.
+ autocmd BufEnter * if gitbranch#name() != '' | silent! lcd %:p:h
+else
+ set autochdir
+endif
+
+" inotify compat?
+set backupcopy=yes
+
+" Old defaults (I think).
+set splitright
+set splitbelow
+
+" Syntax and indent from filetype.
+set nocompatible
+filetype plugin indent on
+syntax on
+
+" Check for SHIFT_JIS.
+set fileencodings=ucs-bom,utf-8,sjis,default,latin1
+
+" 4 spaces autoindent.
+set tabstop=4
+set shiftwidth=4
+set expandtab
+set autoindent
+
+" C syntax preference.
+let g:c_syntax_for_h=1
+let g:c_no_curly_error=1
+let g:c_function_pointers=1
+set cinoptions=:0,=4,l1,g2,h2,(4,u4,+4,m1,j1,J1
+set cindent
+
+" Set different format for mail and text files.
+set nowrap nolinebreak nolist formatoptions=l textwidth=0
+autocmd FileType mail,text setlocal wrap formatoptions=l textwidth=0
+
+" Ex tab complete that makes sense to me.
+set wildmode=longest,list,full
+set wildmenu
+
+" Allow distinguishing <C-i> from <Tab> in bindings.
+let &t_TI = '\<Esc>[>4;2m'
+let &t_TE = '\<Esc>[>4;m'
+" Treat shift + backspace as normal backspace.
+tnoremap <S-BS> <BS>
+
+" System clipboard on linux.
+set clipboard+=unnamedplus
+
+" Session options.
+set ssop=skiprtp,blank,buffers,folds,winsize,terminal
+set vop-=curdir
+if isdirectory(expand('~/c'))
+ let view_dir = expand('~/c/sessions/nvim/views')
+ if !isdirectory(view_dir)
+ call mkdir(view_dir, 'p', 0755)
+ endif
+ let &viewdir=view_dir
+
+ " Staggered backups.
+ let backup_dir = '/mnt/store/backup/vim'
+ if !isdirectory(backup_dir)
+ let backup_dir = expand('~/c/sessions/nvim/backup//')
+ if !isdirectory(backup_dir)
+ call mkdir(backup_dir, 'p', 0755)
+ endif
+ endif
+ let &backupdir=backup_dir
+ set backup
+
+ " Swap file directory.
+ let swap_dir = expand('~/c/sessions/nvim/swaps//')
+ if !isdirectory(swap_dir)
+ call mkdir(swap_dir, 'p', 0755)
+ endif
+ let &directory=swap_dir
+
+ if has('persistent_undo')
+ let undo_dir = expand('~/c/sessions/nvim/undo')
+ if !isdirectory(undo_dir)
+ call mkdir(undo_dir, 'p', 0755)
+ endif
+ let &undodir=undo_dir
+ set undofile
+ endif
+endif
+
+" Colorscheme.
+set termguicolors
+colo wal-gui
+
+" Cursor blink.
+"set guicursor=a:blinkon1
+
+" Highlight whitespace.
+au BufEnter * match ExtraWhitespace /\s\+$/
+au InsertEnter * match ExtraWhitespace /\s\+\%#\@<!$/
+au InsertLeave * match ExtraWhitespace /\s\+$/
+
+" Fzf format.
+let g:fzf_colors = {
+ \'fg': ['fg', 'Normal'],
+ \'bg': ['bg', 'Normal'],
+ \'hl': ['fg', 'Type'],
+ \'fg+': ['fg', 'CursorLine', 'CursorColumn', 'Normal'],
+ \'bg+': ['bg', 'CursorLine', 'CursorColumn'],
+ \'hl+': ['fg', 'Type'],
+ \'info': ['fg', 'PreProc'],
+ \'border': ['fg', 'Operator'],
+ \'prompt': ['fg', 'Identifier'],
+ \'pointer': ['fg', 'Type'],
+ \'marker': ['fg', 'Keyword'],
+ \'spinner': ['fg', 'String'],
+ \'header': ['fg', 'Type']
+\}
+let g:fzf_preview_window = ['right,55%']
+" This is redundant but I want to keep FZF_DEFAULT_OPTS here.
+let $FZF_DEFAULT_OPTS = '--preview-window=border-sharp'
+let g:fzf_layout = {
+ \'window': { 'width': 0.75, 'height': 0.60, 'rounded': 0 },
+\}
+
+function! StatuslineMode() abort
+ if mode() == nr2char(22)
+ return mode()
+ else
+ return '-'.mode()
+ endif
+endfunction
+
+function! StatuslineGit()
+ let l:branchname = gitbranch#name()
+ return strlen(l:branchname) > 0 ? ' '.l:branchname.' ' : ' '
+endfunction
+
+function! StatuslineLsp() abort
+ return luaeval('get_lsp_name()')
+endfunction
+
+" Custom statusline.
+function! Statusline() abort
+ let focused = g:statusline_winid == win_getid(winnr())
+ let status = focused ? '%#StatusLine#' : '%#StatusLineNC#'
+ let status .= '%{StatuslineGit()}'
+ let status .= ' %f'
+ let status .= ' vim@%{hostname()}'
+ let status .= '%='
+ let status .= ' %y'
+ let status .= '%{StatuslineLsp()}'
+ let status .= ' %{&fileencoding}'
+ let status .= '[%{&fileformat}]'
+ let status .= '%3p%%'
+ let status .= ' %3l:%-3c'
+ return status
+endfunction
+set statusline=%!Statusline()
+
+" Make shift + nav keys no-ops.
+nmap H <nop>
+nmap J <nop>
+nmap K <nop>
+nmap L <nop>
+" Normal mode tab no-op.
+nmap <Tab> <nop>
+" ctrl + c no-op.
+nmap <C-c> <nop>
+" Disable F1 for help.
+nmap <F1> <nop>
+" Disable q: for histroy.
+nmap q: <nop>
+" Simplify split movement.
+nmap <silent> <C-h> :wincmd h<CR>
+nmap <silent> <C-j> :wincmd j<CR>
+nmap <silent> <C-k> :wincmd k<CR>
+nmap <silent> <C-l> :wincmd l<CR>
+nmap <silent> <C-o> :vsplit<CR>
+" Make ctrl + '.' and ',' map to previous buffer.
+nmap <C-,> <C-^>
+nmap <C-.> <C-^>
+" Swap ctrl + f and b.
+"nnoremap <C-b> <C-f>
+"nnoremap <C-f> <C-b>
+" Toggle colorcolumn.
+nmap <silent> C :execute 'set colorcolumn=' . (&colorcolumn == '' ? '101' : '')<CR>
+" Personally intuitive pop-up menu binds.
+inoremap <expr> <CR> pumvisible() ? '<C-y><CR>' : '<CR>'
+inoremap <expr> <Up> pumvisible() ? '<C-p>' : '<Up>'
+inoremap <expr> <Down> pumvisible() ? '<C-n>' : '<Down>'
+" Lsp Binds.
+nmap <C-d> <C-]>
+" Fzf binds.
+nmap <silent> \ :Buffers<CR>
+nmap <silent> <C-o> :GGrep<CR>
+nmap <silent> <C-\> :GFiles<CR>
+" Only Neogit bind, handle all further operations from this menu.
+nmap <silent> Y :Neogit<CR>
+nmap <silent> L :lua neogit_log_current()<CR>
+" Undotree.
+nmap <silent> U :UndotreeToggle<CR>
+" Toggle hex color highlighting.
+nnoremap <silent> # :CccHighlighterToggle<CR>
+
+command Tabify set noexpandtab | %retab! | set expandtab
+command Untabify set expandtab | %retab!
+
+" https://stackoverflow.com/a/37040415
+function! SyntaxGroup()
+ let l:s = synID(line('.'), col('.'), 1)
+ echo synIDattr(l:s, 'name') . ' -> ' . synIDattr(synIDtrans(l:s), 'name')
+endfun
+
+" https://vi.stackexchange.com/a/456
+function! TrimWhitespace()
+ let l:save = winsaveview()
+ keeppatterns %s/\s\+$//e
+ call winrestview(l:save)
+endfun
+
+" https://github.com/junegunn/fzf.vim?tab=readme-ov-file#example-git-grep-wrapper
+command! -bang -nargs=* GGrep
+ \ call fzf#vim#grep(
+ \ 'git grep --line-number -- '.fzf#shellescape(<q-args>),
+ \ fzf#vim#with_preview({'dir': systemlist('git rev-parse --show-toplevel')[0]}), <bang>0)
+
+" https://vim.fandom.com/wiki/Replace_a_builtin_command_using_cabbrev
+function! CommandCabbr(abbreviation, expansion)
+ execute 'cabbr ' . a:abbreviation . ' <C-R>=getcmdpos() == 1 && getcmdtype() == ":" ? "' . a:expansion . '" : "' . a:abbreviation . '"<CR>'
+endfunction
+command! -nargs=+ CommandCabbr call CommandCabbr(<f-args>)
+CommandCabbr no nohlsearch
+
+call Juliana#Init() " Custom insert mode tab behavior inherited from Emacs.
+inoremap <silent><Tab> <C-R>=Juliana#CompleteTab('START')<CR>
+ \<C-R>=Juliana#CompleteTab('TAB')<CR>
+ \<C-R>=Juliana#CompleteTab('ALIGN')<CR>
+ \<C-R>=Juliana#CompleteTab('NEXT')<CR>
+inoremap <silent><S-Tab> <C-R>=Juliana#CompleteSTab('PREV')<CR>
+
+lua << EOF
+function get_lsp_name()
+ local active_clients = vim.lsp.get_clients({bufnr = vim.api.nvim_get_current_buf()})
+ if next(active_clients) == nil then
+ return ''
+ else
+ str = '<'
+ for _, v in pairs(active_clients) do
+ str = str .. v.name .. '+'
+ end
+ return str:sub(1, -2) .. '>'
+ end
+end
+
+buf_is_big = function(bufnr)
+ local max_filesize = 100 * 1024 -- 100KB
+ local ok, stats = pcall(vim.loop.fs_stat, vim.api.nvim_buf_get_name(bufnr))
+ if ok and stats and stats.size > max_filesize then
+ return true
+ else
+ return false
+ end
+end
+
+-- LSP configs.
+if os.getenv('NIX_SHELL') ~= nil then
+ vim.diagnostic.config({ virtual_text = true })
+ vim.lsp.config('clangd', {
+ cmd = {
+ 'clangd',
+ '-j=4',
+ '--log=error',
+ '--malloc-trim',
+ '--background-index',
+ '--clang-tidy',
+ '--completion-style=bundled',
+ '--pch-storage=memory',
+ '--header-insertion=never',
+ '--header-insertion-decorators=0',
+ '--query-driver=gcc'
+ },
+ capabilities = {
+ textDocument = {
+ semanticHighlightingCapabilities = {
+ semanticHighlighting = true
+ },
+ completion = {
+ completionItem = {
+ snippetSupport = false
+ }
+ }
+ }
+ },
+ })
+ vim.lsp.enable({'clangd', 'ruff', 'ty'})
+ -- https://github.com/neovim/nvim-lspconfig/issues/2626#issuecomment-2117022664
+ -- https://github.com/neovim/nvim-lspconfig/issues/2508
+ vim.api.nvim_create_autocmd('BufReadPre', {
+ callback = function(t)
+ if buf_is_big(t.buf) then
+ vim.o.eventignore = 'FileType'
+ vim.schedule(function()
+ vim.o.eventignore = ''
+ print('Dropped FileType events because the buffer is too big')
+ end)
+ end
+ end
+ })
+ require('inc_rename').setup({})
+ vim.keymap.set('n', '<C-n>', function()
+ return ':IncRename ' .. vim.fn.expand('<cword>')
+ end, { expr = true })
+end
+
+-- Set sessions folder and autowrite.
+if vim.fn.isdirectory(vim.fn.expand('~/c')) then
+ require('mini.sessions').setup({
+ autoread = false,
+ autowrite = true,
+ directory = '~/c/sessions'
+ })
+end
+
+-- Completion.
+require('mini.completion').setup({
+ window = {
+ info = { border = 'none' },
+ signature = { border = 'none' }
+ }
+})
+
+-- Don't use tabs in Neogit.
+require('neogit').setup({
+ disable_hint = true,
+ kind = 'vsplit',
+ commit_editor = { kind = 'split' },
+ commit_select_view = { kind = 'vsplit' },
+ commit_view = { kind = 'vsplit' },
+ log_view = { kind = 'split' },
+ reflog_view = { kind = 'split' },
+ preview_buffer = { kind = 'split' },
+ popup = { kind = 'split' },
+ refs_view = { kind = 'split' },
+ -- Allow basic movement in Neogit without mapping conflicts.
+ mappings = {
+ popup = { ['l'] = false, ['L'] = 'LogPopup', ['d'] = false },
+ status = { ['$'] = false, ['#'] = 'CommandHistory' }
+ },
+ integrations = {}
+})
+
+-- Doesn't work consistently.
+function neogit_log_current()
+ require("neogit").action("log", "log_current", { "--", vim.fn.expand("%:p") })()
+end
+
+-- Preview colors in #<hex> format.
+require('ccc').setup({ highlighter = { auto_enable = false, lsp = true } })
+EOF
diff --git a/nix_archive/files/nvim/local/autoload/Juliana.vim b/nix_archive/files/nvim/local/autoload/Juliana.vim
new file mode 100644
index 0000000..1b684b9
--- /dev/null
+++ b/nix_archive/files/nvim/local/autoload/Juliana.vim
@@ -0,0 +1,46 @@
+" https://github.com/neitanod/vim-clevertab
+
+function! Juliana#Init()
+ let g:Juliana#has_selection = 0
+ augroup JulianaPersistAu
+ autocmd ModeChanged [V\x16]*:i let g:Juliana#has_selection = 1
+ autocmd InsertLeave * let g:Juliana#has_selection = 0
+ augroup END
+endfunction
+
+function! Juliana#CompleteTab(type)
+ if a:type == "START"
+ let g:Juliana#stop=0
+ return ""
+ endif
+
+ if !g:Juliana#stop
+ " Vanilla <Tab> if we are at the front of a line.
+ if a:type == "TAB" && col(".") >= col("$") && !pumvisible()
+ let g:Juliana#stop=1
+ return "\<Tab>"
+ elseif a:type == "ALIGN" && !pumvisible() " Align if !pumvisible().
+ let g:Juliana#stop=1
+ if g:Juliana#has_selection
+ return "\<ESC>gv=i"
+ else
+ return "\<ESC>\<C-v>=i"
+ endif
+ elseif a:type == "NEXT" " If pumvisible(), goto the next result.
+ let g:Juliana#stop=1
+ return "\<C-n>"
+ endif
+ endif
+
+ return ""
+endfunction
+
+function! Juliana#CompleteSTab(type)
+ if a:type == "PREV"
+ if pumvisible() " If pumvisible(), goto the previous result.
+ return "\<C-p>"
+ else
+ return "\<Tab>" " <S-Tab> = <Tab>
+ endif
+ endif
+endfunction
diff --git a/nix_archive/files/nvim/mini_completion_no_title.diff b/nix_archive/files/nvim/mini_completion_no_title.diff
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/nix_archive/files/nvim/mini_completion_no_title.diff
diff --git a/nix_archive/files/nvim/mini_starter_picture.diff b/nix_archive/files/nvim/mini_starter_picture.diff
new file mode 100644
index 0000000..2efc2a1
--- /dev/null
+++ b/nix_archive/files/nvim/mini_starter_picture.diff
@@ -0,0 +1,288 @@
+diff --git a/lua/mini/starter.lua b/lua/mini/starter.lua
+index 66d46a52..9b7e4397 100644
+--- a/lua/mini/starter.lua
++++ b/lua/mini/starter.lua
+@@ -138,7 +138,7 @@
+ --- local timer = vim.loop.new_timer()
+ --- local n_seconds = 0
+ --- timer:start(0, 1000, vim.schedule_wrap(function()
+---- if vim.bo.filetype ~= 'ministarter' then
++--- if vim.bo.filetype ~= 'dashboard' then
+ --- timer:stop()
+ --- return
+ --- end
+@@ -239,6 +239,9 @@ MiniStarter.config = {
+ -- If `nil` (default), default items will be used (see |mini.starter|).
+ items = nil,
+
++ -- Empty lines at the top of the content.
++ top_padding = 0,
++
+ -- Header to be displayed before items. Converted to single string via
+ -- `tostring` (use `\n` to display several lines). If function, it is
+ -- evaluated first. If `nil` (default), polite greeting will be used.
+@@ -249,6 +252,12 @@ MiniStarter.config = {
+ -- evaluated first. If `nil` (default), default usage help will be shown.
+ footer = nil,
+
++ -- Amount of empty lines between items and the footer.
++ footer_offset = 1,
++
++ -- Picture to show to the side of the content.
++ picture = nil,
++
+ -- Array of functions to be applied consecutively to initial content.
+ -- Each function should take and return content for Starter buffer (see
+ -- |mini.starter| and |MiniStarter.get_content()| for more details).
+@@ -373,7 +382,7 @@ MiniStarter.refresh = function(buf_id)
+ data.footer = H.normalize_header_footer(config.footer or H.default_footer)
+
+ -- Evaluate content
+- local content = H.make_initial_content(data.header, items, data.footer)
++ local content = H.make_initial_content(data.header, items, data.footer, config)
+ local hooks = config.content_hooks or H.default_content_hooks
+ for _, f in ipairs(hooks) do
+ content = f(content, buf_id)
+@@ -400,6 +409,16 @@ MiniStarter.refresh = function(buf_id)
+
+ -- Apply current query (clear command line afterwards)
+ H.make_query(buf_id)
++
++ -- The picture drawn here used to get cleared at some point
++ -- that _usually_ came before any scheduled timers fired.
++ -- That seems to not happen anymore (nvim-0.11.1, kitty 0.42.1).
++ H.draw_picture(config, false)
++ --local timer = vim.loop.new_timer()
++ --timer:start(0, 0, vim.schedule_wrap(function()
++ -- timer:stop()
++ -- H.draw_picture(config, false)
++ --end))
+ end
+
+ --- Close Starter buffer
+@@ -729,18 +748,45 @@ MiniStarter.gen_hook.aligning = function(horizontal, vertical)
+ local win_id = vim.fn.bufwinid(buf_id)
+ if win_id < 0 then return end
+
++ local config = H.get_config()
++
+ local line_strings = MiniStarter.content_to_lines(content)
+
++ H.win_width = vim.api.nvim_win_get_width(win_id)
++ H.win_height = vim.api.nvim_win_get_height(win_id)
++
+ -- Align horizontally
+ -- Don't use `string.len()` to account for multibyte characters
+ local lines_width = vim.tbl_map(function(l) return vim.fn.strdisplaywidth(l) end, line_strings)
+- local min_right_space = vim.api.nvim_win_get_width(win_id) - math.max(unpack(lines_width))
++ -- Ignore the max line width
++ local min_right_space = H.win_width -- - math.max(unpack(lines_width))
+ local left_pad = math.max(math.floor(horiz_coef * min_right_space), 0)
+
+ -- Align vertically
+- local bottom_space = vim.api.nvim_win_get_height(win_id) - #line_strings
++ local bottom_space = H.win_height - #line_strings
+ local top_pad = math.max(math.floor(vert_coef * bottom_space), 0)
+
++ -- Position picture
++ if config.picture ~= nil then
++ if config.picture.width == nil then config.picture.width = 25 end
++ if config.picture.position ~= 'right' then config.picture.position = 'left' end
++ if config.picture.padding == nil then config.picture.padding = {} end
++ if config.picture.padding.left == nil then config.picture.padding.left = 0 end
++ if config.picture.padding.top == nil then config.picture.padding.top = 0 end
++ if config.picture.padding.text == nil then config.picture.padding.text = 0 end
++
++ local picture_left_pad = (config.picture.width / 2.0) - config.picture.padding.left
++
++ left_pad = left_pad + config.picture.padding.text
++ if config.picture.position == 'left' then
++ H.picture_x = left_pad - picture_left_pad
++ else
++ H.picture_x = left_pad + picture_left_pad
++ end
++ if H.picture_x < 0.0 then H.picture_x = 0.0 end
++ H.picture_y = top_pad + config.picture.padding.top + config.top_padding
++ end
++
+ return MiniStarter.gen_hook.padding(left_pad, top_pad)(content)
+ end
+ end
+@@ -1003,7 +1049,7 @@ H.default_footer = [[
+ Type query to filter items
+ <BS> deletes latest character from query
+ <Esc> resets current query
+-<Down/Up>, <C-n/p>, <M-j/k> move current item
++<C-j/k> move current item
+ <CR> executes action of current item
+ <C-c> closes this buffer]]
+
+@@ -1044,8 +1090,54 @@ end
+
+ H.apply_config = function(config) MiniStarter.config = config end
+
++H.is_file_readable = function(path)
++ return vim.fn.filereadable(vim.fn.expand(path)) ~= 0
++end
++
++H.draw_picture = function(config, clear)
++ if config ~= nil then
++ if config.picture == nil or config.picture.path == nil or not H.is_file_readable(config.picture.path) then return end
++ else
++ -- No picture, so nothing to clear
++ if H.picture_x == nil or H.picture_y == nil then return end
++ end
++ local cmd = ''
++ if clear and not config.picture.kitty then
++ cmd = ('for i in $(seq %d %d); do tput cup $i 0 && tput el; done'):format(0, H.win_height - 1)
++ else
++ cmd = ('chafa %s --align left,top -s %dx%d 2>&1'):format(config.picture.path, config.picture.width, (H.win_height - 2) - H.picture_y)
++ end
++ -- Resizing will not clear on non-kitty mode
++ local output = ''
++ if config.picture.kitty then
++ output = output .. '\027_Ga=d\027\\'
++ end
++ if not clear or not config.picture.kitty then
++ local handle = io.popen(cmd)
++ output = output .. handle:read('*a')
++ -- `rc` doesn't work when run from inside vim (last tested in neovim-0.9)
++ local rc = {handle:close()}
++ end
++ local tty, err = io.open('/proc/self/fd/0', 'wb')
++ if tty then
++ tty:write('\x1b[s')
++ if not clear then
++ tty:write(('\x1b[%d;%dH'):format(H.picture_y, H.picture_x))
++ elseif not config.picture.kitty then
++ tty:write('\x1b[48;5;0m')
++ end
++ tty:write(output)
++ if not clear then
++ tty:write('\x1b[u')
++ end
++ tty:close()
++ else
++ H.echo('Error opening tty: ' .. err)
++ end
++end
++
+ H.create_autocommands = function(config)
+- local gr = vim.api.nvim_create_augroup('MiniStarter', {})
++ H.augroup = vim.api.nvim_create_augroup('MiniStarter', {})
+
+ if config.autoopen then
+ local on_vimenter = function()
+@@ -1057,7 +1149,7 @@ H.create_autocommands = function(config)
+ vim.cmd('noautocmd lua MiniStarter.open()')
+ end
+
+- local au_opts = { group = gr, nested = true, once = true, callback = on_vimenter, desc = 'Open on VimEnter' }
++ local au_opts = { group = H.augroup, nested = true, once = true, callback = on_vimenter, desc = 'Open on VimEnter' }
+ vim.api.nvim_create_autocmd('VimEnter', au_opts)
+ end
+
+@@ -1103,9 +1195,11 @@ H.normalize_header_footer = function(x)
+ end
+
+ -- Work with buffer content ---------------------------------------------------
+-H.make_initial_content = function(header, items, footer)
++H.make_initial_content = function(header, items, footer, config)
+ local content = {}
+
++ H.content_add_empty_lines(content, config.top_padding)
++
+ -- Add header lines
+ for _, l in ipairs(header) do
+ H.content_add_line(content, { H.content_unit(l, 'header', 'MiniStarterHeader') })
+@@ -1116,7 +1210,7 @@ H.make_initial_content = function(header, items, footer)
+ H.content_add_items(content, items)
+
+ -- Add footer lines
+- H.content_add_empty_lines(content, #footer > 0 and 1 or 0)
++ H.content_add_empty_lines(content, #footer > 0 and config.footer_offset or 0)
+ for _, l in ipairs(footer) do
+ H.content_add_line(content, { H.content_unit(l, 'footer', 'MiniStarterFooter') })
+ end
+@@ -1319,11 +1413,23 @@ H.make_buffer_autocmd = function(buf_id)
+ au('VimResized', function() MiniStarter.refresh(buf_id) end, 'Refresh')
+ au('CursorMoved', function() H.position_cursor_on_current_item(buf_id) end, 'Position cursor')
+
++ local config = H.get_config()
++
+ local cache_showtabline = vim.o.showtabline
+ au('BufLeave', function()
+ if vim.o.cmdheight > 0 then vim.cmd("echo ''") end
+ if vim.o.showtabline == 1 then vim.o.showtabline = cache_showtabline end
++ H.draw_picture(config, true)
+ end, 'On BufLeave')
++
++ au('BufEnter', function()
++ H.draw_picture(config, false)
++ --local timer = vim.loop.new_timer()
++ --timer:start(0, 0, vim.schedule_wrap(function()
++ -- timer:stop()
++ -- H.draw_picture(config, false)
++ --end))
++ end, 'On BufEnter')
+ end
+
+ H.apply_buffer_options = function(buf_id)
+@@ -1336,7 +1442,7 @@ H.apply_buffer_options = function(buf_id)
+ vim.api.nvim_feedkeys('\28\14', 'nx', false)
+
+ -- Having `noautocmd` is crucial for performance: ~9ms without it, ~1.6ms with it
+- vim.cmd('noautocmd silent! set filetype=ministarter')
++ vim.cmd('noautocmd silent! set filetype=dashboard')
+
+ local options = {
+ -- Taken from 'vim-startify'
+@@ -1383,12 +1489,8 @@ H.apply_buffer_mappings = function(buf_id)
+
+ buf_keymap('<CR>', 'MiniStarter.eval_current_item()')
+
+- buf_keymap('<Up>', [[MiniStarter.update_current_item('prev')]])
+- buf_keymap('<C-p>', [[MiniStarter.update_current_item('prev')]])
+- buf_keymap('<M-k>', [[MiniStarter.update_current_item('prev')]])
+- buf_keymap('<Down>', [[MiniStarter.update_current_item('next')]])
+- buf_keymap('<C-n>', [[MiniStarter.update_current_item('next')]])
+- buf_keymap('<M-j>', [[MiniStarter.update_current_item('next')]])
++ buf_keymap('<C-k>', [[MiniStarter.update_current_item('prev')]])
++ buf_keymap('<C-j>', [[MiniStarter.update_current_item('next')]])
+
+ -- Make all special symbols to update query
+ for _, key in ipairs(vim.split(H.get_config().query_updaters, '')) do
+@@ -1464,21 +1566,21 @@ H.is_something_shown = function()
+ end
+
+ -- Utilities ------------------------------------------------------------------
+-H.error = function(msg) error('(mini.starter) ' .. msg, 0) end
++H.error = function(msg) error('' .. msg, 0) end
+
+ H.check_type = function(name, val, ref, allow_nil)
+ if type(val) == ref or (ref == 'callable' and vim.is_callable(val)) or (allow_nil and val == nil) then return end
+ H.error(string.format('`%s` should be %s, not %s', name, ref, type(val)))
+ end
+
+-H.set_buf_name = function(buf_id, name) vim.api.nvim_buf_set_name(buf_id, 'ministarter://' .. buf_id .. '/' .. name) end
++H.set_buf_name = function(buf_id, name) vim.api.nvim_buf_set_name(buf_id, '*dashboard*') end
+
+ H.echo = function(msg, is_important)
+ if H.get_config().silent then return end
+
+ -- Construct message chunks
+ msg = type(msg) == 'string' and { { msg } } or msg
+- table.insert(msg, 1, { '(mini.starter) ', 'WarningMsg' })
++ table.insert(msg, 1, { '', 'Warning' })
+
+ -- Avoid hit-enter-prompt
+ local max_width = vim.o.columns * math.max(vim.o.cmdheight - 1, 0) + vim.v.echospace
+@@ -1527,7 +1629,7 @@ H.eval_fun_or_string = function(x, string_as_cmd)
+ if type(x) == 'function' then return x() end
+ if type(x) == 'string' then
+ if string_as_cmd then
+- vim.cmd(x)
++ pcall(function() vim.cmd(x) end)
+ else
+ return x
+ end