diff --git a/Dockerfile b/Dockerfile index 7c5511d..b319f81 100644 --- a/Dockerfile +++ b/Dockerfile @@ -1,54 +1,40 @@ FROM homebrew/ubuntu24.04 -ARG username="user" -ARG password="password" - # Install requirements -RUN apt-get update && \ - apt-get install -y \ - build-essential \ - curl \ - wget \ - file \ - git \ - locales \ - locales-all \ - zsh \ - libssl-dev \ - zlib1g-dev \ - libbz2-dev \ - libreadline-dev \ - libsqlite3-dev \ - llvm \ - libncurses5-dev \ - libncursesw5-dev \ - xz-utils \ - tk-dev \ - libffi-dev \ - liblzma-dev \ - python3-openssl -RUN locale-gen ja_JP.UTF-8 && update-locale -RUN apt-get autoremove -y && \ - apt-get clean && \ +RUN sudo apt-get update && \ + sudo apt-get install -y \ + build-essential \ + curl \ + wget \ + file \ + git \ + locales \ + locales-all \ + zsh \ + libssl-dev \ + zlib1g-dev \ + libbz2-dev \ + libreadline-dev \ + libsqlite3-dev \ + llvm \ + libncurses5-dev \ + libncursesw5-dev \ + xz-utils \ + tk-dev \ + libffi-dev \ + liblzma-dev \ + python3-openssl +RUN sudo apt-get autoremove -y && \ + sudo apt-get clean && \ rm -rf /usr/local/src/* -RUN brew install tmux anyenv neovim +RUN brew install tmux anyenv neovim hub -# Setup user -ENV USER $username -ENV HOME /home/${USER} +# Set up shell ENV SHELL /usr/bin/zsh -# Create user -RUN useradd -m ${USER} && \ - gpasswd -a ${USER} sudo && \ - echo "${USER}:${password}" | chpasswd -RUN chown -R ${USER} /home/linuxbrew/.linuxbrew - # Install dotfiles WORKDIR ${HOME} COPY ./ ./.dotfiles -RUN chown -R ${USER} ${HOME}/.dotfiles -USER ${USER} RUN cd .dotfiles && make CMD ["/bin/zsh"] diff --git a/Makefile b/Makefile index 8ca6518..99fde97 100644 --- a/Makefile +++ b/Makefile @@ -7,9 +7,9 @@ DOCKER_CONTAINER_NAME = dotfiles DOCKERFILE_PATH = $(PWD)/Dockerfile .PHONY: all brew \ - apps anyenv_app fzf_app git_app nvim_app poetry_app tmux_app zsh_app efm_app \ + apps anyenv_app fzf_app git_app nvim_app tmux_app zsh_app efm_app \ languages clang golang node python rust nim ruby vala zig crystal \ - configs editorconfig git nvim poetry tmux zsh efm \ + configs editorconfig git nvim tmux zsh efm \ docker docker_attach docker_build docker_run docker_stop \ clean editorconfig_clean git_clean nvim_clean tmux_clean zsh_clean @@ -36,9 +36,6 @@ git_app: nvim_app: $(PWD)/nvim/bin/install.sh -poetry_app: python - $(PWD)/poetry/bin/install.sh - tmux_app: $(PWD)/tmux/bin/install.sh @@ -91,7 +88,7 @@ lua: # CONFIGS # -configs: git editorconfig nvim poetry tmux zsh +configs: git editorconfig nvim tmux zsh editorconfig: $(PWD)/editorconfig/bin/setup.sh @@ -102,9 +99,6 @@ git: git_app nvim: node nvim_app $(PWD)/nvim/bin/setup.sh -poetry: poetry_app - $(PWD)/poetry/bin/setup.sh - tmux: tmux_app $(PWD)/tmux/bin/setup.sh diff --git a/bin/python_install.sh b/bin/python_install.sh index c243785..e2a296a 100755 --- a/bin/python_install.sh +++ b/bin/python_install.sh @@ -19,7 +19,7 @@ fi if (type "pyenv" > /dev/null 2>&1); then # Install latest conda - PYTHON_VERSION="3.11.6" + PYTHON_VERSION="3.13" pyenv install $PYTHON_VERSION pyenv rehash pyenv global $PYTHON_VERSION @@ -29,4 +29,4 @@ fi python --version pip --version -pip install flake8 mypy black isort refurb 'python-lsp-server[mypy,flake8,isort,black]' +pip install refurb diff --git a/editorconfig/conf.d/editorconfig b/editorconfig/conf.d/editorconfig index ead5928..7144c1e 100644 --- a/editorconfig/conf.d/editorconfig +++ b/editorconfig/conf.d/editorconfig @@ -20,6 +20,9 @@ indent_size = 2 [*.{html,xml}] indent_size = 2 +[*.{css,scss,sass}] +indent_size = 2 + [*.{json,jsonnet,libsonnet,yml,yaml}] indent_size = 2 @@ -41,5 +44,8 @@ indent_size = 2 [*.tsv] indent_style = tab +[*.plist] +indent_style = tab + [Makefile] indent_style = tab diff --git a/nvim/bin/setup.sh b/nvim/bin/setup.sh index 5026992..57e4a48 100755 --- a/nvim/bin/setup.sh +++ b/nvim/bin/setup.sh @@ -1,19 +1,9 @@ #!/bin/bash -rm -rf $HOME/.config/nvim $HOME/.config/coc $HOME/.cache/dein +rm -rf $HOME/.config/nvim mkdir -p $HOME/.config/nvim ln -s `pwd`/nvim/conf.d/init.lua $HOME/.config/nvim/init.lua ln -s `pwd`/nvim/conf.d/lua $HOME/.config/nvim/lua -ln -s `pwd`/nvim/conf.d/coc-settings.json $HOME/.config/nvim/coc-settings.json nvim --headless -u $HOME/.config/nvim/init.lua +qall - -# Install coc.nvim extensions -if (type "anyenv" > /dev/null 2>&1); then - eval "$(anyenv init -)" -fi -mkdir -p $HOME/.config/coc/extensions -cp `pwd`/nvim/conf.d/coc-package.json $HOME/.config/coc/extensions/package.json -cd $HOME/.config/coc/extensions -npm install --global-style --ignore-scripts --no-bin-links --no-package-lock --only=prod diff --git a/nvim/conf.d/coc-package.json b/nvim/conf.d/coc-package.json deleted file mode 100644 index e47620f..0000000 --- a/nvim/conf.d/coc-package.json +++ /dev/null @@ -1,18 +0,0 @@ -{ - "dependencies": { - "coc-clangd": "latest", - "coc-docker": "latest", - "coc-go": "latest", - "coc-html": "latest", - "coc-json": "latest", - "coc-rust-analyzer": "latest", - "coc-sh": "latest", - "coc-tsserver": "latest", - "coc-yaml": "latest", - "coc-xml": "latest", - "coc-svelte": "latest", - "coc-markdownlint": "latest", - "coc-solargraph": "latest", - "coc-zig": "latest" - } -} diff --git a/nvim/conf.d/coc-settings.json b/nvim/conf.d/coc-settings.json deleted file mode 100644 index b1b6dde..0000000 --- a/nvim/conf.d/coc-settings.json +++ /dev/null @@ -1,100 +0,0 @@ -{ - "suggest.noselect": true, - "python.venvPath": ".venv", - "python.linting.flake8Enabled": true, - "python.linting.mypyEnabled": true, - "pylsp.builtin.installExtrasArgs": ["flake8"], - "pylsp.builtin.enableInstallPylspMypy": true, - "pylsp.builtin.enableInstallPylsIsort": true, - "pylsp.builtin.enableInstallPythonLspBlack": true, - "pylsp.plugins.pycodestyle.enabled": false, - "pylsp.plugins.pyflakes.enabled": false, - "tsserver.enable": true, - "tsserver.useLocalTsdk": true, - "svelte.enable-ts-plugin": true, - "zig.enabled": true, - "zig.path": "zls", - "ruff.enable": false, - "pyright.enable": false, - "languageserver": { - "golang": { - "command": "gopls", - "rootPatterns": ["go.mod"], - "filetypes": ["go"] - }, - "nim": { - "command": "nimlsp", - "filetypes": ["nim"] - }, - "vala": { - "command": "vala-language-server", - "filetypes": ["vala", "genie"] - }, - "tailwind-lsp": { - "command": "tailwindcss-language-server", - "args": ["--stdio"], - - "filetypes": [ - "javascript", - "javascriptreact", - "typescript", - "typescriptreact", - "svelte" - ], - - "rootPatterns": [ - "tailwind.config.cjs", - "tailwind.config.js", - "tailwind.config.ts", - "postcss.config.cts", - "postcss.config.js", - "postcss.config.ts", - "package.json", - "node_modules", - ".git" - ], - "settings": { - "tailwindCSS": { - "validate": true, - "lint": { - "cssConflict": "warning", - "invalidApply": "error", - "invalidScreen": "error", - "invalidVariant": "error", - "invalidConfigPath": "error", - "invalidTailwindDirective": "error", - "recommendedVariantOrder": "warning" - }, - "classAttributes": ["class", "className", "classList", "ngClass"], - "experimental": {} - } - } - }, - "efm": { - "command": "efm-langserver", - "args": [], - "filetypes": ["*"] - }, - "crystal": { - "command": "crystalline", - "args": [ - "--stdio" - ], - "filetypes": [ - "crystal" - ], - "rootPatterns": ["shard.yml"] - }, - "terraform": { - "command": "terraform-ls", - "args": ["serve"], - "filetypes": ["terraform", "tf"], - "initializationOptions": {} - }, - "jsonnet": { - "command": "jsonnet-language-server", - "args": [], - "filetypes": ["jsonnet", "libsonnet"] - } - } -} diff --git a/nvim/conf.d/init.lua b/nvim/conf.d/init.lua index 98e9e2b..a735d54 100644 --- a/nvim/conf.d/init.lua +++ b/nvim/conf.d/init.lua @@ -1,2 +1,5 @@ -require("base") -require("plugins") +require("config.base") +require("config.lazy") + +vim.o.exrc = true +vim.o.secure = true diff --git a/nvim/conf.d/lua/base.lua b/nvim/conf.d/lua/config/base.lua similarity index 68% rename from nvim/conf.d/lua/base.lua rename to nvim/conf.d/lua/config/base.lua index 46c20f6..8c673fd 100644 --- a/nvim/conf.d/lua/base.lua +++ b/nvim/conf.d/lua/config/base.lua @@ -26,18 +26,14 @@ vim.api.nvim_create_autocmd({ "BufLeave", "FocusLost", "InsertEnter", "WinLeave" -- SWAP FILE vim.opt.swapfile = false --- KEY MAPPINGS -vim.g.mapleader = " " -vim.api.nvim_set_keymap("i", "", "", { noremap = true }) -vim.api.nvim_set_keymap("i", "jj", "", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("i", "kk", "", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("i", "", "j", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("i", "", "k", { noremap = true, silent = true }) -vim.api.nvim_set_keymap("n", "", ":nohlsearch", { noremap = true }) -vim.api.nvim_set_keymap("n", "", ":set relativenumber!", { noremap = true }) - --- FOR TERMINAL -vim.api.nvim_set_keymap("t", "", "", { noremap = true }) +-- DIAGNOSTIC +vim.diagnostic.config({ + virtual_text = true, + severity_sort = true, + float = { + source = "always", + }, +}) -- INDENTATION AND FORMATTING vim.opt.tabstop = 4 @@ -53,9 +49,22 @@ vim.opt.ignorecase = true vim.opt.smartcase = true vim.opt.hlsearch = true +-- KEY MAPPINGS +vim.g.mapleader = " " +vim.keymap.set({ "n", "i", "v" }, "", "", { noremap = true, silent = true }) +vim.api.nvim_set_keymap("i", "jj", "", { noremap = true, silent = true }) +vim.api.nvim_set_keymap("i", "kk", "", { noremap = true, silent = true }) +vim.api.nvim_set_keymap("i", "", "j", { noremap = true, silent = true }) +vim.api.nvim_set_keymap("i", "", "k", { noremap = true, silent = true }) +vim.api.nvim_set_keymap("n", "", ":nohlsearch", { noremap = true }) +vim.api.nvim_set_keymap("n", "", ":set relativenumber!", { noremap = true }) + +-- FOR TERMINAL +vim.api.nvim_set_keymap("t", "", "", { noremap = true }) + -- CURSORLINE AND CURSORCOLUMN vim.opt.cursorline = true -vim.opt.cursorcolumn = true +vim.opt.cursorcolumn = false -- MOUSE AND SPELLCHECK vim.opt.mouse = "a" @@ -72,32 +81,6 @@ if vim.fn.has("termguicolors") == 1 then end vim.env.NVIM_TUI_ENABLE_TRUE_COLOR = 1 --- FILETYPES -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.jsonnet", - command = "setfiletype jsonnet", -}) -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.libsonnet", - command = "setfiletype libsonnet", -}) -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.nim", - command = "setfiletype nim", -}) -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.nimble", - command = "setfiletype nimble", -}) -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.hsh", - command = "setfiletype hush", -}) -vim.api.nvim_create_autocmd({ "BufNewFile", "BufRead" }, { - pattern = "*.cr", - command = "setfiletype crystal", -}) - -- DISABLE JSON CONCEAL vim.g.vim_json_conceal = 0 @@ -107,12 +90,5 @@ vim.cmd([[ match DoubleByteSpace / / ]]) --- TERMINAL -vim.api.nvim_create_autocmd({ "TermOpen" }, { - pattern = "*", - command = "startinsert", -}) -vim.api.nvim_create_autocmd({ "TermOpen" }, { - pattern = "*", - command = "setlocal nonumber norelativenumber", -}) +-- MISC +vim.opt.wrap = false diff --git a/nvim/conf.d/lua/config/lazy.lua b/nvim/conf.d/lua/config/lazy.lua new file mode 100644 index 0000000..f5ee74c --- /dev/null +++ b/nvim/conf.d/lua/config/lazy.lua @@ -0,0 +1,35 @@ +-- Bootstrap lazy.nvim +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" +if not (vim.uv or vim.loop).fs_stat(lazypath) then + local lazyrepo = "https://github.com/folke/lazy.nvim.git" + local out = vim.fn.system({ "git", "clone", "--filter=blob:none", "--branch=stable", lazyrepo, lazypath }) + if vim.v.shell_error ~= 0 then + vim.api.nvim_echo({ + { "Failed to clone lazy.nvim:\n", "ErrorMsg" }, + { out, "WarningMsg" }, + { "\nPress any key to exit..." }, + }, true, {}) + vim.fn.getchar() + os.exit(1) + end +end +vim.opt.rtp:prepend(lazypath) + +-- Make sure to setup `mapleader` and `maplocalleader` before +-- loading lazy.nvim so that mappings are correct. +-- This is also a good place to setup other settings (vim.opt) +vim.g.mapleader = " " +vim.g.maplocalleader = "\\" + +-- Setup lazy.nvim +require("lazy").setup({ + spec = { + -- import your plugins + { import = "plugins" }, + }, + -- Configure any other settings here. See the documentation for more details. + -- colorscheme that will be used when installing plugins. + install = { colorscheme = { "habamax" } }, + -- automatically check for plugin updates + checker = { enabled = true }, +}) diff --git a/nvim/conf.d/lua/plugins.lua b/nvim/conf.d/lua/plugins.lua deleted file mode 100644 index ccdad58..0000000 --- a/nvim/conf.d/lua/plugins.lua +++ /dev/null @@ -1,289 +0,0 @@ -local ensure_packer = function() - local fn = vim.fn - local install_path = fn.stdpath("data") .. "/site/pack/packer/start/packer.nvim" - if fn.empty(fn.glob(install_path)) > 0 then - fn.system({ "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path }) - vim.cmd([[packadd packer.nvim]]) - return true - end - return false -end - -local packer_bootstrap = ensure_packer() - -return require("packer").startup(function(use) - use({ "wbthomason/packer.nvim" }) - - use({ "editorconfig/editorconfig-vim" }) - - use({ "nvim-treesitter/nvim-treesitter", run = ":TSUpdate" }) - - use({ - "neoclide/coc.nvim", - branch = "release", - config = function() - local keyset = vim.keymap.set - keyset("n", "gd", "(coc-definition)", { silent = true }) - keyset("n", "gy", "(coc-type-definition)", { silent = true }) - keyset("n", "gi", "(coc-implementation)", { silent = true }) - keyset("n", "gr", "(coc-references)", { silent = true }) - end, - }) - - use({ - "nvim-lualine/lualine.nvim", - config = function() - local colors_dark = { - blue = "#839bd3", - cyan = "#739389", - black = "#080616", - white = "#dbd7bc", - red = "#b44947", - violet = "#917fb4", - grey = "#717169", - } - local colors_light = { - blue = "#839bd3", - cyan = "#597b75", - black = "#1f1f28", - white = "#f2ecbc", - red = "#c84053", - violet = "#b35b79", - grey = "#8a8980", - } - - local colors = colors_dark - - local kanagawa_theme = { - normal = { - a = { fg = colors.black, bg = colors.violet }, - b = { fg = colors.white, bg = colors.grey }, - c = { fg = colors.white }, - }, - - insert = { a = { fg = colors.black, bg = colors.blue } }, - visual = { a = { fg = colors.black, bg = colors.cyan } }, - replace = { a = { fg = colors.black, bg = colors.red } }, - - inactive = { - a = { fg = colors.white, bg = colors.black }, - b = { fg = colors.white, bg = colors.black }, - c = { fg = colors.white }, - }, - } - - require("lualine").setup({ - options = { - theme = kanagawa_theme, - component_separators = "", - section_separators = { left = "", right = "" }, - }, - sections = { - lualine_a = { { "mode", separator = { left = "" }, right_padding = 2 } }, - lualine_b = { "filename", "branch" }, - lualine_c = { - "%=", --[[ add your center compoentnts here in place of this comment ]] - }, - lualine_x = {}, - lualine_y = { "filetype", "progress" }, - lualine_z = { - { "location", separator = { right = "" }, left_padding = 2 }, - }, - }, - inactive_sections = { - lualine_a = { "filename" }, - lualine_b = {}, - lualine_c = {}, - lualine_x = {}, - lualine_y = {}, - lualine_z = { "location" }, - }, - tabline = {}, - extensions = {}, - }) - end, - requires = { "nvim-tree/nvim-web-devicons", opt = true }, - }) - - use({ - "akinsho/bufferline.nvim", - tag = "*", - requires = "nvim-tree/nvim-web-devicons", - config = function() - require("bufferline").setup({ - options = { - numbers = "ordinal", - diagnostics = "coc", - separator_style = "slant", - diagnostics_indicator = function(count, level) - local icon = level:match("error") and " " or "" - return " " .. icon - end, - }, - }) - vim.api.nvim_set_keymap("n", "", ":BufferLineCycleNext", { noremap = true }) - vim.api.nvim_set_keymap("n", "", ":BufferLineCyclePrev", { noremap = true }) - end, - }) - - use({ - "rebelot/kanagawa.nvim", - config = function() - vim.cmd("colorscheme kanagawa") - require("kanagawa").setup({ - backgronnd = { - dark = "wave", - light = "lotus", - }, - }) - end, - }) - - use({ - "nvim-telescope/telescope.nvim", - tag = "0.1.8", - requires = { { "nvim-lua/plenary.nvim" } }, - config = function() - require("telescope").setup({}) - local builtin = require("telescope.builtin") - vim.keymap.set("n", "", builtin.find_files, { desc = "Telescope find files" }) - vim.keymap.set("n", "", builtin.live_grep, { desc = "Telescope live grep" }) - vim.keymap.set("n", "fb", builtin.buffers, { desc = "Telescope buffers" }) - vim.keymap.set("n", "fh", builtin.help_tags, { desc = "Telescope help tags" }) - end, - }) - - use({ - "stevearc/conform.nvim", - config = function() - require("conform").setup({ - formatters_by_ft = { - c = { "clang-format" }, - cpp = { "clang-format" }, - crystal = { "crystal" }, - go = { "goimports", "gofmt" }, - lua = { "stylua" }, - nim = { "nimpretty" }, - python = function(bufnr) - if require("conform").get_formatter_info("ruff_format", bufnr).available then - return { "ruff_format" } - else - return { "isort", "black" } - end - end, - rust = { "rustfmt", lsp_format = "fallback" }, - terraform = { "terraform_fmt" }, - ["*"] = { "trim_whitespace", "trim_newlines" }, - }, - format_on_save = { - lsp_format = "fallback", - timeout_ms = 500, - }, - format_after_save = { - lsp_format = "fallback", - }, - }) - end, - }) - - use({ - "NeogitOrg/neogit", - requires = "sindrets/diffview.nvim", - config = function() - require("neogit").setup({}) - end, - }) - - use({ - "lewis6991/gitsigns.nvim", - config = function() - require("gitsigns").setup({}) - end, - }) - - use({ - "petertriho/nvim-scrollbar", - config = function() - require("scrollbar").setup({}) - end, - }) - - use({ - "kevinhwang91/nvim-hlslens", - config = function() - require("scrollbar.handlers.search").setup({}) - end, - }) - - use({ - "norcalli/nvim-colorizer.lua", - config = function() - require("colorizer").setup({ - "lua", - "css", - "html", - "javascript", - "typescript", - }) - end, - }) - - use({ "github/copilot.vim" }) - - use({ - "windwp/nvim-autopairs", - event = "InsertEnter", - config = function() - require("nvim-autopairs").setup({}) - end, - }) - - use({ - "nvim-neo-tree/neo-tree.nvim", - branch = "v3.x", - requires = { - "nvim-lua/plenary.nvim", - "nvim-tree/nvim-web-devicons", - "MunifTanjim/nui.nvim", - }, - config = function() - vim.api.nvim_set_keymap("n", "", ":Neotree toggle", { noremap = true }) - end, - }) - - use({ "vimpostor/vim-lumen" }) - - use({ - "google/vim-jsonnet", - opt = true, - ft = { "jsonnet" }, - }) - - use({ - "akinsho/toggleterm.nvim", - tag = "*", - config = function() - require("toggleterm").setup({ - size = 10, - hide_numbers = true, - start_in_insert = true, - close_on_exit = true, - direction = "horizontal", - shade_terminals = false, - }) - vim.api.nvim_create_user_command("T", function(args) - vim.cmd("ToggleTerm" .. args.args) - end, { nargs = "*" }) - end, - }) - - use({ - "iamcco/markdown-preview.nvim", - ft = { "markdown", "pandoc.markdown", "rmarkdown" }, - run = "cd app && npx --yes yarn install", - }) - - if packer_bootstrap then - require("packer").sync() - end -end) diff --git a/nvim/conf.d/lua/plugins/completion.lua b/nvim/conf.d/lua/plugins/completion.lua new file mode 100644 index 0000000..4e9852c --- /dev/null +++ b/nvim/conf.d/lua/plugins/completion.lua @@ -0,0 +1,20 @@ +return { + { + "windwp/nvim-autopairs", + event = "InsertEnter", + config = true, + }, + { + "saghen/blink.cmp", + version = "1.*", + opts = { + keymap = { preset = "default" }, + appearance = { nerd_font_variant = "mono" }, + completion = { documentation = { auto_show = true } }, + sources = { default = { "lsp", "path", "buffer" } }, + }, + }, + { + "github/copilot.vim", + }, +} diff --git a/nvim/conf.d/lua/plugins/finder.lua b/nvim/conf.d/lua/plugins/finder.lua new file mode 100644 index 0000000..1be1107 --- /dev/null +++ b/nvim/conf.d/lua/plugins/finder.lua @@ -0,0 +1,31 @@ +return { + { + "nvim-telescope/telescope.nvim", + cmd = "Telescope", + lazy = true, + branch = "0.1.x", + dependencies = { "nvim-lua/plenary.nvim" }, + config = function() + require("telescope").setup() + local builtin = require("telescope.builtin") + vim.keymap.set("n", "", builtin.find_files, { desc = "Telescope find files" }) + vim.keymap.set("n", "", builtin.live_grep, { desc = "Telescope live grep" }) + vim.cmd([[highlight TelescopeBorder guibg=none]]) + vim.cmd([[highlight TelescopeTitle guibg=none]]) + end, + }, + { + "nvim-neo-tree/neo-tree.nvim", + branch = "v3.x", + dependencies = { + "nvim-lua/plenary.nvim", + "nvim-tree/nvim-web-devicons", + "MunifTanjim/nui.nvim", + }, + lazy = false, + opts = {}, + config = function() + vim.api.nvim_set_keymap("n", "", ":Neotree toggle", { noremap = true }) + end, + }, +} diff --git a/nvim/conf.d/lua/plugins/format.lua b/nvim/conf.d/lua/plugins/format.lua new file mode 100644 index 0000000..ab11d64 --- /dev/null +++ b/nvim/conf.d/lua/plugins/format.lua @@ -0,0 +1,16 @@ +return { + { + "stevearc/conform.nvim", + event = { "BufWritePre" }, + cmd = { "ConformInfo" }, + opts = { + formatters_by_ft = { + lua = { "stylua" }, + }, + default_format_opts = { + lsp_format = "fallback", + }, + format_on_save = { timeout_ms = 500 }, + }, + }, +} diff --git a/nvim/conf.d/lua/plugins/git.lua b/nvim/conf.d/lua/plugins/git.lua new file mode 100644 index 0000000..6267181 --- /dev/null +++ b/nvim/conf.d/lua/plugins/git.lua @@ -0,0 +1,20 @@ +return { + { + "NeogitOrg/neogit", + dependencies = { + "nvim-lua/plenary.nvim", + "sindrets/diffview.nvim", + "nvim-telescope/telescope.nvim", + }, + config = function() + require("neogit").setup({}) + end, + }, + { + "lewis6991/gitsigns.nvim", + tag = "v1.0.2", + config = function() + require("gitsigns").setup({}) + end, + }, +} diff --git a/nvim/conf.d/lua/plugins/language.lua b/nvim/conf.d/lua/plugins/language.lua new file mode 100644 index 0000000..0854f71 --- /dev/null +++ b/nvim/conf.d/lua/plugins/language.lua @@ -0,0 +1,7 @@ +return { + { + "google/vim-jsonnet", + lazy = true, + ft = { "jsonnet", "libsonnet" }, + }, +} diff --git a/nvim/conf.d/lua/plugins/lint.lua b/nvim/conf.d/lua/plugins/lint.lua new file mode 100644 index 0000000..3ef050e --- /dev/null +++ b/nvim/conf.d/lua/plugins/lint.lua @@ -0,0 +1,24 @@ +return { + { + "editorconfig/editorconfig-vim", + }, + { + "mfussenegger/nvim-lint", + config = function() + local lint = require("lint") + lint.linters_by_ft = { + markdown = { "markdownlint" }, + } + + local lint_augroup = vim.api.nvim_create_augroup("lint", { clear = true }) + vim.api.nvim_create_autocmd({ "BufEnter", "BufWritePost", "InsertLeave" }, { + group = lint_augroup, + callback = function() + if vim.opt_local.modifiable:get() then + lint.try_lint() + end + end, + }) + end, + }, +} diff --git a/nvim/conf.d/lua/plugins/lsp.lua b/nvim/conf.d/lua/plugins/lsp.lua new file mode 100644 index 0000000..92919bf --- /dev/null +++ b/nvim/conf.d/lua/plugins/lsp.lua @@ -0,0 +1,366 @@ +-- Project configuration cache +local project_config_cache = {} + +-- Get project configuration with caching +local function get_project_config(root_dir) + if project_config_cache[root_dir] then + return project_config_cache[root_dir] + end + + local config = { + has_pyright = false, + has_ruff = false, + has_mypy = false, + has_black = false, + has_isort = false, + has_pylint = false, + } + + -- Check pyproject.toml + local pyproject_path = root_dir .. "/pyproject.toml" + local pyproject_file = io.open(pyproject_path, "r") + if pyproject_file then + local content = pyproject_file:read("*all") + pyproject_file:close() + + -- More accurate matching: consider sections and keys + config.has_pyright = content:match("%[tool%.pyright%]") ~= nil or content:match("pyright%s*=") ~= nil + config.has_ruff = content:match("%[tool%.ruff%]") ~= nil or content:match("ruff%s*=") ~= nil + config.has_mypy = content:match("%[tool%.mypy%]") ~= nil or content:match("mypy%s*=") ~= nil + config.has_black = content:match("%[tool%.black%]") ~= nil or content:match("black%s*=") ~= nil + config.has_isort = content:match("%[tool%.isort%]") ~= nil or content:match("isort%s*=") ~= nil + config.has_pylint = content:match("%[tool%.pylint%]") ~= nil or content:match("pylint%s*=") ~= nil + end + + -- Check Pipfile + local pipfile_path = root_dir .. "/Pipfile" + local pipfile = io.open(pipfile_path, "r") + if pipfile then + local content = pipfile:read("*all") + pipfile:close() + + config.has_pyright = config.has_pyright or content:match("pyright") ~= nil + config.has_ruff = config.has_ruff or content:match("ruff") ~= nil + config.has_mypy = config.has_mypy or content:match("mypy") ~= nil + config.has_black = config.has_black or content:match("black") ~= nil + config.has_isort = config.has_isort or content:match("isort") ~= nil + config.has_pylint = config.has_pylint or content:match("pylint") ~= nil + end + + project_config_cache[root_dir] = config + + -- Debug logging + if vim.g.lsp_debug then + vim.notify(string.format("Project config for %s: %s", root_dir, vim.inspect(config)), vim.log.levels.INFO) + end + + return config +end + +-- Get Python project root directory +local function get_python_root(fname) + local util = require("lspconfig.util") + return util.root_pattern("pyproject.toml", "setup.py", "setup.cfg", "Pipfile", "requirements.txt", ".git")(fname) +end + +-- Mason package path helper +local function mason_package_path(package) + local path = vim.fn.resolve(vim.fn.stdpath("data") .. "/mason/packages/" .. package) + return path +end + +return { + { + "williamboman/mason.nvim", + dependencies = { + "williamboman/mason-lspconfig.nvim", + "neovim/nvim-lspconfig", + "saghen/blink.cmp", + }, + opts = { + servers = { + -- css + cssls = {}, + tailwindcss = {}, + -- docker + dockerls = {}, + docker_compose_language_service = {}, + -- go + gopls = {}, + -- html + html = {}, + -- lua + lua_ls = { + lsp = { + root_dir = function(fname) + local util = require("lspconfig.util") + return util.root_pattern(".git", "stylua.toml", ".stylua.toml")(fname) or util.path.dirname(fname) + end, + settings = { + Lua = { + runtime = { + version = "LuaJIT", + }, + diagnostics = { + globals = { "vim" }, + disable = { "missing-fields" }, + }, + workspace = { + library = { + vim.env.VIMRUNTIME, + vim.fn.stdpath("config"), + }, + checkThirdParty = false, + }, + telemetry = { + enable = false, + }, + completion = { + callSnippet = "Replace", + }, + }, + }, + }, + }, + -- python + pyright = { + available = function(_, fname) + local root = get_python_root(fname) + if not root then + return false + end + local config = get_project_config(root) + return config.has_pyright + end, + }, + ruff = { + available = function(_, fname) + local root = get_python_root(fname) + if not root then + return false + end + local config = get_project_config(root) + return config.has_ruff + end, + }, + pylsp = { + libs = { + mypy = "pylsp-mypy", + black = "python-lsp-black", + isort = "python-lsp-isort", + }, + available = function(config, fname) + local root = get_python_root(fname) + if not root then + return false + end + + local proj_config = get_project_config(root) + + -- Don't use pylsp if pyright or ruff is used + if proj_config.has_pyright or proj_config.has_ruff then + return false + end + + -- Enable only if mypy, black, or isort is used + return proj_config.has_mypy or proj_config.has_black or proj_config.has_isort + end, + init = function(config, fname) + local root = get_python_root(fname) + if not root then + return + end + + local proj_config = get_project_config(root) + local path = mason_package_path("python-lsp-server") + local command = path .. "/venv/bin/pip" + + local args = { "install", "-U" } + if proj_config.has_mypy then + table.insert(args, config.libs.mypy) + end + if proj_config.has_black then + table.insert(args, config.libs.black) + end + if proj_config.has_isort then + table.insert(args, config.libs.isort) + end + + -- Only install if there are plugins to install + if #args > 2 then + require("plenary.job") + :new({ + command = command, + args = args, + cwd = path, + }) + :start() + end + end, + get_lsp_config = function(config, fname) + local root = get_python_root(fname) + if not root then + return {} + end + + local proj_config = get_project_config(root) + local util = require("lspconfig.util") + + return { + root_dir = function(fname) + return util.root_pattern( + "pyproject.toml", + "setup.py", + "setup.cfg", + "Pipfile", + "requirements.txt", + ".venv" + )(fname) or util.path.dirname(fname) + end, + settings = { + pylsp = { + plugins = { + pycodestyle = { enabled = true }, + pylint = { enabled = proj_config.has_pylint }, + flake8 = { enabled = false }, + mypy = { enabled = proj_config.has_mypy }, + black = { enabled = proj_config.has_black }, + isort = { enabled = proj_config.has_isort }, + }, + }, + }, + } + end, + }, + -- rust + rust_analyzer = {}, + -- sh + bashls = {}, + -- text + vale_ls = {}, + -- typescript + biome = {}, + ts_ls = {}, + -- yaml + yamlls = {}, + -- others + efm = {}, + typos_lsp = {}, + }, + }, + init = function(settings) + local fname = vim.api.nvim_buf_get_name(0) + local opts = settings.opts + + require("mason").setup({}) + for _, config in pairs(opts.servers) do + if (not config.available or config.available(config, fname)) and config.init then + config.init(config, fname) + end + end + end, + config = function(_, opts) + -- Mason setup + require("mason").setup() + require("mason-lspconfig").setup({ + automatic_installation = true, + }) + + -- Setup static LSP configurations once (excluding dynamic ones like pylsp) + local cmp = require("blink.cmp") + for server, config in pairs(opts.servers) do + if not config.get_lsp_config then + local lsp_config = config.lsp or {} + lsp_config.capabilities = cmp.get_lsp_capabilities(lsp_config.capabilities) + vim.lsp.config[server] = lsp_config + end + end + + -- Cache for enabled LSP servers per buffer + local buffer_lsp_cache = {} + + -- Setup LSP for each buffer + local function setup_lsp_for_buffer(bufnr) + local fname = vim.api.nvim_buf_get_name(bufnr) + if fname == "" then + return + end + + -- Avoid duplicate setup + if buffer_lsp_cache[bufnr] then + return + end + buffer_lsp_cache[bufnr] = true + + for server, config in pairs(opts.servers) do + if not config.available or config.available(config, fname) then + -- For servers with dynamic config, generate it now + if config.get_lsp_config then + local lsp_config = config.get_lsp_config(config, fname) + lsp_config.capabilities = cmp.get_lsp_capabilities(lsp_config.capabilities) + vim.lsp.config[server] = lsp_config + end + -- Enable LSP for this buffer + vim.lsp.enable(server) + end + end + end + + -- Setup LSP on FileType event + vim.api.nvim_create_autocmd("FileType", { + callback = function(ev) + setup_lsp_for_buffer(ev.buf) + end, + }) + + -- Setup LSP for existing buffers + vim.api.nvim_create_autocmd("VimEnter", { + callback = function() + vim.schedule(function() + for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do + if vim.api.nvim_buf_is_loaded(bufnr) then + setup_lsp_for_buffer(bufnr) + end + end + + -- Setup keybindings + vim.keymap.set("n", "gd", ":lua vim.lsp.buf.definition()") + end) + end, + }) + + -- Clear cache when configuration files are modified + vim.api.nvim_create_autocmd("BufWritePost", { + pattern = { "pyproject.toml", "Pipfile" }, + callback = function() + local fname = vim.fn.expand(":p") + local root = vim.fn.fnamemodify(fname, ":h") + project_config_cache[root] = nil + + if vim.g.lsp_debug then + vim.notify(string.format("Cleared cache for %s", root), vim.log.levels.INFO) + end + end, + }) + + -- LspAttach autocmd for dynamic control + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(ev) + local client = vim.lsp.get_client_by_id(ev.data.client_id) + local config = opts.servers[client.name] + if + client + and config + and config.available + and not config.available(config, vim.api.nvim_buf_get_name(ev.buf)) + then + vim.schedule(function() + vim.lsp.buf_detach_client(ev.buf, client.id) + client.stop() + end) + end + end, + }) + end, + }, +} diff --git a/nvim/conf.d/lua/plugins/misc.lua b/nvim/conf.d/lua/plugins/misc.lua new file mode 100644 index 0000000..5a2fe80 --- /dev/null +++ b/nvim/conf.d/lua/plugins/misc.lua @@ -0,0 +1,7 @@ +return { + { + "m4xshen/hardtime.nvim", + lazy = false, + dependencies = { "MunifTanjim/nui.nvim" }, + }, +} diff --git a/nvim/conf.d/lua/plugins/preference.lua b/nvim/conf.d/lua/plugins/preference.lua new file mode 100644 index 0000000..a52df71 --- /dev/null +++ b/nvim/conf.d/lua/plugins/preference.lua @@ -0,0 +1,198 @@ +return { + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + config = function() + local configs = require("nvim-treesitter.configs") + configs.setup({ + ensure_installed = { + "lua", + "python", + "vim", + "vimdoc", + }, + sync_install = false, + highlight = { enable = true }, + indent = { enable = true }, + }) + end, + }, + { + "nvim-lualine/lualine.nvim", + config = function() + local themes = { + dark = { + blue = "#839bd3", + cyan = "#739389", + black = "#080616", + white = "#dbd7bc", + red = "#b44947", + violet = "#917fb4", + grey = "#717169", + }, + light = { + blue = "#839bd3", + cyan = "#597b75", + black = "#1f1f28", + white = "#f2ecbc", + red = "#c84053", + violet = "#b35b79", + grey = "#8a8980", + }, + } + + local colors = themes.dark + + local kanagawa_theme = { + normal = { + a = { fg = colors.black, bg = colors.violet }, + b = { fg = colors.white, bg = colors.grey }, + c = { fg = colors.white }, + }, + + insert = { a = { fg = colors.black, bg = colors.blue } }, + visual = { a = { fg = colors.black, bg = colors.cyan } }, + replace = { a = { fg = colors.black, bg = colors.red } }, + + inactive = { + a = { fg = colors.white, bg = colors.black }, + b = { fg = colors.white, bg = colors.black }, + c = { fg = colors.white }, + }, + } + + require("lualine").setup({ + options = { + theme = kanagawa_theme, + component_separators = "", + section_separators = { left = "", right = "" }, + }, + sections = { + lualine_a = { { "mode", separator = { left = "" }, right_padding = 2 } }, + lualine_b = { "filename", "branch" }, + lualine_c = { + "%=", --[[ add your center compoentnts here in place of this comment ]] + }, + lualine_x = {}, + lualine_y = { "filetype", "progress" }, + lualine_z = { + { "location", separator = { right = "" }, left_padding = 2 }, + }, + }, + inactive_sections = { + lualine_a = { "filename" }, + lualine_b = {}, + lualine_c = {}, + lualine_x = {}, + lualine_y = {}, + lualine_z = { "location" }, + }, + tabline = {}, + extensions = {}, + }) + end, + }, + { + "akinsho/bufferline.nvim", + dependencies = { "nvim-tree/nvim-web-devicons" }, + config = function() + local bufferline = require("bufferline") + bufferline.setup({ + options = { + number = "ordinal", + separator_style = "slant", + diagnostics_indicator = function(_, level) + local icon = level:match("error") and " " or "" + return " " .. icon + end, + }, + }) + vim.api.nvim_set_keymap("n", "", ":BufferLineCycleNext", { noremap = true }) + vim.api.nvim_set_keymap("n", "", ":BufferLineCyclePrev", { noremap = true }) + end, + }, + { + "rebelot/kanagawa.nvim", + config = function() + vim.cmd("colorscheme kanagawa") + require("kanagawa").setup({ + background = { + dark = "wave", + light = "lotus", + }, + }) + end, + }, + { + "petertriho/nvim-scrollbar", + config = function() + require("scrollbar").setup({}) + end, + }, + { + "shellRaining/hlchunk.nvim", + event = { "BufReadPre", "BufNewFile" }, + config = function() + require("hlchunk").setup({ + chunk = { + enable = true, + }, + indent = { + enable = true, + }, + }) + end, + }, + { + "norcalli/nvim-colorizer.lua", + config = function() + require("colorizer").setup({ + "lua", + "css", + "html", + "javascript", + "typescript", + }) + end, + }, + { + "folke/noice.nvim", + event = "VeryLazy", + opts = {}, + dependencies = { + "MunifTanjim/nui.nvim", + "rcarriga/nvim-notify", + }, + config = function() + require("noice").setup({ + lsp = { + override = { + ["vim.lsp.util.convert_input_to_markdown_lines"] = true, + ["vim.lsp.util.stylize_markdown"] = true, + ["cmp.entry.get_documentation"] = true, + }, + }, + presets = { + bottom_search = true, + command_palette = true, + long_message_to_split = true, + inc_rename = false, + lsp_doc_border = false, + }, + routes = { + { + filter = { + event = "msg_show", + find = "Type .qa", + }, + opts = { skip = true }, + }, + }, + }) + vim.opt.cmdheight = 0 + + -- Dismiss all notifications instantly + vim.keymap.set("n", "nd", "Noice dismiss", { desc = "Dismiss all notifications" }) + end, + }, +} diff --git a/nvim/conf.d/lua/plugins/terminal.lua b/nvim/conf.d/lua/plugins/terminal.lua new file mode 100644 index 0000000..d88b4c3 --- /dev/null +++ b/nvim/conf.d/lua/plugins/terminal.lua @@ -0,0 +1,18 @@ +return { + { + 'akinsho/toggleterm.nvim', + config = function() + require('toggleterm').setup({ + size = 10, + hide_numbers = true, + start_in_insert = true, + close_on_exit = true, + direction = 'horizontal', + shade_terminals = false, + }) + vim.api.nvim_create_user_command('T', function(args) + vim.cmd('ToggleTerm' .. args.args) + end, { nargs = '*' }) + end, + } +} diff --git a/zsh/conf.d/zshrc b/zsh/conf.d/zshrc index 69369c1..fa41ce2 100644 --- a/zsh/conf.d/zshrc +++ b/zsh/conf.d/zshrc @@ -10,13 +10,13 @@ setopt hist_ignore_dups setopt EXTENDED_HISTORY ### zsh completion -fpath+=~/.zfunc -if type brew &>/dev/null -then - FPATH="$(brew --prefix)/share/zsh/site-functions:${FPATH}" -fi +autoload -Uz compinit +if [[ -n ${ZDOTDIR}/.zcompdump(#qN.mh+24) ]]; then + compinit; +else + compinit -C; +fi; export LS_COLORS='di=01;34:ln=01;35:so=01;32:ex=01;31:bd=46;34:cd=43;34:su=41;30:sg=46;30:tw=42;30:ow=43;30' -autoload -Uz compinit ; compinit autoload -U colors ; colors ; zstyle ':completion:*' list-colors "${LS_COLORS}" zstyle ':completion:*' completer _complete _match _approximate zstyle ':completion:*' menu select @@ -24,8 +24,7 @@ zstyle ':completion::complete:*' use-cache true zstyle ':completion:*:approximate:*' max-errors 3 numeric zstyle ':completion:*:sudo:*' command-path /usr/local/sbin /usr/local/bin \ /usr/sbin /usr/bin /sbin /bin /usr/X11R6/bin - -### zsh utils +# zsh utils autoload -Uz edit-command-line zle -N edit-command-line bindkey "^O" edit-command-line @@ -109,7 +108,14 @@ fi ### anyenv if is_exists anyenv; then - eval "$(anyenv init - zsh)" + export PATH="$HOME/.anyenv/bin:$PATH" + # eval "$(anyenv init --no-rehash - zsh)" + if ! [ -f ~/.cache/anyenv.cache ] + then + anyenv init - --no-rehash > ~/.cache/anyenv.cache + zcompile ~/.cache/anyenv.cache + fi + source ~/.cache/anyenv.cache fi ### direnv @@ -167,3 +173,22 @@ case ${OSTYPE} in fi ;; esac + +if [ -d ${HOME}/.nvm ]; then + export NVM_DIR="${NVM_DIR:-$HOME/.nvm}" + + nvm() { + unset -f nvm + source "${NVM_DIR}/nvm.sh" + nvm "$@" + } + + if [ -f "${NVM_DIR}/alias/default" ]; then + DEFAULT_NODE_VERSION=$(cat "${NVM_DIR}/alias/default") + NODE_BIN_PATH="${NVM_DIR}/versions/node/v${DEFAULT_NODE_VERSION}/bin" + if [ -d "${NODE_BIN_PATH}" ]; then + export PATH="${NODE_BIN_PATH}:$PATH" + export NODE_PATH="${NVM_DIR}/versions/node/v${DEFAULT_NODE_VERSION}/lib/node_modules" + fi + fi +fi