summaryrefslogtreecommitdiff
path: root/files/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'files/nvim')
-rw-r--r--files/nvim/fzf_no_linenum.diff24
-rw-r--r--files/nvim/init.vim284
-rw-r--r--files/nvim/local/autoload/Juliana.vim46
-rw-r--r--files/nvim/mini_sessions_view.diff13
-rw-r--r--files/nvim/mini_starter_picture.diff264
5 files changed, 631 insertions, 0 deletions
diff --git a/files/nvim/fzf_no_linenum.diff b/files/nvim/fzf_no_linenum.diff
new file mode 100644
index 0000000..bed26be
--- /dev/null
+++ b/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/files/nvim/init.vim b/files/nvim/init.vim
new file mode 100644
index 0000000..fe40153
--- /dev/null
+++ b/files/nvim/init.vim
@@ -0,0 +1,284 @@
+" Basic settings.
+set number
+set noshowmode
+set signcolumn=yes
+set updatetime=250
+set scrolloff=5
+
+" Change directory based on current file.
+set autochdir
+
+" 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
+
+" 4 spaces autoindent.
+set tabstop=4
+set shiftwidth=4
+set expandtab
+set autoindent
+
+" C syntax preference.
+let g:c_syntax_for_h=1
+set cinoptions=l1,:0,g2,h2,(4,u0
+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
+let view_dir = expand('~/c/sessions/views')
+if !isdirectory(view_dir)
+ call mkdir(view_dir, "p", 0700)
+endif
+let &viewdir=view_dir
+" https://github.com/zhimsel/vim-stay/issues/10#issuecomment-336637546
+augroup stay_no_lcd
+ autocmd!
+ if exists(':tcd') == 2
+ autocmd User BufStaySavePre if haslocaldir() | let w:lcd = getcwd() | exe 'cd '.fnameescape(getcwd(-1, -1)) | endif
+ else
+ autocmd User BufStaySavePre if haslocaldir() | let w:lcd = getcwd() | cd - | cd - | endif
+ endif
+ autocmd User BufStaySavePost if exists('w:lcd') | execute 'lcd' fnameescape(w:lcd) | unlet w:lcd | endif
+augroup END
+
+" Staggered backups.
+if isdirectory(expand('/mnt/store/backup/vim'))
+ set backupdir=/mnt/store/backup/vim//
+else
+ set backupdir=~/c/sessions/backup//
+endif
+set backup
+
+" Swap file directory.
+set directory=~/c/sessions/swaps//
+
+if has("persistent_undo")
+ let undo_dir = expand('~/c/sessions/undo')
+ if !isdirectory(undo_dir)
+ call mkdir(undo_dir, "p", 0700)
+ endif
+ let &undodir=undo_dir
+ set undofile
+endif
+
+" Colorscheme.
+set background=dark
+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', 'String'],
+ \'marker': ['fg', 'Keyword'],
+ \'spinner': ['fg', 'String'],
+ \'header': ['fg', 'Type']
+\}
+let g:fzf_preview_window = ['right,47%']
+let g:fzf_layout = { 'window': { 'width': 0.65, 'height': 0.50 } }
+
+function! StatuslineGit()
+ let l:branchname = gitbranch#name()
+ return strlen(l:branchname) > 0?' '.l:branchname.' ':''
+endfunction
+
+lua << EOF
+function get_lsp_name()
+ local active_clients = vim.lsp.get_active_clients({bufnr = vim.api.nvim_get_current_buf()})
+ if next(active_clients) == nil then
+ return ''
+ else
+ return '+'..active_clients[1].name
+ end
+end
+EOF
+
+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 .= ' %m'
+ let status .= ' vim@%{hostname()}'
+ let status .= '%='
+ let status .= ' %y'
+ let status .= '%{StatuslineLsp()}'
+ let status .= ' %{&fileencoding?&fileencoding:&encoding}'
+ let status .= '[%{&fileformat}]'
+ let status .= '%3p%%'
+ let status .= ' %3l:%-3c'
+ return status
+endfunction
+set statusline=%!Statusline()
+
+lua << EOF
+-- LSP configs.
+if os.getenv('NIX_SHELL') ~= nil then
+ local lsp = require('lspconfig')
+ lsp.clangd.setup({
+ 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'
+ }
+ })
+ lsp.ruff.setup({})
+ require("inc_rename").setup({})
+end
+
+-- Try to make treesitter suck less.
+require('nvim-treesitter.configs').setup({
+ highlight = {
+ enable = true,
+ additional_vim_regex_highlighting = false
+ },
+ indent = {
+ enable = true,
+ disable = { 'c', 'cpp' }
+ }
+})
+
+-- Set sessions folder and autowrite.
+require('mini.sessions').setup({
+ autoread = false,
+ autowrite = true,
+ directory = '~/c/sessions'
+})
+
+-- Completion.
+require('mini.completion').setup({})
+
+-- Disable icons in diffview.
+require("diffview").setup({
+ diff_binaries = false,
+ use_icons = false
+})
+
+-- Don't use tabs in Neogit.
+require('neogit').setup({
+ 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" },
+ status = { ["$"] = false, ["#"] = "CommandHistory" }
+ }
+})
+
+-- Preview colors in #<hex> format.
+require('ccc').setup({ highlighter = { auto_enable = true, lsp = true } })
+
+-- Make shift + nav keys no-ops.
+vim.keymap.set('n', 'H', '<nop>', { silent = true })
+vim.keymap.set('n', 'J', '<nop>', { silent = true })
+vim.keymap.set('n', 'K', '<nop>', { silent = true })
+vim.keymap.set('n', 'L', '<nop>', { silent = true })
+-- Normal mode tab no-op.
+vim.keymap.set('n', '<Tab>', [[]], { silent = true })
+-- Disable q: for histroy.
+vim.keymap.set('n', 'q:', [[]], { silent = true })
+-- Simplify split movement.
+vim.keymap.set('n', '<C-h>', [[:wincmd h<CR>]], { silent = true })
+vim.keymap.set('n', '<C-j>', [[:wincmd j<CR>]], { silent = true })
+vim.keymap.set('n', '<C-k>', [[:wincmd k<CR>]], { silent = true })
+vim.keymap.set('n', '<C-l>', [[:wincmd l<CR>]], { silent = true })
+vim.keymap.set('n', '<C-o>', [[:vsplit<CR>]], { silent = true })
+-- Make ctrl + '.' and ',' map to previous buffer.
+vim.keymap.set('n', '<C-,>', '<c-^>', {})
+vim.keymap.set('n', '<C-.>', '<c-^>', {})
+-- Undotree
+vim.keymap.set('n', 'U', vim.cmd.UndotreeToggle)
+-- Toggle colorcolumn.
+vim.keymap.set('n', 'C', [[:execute 'set colorcolumn=' . (&colorcolumn == '' ? '101' : '')<CR>]], { silent = true })
+-- Lsp Binds.
+vim.keymap.set('n', '<C-d>', '<C-]>', {})
+vim.keymap.set('n', '<C-n>', function()
+ return ":IncRename " .. vim.fn.expand("<cword>")
+end, { expr = true })
+-- Fzf binds.
+vim.keymap.set('n', '<C-i>', [[:GGrep<CR>]], { silent = true })
+vim.keymap.set('n', '\\', [[:Buffers<CR>]], { silent = true })
+-- Personally intuitive pop-up menu binds.
+vim.keymap.set('i', '<CR>', [[pumvisible() ? '<C-y><CR>' : '<CR>']], { expr = true })
+vim.keymap.set('i', '<Up>', [[pumvisible() ? '<C-p>' : '<Up>']], { expr = true })
+vim.keymap.set('i', '<Down>', [[pumvisible() ? '<C-n>' : '<Down>']], { expr = true })
+-- Only Neogit bind, handle all further operations from this menu.
+vim.keymap.set('n', 'Y', [[:Neogit<CR>]], { silent = true })
+EOF
+
+command Tabify set noexpandtab | %retab! | set expandtab
+command Untabify set expandtab | %retab!
+
+" 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)
+
+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>
diff --git a/files/nvim/local/autoload/Juliana.vim b/files/nvim/local/autoload/Juliana.vim
new file mode 100644
index 0000000..1b684b9
--- /dev/null
+++ b/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/files/nvim/mini_sessions_view.diff b/files/nvim/mini_sessions_view.diff
new file mode 100644
index 0000000..7fa8500
--- /dev/null
+++ b/files/nvim/mini_sessions_view.diff
@@ -0,0 +1,13 @@
+diff --git a/lua/mini/sessions.lua b/lua/mini/sessions.lua
+index 67d0239..bb20292 100644
+--- a/lua/mini/sessions.lua
++++ b/lua/mini/sessions.lua
+@@ -248,7 +248,7 @@ MiniSessions.write = function(session_name, opts)
+ H.possibly_execute(opts.hooks.pre, data)
+
+ -- Make session file
+- local command = string.format('mksession%s %s', opts.force and '!' or '', vim.fn.fnameescape(session_path))
++ local command = string.format('mkview%s %s', opts.force and '!' or '', vim.fn.fnameescape(session_path))
+ vim.cmd(command)
+ data.modify_time = vim.fn.getftime(session_path)
+
diff --git a/files/nvim/mini_starter_picture.diff b/files/nvim/mini_starter_picture.diff
new file mode 100644
index 0000000..555009a
--- /dev/null
+++ b/files/nvim/mini_starter_picture.diff
@@ -0,0 +1,264 @@
+diff --git a/lua/mini/starter.lua b/lua/mini/starter.lua
+index 64939dc..493486b 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
+@@ -249,6 +249,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).
+@@ -372,7 +378,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)
+@@ -399,6 +405,12 @@ MiniStarter.refresh = function(buf_id)
+
+ -- Apply current query (clear command line afterwards)
+ H.make_query(buf_id)
++
++ 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
+@@ -730,18 +742,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
++ end
++
+ return MiniStarter.gen_hook.padding(left_pad, top_pad)(content)
+ end
+ end
+@@ -1004,7 +1043,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]]
+
+@@ -1052,8 +1091,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()
+@@ -1065,7 +1150,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
+
+@@ -1111,7 +1196,7 @@ 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 = {}
+
+ -- Add header lines
+@@ -1124,7 +1209,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
+@@ -1327,11 +1412,22 @@ 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()
++ 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)
+@@ -1345,17 +1441,11 @@ H.apply_buffer_options = function(buf_id)
+
+ -- Set unique buffer name. Prefer "Starter" prefix as more user friendly.
+ H.buffer_number = H.buffer_number + 1
+- local name = H.buffer_number <= 1 and 'Starter' or ('Starter_' .. H.buffer_number)
+- for _, buf in ipairs(vim.api.nvim_list_bufs()) do
+- if vim.fn.fnamemodify(vim.api.nvim_buf_get_name(buf), ':t') == name then
+- name = 'ministarter://' .. H.buffer_number
+- break
+- end
+- end
++ local name = H.buffer_number <= 1 and '*dashboard*' or ('dashboard://' .. H.buffer_number)
+ vim.api.nvim_buf_set_name(buf_id, name)
+
+ -- 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'
+@@ -1401,12 +1491,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
+@@ -1487,7 +1573,7 @@ H.echo = function(msg, is_important)
+
+ -- 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
+@@ -1525,7 +1611,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