332 lines
11 KiB
Lua
332 lines
11 KiB
Lua
-- Core options and settings
|
||
local opt = vim.opt
|
||
local g = vim.g
|
||
local fn = vim.fn
|
||
|
||
-- Disable deprecated API warnings
|
||
vim.deprecate = function() end
|
||
|
||
-- Set leader key before lazy
|
||
g.mapleader = " "
|
||
g.maplocalleader = " "
|
||
|
||
-- General settings
|
||
opt.mouse = "a" -- Enable mouse
|
||
opt.clipboard = "unnamedplus" -- Use system clipboard
|
||
opt.swapfile = false -- Don't create swap files
|
||
opt.completeopt = "menuone,noselect" -- Better completion
|
||
opt.undofile = true -- Persistent undo
|
||
opt.undodir = vim.fn.stdpath("data") .. "/undodir"
|
||
opt.autoread = true -- Auto-reload files when changed externally
|
||
|
||
-- Suppress startup messages to avoid "Press ENTER" prompts
|
||
opt.shortmess = "aoOtTIcFWS" -- Suppress various messages
|
||
opt.cmdheight = 1 -- Set command height to avoid prompts
|
||
|
||
-- Search settings
|
||
opt.ignorecase = true -- Case insensitive search
|
||
opt.smartcase = true -- Case sensitive when uppercase
|
||
opt.hlsearch = false -- Don't highlight search results
|
||
opt.incsearch = true -- Incremental search
|
||
|
||
-- Indentation
|
||
opt.expandtab = true -- Use spaces instead of tabs
|
||
opt.shiftwidth = 2 -- Number of spaces for indentation
|
||
opt.tabstop = 2 -- Number of spaces for tabs
|
||
opt.softtabstop = 2 -- Number of spaces for soft tabs
|
||
opt.autoindent = true -- Auto indent
|
||
opt.smartindent = true -- Smart indent
|
||
|
||
-- Performance optimizations
|
||
opt.updatetime = 100 -- Faster completion (reduced from 250)
|
||
opt.timeoutlen = 200 -- Faster key sequence completion (reduced from 300)
|
||
opt.redrawtime = 1500 -- Allow more time for loading syntax
|
||
opt.synmaxcol = 200 -- Only highlight the first 200 columns (conservative for performance)
|
||
opt.maxmempattern = 1000 -- Reduce memory for pattern matching
|
||
opt.hidden = true -- Allow switching buffers without saving
|
||
opt.scrolljump = 1 -- Minimal number of screen lines to scroll
|
||
opt.scrolloff = 3 -- Keep 3 lines above/below cursor (reduced from 8)
|
||
opt.sidescrolloff = 3 -- Keep 3 columns left/right of cursor (reduced from 8)
|
||
|
||
-- Syntax loading optimizations
|
||
opt.syntax = "on" -- Enable syntax highlighting
|
||
opt.lazyredraw = false -- Don't use lazy redraw (can cause issues)
|
||
opt.foldlevel = 99 -- Don't fold by default
|
||
|
||
-- Filetype plugin optimizations
|
||
opt.filetype = "on" -- Enable filetype detection
|
||
opt.modeline = false -- Disable modeline for security and performance
|
||
opt.modelines = 0 -- Disable modelines
|
||
|
||
-- Matchparen optimizations
|
||
g.matchparen_timeout = 100 -- Reduce from default 300ms
|
||
g.matchparen_insert_timeout = 50 -- Reduce from default 100ms
|
||
g.matchparen_disable_cursor_hl = 0 -- Keep cursor highlighting but optimize
|
||
|
||
-- UI settings
|
||
opt.number = true -- Show line numbers
|
||
opt.relativenumber = true -- Show relative line numbers
|
||
opt.cursorline = false -- Disable cursor line highlighting for performance
|
||
opt.cursorcolumn = false -- Don't highlight current column
|
||
opt.signcolumn = "yes" -- Always show sign column
|
||
|
||
-- =============================================================================
|
||
-- NATIVE AUTO WRAPPER CONFIGURATION
|
||
-- =============================================================================
|
||
|
||
-- Text wrapping settings
|
||
opt.wrap = true -- Enable visual line wrapping (wraps based on window width)
|
||
opt.linebreak = true -- Break lines at word boundaries
|
||
opt.breakindent = true -- Preserve indentation in wrapped lines
|
||
opt.showbreak = "↪ " -- Show break indicator
|
||
opt.breakindentopt = "shift:2" -- Indent wrapped lines by 2 spaces
|
||
|
||
-- Text width and formatting
|
||
opt.textwidth = 0 -- Disable hard wrapping (0 = no limit, wraps based on window width)
|
||
opt.colorcolumn = "" -- Disable color column (or set to a high value if you want a guide)
|
||
opt.formatoptions = "jcroqln" -- Format options (removed 't' to disable auto-wrap based on textwidth)
|
||
|
||
-- Format options settings
|
||
-- Note: 't' option removed - we want visual wrapping only, not hard line breaks
|
||
opt.formatoptions:append("c") -- Auto-wrap comments using textwidth (only applies if textwidth > 0)
|
||
opt.formatoptions:append("r") -- Auto-wrap comments when pressing Enter
|
||
opt.formatoptions:append("o") -- Auto-wrap comments when pressing 'o' or 'O'
|
||
opt.formatoptions:append("q") -- Allow formatting of comments with 'gq'
|
||
opt.formatoptions:append("l") -- Long lines are not broken in insert mode
|
||
opt.formatoptions:append("n") -- Recognize numbered lists
|
||
opt.formatoptions:append("j") -- Remove comment leader when joining lines
|
||
|
||
-- Scroll settings for wrapped text
|
||
opt.showmatch = true -- Show matching brackets
|
||
opt.matchtime = 2 -- How long to show matching brackets
|
||
|
||
-- Folding (indent-based is generally faster than syntax-based)
|
||
opt.foldmethod = "indent" -- Fold based on indentation
|
||
opt.foldnestmax = 10 -- Maximum nesting level
|
||
|
||
-- Backup and swap
|
||
opt.backup = false -- Don't create backup files
|
||
opt.writebackup = false -- Don't create backup files while writing
|
||
opt.swapfile = false -- Don't create swap files
|
||
|
||
-- Terminal
|
||
opt.termguicolors = true -- Enable true color support
|
||
opt.background = "dark" -- Set background to dark
|
||
|
||
-- File encoding
|
||
opt.encoding = "utf-8" -- Set encoding to UTF-8
|
||
opt.fileencoding = "utf-8" -- Set file encoding to UTF-8
|
||
|
||
-- Wildmenu
|
||
opt.wildmenu = true -- Enable wildmenu
|
||
opt.wildmode = "longest:full,full" -- Wildmenu mode
|
||
|
||
-- Split behavior
|
||
opt.splitbelow = true -- Split below when creating horizontal splits
|
||
opt.splitright = true -- Split right when creating vertical splits
|
||
|
||
-- Conceal
|
||
opt.conceallevel = 2 -- Conceal certain characters
|
||
|
||
-- Provider configurations
|
||
g.loaded_perl_provider = 0 -- Disable Perl provider
|
||
g.loaded_ruby_provider = 0 -- Disable Ruby provider (optional)
|
||
|
||
-- Python provider configuration
|
||
|
||
g.python3_host_prog = fn.expand("~/.local/pipx/venvs/pynvim/bin/python")
|
||
|
||
-- Clipboard provider optimization (macOS)
|
||
g.clipboard = {
|
||
name = "macOS-clipboard",
|
||
copy = {
|
||
["+"] = "pbcopy",
|
||
["*"] = "pbcopy",
|
||
},
|
||
paste = {
|
||
["+"] = "pbpaste",
|
||
["*"] = "pbpaste",
|
||
},
|
||
}
|
||
|
||
-- Lua specific settings
|
||
opt.runtimepath:append(vim.fn.stdpath("config") .. "/lua")
|
||
|
||
-- Custom file type associations
|
||
vim.filetype.add({
|
||
extension = {
|
||
strata = "html",
|
||
sts = "typescript",
|
||
},
|
||
})
|
||
|
||
-- Better diff
|
||
opt.diffopt:append("algorithm:patience")
|
||
opt.diffopt:append("indent-heuristic")
|
||
|
||
-- Better grep
|
||
opt.grepprg = "rg --vimgrep --smart-case"
|
||
opt.grepformat = "%f:%l:%c:%m"
|
||
|
||
-- Better listchars
|
||
opt.list = true
|
||
opt.listchars = {
|
||
tab = "▸ ",
|
||
trail = "·",
|
||
extends = "❯",
|
||
precedes = "❮",
|
||
nbsp = "␣",
|
||
}
|
||
|
||
-- Better fillchars
|
||
opt.fillchars = {
|
||
horiz = "━",
|
||
horizup = "┻",
|
||
horizdown = "┳",
|
||
vert = "┃",
|
||
vertleft = "┫",
|
||
vertright = "┣",
|
||
verthoriz = "╋",
|
||
}
|
||
|
||
-- Disable builtin plugins
|
||
local disabled_built_ins = {
|
||
"netrw",
|
||
"netrwPlugin",
|
||
"netrwSettings",
|
||
"netrwFileHandlers",
|
||
"gzip",
|
||
"zip",
|
||
"zipPlugin",
|
||
"tar",
|
||
"tarPlugin",
|
||
"getscript",
|
||
"getscriptPlugin",
|
||
"vimball",
|
||
"vimballPlugin",
|
||
"2html_plugin",
|
||
"logipat",
|
||
"rrhelper",
|
||
"spellfile_plugin",
|
||
"matchit",
|
||
}
|
||
|
||
for _, plugin in pairs(disabled_built_ins) do
|
||
g["loaded_" .. plugin] = 1
|
||
end
|
||
|
||
-- =============================================================================
|
||
-- AUTO-RELOAD FILES WHEN CHANGED EXTERNALLY
|
||
-- =============================================================================
|
||
|
||
-- Trigger checktime when switching buffers or focusing Neovim
|
||
vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" }, {
|
||
pattern = "*",
|
||
callback = function()
|
||
if vim.fn.mode() ~= "c" then
|
||
vim.cmd("checktime")
|
||
end
|
||
end,
|
||
})
|
||
|
||
-- Notify when file is reloaded
|
||
vim.api.nvim_create_autocmd("FileChangedShellPost", {
|
||
pattern = "*",
|
||
callback = function()
|
||
vim.notify("File changed on disk. Buffer reloaded.", vim.log.levels.WARN)
|
||
end,
|
||
})
|
||
|
||
-- =============================================================================
|
||
-- OPTIMIZED AUTO WRAPPER AUTOCMDS
|
||
-- =============================================================================
|
||
|
||
-- Consolidated auto-wrapping configuration
|
||
-- Note: textwidth is set to 0 globally to allow visual wrapping based on window width
|
||
vim.api.nvim_create_autocmd("FileType", {
|
||
pattern = "*",
|
||
callback = function()
|
||
local filetype = vim.bo.filetype
|
||
local opt = vim.opt_local
|
||
|
||
-- Text/documentation files - visual wrapping only (no hard breaks)
|
||
if vim.tbl_contains({ "text", "markdown", "gitcommit", "mail", "help", "man" }, filetype) then
|
||
opt.textwidth = 0 -- Disable hard wrapping, use visual wrapping based on window width
|
||
opt.wrap = true
|
||
opt.linebreak = true
|
||
-- Removed 't' option - we want visual wrapping only, not hard line breaks
|
||
end
|
||
|
||
-- Code files - visual wrapping only (no hard breaks)
|
||
if vim.tbl_contains({ "lua", "javascript", "typescript", "python", "java", "cpp", "c", "rust", "go" }, filetype) then
|
||
opt.textwidth = 0 -- Disable hard wrapping, use visual wrapping based on window width
|
||
opt.formatoptions:append("c") -- Auto-wrap comments (only if textwidth > 0, so this won't apply)
|
||
opt.formatoptions:append("r") -- Auto-wrap comments with leader
|
||
opt.formatoptions:append("o") -- Auto-wrap comments with 'o'
|
||
opt.formatoptions:append("q") -- Allow formatting of comments with 'gq'
|
||
end
|
||
|
||
-- Configuration files - visual wrapping only (no hard breaks)
|
||
if vim.tbl_contains({ "conf", "config", "ini", "toml", "yaml", "json" }, filetype) then
|
||
opt.textwidth = 0 -- Disable hard wrapping, use visual wrapping based on window width
|
||
opt.formatoptions:append("c") -- Auto-wrap comments (only if textwidth > 0, so this won't apply)
|
||
end
|
||
end,
|
||
})
|
||
|
||
-- =============================================================================
|
||
-- MODERN UI: GLOBAL ROUNDED BORDERS
|
||
-- =============================================================================
|
||
|
||
-- Rounded border style for all floating windows
|
||
local border = "rounded"
|
||
|
||
-- Override default floating window border
|
||
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { border = border })
|
||
vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = border })
|
||
|
||
-- Diagnostic floating window border
|
||
vim.diagnostic.config({
|
||
float = {
|
||
border = border,
|
||
source = "always",
|
||
header = "",
|
||
prefix = "",
|
||
},
|
||
})
|
||
|
||
-- Set global float border highlight
|
||
vim.api.nvim_set_hl(0, "FloatBorder", { fg = "#7aa2f7", bg = "NONE" })
|
||
vim.api.nvim_set_hl(0, "NormalFloat", { bg = "#1a1b26" })
|
||
|
||
-- Modern cursor line (subtle highlight)
|
||
vim.api.nvim_set_hl(0, "CursorLine", { bg = "#292e42" })
|
||
vim.api.nvim_set_hl(0, "CursorLineNr", { fg = "#7aa2f7", bold = true })
|
||
|
||
-- =============================================================================
|
||
-- WORD COUNTER (EXCLUDING SYMBOLS)
|
||
-- =============================================================================
|
||
|
||
-- Function to count words excluding symbols
|
||
local function count_words_no_symbols()
|
||
local lines = vim.api.nvim_buf_get_lines(0, 0, -1, false)
|
||
local text = table.concat(lines, " ")
|
||
-- Remove all non-alphanumeric characters except spaces
|
||
local clean_text = text:gsub("[^%w%s]", "")
|
||
-- Count words (sequences of alphanumeric characters)
|
||
local count = 0
|
||
for _ in clean_text:gmatch("%w+") do
|
||
count = count + 1
|
||
end
|
||
return count
|
||
end
|
||
|
||
-- Make it globally accessible for statusline
|
||
_G.word_count_no_symbols = count_words_no_symbols
|
||
|
||
-- Create user command to display word count
|
||
vim.api.nvim_create_user_command("WordCount", function()
|
||
local count = count_words_no_symbols()
|
||
vim.notify("Words (excluding symbols): " .. count, vim.log.levels.INFO)
|
||
end, { desc = "Count words excluding symbols" })
|