summaryrefslogtreecommitdiffstats
path: root/lua/core
diff options
context:
space:
mode:
authorSquibid <me@zacharyscheiman.com>2023-11-24 21:38:31 -0500
committerSquibid <me@zacharyscheiman.com>2023-11-24 21:38:31 -0500
commitf35b13d669867209427449840ff0930a732591dc (patch)
tree3acb658ec5d01f456c49a097d56f736cbfbbfc7d /lua/core
parentebf9d2d1c4682068f5116f7efc1568ce5adf4f1b (diff)
downloadnvim-f35b13d669867209427449840ff0930a732591dc.tar.gz
nvim-f35b13d669867209427449840ff0930a732591dc.tar.bz2
nvim-f35b13d669867209427449840ff0930a732591dc.zip
more stuff too lazy to seperate
Diffstat (limited to 'lua/core')
-rw-r--r--lua/core/auto.lua30
-rw-r--r--lua/core/binds.lua162
-rw-r--r--lua/core/cmds.lua8
-rw-r--r--lua/core/conf.lua81
-rw-r--r--lua/core/handler.lua5
-rw-r--r--lua/core/misc.lua30
-rw-r--r--lua/core/opts.lua65
-rw-r--r--lua/core/plugins.lua134
-rw-r--r--lua/core/statusbar/components.lua315
-rw-r--r--lua/core/theme.lua76
10 files changed, 502 insertions, 404 deletions
diff --git a/lua/core/auto.lua b/lua/core/auto.lua
deleted file mode 100644
index 170f2d7..0000000
--- a/lua/core/auto.lua
+++ /dev/null
@@ -1,30 +0,0 @@
-local function auto(event, opts)
- a.nvim_create_autocmd(event, opts)
-end
-
-a.nvim_create_augroup('bufcheck', { clear = true })
-
-auto('TextYankPost', { -- highlight yanks
- group = 'bufcheck',
- pattern = '*',
- desc = 'Highlight on yank.',
- callback = function()
- vim.highlight.on_yank{ timeout = 250 }
- end
-})
-
-auto('BufRead', { -- return to last place
- pattern = '*',
- command = [[call setpos(".", getpos("'\""))]],
- desc = 'Return to the last place the buffer was closed in.',
-})
-
-auto('BufWritePre', { -- make dirs when they don't exist
- pattern = '*',
- group = vim.api.nvim_create_augroup('auto_create_dir', { clear = true }),
- desc = 'Basically mkdir -p.',
- callback = function(ctx)
- local dir = vim.fn.fnamemodify(ctx.file, ':p:h')
- vim.fn.mkdir(dir, 'p')
- end
-})
diff --git a/lua/core/binds.lua b/lua/core/binds.lua
deleted file mode 100644
index b1e98be..0000000
--- a/lua/core/binds.lua
+++ /dev/null
@@ -1,162 +0,0 @@
-local function map(mode, bind, cmd, opts)
- opts = opts or {}
- opts['noremap'] = true
- opts['silent'] = true
-
- if type(bind) == 'table' then
- for i in pairs(bind) do
- vim.keymap.set(mode, bind[i], cmd, opts)
- end
- elseif type(bind) == 'string' then
- vim.keymap.set(mode, bind, cmd, opts)
- end
-end
-
--- vim binds ------------------------------------------------------------------
-g.mapleader = ' ' -- set leader key
-
-map('x', '<leader>p', [["_dP]], { desc = 'Greatest remap of all time.' })
-map('n', '<esc>', ':nohlsearch<Bar>:echo<CR>', { desc = 'Clear search.' })
-map('t', '<esc>', '<C-\\><C-n>', { desc = 'make <esc> work in terminals.' })
--- move selected text up/down
-map('v', '<S-k>', ":m '<-2<CR>gv=gv", { desc = 'Move selected text up.' })
-map('v', '<S-j>', ":m '>+1<CR>gv=gv", { desc = 'Move selected text down.' })
-
--- the cursor STAYS IN THE MIDDLE
-map('n', '<S-j>', 'mzJ`z<cmd>delm z<CR>') -- when combining lines
-map('n', 'n', 'nzzzv') -- when searching
-map('n', 'N', 'Nzzzv')
-map('n', '<C-d>', '<C-d>zz') -- half page jumping
-map('n', '<C-u>', '<C-u>zz')
-
-map('n', '<leader>x', '<cmd>!chmod +x "%"<CR>') -- execute order 111
-
--- add some keybinds to the file view (netrw)
-a.nvim_create_autocmd('FileType', {
- pattern = 'netrw',
- callback = function()
- local bind = function(lhs, rhs)
- vim.keymap.set('n', lhs, rhs, { remap = true, buffer = true })
- end
- bind('h', '-^') -- Go up a directory
- bind('l', '<CR>') -- Go down a directory / open a file
- bind('.', 'gh') -- Toggle hidden files
- bind('P', '<C-w>z') -- Close preview window
- bind('<esc>', '<cmd>q<CR>') -- Close netrw
- end
-})
-
--- tabs
-map('n', '[]', '<cmd>tabnew<CR>')
-map('n', '][', '<cmd>tabc<CR>')
-map('n', '[[', '<cmd>tabp<CR>')
-map('n', ']]', '<cmd>tabN<CR>')
-
--- plugin binds ---------------------------------------------------------------
-
--- pretty lsp view
-map('n', 'gd', '<CMD>Glance definitions<CR>')
-map('n', 'gr', '<CMD>Glance references<CR>')
-map('n', 'gy', '<CMD>Glance type_definitions<CR>')
-map('n', 'gi', '<CMD>Glance implementations<CR>')
-
-if pcall(require, "treesj") then
- local treesj = require('treesj') -- treesj
- map('n', '<leader>j', treesj.toggle)
-end
-
-if pcall(require, "telescope") then
- local telebuilt = require('telescope.builtin') -- telescope
- -- local telexten = require('telescope').extensions
- map('n', '<leader>sf', telebuilt.find_files, { desc = 'Find files.' })
- map('n', '<leader>so', telebuilt.oldfiles, { desc = 'Find old files.' })
- map('n', '<leader>sg', telebuilt.git_files, { desc = 'Find git files.' })
- -- search urls in buffer
- map('n', '<leader>su', '<Cmd>UrlView<CR>', { desc = 'Find urls in buffer.' })
- -- search lsp symbols
- map('n', '<leader>ss', telebuilt.lsp_document_symbols,
- { desc = 'Find LSP Symbols.' })
- -- search for keybinds
- map('n', '<leader>sk', telebuilt.keymaps,
- { desc = 'Find nvim Highlights.' })
- -- search for highlights
- map('n', '<leader>sh', telebuilt.highlights,
- { desc = 'Find nvim Highlights.' })
- -- search for autocommands
- map('n', '<leader>sa', telebuilt.autocommands,
- { desc = 'Find nvim Autocommands.' })
- -- search for vim options
- map('n', '<leader>sv', telebuilt.vim_options, { desc = 'Find vim options.' })
- -- search for string in project
- map('n', '<leader>sp', function()
- telebuilt.grep_string({ search = vim.fn.input('Find string in project > ')})
- end, { desc = 'Find string in project.' })
- -- Code Actions (requires telescope)
- if pcall(require, "actions-preview") then
- map({ "n", "v" }, "<leader>ca", require("actions-preview").code_actions, {
- desc = 'preview code actions'
- })
- end
-end
-
-map('n', '<leader>u', '<cmd>UndotreeToggle<CR>', { desc = 'Open undo tree.' })
-map('n', '<leader>f', '<cmd>SFMToggle<CR>', { desc = 'Open file tree view.' })
-map('n', '<leader>b', '<cmd>JABSOpen<CR>', { desc = 'Switch between buffers.' })
-
-if pcall(require, "smart-splits") then
- local smartsplits = require('smart-splits') -- resizing buffers (toggleable)
- map('n', '<leader>r', smartsplits.start_resize_mode)
-end
-
--- toggle term (don't use leader key in these binds)
-map({'n', 't'}, '<C-\\>', '<cmd>ToggleTerm direction=float<CR>')
-map({'n', 't'}, '<C-g>', '<cmd>lua _glow()<CR>')
-
--- true zen
-if pcall(require, "true-zen") then
- map('n', '<leader>zf', require("true-zen.focus").toggle, {
- desc = 'fullscreen',
- })
- map('n', '<leader>zm', require("true-zen.minimalist").toggle, {
- desc = 'minimal',
- })
- map('n', '<leader>za', require("true-zen.ataraxis").toggle, {
- desc = 'zen',
- })
-end
-
--- git
-map('n', '<leader>gp', '<cmd>Gitsigns preview_hunk_inline<CR>')
-map('n', '<leader>gs', '<cmd>Gitsigns stage_hunk<CR>')
-map('n', '<leader>gb', '<cmd>Gitsigns blame_line<CR>')
-map('n', '<leader>g]', '<cmd>Gitsigns next_hunk<CR>')
-map('n', '<leader>g[', '<cmd>Gitsigns prev_hunk<CR>')
-
--- neogen
-if pcall(require, "neogen") then
- map('n', '<leader>df', require("neogen").generate, {
- desc = 'Generate anotations',
- })
-end
-
--- venn
-function _G.Toggle_venn()
- local venn_enabled = vim.inspect(vim.b.venn_enabled)
- if venn_enabled == "nil" then
- vim.b.venn_enabled = true
- vim.cmd([[setlocal ve=all]])
- -- draw a line on HJKL keystokes
- vim.api.nvim_buf_set_keymap(0, "n", "J", "<C-v>j:VBox<CR>", {noremap = true})
- vim.api.nvim_buf_set_keymap(0, "n", "K", "<C-v>k:VBox<CR>", {noremap = true})
- vim.api.nvim_buf_set_keymap(0, "n", "L", "<C-v>l:VBox<CR>", {noremap = true})
- vim.api.nvim_buf_set_keymap(0, "n", "H", "<C-v>h:VBox<CR>", {noremap = true})
- -- draw a box by pressing "f" with visual selection
- vim.api.nvim_buf_set_keymap(0, "v", "f", ":VBox<CR>", {noremap = true})
- else
- vim.cmd[[setlocal ve=]]
- vim.cmd[[mapclear <buffer>]]
- vim.b.venn_enabled = nil
- end
-end
--- toggle keymappings for venn using <leader>v
-vim.api.nvim_set_keymap('n', '<leader>v', ":lua Toggle_venn()<CR>", { noremap = true})
diff --git a/lua/core/cmds.lua b/lua/core/cmds.lua
deleted file mode 100644
index 3cc78e1..0000000
--- a/lua/core/cmds.lua
+++ /dev/null
@@ -1,8 +0,0 @@
-local function cmd(name, exec, opts)
- opts = opts or {}
- vim.api.nvim_create_user_command(name, exec, opts)
-end
-
-cmd('Colorscheme', function()
- require('telescope.builtin').colorscheme()
-end)
diff --git a/lua/core/conf.lua b/lua/core/conf.lua
new file mode 100644
index 0000000..72dd9bf
--- /dev/null
+++ b/lua/core/conf.lua
@@ -0,0 +1,81 @@
+local pickers = require("telescope.pickers")
+local finders = require("telescope.finders")
+local previewers = require("telescope.previewers")
+local conf = require("telescope.config").values
+local actions = require("telescope.actions")
+local action_state = require("telescope.actions.state")
+
+local M = {}
+
+local function genmenu()
+ local list = {}
+ local function add(name, plug)
+ if not plug then
+ table.insert(list, name)
+ elseif package.loaded[plug] then
+ table.insert(list, name)
+ end
+ end
+
+ add('Edit Config', nil)
+ add('Update Plugins', 'dep')
+ add('Keybinds', 'telescope')
+ add('Colorscheme', 'telescope')
+
+ return list
+end
+
+function M.configmenu()
+ pickers.new({
+ prompt_title = "Nvim Config Menu",
+ finder = finders.new_table { results = genmenu() },
+ sorter = conf.generic_sorter(),
+ previewer = previewers.new_buffer_previewer {
+ define_preview = function(self, entry)
+ local lines = {
+ 'a'
+ }
+ if entry.value == "Edit Config" then
+ lines = misc.readf(os.getenv('XDG_CONFIG_HOME')..'/nvim/init.lua')
+ local ft = vim.filetype.match({
+ filename = os.getenv('XDG_CONFIG_HOME')..'/nvim/init.lua' })
+ require("telescope.previewers.utils").highlighter(self.state.bufnr, ft)
+ elseif entry.value == "Colorscheme" then
+ lines = vim.fn.getcompletion('', 'color')
+ for k, v in pairs(lines) do
+ if v.find(v, '.ext') then
+ table.remove(lines, k)
+ break
+ end
+ end
+ end
+ vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines)
+ end
+ },
+
+ attach_mappings = function(bufnr, map)
+ actions.select_default:replace(function()
+ actions.close(bufnr)
+ local selection = action_state.get_selected_entry()
+ if selection[1] == 'Edit Config' then
+ vim.cmd('e $XDG_CONFIG_HOME/nvim/init.lua')
+ elseif selection[1] == 'Update Plugins' then
+ require('dep').sync()
+ if package.loaded['nvim-treesitter'] then
+ vim.cmd('TSUpdate')
+ end
+ if package.loaded['mason'] then
+ require('mason.api.command').MasonUpdate()
+ end
+ elseif selection[1] == 'Keybinds' then
+ require('telescope.builtin').keymaps()
+ elseif selection[1] == 'Colorscheme' then
+ require('core.theme').switcher()
+ end
+ end)
+ return true
+ end,
+ }):find()
+end
+
+return M
diff --git a/lua/core/handler.lua b/lua/core/handler.lua
deleted file mode 100644
index 0038146..0000000
--- a/lua/core/handler.lua
+++ /dev/null
@@ -1,5 +0,0 @@
-require('core.plugins') -- load plugins first to allow colorscheme to be set in opts
-require('core.opts')
-require('core.binds')
-require('core.auto')
-require('core.cmds')
diff --git a/lua/core/misc.lua b/lua/core/misc.lua
new file mode 100644
index 0000000..41cbf93
--- /dev/null
+++ b/lua/core/misc.lua
@@ -0,0 +1,30 @@
+local M = {}
+
+M.appid = "Nvim Config"
+
+function M.colorscheme(name)
+ vim.cmd('colorscheme '..name)
+ for k, v in pairs(vim.fn.getcompletion('', 'color')) do
+ if v == name..'.ext' then
+ vim.cmd('colorscheme '..name..'.ext')
+ end
+ end
+end
+
+function M.include(fn)
+ if not pcall(require, fn) then
+ vim.notify('Could not find '..fn, vim.log.levels.WARN, { title = M.appid })
+ end
+end
+
+function M.readf(fn)
+ local f = io.open(fn, "r")
+ if not f then return nil end
+ local tab = {}
+ for l in f:lines() do
+ table.insert(tab, l)
+ end
+ return tab
+end
+
+return M
diff --git a/lua/core/opts.lua b/lua/core/opts.lua
deleted file mode 100644
index 82d88bd..0000000
--- a/lua/core/opts.lua
+++ /dev/null
@@ -1,65 +0,0 @@
--- better ui ------------------------------------------------------------------
-if pcall(require, "notify") then vim.notify = require("notify") end
-o.colorcolumn = { 80 }
-
--- buffer
-o.scrolloff = 5
-o.wrap = true -- wraping lines
-o.linebreak = true -- fix where line is wraped
-o.cursorline = true
-
--- statusbar
-o.laststatus = 3
-o.cmdheight = 1
-o.showmode = false -- stop vim from showing mode (we have a statusbar)
-
--- tabline
-o.showtabline = 2
-
--- status column
-o.signcolumn = 'yes:1' -- show gutter
-
--- indents + tabs
-local tabwidth = 2
-o.expandtab = true
-o.smarttab = true
-o.cindent = true
-o.autoindent = true
-o.tabstop = tabwidth
-o.shiftwidth = tabwidth
-o.softtabstop = tabwidth
-
--- colorscheme
-o.termguicolors = true
-vim.cmd('colorscheme mellow') -- mellow
-vim.cmd('colorscheme mellow+') -- some changes
-
--- better editing -------------------------------------------------------------
-o.clipboard = 'unnamedplus' -- system clipboard
-
--- file saving ----------------------------------------------------------------
-o.swapfile = false
-o.undofile = true
-o.confirm = true
-
--- searching ------------------------------------------------------------------
-o.ignorecase = true
-o.smartcase = true
-o.wrapscan = true
-o.showmatch = true
-o.incsearch = true
-
--- wild menus -----------------------------------------------------------------
-o.wildoptions = 'pum'
-o.pumblend = 3
-o.pumheight = 20
-
-o.wildignorecase = true
-o.wildignore = '*.o'
-
--- netrw ----------------------------------------------------------------------
-g.netrw_banner = 1
-g.netrw_localcopydircmd = 'cp -r'
-g.netrw_winsize = 30
-g.netrw_liststyle = 1
-g.netrw_preview = 1
diff --git a/lua/core/plugins.lua b/lua/core/plugins.lua
deleted file mode 100644
index db20075..0000000
--- a/lua/core/plugins.lua
+++ /dev/null
@@ -1,134 +0,0 @@
-require 'dep' {
- sync = "always",
- -- dep manages dep ----------------------------------------------------------
- { 'squibid/dep',
- url = 'https://git.squi.bid/dep',
- -- branch = 'dev'
- },
-
- { 'squibid/git-yodel',
- url = 'https://git.squi.bid/git-yodel'
- },
-
- -- colorschemes -------------------------------------------------------------
- { 'kvrohit/mellow.nvim',
- requires = 'nvim-treesitter/nvim-treesitter'
- },
-
- -- ui -----------------------------------------------------------------------
- { 'lukas-reineke/indent-blankline.nvim' }, -- indentation indicators
- { 'folke/which-key.nvim' }, -- key map help
- { 'rcarriga/nvim-notify' }, -- notifications
- { 'tjdevries/express_line.nvim', -- status bar
- requires = 'nvim-lua/plenary.nvim',
- },
- { 'goolord/alpha-nvim' }, -- start page
- { 'dinhhuy258/sfm.nvim', -- tree view
- deps = 'dinhhuy258/sfm-git.nvim',
- },
- { 'matbme/JABS.nvim' }, -- buffer switcher
- { 'tomiis4/Hypersonic.nvim' }, -- regex helper/displayer
-
- -- functional plugins -------------------------------------------------------
- { 'lewis6991/gitsigns.nvim' }, -- very helpful git things
- { 'squibid/git-yodel', -- git cache diff preview when in commit buffer
- url = 'https://git.squi.bid/git-yodel'
- },
- { 'chentoast/marks.nvim' }, -- marks in gutter
- { 'vidocqh/auto-indent.nvim' }, -- better tabbing into indents
- { 'mbbill/undotree' }, -- careful this one is written in vimscript
- { 'dhruvasagar/vim-table-mode' }, -- same with this one
- { 'windwp/nvim-autopairs' },
- { 'numToStr/Comment.nvim' },
- { 'ahmedkhalf/project.nvim' }, -- cd into root of project
- { 'akinsho/toggleterm.nvim' }, -- TODO: switch to tmux based popup terminal
- { 'mrjones2014/smart-splits.nvim'}, -- buffer resizing
-
- -- note taking --------------------------------------------------------------
- { 'nvim-neorg/neorg',
- config = function()
- if package.loaded['nvim-treesitter'] then
- vim.cmd(':Neorg sync-parsers<CR>')
- end
- end,
- requires = {
- 'nvim-lua/plenary.nvim',
- 'nvim-treesitter/nvim-treesitter'
- },
- deps = 'nvim-neorg/neorg-telescope'
- },
-
- { 'jbyuki/venn.nvim' },
-
- -- fzf ----------------------------------------------------------------------
- { 'nvim-telescope/telescope.nvim',
- requires = 'nvim-lua/plenary.nvim',
- deps = {
- 'nvim-telescope/telescope-file-browser.nvim',
- 'nvim-telescope/telescope-ui-select.nvim',
- 'nvim-telescope/telescope-symbols.nvim',
- 'axieax/urlview.nvim',
- }
- },
-
- -- treesitter + colorizing --------------------------------------------------
- { 'nvim-treesitter/nvim-treesitter',
- deps = {
- 'm-demare/hlargs.nvim',
- 'Wansmer/treesj',
- 'nvim-treesitter/nvim-treesitter-context',
- }
- },
- { 'NvChad/nvim-colorizer.lua' },
- { 'folke/todo-comments.nvim',
- requires = 'nvim-lua/plenary.nvim',
- },
-
- -- cmp ----------------------------------------------------------------------
- { 'hrsh7th/nvim-cmp',
- deps = {
- 'lukas-reineke/cmp-under-comparator', -- better results
- 'hrsh7th/cmp-buffer', -- buffers
- 'FelipeLema/cmp-async-path', -- path
- 'hrsh7th/cmp-calc', -- calculator
- 'saadparwaiz1/cmp_luasnip', -- snippets
- 'hrsh7th/cmp-nvim-lsp', -- lsp
- 'uga-rosa/cmp-dictionary', -- dictionary
- 'hrsh7th/cmp-nvim-lua', -- nvim lua api
- },
- },
-
- -- snippets -----------------------------------------------------------------
- { 'L3MON4D3/LuaSnip',
- deps = 'rafamadriz/friendly-snippets',
- },
- { 'doxnit/cmp-luasnip-choice' },
-
- -- lsp ----------------------------------------------------------------------
- { 'neovim/nvim-lspconfig' }, -- setup lsp
- { 'j-hui/fidget.nvim', -- shows lsp progress
- branch = 'legacy',
- },
-
- { 'ray-x/lsp_signature.nvim' }, -- see information about the current function
- { 'dnlhc/glance.nvim' }, -- diagnostic info at a glance
- { 'aznhe21/actions-preview.nvim', -- codeactions
- requires = 'nvim-telescope/telescope.nvim'
- },
-
- { 'danymat/neogen', -- generate lsp annotations
- requires = 'nvim-treesitter/nvim-treesitter'
- },
-
- { 'whynothugo/lsp_lines.nvim',
- url = 'https://git.sr.ht/~whynothugo/lsp_lines.nvim',
- },
-
- -- mason --------------------------------------------------------------------
- { 'williamboman/mason.nvim',
- deps = {
- 'WhoIsSethDaniel/mason-tool-installer.nvim',
- 'williamboman/mason-lspconfig.nvim',
- }
- }
-}
diff --git a/lua/core/statusbar/components.lua b/lua/core/statusbar/components.lua
new file mode 100644
index 0000000..cce3127
--- /dev/null
+++ b/lua/core/statusbar/components.lua
@@ -0,0 +1,315 @@
+if not pcall(require, "el") then return end
+
+local job = require "plenary.job"
+local el_sub = require "el.subscribe"
+
+local M = {}
+
+function M.extract_hl(spec)
+ if not spec or vim.tbl_isempty(spec) then return end
+ local hl_name, hl_opts = { "El" }, {}
+ for attr, val in pairs(spec) do
+ if type(val) == "table" then
+ table.insert(hl_name, attr)
+ assert(vim.tbl_count(val) == 1)
+ local hl, what = next(val)
+ local hlID = vim.fn.hlID(hl)
+ if hlID > 0 then
+ table.insert(hl_name, hl)
+ local col = vim.fn.synIDattr(hlID, what)
+ if col and #col > 0 then
+ table.insert(hl_name, what)
+ hl_opts[attr] = col
+ end
+ end
+ else
+ -- bold, underline, etc
+ hl_opts[attr] = val
+ end
+ end
+ hl_name = table.concat(hl_name, "_")
+ -- if highlight exists, verify it has
+ -- the correct colorscheme highlights
+ local newID = vim.fn.hlID(hl_name)
+ if newID > 0 then
+ for what, expected in pairs(hl_opts) do
+ local res = vim.fn.synIDattr(newID, what)
+ if type(expected) == "boolean" then
+ -- synIDattr returns '1' for boolean
+ res = res and res == "1" and true
+ end
+ if res ~= expected then
+ -- need to regen the highlight
+ -- print("color mismatch", hl_name, what, "e:", expected, "c:", res)
+ newID = 0
+ end
+ end
+ end
+ if newID == 0 then
+ vim.api.nvim_set_hl(0, hl_name, hl_opts)
+ end
+ return hl_name
+end
+
+local function set_hl(hls, s)
+ if not hls or not s then return s end
+ hls = type(hls) == "string" and { hls } or hls
+ for _, hl in ipairs(hls) do
+ if vim.fn.hlID(hl) > 0 then
+ return ("%%#%s#%s%%0*"):format(hl, s)
+ end
+ end
+ return s
+end
+
+local function wrap_fnc(opts, fn)
+ return function(window, buffer)
+ -- buf_autocmd doesn't send win
+ if not window and buffer then
+ window = { win_id = vim.fn.bufwinid(buffer.bufnr) }
+ end
+ if opts.hide_inactive and window and
+ window.win_id ~= vim.api.nvim_get_current_win() then
+ return ""
+ end
+ return fn(window, buffer)
+ end
+end
+
+function M.mode(opts)
+ opts = opts or {}
+ return wrap_fnc(opts, function(_, _)
+ local fmt = opts.fmt or "%s%s"
+ local mode = vim.api.nvim_get_mode().mode
+ local mode_data = opts.modes and opts.modes[mode]
+ local hls = mode_data and mode_data[3]
+ local icon = opts.hl_icon_only and set_hl(hls, opts.icon) or opts.icon
+ mode = mode_data and mode_data[1]:upper() or mode
+ mode = (fmt):format(icon or "", mode)
+ return not opts.hl_icon_only and set_hl(hls, mode) or mode
+ end)
+end
+
+function M.git_branch(opts)
+ opts = opts or {}
+ return el_sub.buf_autocmd("el_git_branch", "BufEnter",
+ wrap_fnc(opts, function(_, buffer)
+ -- Try fugitive first as it's most reliable
+ local branch = vim.g.loaded_fugitive == 1 and
+ vim.fn.FugitiveHead() or nil
+ -- buffer can be null and code will crash with:
+ -- E5108: Error executing lua ... 'attempt to index a nil value'
+ if not buffer or not (buffer.bufnr > 0) then
+ return
+ end
+ -- fugitive is empty or not loaded, try gitsigns
+ if not branch or #branch == 0 then
+ local ok, res = pcall(vim.api.nvim_buf_get_var,
+ buffer.bufnr, "gitsigns_head")
+ if ok then branch = res end
+ end
+ -- last resort run git command
+ if not branch then
+ local j = job:new {
+ command = "git",
+ args = { "branch", "--show-current" },
+ cwd = vim.fn.fnamemodify(buffer.name, ":h"),
+ }
+
+ local ok, result = pcall(function()
+ return vim.trim(j:sync()[1])
+ end)
+ if ok then
+ branch = result
+ end
+ end
+
+ if branch and #branch > 0 then
+ local fmt = opts.fmt or "%s %s"
+ local icon = opts.icon or ""
+ return set_hl(opts.hl, (fmt):format(icon, branch))
+ end
+ end))
+end
+
+local function git_changes_formatter(opts)
+ local specs = {
+ insert = {
+ regex = "(%d+) insertions?",
+ icon = opts.icon_insert or "+",
+ hl = opts.hl_insert,
+ },
+ change = {
+ regex = "(%d+) files? changed",
+ icon = opts.icon_change or "~",
+ hl = opts.hl_change,
+ },
+ delete = {
+ regex = "(%d+) deletions?",
+ icon = opts.icon_delete or "-",
+ hl = opts.hl_delete,
+ },
+ }
+ return function(_, _, s)
+ local result = {}
+ for k, v in pairs(specs) do
+ local count = nil
+ if type(s) == "string" then
+ -- 'git diff --shortstat' output
+ -- from 'git_changes_all'
+ count = tonumber(string.match(s, v.regex))
+ else
+ -- map from 'git_changes_buf'
+ count = s[k]
+ end
+ if count and count > 0 then
+ table.insert(result, set_hl(v.hl, ("%s%d"):format(v.icon, count)))
+ end
+ end
+ return table.concat(result, " ")
+ end
+end
+
+-- requires gitsigns
+function M.git_changes_buf(opts)
+ opts = opts or {}
+ local formatter = opts.formatter or git_changes_formatter(opts)
+ return wrap_fnc(opts, function(window, buffer)
+ local stats = {}
+ if buffer and buffer.bufnr > 0 then
+ local ok, res = pcall(vim.api.nvim_buf_get_var,
+ buffer.bufnr, "vgit_status")
+ if ok then stats = res end
+ end
+ if buffer and buffer.bufnr > 0 then
+ local ok, res = pcall(vim.api.nvim_buf_get_var,
+ buffer.bufnr, "gitsigns_status_dict")
+ if ok then stats = res end
+ end
+ local counts = {
+ insert = stats.added > 0 and stats.added or nil,
+ change = stats.changed > 0 and stats.changed or nil,
+ delete = stats.removed > 0 and stats.removed or nil,
+ }
+ if not vim.tbl_isempty(counts) then
+ local fmt = opts.fmt or "%s"
+ local out = formatter(window, buffer, counts)
+ return out and fmt:format(out) or nil
+ else
+ -- el functions that return a
+ -- string must not return nil
+ return ""
+ end
+ end)
+end
+
+function M.git_changes_all(opts)
+ opts = opts or {}
+ local formatter = opts.formatter or git_changes_formatter(opts)
+ return el_sub.buf_autocmd("el_git_changes", "BufWritePost",
+ wrap_fnc(opts, function(window, buffer)
+ if not buffer or
+ not (buffer.bufnr > 0) or
+ vim.bo[buffer.bufnr].bufhidden ~= "" or
+ vim.bo[buffer.bufnr].buftype == "nofile" or
+ vim.fn.filereadable(buffer.name) ~= 1 then
+ return
+ end
+
+ local j = job:new {
+ command = "git",
+ args = { "diff", "--shortstat" },
+ -- makes no sense to run for one file as
+ -- 'file(s) changed' will always be 1
+ -- args = { "diff", "--shortstat", buffer.name },
+ cwd = vim.fn.fnamemodify(buffer.name, ":h"),
+ }
+
+ local ok, git_changes = pcall(function()
+ return formatter(window, buffer, vim.trim(j:sync()[1]))
+ end)
+
+ if ok then
+ local fmt = opts.fmt or "%s"
+ return git_changes and fmt:format(git_changes) or nil
+ end
+ end))
+end
+
+function M.lsp_srvname(opts)
+ local fmt = opts.fmt or "%s"
+ local icon = opts.icon or ""
+ local buf_clients = vim.lsp.buf_get_clients(0)
+ if not buf_clients or #buf_clients == 0 then
+ return ""
+ end
+ local names = ""
+ for i, c in ipairs(buf_clients) do
+ if i > 1 then names = names .. ", " end
+ names = names .. c.name
+ end
+ return icon..fmt:format(names)
+end
+
+local function diag_formatter(opts)
+ return function(_, buffer, counts)
+ local items = {}
+ local icons = {
+ ["errors"] = { opts.icon_err or "x", opts.hl_err or "DiagnosticError"},
+ ["warnings"] = { opts.icon_warn or "!", opts.hl_warn or "DiagnosticWarn"},
+ ["infos"] = { opts.icon_info or "i", opts.hl_info or "DiagnosticInfo"},
+ ["hints"] = { opts.icon_hint or "h", opts.hl_hint or "DiagnosticHint"},
+ }
+ for _, k in ipairs({ "errors", "warnings", "infos", "hints" }) do
+ if counts[k] > 0 then
+ table.insert(items,
+ set_hl(icons[k][2], ("%s:%s"):format(icons[k][1], counts[k])))
+ end
+ end
+ local fmt = opts.fmt or "%s"
+ if vim.tbl_isempty(items) then
+ return ""
+ else
+ return fmt:format(table.concat(items, " "))
+ end
+ end
+end
+
+local function get_buffer_counts(diagnostic, _, buffer)
+ local counts = { 0, 0, 0, 0 }
+ local diags = diagnostic.get(buffer.bufnr)
+ if diags and not vim.tbl_isempty(diags) then
+ for _, d in ipairs(diags) do
+ if tonumber(d.severity) then
+ counts[d.severity] = counts[d.severity] + 1
+ end
+ end
+ end
+ return {
+ errors = counts[1],
+ warnings = counts[2],
+ infos = counts[3],
+ hints = counts[4],
+ }
+end
+
+function M.diagnostics(opts)
+ opts = opts or {}
+ local formatter = opts.formatter or diag_formatter(opts)
+ return el_sub.buf_autocmd("el_buf_diagnostic", "LspAttach,DiagnosticChanged",
+ wrap_fnc(opts, function(window, buffer)
+ return formatter(window, buffer, get_buffer_counts(vim.diagnostic, window, buffer))
+ end))
+end
+
+function M.line(opts)
+ opts = opts or {}
+ local fmt = opts.fmt or "%s"
+ return wrap_fnc(opts, function(_, _)
+ local al = vim.api.nvim_buf_line_count(0)
+ local cl = vim.api.nvim_win_get_cursor(0)[1]
+ return (fmt):format(cl.."/"..al.." "..math.floor((cl / al) * 100).."%%")
+ end)
+end
+
+return M
diff --git a/lua/core/theme.lua b/lua/core/theme.lua
new file mode 100644
index 0000000..9d508f2
--- /dev/null
+++ b/lua/core/theme.lua
@@ -0,0 +1,76 @@
+local pickers = require("telescope.pickers")
+local finders = require("telescope.finders")
+local previewers = require("telescope.previewers")
+local conf = require("telescope.config").values
+local actions = require("telescope.actions")
+local action_set = require("telescope.actions.set")
+local action_state = require("telescope.actions.state")
+local misc = require('core.misc')
+
+local M = {}
+
+function M.switcher()
+ local bufnr = vim.api.nvim_get_current_buf()
+
+ -- show current buffer content in previewer
+ local colors = vim.fn.getcompletion('', 'color')
+ for k, v in pairs(colors) do
+ if v.find(v, '.ext') then
+ table.remove(colors, k)
+ break
+ end
+ end
+
+ -- our picker function: colors
+ pickers.new({
+ prompt_title = "Set Nvim Colorscheme",
+ finder = finders.new_table { results = colors },
+ sorter = conf.generic_sorter(),
+ previewer = previewers.new_buffer_previewer {
+ define_preview = function(self, entry)
+ -- add content
+ local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
+ vim.api.nvim_buf_set_lines(self.state.bufnr, 0, -1, false, lines)
+
+ -- add syntax highlighting in previewer
+ local ft = (vim.filetype.match { buf = bufnr } or "diff"):match "%w+"
+ require("telescope.previewers.utils").highlighter(self.state.bufnr, ft)
+ end
+ },
+
+ attach_mappings = function(prompt_bufnr, map)
+ -- reload theme while typing
+ vim.schedule(function()
+ vim.api.nvim_create_autocmd("TextChangedI", {
+ buffer = prompt_bufnr,
+ callback = function()
+ if action_state.get_selected_entry() then
+ misc.colorscheme(action_state.get_selected_entry()[1])
+ end
+ end,
+ })
+ end)
+
+ -- reload theme on cycling
+ actions.move_selection_previous:replace(function()
+ action_set.shift_selection(prompt_bufnr, -1)
+ misc.colorscheme(action_state.get_selected_entry()[1])
+ end)
+ actions.move_selection_next:replace(function()
+ action_set.shift_selection(prompt_bufnr, 1)
+ misc.colorscheme(action_state.get_selected_entry()[1])
+ end)
+
+ -- reload theme on selection
+ actions.select_default:replace(function()
+ if action_state.get_selected_entry() then
+ actions.close(prompt_bufnr)
+ misc.colorscheme(action_state.get_selected_entry()[1])
+ end
+ end)
+ return true
+ end,
+ }):find()
+end
+
+return M