diff options
167 files changed, 3807 insertions, 2425 deletions
| diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index 12d6ceab..219f903b 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -2,7 +2,7 @@ blank_issues_enabled: true  contact_links:    - name: Matrix community -    url: https://matrix.to/#/+atmachine:matrix +    url: https://matrix.to/#/#atmachine-neovim:matrix.org      about: Please ask and answer questions on Matrix.    - name: Discord community      url: https://discord.gg/Xb9B4Ny diff --git a/.github/workflows/commitlint.config.js b/.github/workflows/commitlint.config.js new file mode 100644 index 00000000..2bc8d493 --- /dev/null +++ b/.github/workflows/commitlint.config.js @@ -0,0 +1,34 @@ +module.exports = { +  rules: { +    "body-leading-blank": [1, "always"], +    "body-max-line-length": [2, "always", 100], +    "footer-leading-blank": [1, "always"], +    "footer-max-line-length": [2, "always", 100], +    "header-max-length": [2, "always", 72], +    "scope-case": [2, "always", "lower-case"], +    "subject-case": [ +      2, +      "never", +      ["upper-case", "pascal-case", "sentence-case", "start-case"], +    ], +    "subject-empty": [2, "never"], +    "subject-full-stop": [2, "never", "."], +    "type-case": [2, "always", "lower-case"], +    "type-empty": [2, "never"], +    "type-enum": [ +      2, +      "always", +      [ +        "build", +        "ci", +        "docs", +        "feat", +        "fix", +        "perf", +        "refactor", +        "revert", +        "test", +      ], +    ], +  }, +}; diff --git a/.github/workflows/commitlint.yml b/.github/workflows/commitlint.yml new file mode 100644 index 00000000..93c776e3 --- /dev/null +++ b/.github/workflows/commitlint.yml @@ -0,0 +1,15 @@ +name: "Commit Linter" +on: pull_request +jobs: +  lint-commits: +    runs-on: ubuntu-latest +    env: +      GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} +    steps: +      - uses: actions/[email protected] +        with: +          fetch-depth: 0 +      - uses: wagoid/commitlint-github-action@v4 +        with: +          configFile: .github/workflows/commitlint.config.js +          helpURL: https://github.com/LunarVim/LunarVim/blob/rolling/CONTRIBUTING.md#commit-messages diff --git a/.github/workflows/format.yaml b/.github/workflows/format.yaml index 142ba7f1..7f5f57d6 100644 --- a/.github/workflows/format.yaml +++ b/.github/workflows/format.yaml @@ -1,11 +1,11 @@  name: format  on:    push: -    branches: '**' +    branches: "**"    pull_request:      branches: -      - 'master' -      - 'rolling' +      - "master" +      - "rolling"  jobs:    stylua-check: @@ -14,14 +14,13 @@ jobs:      steps:        - uses: actions/checkout@v2 -      - name: Prepare dependencies -        run: | -          sudo apt install -y curl unzip --no-install-recommends -          bash ./utils/installer/install_stylua.sh +      - name: Lint with stylua +        uses: JohnnyMorganz/[email protected] +        with: +          token: ${{ secrets.GITHUB_TOKEN }} +          # CLI arguments +          args: --check . -      - name: Check formatting -        run: | -          ./utils/stylua --config-path .stylua.toml -c .    shfmt-check:      name: "Formatting check with shfmt"      runs-on: ubuntu-20.04 @@ -31,14 +30,12 @@ jobs:        - name: Setup Go          uses: actions/setup-go@v2          with: -          go-version: '1.16' -       +          go-version: "1.16" +        - name: Use shfmt          run: |            GO111MODULE=on go get mvdan.cc/sh/v3/cmd/shfmt        # https://google.github.io/styleguide/shellguide.html        - name: Check formatting -        run: | -          shfmt -f . | grep -v jdtls | xargs shfmt -i 2 -ci -l -d -     +        run: make style-sh diff --git a/.github/workflows/install.yaml b/.github/workflows/install.yaml index fa8bf0e3..fa1b9be8 100644 --- a/.github/workflows/install.yaml +++ b/.github/workflows/install.yaml @@ -1,7 +1,7 @@  name: install  on:    push: -    branches: "**" +    branches: ["**"]    pull_request:      branches:        - "master" @@ -23,31 +23,26 @@ jobs:      steps:        - uses: actions/checkout@v2 -      # sha256sum is not available by default -      - name: Installl dependencies for OSX -        if: matrix.os == 'osx' -        run: | -          echo "HOMEBREW_NO_AUTO_UPDATE=1" >> $GITHUB_ENV -          echo "$HOME/.local/bin" >> $GITHUB_PATH -          brew install coreutils -        - name: Install neovim binary          run: | +          echo "$HOME/.local/bin" >> $GITHUB_PATH            bash ./utils/installer/install-neovim-from-release        - name: Install LunarVim          timeout-minutes: 4          run: | -          mkdir -p "$HOME"/.local/share/lunarvim/lvim -          mkdir -p "$HOME"/.config/lvim -          ln -s "$PWD"/* "$HOME"/.local/share/lunarvim/lvim/. -          bash ./utils/installer/install.sh +          ./utils/installer/install.sh --local --no-install-dependencies        - name: Test LunarVim PackerCompile          run: if "$HOME"/.local/bin/lvim --headless +PackerCompile -c ':qall' 2>&1|grep -q 'Error'; then false; fi        - name: Test LunarVim Health          run: if "$HOME"/.local/bin/lvim --headless +checkhealth -c ':qall' 2>&1|grep -q 'Error'; then false; fi + +      - name: Run unit-tests +        # NOTE: make sure to adjust the timeout if you start adding a lot of tests +        timeout-minutes: 4 +        run: make test  #   freebsd:  #     runs-on: macos-latest  #     if: github.event.pull_request.draft == false diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index d187f497..93050bba 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -1,11 +1,11 @@  name: lint  on:    push: -    branches: '**' +    branches: "**"    pull_request:      branches: -      - 'master' -      - 'rolling' +      - "master" +      - "rolling"  jobs:    lua-linter: @@ -13,23 +13,23 @@ jobs:      runs-on: ubuntu-20.04      steps:        - uses: actions/checkout@v2 -       +        - uses: leafo/gh-actions-lua@v8        - uses: leafo/gh-actions-luarocks@v4        - name: Use luacheck          run: luarocks install luacheck -       +        - name: Run luacheck -        run: luacheck *.lua lua/ +        run: make lint-lua    shellcheck:      name: Shellcheck      runs-on: ubuntu-latest      steps: -    - uses: actions/checkout@v2 -    - name: Run ShellCheck -      uses: ludeeus/action-shellcheck@master -      with: -       scandir: './utils' -       ignore: 'bin' +      - uses: actions/checkout@v2 +      - name: Run ShellCheck +        uses: ludeeus/action-shellcheck@master +        with: +          scandir: "./utils" +          ignore: "bin" diff --git a/.luacheckrc b/.luacheckrc index a3875f91..8c965f6b 100644 --- a/.luacheckrc +++ b/.luacheckrc @@ -4,9 +4,6 @@ stds.nvim = {    globals = {      "lvim",      vim = { fields = { "g" } }, -    "CONFIG_PATH", -    "CACHE_PATH", -    "DATA_PATH",      "TERMINAL",      "USER",      "C", @@ -21,11 +18,18 @@ stds.nvim = {      "jit",      "os",      "vim", +    "join_paths", +    "get_runtime_dir", +    "get_config_dir", +    "get_cache_dir", +    "get_version",      -- vim = { fields = { "cmd", "api", "fn", "o" } },    },  }  std = "lua51+nvim" +files["tests/*_spec.lua"].std = "lua51+nvim+busted" +  -- Don't report unused self arguments of methods.  self = false diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 8ecda3bd..2c4921ec 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,23 +7,28 @@ repos:          language: system          types: [shell]          entry: bash -        args: [-c, "shfmt -f $(git rev-parse --show-toplevel) | grep -v jdtls | xargs shfmt -i=2 -ci -w"] +        args: [-c, make lint-sh]        - id: shellcheck          name: shellcheck          language: system          types: [shell]          entry: bash -        args: -          [-c, "shfmt -f $(git rev-parse --show-toplevel) | grep -v jdtls | xargs shellcheck"] +        args: [-c, make style-sh]        - id: stylua          name: StyLua          language: rust          entry: stylua          types: [lua] -        args: ['-'] +        args: ["-"]        - id: luacheck          name: luacheck          language: system          entry: luacheck          types: [lua]          args: [.] +      - id: commitlint +        name: commitlint +        language: system +        entry: bash +        args: [./utils/ci/run_commitlint.sh] +        stages: [commit-msg] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 45edf8c1..37865518 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -11,10 +11,12 @@ One of the best ways to begin contributing in a meaningful way is by helping fin  ## Getting Started  1. Backup your ~/.config/nvim -2. Follow the [Installation](https://github.com/lunarvim/LunarVim/wiki/Installation) guide +2. Follow the [Installation](https://www.lunarvim.org/01-installing.html) guide  3. Link your fork with the repository `git remote add upstream https://github.com/lunarvim/LunarVim.git`  4. That's it ! You can now `git fetch upstream` and `git rebase [-i] upstream/rolling` to update your branches with the latest contributions. +<br /> +  ## Setting up development tools  ### For editing Lua files @@ -31,21 +33,9 @@ One of the best ways to begin contributing in a meaningful way is by helping fin  Install [pre-commit](https://github.com/pre-commit/pre-commit) which will run all linters and formatters for you as a pre-commit-hook. -## Some Guidelines - -### Git Commit Messages - -* Use the present tense ("Add feature" not "Added feature") -* Use the imperative mood ("Move cursor to..." not "Moves cursor to...") -* Limit the first line to 72 characters or less -* Reference issues and pull requests liberally after the first line +<br /> -### Git Branch Naming - -* Name your branches meaningfully, -ex: (feature|bugfix|hotfix)/what-my-pr-does - -### Code  +## Code Conventions  All lua code is formatted with [Stylua](https://github.com/JohnnyMorganz/StyLua).  * Use snake_case @@ -60,10 +50,64 @@ All shell code is formatted according to [Google Shell Style Guide](https://goog  shfmt -i 2 -ci -l -d .  ``` +<br /> + +## Pull Requests (PRs) + +To avoid duplicate work, create a draft pull request. + +### Commit Messages +* Commit header is limited to 72 characters. +* Commit body and footer is limited to 100 characters per line. + +**Commit header format:** +``` +<type>(<scope>?): <summary> +  │       │           │ +  │       │           └─> Present tense.     'add something...'(O) vs 'added something...'(X) +  │       │               Imperative mood.   'move cursor to...'(O) vs 'moves cursor to...'(X) +  │       │               Not capitalized.  +  │       │               No period at the end. +  │       │ +  │       └─> Commit Scope is optional, but strongly recommended. +  │           Use lower case. +  │           'plugin', 'file', or 'directory' name is suggested, but not limited. +  │ +  └─> Commit Type: build|ci|docs|feat|fix|perf|refactor|test +``` + +##### Commit Type Guideline + +* **build**: changes that affect the build system or external dependencies (example scopes: npm, pip, rg) +* **ci**: changes to CI configuration files and scripts (example scopes: format, lint, issue_templates) +* **docs**: changes to the documentation only +* **feat**: a new feature for the user +* **fix**: a bug fix +* **perf**: a performance improvement +* **refactor**: a code change that neither fixes a bug nor adds a feature +* **test**: Adding missing tests or correcting existing tests + +**Real world examples:** +``` +feat(quickfix): add 'q' binding to quit quickfix window when focused  +``` +``` +fix(installer): add missing "HOME" variable  +``` + + +### Branch Naming + +Name your branches meaningfully. + +ex) +```(feature|bugfix|hotfix)/what-my-pr-does``` + +<br />  ## Communication  Members of the community have multiple ways to collaborate on the project.  We encourage you to join the community:  - [Discord server](https://discord.gg/Xb9B4Ny) -- [Matrix server](https://matrix.to/#/+atmachine:matrix) +- [Matrix server](https://matrix.to/#/#atmachine-neovim:matrix.org) diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..8efa4f4d --- /dev/null +++ b/Makefile @@ -0,0 +1,33 @@ +SHELL := /bin/bash + +install: +	@echo Starting LunarVim Installer +	bash ./utils/installer/install.sh + +install-neovim-binary: +	@echo Installing Neovim from github releases +	bash ./utils/installer/install-neovim-from-release + +uninstall: +	@echo TODO: this is currently not supported + +lint: lint-lua lint-sh + +lint-lua: +	luacheck *.lua lua/* tests/* + +lint-sh: +	shfmt -f . | grep -v jdtls | xargs shellcheck + +style: style-lua style-sh + +style-lua: +	stylua --config-path .stylua.toml --check . + +style-sh: +	shfmt -f . | grep -v jdtls | xargs shfmt -i 2 -ci -l -d + +test: +	bash ./utils/bin/test_runner.sh "$(TEST)" + +.PHONY: install install-neovim-binary uninstall lint style test @@ -16,83 +16,45 @@      <a href="https://twitter.com/intent/follow?screen_name=chrisatmachine">        <img src="https://img.shields.io/twitter/follow/chrisatmachine?style=social&logo=twitter" alt="follow on Twitter">      </a> -</p>	 +</p>  </div> -## Install In One Command! - -Make sure you have the newest version of Neovim (0.5). +## Documentation -``` bash -bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh) -``` +You can find all the documentation for LunarVim at [lunarvim.org](https://www.lunarvim.org) -### Customizing the installation - -The following options are supported by setting environment variables: -- `"$LV_REMOTE"`            Select a different LunarVim remote [default: 'lunarvim/lunarvim.git'] -- `"$LV_BRANCH"`            Select LunarVim's branch [default: 'rolling'] -- `"$INSTALL_PREFIX"`       Select LunarVim's install prefix [default: `'$HOME/.local'`] -- `"$LUNARVIM_RUNTIME_DIR"` Select LunarVim's runtime directory [default: `'$HOME/.local/share/lunarvim'`] -- `"$LUNARVIM_CONFIG_DIR"`  Select LunarVim's configuration directory [default: `'$HOME/.config/lvim'`] - -Putting it all together +## Install In One Command! -``` bash -curl -LSs https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh -O install.sh -INSTALL_PREFIX=/tmp/t1 LUNARVIM_CONFIG_DIR=/tmp/t2 LUNARVIM_RUNTIME_DIR=/tmp/t3 bash ./install.sh -``` +Make sure you have the release version of Neovim (0.5). -### BREAKING CHANGE on rolling and master branches -* The latest changes to LunarVim require you to [remove it completely](https://github.com/lunarvim/LunarVim/wiki/Uninstalling-LunarVim) before upgrading -* Going forward LunarVim will no longer reside in the nvim configuration folder.  LunarVim has been moved to `~/.local/share/lunarvim`.   -* To launch Lunarvim use the new `lvim` command.  `nvim` will only launch standard neovim.   -* Your personal configuration file (`config.lua`) can now be found in `~/.config/lvim`.  You can initialize this folder as a git repository to track changes to your configuration files. -* If you want to keep launching LunarVim with the `nvim` command, add an alias entry to your shell's config file:  `alias nvim=lvim`.  To temporarily revert to the default `nvim` prefix it with a backslash `\nvim`. -* Many options formerly available in `config.lua` have been renamed.  For details [look here](https://github.com/lunarvim/LunarVim/wiki/Breaking-changes-in-rolling) - -### Debugging LunarVim's configuration -* To turn on debugging add these settings `lvim.log.level = debug` and use `<leader>Ll` to see the options of viewing the logfiles -* You can also use install [lnav](https://github.com/tstack/lnav) and use it in a floating terminal. Make sure to set `lvim.builtin.terminal.active = true`. - -### Fixing installation problems -If your installation is stuck on `Ok to remove? [y/N]`, it means there are some leftovers, \ -you can run the script with `--overwrite` but be warned this will remove the following folders: -- `~/.cache/nvim` -- `~/.config/nvim`                        #Removed only on Master Branch -- `~/.local/share/nvim/site/pack/packer`  #Removed only on Master Branch -- `~/.local/share/lunarvim`               #Removed only on Rolling Branch -- `~/.config/lvim`                        #Removed only on Rolling Branch  ```bash -curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh | LVBRANCH=rolling bash -s -- --overwrite +bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)  ``` -then run nvim and wait for treesitter to finish the installation +## Install Language support -## Installing LSP for your language +- Enter `:LspInstall` followed by `<TAB>` to see your options for LSP -Just enter `:LspInstall` followed by `<TAB>` to see your options +- Enter `:TSInstall` followed by `<TAB>` to see your options for syntax highlighting  **NOTE** I recommend installing `lua` for autocomplete in `config.lua` -For the julia language server look [here](https://github.com/lunarvim/LunarVim/wiki/Enabling-a-language-server#julia-support) + + +  ## Configuration file -To activate other plugins and language features use the `lv-config.lua` file provided in the `nvim` folder (`~/.config/nvim/lv-config.lua`) in the master branch or (`~/.config/lvim/config.lua`) on rolling +To install plugins configure LunarVim use the `config.lua` located here: `~/.config/lvim/config.lua`  Example:  ```lua  -- general  lvim.format_on_save = true -lvim.lint_on_save = true -lvim.colorscheme = "spacegray" +lvim.colorscheme = "onedarker" -lvim.builtin.compe.autocomplete = true - --- keymappings [view all the defaults by pressing <leader>Lk]  lvim.leader = "space"  -- add your own keymapping  lvim.keys.normal_mode["<C-s>"] = ":w<cr>" @@ -105,25 +67,16 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"  -- Use which-key to add extra bindings with the leader-key prefix  -- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" } --- lvim.builtin.which_key.mappings["t"] = { ---   name = "+Trouble", ---   r = { "<cmd>Trouble lsp_references<cr>", "References" }, ---   f = { "<cmd>Trouble lsp_definitions<cr>", "Definitions" }, ---   d = { "<cmd>Trouble lsp_document_diagnostics<cr>", "Diagnosticss" }, ---   q = { "<cmd>Trouble quickfix<cr>", "QuickFix" }, ---   l = { "<cmd>Trouble loclist<cr>", "LocationList" }, ---   w = { "<cmd>Trouble lsp_workspace_diagnostics<cr>", "Diagnosticss" }, --- } - --- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile + +-- Configure builtin plugins  lvim.builtin.dashboard.active = true  lvim.builtin.terminal.active = true --- if you don't want all the parsers change this to a table of the ones you want +-- Treesitter parsers change this to a table of the languages you want i.e. {"java", "python", javascript}  lvim.builtin.treesitter.ensure_installed = "maintained"  lvim.builtin.treesitter.ignore_install = { "haskell" } -lvim.builtin.treesitter.highlight.enabled = true +-- Disable virtual text  lvim.lsp.diagnostics.virtual_text = false  -- set a formatter if you want to override the default lsp one (if it exists) @@ -148,74 +101,31 @@ lvim.plugins = {      {"folke/tokyonight.nvim"}, {          "ray-x/lsp_signature.nvim",          config = function() require"lsp_signature".on_attach() end, -        event = "InsertEnter" +        event = "BufRead"      }  } - --- Autocommands (https://neovim.io/doc/user/autocmd.html) --- lvim.autocommands.custom_groups = { ---   { "BufWinEnter", "*.lua", "setlocal ts=8 sw=8" }, --- } - -  ``` -In case you want to see all the settings inside LunarVim, run the following: - -```bash -cd /tmp -lvim --headless +'lua require("utils").generate_settings()' +qa && sort -o lv-settings.lua{,} -``` -and then inspect `/tmp/lv-settings.lua` file -  ## Updating LunarVim -In order to update you should be aware of three things `Plugins`, `LunarVim` and `Neovim` +- inside LunarVim `:LvimUpdate` +- from the command-line `lvim +LvimUpdate +q` -To update plugins: +### Update the plugins -``` -:PackerUpdate -``` +- inside LunarVim `:PackerUpdate` -To update LunarVim: +## Breaking changes -```bash -cd ~/.local/share/lunarvim/lvim && git pull -:PackerSync -``` - -To update Neovim use your package manager or [compile from source](https://github.com/lunarvim/LunarVim/wiki/Installation#get-the-latest-version-of-neovim) - -## Project Goals - -1. Provide basic functionalities required from an IDE -    - LSP -    - Formatting/Linting -    - Debugging -    - Treesitter -    - Colorschemes -2. Be as fast and lean as possible  -    - Lazy loading -    - Not a single extra plugin -    - User configurable lang/feature enable/disable -3. Provide a [simple and easy](https://github.com/LunarVim/LunarVimCommunity) way for users to share their own configuration or use others.  -4. Hot reload of configurations -    - Hot install of lsp/treesitter/formatter required upon opening a filetype for the first time -5. Provide a stable & maintainable error free configuration layer over neovim  -    - With the help of the community behind it -    - Github workflow testing -    - Freezing plugin versions -6. Provide detailed documentation -    - Video series on how to configure LunarVim as an IDE for each lang -7. Valhalla +- `lvim.lang.FOO.lsp` is no longer supported after #1584. +  You can either use `:NlspConfig` for most of the settings you might need, or override the setup by adding an entry to `lvim.lsp.override = { "FOO" }`.  ## Resources -- [YouTube](https://www.youtube.com/channel/UCS97tchJDq17Qms3cux8wcA) -  - [Documentation](https://www.lunarvim.org) +- [YouTube](https://www.youtube.com/channel/UCS97tchJDq17Qms3cux8wcA) +  - [Discord](https://discord.gg/Xb9B4Ny)  - [Twitter](https://twitter.com/chrisatmachine) @@ -223,9 +133,11 @@ To update Neovim use your package manager or [compile from source](https://githu  ## Testimonials  > "I have the processing power of a potato with 4 gb of ram and LunarVim runs perfectly." +>  > - @juanCortelezzi, LunarVim user.  > "My minimal config with a good amount less code than LunarVim loads 40ms slower. Time to switch." +>  > - @mvllow, Potential LunarVim user.  <div align="center" id="madewithlua"> diff --git a/colors/onedarker.vim b/colors/onedarker.vim new file mode 100644 index 00000000..42f2dbcb --- /dev/null +++ b/colors/onedarker.vim @@ -0,0 +1,13 @@ +" Author: Christian Chiarulli <[email protected]> + +lua << EOF +package.loaded['onedarker'] = nil +package.loaded['onedarker.highlights'] = nil +package.loaded['onedarker.Treesitter'] = nil +package.loaded['onedarker.markdown'] = nil +package.loaded['onedarker.Whichkey'] = nil +package.loaded['onedarker.Git'] = nil +package.loaded['onedarker.LSP'] = nil + +require("onedarker") +EOF diff --git a/colors/spacegray.vim b/colors/spacegray.vim deleted file mode 100644 index 8d075ee1..00000000 --- a/colors/spacegray.vim +++ /dev/null @@ -1,2 +0,0 @@ -" Author: Christian Chiarulli <[email protected]> -lua require("spacegray")
\ No newline at end of file diff --git a/ftdetect/bicep.lua b/ftdetect/bicep.lua new file mode 100644 index 00000000..bdd52e5e --- /dev/null +++ b/ftdetect/bicep.lua @@ -0,0 +1,3 @@ +vim.cmd [[ + au BufRead,BufNewFile *.bicep set filetype=bicep +]] diff --git a/ftdetect/json.lua b/ftdetect/json.lua new file mode 100644 index 00000000..9824e3e4 --- /dev/null +++ b/ftdetect/json.lua @@ -0,0 +1,3 @@ +vim.cmd [[ + au BufRead,BufNewFile tsconfig.json set filetype=jsonc +]] diff --git a/ftdetect/sol.lua b/ftdetect/sol.lua new file mode 100644 index 00000000..b716f759 --- /dev/null +++ b/ftdetect/sol.lua @@ -0,0 +1,3 @@ +vim.cmd [[ + au BufRead,BufNewFile *.sol set filetype=solidity +]] diff --git a/ftplugin/asm.lua b/ftplugin/asm.lua deleted file mode 100644 index 4f135295..00000000 --- a/ftplugin/asm.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "asm" diff --git a/ftplugin/beancount.lua b/ftplugin/beancount.lua deleted file mode 100644 index ac8aff33..00000000 --- a/ftplugin/beancount.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "beancount" diff --git a/ftplugin/c.lua b/ftplugin/c.lua deleted file mode 100644 index 3f931e4a..00000000 --- a/ftplugin/c.lua +++ /dev/null @@ -1,4 +0,0 @@ -require("lsp").setup "c" - --- TODO get from dap --- require("lang.c").dap() diff --git a/ftplugin/clojure.lua b/ftplugin/clojure.lua deleted file mode 100644 index 683720a5..00000000 --- a/ftplugin/clojure.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "clojure" diff --git a/ftplugin/cmake.lua b/ftplugin/cmake.lua deleted file mode 100644 index 56d30106..00000000 --- a/ftplugin/cmake.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "cmake" diff --git a/ftplugin/cpp.lua b/ftplugin/cpp.lua deleted file mode 100644 index 6028ea49..00000000 --- a/ftplugin/cpp.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "cpp" diff --git a/ftplugin/crystal.lua b/ftplugin/crystal.lua deleted file mode 100644 index 38605db8..00000000 --- a/ftplugin/crystal.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "crystal" diff --git a/ftplugin/cs.lua b/ftplugin/cs.lua deleted file mode 100644 index 6c349494..00000000 --- a/ftplugin/cs.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "cs" diff --git a/ftplugin/css.lua b/ftplugin/css.lua deleted file mode 100644 index 094ed2a3..00000000 --- a/ftplugin/css.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "css" diff --git a/ftplugin/d.lua b/ftplugin/d.lua deleted file mode 100644 index 41a6433b..00000000 --- a/ftplugin/d.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "d" diff --git a/ftplugin/dart.lua b/ftplugin/dart.lua deleted file mode 100644 index 9f0ccfa0..00000000 --- a/ftplugin/dart.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "dart" diff --git a/ftplugin/dockerfile.lua b/ftplugin/dockerfile.lua deleted file mode 100644 index 72ec7f90..00000000 --- a/ftplugin/dockerfile.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "docker" diff --git a/ftplugin/elixir.lua b/ftplugin/elixir.lua deleted file mode 100644 index 2d4c90e2..00000000 --- a/ftplugin/elixir.lua +++ /dev/null @@ -1,10 +0,0 @@ -require("lsp").setup "elixir" -vim.api.nvim_buf_set_option(0, "commentstring", "# %s") - --- TODO: do we need this? --- needed for the LSP to recognize elixir files (alternatively just use elixir-editors/vim-elixir) --- vim.cmd [[ ---   au BufRead,BufNewFile *.ex,*.exs set filetype=elixir ---   au BufRead,BufNewFile *.eex,*.leex,*.sface set filetype=eelixir ---   au BufRead,BufNewFile mix.lock set filetype=elixir --- ]] diff --git a/ftplugin/elm.lua b/ftplugin/elm.lua deleted file mode 100644 index 38fda314..00000000 --- a/ftplugin/elm.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "elm" diff --git a/ftplugin/erlang.lua b/ftplugin/erlang.lua deleted file mode 100644 index c6426dba..00000000 --- a/ftplugin/erlang.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "erlang" diff --git a/ftplugin/euphoria3.lua b/ftplugin/euphoria3.lua deleted file mode 100644 index 168af22b..00000000 --- a/ftplugin/euphoria3.lua +++ /dev/null @@ -1,9 +0,0 @@ -require("lsp").setup "erlang" - --- TODO: do we need this? --- needed for the LSP to recognize elixir files (alternatively just use elixir-editors/vim-elixir) --- vim.cmd [[ ---   au BufRead,BufNewFile *.ex,*.exs set filetype=elixir ---   au BufRead,BufNewFile *.eex,*.leex,*.sface set filetype=eelixir ---   au BufRead,BufNewFile mix.lock set filetype=elixir --- ]] diff --git a/ftplugin/fish.lua b/ftplugin/fish.lua deleted file mode 100644 index 575ec434..00000000 --- a/ftplugin/fish.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "fish" diff --git a/ftplugin/fortran.lua b/ftplugin/fortran.lua deleted file mode 100644 index 36f4f484..00000000 --- a/ftplugin/fortran.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "fortran" diff --git a/ftplugin/gdscript.lua b/ftplugin/gdscript.lua deleted file mode 100644 index b23a20e2..00000000 --- a/ftplugin/gdscript.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "gdscript" diff --git a/ftplugin/go.lua b/ftplugin/go.lua deleted file mode 100644 index 218b634c..00000000 --- a/ftplugin/go.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "go" diff --git a/ftplugin/graphql.lua b/ftplugin/graphql.lua deleted file mode 100644 index 83e8878d..00000000 --- a/ftplugin/graphql.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "graphql" diff --git a/ftplugin/haskell.lua b/ftplugin/haskell.lua deleted file mode 100644 index 374bed1a..00000000 --- a/ftplugin/haskell.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "haskell" diff --git a/ftplugin/html.lua b/ftplugin/html.lua deleted file mode 100644 index c60394c0..00000000 --- a/ftplugin/html.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "html" diff --git a/ftplugin/java.lua b/ftplugin/java.lua deleted file mode 100644 index dcb46ca2..00000000 --- a/ftplugin/java.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "java" diff --git a/ftplugin/javascript.lua b/ftplugin/javascript.lua deleted file mode 100644 index 37b95c71..00000000 --- a/ftplugin/javascript.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "javascript" diff --git a/ftplugin/javascriptreact.lua b/ftplugin/javascriptreact.lua deleted file mode 100644 index 90920166..00000000 --- a/ftplugin/javascriptreact.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "javascriptreact" diff --git a/ftplugin/json.lua b/ftplugin/json.lua deleted file mode 100644 index 18368cf9..00000000 --- a/ftplugin/json.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "json" diff --git a/ftplugin/julia.lua b/ftplugin/julia.lua deleted file mode 100644 index 9840be1f..00000000 --- a/ftplugin/julia.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "julia" diff --git a/ftplugin/kotlin.lua b/ftplugin/kotlin.lua deleted file mode 100644 index a0e6d5d6..00000000 --- a/ftplugin/kotlin.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "kotlin" diff --git a/ftplugin/less.lua b/ftplugin/less.lua deleted file mode 120000 index 6b9e5a8d..00000000 --- a/ftplugin/less.lua +++ /dev/null @@ -1 +0,0 @@ -css.lua
\ No newline at end of file diff --git a/ftplugin/lua.lua b/ftplugin/lua.lua deleted file mode 100644 index 2ed88315..00000000 --- a/ftplugin/lua.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "lua" diff --git a/ftplugin/netrw.lua b/ftplugin/netrw.lua deleted file mode 100644 index b2292870..00000000 --- a/ftplugin/netrw.lua +++ /dev/null @@ -1,2 +0,0 @@ -vim.cmd [[nmap <buffer> h -]] -vim.cmd [[nmap <buffer> l <cr>]] diff --git a/ftplugin/nix.lua b/ftplugin/nix.lua deleted file mode 100644 index 41152a75..00000000 --- a/ftplugin/nix.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "nix" diff --git a/ftplugin/perl.lua b/ftplugin/perl.lua deleted file mode 100644 index f1d3b772..00000000 --- a/ftplugin/perl.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "perl" diff --git a/ftplugin/php.lua b/ftplugin/php.lua deleted file mode 100644 index 4eabcf71..00000000 --- a/ftplugin/php.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "php" diff --git a/ftplugin/ps1.lua b/ftplugin/ps1.lua deleted file mode 100644 index 6d388496..00000000 --- a/ftplugin/ps1.lua +++ /dev/null @@ -1,3 +0,0 @@ -require("lsp").setup "ps1" - -vim.cmd [[setlocal ts=4 sw=4]] diff --git a/ftplugin/puppet.lua b/ftplugin/puppet.lua deleted file mode 100644 index f8521762..00000000 --- a/ftplugin/puppet.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "puppet" diff --git a/ftplugin/python.lua b/ftplugin/python.lua deleted file mode 100644 index 3e79e6bc..00000000 --- a/ftplugin/python.lua +++ /dev/null @@ -1,3 +0,0 @@ -require("lsp").setup "python" --- TODO get from dap --- require("lang.python").dap() diff --git a/ftplugin/r.lua b/ftplugin/r.lua deleted file mode 100644 index 296d3c86..00000000 --- a/ftplugin/r.lua +++ /dev/null @@ -1,2 +0,0 @@ --- R -e 'install.packages("languageserver",repos = "http://cran.us.r-project.org")' -require("lsp").setup "r" diff --git a/ftplugin/rmd.lua b/ftplugin/rmd.lua deleted file mode 120000 index 401cef17..00000000 --- a/ftplugin/rmd.lua +++ /dev/null @@ -1 +0,0 @@ -r.lua
\ No newline at end of file diff --git a/ftplugin/ruby.lua b/ftplugin/ruby.lua deleted file mode 100644 index 7e968917..00000000 --- a/ftplugin/ruby.lua +++ /dev/null @@ -1,2 +0,0 @@ --- also support sorbet -require("lsp").setup "ruby" diff --git a/ftplugin/rust.lua b/ftplugin/rust.lua deleted file mode 100644 index f1623f25..00000000 --- a/ftplugin/rust.lua +++ /dev/null @@ -1,4 +0,0 @@ -require("lsp").setup "rust" - --- TODO get from dap --- require("lang.rust").dap() diff --git a/ftplugin/sass.lua b/ftplugin/sass.lua deleted file mode 120000 index 6b9e5a8d..00000000 --- a/ftplugin/sass.lua +++ /dev/null @@ -1 +0,0 @@ -css.lua
\ No newline at end of file diff --git a/ftplugin/sbt.lua b/ftplugin/sbt.lua deleted file mode 120000 index d0d6ce5b..00000000 --- a/ftplugin/sbt.lua +++ /dev/null @@ -1 +0,0 @@ -scala.lua
\ No newline at end of file diff --git a/ftplugin/scala.lua b/ftplugin/scala.lua deleted file mode 100644 index 169e36ad..00000000 --- a/ftplugin/scala.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "scala" diff --git a/ftplugin/scss.lua b/ftplugin/scss.lua deleted file mode 120000 index 6b9e5a8d..00000000 --- a/ftplugin/scss.lua +++ /dev/null @@ -1 +0,0 @@ -css.lua
\ No newline at end of file diff --git a/ftplugin/sh.lua b/ftplugin/sh.lua deleted file mode 100644 index 4f18fbca..00000000 --- a/ftplugin/sh.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "sh" diff --git a/ftplugin/sql.lua b/ftplugin/sql.lua deleted file mode 100644 index b4658023..00000000 --- a/ftplugin/sql.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "sql" diff --git a/ftplugin/svelte.lua b/ftplugin/svelte.lua deleted file mode 100644 index 175a5cbd..00000000 --- a/ftplugin/svelte.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "svelte" diff --git a/ftplugin/swift.lua b/ftplugin/swift.lua deleted file mode 100644 index 1ae7554a..00000000 --- a/ftplugin/swift.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "swift" diff --git a/ftplugin/terraform.lua b/ftplugin/terraform.lua deleted file mode 100644 index 3486663d..00000000 --- a/ftplugin/terraform.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "terraform" diff --git a/ftplugin/tex.lua b/ftplugin/tex.lua deleted file mode 100644 index e9a98ec5..00000000 --- a/ftplugin/tex.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "tex" diff --git a/ftplugin/thing.pp b/ftplugin/thing.pp deleted file mode 100644 index e69de29b..00000000 --- a/ftplugin/thing.pp +++ /dev/null diff --git a/ftplugin/toml.lua b/ftplugin/toml.lua deleted file mode 100644 index 701685a4..00000000 --- a/ftplugin/toml.lua +++ /dev/null @@ -1 +0,0 @@ -vim.cmd [[setlocal commentstring=#%s]] diff --git a/ftplugin/typescript.lua b/ftplugin/typescript.lua deleted file mode 100644 index 2f6219df..00000000 --- a/ftplugin/typescript.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "typescript" diff --git a/ftplugin/typescriptreact.lua b/ftplugin/typescriptreact.lua deleted file mode 100644 index 2f6219df..00000000 --- a/ftplugin/typescriptreact.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "typescript" diff --git a/ftplugin/vim.lua b/ftplugin/vim.lua deleted file mode 100644 index 88c00c1c..00000000 --- a/ftplugin/vim.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "vim" diff --git a/ftplugin/vue.lua b/ftplugin/vue.lua deleted file mode 100644 index a174c9bf..00000000 --- a/ftplugin/vue.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "vue" diff --git a/ftplugin/yaml.lua b/ftplugin/yaml.lua deleted file mode 100644 index d21f9785..00000000 --- a/ftplugin/yaml.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "yaml" diff --git a/ftplugin/zig.lua b/ftplugin/zig.lua deleted file mode 100644 index ef3d64d4..00000000 --- a/ftplugin/zig.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "zig" diff --git a/ftplugin/zsh.lua b/ftplugin/zsh.lua deleted file mode 100644 index 4f18fbca..00000000 --- a/ftplugin/zsh.lua +++ /dev/null @@ -1 +0,0 @@ -require("lsp").setup "sh" @@ -1,61 +1,26 @@ --- {{{ Bootstrap -local home_dir = vim.loop.os_homedir() - -vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/lvim") - -vim.opt.rtp:remove(home_dir .. "/.config/nvim") -vim.opt.rtp:remove(home_dir .. "/.config/nvim/after") -vim.opt.rtp:append(home_dir .. "/.config/lvim") -vim.opt.rtp:append(home_dir .. "/.config/lvim/after") - -vim.opt.rtp:remove(home_dir .. "/.local/share/nvim/site") -vim.opt.rtp:remove(home_dir .. "/.local/share/nvim/site/after") -vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/site") -vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/site/after") +if os.getenv "LUNARVIM_RUNTIME_DIR" then +  local path_sep = vim.loop.os_uname().version:match "Windows" and "\\" or "/" +  vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim") +end --- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp -vim.cmd [[let &packpath = &runtimepath]] --- }}} +require("bootstrap"):init()  local config = require "config" -config:init() +-- config:init()  config:load()  local plugins = require "plugins" -local plugin_loader = require("plugin-loader").init() -plugin_loader:load { plugins, lvim.plugins } +require("plugin-loader"):load { plugins, lvim.plugins }  local Log = require "core.log" -Log:info "Starting LunarVim" +Log:debug "Starting LunarVim"  vim.g.colors_name = lvim.colorscheme -- Colorscheme must get called after plugins are loaded or it will break new installs.  vim.cmd("colorscheme " .. lvim.colorscheme) -local utils = require "utils" -utils.toggle_autoformat()  local commands = require "core.commands"  commands.load(commands.defaults) -require("lsp").config() - -local null_status_ok, null_ls = pcall(require, "null-ls") -if null_status_ok then -  null_ls.config {} -  require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) -end - -local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings") -if lsp_settings_status_ok then -  lsp_settings.setup { -    config_home = home_dir .. "/.config/lvim/lsp-settings", -  } -end -  require("keymappings").setup() --- TODO: these guys need to be in language files --- if lvim.lang.emmet.active then ---   require "lsp.emmet-ls" --- end --- if lvim.lang.tailwindcss.active then ---   require "lsp.tailwind +require("lsp").setup() diff --git a/lua/bootstrap.lua b/lua/bootstrap.lua new file mode 100644 index 00000000..866403b7 --- /dev/null +++ b/lua/bootstrap.lua @@ -0,0 +1,193 @@ +local M = {} + +package.loaded["utils.hooks"] = nil +local _, hooks = pcall(require, "utils.hooks") + +---Join path segments that were passed as input +---@return string +function _G.join_paths(...) +  local uv = vim.loop +  local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/" +  local result = table.concat({ ... }, path_sep) +  return result +end + +---Get the full path to `$LUNARVIM_RUNTIME_DIR` +---@return string +function _G.get_runtime_dir() +  local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR" +  if not lvim_runtime_dir then +    -- when nvim is used directly +    return vim.fn.stdpath "config" +  end +  return lvim_runtime_dir +end + +---Get the full path to `$LUNARVIM_CONFIG_DIR` +---@return string +function _G.get_config_dir() +  local lvim_config_dir = os.getenv "LUNARVIM_CONFIG_DIR" +  if not lvim_config_dir then +    return vim.fn.stdpath "config" +  end +  return lvim_config_dir +end + +---Get the full path to `$LUNARVIM_CACHE_DIR` +---@return string +function _G.get_cache_dir() +  local lvim_cache_dir = os.getenv "LUNARVIM_CACHE_DIR" +  if not lvim_cache_dir then +    return vim.fn.stdpath "cache" +  end +  return lvim_cache_dir +end + +---Get the full path to the currently installed lunarvim repo +---@return string +local function get_install_path() +  local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR" +  if not lvim_runtime_dir then +    -- when nvim is used directly +    return vim.fn.stdpath "config" +  end +  return join_paths(lvim_runtime_dir, "lvim") +end + +---Get currently installed version of LunarVim +---@param type string can be "short" +---@return string +function _G.get_version(type) +  type = type or "" +  local lvim_full_ver = vim.fn.system("git -C " .. get_install_path() .. " describe --tags") + +  if string.match(lvim_full_ver, "%d") == nil then +    return nil +  end +  if type == "short" then +    return vim.fn.split(lvim_full_ver, "-")[1] +  else +    return string.sub(lvim_full_ver, 1, #lvim_full_ver - 1) +  end +end + +---Initialize the `&runtimepath` variables and prepare for startup +---@return table +function M:init() +  self.runtime_dir = get_runtime_dir() +  self.config_dir = get_config_dir() +  self.cache_path = get_cache_dir() +  self.install_path = get_install_path() + +  self.pack_dir = join_paths(self.runtime_dir, "site", "pack") +  self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim") +  self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua") + +  if os.getenv "LUNARVIM_RUNTIME_DIR" then +    vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site")) +    vim.opt.rtp:remove(join_paths(vim.fn.stdpath "data", "site", "after")) +    vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site")) +    vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after")) + +    vim.opt.rtp:remove(vim.fn.stdpath "config") +    vim.opt.rtp:remove(join_paths(vim.fn.stdpath "config", "after")) +    vim.opt.rtp:prepend(self.config_dir) +    vim.opt.rtp:append(join_paths(self.config_dir, "after")) +    -- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp + +    vim.cmd [[let &packpath = &runtimepath]] +    vim.cmd("set spellfile=" .. join_paths(self.config_dir, "spell", "en.utf-8.add")) +  end + +  vim.fn.mkdir(vim.fn.stdpath "cache", "p") + +  -- FIXME: currently unreliable in unit-tests +  if not os.getenv "LVIM_TEST_ENV" then +    require("impatient").setup { +      path = vim.fn.stdpath "cache" .. "/lvim_cache", +      enable_profiling = true, +    } +  end + +  local config = require "config" +  config:init { +    path = join_paths(self.config_dir, "config.lua"), +  } + +  require("plugin-loader"):init { +    package_root = self.pack_dir, +    install_path = self.packer_install_dir, +  } + +  return self +end + +---Update LunarVim +---pulls the latest changes from github and, resets the startup cache +function M:update() +  hooks.run_pre_update() +  M:update_repo() +  hooks.run_post_update() +end + +local function git_cmd(subcmd) +  local Job = require "plenary.job" +  local Log = require "core.log" +  local args = { "-C", get_install_path() } +  vim.list_extend(args, subcmd) + +  local stderr = {} +  local stdout, ret = Job +    :new({ +      command = "git", +      args = args, +      cwd = get_install_path(), +      on_stderr = function(_, data) +        table.insert(stderr, data) +      end, +    }) +    :sync() + +  if not vim.tbl_isempty(stderr) then +    Log:debug(stderr) +  end + +  if not vim.tbl_isempty(stdout) then +    Log:debug(stdout) +  end + +  return ret +end + +---pulls the latest changes from github +function M:update_repo() +  local Log = require "core.log" +  local sub_commands = { +    fetch = { "fetch" }, +    diff = { "diff", "--quiet", "@{upstream}" }, +    merge = { "merge", "--ff-only", "--progress" }, +  } +  Log:info "Checking for updates" + +  local ret = git_cmd(sub_commands.fetch) +  if ret ~= 0 then +    Log:error "Update failed! Check the log for further information" +    return +  end + +  ret = git_cmd(sub_commands.diff) + +  if ret == 0 then +    Log:info "LunarVim is already up-to-date" +    return +  end + +  ret = git_cmd(sub_commands.merge) + +  if ret ~= 0 then +    Log:error "Update failed! Please pull the changes manually instead." +    return +  end +end + +return M diff --git a/lua/config/defaults.lua b/lua/config/defaults.lua index 9bd1bdd8..f030234d 100644 --- a/lua/config/defaults.lua +++ b/lua/config/defaults.lua @@ -1,19 +1,14 @@  local home_dir = vim.loop.os_homedir() -CONFIG_PATH = home_dir .. "/.local/share/lunarvim/lvim" -DATA_PATH = vim.fn.stdpath "data" -CACHE_PATH = vim.fn.stdpath "cache" -TERMINAL = vim.fn.expand "$TERMINAL" -USER = vim.fn.expand "$USER" -vim.cmd [[ set spellfile=~/.config/lvim/spell/en.utf-8.add ]] +local utils = require "utils"  lvim = {    leader = "space", -  colorscheme = "spacegray", +  colorscheme = "onedarker",    line_wrap_cursor_movement = true,    transparent_window = false,    format_on_save = true, -  vsnip_dir = home_dir .. "/.config/snippets", -  database = { save_location = "~/.config/lunarvim_db", auto_execute = 1 }, +  vsnip_dir = utils.join_paths(home_dir, ".config", "snippets"), +  database = { save_location = utils.join_paths(home_dir, ".config", "lunarvim_db"), auto_execute = 1 },    keys = {},    builtin = {}, @@ -33,1131 +28,10 @@ lvim = {        },      },    }, - -  lsp = { -    completion = { -      item_kind = { -        "   (Text) ", -        "   (Method)", -        "   (Function)", -        "   (Constructor)", -        " ﴲ  (Field)", -        "[] (Variable)", -        "   (Class)", -        " ﰮ  (Interface)", -        "   (Module)", -        " 襁 (Property)", -        "   (Unit)", -        "   (Value)", -        " 練 (Enum)", -        "   (Keyword)", -        "   (Snippet)", -        "   (Color)", -        "   (File)", -        "   (Reference)", -        "   (Folder)", -        "   (EnumMember)", -        " ﲀ  (Constant)", -        " ﳤ  (Struct)", -        "   (Event)", -        "   (Operator)", -        "   (TypeParameter)", -      }, -    }, -    diagnostics = { -      signs = { -        active = true, -        values = { -          { name = "LspDiagnosticsSignError", text = "" }, -          { name = "LspDiagnosticsSignWarning", text = "" }, -          { name = "LspDiagnosticsSignHint", text = "" }, -          { name = "LspDiagnosticsSignInformation", text = "" }, -        }, -      }, -      virtual_text = { -        prefix = "", -        spacing = 0, -      }, -      underline = true, -      severity_sort = true, -    }, -    override = {}, -    document_highlight = true, -    popup_border = "single", -    on_attach_callback = nil, -    on_init_callback = nil, -    null_ls = { -      setup = {}, -    }, -  }, -    plugins = {      -- use config.lua for this not put here    },    autocommands = {}, -} - -local schemas = nil -local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls") -if status_ok then -  schemas = jsonls_settings.get_default_schemas() -end - --- TODO move all of this into lang specific files, only require when using -lvim.lang = { -  asm = { -    formatters = { -      -- { -      --   exe = "asmfmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "", -      setup = {}, -    }, -  }, -  beancount = { -    formatters = { -      -- { -      --   exe = "bean_format", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "beancount", -      setup = { -        cmd = { "beancount-langserver" }, -      }, -    }, -  }, -  c = { -    formatters = { -      -- { -      --   exe = "clang_format", -      --   args = {}, -      -- }, -      -- { -      --   exe = "uncrustify", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "clangd", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd", -          "--background-index", -          "--header-insertion=never", -          "--cross-file-rename", -          "--clang-tidy", -          "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*", -        }, -      }, -    }, -  }, -  cpp = { -    formatters = { -      -- { -      --   exe = "clang_format", -      --   args = {}, -      -- }, -      -- { -      --   exe = "uncrustify", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "clangd", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/cpp/clangd/bin/clangd", -          "--background-index", -          "--header-insertion=never", -          "--cross-file-rename", -          "--clang-tidy", -          "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*", -        }, -      }, -    }, -  }, -  crystal = { -    formatters = { -      -- { -      --   exe = "crystal_format", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "crystalline", -      setup = { -        cmd = { "crystalline" }, -      }, -    }, -  }, -  cs = { -    formatters = { -      -- { -      --   exe = "clang_format ", -      --   args = {}, -      -- }, -      -- { -      --   exe = "uncrustify", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "omnisharp", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/csharp/omnisharp/run", -          "--languageserver", -          "--hostPID", -          tostring(vim.fn.getpid()), -        }, -      }, -    }, -  }, -  cmake = { -    formatters = { -      -- { -      --   exe = "cmake_format", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "cmake", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/cmake/venv/bin/cmake-language-server", -        }, -      }, -    }, -  }, -  clojure = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "clojure_lsp", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/clojure/clojure-lsp", -        }, -      }, -    }, -  }, -  css = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "cssls", -      setup = { -        cmd = { -          "node", -          DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js", -          "--stdio", -        }, -      }, -    }, -  }, -  less = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "cssls", -      setup = { -        cmd = { -          "node", -          DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js", -          "--stdio", -        }, -      }, -    }, -  }, -  d = { -    formatters = { -      -- { -      --   exe = "dfmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "serve_d", -      setup = { -        cmd = { "serve-d" }, -      }, -    }, -  }, -  dart = { -    formatters = { -      -- { -      --   exe = "dart_format", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "dartls", -      setup = { -        cmd = { -          "dart", -          "/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot", -          "--lsp", -        }, -      }, -    }, -  }, -  docker = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "dockerls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/dockerfile/node_modules/.bin/docker-langserver", -          "--stdio", -        }, -      }, -    }, -  }, -  elixir = { -    formatters = { -      -- { -      --   exe = "mix", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "elixirls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/elixir/elixir-ls/language_server.sh", -        }, -      }, -    }, -  }, -  elm = { -    formatters = { -      -- { -      --   exe = "elm_format", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "elmls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-language-server", -        }, -        -- init_options = { -        -- elmAnalyseTrigger = "change", -        -- elmFormatPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-format", -        -- elmPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/", -        -- elmTestPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-test", -        -- }, -      }, -    }, -  }, -  erlang = { -    formatters = { -      -- { -      --   exe = "erlfmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "erlangls", -      setup = { -        cmd = { -          "erlang_ls", -        }, -      }, -    }, -  }, -  emmet = { active = false }, -  fish = { -    formatters = { -      -- { -      --   exe = "fish_indent", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "", -      setup = {}, -    }, -  }, -  fortran = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "fortls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/fortran/venv/bin/fortls", -        }, -      }, -    }, -  }, -  go = { -    formatters = { -      -- { -      --   exe = "gofmt", -      --   args = {}, -      -- }, -      -- { -      --   exe = "goimports", -      --   args = {}, -      -- }, -      -- { -      --   exe = "gofumpt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "gopls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/go/gopls", -        }, -      }, -    }, -  }, -  graphql = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "graphql", -      setup = { -        cmd = { -          "graphql-lsp", -          "server", -          "-m", -          "stream", -        }, -      }, -    }, -  }, -  haskell = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "hls", -      setup = { -        cmd = { DATA_PATH .. "/lspinstall/haskell/hls" }, -      }, -    }, -  }, -  html = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "html", -      setup = { -        cmd = { -          "node", -          DATA_PATH .. "/lspinstall/html/vscode-html/html-language-features/server/dist/node/htmlServerMain.js", -          "--stdio", -        }, -      }, -    }, -  }, -  java = { -    formatters = { -      -- { -      --   exe = "clang_format", -      --   args = {}, -      -- }, -      -- { -      --   exe = "uncrustify", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "jdtls", -      setup = { -        cmd = { DATA_PATH .. "/lspinstall/java/jdtls.sh" }, -      }, -    }, -  }, -  json = { -    formatters = { -      -- { -      --   exe = "json_tool", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "jsonls", -      setup = { -        cmd = { -          "node", -          DATA_PATH .. "/lspinstall/json/vscode-json/json-language-features/server/dist/node/jsonServerMain.js", -          "--stdio", -        }, -        settings = { -          json = { -            schemas = schemas, -            --   = { -            --   { -            --     fileMatch = { "package.json" }, -            --     url = "https://json.schemastore.org/package.json", -            --   }, -            -- }, -          }, -        }, -        commands = { -          Format = { -            function() -              vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) -            end, -          }, -        }, -      }, -    }, -  }, -  julia = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "julials", -      setup = { -        { -          "julia", -          "--startup-file=no", -          "--history-file=no", -          -- vim.fn.expand "~/.config/nvim/lua/lsp/julia/run.jl", -          CONFIG_PATH .. "/utils/julia/run.jl", -        }, -      }, -    }, -  }, -  kotlin = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "kotlin_language_server", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/kotlin/server/bin/kotlin-language-server", -        }, -        root_dir = function(fname) -          local util = require "lspconfig/util" - -          local root_files = { -            "settings.gradle", -- Gradle (multi-project) -            "settings.gradle.kts", -- Gradle (multi-project) -            "build.xml", -- Ant -            "pom.xml", -- Maven -          } - -          local fallback_root_files = { -            "build.gradle", -- Gradle -            "build.gradle.kts", -- Gradle -          } -          return util.root_pattern(unpack(root_files))(fname) or util.root_pattern(unpack(fallback_root_files))(fname) -        end, -      }, -    }, -  }, -  lua = { -    formatters = { -      -- { -      --   exe = "stylua", -      --   args = {}, -      -- }, -      -- { -      --   exe = "lua_format", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "sumneko_lua", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/lua/sumneko-lua-language-server", -          "-E", -          DATA_PATH .. "/lspinstall/lua/main.lua", -        }, -        settings = { -          Lua = { -            runtime = { -              -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) -              version = "LuaJIT", -              -- Setup your lua path -              path = vim.split(package.path, ";"), -            }, -            diagnostics = { -              -- Get the language server to recognize the `vim` global -              globals = { "vim", "lvim" }, -            }, -            workspace = { -              -- Make the server aware of Neovim runtime files -              library = { -                [vim.fn.expand "~/.local/share/lunarvim/lvim/lua"] = true, -                [vim.fn.expand "$VIMRUNTIME/lua"] = true, -                [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, -              }, -              maxPreload = 100000, -              preloadFileSize = 1000, -            }, -          }, -        }, -      }, -    }, -  }, -  nginx = { -    formatters = { -      -- { -      --   exe = "nginx_beautifier", -      --   args = { -      --     provider = "", -      --     setup = {}, -      --   }, -      -- }, -    }, -    linters = {}, -    lsp = {}, -  }, -  perl = { -    formatters = { -      -- { -      --   exe = "perltidy", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "", -      setup = {}, -    }, -  }, -  sql = { -    formatters = { -      -- { -      --   exe = "sqlformat", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "sqls", -      setup = { -        cmd = { "sqls" }, -      }, -    }, -  }, -  php = { -    formatters = { -      -- { -      --   exe = "phpcbf", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "intelephense", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/php/node_modules/.bin/intelephense", -          "--stdio", -        }, -        filetypes = { "php", "phtml" }, -        settings = { -          intelephense = { -            environment = { -              phpVersion = "7.4", -            }, -          }, -        }, -      }, -    }, -  }, -  puppet = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "puppet", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/puppet/puppet-editor-services/puppet-languageserver", -          "--stdio", -        }, -      }, -    }, -  }, -  javascript = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettier_d_slim", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    -- @usage can be {"eslint"} or {"eslint_d"} -    linters = {}, -    lsp = { -      provider = "tsserver", -      setup = { -        cmd = { -          -- TODO: -          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", -          "--stdio", -        }, -      }, -    }, -  }, -  javascriptreact = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettier_d_slim", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "tsserver", -      setup = { -        cmd = { -          -- TODO: -          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", -          "--stdio", -        }, -      }, -    }, -  }, -  python = { -    formatters = { -      -- { -      --   exe = "yapf", -      --   args = {}, -      -- }, -      -- { -      --   exe = "isort", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "pyright", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/python/node_modules/.bin/pyright-langserver", -          "--stdio", -        }, -      }, -    }, -  }, -  -- R -e 'install.packages("formatR",repos = "http://cran.us.r-project.org")' -  -- R -e 'install.packages("readr",repos = "http://cran.us.r-project.org")' -  r = { -    formatters = { -      -- { -      --   exe = "format_r", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "r_language_server", -      setup = { -        cmd = { -          "R", -          "--slave", -          "-e", -          "languageserver::run()", -        }, -      }, -    }, -  }, -  ruby = { -    formatters = { -      -- { -      --   exe = "rufo", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "solargraph", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/ruby/solargraph/solargraph", -          "stdio", -        }, -        filetypes = { "ruby" }, -        init_options = { -          formatting = true, -        }, -        root_dir = function(fname) -          local util = require("lspconfig").util -          return util.root_pattern("Gemfile", ".git")(fname) -        end, -        settings = { -          solargraph = { -            diagnostics = true, -          }, -        }, -      }, -    }, -  }, -  rust = { -    formatters = { -      -- { -      --   exe = "rustfmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "rust_analyzer", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/rust/rust-analyzer", -        }, -      }, -    }, -  }, -  scala = { -    formatters = { -      -- { -      --   exe = "scalafmt", -      --   args = {}, -      -- }, -    }, -    linters = { "" }, -    lsp = { -      provider = "metals", -      setup = {}, -    }, -  }, -  sh = { -    formatters = { -      -- { -      --   exe = "shfmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "bashls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server", -          "start", -        }, -      }, -    }, -  }, -  svelte = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "svelte", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/svelte/node_modules/.bin/svelteserver", -          "--stdio", -        }, -      }, -    }, -  }, -  swift = { -    formatters = { -      -- { -      --   exe = "swiftformat", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "sourcekit", -      setup = { -        cmd = { -          "xcrun", -          "sourcekit-lsp", -        }, -      }, -    }, -  }, -  tailwindcss = { -    active = false, -    filetypes = { -      "html", -      "css", -      "scss", -      "javascript", -      "javascriptreact", -      "typescript", -      "typescriptreact", -    }, -  }, -  terraform = { -    formatters = { -      -- { -      --   exe = "terraform_fmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "terraformls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/terraform/terraform-ls", -          "serve", -        }, -      }, -    }, -  }, -  tex = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "texlab", -      setup = { -        cmd = { DATA_PATH .. "/lspinstall/latex/texlab" }, -      }, -    }, -  }, -  typescript = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettier_d_slim", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "tsserver", -      setup = { -        cmd = { -          -- TODO: -          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", -          "--stdio", -        }, -      }, -    }, -  }, -  typescriptreact = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettier_d_slim", -      --   args = {}, -      -- }, -    }, -    -- @usage can be {"eslint"} or {"eslint_d"} -    linters = {}, -    lsp = { -      provider = "tsserver", -      setup = { -        cmd = { -          -- TODO: -          DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server", -          "--stdio", -        }, -      }, -    }, -  }, -  vim = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "vimls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server", -          "--stdio", -        }, -      }, -    }, -  }, -  vue = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettier_d_slim", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "vuels", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/vue/node_modules/.bin/vls", -        }, -      }, -    }, -  }, -  yaml = { -    formatters = { -      -- { -      --   exe = "prettier", -      --   args = {}, -      -- }, -      -- { -      --   exe = "prettierd", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "yamlls", -      setup = { -        cmd = { -          DATA_PATH .. "/lspinstall/yaml/node_modules/.bin/yaml-language-server", -          "--stdio", -        }, -      }, -    }, -  }, -  zig = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "zls", -      setup = { -        cmd = { -          "zls", -        }, -      }, -    }, -  }, -  gdscript = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "gdscript", -      setup = { -        cmd = { -          "nc", -          "localhost", -          "6008", -        }, -      }, -    }, -  }, -  ps1 = { -    formatters = {}, -    linters = {}, -    lsp = { -      provider = "powershell_es", -      setup = { -        bundle_path = "", -      }, -    }, -  }, -  nix = { -    formatters = { -      -- { -      --   exe = "nixfmt", -      --   args = {}, -      -- }, -    }, -    linters = {}, -    lsp = { -      provider = "rnix", -      setup = { -        cmd = { "rnix-lsp" }, -        filetypes = { "nix" }, -        init_options = {}, -        settings = {}, -        root_dir = function(fname) -          local util = require "lspconfig/util" -          return util.root_pattern ".git"(fname) or vim.fn.getcwd() -        end, -      }, -    }, -  }, +  lang = {},  } diff --git a/lua/config/init.lua b/lua/config/init.lua index 332460d3..411f7a93 100644 --- a/lua/config/init.lua +++ b/lua/config/init.lua @@ -1,27 +1,146 @@ -local home_dir = vim.loop.os_homedir() -local M = { -  path = string.format("%s/.config/lvim/config.lua", home_dir), -} +local M = {}  --- Initialize lvim default configuration  -- Define lvim global variable -function M:init() +function M:init(opts) +  opts = opts or {} +  self.path = opts.path    local utils = require "utils"    require "config.defaults" +  -- Fallback config.lua to lv-config.lua +  if not utils.is_file(self.path) then +    local lv_config = self.path:gsub("config.lua$", "lv-config.lua") +    print(self.path, "not found, falling back to", lv_config) + +    self.path = lv_config +  end +    local builtins = require "core.builtins"    builtins.config(self)    local settings = require "config.settings"    settings.load_options() -  -- Fallback config.lua to lv-config.lua -  if not utils.is_file(self.path) then -    local lv_config = self.path:gsub("config.lua$", "lv-config.lua") -    print(self.path, "not found, falling back to", lv_config) +  local lvim_lsp_config = require "lsp.config" +  lvim.lsp = vim.deepcopy(lvim_lsp_config) -    self.path = lv_config +  local supported_languages = { +    "asm", +    "bash", +    "beancount", +    "bibtex", +    "bicep", +    "c", +    "c_sharp", +    "clojure", +    "cmake", +    "comment", +    "commonlisp", +    "cpp", +    "crystal", +    "cs", +    "css", +    "cuda", +    "d", +    "dart", +    "dockerfile", +    "dot", +    "elixir", +    "elm", +    "emmet", +    "erlang", +    "fennel", +    "fish", +    "fortran", +    "gdscript", +    "glimmer", +    "go", +    "gomod", +    "graphql", +    "haskell", +    "hcl", +    "heex", +    "html", +    "java", +    "javascript", +    "javascriptreact", +    "jsdoc", +    "json", +    "json5", +    "jsonc", +    "julia", +    "kotlin", +    "latex", +    "ledger", +    "less", +    "lua", +    "markdown", +    "nginx", +    "nix", +    "ocaml", +    "ocaml_interface", +    "perl", +    "php", +    "pioasm", +    "ps1", +    "puppet", +    "python", +    "ql", +    "query", +    "r", +    "regex", +    "rst", +    "ruby", +    "rust", +    "scala", +    "scss", +    "sh", +    "solidity", +    "sparql", +    "sql", +    "supercollider", +    "surface", +    "svelte", +    "swift", +    "tailwindcss", +    "terraform", +    "tex", +    "tlaplus", +    "toml", +    "tsx", +    "turtle", +    "typescript", +    "typescriptreact", +    "verilog", +    "vim", +    "vue", +    "yaml", +    "yang", +    "zig", +  } + +  require("lsp.manager").init_defaults(supported_languages) +end + +local function deprecation_notice() +  local in_headless = #vim.api.nvim_list_uis() == 0 +  if in_headless then +    return +  end + +  for lang, entry in pairs(lvim.lang) do +    local deprecated_config = entry["lsp"] or {} +    if not vim.tbl_isempty(deprecated_config) then +      local msg = string.format( +        "Deprecation notice: [lvim.lang.%s.lsp] setting is no longer supported. See https://github.com/LunarVim/LunarVim#breaking-changes", +        lang +      ) +      vim.schedule(function() +        vim.notify(msg, vim.log.levels.WARN) +      end) +    end    end  end @@ -38,6 +157,8 @@ function M:load(config_path)      return    end +  deprecation_notice() +    self.path = config_path    autocmds.define_augroups(lvim.autocommands) diff --git a/lua/config/settings.lua b/lua/config/settings.lua index ba71a922..90042c4f 100644 --- a/lua/config/settings.lua +++ b/lua/config/settings.lua @@ -1,5 +1,5 @@  local M = {} - +local utils = require "utils"  M.load_options = function()    local default_options = {      backup = false, -- creates a backup file @@ -28,7 +28,7 @@ M.load_options = function()      timeoutlen = 100, -- time to wait for a mapped sequence to complete (in milliseconds)      title = true, -- set the title of window to the value of the titlestring      -- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to -    undodir = CACHE_PATH .. "/undo", -- set an undo directory +    undodir = utils.join_paths(get_cache_dir(), "undo"), -- set an undo directory      undofile = true, -- enable persistent undo      updatetime = 300, -- faster completion      writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited @@ -45,7 +45,7 @@ M.load_options = function()      spelllang = "en",      scrolloff = 8, -- is one of my fav      sidescrolloff = 8, -  } ---  VIM ONLY COMMANDS  ---cmd "filetype plugin on"cmd('let &titleold="' .. TERMINAL .. '"')cmd "set inccommand=split"cmd "set iskeyword+=-" +  }    ---  SETTINGS  --- diff --git a/lua/core/autocmds.lua b/lua/core/autocmds.lua index 041926e5..662afcfa 100644 --- a/lua/core/autocmds.lua +++ b/lua/core/autocmds.lua @@ -14,6 +14,11 @@ lvim.autocommands = {        "nnoremap <silent> <buffer> q :q<CR>",      },      { +      "FileType", +      "lsp-installer", +      "nnoremap <silent> <buffer> q :q<CR>", +    }, +    {        "TextYankPost",        "*",        "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})", diff --git a/lua/core/autopairs.lua b/lua/core/autopairs.lua index 24aa1875..eb080fb1 100644 --- a/lua/core/autopairs.lua +++ b/lua/core/autopairs.lua @@ -4,11 +4,13 @@ function M.config()    lvim.builtin.autopairs = {      active = true,      on_config_done = nil, -    ---@usage  map <CR> on insert mode -    map_cr = true,      ---@usage auto insert after select function or method item -    -- NOTE: This should be wrapped into a function so that it is re-evaluated when opening new files -    map_complete = vim.bo.filetype ~= "tex", +    map_complete = true, +    ---@usage  -- modifies the function or method delimiter by filetypes +    map_char = { +      all = "(", +      tex = "{", +    },      ---@usage check treesitter      check_ts = true,      ts_config = { @@ -20,36 +22,46 @@ function M.config()  end  M.setup = function() -  -- skip it, if you use another global object -  _G.MUtils = {}    local autopairs = require "nvim-autopairs"    local Rule = require "nvim-autopairs.rule" +  local cond = require "nvim-autopairs.conds" -  vim.g.completion_confirm_key = "" -  MUtils.completion_confirm = function() -    if vim.fn.pumvisible() ~= 0 then -      if vim.fn.complete_info()["selected"] ~= -1 then -        return vim.fn["compe#confirm"](autopairs.esc "<cr>") -      else -        return autopairs.esc "<cr>" +  autopairs.setup { +    check_ts = lvim.builtin.autopairs.check_ts, +    ts_config = lvim.builtin.autopairs.ts_config, +  } + +  -- vim.g.completion_confirm_key = "" + +  autopairs.add_rule(Rule("$$", "$$", "tex")) +  autopairs.add_rules { +    Rule("$", "$", { "tex", "latex" }) -- don't add a pair if the next character is % +      :with_pair(cond.not_after_regex_check "%%") -- don't add a pair if  the previous character is xxx +      :with_pair(cond.not_before_regex_check("xxx", 3)) -- don't move right when repeat character +      :with_move(cond.none()) -- don't delete if the next character is xx +      :with_del(cond.not_after_regex_check "xx") -- disable  add newline when press <cr> +      :with_cr(cond.none()), +  } +  autopairs.add_rules { +    Rule("$$", "$$", "tex"):with_pair(function(opts) +      print(vim.inspect(opts)) +      if opts.line == "aa $$" then +        -- don't add pair on that line +        return false        end -    else -      return autopairs.autopairs_cr() -    end -  end +    end), +  } -  if package.loaded["compe"] then -    require("nvim-autopairs.completion.compe").setup { -      map_cr = lvim.builtin.autopairs.map_cr, +  if package.loaded["cmp"] then +    require("nvim-autopairs.completion.cmp").setup { +      map_cr = false,        map_complete = lvim.builtin.autopairs.map_complete, +      map_char = lvim.builtin.autopairs.map_char,      } +    -- we map CR explicitly in cmp.lua but we still need to setup the autopairs CR keymap +    vim.api.nvim_set_keymap("i", "<CR>", "v:lua.MPairs.autopairs_cr()", { expr = true, noremap = true })    end -  autopairs.setup { -    check_ts = lvim.builtin.autopairs.check_ts, -    ts_config = lvim.builtin.autopairs.ts_config, -  } -    require("nvim-treesitter.configs").setup { autopairs = { enable = true } }    local ts_conds = require "nvim-autopairs.ts-conds" diff --git a/lua/core/builtins/init.lua b/lua/core/builtins/init.lua index 32f96af5..c3b3618f 100644 --- a/lua/core/builtins/init.lua +++ b/lua/core/builtins/init.lua @@ -4,7 +4,7 @@ local builtins = {    "keymappings",    "core.which-key",    "core.gitsigns", -  "core.compe", +  "core.cmp",    "core.dashboard",    "core.dap",    "core.terminal", @@ -15,7 +15,6 @@ local builtins = {    "core.bufferline",    "core.autopairs",    "core.comment", -  "core.lspinstall",    "core.lualine",  } diff --git a/lua/core/cmp.lua b/lua/core/cmp.lua new file mode 100644 index 00000000..d5d92314 --- /dev/null +++ b/lua/core/cmp.lua @@ -0,0 +1,260 @@ +local M = {} + +local check_backspace = function() +  local col = vim.fn.col "." - 1 +  return col == 0 or vim.fn.getline("."):sub(col, col):match "%s" +end + +local function T(str) +  return vim.api.nvim_replace_termcodes(str, true, true, true) +end + +local is_emmet_active = function() +  local clients = vim.lsp.buf_get_clients() + +  for _, client in pairs(clients) do +    if client.name == "emmet_ls" then +      return true +    end +  end +  return false +end + +M.config = function() +  local status_cmp_ok, cmp = pcall(require, "cmp") +  if not status_cmp_ok then +    return +  end +  local status_luasnip_ok, luasnip = pcall(require, "luasnip") +  if not status_luasnip_ok then +    return +  end +  local win_get_cursor = vim.api.nvim_win_get_cursor +  local get_current_buf = vim.api.nvim_get_current_buf + +  local function inside_snippet() +    -- for outdated versions of luasnip +    if not luasnip.session.current_nodes then +      return false +    end + +    local node = luasnip.session.current_nodes[get_current_buf()] +    if not node then +      return false +    end + +    local snip_begin_pos, snip_end_pos = node.parent.snippet.mark:pos_begin_end() +    local pos = win_get_cursor(0) +    pos[1] = pos[1] - 1 -- LuaSnip is 0-based not 1-based like nvim for rows +    return pos[1] >= snip_begin_pos[1] and pos[1] <= snip_end_pos[1] +  end + +  ---sets the current buffer's luasnip to the one nearest the cursor +  ---@return boolean true if a node is found, false otherwise +  local function seek_luasnip_cursor_node() +    -- for outdated versions of luasnip +    if not luasnip.session.current_nodes then +      return false +    end + +    local pos = win_get_cursor(0) +    pos[1] = pos[1] - 1 +    local node = luasnip.session.current_nodes[get_current_buf()] +    if not node then +      return false +    end + +    local snippet = node.parent.snippet +    local exit_node = snippet.insert_nodes[0] + +    -- exit early if we're past the exit node +    if exit_node then +      local exit_pos_end = exit_node.mark:pos_end() +      if (pos[1] > exit_pos_end[1]) or (pos[1] == exit_pos_end[1] and pos[2] > exit_pos_end[2]) then +        snippet:remove_from_jumplist() +        luasnip.session.current_nodes[get_current_buf()] = nil + +        return false +      end +    end + +    node = snippet.inner_first:jump_into(1, true) +    while node ~= nil and node.next ~= nil and node ~= snippet do +      local n_next = node.next +      local next_pos = n_next and n_next.mark:pos_begin() +      local candidate = n_next ~= snippet and next_pos and (pos[1] < next_pos[1]) +        or (pos[1] == next_pos[1] and pos[2] < next_pos[2]) + +      -- Past unmarked exit node, exit early +      if n_next == nil or n_next == snippet.next then +        snippet:remove_from_jumplist() +        luasnip.session.current_nodes[get_current_buf()] = nil + +        return false +      end + +      if candidate then +        luasnip.session.current_nodes[get_current_buf()] = node +        return true +      end + +      local ok +      ok, node = pcall(node.jump_from, node, 1, true) -- no_move until last stop +      if not ok then +        snippet:remove_from_jumplist() +        luasnip.session.current_nodes[get_current_buf()] = nil + +        return false +      end +    end + +    -- No candidate, but have an exit node +    if exit_node then +      -- to jump to the exit node, seek to snippet +      luasnip.session.current_nodes[get_current_buf()] = snippet +      return true +    end + +    -- No exit node, exit from snippet +    snippet:remove_from_jumplist() +    luasnip.session.current_nodes[get_current_buf()] = nil +    return false +  end + +  lvim.builtin.cmp = { +    confirm_opts = { +      behavior = cmp.ConfirmBehavior.Replace, +      select = false, +    }, +    experimental = { +      ghost_text = true, +      native_menu = false, +    }, +    formatting = { +      kind_icons = { +        Class = " ", +        Color = " ", +        Constant = "ﲀ ", +        Constructor = " ", +        Enum = "練", +        EnumMember = " ", +        Event = " ", +        Field = " ", +        File = "", +        Folder = " ", +        Function = " ", +        Interface = "ﰮ ", +        Keyword = " ", +        Method = " ", +        Module = " ", +        Operator = "", +        Property = " ", +        Reference = " ", +        Snippet = " ", +        Struct = " ", +        Text = " ", +        TypeParameter = " ", +        Unit = "塞", +        Value = " ", +        Variable = " ", +      }, +      format = function(entry, vim_item) +        vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind] +        vim_item.menu = ({ +          nvim_lsp = "(LSP)", +          emoji = "(Emoji)", +          path = "(Path)", +          calc = "(Calc)", +          cmp_tabnine = "(Tabnine)", +          vsnip = "(Snippet)", +          luasnip = "(Snippet)", +          buffer = "(Buffer)", +        })[entry.source.name] +        vim_item.dup = ({ +          buffer = 1, +          path = 1, +          nvim_lsp = 0, +        })[entry.source.name] or 0 +        return vim_item +      end, +    }, +    snippet = { +      expand = function(args) +        require("luasnip").lsp_expand(args.body) +      end, +    }, +    documentation = { +      border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" }, +    }, +    sources = { +      { name = "nvim_lsp" }, +      { name = "path" }, +      { name = "luasnip" }, +      { name = "cmp_tabnine" }, +      { name = "nvim_lua" }, +      { name = "buffer" }, +      { name = "calc" }, +      { name = "emoji" }, +      { name = "treesitter" }, +      { name = "crates" }, +    }, +    mapping = { +      ["<C-d>"] = cmp.mapping.scroll_docs(-4), +      ["<C-f>"] = cmp.mapping.scroll_docs(4), +      -- TODO: potentially fix emmet nonsense +      ["<Tab>"] = cmp.mapping(function() +        if cmp.visible() then +          cmp.select_next_item() +        elseif luasnip.expandable() then +          luasnip.expand() +        elseif inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then +          luasnip.jump(1) +        elseif check_backspace() then +          vim.fn.feedkeys(T "<Tab>", "n") +        elseif is_emmet_active() then +          return vim.fn["cmp#complete"]() +        else +          vim.fn.feedkeys(T "<Tab>", "n") +        end +      end, { +        "i", +        "s", +      }), +      ["<S-Tab>"] = cmp.mapping(function(fallback) +        if cmp.visible() then +          cmp.select_prev_item() +        elseif inside_snippet() and luasnip.jumpable(-1) then +          luasnip.jump(-1) +        else +          fallback() +        end +      end, { +        "i", +        "s", +      }), + +      ["<C-Space>"] = cmp.mapping.complete(), +      ["<C-e>"] = cmp.mapping.close(), +      ["<CR>"] = cmp.mapping(function(fallback) +        if cmp.visible() and cmp.confirm(lvim.builtin.cmp.confirm_opts) then +          return +        end + +        if inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable() then +          if not luasnip.jump(1) then +            fallback() +          end +        else +          fallback() +        end +      end), +    }, +  } +end + +M.setup = function() +  require("luasnip/loaders/from_vscode").lazy_load() +  require("cmp").setup(lvim.builtin.cmp) +end + +return M diff --git a/lua/core/commands.lua b/lua/core/commands.lua index 22170c85..6ceeaaff 100644 --- a/lua/core/commands.lua +++ b/lua/core/commands.lua @@ -11,7 +11,9 @@ M.defaults = {    endfunction    ]],    -- :LvimInfo -  [[command! LvimInfo lua require('core.info').toggle_popup(vim.bo.filetype)]], +  [[ command! LvimInfo lua require('core.info').toggle_popup(vim.bo.filetype) ]], +  [[ command! LvimCacheReset lua require('utils.hooks').reset_cache() ]], +  [[ command! LvimUpdate lua require('bootstrap').update() ]],  }  M.load = function(commands) diff --git a/lua/core/compe.lua b/lua/core/compe.lua deleted file mode 100644 index 9eb3dcfa..00000000 --- a/lua/core/compe.lua +++ /dev/null @@ -1,133 +0,0 @@ -local M = {} - -M.config = function() -  lvim.builtin.compe = { -    active = true, -    on_config_done = nil, -    autocomplete = true, -    debug = false, -    min_length = 1, -    preselect = "enable", -    throttle_time = 80, -    source_timeout = 200, -    incomplete_delay = 400, -    max_abbr_width = 100, -    max_kind_width = 100, -    max_menu_width = 100, -    documentation = { -      border = "single", -      winhighlight = "NormalFloat:CompeDocumentation,FloatBorder:CompeDocumentationBorder", -      max_width = 120, -      min_width = 60, -      max_height = math.floor(vim.o.lines * 0.3), -      min_height = 1, -    }, -    -- documentation = true, - -    source = { -      path = { kind = "   (Path)" }, -      buffer = { kind = "   (Buffer)" }, -      calc = { kind = "   (Calc)" }, -      vsnip = { kind = "   (Snippet)" }, -      nvim_lsp = { kind = "   (LSP)" }, -      nvim_lua = false, -      spell = { kind = "   (Spell)" }, -      tags = false, -      vim_dadbod_completion = false, -      snippets_nvim = false, -      ultisnips = false, -      treesitter = false, -      emoji = { kind = " ﲃ  (Emoji)", filetypes = { "markdown", "text" } }, -      -- for emoji press : (idk if that in compe tho) -    }, - -    keymap = { -      values = { -        insert_mode = { -          -- ["<Tab>"] = { 'pumvisible() ? "<C-n>" : "<Tab>"', { silent = true, noremap = true, expr = true } }, -          -- ["<S-Tab>"] = { 'pumvisible() ? "<C-p>" : "<S-Tab>"', { silent = true, noremap = true, expr = true } }, -          ["<C-Space>"] = { "compe#complete()", { silent = true, noremap = true, expr = true } }, -          ["<C-e>"] = { "compe#close('<C-e>')", { silent = true, noremap = true, expr = true } }, -          ["<C-f>"] = { "compe#scroll({ 'delta': +4 })", { silent = true, noremap = true, expr = true } }, -          ["<C-d>"] = { "compe#scroll({ 'delta': -4 })", { silent = true, noremap = true, expr = true } }, -        }, -      }, -      opts = { -        insert_mode = { noremap = true, silent = true, expr = true }, -      }, -    }, -  } -end - -M.setup = function() -  vim.g.vsnip_snippet_dir = lvim.vsnip_dir - -  local compe = require "compe" - -  compe.setup(lvim.builtin.compe) - -  local t = function(str) -    return vim.api.nvim_replace_termcodes(str, true, true, true) -  end - -  local check_back_space = function() -    local col = vim.fn.col "." - 1 -    if col == 0 or vim.fn.getline("."):sub(col, col):match "%s" then -      return true -    else -      return false -    end -  end - -  local is_emmet_active = function() -    local clients = vim.lsp.buf_get_clients() - -    for _, client in pairs(clients) do -      if client.name == "emmet_ls" then -        return true -      end -    end -    return false -  end - -  -- Use (s-)tab to: -  --- move to prev/next item in completion menuone -  --- jump to prev/next snippet's placeholder -  _G.tab_complete = function() -    if vim.fn.pumvisible() == 1 then -      return t "<C-n>" -    elseif vim.fn.call("vsnip#jumpable", { 1 }) == 1 then -      return t "<Plug>(vsnip-jump-next)" -    elseif check_back_space() then -      return t "<Tab>" -    elseif is_emmet_active() then -      return vim.fn["compe#complete"]() -    else -      return t "<Tab>" -    end -  end - -  _G.s_tab_complete = function() -    if vim.fn.pumvisible() == 1 then -      return t "<C-p>" -    elseif vim.fn.call("vsnip#jumpable", { -1 }) == 1 then -      return t "<Plug>(vsnip-jump-prev)" -    else -      return t "<S-Tab>" -    end -  end - -  local keymap = require "keymappings" -  keymap.load(lvim.builtin.compe.keymap.values, lvim.builtin.compe.keymap.opts) - -  vim.api.nvim_set_keymap("i", "<Tab>", "v:lua.tab_complete()", { expr = true }) -  vim.api.nvim_set_keymap("s", "<Tab>", "v:lua.tab_complete()", { expr = true }) -  vim.api.nvim_set_keymap("i", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true }) -  vim.api.nvim_set_keymap("s", "<S-Tab>", "v:lua.s_tab_complete()", { expr = true }) - -  if lvim.builtin.compe.on_config_done then -    lvim.builtin.compe.on_config_done(compe) -  end -end - -return M diff --git a/lua/core/dap.lua b/lua/core/dap.lua index 5de3b7c4..d9b59641 100644 --- a/lua/core/dap.lua +++ b/lua/core/dap.lua @@ -10,6 +10,18 @@ M.config = function()        linehl = "",        numhl = "",      }, +    breakpoint_rejected = { +      text = "", +      texthl = "LspDiagnosticsSignHint", +      linehl = "", +      numhl = "", +    }, +    stopped = { +      text = "", +      texthl = "LspDiagnosticsSignInformation", +      linehl = "DiagnosticUnderlineInfo", +      numhl = "LspDiagnosticsSignInformation", +    },    }  end @@ -17,6 +29,9 @@ M.setup = function()    local dap = require "dap"    vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint) +  vim.fn.sign_define("DapBreakpointRejected", lvim.builtin.dap.breakpoint_rejected) +  vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped) +    dap.defaults.fallback.terminal_win_cmd = "50vsplit new"    lvim.builtin.which_key.mappings["d"] = { diff --git a/lua/core/dashboard.lua b/lua/core/dashboard.lua index a613921f..505350cb 100644 --- a/lua/core/dashboard.lua +++ b/lua/core/dashboard.lua @@ -1,5 +1,5 @@  local M = {} -local home_dir = vim.loop.os_homedir() +local utils = require "utils"  M.config = function(config)    lvim.builtin.dashboard = { @@ -7,7 +7,7 @@ M.config = function(config)      on_config_done = nil,      search_handler = "telescope",      disable_at_vim_enter = 0, -    session_directory = home_dir .. "/.cache/lvim/sessions", +    session_directory = utils.join_paths(get_cache_dir(), "sessions"),      custom_header = {        "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",        "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣶⣾⠿⠿⠟⠛⠛⠛⠛⠿⠿⣿⣷⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", @@ -69,14 +69,23 @@ M.setup = function()    vim.g.dashboard_session_directory = lvim.builtin.dashboard.session_directory -  vim.cmd "let packages = len(globpath('~/.local/share/lunarvim/site/pack/packer/start', '*', 0, 1))" +  local lvim_site = "lunarvim.org" +  local lvim_version = get_version "short" +  local num_plugins_loaded = #vim.fn.globpath(get_runtime_dir() .. "/site/pack/packer/start", "*", 0, 1) -  vim.api.nvim_exec( -    [[ -    let g:dashboard_custom_footer = ['LunarVim loaded '..packages..' plugins  '] -]], -    false -  ) +  local footer = { +    "LunarVim loaded " .. num_plugins_loaded .. " plugins ", +    "", +    lvim_site, +  } + +  if lvim_version then +    table.insert(footer, 2, "") +    table.insert(footer, 3, "v" .. lvim_version) +  end + +  local text = require "interface.text" +  vim.g.dashboard_custom_footer = text.align_center({ width = 0 }, footer, 0.49) -- Use 0.49 as  counts for 2 characters    require("core.autocmds").define_augroups {      _dashboard = { diff --git a/lua/core/gitsigns.lua b/lua/core/gitsigns.lua index bb9d088b..cc6387dc 100644 --- a/lua/core/gitsigns.lua +++ b/lua/core/gitsigns.lua @@ -44,7 +44,7 @@ M.config = function()          noremap = true,          buffer = true,        }, -      watch_index = { interval = 1000 }, +      watch_gitdir = { interval = 1000 },        sign_priority = 6,        update_debounce = 200,        status_formatter = nil, -- Use default diff --git a/lua/core/info.lua b/lua/core/info.lua index 67e45d1c..16001d07 100644 --- a/lua/core/info.lua +++ b/lua/core/info.lua @@ -10,6 +10,8 @@ local M = {  }  local fmt = string.format +local text = require "interface.text" +local lsp_utils = require "lsp.utils"  local function str_list(list)    return fmt("[ %s ]", table.concat(list, ", ")) @@ -65,44 +67,54 @@ local function tbl_set_highlight(terms, highlight_group)    end  end -function M.toggle_popup(ft) -  local lsp_utils = require "lsp.utils" -  local client = lsp_utils.get_active_client_by_ft(ft) -  local is_client_active = false -  local client_enabled_caps = {} -  local client_name = "" -  local client_id = 0 -  local document_formatting = false -  if client ~= nil then -    is_client_active = not client.is_stopped() -    client_enabled_caps = require("lsp").get_ls_capabilities(client.id) -    client_name = client.name -    client_id = client.id -    document_formatting = client.resolved_capabilities.document_formatting +local function make_client_info(client) +  local client_enabled_caps = lsp_utils.get_client_capabilities(client.id) +  local name = client.name +  local id = client.id +  local document_formatting = client.resolved_capabilities.document_formatting +  local client_info = { +    fmt("* Name:                 %s", name), +    fmt("* Id:                   %s", tostring(id)), +    fmt("* Supports formatting:  %s", tostring(document_formatting)), +  } +  if not vim.tbl_isempty(client_enabled_caps) then +    local caps_text = "* Capabilities list:    " +    local caps_text_len = caps_text:len() +    local enabled_caps = text.format_table(client_enabled_caps, 3, " | ") +    enabled_caps = text.shift_right(enabled_caps, caps_text_len) +    enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1)) +    vim.list_extend(client_info, enabled_caps)    end +  return client_info +end + +function M.toggle_popup(ft) +  local clients = lsp_utils.get_active_clients_by_ft(ft) +  local client_names = {} +    local header = {      fmt("Detected filetype:      %s", ft),      fmt("Treesitter active:      %s", tostring(next(vim.treesitter.highlighter.active) ~= nil)),    } -  local text = require "interface.text"    local lsp_info = {      "Language Server Protocol (LSP) info", -    fmt("* Associated server:    %s", client_name), -    fmt("* Active:               %s (id: %d)", tostring(is_client_active), client_id), -    fmt("* Supports formatting:  %s", tostring(document_formatting)), +    fmt "* Associated server(s):",    } -  if not vim.tbl_isempty(client_enabled_caps) then -    local caps_text = "* Capabilities list:    " -    local caps_text_len = caps_text:len() -    local enabled_caps = text.format_table(client_enabled_caps, 3, " | ") -    enabled_caps = text.shift_left(enabled_caps, caps_text_len) -    enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1)) -    vim.list_extend(lsp_info, enabled_caps) + +  for _, client in pairs(clients) do +    vim.list_extend(lsp_info, make_client_info(client)) +    table.insert(client_names, client.name)    end -  local null_ls = require "lsp.null-ls" -  local registered_providers = null_ls.list_supported_provider_names(ft) + +  local null_formatters = require "lsp.null-ls.formatters" +  local null_linters = require "lsp.null-ls.linters" +  local registered_formatters = null_formatters.list_supported_names(ft) +  local registered_linters = null_linters.list_supported_names(ft) +  local registered_providers = {} +  vim.list_extend(registered_providers, registered_formatters) +  vim.list_extend(registered_providers, registered_linters)    local registered_count = vim.tbl_count(registered_providers)    local null_ls_info = {      "Formatters and linters", @@ -113,24 +125,6 @@ function M.toggle_popup(ft)      ),    } -  local null_formatters = require "lsp.null-ls.formatters" -  local missing_formatters = null_formatters.list_unsupported_names(ft) -  local missing_formatters_status = {} -  if not vim.tbl_isempty(missing_formatters) then -    missing_formatters_status = { -      fmt("* Missing formatters:   %s", table.concat(missing_formatters, "  , ") .. "  "), -    } -  end - -  local null_linters = require "lsp.null-ls.linters" -  local missing_linters = null_linters.list_unsupported_names(ft) -  local missing_linters_status = {} -  if not vim.tbl_isempty(missing_linters) then -    missing_linters_status = { -      fmt("* Missing linters:      %s", table.concat(missing_linters, "  , ") .. "  "), -    } -  end -    local content_provider = function(popup)      local content = {} @@ -143,8 +137,6 @@ function M.toggle_popup(ft)        lsp_info,        { "" },        null_ls_info, -      missing_formatters_status, -      missing_linters_status,        { "" },        { "" },        get_formatter_suggestion_msg(ft), @@ -155,7 +147,7 @@ function M.toggle_popup(ft)        vim.list_extend(content, section)      end -    return text.align(popup, content, 0.5) +    return text.align_left(popup, content, 0.5)    end    local function set_syntax_hl() @@ -167,11 +159,8 @@ function M.toggle_popup(ft)      vim.cmd 'let m=matchadd("string", "true")'      vim.cmd 'let m=matchadd("error", "false")'      tbl_set_highlight(registered_providers, "LvimInfoIdentifier") -    tbl_set_highlight(missing_formatters, "LvimInfoIdentifier") -    tbl_set_highlight(missing_linters, "LvimInfoIdentifier")      -- tbl_set_highlight(require("lsp.null-ls.formatters").list_available(ft), "LvimInfoIdentifier")      -- tbl_set_highlight(require("lsp.null-ls.linters").list_available(ft), "LvimInfoIdentifier") -    vim.cmd('let m=matchadd("LvimInfoIdentifier", "' .. client_name .. '")')    end    local Popup = require("interface.popup"):new { diff --git a/lua/core/log.lua b/lua/core/log.lua index 1eb786ba..fca1fcb4 100644 --- a/lua/core/log.lua +++ b/lua/core/log.lua @@ -8,6 +8,7 @@ function Log:add_entry(msg, level)    if self.__handle then      -- plenary uses lower-case log levels      self.__handle[level:lower()](msg) +    return    end    local status_ok, plenary = pcall(require, "plenary")    if status_ok then diff --git a/lua/core/lspinstall.lua b/lua/core/lspinstall.lua deleted file mode 100644 index 0bb59e0e..00000000 --- a/lua/core/lspinstall.lua +++ /dev/null @@ -1,19 +0,0 @@ -local M = {} - -M.config = function() -  lvim.builtin.lspinstall = { -    active = true, -    on_config_done = nil, -  } -end - -M.setup = function() -  local lspinstall = require "lspinstall" -  lspinstall.setup() - -  if lvim.builtin.lspinstall.on_config_done then -    lvim.builtin.lspinstall.on_config_done(lspinstall) -  end -end - -return M diff --git a/lua/core/lualine/components.lua b/lua/core/lualine/components.lua index 894d9e9b..3ee2fdf8 100644 --- a/lua/core/lualine/components.lua +++ b/lua/core/lualine/components.lua @@ -17,31 +17,32 @@ return {      function()        return " "      end, -    left_padding = 0, -    right_padding = 0, +    padding = { left = 0, right = 0 },      color = {}, -    condition = nil, +    cond = nil,    },    branch = {      "b:gitsigns_head",      icon = " ",      color = { gui = "bold" }, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,    },    filename = {      "filename",      color = {}, -    condition = nil, +    cond = nil,    },    diff = {      "diff",      source = diff_source,      symbols = { added = "  ", modified = "柳", removed = " " }, -    color_added = { fg = colors.green }, -    color_modified = { fg = colors.yellow }, -    color_removed = { fg = colors.red }, +    diff_color = { +      added = { fg = colors.green }, +      modified = { fg = colors.yellow }, +      removed = { fg = colors.red }, +    },      color = {}, -    condition = nil, +    cond = nil,    },    python_env = {      function() @@ -60,44 +61,46 @@ return {        return ""      end,      color = { fg = colors.green }, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,    },    diagnostics = {      "diagnostics",      sources = { "nvim_lsp" },      symbols = { error = " ", warn = " ", info = " ", hint = " " },      color = {}, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,    },    treesitter = {      function() -      if next(vim.treesitter.highlighter.active) then +      local b = vim.api.nvim_get_current_buf() +      if next(vim.treesitter.highlighter.active[b]) then          return "  "        end        return ""      end,      color = { fg = colors.green }, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,    },    lsp = {      function(msg) -      msg = msg or "LSP Inactive" +      msg = msg or "LS Inactive"        local buf_clients = vim.lsp.buf_get_clients()        if next(buf_clients) == nil then +        -- TODO: clean up this if statement +        if type(msg) == "boolean" or #msg == 0 then +          return "LS Inactive" +        end          return msg        end        local buf_ft = vim.bo.filetype        local buf_client_names = {}        -- add client -      local utils = require "lsp.utils" -      local active_client = utils.get_active_client_by_ft(buf_ft)        for _, client in pairs(buf_clients) do          if client.name ~= "null-ls" then            table.insert(buf_client_names, client.name)          end        end -      vim.list_extend(buf_client_names, active_client or {})        -- add formatter        local formatters = require "lsp.null-ls.formatters" @@ -113,10 +116,10 @@ return {      end,      icon = " ",      color = { gui = "bold" }, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,    }, -  location = { "location", condition = conditions.hide_in_width, color = {} }, -  progress = { "progress", condition = conditions.hide_in_width, color = {} }, +  location = { "location", cond = conditions.hide_in_width, color = {} }, +  progress = { "progress", cond = conditions.hide_in_width, color = {} },    spaces = {      function()        local label = "Spaces: " @@ -125,16 +128,16 @@ return {        end        return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " "      end, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,      color = {},    },    encoding = {      "o:encoding", -    upper = true, +    fmt = string.upper,      color = {}, -    condition = conditions.hide_in_width, +    cond = conditions.hide_in_width,    }, -  filetype = { "filetype", condition = conditions.hide_in_width, color = {} }, +  filetype = { "filetype", cond = conditions.hide_in_width, color = {} },    scrollbar = {      function()        local current_line = vim.fn.line "." @@ -144,9 +147,8 @@ return {        local index = math.ceil(line_ratio * #chars)        return chars[index]      end, -    left_padding = 0, -    right_padding = 0, +    padding = { left = 0, right = 0 },      color = { fg = colors.yellow, bg = colors.bg }, -    condition = nil, +    cond = nil,    },  } diff --git a/lua/core/lualine/styles.lua b/lua/core/lualine/styles.lua index 3595e5e3..19097424 100644 --- a/lua/core/lualine/styles.lua +++ b/lua/core/lualine/styles.lua @@ -11,8 +11,8 @@ styles.none = {    style = "none",    options = {      icons_enabled = true, -    component_separators = "", -    section_separators = "", +    component_separators = { left = "", right = "" }, +    section_separators = { left = "", right = "" },      disabled_filetypes = {},    },    sections = { @@ -39,8 +39,8 @@ styles.default = {    style = "default",    options = {      icons_enabled = true, -    component_separators = { "", "" }, -    section_separators = { "", "" }, +    component_separators = { left = "", right = "" }, +    section_separators = { left = "", right = "" },      disabled_filetypes = {},    },    sections = { @@ -67,8 +67,8 @@ styles.lvim = {    style = "lvim",    options = {      icons_enabled = true, -    component_separators = "", -    section_separators = "", +    component_separators = { left = "", right = "" }, +    section_separators = { left = "", right = "" },      disabled_filetypes = { "dashboard", "NvimTree", "Outline" },    },    sections = { diff --git a/lua/core/nvimtree.lua b/lua/core/nvimtree.lua index 6aa5401d..55cc6175 100644 --- a/lua/core/nvimtree.lua +++ b/lua/core/nvimtree.lua @@ -5,8 +5,23 @@ function M.config()    lvim.builtin.nvimtree = {      active = true,      on_config_done = nil, -    side = "left", -    width = 30, +    setup = { +      open_on_setup = 0, +      auto_close = 1, +      open_on_tab = 0, +      update_focused_file = { +        enable = 1, +      }, +      lsp_diagnostics = 1, +      view = { +        width = 30, +        side = "left", +        auto_resize = false, +        mappings = { +          custom_only = false, +        }, +      }, +    },      show_icons = {        git = 1,        folders = 1, @@ -15,16 +30,11 @@ function M.config()        tree_width = 30,      },      ignore = { ".git", "node_modules", ".cache" }, -    auto_open = 0, -    auto_close = 1,      quit_on_open = 0, -    follow = 1,      hide_dotfiles = 1,      git_hl = 1,      root_folder_modifier = ":t", -    tab_open = 0,      allow_resize = 1, -    lsp_diagnostics = 1,      auto_ignore_ft = { "startify", "dashboard" },      icons = {        default = "", @@ -63,17 +73,17 @@ function M.setup()    -- Implicitly update nvim-tree when project module is active    if lvim.builtin.project.active then -    vim.g.nvim_tree_update_cwd = 1 -    vim.g.nvim_tree_respect_buf_cwd = 1 -    vim.g.nvim_tree_disable_netrw = 0 -    vim.g.nvim_tree_hijack_netrw = 0 +    lvim.builtin.nvimtree.respect_buf_cwd = 1 +    lvim.builtin.nvimtree.setup.update_cwd = 1 +    lvim.builtin.nvimtree.setup.disable_netrw = 0 +    lvim.builtin.nvimtree.setup.hijack_netrw = 0      vim.g.netrw_banner = 0    end    local tree_cb = nvim_tree_config.nvim_tree_callback -  if not g.nvim_tree_bindings then -    g.nvim_tree_bindings = { +  if not lvim.builtin.nvimtree.setup.view.mappings.list then +    lvim.builtin.nvimtree.setup.view.mappings.list = {        { key = { "l", "<CR>", "o" }, cb = tree_cb "edit" },        { key = "h", cb = tree_cb "close_node" },        { key = "v", cb = tree_cb "vsplit" }, @@ -96,11 +106,12 @@ function M.setup()    if lvim.builtin.nvimtree.on_config_done then      lvim.builtin.nvimtree.on_config_done(nvim_tree_config)    end +  require("nvim-tree").setup(lvim.builtin.nvimtree.setup)  end  function M.on_open() -  if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then -    require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "") +  if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.setup.view.side == "left" then +    require("bufferline.state").set_offset(lvim.builtin.nvimtree.setup.view.width + 1, "")    end  end diff --git a/lua/core/project.lua b/lua/core/project.lua index 7fb04933..e7527440 100644 --- a/lua/core/project.lua +++ b/lua/core/project.lua @@ -35,7 +35,7 @@ function M.config()      ---@type string      ---@usage path to store the project history for use in telescope -    datapath = CACHE_PATH, +    datapath = get_cache_dir(),    }  end diff --git a/lua/core/telescope.lua b/lua/core/telescope.lua index 4ae56df0..ba0a9ee1 100644 --- a/lua/core/telescope.lua +++ b/lua/core/telescope.lua @@ -1,5 +1,7 @@  local M = {} +local utils = require "utils" +  function M.config()    -- Define this minimal config so that it's available if telescope is not yet available.    lvim.builtin.telescope = { @@ -24,7 +26,6 @@ function M.config()        layout_strategy = "horizontal",        layout_config = {          width = 0.75, -        prompt_position = "bottom",          preview_cutoff = 120,          horizontal = { mirror = false },          vertical = { mirror = false }, @@ -87,16 +88,11 @@ function M.find_lunarvim_files(opts)    opts = opts or {}    local themes = require "telescope.themes"    local theme_opts = themes.get_ivy { -    previewer = false,      sorting_strategy = "ascending",      layout_strategy = "bottom_pane", -    layout_config = { -      height = 5, -      width = 0.5, -    }, -    prompt = ">> ", +    prompt_prefix = ">> ",      prompt_title = "~ LunarVim files ~", -    cwd = CONFIG_PATH, +    cwd = utils.join_paths(get_runtime_dir(), "lvim"),      find_command = { "git", "ls-files" },    }    opts = vim.tbl_deep_extend("force", theme_opts, opts) @@ -109,14 +105,79 @@ function M.grep_lunarvim_files(opts)    local theme_opts = themes.get_ivy {      sorting_strategy = "ascending",      layout_strategy = "bottom_pane", -    prompt = ">> ", +    prompt_prefix = ">> ",      prompt_title = "~ search LunarVim ~", -    cwd = CONFIG_PATH, +    cwd = utils.join_paths(get_runtime_dir(), "lvim"),    }    opts = vim.tbl_deep_extend("force", theme_opts, opts)    require("telescope.builtin").live_grep(opts)  end +function M.view_lunarvim_changelog() +  local finders = require "telescope.finders" +  local make_entry = require "telescope.make_entry" +  local pickers = require "telescope.pickers" +  local previewers = require "telescope.previewers" +  local actions = require "telescope.actions" +  local opts = {} + +  local conf = require("telescope.config").values +  opts.entry_maker = make_entry.gen_from_git_commits(opts) + +  pickers.new(opts, { +    prompt_title = "LunarVim changelog", + +    finder = finders.new_oneshot_job( +      vim.tbl_flatten { +        "git", +        "log", +        "--pretty=oneline", +        "--abbrev-commit", +        "--", +        ".", +      }, +      opts +    ), +    previewer = { +      previewers.git_commit_diff_to_parent.new(opts), +      previewers.git_commit_diff_to_head.new(opts), +      previewers.git_commit_diff_as_was.new(opts), +      previewers.git_commit_message.new(opts), +    }, + +    --TODO: consider opening a diff view when pressing enter +    attach_mappings = function(_, map) +      map("i", "<enter>", actions._close) +      map("n", "<enter>", actions._close) +      map("i", "<esc>", actions._close) +      map("n", "<esc>", actions._close) +      map("n", "q", actions._close) +      return true +    end, +    sorter = conf.file_sorter(opts), +  }):find() +end + +function M.code_actions() +  local opts = { +    winblend = 15, +    layout_config = { +      prompt_position = "top", +      width = 80, +      height = 12, +    }, +    borderchars = { +      prompt = { "─", "│", " ", "│", "╭", "╮", "│", "│" }, +      results = { "─", "│", "─", "│", "├", "┤", "╯", "╰" }, +      preview = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" }, +    }, +    border = {}, +    previewer = false, +    shorten_path = false, +  } +  require("telescope.builtin").lsp_code_actions(require("telescope.themes").get_dropdown(opts)) +end +  function M.setup()    local telescope = require "telescope" diff --git a/lua/core/terminal.lua b/lua/core/terminal.lua index f9be8734..3a0c6e46 100644 --- a/lua/core/terminal.lua +++ b/lua/core/terminal.lua @@ -1,5 +1,5 @@  local M = {} -local utils = require "utils" +local Log = require "core.log"  M.config = function()    lvim.builtin["terminal"] = { @@ -81,7 +81,6 @@ end  M._exec_toggle = function(exec)    local binary = M._split(exec)[1]    if vim.fn.executable(binary) ~= 1 then -    local Log = require "core.log"      Log:error("Unable to run executable " .. binary .. ". Please make sure it is installed properly.")      return    end @@ -90,29 +89,16 @@ M._exec_toggle = function(exec)    exec_term:toggle()  end -local function get_log_path(name) -  --handle custom paths not managed by Plenary.log -  local logger = require "core.log" -  local file -  if name == "nvim" then -    file = CACHE_PATH .. "/log" -  else -    file = logger:new({ plugin = name }):get_path() -  end -  if utils.is_file(file) then -    return file -  end -end -  ---Toggles a log viewer according to log.viewer.layout_config ----@param name can be the name of any of the managed logs, e,g. "lunarvim" or the default ones {"nvim", "lsp", "packer.nvim"} -M.toggle_log_view = function(name) -  local logfile = get_log_path(name) -  if not logfile then -    return +---@param logfile string the fullpath to the logfile +M.toggle_log_view = function(logfile) +  local log_viewer = lvim.log.viewer.cmd +  if vim.fn.executable(log_viewer) ~= 1 then +    log_viewer = "less +F"    end +  log_viewer = log_viewer .. " " .. logfile    local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, { -    cmd = lvim.log.viewer.cmd .. " " .. logfile, +    cmd = log_viewer,      open_mapping = lvim.log.viewer.layout_config.open_mapping,      direction = lvim.log.viewer.layout_config.direction,      -- TODO: this might not be working as expected @@ -122,7 +108,6 @@ M.toggle_log_view = function(name)    local Terminal = require("toggleterm.terminal").Terminal    local log_view = Terminal:new(term_opts) -  -- require("core.log"):debug("term", vim.inspect(term_opts))    log_view:toggle()  end diff --git a/lua/core/which-key.lua b/lua/core/which-key.lua index 71c0b695..c9e9b2f4 100644 --- a/lua/core/which-key.lua +++ b/lua/core/which-key.lua @@ -72,25 +72,26 @@ M.config = function()        ["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },        b = {          name = "Buffers", -        j = { "<cmd>BufferPick<cr>", "jump to buffer" }, -        f = { "<cmd>Telescope buffers<cr>", "Find buffer" }, -        w = { "<cmd>BufferWipeout<cr>", "wipeout buffer" }, +        j = { "<cmd>BufferPick<cr>", "Jump" }, +        f = { "<cmd>Telescope buffers<cr>", "Find" }, +        b = { "<cmd>b#<cr>", "Previous" }, +        w = { "<cmd>BufferWipeout<cr>", "Wipeout" },          e = {            "<cmd>BufferCloseAllButCurrent<cr>", -          "close all but current buffer", +          "Close all but current",          }, -        h = { "<cmd>BufferCloseBuffersLeft<cr>", "close all buffers to the left" }, +        h = { "<cmd>BufferCloseBuffersLeft<cr>", "Close all to the left" },          l = {            "<cmd>BufferCloseBuffersRight<cr>", -          "close all BufferLines to the right", +          "Close all to the right",          },          D = {            "<cmd>BufferOrderByDirectory<cr>", -          "sort BufferLines automatically by directory", +          "Sort by directory",          },          L = {            "<cmd>BufferOrderByLanguage<cr>", -          "sort BufferLines automatically by language", +          "Sort by language",          },        },        p = { @@ -130,11 +131,15 @@ M.config = function()            "<cmd>Telescope git_bcommits<cr>",            "Checkout commit(for current file)",          }, +        d = { +          "<cmd>Gitsigns diffthis HEAD<cr>", +          "Git Diff", +        },        },        l = {          name = "LSP", -        a = { "<cmd>lua vim.lsp.buf.code_action()<cr>", "Code Action" }, +        a = { "<cmd>lua require('core.telescope').code_actions()<cr>", "Code Action" },          d = {            "<cmd>Telescope lsp_document_diagnostics<cr>",            "Document Diagnostics", @@ -143,9 +148,9 @@ M.config = function()            "<cmd>Telescope lsp_workspace_diagnostics<cr>",            "Workspace Diagnostics",          }, -        -- f = { "<cmd>silent FormatWrite<cr>", "Format" },          f = { "<cmd>lua vim.lsp.buf.formatting()<cr>", "Format" },          i = { "<cmd>LspInfo<cr>", "Info" }, +        I = { "<cmd>LspInstallInfo<cr>", "Installer Info" },          j = {            "<cmd>lua vim.lsp.diagnostic.goto_next({popup_opts = {border = lvim.lsp.popup_border}})<cr>",            "Next Diagnostic", @@ -154,6 +159,7 @@ M.config = function()            "<cmd>lua vim.lsp.diagnostic.goto_prev({popup_opts = {border = lvim.lsp.popup_border}})<cr>",            "Prev Diagnostic",          }, +        l = { "<cmd>lua vim.lsp.codelens.run()<cr>", "CodeLens Action" },          p = {            name = "Peek",            d = { "<cmd>lua require('lsp.peek').Peek('definition')<cr>", "Definition" }, @@ -171,7 +177,7 @@ M.config = function()        L = {          name = "+LunarVim",          c = { -          "<cmd>edit ~/.config/lvim/config.lua<cr>", +          "<cmd>edit" .. get_config_dir() .. "/config.lua<cr>",            "Edit config.lua",          },          f = { @@ -187,23 +193,32 @@ M.config = function()            "<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>",            "Toggle LunarVim Info",          }, +        I = { +          "<cmd>lua require('core.telescope').view_lunarvim_changelog()<cr>", +          "View LunarVim's changelog", +        },          l = {            name = "+logs",            d = { -            "<cmd>lua require('core.terminal').toggle_log_view('lunarvim')<cr>", +            "<cmd>lua require('core.terminal').toggle_log_view(require('core.log').get_path())<cr>",              "view default log",            }, -          D = { "<cmd>edit ~/.cache/nvim/lunarvim.log<cr>", "Open the default logfile" }, -          n = { "<cmd>lua require('core.terminal').toggle_log_view('lsp')<cr>", "view lsp log" }, -          N = { "<cmd>edit ~/.cache/nvim/log<cr>", "Open the Neovim logfile" }, -          l = { "<cmd>lua require('core.terminal').toggle_log_view('nvim')<cr>", "view neovim log" }, -          L = { "<cmd>edit ~/.cache/nvim/lsp.log<cr>", "Open the LSP logfile" }, +          D = { "<cmd>lua vim.fn.execute('edit ' .. require('core.log').get_path())<cr>", "Open the default logfile" }, +          l = { "<cmd>lua require('core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>", "view lsp log" }, +          L = { "<cmd>lua vim.fn.execute('edit ' .. vim.lsp.get_log_path())<cr>", "Open the LSP logfile" }, +          n = { +            "<cmd>lua require('core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>", +            "view neovim log", +          }, +          N = { "<cmd>edit $NVIM_LOG_FILE<cr>", "Open the Neovim logfile" },            p = {              "<cmd>lua require('core.terminal').toggle_log_view('packer.nvim')<cr>",              "view packer log",            }, -          P = { "<cmd>edit ~/.cache/nvim/packer.nvim.log<cr>", "Open the Packer logfile" }, +          P = { "<cmd>exe 'edit '.stdpath('cache').'/packer.nvim.log'<cr>", "Open the Packer logfile" },          }, +        r = { "<cmd>lua require('utils').reload_lv_config()<cr>", "Reload configurations" }, +        u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },        },        s = {          name = "Search", diff --git a/lua/impatient.lua b/lua/impatient.lua new file mode 100644 index 00000000..d438851c --- /dev/null +++ b/lua/impatient.lua @@ -0,0 +1,360 @@ +-- modified version from https://github.com/lewis6991/impatient.nvim + +local vim = vim +local uv = vim.loop +local impatient_load_start = uv.hrtime() +local api = vim.api +local ffi = require "ffi" + +local get_option, set_option = api.nvim_get_option, api.nvim_set_option +local get_runtime_file = api.nvim_get_runtime_file + +local impatient_dur + +local M = { +  cache = {}, +  profile = nil, +  dirty = false, +  path = nil, +  log = {}, +} + +_G.__luacache = M + +--{{{ +local cachepack = {} + +-- using double for packing/unpacking numbers has no conversion overhead +-- 32-bit ARM causes a bus error when casting to double, so use int there +local number_t = jit.arch ~= "arm" and "double" or "int" +ffi.cdef("typedef " .. number_t .. " number_t;") + +local c_number_t = ffi.typeof "number_t[1]" +local c_sizeof_number_t = ffi.sizeof "number_t" + +local out_buf = {} + +function out_buf.write_number(buf, num) +  buf[#buf + 1] = ffi.string(c_number_t(num), c_sizeof_number_t) +end + +function out_buf.write_string(buf, str) +  out_buf.write_number(buf, #str) +  buf[#buf + 1] = str +end + +function out_buf.to_string(buf) +  return table.concat(buf) +end + +local in_buf = {} + +function in_buf.read_number(buf) +  if buf.size < buf.pos then +    error "buffer access violation" +  end +  local res = ffi.cast("number_t*", buf.ptr + buf.pos)[0] +  buf.pos = buf.pos + c_sizeof_number_t +  return res +end + +function in_buf.read_string(buf) +  local len = in_buf.read_number(buf) +  local res = ffi.string(buf.ptr + buf.pos, len) +  buf.pos = buf.pos + len + +  return res +end + +function cachepack.pack(cache) +  local total_keys = vim.tbl_count(cache) +  local buf = {} + +  out_buf.write_number(buf, total_keys) +  for k, v in pairs(cache) do +    out_buf.write_string(buf, k) +    out_buf.write_string(buf, v[1] or "") +    out_buf.write_number(buf, v[2] or 0) +    out_buf.write_string(buf, v[3] or "") +  end + +  return out_buf.to_string(buf) +end + +function cachepack.unpack(str, raw_buf_size) +  if raw_buf_size == 0 or str == nil or (raw_buf_size == nil and #str == 0) then +    return {} +  end + +  local buf = { +    ptr = raw_buf_size and str or ffi.new("const char[?]", #str, str), +    pos = 0, +    size = raw_buf_size or #str, +  } +  local cache = {} + +  local total_keys = in_buf.read_number(buf) +  for _ = 1, total_keys do +    local k = in_buf.read_string(buf) +    local v = { +      in_buf.read_string(buf), +      in_buf.read_number(buf), +      in_buf.read_string(buf), +    } +    cache[k] = v +  end + +  return cache +end +--}}} + +local function log(...) +  M.log[#M.log + 1] = table.concat({ string.format(...) }, " ") +end + +function M.print_log() +  for _, l in ipairs(M.log) do +    print(l) +  end +end + +function M.enable_profile() +  M.profile = {} +  M.print_profile = function() +    M.profile["impatient"] = { +      resolve = 0, +      load = impatient_dur, +      loader = "standard", +    } +    require("impatient.profile").print_profile(M.profile) +  end +  vim.cmd [[command! LuaCacheProfile lua _G.__luacache.print_profile()]] +end + +local function is_cacheable(path) +  -- Don't cache files in /tmp since they are not likely to persist. +  -- Note: Appimage versions of Neovim mount $VIMRUNTIME in /tmp in a unique +  -- directory on each launch. +  return not vim.startswith(path, "/tmp/") +end + +local function hash(modpath) +  local stat = uv.fs_stat(modpath) +  if stat then +    return stat.mtime.sec +  end +end + +local function hrtime() +  if M.profile then +    return uv.hrtime() +  end +end + +local function load_package_with_cache(name, loader) +  local resolve_start = hrtime() + +  local basename = name:gsub("%.", "/") +  local paths = { "lua/" .. basename .. ".lua", "lua/" .. basename .. "/init.lua" } + +  for _, path in ipairs(paths) do +    local modpath = get_runtime_file(path, false)[1] +    if modpath then +      local load_start = hrtime() +      local chunk, err = loadfile(modpath) + +      if M.profile then +        M.profile[name] = { +          resolve = load_start - resolve_start, +          load = hrtime() - load_start, +          loader = loader or "standard", +        } +      end + +      if chunk == nil then +        return err +      end + +      if is_cacheable(modpath) then +        log("Creating cache for module %s", name) +        M.cache[name] = { modpath, hash(modpath), string.dump(chunk) } +        M.dirty = true +      else +        log("Unable to cache module %s", name) +      end + +      return chunk +    end +  end +  return nil +end + +local reduced_rtp + +-- Speed up non-cached loads by reducing the rtp path during requires +function M.update_reduced_rtp() +  local luadirs = get_runtime_file("lua/", true) + +  for i = 1, #luadirs do +    luadirs[i] = luadirs[i]:sub(1, -6) +  end + +  reduced_rtp = table.concat(luadirs, ",") +end + +local function load_package_with_cache_reduced_rtp(name) +  local orig_rtp = get_option "runtimepath" +  local orig_ei = get_option "eventignore" + +  if not reduced_rtp then +    M.update_reduced_rtp() +  end + +  set_option("eventignore", "all") +  set_option("rtp", reduced_rtp) + +  local found = load_package_with_cache(name, "reduced") + +  set_option("rtp", orig_rtp) +  set_option("eventignore", orig_ei) + +  return found +end + +local function load_from_cache(name) +  local resolve_start = hrtime() +  if M.cache[name] == nil then +    log("No cache for module %s", name) +    return "No cache entry" +  end + +  local modpath, mhash, codes = unpack(M.cache[name]) + +  if mhash ~= hash(modpath) then +    log("Stale cache for module %s", name) +    M.cache[name] = nil +    M.dirty = true +    return "Stale cache" +  end + +  local load_start = hrtime() +  local chunk = loadstring(codes) + +  if M.profile then +    M.profile[name] = { +      resolve = load_start - resolve_start, +      load = hrtime() - load_start, +      loader = "cache", +    } +  end + +  if not chunk then +    M.cache[name] = nil +    M.dirty = true +    log("Error loading cache for module. Invalidating", name) +    return "Cache error" +  end + +  return chunk +end + +function M.save_cache() +  if M.dirty then +    log("Updating cache file: %s", M.path) +    local f = io.open(M.path, "w+b") +    f:write(cachepack.pack(M.cache)) +    f:flush() +    M.dirty = false +  end +end + +function M.clear_cache() +  M.cache = {} +  os.remove(M.path) +end + +impatient_dur = uv.hrtime() - impatient_load_start + +function M.setup(opts) +  opts = opts or {} +  M.path = opts.path or vim.fn.stdpath "cache" .. "/lvim_cache" + +  if opts.enable_profiling then +    M.enable_profile() +  end + +  local impatient_setup_start = uv.hrtime() +  local stat = uv.fs_stat(M.path) +  if stat then +    log("Loading cache file %s", M.path) +    local ok +    -- Linux/macOS lets us easily mmap the cache file for faster reads without passing to Lua +    if jit.os == "Linux" or jit.os == "OSX" then +      local size = stat.size + +      local C = ffi.C +      local O_RDONLY = 0x00 +      local PROT_READ = 0x01 +      local MAP_PRIVATE = 0x02 + +      ffi.cdef [[ +      int open(const char *pathname, int flags); +      int close(int fd); +      void *mmap(void *addr, size_t length, int prot, int flags, int fd, long int offset); +      int munmap(void *addr, size_t length); +      ]] +      local f = C.open(M.path, O_RDONLY) + +      local addr = C.mmap(nil, size, PROT_READ, MAP_PRIVATE, f, 0) +      ok = ffi.cast("intptr_t", addr) ~= -1 + +      if ok then +        M.cache = cachepack.unpack(ffi.cast("char *", addr), size) +        C.munmap(addr, size) +      end + +      C.close(f) +    else +      local f = io.open(M.path, "rb") +      ok, M.cache = pcall(function() +        return cachepack.unpack(f:read "*a") +      end) +    end + +    if not ok then +      log("Corrupted cache file, %s. Invalidating...", M.path) +      os.remove(M.path) +      M.cache = {} +    end +    M.dirty = not ok +  end + +  local insert = table.insert +  local package = package + +  -- Fix the position of the preloader. This also makes loading modules like 'ffi' +  -- and 'bit' quicker +  if package.loaders[1] == vim._load_package then +    -- Move vim._load_package to the second position +    local vim_load = table.remove(package.loaders, 1) +    insert(package.loaders, 2, vim_load) +  end + +  insert(package.loaders, 2, load_from_cache) +  insert(package.loaders, 3, load_package_with_cache_reduced_rtp) +  insert(package.loaders, 4, load_package_with_cache) + +  vim.cmd [[ +    augroup impatient +      autocmd VimEnter,VimLeave * lua _G.__luacache.save_cache() +      autocmd OptionSet runtimepath lua _G.__luacache.update_reduced_rtp(true) +    augroup END + +    command! LuaCacheClear lua _G.__luacache.clear_cache() +    command! LuaCacheLog   lua _G.__luacache.print_log() +  ]] + +  impatient_dur = impatient_dur + (uv.hrtime() - impatient_setup_start) +end + +return M diff --git a/lua/impatient/profile.lua b/lua/impatient/profile.lua new file mode 100644 index 00000000..0f4f8236 --- /dev/null +++ b/lua/impatient/profile.lua @@ -0,0 +1,145 @@ +local M = {} + +local api = vim.api + +function M.print_profile(profile) +  if not profile then +    print "Error: profiling was not enabled" +    return +  end + +  local total_resolve = 0 +  local total_load = 0 +  local name_pad = 0 +  local modules = {} +  local plugins = {} + +  for module, p in pairs(profile) do +    p.resolve = p.resolve / 1000000 +    p.load = p.load / 1000000 +    p.total = p.resolve + p.load +    p.module = module:gsub("/", ".") + +    local plugin = p.module:match "([^.]+)" +    if plugin then +      if not plugins[plugin] then +        plugins[plugin] = { +          module = plugin, +          resolve = 0, +          load = 0, +          total = 0, +        } +      end +      local r = plugins[plugin] + +      r.resolve = r.resolve + p.resolve +      r.load = r.load + p.load +      r.total = r.total + p.total + +      if not r.loader then +        r.loader = p.loader +      elseif r.loader ~= p.loader then +        r.loader = "mixed" +      end +    end + +    total_resolve = total_resolve + p.resolve +    total_load = total_load + p.load + +    if #module > name_pad then +      name_pad = #module +    end + +    modules[#modules + 1] = p +  end + +  table.sort(modules, function(a, b) +    return a.module > b.module +  end) + +  do +    local plugins_a = {} +    for _, v in pairs(plugins) do +      plugins_a[#plugins_a + 1] = v +    end +    plugins = plugins_a +  end + +  table.sort(plugins, function(a, b) +    return a.total > b.total +  end) + +  local lines = {} +  local function add(...) +    lines[#lines + 1] = string.format(...) +  end + +  local l = string.rep("─", name_pad + 1) + +  add( +    "%s┬───────────┬────────────┬────────────┬────────────┐", +    l +  ) +  add("%-" .. name_pad .. "s │ Loader    │ Resolve    │ Load       │ Total      │", "") +  add( +    "%s┼───────────┼────────────┼────────────┼────────────┤", +    l +  ) +  add( +    "%-" .. name_pad .. "s │           │ %8.4fms │ %8.4fms │ %8.4fms │", +    "Total", +    total_resolve, +    total_load, +    total_resolve + total_load +  ) +  add( +    "%s┴───────────┴────────────┴────────────┴────────────┤", +    l +  ) +  add("%-" .. name_pad .. "s                                                    │", "By Plugin") +  add( +    "%s┬───────────┬────────────┬────────────┬────────────┤", +    l +  ) +  for _, p in ipairs(plugins) do +    add( +      "%-" .. name_pad .. "s │ %9s │ %8.4fms │ %8.4fms │ %8.4fms │", +      p.module, +      p.loader, +      p.resolve, +      p.load, +      p.total +    ) +  end +  add( +    "%s┴───────────┴────────────┴────────────┴────────────┤", +    l +  ) +  add("%-" .. name_pad .. "s                                                    │", "By Module") +  add( +    "%s┬───────────┬────────────┬────────────┬────────────┤", +    l +  ) +  for _, p in pairs(modules) do +    add( +      "%-" .. name_pad .. "s │ %9s │ %8.4fms │ %8.4fms │ %8.4fms │", +      p.module, +      p.loader, +      p.resolve, +      p.load, +      p.total +    ) +  end +  add( +    "%s┴───────────┴────────────┴────────────┴────────────┘", +    l +  ) + +  local bufnr = api.nvim_create_buf(false, false) +  api.nvim_buf_set_lines(bufnr, 0, 0, false, lines) +  api.nvim_buf_set_option(bufnr, "buftype", "nofile") +  api.nvim_buf_set_name(bufnr, "Impatient Profile Report") +  api.nvim_set_current_buf(bufnr) +end + +return M diff --git a/lua/interface/text.lua b/lua/interface/text.lua index f68cc491..6bf280e8 100644 --- a/lua/interface/text.lua +++ b/lua/interface/text.lua @@ -13,20 +13,36 @@ local function max_len_line(lines)    return max_len  end ---- Center align lines relatively to the parent container +--- Left align lines relatively to the parent container  -- @param container The container where lines will be displayed  -- @param lines The text to align  -- @param alignment The alignment value, range: [0-1] -function M.align(container, lines, alignment) +function M.align_left(container, lines, alignment)    local max_len = max_len_line(lines)    local indent_amount = math.ceil(math.max(container.width - max_len, 0) * alignment) -  return M.shift_left(lines, indent_amount) +  return M.shift_right(lines, indent_amount) +end + +--- Center align lines relatively to the parent container +-- @param container The container where lines will be displayed +-- @param lines The text to align +-- @param alignment The alignment value, range: [0-1] +function M.align_center(container, lines, alignment) +  local output = {} +  local max_len = max_len_line(lines) + +  for _, line in ipairs(lines) do +    local padding = string.rep(" ", (math.max(container.width, max_len) - line:len()) * alignment) +    table.insert(output, padding .. line) +  end + +  return output  end  --- Shift lines by a given amount  -- @params lines The lines the shift  -- @param amount The amount of spaces to add -function M.shift_left(lines, amount) +function M.shift_right(lines, amount)    local output = {}    local padding = string.rep(" ", amount) diff --git a/lua/keymappings.lua b/lua/keymappings.lua index 557e0bde..027ca83f 100644 --- a/lua/keymappings.lua +++ b/lua/keymappings.lua @@ -83,8 +83,8 @@ function M.config()        ["<A-Right>"] = "<C-\\><C-N><C-w>l",        -- navigate tab completion with <c-j> and <c-k>        -- runs conditionally -      ["<C-j>"] = { 'pumvisible() ? "\\<C-n>" : "\\<C-j>"', { expr = true, noremap = true } }, -      ["<C-k>"] = { 'pumvisible() ? "\\<C-p>" : "\\<C-k>"', { expr = true, noremap = true } }, +      ["<C-j>"] = { 'pumvisible() ? "\\<down>" : "\\<C-j>"', { expr = true, noremap = true } }, +      ["<C-k>"] = { 'pumvisible() ? "\\<up>" : "\\<C-k>"', { expr = true, noremap = true } },      },      ---@usage change or add keymappings for normal mode diff --git a/lua/lsp/config.lua b/lua/lsp/config.lua new file mode 100644 index 00000000..f13d9659 --- /dev/null +++ b/lua/lsp/config.lua @@ -0,0 +1,45 @@ +return { +  templates_dir = join_paths(get_runtime_dir(), "site", "after", "ftplugin"), +  diagnostics = { +    signs = { +      active = true, +      values = { +        { name = "LspDiagnosticsSignError", text = "" }, +        { name = "LspDiagnosticsSignWarning", text = "" }, +        { name = "LspDiagnosticsSignHint", text = "" }, +        { name = "LspDiagnosticsSignInformation", text = "" }, +      }, +    }, +    virtual_text = true, +    update_in_insert = false, +    underline = true, +    severity_sort = true, +  }, +  override = {}, +  document_highlight = true, +  code_lens_refresh = true, +  popup_border = "single", +  on_attach_callback = nil, +  on_init_callback = nil, +  automatic_servers_installation = true, +  buffer_mappings = { +    normal_mode = { +      ["K"] = { "<cmd>lua vim.lsp.buf.hover()<CR>", "Show hover" }, +      ["gd"] = { "<cmd>lua vim.lsp.buf.definition()<CR>", "Goto Definition" }, +      ["gD"] = { "<cmd>lua vim.lsp.buf.declaration()<CR>", "Goto declaration" }, +      ["gr"] = { "<cmd>lua vim.lsp.buf.references()<CR>", "Goto references" }, +      ["gI"] = { "<cmd>lua vim.lsp.buf.implementation()<CR>", "Goto Implementation" }, +      ["gs"] = { "<cmd>lua vim.lsp.buf.signature_help()<CR>", "show signature help" }, +      ["gp"] = { "<cmd>lua require'lsp.peek'.Peek('definition')<CR>", "Peek definition" }, +      ["gl"] = { +        "<cmd>lua require'lsp.handlers'.show_line_diagnostics()<CR>", +        "Show line diagnostics", +      }, +    }, +    insert_mode = {}, +    visual_mode = {}, +  }, +  null_ls = { +    setup = {}, +  }, +} diff --git a/lua/lsp/handlers.lua b/lua/lsp/handlers.lua index 2322e76a..ffb7564a 100644 --- a/lua/lsp/handlers.lua +++ b/lua/lsp/handlers.lua @@ -3,52 +3,73 @@  local M = {}  function M.setup() -  vim.lsp.handlers["textDocument/publishDiagnostics"] = vim.lsp.with(vim.lsp.diagnostic.on_publish_diagnostics, { +  local config = { -- your config      virtual_text = lvim.lsp.diagnostics.virtual_text, -    signs = lvim.lsp.diagnostics.signs.active, -    underline = lvim.lsp.document_highlight, -  }) - -  vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _) -    local config = { -- your config -      virtual_text = lvim.lsp.diagnostics.virtual_text, -      signs = lvim.lsp.diagnostics.signs, -      underline = lvim.lsp.diagnostics.underline, -      update_in_insert = lvim.lsp.diagnostics.update_in_insert, -      severity_sort = lvim.lsp.diagnostics.severity_sort, -    } -    local uri = params.uri -    local bufnr = vim.uri_to_bufnr(uri) +    signs = lvim.lsp.diagnostics.signs, +    underline = lvim.lsp.diagnostics.underline, +    update_in_insert = lvim.lsp.diagnostics.update_in_insert, +    severity_sort = lvim.lsp.diagnostics.severity_sort, +  } +  if vim.fn.has "nvim-0.5.1" > 0 then +    vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, result, ctx, _) +      local uri = result.uri +      local bufnr = vim.uri_to_bufnr(uri) +      if not bufnr then +        return +      end -    if not bufnr then -      return -    end +      local diagnostics = result.diagnostics +      local ok, vim_diag = pcall(require, "vim.diagnostic") +      if ok then +        -- FIX: why can't we just use vim.diagnostic.get(buf_id)? +        config.signs = true +        for i, diagnostic in ipairs(diagnostics) do +          local rng = diagnostic.range +          diagnostics[i].lnum = rng["start"].line +          diagnostics[i].end_lnum = rng["end"].line +          diagnostics[i].col = rng["start"].character +          diagnostics[i].end_col = rng["end"].character +        end +        local namespace = vim.lsp.diagnostic.get_namespace(ctx.client_id) -    local diagnostics = params.diagnostics +        vim_diag.set(namespace, bufnr, diagnostics, config) +        if not vim.api.nvim_buf_is_loaded(bufnr) then +          return +        end -    for i, v in ipairs(diagnostics) do -      local source = v.source -      if source then -        if string.find(source, "/") then -          source = string.sub(v.source, string.find(v.source, "([%w-_]+)$")) +        local sign_names = { +          "DiagnosticSignError", +          "DiagnosticSignWarn", +          "DiagnosticSignInfo", +          "DiagnosticSignHint", +        } +        for i, sign in ipairs(lvim.lsp.diagnostics.signs.values) do +          vim.fn.sign_define(sign_names[i], { texthl = sign_names[i], text = sign.text, numhl = "" })          end -        diagnostics[i].message = string.format("%s: %s", source, v.message) +        vim_diag.show(namespace, bufnr, diagnostics, config)        else -        diagnostics[i].message = string.format("%s", v.message) -      end - -      if vim.tbl_contains(vim.tbl_keys(v), "code") then -        diagnostics[i].message = diagnostics[i].message .. string.format(" [%s]", v.code) +        vim.lsp.diagnostic.save(diagnostics, bufnr, ctx.client_id) +        if not vim.api.nvim_buf_is_loaded(bufnr) then +          return +        end +        vim.lsp.diagnostic.display(diagnostics, bufnr, ctx.client_id, config)        end      end +  else +    vim.lsp.handlers["textDocument/publishDiagnostics"] = function(_, _, params, client_id, _) +      local uri = params.uri +      local bufnr = vim.uri_to_bufnr(uri) +      if not bufnr then +        return +      end -    vim.lsp.diagnostic.save(diagnostics, bufnr, client_id) - -    if not vim.api.nvim_buf_is_loaded(bufnr) then -      return +      local diagnostics = params.diagnostics +      vim.lsp.diagnostic.save(diagnostics, bufnr, client_id) +      if not vim.api.nvim_buf_is_loaded(bufnr) then +        return +      end +      vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config)      end - -    vim.lsp.diagnostic.display(diagnostics, bufnr, client_id, config)    end    vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, { @@ -60,4 +81,89 @@ function M.setup()    })  end +local function split_by_chunk(text, chunkSize) +  local s = {} +  for i = 1, #text, chunkSize do +    s[#s + 1] = text:sub(i, i + chunkSize - 1) +  end +  return s +end + +function M.show_line_diagnostics() +  -- TODO: replace all this with vim.diagnostic.show_position_diagnostics() +  local diagnostics = vim.lsp.diagnostic.get_line_diagnostics() +  local severity_highlight = { +    "LspDiagnosticsFloatingError", +    "LspDiagnosticsFloatingWarning", +    "LspDiagnosticsFloatingInformation", +    "LspDiagnosticsFloatingHint", +  } +  local ok, vim_diag = pcall(require, "vim.diagnostic") +  if ok then +    local buf_id = vim.api.nvim_win_get_buf(0) +    local win_id = vim.api.nvim_get_current_win() +    local cursor_position = vim.api.nvim_win_get_cursor(win_id) +    severity_highlight = { +      "DiagnosticFloatingError", +      "DiagnosticFloatingWarn", +      "DiagnosticFloatingInfo", +      "DiagnosticFloatingHint", +    } +    diagnostics = vim_diag.get(buf_id, { lnum = cursor_position[1] - 1 }) +  end +  local lines = {} +  local max_width = vim.fn.winwidth(0) - 5 +  local height = #diagnostics +  local width = 0 +  local opts = {} +  local close_events = { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" } +  if height == 0 then +    return +  end +  local bufnr = vim.api.nvim_create_buf(false, true) +  local diag_message +  table.sort(diagnostics, function(a, b) +    return a.severity < b.severity +  end) +  for i, diagnostic in ipairs(diagnostics) do +    local source = diagnostic.source +    diag_message = diagnostic.message:gsub("[\n\r]", " ") +    if source then +      if string.find(source, "/") then +        source = string.sub(diagnostic.source, string.find(diagnostic.source, "([%w-_]+)$")) +      end +      diag_message = string.format("%d. %s: %s", i, source, diag_message) +    else +      diag_message = string.format("%d. %s", i, diag_message) +    end +    if diagnostic.code then +      diag_message = string.format("%s [%s]", diag_message, diagnostic.code) +    end +    local msgs = split_by_chunk(diag_message, max_width) +    for _, diag in ipairs(msgs) do +      table.insert(lines, { message = diag, severity = diagnostic.severity }) +      width = math.max(diag:len(), width) +    end +  end +  height = #lines +  opts = vim.lsp.util.make_floating_popup_options(width, height, opts) +  opts["style"] = "minimal" +  opts["border"] = "rounded" +  opts["focusable"] = true + +  vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe") +  local winnr = vim.api.nvim_open_win(bufnr, false, opts) +  vim.api.nvim_win_set_option(winnr, "winblend", 0) +  vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr) +  for i, diag in ipairs(lines) do +    vim.api.nvim_buf_set_lines(bufnr, i - 1, i - 1, 0, { diag.message }) +    vim.api.nvim_buf_add_highlight(bufnr, -1, severity_highlight[diag.severity], i - 1, 0, diag.message:len()) +  end + +  vim.api.nvim_command( +    "autocmd QuitPre <buffer> ++nested ++once lua pcall(vim.api.nvim_win_close, " .. winnr .. ", true)" +  ) +  vim.lsp.util.close_preview_autocmd(close_events, winnr) +end +  return M diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index 9c948803..88111005 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -1,15 +1,6 @@  local M = {}  local Log = require "core.log" - -function M.config() -  vim.lsp.protocol.CompletionItemKind = lvim.lsp.completion.item_kind - -  for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do -    vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) -  end - -  require("lsp.handlers").setup() -end +local utils = require "utils"  local function lsp_highlight_document(client)    if lvim.lsp.document_highlight == false then @@ -19,9 +10,6 @@ local function lsp_highlight_document(client)    if client.resolved_capabilities.document_highlight then      vim.api.nvim_exec(        [[ -      hi LspReferenceRead cterm=bold ctermbg=red guibg=#464646 -      hi LspReferenceText cterm=bold ctermbg=red guibg=#464646 -      hi LspReferenceWrite cterm=bold ctermbg=red guibg=#464646        augroup lsp_document_highlight          autocmd! * <buffer>          autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight() @@ -33,26 +21,49 @@ local function lsp_highlight_document(client)    end  end -local function add_lsp_buffer_keybindings(bufnr) -  local status_ok, wk = pcall(require, "which-key") -  if not status_ok then +local function lsp_code_lens_refresh(client) +  if lvim.lsp.code_lens_refresh == false then      return    end -  local keys = { -    ["K"] = { "<cmd>lua vim.lsp.buf.hover()<CR>", "Show hover" }, -    ["gd"] = { "<cmd>lua vim.lsp.buf.definition()<CR>", "Goto Definition" }, -    ["gD"] = { "<cmd>lua vim.lsp.buf.declaration()<CR>", "Goto declaration" }, -    ["gr"] = { "<cmd>lua vim.lsp.buf.references()<CR>", "Goto references" }, -    ["gI"] = { "<cmd>lua vim.lsp.buf.implementation()<CR>", "Goto Implementation" }, -    ["gs"] = { "<cmd>lua vim.lsp.buf.signature_help()<CR>", "show signature help" }, -    ["gp"] = { "<cmd>lua require'lsp.peek'.Peek('definition')<CR>", "Peek definition" }, -    ["gl"] = { -      "<cmd>lua vim.lsp.diagnostic.show_line_diagnostics({ show_header = false, border = 'single' })<CR>", -      "Show line diagnostics", -    }, +  if client.resolved_capabilities.code_lens then +    vim.api.nvim_exec( +      [[ +      augroup lsp_code_lens_refresh +        autocmd! * <buffer> +        autocmd InsertLeave <buffer> lua vim.lsp.codelens.refresh() +        autocmd InsertLeave <buffer> lua vim.lsp.codelens.display() +      augroup END +    ]], +      false +    ) +  end +end + +local function add_lsp_buffer_keybindings(bufnr) +  local mappings = { +    normal_mode = "n", +    insert_mode = "i", +    visual_mode = "v",    } -  wk.register(keys, { mode = "n", buffer = bufnr }) + +  if lvim.builtin.which_key.active then +    -- Remap using which_key +    local status_ok, wk = pcall(require, "which-key") +    if not status_ok then +      return +    end +    for mode_name, mode_char in pairs(mappings) do +      wk.register(lvim.lsp.buffer_mappings[mode_name], { mode = mode_char, buffer = bufnr }) +    end +  else +    -- Remap using nvim api +    for mode_name, mode_char in pairs(mappings) do +      for key, remap in pairs(lvim.lsp.buffer_mappings[mode_name]) do +        vim.api.nvim_buf_set_keymap(bufnr, mode_char, key, remap[1], { noremap = true, silent = true }) +      end +    end +  end  end  function M.common_capabilities() @@ -65,35 +76,30 @@ function M.common_capabilities()        "additionalTextEdits",      },    } -  return capabilities -end -function M.get_ls_capabilities(client_id) -  local client -  if not client_id then -    local buf_clients = vim.lsp.buf_get_clients() -    for _, buf_client in ipairs(buf_clients) do -      if buf_client.name ~= "null-ls" then -        client_id = buf_client.id -        break -      end -    end -  end -  if not client_id then -    error "Unable to determine client_id" +  local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp") +  if status_ok then +    capabilities = cmp_nvim_lsp.update_capabilities(capabilities)    end -  client = vim.lsp.get_client_by_id(tonumber(client_id)) - -  local enabled_caps = {} +  return capabilities +end -  for k, v in pairs(client.resolved_capabilities) do -    if v == true then -      table.insert(enabled_caps, k) +local function select_default_formater(client) +  local client_formatting = client.resolved_capabilities.document_formatting +    or client.resolved_capabilities.document_range_formatting +  if client.name == "null-ls" or not client_formatting then +    return +  end +  Log:debug("Checking for formatter overriding for " .. client.name) +  local client_filetypes = client.config.filetypes or {} +  for _, filetype in ipairs(client_filetypes) do +    if lvim.lang[filetype] and #vim.tbl_keys(lvim.lang[filetype].formatters) > 0 then +      Log:debug("Formatter overriding detected. Disabling formatting capabilities for " .. client.name) +      client.resolved_capabilities.document_formatting = false +      client.resolved_capabilities.document_range_formatting = false      end    end - -  return enabled_caps  end  function M.common_on_init(client, bufnr) @@ -102,55 +108,58 @@ function M.common_on_init(client, bufnr)      Log:debug "Called lsp.on_init_callback"      return    end - -  local formatters = lvim.lang[vim.bo.filetype].formatters -  if not vim.tbl_isempty(formatters) and formatters[1]["exe"] ~= nil and formatters[1].exe ~= "" then -    client.resolved_capabilities.document_formatting = false -    Log:debug( -      string.format("Overriding language server [%s] with format provider [%s]", client.name, formatters[1].exe) -    ) -  end +  select_default_formater(client)  end  function M.common_on_attach(client, bufnr)    if lvim.lsp.on_attach_callback then      lvim.lsp.on_attach_callback(client, bufnr) -    Log:debug "Called lsp.on_init_callback" +    Log:debug "Called lsp.on_attach_callback"    end    lsp_highlight_document(client) +  lsp_code_lens_refresh(client)    add_lsp_buffer_keybindings(bufnr) -  require("lsp.null-ls").setup(vim.bo.filetype)  end -function M.setup(lang) -  local lsp_utils = require "lsp.utils" -  local lsp = lvim.lang[lang].lsp -  if lsp_utils.is_client_active(lsp.provider) then -    return +local function bootstrap_nlsp(opts) +  opts = opts or {} +  local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings") +  if lsp_settings_status_ok then +    lsp_settings.setup(opts)    end +end -  local overrides = lvim.lsp.override -  if type(overrides) == "table" then -    if vim.tbl_contains(overrides, lang) then -      return -    end +function M.get_common_opts() +  return { +    on_attach = M.common_on_attach, +    on_init = M.common_on_init, +    capabilities = M.common_capabilities(), +  } +end + +function M.setup() +  Log:debug "Setting up LSP support" + +  local lsp_status_ok, _ = pcall(require, "lspconfig") +  if not lsp_status_ok then +    return    end -  if lsp.provider ~= nil and lsp.provider ~= "" then -    local lspconfig = require "lspconfig" +  for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do +    vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name }) +  end -    if not lsp.setup.on_attach then -      lsp.setup.on_attach = M.common_on_attach -    end -    if not lsp.setup.on_init then -      lsp.setup.on_init = M.common_on_init -    end -    if not lsp.setup.capabilities then -      lsp.setup.capabilities = M.common_capabilities() -    end +  require("lsp.handlers").setup() -    lspconfig[lsp.provider].setup(lsp.setup) +  if not utils.is_directory(lvim.lsp.templates_dir) then +    require("lsp.templates").generate_templates()    end + +  bootstrap_nlsp { config_home = utils.join_paths(get_config_dir(), "lsp-settings") } + +  require("lsp.null-ls").setup() + +  require("utils").toggle_autoformat()  end  return M diff --git a/lua/lsp/manager.lua b/lua/lsp/manager.lua new file mode 100644 index 00000000..9cb81910 --- /dev/null +++ b/lua/lsp/manager.lua @@ -0,0 +1,86 @@ +local M = {} + +local Log = require "core.log" +local lsp_utils = require "lsp.utils" + +function M.init_defaults(languages) +  for _, entry in ipairs(languages) do +    if not lvim.lang[entry] then +      lvim.lang[entry] = { +        formatters = {}, +        linters = {}, +        lsp = {}, +      } +    end +  end +end + +local function is_overridden(server) +  local overrides = lvim.lsp.override +  if type(overrides) == "table" then +    if vim.tbl_contains(overrides, server) then +      return true +    end +  end +end + +---Resolve the configuration for a server based on both common and user configuration +---@param name string +---@param user_config table [optional] +---@return table +local function resolve_config(name, user_config) +  local config = { +    on_attach = require("lsp").common_on_attach, +    on_init = require("lsp").common_on_init, +    capabilities = require("lsp").common_capabilities(), +  } + +  local status_ok, custom_config = pcall(require, "lsp/providers/" .. name) +  if status_ok then +    Log:debug("Using custom configuration for requested server: " .. name) +    config = vim.tbl_deep_extend("force", config, custom_config) +  end + +  if user_config then +    config = vim.tbl_deep_extend("force", config, user_config) +  end + +  return config +end + +---Setup a language server by providing a name +---@param server_name string name of the language server +---@param user_config table [optional] when available it will take predence over any default configurations +function M.setup(server_name, user_config) +  vim.validate { name = { server_name, "string" } } + +  if lsp_utils.is_client_active(server_name) or is_overridden(server_name) then +    return +  end + +  local config = resolve_config(server_name, user_config) +  local server_available, requested_server = require("nvim-lsp-installer.servers").get_server(server_name) + +  local function ensure_installed(server) +    if server:is_installed() then +      return true +    end +    if not lvim.lsp.automatic_servers_installation then +      Log:debug(server.name .. " is not managed by the automatic installer") +      return false +    end +    Log:debug(string.format("Installing [%s]", server.name)) +    server:install() +    vim.schedule(function() +      vim.cmd [[LspStart]] +    end) +  end + +  if server_available and ensure_installed(requested_server) then +    requested_server:setup(config) +  else +    require("lspconfig")[server_name].setup(config) +  end +end + +return M diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua index 26be00da..4728b908 100644 --- a/lua/lsp/null-ls/formatters.lua +++ b/lua/lsp/null-ls/formatters.lua @@ -1,36 +1,23 @@  local M = {} -local formatters_by_ft = {}  local null_ls = require "null-ls"  local services = require "lsp.null-ls.services"  local Log = require "core.log" -local function list_names(formatters, options) -  options = options or {} -  local filter = options.filter or "supported" - -  return vim.tbl_keys(formatters[filter]) -end -  function M.list_supported_names(filetype) -  if not formatters_by_ft[filetype] then -    return {} -  end -  return list_names(formatters_by_ft[filetype], { filter = "supported" }) -end - -function M.list_unsupported_names(filetype) -  if not formatters_by_ft[filetype] then -    return {} -  end -  return list_names(formatters_by_ft[filetype], { filter = "unsupported" }) +  local null_ls_methods = require "null-ls.methods" +  local formatter_method = null_ls_methods.internal["FORMATTING"] +  local registered_providers = services.list_registered_providers_names(filetype) +  return registered_providers[formatter_method] or {}  end  function M.list_available(filetype)    local formatters = {} +  local tbl = require "utils.table"    for _, provider in pairs(null_ls.builtins.formatting) do -    -- TODO: Add support for wildcard filetypes -    if vim.tbl_contains(provider.filetypes or {}, filetype) then +    if tbl.contains(provider.filetypes or {}, function(ft) +      return ft == "*" or ft == filetype +    end) then        table.insert(formatters, provider.name)      end    end @@ -42,19 +29,24 @@ function M.list_configured(formatter_configs)    local formatters, errors = {}, {}    for _, fmt_config in ipairs(formatter_configs) do -    local formatter = null_ls.builtins.formatting[fmt_config.exe] +    local formatter_name = fmt_config.exe:gsub("-", "_") +    local formatter = null_ls.builtins.formatting[formatter_name]      if not formatter then -      Log:error("Not a valid formatter:", fmt_config.exe) +      Log:error("Not a valid formatter: " .. fmt_config.exe)        errors[fmt_config.exe] = {} -- Add data here when necessary      else        local formatter_cmd = services.find_command(formatter._opts.command)        if not formatter_cmd then -        Log:warn("Not found:", formatter._opts.command) +        Log:warn("Not found: " .. formatter._opts.command)          errors[fmt_config.exe] = {} -- Add data here when necessary        else -        Log:debug("Using formatter:", formatter_cmd) -        formatters[fmt_config.exe] = formatter.with { command = formatter_cmd, extra_args = fmt_config.args } +        Log:debug("Using formatter: " .. formatter_cmd) +        formatters[fmt_config.exe] = formatter.with { +          command = formatter_cmd, +          extra_args = fmt_config.args, +          filetypes = fmt_config.filetypes, +        }        end      end    end @@ -62,13 +54,13 @@ function M.list_configured(formatter_configs)    return { supported = formatters, unsupported = errors }  end -function M.setup(filetype, options) -  if not lvim.lang[filetype] or (formatters_by_ft[filetype] and not options.force_reload) then +function M.setup(formatter_configs) +  if vim.tbl_isempty(formatter_configs) then      return    end -  formatters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].formatters) -  null_ls.register { sources = formatters_by_ft[filetype].supported } +  local formatters_by_ft = M.list_configured(formatter_configs) +  null_ls.register { sources = formatters_by_ft.supported }  end  return M diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua index ce4c07d9..0d030c22 100644 --- a/lua/lsp/null-ls/init.lua +++ b/lua/lsp/null-ls/init.lua @@ -1,44 +1,32 @@  local M = {} -function M.list_supported_provider_names(filetype) -  local names = {} - -  local formatters = require "lsp.null-ls.formatters" -  local linters = require "lsp.null-ls.linters" - -  vim.list_extend(names, formatters.list_supported_names(filetype)) -  vim.list_extend(names, linters.list_supported_names(filetype)) - -  return names -end - -function M.list_unsupported_provider_names(filetype) -  local names = {} - -  local formatters = require "lsp.null-ls.formatters" -  local linters = require "lsp.null-ls.linters" - -  vim.list_extend(names, formatters.list_unsupported_names(filetype)) -  vim.list_extend(names, linters.list_unsupported_names(filetype)) - -  return names -end - --- TODO: for linters and formatters with spaces and '-' replace with '_' -function M.setup(filetype, options) -  options = options or {} - -  local ok, _ = pcall(require, "null-ls") -  if not ok then -    require("core.log"):error "Missing null-ls dependency" +local Log = require "core.log" +local formatters = require "lsp.null-ls.formatters" +local linters = require "lsp.null-ls.linters" + +function M:setup() +  local status_ok, null_ls = pcall(require, "null-ls") +  if not status_ok then +    Log:error "Missing null-ls dependency"      return    end -  local formatters = require "lsp.null-ls.formatters" -  local linters = require "lsp.null-ls.linters" - -  formatters.setup(filetype, options) -  linters.setup(filetype, options) +  null_ls.config() +  require("lspconfig")["null-ls"].setup(lvim.lsp.null_ls.setup) +  for filetype, config in pairs(lvim.lang) do +    if not vim.tbl_isempty(config.formatters) then +      vim.tbl_map(function(c) +        c.filetypes = { filetype } +      end, config.formatters) +      formatters.setup(config.formatters) +    end +    if not vim.tbl_isempty(config.linters) then +      vim.tbl_map(function(c) +        c.filetypes = { filetype } +      end, config.formatters) +      linters.setup(config.linters) +    end +  end  end  return M diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua index bc191d7e..549c6cdd 100644 --- a/lua/lsp/null-ls/linters.lua +++ b/lua/lsp/null-ls/linters.lua @@ -1,36 +1,23 @@  local M = {} -local linters_by_ft = {}  local null_ls = require "null-ls"  local services = require "lsp.null-ls.services"  local Log = require "core.log" -local function list_names(linters, options) -  options = options or {} -  local filter = options.filter or "supported" - -  return vim.tbl_keys(linters[filter]) -end -  function M.list_supported_names(filetype) -  if not linters_by_ft[filetype] then -    return {} -  end -  return list_names(linters_by_ft[filetype], { filter = "supported" }) -end - -function M.list_unsupported_names(filetype) -  if not linters_by_ft[filetype] then -    return {} -  end -  return list_names(linters_by_ft[filetype], { filter = "unsupported" }) +  local null_ls_methods = require "null-ls.methods" +  local linter_method = null_ls_methods.internal["DIAGNOSTICS"] +  local registered_providers = services.list_registered_providers_names(filetype) +  return registered_providers[linter_method] or {}  end  function M.list_available(filetype)    local linters = {} +  local tbl = require "utils.table"    for _, provider in pairs(null_ls.builtins.diagnostics) do -    -- TODO: Add support for wildcard filetypes -    if vim.tbl_contains(provider.filetypes or {}, filetype) then +    if tbl.contains(provider.filetypes or {}, function(ft) +      return ft == "*" or ft == filetype +    end) then        table.insert(linters, provider.name)      end    end @@ -42,19 +29,24 @@ function M.list_configured(linter_configs)    local linters, errors = {}, {}    for _, lnt_config in pairs(linter_configs) do -    local linter = null_ls.builtins.diagnostics[lnt_config.exe] +    local linter_name = lnt_config.exe:gsub("-", "_") +    local linter = null_ls.builtins.diagnostics[linter_name]      if not linter then -      Log:error("Not a valid linter:", lnt_config.exe) +      Log:error("Not a valid linter: " .. lnt_config.exe)        errors[lnt_config.exe] = {} -- Add data here when necessary      else        local linter_cmd = services.find_command(linter._opts.command)        if not linter_cmd then -        Log:warn("Not found:", linter._opts.command) +        Log:warn("Not found: " .. linter._opts.command)          errors[lnt_config.exe] = {} -- Add data here when necessary        else -        Log:debug("Using linter:", linter_cmd) -        linters[lnt_config.exe] = linter.with { command = linter_cmd, extra_args = lnt_config.args } +        Log:debug("Using linter: " .. linter_cmd) +        linters[lnt_config.exe] = linter.with { +          command = linter_cmd, +          extra_args = lnt_config.args, +          filetypes = lnt_config.filetypes, +        }        end      end    end @@ -62,13 +54,13 @@ function M.list_configured(linter_configs)    return { supported = linters, unsupported = errors }  end -function M.setup(filetype, options) -  if not lvim.lang[filetype] or (linters_by_ft[filetype] and not options.force_reload) then +function M.setup(linter_configs) +  if vim.tbl_isempty(linter_configs) then      return    end -  linters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].linters) -  null_ls.register { sources = linters_by_ft[filetype].supported } +  local linters = M.list_configured(linter_configs) +  null_ls.register { sources = linters.supported }  end  return M diff --git a/lua/lsp/null-ls/services.lua b/lua/lsp/null-ls/services.lua index a1e3a06c..ef9e7d22 100644 --- a/lua/lsp/null-ls/services.lua +++ b/lua/lsp/null-ls/services.lua @@ -4,8 +4,8 @@ local function find_root_dir()    local util = require "lspconfig/util"    local lsp_utils = require "lsp.utils" -  local status_ok, ts_client = lsp_utils.is_client_active "typescript" -  if status_ok then +  local ts_client = lsp_utils.is_client_active "typescript" +  if ts_client then      return ts_client.config.root_dir    end    local dirname = vim.fn.expand "%:p:h" @@ -28,6 +28,7 @@ local local_providers = {    prettier_d_slim = { find = from_node_modules },    eslint_d = { find = from_node_modules },    eslint = { find = from_node_modules }, +  stylelint = { find = from_node_modules },  }  function M.find_command(command) @@ -44,4 +45,19 @@ function M.find_command(command)    return nil  end +function M.list_registered_providers_names(filetype) +  local u = require "null-ls.utils" +  local c = require "null-ls.config" +  local registered = {} +  for method, source in pairs(c.get()._methods) do +    for name, filetypes in pairs(source) do +      if u.filetype_matches(filetypes, filetype) then +        registered[method] = registered[method] or {} +        table.insert(registered[method], name) +      end +    end +  end +  return registered +end +  return M diff --git a/lua/lsp/peek.lua b/lua/lsp/peek.lua index cc8e57a9..cb00488e 100644 --- a/lua/lsp/peek.lua +++ b/lua/lsp/peek.lua @@ -42,6 +42,7 @@ local function create_floating_file(location, opts)    local winnr = vim.api.nvim_open_win(bufnr, false, opts)    vim.api.nvim_win_set_option(winnr, "winblend", 0) +  vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character })    vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr)    -- Set some autocmds to close the window @@ -53,9 +54,8 @@ local function create_floating_file(location, opts)    return bufnr, winnr  end -local function preview_location_callback(_, method, result) +local function preview_location_callback(result)    if result == nil or vim.tbl_isempty(result) then -    print("peek: No location found: " .. method)      return nil    end @@ -73,6 +73,14 @@ local function preview_location_callback(_, method, result)    end  end +local function preview_location_callback_old_signature(_, _, result) +  return preview_location_callback(result) +end + +local function preview_location_callback_new_signature(_, result) +  return preview_location_callback(result) +end +  function M.open_file()    -- Get the file currently open in the floating window    local filepath = vim.fn.expand "%:." @@ -128,7 +136,11 @@ function M.Peek(what)    else      -- Make a new request and then create the new window in the callback      local params = vim.lsp.util.make_position_params() -    local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_location_callback) +    local preview_callback = preview_location_callback_old_signature +    if vim.fn.has "nvim-0.5.1" > 0 then +      preview_callback = preview_location_callback_new_signature +    end +    local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)      if not success then        print(          'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.' diff --git a/lua/lsp/providers/jsonls.lua b/lua/lsp/providers/jsonls.lua new file mode 100644 index 00000000..1fffa686 --- /dev/null +++ b/lua/lsp/providers/jsonls.lua @@ -0,0 +1,197 @@ +local default_schemas = nil +local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls") +if status_ok then +  default_schemas = jsonls_settings.get_default_schemas() +end + +local schemas = { +  { +    description = "TypeScript compiler configuration file", +    fileMatch = { +      "tsconfig.json", +      "tsconfig.*.json", +    }, +    url = "https://json.schemastore.org/tsconfig.json", +  }, +  { +    description = "Lerna config", +    fileMatch = { "lerna.json" }, +    url = "https://json.schemastore.org/lerna.json", +  }, +  { +    description = "Babel configuration", +    fileMatch = { +      ".babelrc.json", +      ".babelrc", +      "babel.config.json", +    }, +    url = "https://json.schemastore.org/babelrc.json", +  }, +  { +    description = "ESLint config", +    fileMatch = { +      ".eslintrc.json", +      ".eslintrc", +    }, +    url = "https://json.schemastore.org/eslintrc.json", +  }, +  { +    description = "Bucklescript config", +    fileMatch = { "bsconfig.json" }, +    url = "https://raw.githubusercontent.com/rescript-lang/rescript-compiler/8.2.0/docs/docson/build-schema.json", +  }, +  { +    description = "Prettier config", +    fileMatch = { +      ".prettierrc", +      ".prettierrc.json", +      "prettier.config.json", +    }, +    url = "https://json.schemastore.org/prettierrc", +  }, +  { +    description = "Vercel Now config", +    fileMatch = { "now.json" }, +    url = "https://json.schemastore.org/now", +  }, +  { +    description = "Stylelint config", +    fileMatch = { +      ".stylelintrc", +      ".stylelintrc.json", +      "stylelint.config.json", +    }, +    url = "https://json.schemastore.org/stylelintrc", +  }, +  { +    description = "A JSON schema for the ASP.NET LaunchSettings.json files", +    fileMatch = { "launchsettings.json" }, +    url = "https://json.schemastore.org/launchsettings.json", +  }, +  { +    description = "Schema for CMake Presets", +    fileMatch = { +      "CMakePresets.json", +      "CMakeUserPresets.json", +    }, +    url = "https://raw.githubusercontent.com/Kitware/CMake/master/Help/manual/presets/schema.json", +  }, +  { +    description = "Configuration file as an alternative for configuring your repository in the settings page.", +    fileMatch = { +      ".codeclimate.json", +    }, +    url = "https://json.schemastore.org/codeclimate.json", +  }, +  { +    description = "LLVM compilation database", +    fileMatch = { +      "compile_commands.json", +    }, +    url = "https://json.schemastore.org/compile-commands.json", +  }, +  { +    description = "Config file for Command Task Runner", +    fileMatch = { +      "commands.json", +    }, +    url = "https://json.schemastore.org/commands.json", +  }, +  { +    description = "AWS CloudFormation provides a common language for you to describe and provision all the infrastructure resources in your cloud environment.", +    fileMatch = { +      "*.cf.json", +      "cloudformation.json", +    }, +    url = "https://raw.githubusercontent.com/awslabs/goformation/v5.2.9/schema/cloudformation.schema.json", +  }, +  { +    description = "The AWS Serverless Application Model (AWS SAM, previously known as Project Flourish) extends AWS CloudFormation to provide a simplified way of defining the Amazon API Gateway APIs, AWS Lambda functions, and Amazon DynamoDB tables needed by your serverless application.", +    fileMatch = { +      "serverless.template", +      "*.sam.json", +      "sam.json", +    }, +    url = "https://raw.githubusercontent.com/awslabs/goformation/v5.2.9/schema/sam.schema.json", +  }, +  { +    description = "Json schema for properties json file for a GitHub Workflow template", +    fileMatch = { +      ".github/workflow-templates/**.properties.json", +    }, +    url = "https://json.schemastore.org/github-workflow-template-properties.json", +  }, +  { +    description = "golangci-lint configuration file", +    fileMatch = { +      ".golangci.toml", +      ".golangci.json", +    }, +    url = "https://json.schemastore.org/golangci-lint.json", +  }, +  { +    description = "JSON schema for the JSON Feed format", +    fileMatch = { +      "feed.json", +    }, +    url = "https://json.schemastore.org/feed.json", +    versions = { +      ["1"] = "https://json.schemastore.org/feed-1.json", +      ["1.1"] = "https://json.schemastore.org/feed.json", +    }, +  }, +  { +    description = "Packer template JSON configuration", +    fileMatch = { +      "packer.json", +    }, +    url = "https://json.schemastore.org/packer.json", +  }, +  { +    description = "NPM configuration file", +    fileMatch = { +      "package.json", +    }, +    url = "https://json.schemastore.org/package.json", +  }, +  { +    description = "JSON schema for Visual Studio component configuration files", +    fileMatch = { +      "*.vsconfig", +    }, +    url = "https://json.schemastore.org/vsconfig.json", +  }, +  { +    description = "Resume json", +    fileMatch = { "resume.json" }, +    url = "https://raw.githubusercontent.com/jsonresume/resume-schema/v1.0.0/schema.json", +  }, +} + +local function extend(tab1, tab2) +  for _, value in ipairs(tab2) do +    table.insert(tab1, value) +  end +  return tab1 +end + +local extended_schemas = extend(schemas, default_schemas) + +local opts = { +  settings = { +    json = { +      schemas = extended_schemas, +    }, +  }, +  setup = { +    commands = { +      Format = { +        function() +          vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 }) +        end, +      }, +    }, +  }, +} + +return opts diff --git a/lua/lsp/providers/sumneko_lua.lua b/lua/lsp/providers/sumneko_lua.lua new file mode 100644 index 00000000..4fee1fd1 --- /dev/null +++ b/lua/lsp/providers/sumneko_lua.lua @@ -0,0 +1,19 @@ +local opts = { +  settings = { +    Lua = { +      diagnostics = { +        globals = { "vim", "lvim" }, +      }, +      workspace = { +        library = { +          [require("utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true, +          [vim.fn.expand "$VIMRUNTIME/lua"] = true, +          [vim.fn.expand "$VIMRUNTIME/lua/vim/lsp"] = true, +        }, +        maxPreload = 100000, +        preloadFileSize = 10000, +      }, +    }, +  }, +} +return opts diff --git a/lua/lsp/providers/vuels.lua b/lua/lsp/providers/vuels.lua new file mode 100644 index 00000000..3f44275d --- /dev/null +++ b/lua/lsp/providers/vuels.lua @@ -0,0 +1,26 @@ +local opts = { +  setup = { +    root_dir = function(fname) +      local util = require "lspconfig/util" +      return util.root_pattern "package.json"(fname) or util.root_pattern "vue.config.js"(fname) or vim.fn.getcwd() +    end, +    init_options = { +      config = { +        vetur = { +          completion = { +            autoImport = true, +            tagCasing = "kebab", +            useScaffoldSnippets = true, +          }, +          useWorkspaceDependencies = true, +          validation = { +            script = true, +            style = true, +            template = true, +          }, +        }, +      }, +    }, +  }, +} +return opts diff --git a/lua/lsp/providers/yamlls.lua b/lua/lsp/providers/yamlls.lua new file mode 100644 index 00000000..156a35b0 --- /dev/null +++ b/lua/lsp/providers/yamlls.lua @@ -0,0 +1,30 @@ +local opts = { +  settings = { +    yaml = { +      hover = true, +      completion = true, +      validate = true, +      schemaStore = { +        enable = true, +        url = "https://www.schemastore.org/api/json/catalog.json", +      }, +      schemas = { +        kubernetes = { +          "daemon.{yml,yaml}", +          "manager.{yml,yaml}", +          "restapi.{yml,yaml}", +          "role.{yml,yaml}", +          "role_binding.{yml,yaml}", +          "*onfigma*.{yml,yaml}", +          "*ngres*.{yml,yaml}", +          "*ecre*.{yml,yaml}", +          "*eployment*.{yml,yaml}", +          "*ervic*.{yml,yaml}", +          "kubectl-edit*.yaml", +        }, +      }, +    }, +  }, +} + +return opts diff --git a/lua/lsp/templates.lua b/lua/lsp/templates.lua new file mode 100644 index 00000000..fbbc37f6 --- /dev/null +++ b/lua/lsp/templates.lua @@ -0,0 +1,98 @@ +local M = {} + +local Log = require "core.log" +local utils = require "utils" +local get_supported_filetypes = require("lsp.utils").get_supported_filetypes + +local ftplugin_dir = lvim.lsp.templates_dir + +local join_paths = _G.join_paths + +function M.remove_template_files() +  -- remove any outdated files +  for _, file in ipairs(vim.fn.glob(ftplugin_dir .. "/*.lua", 1, 1)) do +    vim.fn.delete(file) +  end +end + +---Checks if a server is ignored by default because of a conflict +---Only TSServer is enabled by default for the javascript-family +---@param server_name string +function M.is_ignored(server_name, filetypes) +  --TODO: this is easy to be made configurable once stable +  filetypes = filetypes or get_supported_filetypes(server_name) + +  if vim.tbl_contains(filetypes, "javascript") then +    if server_name == "tsserver" then +      return false +    else +      return true +    end +  end + +  local blacklist = { +    "jedi_language_server", +    "pylsp", +    "sqlls", +    "sqls", +    "angularls", +    "ansiblels", +  } +  return vim.tbl_contains(blacklist, server_name) +end + +---Generates an ftplugin file based on the server_name in the selected directory +---@param server_name string name of a valid language server, e.g. pyright, gopls, tsserver, etc. +---@param dir string the full path to the desired directory +function M.generate_ftplugin(server_name, dir) +  -- we need to go through lspconfig to get the corresponding filetypes currently +  local filetypes = get_supported_filetypes(server_name) or {} +  if not filetypes then +    return +  end + +  if M.is_ignored(server_name, filetypes) then +    return +  end + +  -- print("got associated filetypes: " .. vim.inspect(filetypes)) + +  for _, filetype in ipairs(filetypes) do +    local filename = join_paths(dir, filetype .. ".lua") +    local setup_cmd = string.format([[require("lsp.manager").setup(%q)]], server_name) +    -- print("using setup_cmd: " .. setup_cmd) +    -- overwrite the file completely +    utils.write_file(filename, setup_cmd .. "\n", "a") +  end +end + +---Generates ftplugin files based on a list of server_names +---The files are generated to a runtimepath: "$LUNARVIM_RUNTIME_DIR/site/after/ftplugin/template.lua" +---@param servers_names table list of servers to be enabled. Will add all by default +function M.generate_templates(servers_names) +  servers_names = servers_names or {} + +  Log:debug "Templates installation in progress" + +  M.remove_template_files() + +  if vim.tbl_isempty(servers_names) then +    local available_servers = require("nvim-lsp-installer.servers").get_available_servers() + +    for _, server in pairs(available_servers) do +      table.insert(servers_names, server.name) +    end +  end + +  -- create the directory if it didn't exist +  if not utils.is_directory(lvim.lsp.templates_dir) then +    vim.fn.mkdir(ftplugin_dir, "p") +  end + +  for _, server in ipairs(servers_names) do +    M.generate_ftplugin(server, ftplugin_dir) +  end +  Log:debug "Templates installation is complete" +end + +return M diff --git a/lua/lsp/utils.lua b/lua/lsp/utils.lua index 17b9c3bc..59003406 100644 --- a/lua/lsp/utils.lua +++ b/lua/lsp/utils.lua @@ -1,28 +1,62 @@  local M = {} +local tbl = require "utils.table" +  function M.is_client_active(name)    local clients = vim.lsp.get_active_clients() +  return tbl.find_first(clients, function(client) +    return client.name == name +  end) +end + +function M.get_active_clients_by_ft(filetype) +  local matches = {} +  local clients = vim.lsp.get_active_clients()    for _, client in pairs(clients) do -    if client.name == name then -      return true, client +    local supported_filetypes = client.config.filetypes or {} +    if client.name ~= "null-ls" and vim.tbl_contains(supported_filetypes, filetype) then +      table.insert(matches, client)      end    end -  return false +  return matches  end --- FIXME: this should return a list instead -function M.get_active_client_by_ft(filetype) -  if not lvim.lang[filetype] or not lvim.lang[filetype].lsp then -    return nil +function M.get_client_capabilities(client_id) +  if not client_id then +    local buf_clients = vim.lsp.buf_get_clients() +    for _, buf_client in ipairs(buf_clients) do +      if buf_client.name ~= "null-ls" then +        client_id = buf_client.id +        break +      end +    end +  end +  if not client_id then +    error "Unable to determine client_id" +    return    end -  local clients = vim.lsp.get_active_clients() -  for _, client in pairs(clients) do -    if client.name == lvim.lang[filetype].lsp.provider then -      return client +  local client = vim.lsp.get_client_by_id(tonumber(client_id)) + +  local enabled_caps = {} +  for capability, status in pairs(client.resolved_capabilities) do +    if status == true then +      table.insert(enabled_caps, capability) +    end +  end + +  return enabled_caps +end + +function M.get_supported_filetypes(server_name) +  -- print("got filetypes query request for: " .. server_name) +  local configs = require "lspconfig/configs" +  pcall(require, ("lspconfig/" .. server_name)) +  for _, config in pairs(configs) do +    if config.name == server_name then +      return config.document_config.default_config.filetypes or {}      end    end -  return nil  end  return M diff --git a/lua/lualine/themes/onedarker.lua b/lua/lualine/themes/onedarker.lua new file mode 100644 index 00000000..396657bb --- /dev/null +++ b/lua/lualine/themes/onedarker.lua @@ -0,0 +1,35 @@ +-- Copyright (c) 2020-2021 shadmansaleh +-- MIT license, see LICENSE for more details. +-- Credit: Zoltan Dalmadi(lightline) +-- LuaFormatter off +local colors = { +  blue = "#61afef", +  green = "#98c379", +  purple = "#c678dd", +  red1 = "#e06c75", +  red2 = "#be5046", +  yellow = "#e5c07b", +  orange = "#D19A66", +  fg = "#abb2bf", +  bg = "#282c34", +  gray1 = "#5c6370", +  gray2 = "#2c323d", +  gray3 = "#3e4452", +} +-- LuaFormatter on +return { +  normal = { +    a = { fg = colors.fg, bg = colors.blue, gui = "bold" }, +    b = { fg = colors.fg, bg = colors.bg }, +    c = { fg = colors.fg, bg = colors.bg }, +  }, +  insert = { a = { fg = colors.fg, bg = colors.green, gui = "bold" } }, +  visual = { a = { fg = colors.fg, bg = colors.purple, gui = "bold" } }, +  command = { a = { fg = colors.fg, bg = colors.yellow, gui = "bold" } }, +  replace = { a = { fg = colors.fg, bg = colors.red1, gui = "bold" } }, +  inactive = { +    a = { fg = colors.gray1, bg = colors.bg, gui = "bold" }, +    b = { fg = colors.gray1, bg = colors.bg }, +    c = { fg = colors.gray1, bg = colors.bg }, +  }, +} diff --git a/lua/spacegray/Git.lua b/lua/onedarker/Git.lua index b47ccf23..b47ccf23 100644 --- a/lua/spacegray/Git.lua +++ b/lua/onedarker/Git.lua diff --git a/lua/spacegray/LSP.lua b/lua/onedarker/LSP.lua index dd3d77ac..82b9f799 100644 --- a/lua/spacegray/LSP.lua +++ b/lua/onedarker/LSP.lua @@ -11,10 +11,18 @@ local LSP = {    LspDiagnosticsFloatingWarning = { fg = C.warning_orange },    LspDiagnosticsFloatingInformation = { fg = C.info_yellow },    LspDiagnosticsFloatingHint = { fg = C.hint_blue }, +  DiagnosticFloatingError = { fg = C.error_red }, +  DiagnosticFloatingWarn = { fg = C.warning_orange }, +  DiagnosticFloatingInfo = { fg = C.info_yellow }, +  DiagnosticFloatingHint = { fg = C.hint_blue },    LspDiagnosticsSignError = { fg = C.error_red },    LspDiagnosticsSignWarning = { fg = C.warning_orange },    LspDiagnosticsSignInformation = { fg = C.info_yellow },    LspDiagnosticsSignHint = { fg = C.hint_blue }, +  DiagnosticSignError = { fg = C.error_red }, +  DiagnosticSignWarn = { fg = C.warning_orange }, +  DiagnosticSignInfo = { fg = C.info_yellow }, +  DiagnosticSignHint = { fg = C.hint_blue },    LspDiagnosticsError = { fg = C.error_red },    LspDiagnosticsWarning = { fg = C.warning_orange },    LspDiagnosticsInformation = { fg = C.info_yellow }, @@ -23,11 +31,19 @@ local LSP = {    LspDiagnosticsUnderlineWarning = { style = "underline" },    LspDiagnosticsUnderlineInformation = { style = "underline" },    LspDiagnosticsUnderlineHint = { style = "underline" }, +  DiagnosticUnderlineError = { style = "underline" }, +  DiagnosticUnderlineWarn = { style = "underline" }, +  DiagnosticUnderlineInfo = { style = "underline" }, +  DiagnosticUnderlineHint = { style = "underline" }, +  LspReferenceRead = { bg = C.fg_gutter, style = "bold" }, +  LspReferenceText = { bg = C.fg_gutter, style = "bold" }, +  LspReferenceWrite = { bg = C.fg_gutter, style = "bold" },    QuickScopePrimary = { fg = C.purple_test, style = "underline" },    QuickScopeSecondary = { fg = C.cyan_test, style = "underline" },    TelescopeSelection = { fg = C.hint_blue },    TelescopeMatching = { fg = C.info_yellow, style = "bold" },    TelescopeBorder = { fg = C.cyan, bg = Config.transparent_background and "NONE" or C.bg }, +  TelescopePromptPrefix = { fg = C.purple },    NvimTreeFolderIcon = { fg = C.blue },    NvimTreeIndentMarker = { fg = C.gray },    NvimTreeNormal = { fg = C.light_gray, bg = C.alt_bg }, @@ -37,6 +53,7 @@ local LSP = {    NvimTreeImageFile = { fg = C.purple },    NvimTreeSpecialFile = { fg = C.orange },    NvimTreeGitStaged = { fg = C.sign_add }, +  NvimTreeCursorLine = { bg = C.bg },    NvimTreeGitNew = { fg = C.sign_add },    NvimTreeGitDirty = { fg = C.sign_add },    NvimTreeGitDeleted = { fg = C.sign_delete }, @@ -70,13 +87,16 @@ local LSP = {    StatusLineTerm = { fg = C.alt_bg },    StatusLineTermNC = { fg = C.alt_bg },    CodiVirtualText = { fg = C.hint_blue }, -  IndentBlanklineContextChar = { fg = C.accent }, +  IndentBlanklineContextChar = { fg = C.context }, +  IndentBlanklineChar = { fg = C.dark_gray }, +  IndentBlanklineSpaceChar = { fg = C.cyan_test }, +  IndentBlanklineSpaceCharBlankline = { fg = C.info_yellow },    DashboardHeader = { fg = C.blue },    DashboardCenter = { fg = C.purple },    DashboardFooter = { fg = C.cyan }, -  xmlTag = { fg = C.cyan }, -  xmlTagName = { fg = C.cyan }, -  xmlEndTag = { fg = C.cyan }, +  xmlTag = { fg = C.blue }, +  xmlTagName = { fg = C.blue }, +  xmlEndTag = { fg = C.blue },    CompeDocumentation = { bg = C.alt_bg },    DiffViewNormal = { fg = C.gray, bg = C.alt_bg },    DiffviewStatusAdded = { fg = C.sign_add }, @@ -94,6 +114,8 @@ local LSP = {    diffOldFile = { fg = C.red },    debugPc = { bg = C.cyan },    debugBreakpoint = { fg = C.red, style = "reverse" }, +  FocusedSymbol = { fg = C.purple, style = "bold" }, +  SymbolsOutlineConnector = { fg = C.context },  }  return LSP diff --git a/lua/onedarker/Treesitter.lua b/lua/onedarker/Treesitter.lua new file mode 100644 index 00000000..0718b852 --- /dev/null +++ b/lua/onedarker/Treesitter.lua @@ -0,0 +1,66 @@ +local Treesitter = { +  TSComment = { fg = C.gray }, +  TSAnnotation = { fg = C.blue }, +  TSAttribute = { fg = C.cyan }, +  TSConstructor = { fg = C.yellow }, +  TSType = { fg = C.yellow }, +  TSTypeBuiltin = { fg = C.yellow }, +  TSConditional = { fg = C.purple }, +  TSException = { fg = C.purple }, +  TSInclude = { fg = C.purple }, +  TSKeyword = { fg = C.purple }, +  TSKeywordReturn = { fg = C.purple }, +  TSKeywordFunction = { fg = C.purple }, +  TSLabel = { fg = C.blue }, +  TSNone = { fg = C.fg }, +  TSNamespace = { fg = C.purple }, +  TSRepeat = { fg = C.purple }, +  TSConstant = { fg = C.orange }, +  TSConstBuiltin = { fg = C.orange }, +  TSFloat = { fg = C.orange }, +  TSNumber = { fg = C.orange }, +  TSBoolean = { fg = C.orange }, +  TSCharacter = { fg = C.green }, +  TSError = { fg = C.error_red }, +  TSFunction = { fg = C.blue }, +  TSFuncBuiltin = { fg = C.blue }, +  TSMethod = { fg = C.blue }, +  TSConstMacro = { fg = C.cyan }, +  TSFuncMacro = { fg = C.blue }, +  TSProperty = { fg = C.cyan }, +  TSOperator = { fg = C.purple }, +  TSField = { fg = C.blue }, +  TSParameter = { fg = C.red }, +  TSParameterReference = { fg = C.red }, +  TSVariable = { fg = C.fg }, +  TSVariableBuiltin = { fg = C.red }, +  TSSymbol = { fg = C.cyan }, +  TSText = { fg = C.fg }, +  TSTextReference = { fg = C.red }, +  TSPunctDelimiter = { fg = C.fg }, +  TSTagDelimiter = { fg = C.gray }, +  TSTagAttribute = { fg = C.orange }, +  TSPunctBracket = { fg = C.fg }, +  TSPunctSpecial = { fg = C.fg }, +  TSString = { fg = C.green }, +  TSStringRegex = { fg = C.orange }, +  TSStringEscape = { fg = C.orange }, +  TSTag = { fg = C.blue }, +  TSEmphasis = { style = "italic" }, +  TSUnderline = { style = "underline" }, +  TSNote = { fg = C.info_yellow, style = "bold" }, +  TSWarning = { fg = C.warning_orange, style = "bold" }, +  TSDanger = { fg = C.error_red, style = "bold" }, +  TSTitle = { fg = C.blue, style = "bold" }, +  TSLiteral = { fg = C.green }, +  TSURI = { fg = C.blue, style = "underline" }, +  TSMath = { fg = C.fg }, +  TSKeywordOperator = { fg = C.purple }, +  TSStructure = { fg = C.fg }, +  TSStrong = { fg = C.yellow_orange }, +  TSQueryLinterError = { fg = C.warning_orange }, +  TSEnvironment = { fg = C.fg }, +  TSEnvironmentName = { fg = C.fg }, +} + +return Treesitter diff --git a/lua/spacegray/Whichkey.lua b/lua/onedarker/Whichkey.lua index 5d1ae7ce..86b42bd6 100644 --- a/lua/spacegray/Whichkey.lua +++ b/lua/onedarker/Whichkey.lua @@ -1,8 +1,8 @@  local Whichkey = {    WhichKey = { fg = C.purple },    WhichKeySeperator = { fg = C.green }, -  WhichKeyGroup = { fg = C.blue }, -  WhichKeyDesc = { fg = C.light_blue }, +  WhichKeyGroup = { fg = C.cyan }, +  WhichKeyDesc = { fg = C.blue },    WhichKeyFloat = { bg = C.dark },  } diff --git a/lua/spacegray/config.lua b/lua/onedarker/config.lua index ebac7109..ebac7109 100644 --- a/lua/spacegray/config.lua +++ b/lua/onedarker/config.lua diff --git a/lua/onedarker/diff.lua b/lua/onedarker/diff.lua new file mode 100644 index 00000000..49463daa --- /dev/null +++ b/lua/onedarker/diff.lua @@ -0,0 +1,12 @@ +local diff = { +  DiffAdd = { fg = C.none, bg = C.diff_add }, +  DiffDelete = { fg = C.none, bg = C.diff_delete }, +  DiffChange = { fg = C.none, bg = C.diff_change, style = "bold" }, +  DiffText = { fg = C.none, bg = C.diff_text }, +  DiffAdded = { fg = C.green }, +  DiffRemoved = { fg = C.red }, +  DiffFile = { fg = C.cyan }, +  DiffIndexLine = { fg = C.gray }, +} + +return diff diff --git a/lua/spacegray/highlights.lua b/lua/onedarker/highlights.lua index 208c2c62..28e7c07f 100644 --- a/lua/spacegray/highlights.lua +++ b/lua/onedarker/highlights.lua @@ -16,8 +16,8 @@ local highlights = {    Comment = { fg = C.gray, style = "italic" },    Folded = { fg = C.accent, bg = C.alt_bg },    FoldColumn = { fg = C.accent, bg = C.alt_bg }, -  LineNr = { fg = C.gray }, -  FloatBoder = { fg = C.gray, bg = C.alt_bg }, +  LineNr = { fg = C.context }, +  FloatBorder = { fg = C.gray, bg = C.alt_bg },    Whitespace = { fg = C.bg },    VertSplit = { fg = C.bg, bg = C.fg },    CursorLine = { bg = C.dark }, @@ -30,7 +30,7 @@ local highlights = {    DiffAdd = { fg = C.alt_bg, bg = C.sign_add },    DiffChange = { fg = C.alt_bg, bg = C.sign_change, style = "underline" },    DiffDelete = { fg = C.alt_bg, bg = C.sign_delete }, -  QuickFixLine = { bg = C.accent }, +  QuickFixLine = { bg = C.dark_gray },    PmenuSbar = { bg = C.alt_bg },    PmenuThumb = { bg = C.gray },    MatchWord = { style = "underline" }, @@ -53,37 +53,37 @@ local highlights = {    MoreMsg = { fg = C.orange },    Question = { fg = C.orange },    EndOfBuffer = { fg = C.bg }, -  NonText = { fg = C.bg }, -  Variable = { fg = C.light_blue }, +  NonText = { fg = C.context }, +  Variable = { fg = C.cyan },    String = { fg = C.green }, -  Character = { fg = C.light_green }, -  Constant = { fg = C.blue }, -  Number = { fg = C.red }, -  Boolean = { fg = C.red }, -  Float = { fg = C.red }, -  Identifier = { fg = C.light_blue }, -  Function = { fg = C.yellow }, -  Operator = { fg = C.gray }, -  Type = { fg = C.purple }, -  StorageClass = { fg = C.purple }, +  Character = { fg = C.green }, +  Constant = { fg = C.orange }, +  Number = { fg = C.orange }, +  Boolean = { fg = C.orange }, +  Float = { fg = C.orange }, +  Identifier = { fg = C.fg }, +  Function = { fg = C.blue }, +  Operator = { fg = C.purple }, +  Type = { fg = C.yellow }, +  StorageClass = { fg = C.cyan },    Structure = { fg = C.purple },    Typedef = { fg = C.purple }, -  Keyword = { fg = C.blue }, -  Statement = { fg = C.blue }, -  Conditional = { fg = C.blue }, -  Repeat = { fg = C.blue }, +  Keyword = { fg = C.purple }, +  Statement = { fg = C.purple }, +  Conditional = { fg = C.purple }, +  Repeat = { fg = C.purple },    Label = { fg = C.blue }, -  Exception = { fg = C.blue }, -  Include = { fg = C.blue }, +  Exception = { fg = C.purple }, +  Include = { fg = C.purple },    PreProc = { fg = C.purple },    Define = { fg = C.purple },    Macro = { fg = C.purple },    PreCondit = { fg = C.purple }, -  Special = { fg = C.orange }, -  SpecialChar = { fg = C.white }, +  Special = { fg = C.purple }, +  SpecialChar = { fg = C.fg },    Tag = { fg = C.blue },    Debug = { fg = C.red }, -  Delimiter = { fg = C.gray }, +  Delimiter = { fg = C.fg },    SpecialComment = { fg = C.gray },    Underlined = { style = "underline" },    Bold = { style = "bold" }, @@ -92,8 +92,16 @@ local highlights = {    Todo = { fg = C.red, bg = C.bg, style = "bold" },    Error = { fg = C.error_red, bg = C.bg, style = "bold" },    TabLine = { fg = C.light_gray, bg = C.alt_bg }, -  TabLineSel = { fg = C.white, bg = C.alt_bg }, -  TabLineFill = { fg = C.white, bg = C.alt_bg }, +  TabLineSel = { fg = C.fg, bg = C.alt_bg }, +  TabLineFill = { fg = C.fg, bg = C.alt_bg }, +  CmpDocumentation = { fg = C.fg, bg = C.none }, +  CmpDocumentationBorder = { fg = C.fg_dark, bg = C.none }, +  CmpItemAbbr = { fg = C.fg, bg = C.none }, +  CmpItemAbbrDeprecated = { fg = C.gray, bg = C.none }, +  CmpItemAbbrMatch = { fg = C.cyan, bg = C.none }, +  CmpItemAbbrMatchFuzzy = { fg = C.cyan, bg = C.none }, +  CmpItemKind = { fg = C.blue, bg = C.none }, +  CmpItemMenu = { fg = C.light_gray, bg = C.none },  }  return highlights diff --git a/lua/onedarker/init.lua b/lua/onedarker/init.lua new file mode 100644 index 00000000..73043ac3 --- /dev/null +++ b/lua/onedarker/init.lua @@ -0,0 +1,32 @@ +vim.api.nvim_command "hi clear" +if vim.fn.exists "syntax_on" then +  vim.api.nvim_command "syntax reset" +end +vim.o.background = "dark" +vim.o.termguicolors = true +vim.g.colors_name = "onedarker" + +local util = require "onedarker.util" +Config = require "onedarker.config" +C = require "onedarker.palette" +local highlights = require "onedarker.highlights" +local Treesitter = require "onedarker.Treesitter" +local markdown = require "onedarker.markdown" +local Whichkey = require "onedarker.Whichkey" +local Git = require "onedarker.Git" +local LSP = require "onedarker.LSP" +local diff = require "onedarker.diff" + +local skeletons = { +  highlights, +  Treesitter, +  markdown, +  Whichkey, +  Git, +  LSP, +  diff, +} + +for _, skeleton in ipairs(skeletons) do +  util.initialise(skeleton) +end diff --git a/lua/spacegray/markdown.lua b/lua/onedarker/markdown.lua index 2b83e056..d3a5d485 100644 --- a/lua/spacegray/markdown.lua +++ b/lua/onedarker/markdown.lua @@ -10,7 +10,7 @@ local markdown = {    markdownH4 = { fg = C.blue },    markdownH5 = { fg = C.blue },    markdownH6 = { fg = C.blue }, -  markdownHeadingDelimiter = { fg = C.red }, +  markdownHeadingDelimiter = { fg = C.blue },    markdownHeadingRule = { fg = C.accent },    markdownId = { fg = C.purple },    markdownIdDeclaration = { fg = C.blue }, diff --git a/lua/onedarker/palette.lua b/lua/onedarker/palette.lua new file mode 100644 index 00000000..81ea3af3 --- /dev/null +++ b/lua/onedarker/palette.lua @@ -0,0 +1,45 @@ +local colors = { +  none = "NONE", +  fg = "#abb2bf", +  bg = "#1f2227", +  alt_bg = "#282c34", +  dark = "#282c34", +  accent = "#BBBBBB", +  dark_gray = "#2a2f3e", +  fg_gutter = "#353d46", +  context = "#4b5263", +  popup_back = "#282c34", +  search_orange = "#613214", +  search_blue = "#5e81ac", +  gray = "#5c6370", +  light_gray = "#abb2bf", +  blue = "#61AFEF", +  dark_blue = "#223E55", +  green = "#98C379", +  cyan = "#56B6C2", +  red = "#e06c75", +  orange = "#D19A66", +  light_red = "#be5046", +  yellow = "#E5C07B", +  yellow_orange = "#D7BA7D", +  purple = "#C678DD", +  magenta = "#D16D9E", +  cursor_fg = "#515052", +  cursor_bg = "#AEAFAD", +  sign_add = "#587c0c", +  sign_change = "#0c7d9d", +  sign_delete = "#94151b", +  error_red = "#F44747", +  warning_orange = "#ff8800", +  info_yellow = "#FFCC66", +  hint_blue = "#4FC1FF", +  purple_test = "#ff007c", +  cyan_test = "#00dfff", +  ui_blue = "#264F78", +  diff_add = "#303d27", +  diff_delete = "#6e3b40", +  diff_change = "#18344c", +  diff_text = "#265478", +} + +return colors diff --git a/lua/spacegray/util.lua b/lua/onedarker/util.lua index dbac18a2..dbac18a2 100644 --- a/lua/spacegray/util.lua +++ b/lua/onedarker/util.lua diff --git a/lua/plugin-loader.lua b/lua/plugin-loader.lua index aa1e888d..c20dd21a 100644 --- a/lua/plugin-loader.lua +++ b/lua/plugin-loader.lua @@ -1,9 +1,18 @@  local plugin_loader = {} -function plugin_loader:init() -  local install_path = "~/.local/share/lunarvim/site/pack/packer/start/packer.nvim" +local utils = require "utils" +local Log = require "core.log" +-- we need to reuse this outside of init() +local compile_path = get_config_dir() .. "/plugin/packer_compiled.lua" + +function plugin_loader:init(opts) +  opts = opts or {} + +  local install_path = opts.install_path or vim.fn.stdpath "data" .. "/site/pack/packer/start/packer.nvim" +  local package_root = opts.package_root or vim.fn.stdpath "data" .. "/site/pack" +    if vim.fn.empty(vim.fn.glob(install_path)) > 0 then -    vim.fn.system { "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path } +    vim.fn.system { "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path }      vim.cmd "packadd packer.nvim"    end @@ -12,15 +21,13 @@ function plugin_loader:init()      return    end -  local util = require "packer.util" -    packer.init { -    package_root = util.join_paths "~/.local/share/lunarvim/site/pack/", -    compile_path = util.join_paths("~/.config/lvim", "plugin", "packer_compiled.lua"), +    package_root = package_root, +    compile_path = compile_path,      git = { clone_timeout = 300 },      display = {        open_fn = function() -        return util.float { border = "rounded" } +        return require("packer.util").float { border = "rounded" }        end,      },    } @@ -29,6 +36,20 @@ function plugin_loader:init()    return self  end +function plugin_loader:cache_clear() +  if vim.fn.delete(compile_path) == 0 then +    Log:debug "deleted packer_compiled.lua" +  end +end + +function plugin_loader:cache_reset() +  self.cache_clear() +  require("packer").compile() +  if utils.is_file(compile_path) then +    Log:debug "generated packer_compiled.lua" +  end +end +  function plugin_loader:load(configurations)    return self.packer.startup(function(use)      for _, plugins in ipairs(configurations) do @@ -39,8 +60,4 @@ function plugin_loader:load(configurations)    end)  end -return { -  init = function() -    return plugin_loader:init() -  end, -} +return plugin_loader diff --git a/lua/plugins.lua b/lua/plugins.lua index 0b71d48a..65eb16a8 100644 --- a/lua/plugins.lua +++ b/lua/plugins.lua @@ -6,12 +6,7 @@ return {    { "jose-elias-alvarez/null-ls.nvim" },    { "antoinemadec/FixCursorHold.nvim" }, -- Needed while issue https://github.com/neovim/neovim/issues/12587 is still open    { -    "kabouzeid/nvim-lspinstall", -    event = "VimEnter", -    config = function() -      local lspinstall = require "core.lspinstall" -      lspinstall.setup() -    end, +    "williamboman/nvim-lsp-installer",    },    { "nvim-lua/popup.nvim" }, @@ -24,49 +19,42 @@ return {      end,      disable = not lvim.builtin.telescope.active,    }, - -  -- Completion & Snippets +  -- Install nvim-cmp, and buffer source as a dependency    { -    "hrsh7th/nvim-compe", -    event = "InsertEnter", +    "hrsh7th/nvim-cmp",      config = function() -      require("core.compe").setup() +      require("core.cmp").setup() +    end, +    requires = { +      "L3MON4D3/LuaSnip", +      "saadparwaiz1/cmp_luasnip", +      "hrsh7th/cmp-buffer", +      "hrsh7th/cmp-nvim-lsp", +      "hrsh7th/cmp-path", +      "hrsh7th/cmp-nvim-lua", +    }, +    run = function() +      -- cmp's config requires cmp to be installed to run the first time +      if not lvim.builtin.cmp then +        require("core.cmp").config() +      end      end, -    disable = not lvim.builtin.compe.active, -    -- wants = "vim-vsnip", -    -- requires = { -    -- { -    --   "hrsh7th/vim-vsnip", -    --   wants = "friendly-snippets", -    --   event = "InsertCharPre", -    -- }, -    -- { -    --   "rafamadriz/friendly-snippets", -    --   event = "InsertCharPre", -    -- }, -    -- }, -  }, -  { -    "hrsh7th/vim-vsnip", -    -- wants = "friendly-snippets", -    event = "InsertEnter", -    disable = not lvim.builtin.compe.active,    },    {      "rafamadriz/friendly-snippets", -    event = "InsertCharPre", -    disable = not lvim.builtin.compe.active, +    -- event = "InsertCharPre", +    -- disable = not lvim.builtin.compe.active,    },    -- Autopairs    {      "windwp/nvim-autopairs",      -- event = "InsertEnter", -    after = "nvim-compe", +    after = "nvim-cmp",      config = function()        require("core.autopairs").setup()      end, -    disable = not lvim.builtin.autopairs.active or not lvim.builtin.compe.active, +    disable = not lvim.builtin.autopairs.active,    },    -- Treesitter @@ -116,7 +104,7 @@ return {      "terrortylor/nvim-comment",      event = "BufRead",      config = function() -      require("nvim_comment").setup() +      require("core.comment").setup()      end,      disable = not lvim.builtin.comment.active,    }, @@ -183,7 +171,7 @@ return {    -- Terminal    { -    "akinsho/nvim-toggleterm.lua", +    "akinsho/toggleterm.nvim",      event = "BufWinEnter",      config = function()        require("core.terminal").setup() diff --git a/lua/spacegray/Treesitter.lua b/lua/spacegray/Treesitter.lua deleted file mode 100644 index 4e5ce16e..00000000 --- a/lua/spacegray/Treesitter.lua +++ /dev/null @@ -1,56 +0,0 @@ -local Treesitter = { -  TSComment = { fg = C.gray }, -  TSAnnotation = { fg = C.purple }, -  TSAttribute = { fg = C.cyan }, -  TSConstructor = { fg = C.purple }, -  TSType = { fg = C.purple }, -  TSTypeBuiltin = { fg = C.purple }, -  TSConditional = { fg = C.blue }, -  TSException = { fg = C.blue }, -  TSInclude = { fg = C.blue }, -  TSKeyword = { fg = C.blue }, -  TSKeywordFunction = { fg = C.blue }, -  TSLabel = { fg = C.blue }, -  TSNamespace = { fg = C.blue }, -  TSRepeat = { fg = C.blue }, -  TSConstant = { fg = C.orange }, -  TSConstBuiltin = { fg = C.red }, -  TSFloat = { fg = C.red }, -  TSNumber = { fg = C.red }, -  TSBoolean = { fg = C.red }, -  TSCharacter = { fg = C.light_green }, -  TSError = { fg = C.error_red }, -  TSFunction = { fg = C.yellow }, -  TSFuncBuiltin = { fg = C.yellow }, -  TSMethod = { fg = C.yellow }, -  TSConstMacro = { fg = C.cyan }, -  TSFuncMacro = { fg = C.yellow }, -  TSVariable = { fg = C.light_blue }, -  TSVariableBuiltin = { fg = C.light_blue }, -  TSProperty = { fg = C.light_blue }, -  TSOperator = { fg = C.gray }, -  TSField = { fg = C.light_blue }, -  TSParameter = { fg = C.light_blue }, -  TSParameterReference = { fg = C.light_blue }, -  TSSymbol = { fg = C.light_blue }, -  TSText = { fg = C.fg }, -  TSPunctDelimiter = { fg = C.gray }, -  TSTagDelimiter = { fg = C.gray }, -  TSPunctBracket = { fg = C.gray }, -  TSPunctSpecial = { fg = C.gray }, -  TSString = { fg = C.green }, -  TSStringRegex = { fg = C.yellow_orange }, -  TSStringEscape = { fg = C.yellow_orange }, -  TSTag = { fg = C.blue }, -  TSEmphasis = { style = "italic" }, -  TSUnderline = { style = "underline" }, -  TSTitle = { fg = C.blue, style = "bold" }, -  TSLiteral = { fg = C.yellow_orange }, -  TSURI = { fg = C.yellow_orange, style = "underline" }, -  TSKeywordOperator = { fg = C.blue }, -  TSStructure = { fg = C.light_blue }, -  TSStrong = { fg = C.yellow_orange }, -  TSQueryLinterError = { fg = C.warning_orange }, -} - -return Treesitter diff --git a/lua/spacegray/init.lua b/lua/spacegray/init.lua deleted file mode 100644 index 9ae24dbb..00000000 --- a/lua/spacegray/init.lua +++ /dev/null @@ -1,43 +0,0 @@ -vim.api.nvim_command "hi clear" -if vim.fn.exists "syntax_on" then -  vim.api.nvim_command "syntax reset" -end -vim.o.background = "dark" -vim.o.termguicolors = true -vim.g.colors_name = "spacegray" - -local util = require "spacegray.util" -Config = require "spacegray.config" -C = require "spacegray.palette" - -local async -async = vim.loop.new_async(vim.schedule_wrap(function() -  local skeletons = {} -  for _, skeleton in ipairs(skeletons) do -    util.initialise(skeleton) -  end - -  async:close() -end)) - -local highlights = require "spacegray.highlights" -local Treesitter = require "spacegray.Treesitter" -local markdown = require "spacegray.markdown" -local Whichkey = require "spacegray.Whichkey" -local Git = require "spacegray.Git" -local LSP = require "spacegray.LSP" - -local skeletons = { -  highlights, -  Treesitter, -  markdown, -  Whichkey, -  Git, -  LSP, -} - -for _, skeleton in ipairs(skeletons) do -  util.initialise(skeleton) -end - -async:send() diff --git a/lua/spacegray/palette.lua b/lua/spacegray/palette.lua deleted file mode 100644 index 924482fd..00000000 --- a/lua/spacegray/palette.lua +++ /dev/null @@ -1,40 +0,0 @@ -local colors = { -  fg = "#ABB2BF", -  bg = "#202020", -  alt_bg = "#262626", -  dark = "#222222", -  accent = "#AAAAAA", -  popup_back = "#2D2D30", -  search_orange = "#613214", -  search_blue = "#5e81ac", -  white = "#D8DEE9", -  gray = "#9BA1AB", -  light_gray = "#c8c9c1", -  blue = "#5f8ccd", -  dark_blue = "#223E55", -  light_blue = "#8dc0d5", -  green = "#83ba8b", -  cyan = "#4EC9B0", -  light_green = "#B5CEA8", -  red = "#D16969", -  orange = "#D1866B", -  light_red = "#CA535F", -  yellow = "#ECCC8E", -  yellow_orange = "#D7BA7D", -  purple = "#BF82B4", -  magenta = "#D16D9E", -  cursor_fg = "#515052", -  cursor_bg = "#AEAFAD", -  sign_add = "#587c0c", -  sign_change = "#0c7d9d", -  sign_delete = "#94151b", -  error_red = "#F44747", -  warning_orange = "#ff8800", -  info_yellow = "#FFCC66", -  hint_blue = "#4FC1FF", -  purple_test = "#ff007c", -  cyan_test = "#00dfff", -  ui_blue = "#264F78", -} - -return colors diff --git a/lua/utils/hooks.lua b/lua/utils/hooks.lua new file mode 100644 index 00000000..fa667cfd --- /dev/null +++ b/lua/utils/hooks.lua @@ -0,0 +1,33 @@ +local M = {} + +local Log = require "core.log" +local in_headless = #vim.api.nvim_list_uis() == 0 + +function M.run_pre_update() +  Log:debug "Starting pre-update hook" +end + +---Reset any startup cache files used by Packer and Impatient +---Tip: Useful for clearing any outdated settings +function M.reset_cache() +  _G.__luacache.clear_cache() +  require("plugin-loader"):cache_reset() +end + +function M.run_post_update() +  M.reset_cache() +  Log:debug "Starting post-update hook" +  package.loaded["lsp.templates"] = nil +  require("lsp.templates").generate_templates() + +  if not in_headless then +    vim.schedule(function() +      require("packer").install() +      -- TODO: add a changelog +      vim.notify("Update complete", vim.log.levels.INFO) +      vim.cmd "LspStart" +    end) +  end +end + +return M diff --git a/lua/utils/init.lua b/lua/utils/init.lua index 8ea842ca..eaac54f4 100644 --- a/lua/utils/init.lua +++ b/lua/utils/init.lua @@ -90,16 +90,16 @@ function utils.reload_lv_config()    config:load()    require("keymappings").setup() -- this should be done before loading the plugins -  vim.cmd "source ~/.local/share/lunarvim/lvim/lua/plugins.lua" +  vim.cmd("source " .. utils.join_paths(get_runtime_dir(), "lvim", "lua", "plugins.lua"))    local plugins = require "plugins" -  local plugin_loader = require("plugin-loader").init()    utils.toggle_autoformat() +  local plugin_loader = require "plugin-loader" +  plugin_loader:cache_reset()    plugin_loader:load { plugins, lvim.plugins } -  vim.cmd ":PackerCompile"    vim.cmd ":PackerInstall" +  vim.cmd ":PackerCompile"    -- vim.cmd ":PackerClean" -  local null_ls = require "lsp.null-ls" -  null_ls.setup(vim.bo.filetype, { force_reload = true }) +  require("lsp").setup()    Log:info "Reloaded configuration"  end @@ -119,14 +119,119 @@ function utils.gsub_args(args)    return args  end +--- Returns a table with the default values that are missing. +--- either paramter can be empty. +--@param config (table) table containing entries that take priority over defaults +--@param default_config (table) table contatining default values if found +function utils.apply_defaults(config, default_config) +  config = config or {} +  default_config = default_config or {} +  local new_config = vim.tbl_deep_extend("keep", vim.empty_dict(), config) +  new_config = vim.tbl_deep_extend("keep", new_config, default_config) +  return new_config +end +  --- Checks whether a given path exists and is a file. ---@param filename (string) path to check +--@param path (string) path to check  --@returns (bool) -function utils.is_file(filename) -  local stat = uv.fs_stat(filename) +function utils.is_file(path) +  local stat = uv.fs_stat(path)    return stat and stat.type == "file" or false  end +--- Checks whether a given path exists and is a directory +--@param path (string) path to check +--@returns (bool) +function utils.is_directory(path) +  local stat = uv.fs_stat(path) +  return stat and stat.type == "directory" or false +end + +function utils.write_file(path, txt, flag) +  uv.fs_open(path, flag, 438, function(open_err, fd) +    assert(not open_err, open_err) +    uv.fs_write(fd, txt, -1, function(write_err) +      assert(not write_err, write_err) +      uv.fs_close(fd, function(close_err) +        assert(not close_err, close_err) +      end) +    end) +  end) +end + +utils.join_paths = _G.join_paths + +function utils.write_file(path, txt, flag) +  uv.fs_open(path, flag, 438, function(open_err, fd) +    assert(not open_err, open_err) +    uv.fs_write(fd, txt, -1, function(write_err) +      assert(not write_err, write_err) +      uv.fs_close(fd, function(close_err) +        assert(not close_err, close_err) +      end) +    end) +  end) +end + +function utils.debounce(ms, fn) +  local timer = vim.loop.new_timer() +  return function(...) +    local argv = { ... } +    timer:start(ms, 0, function() +      timer:stop() +      vim.schedule_wrap(fn)(unpack(argv)) +    end) +  end +end + +function utils.search_file(file, args) +  local Job = require "plenary.job" +  local stderr = {} +  local stdout, ret = Job +    :new({ +      command = "grep", +      args = { args, file }, +      cwd = get_cache_dir(), +      on_stderr = function(_, data) +        table.insert(stderr, data) +      end, +    }) +    :sync() +  return stdout, ret, stderr +end + +function utils.file_contains(file, query) +  local stdout, ret, stderr = utils.search_file(file, query) +  if ret == 0 then +    return true +  end +  if not vim.tbl_isempty(stderr) then +    error(vim.inspect(stderr)) +  end +  if not vim.tbl_isempty(stdout) then +    error(vim.inspect(stdout)) +  end +  return false +end + +function utils.log_contains(query) +  local logfile = require("core.log"):get_path() +  local stdout, ret, stderr = utils.search_file(logfile, query) +  if ret == 0 then +    return true +  end +  if not vim.tbl_isempty(stderr) then +    error(vim.inspect(stderr)) +  end +  if not vim.tbl_isempty(stdout) then +    error(vim.inspect(stdout)) +  end +  if not vim.tbl_isempty(stderr) then +    error(vim.inspect(stderr)) +  end +  return false +end +  return utils  -- TODO: find a new home for these autocommands diff --git a/lua/utils/table.lua b/lua/utils/table.lua new file mode 100644 index 00000000..1ac5949e --- /dev/null +++ b/lua/utils/table.lua @@ -0,0 +1,24 @@ +local Table = {} + +--- Find the first entry for which the predicate returns true. +-- @param t The table +-- @param predicate The function called for each entry of t +-- @return The entry for which the predicate returned True or nil +function Table.find_first(t, predicate) +  for _, entry in pairs(t) do +    if predicate(entry) then +      return entry +    end +  end +  return nil +end + +--- Check if the predicate returns True for at least one entry of the table. +-- @param t The table +-- @param predicate The function called for each entry of t +-- @return True if predicate returned True at least once, false otherwise +function Table.contains(t, predicate) +  return Table.find_first(t, predicate) ~= nil +end + +return Table diff --git a/tests/bootstrap_spec.lua b/tests/bootstrap_spec.lua new file mode 100644 index 00000000..e5f7244d --- /dev/null +++ b/tests/bootstrap_spec.lua @@ -0,0 +1,28 @@ +local a = require "plenary.async_lib.tests" + +a.describe("initial start", function() +  local uv = vim.loop +  local home_dir = uv.os_homedir() +  local lvim_config_path = get_config_dir() or home_dir .. "/.config/lvim" +  local lvim_runtime_path = get_runtime_dir() or home_dir .. "/.local/share/lunarvim" + +  a.it("shoud be able to detect test environment", function() +    assert.truthy(os.getenv "LVIM_TEST_ENV") +    assert.falsy(package.loaded["impatient"]) +  end) + +  a.it("should not be reading default neovim directories in the home directoies", function() +    local rtp_list = vim.opt.rtp:get() +    assert.falsy(vim.tbl_contains(rtp_list, vim.fn.stdpath "config")) +  end) + +  a.it("should be able to read lunarvim directories", function() +    local rtp_list = vim.opt.rtp:get() +    assert.truthy(vim.tbl_contains(rtp_list, lvim_runtime_path .. "/lvim")) +    assert.truthy(vim.tbl_contains(rtp_list, lvim_config_path)) +  end) + +  a.it("should be able to run treesitter without errors", function() +    assert.truthy(vim.treesitter.highlighter.active) +  end) +end) diff --git a/tests/lsp_spec.lua b/tests/lsp_spec.lua new file mode 100644 index 00000000..9bd7b96c --- /dev/null +++ b/tests/lsp_spec.lua @@ -0,0 +1,97 @@ +local a = require "plenary.async_lib.tests" +local utils = require "utils" +lvim.lsp.templates_dir = join_paths(get_runtime_dir(), "lvim", "tests", "artifacts") + +a.describe("lsp workflow", function() +  local Log = require "core.log" +  local logfile = Log:get_path() + +  a.it("shoud be able to delete ftplugin templates", function() +    if utils.is_directory(lvim.lsp.templates_dir) then +      assert.equal(vim.fn.delete(lvim.lsp.templates_dir, "rf"), 0) +    end +    assert.False(utils.is_directory(lvim.lsp.templates_dir)) +  end) + +  a.it("shoud be able to generate ftplugin templates", function() +    if utils.is_directory(lvim.lsp.templates_dir) then +      assert.equal(vim.fn.delete(lvim.lsp.templates_dir, "rf"), 0) +    end +    require("lsp").setup() + +    -- we need to delay this check until the generation is completed +    vim.schedule(function() +      assert.True(utils.is_directory(lvim.lsp.templates_dir)) +    end) +  end) + +  a.it("shoud not attempt to re-generate ftplugin templates", function() +    lvim.log.level = "debug" + +    local plugins = require "plugins" +    require("plugin-loader"):load { plugins, lvim.plugins } + +    if utils.is_file(logfile) then +      assert.equal(vim.fn.delete(logfile), 0) +    end + +    assert.True(utils.is_directory(lvim.lsp.templates_dir)) +    require("lsp").setup() + +    -- we need to delay this check until the log gets populated +    vim.schedule(function() +      assert.False(utils.log_contains "templates") +    end) +  end) + +  a.it("shoud retrieve supported filetypes correctly", function() +    local ocaml = { +      name = "ocamlls", +      filetypes = { "ocaml", "reason" }, +    } +    local ocaml_fts = require("lsp.utils").get_supported_filetypes(ocaml.name) +    assert.True(vim.deep_equal(ocaml.filetypes, ocaml_fts)) + +    local tsserver = { +      name = "tsserver", +      filetypes = { +        "javascript", +        "javascriptreact", +        "javascript.jsx", +        "typescript", +        "typescriptreact", +        "typescript.tsx", +      }, +    } +    local tsserver_fts = require("lsp.utils").get_supported_filetypes(tsserver.name) +    assert.True(vim.deep_equal(tsserver.filetypes, tsserver_fts)) +  end) + +  a.it("shoud ignore all javascript servers except tsserver and tailwindcss when generating templates", function() +    local test_server = { name = "denols", filetypes = {} } +    test_server.filetypes = require("lsp.utils").get_supported_filetypes(test_server.name) + +    assert.True(vim.tbl_contains(test_server.filetypes, "javascript")) + +    local is_ignored = require("lsp.templates").is_ignored(test_server.name) +    assert.True(is_ignored) + +    local ts_template = utils.join_paths(lvim.lsp.templates_dir, "typescript.lua") + +    assert.True(utils.file_contains(ts_template, "tsserver")) +    assert.False(utils.file_contains(ts_template, test_server.name)) +  end) + +  a.it("shoud not include blacklisted servers in the generated templates", function() +    assert.True(utils.is_directory(lvim.lsp.templates_dir)) +    require("lsp").setup() + +    local blacklisted = { "jedi_language_server", "pylsp", "sqlls", "sqls", "angularls", "ansiblels" } + +    for _, file in ipairs(vim.fn.glob(lvim.lsp.templates_dir .. "/*.lua", 1, 1)) do +      for _, server in ipairs(blacklisted) do +        assert.False(utils.file_contains(file, server)) +      end +    end +  end) +end) diff --git a/tests/minimal_init.lua b/tests/minimal_init.lua new file mode 100644 index 00000000..f495eba0 --- /dev/null +++ b/tests/minimal_init.lua @@ -0,0 +1,9 @@ +local path_sep = vim.loop.os_uname().version:match "Windows" and "\\" or "/" + +vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim") + +require("bootstrap"):init() + +local config = require "config" +-- config:init() +config:load() diff --git a/tests/plugins_load_spec.lua b/tests/plugins_load_spec.lua new file mode 100644 index 00000000..cf9ea3b6 --- /dev/null +++ b/tests/plugins_load_spec.lua @@ -0,0 +1,34 @@ +local a = require "plenary.async_lib.tests" + +a.describe("plugin-loader", function() +  a.it("should be able to load default packages without errors", function() +    local plugins = require "plugins" +    require("plugin-loader"):load { plugins, lvim.plugins } + +    -- TODO: maybe there's a way to avoid hard-coding the names of the modules? +    local startup_plugins = { +      "packer", +    } + +    for _, plugin in ipairs(startup_plugins) do +      assert.truthy(package.loaded[plugin]) +    end +  end) + +  a.it("should be able to load lsp packages without errors", function() +    local plugins = require "plugins" +    require("plugin-loader"):load { plugins, lvim.plugins } + +    require("lsp").setup() + +    local lsp_packages = { +      "lspconfig", +      "nlspsettings", +      "null-ls", +    } + +    for _, plugin in ipairs(lsp_packages) do +      assert.truthy(package.loaded[plugin]) +    end +  end) +end) diff --git a/utils/bin/lvim b/utils/bin/lvim index 2303be3c..e4cd9c75 100644 --- a/utils/bin/lvim +++ b/utils/bin/lvim @@ -1,6 +1,6 @@  #!/bin/sh  export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-$HOME/.local/share/lunarvim}" -export LUNARVIM_CONFIG_DIR="${LUNARVIM_RUNTIME_DIR:-$HOME/.config/lvim}" +export LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-$HOME/.config/lvim}"  exec nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" "$@" diff --git a/utils/bin/lvim.ps1 b/utils/bin/lvim.ps1 new file mode 100644 index 00000000..e220e8ec --- /dev/null +++ b/utils/bin/lvim.ps1 @@ -0,0 +1,9 @@ +$env:XDG_DATA_HOME = ($env:XDG_DATA_HOME, "$env:APPDATA", 1 -ne $null)[0] +$env:XDG_CONFIG_HOME = ($env:XDG_CONFIG_HOME, "$LOCALAPPDATA", 1 -ne $null)[0] +$env:XDG_CACHE_HOME = ($env:XDG_CACHE_HOME, "$TEMP", 1 -ne $null)[0] + +$env:LUNARVIM_RUNTIME_DIR = ($env:LUNARVIM_RUNTIME_DIR, "$env:XDG_DATA_HOME\lunarvim", 1 -ne $null)[0] +$env:LUNARVIM_CONFIG_DIR = ($env:LUNARVIM_CONFIG_DIR, "$env:XDG_CONFIG_HOME\lvim", 1 -ne $null)[0] +$env:LUNARVIM_CACHE_DIR = ($env:LUNARVIM_CACHE_DIR, "$env:XDG_CACHE_HOME\lvim", 1 -ne $null)[0] + +nvim -u "$env:LUNARVIM_RUNTIME_DIR\lvim\init.lua" diff --git a/utils/bin/test_runner.sh b/utils/bin/test_runner.sh new file mode 100644 index 00000000..ee138345 --- /dev/null +++ b/utils/bin/test_runner.sh @@ -0,0 +1,20 @@ +#!/usr/bin/env bash +set -e + +export LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$HOME/.config/lvim"}" +export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$HOME/.local/share/lunarvim"}" + +export LVIM_TEST_ENV=true + +rm -f "$LUNARVIM_CONFIG_DIR/plugin/packer_compiled.lua" + +lvim() { +  # TODO: allow running with a minimal_init.lua +  nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/tests/minimal_init.lua" --cmd "set runtimepath+=$LUNARVIM_RUNTIME_DIR/lvim" "$@" +} + +if [ -n "$1" ]; then +  lvim --headless -c "lua require('plenary.busted').run('$1')" +else +  lvim --headless -c "PlenaryBustedDirectory tests/ { minimal_init = './tests/minimal_init.lua' }" +fi diff --git a/utils/ci/run_commitlint.sh b/utils/ci/run_commitlint.sh new file mode 100644 index 00000000..b752956d --- /dev/null +++ b/utils/ci/run_commitlint.sh @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -eo pipefail + +REPO_DIR="$(git rev-parse --show-toplevel)" +HELP_URL="https://github.com/LunarVim/LunarVim/blob/rolling/CONTRIBUTING.md#commit-messages" +CONFIG="$REPO_DIR/.github/workflows/commitlint.config.js" + +if ! npx commitlint --edit --verbose --help-url "$HELP_URL" --config "$CONFIG"; then +  exit 1 +fi diff --git a/utils/desktop/lvim.desktop b/utils/desktop/lvim.desktop index f4a51b10..f570cfae 100644 --- a/utils/desktop/lvim.desktop +++ b/utils/desktop/lvim.desktop @@ -4,7 +4,7 @@ GenericName=Text Editor  Comment=An IDE layer for Neovim with sane defaults. Completely free and community driven.  TryExec=lvim  Exec=lvim %F -Terminal=false +Terminal=true  Type=Application  Keywords=Text;editor;  Icon=nvim diff --git a/utils/docker/Dockerfile b/utils/docker/Dockerfile deleted file mode 100644 index 58760001..00000000 --- a/utils/docker/Dockerfile +++ /dev/null @@ -1,11 +0,0 @@ -FROM python:3 - -SHELL ["/bin/bash", "-c"] - -ENV DEBIAN_FRONTEND=noninteractive - -COPY script.sh /tmp/script.sh - -RUN bash -c "/tmp/script.sh" - -ENTRYPOINT ["/bin/bash"] diff --git a/utils/docker/Dockerfile.local b/utils/docker/Dockerfile.local new file mode 100644 index 00000000..c219e34f --- /dev/null +++ b/utils/docker/Dockerfile.local @@ -0,0 +1,27 @@ +# To run this file execute: +# docker build -f <Path to this file> <Path to Lunarvim basedir> -t Lunarvim:local + +FROM ubuntu:latest + +# Set environment correctly +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="/root/.local/bin:/root/.cargo/bin:/root/.npm-global/bin${PATH}" + +# Copy in local directory +COPY --chown=root:root . /LunarVim + +# Install dependencies and LunarVim +RUN apt update && \ +  apt -y install sudo curl build-essential git fzf python3-dev python3-pip cargo && \ +  curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \ +  apt update && \ +  apt -y install nodejs && \ +  apt clean && rm -rf /var/lib/apt/lists/* /tmp/* && \ +  /LunarVim/utils/installer/install-neovim-from-release && \ +  /LunarVim/utils/installer/install.sh --local --no-install-dependencies + +# Setup LVIM to run on starup +ENTRYPOINT ["/bin/bash"] +CMD ["lvim"] + +# vim: ft=dockerfile: diff --git a/utils/docker/Dockerfile.remote b/utils/docker/Dockerfile.remote new file mode 100644 index 00000000..94765c48 --- /dev/null +++ b/utils/docker/Dockerfile.remote @@ -0,0 +1,27 @@ +# To run this file execute: +# docker build -f Dockerfile.remote . -t Lunarvim:remote + +FROM ubuntu:latest + +# Build argument to point to correct branch on GitHub +ARG LV_BRANCH=rolling + +# Set environment correctly +ENV DEBIAN_FRONTEND=noninteractive +ENV PATH="/root/.local/bin:/root/.cargo/bin:/root/.npm-global/bin${PATH}" + +# Install dependencies and LunarVim +RUN apt update && \ +  apt -y install sudo curl build-essential git fzf python3-dev python3-pip cargo && \ +  curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \ +  apt update && \ +  apt -y install nodejs && \ +  apt clean && rm -rf /var/lib/apt/lists/* /tmp/* && \ +  curl -LSs https://raw.githubusercontent.com/lunarvim/lunarvim/${LV_BRANCH}/utils/installer/install-neovim-from-release | bash && \ +  LV_BRANCH=${LV_BRANCH} curl -LSs https://raw.githubusercontent.com/lunarvim/lunarvim/${LV_BRANCH}/utils/installer/install.sh | bash -s -- --no-install-dependencies + +# Setup LVIM to run on starup +ENTRYPOINT ["/bin/bash"] +CMD ["lvim"] + +# vim: ft=dockerfile: diff --git a/utils/docker/script.sh b/utils/docker/script.sh deleted file mode 100755 index 35257147..00000000 --- a/utils/docker/script.sh +++ /dev/null @@ -1,23 +0,0 @@ -#!/bin/bash - -# Updating the package list -apt-get update - -# Installing dependencies -apt-get -y install tzdata sudo git nodejs npm git ripgrep fzf ranger curl fonts-hack-ttf - -pip3 install ueberzug neovim-remote -npm install tree-sitter-cli neovim - -# Installing Neovim -mkdir -p /tmp/neovim -cd /tmp/neovim || exit -curl -L -o nvim.appimage https://github.com/neovim/neovim/releases/download/nightly/nvim.appimage -chmod u+x nvim.appimage -./nvim.appimage --appimage-extract -mv squashfs-root /usr/local/neovim -ln -s /usr/local/neovim/usr/bin/nvim /usr/bin/nvim -rm ./nvim.appimage - -# Installing LunarVim -LVBRANCH=master bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh) diff --git a/utils/installer/config.example-no-ts.lua b/utils/installer/config.example-no-ts.lua index aad13fe0..17bb0217 100644 --- a/utils/installer/config.example-no-ts.lua +++ b/utils/installer/config.example-no-ts.lua @@ -3,7 +3,7 @@  -- general  lvim.format_on_save = true  lvim.lint_on_save = true -lvim.colorscheme = "spacegray" +lvim.colorscheme = "onedarker"  -- keymappings [view all the defaults by pressing <leader>Lk]  lvim.leader = "space" @@ -43,7 +43,7 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"  -- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile  lvim.builtin.dashboard.active = true  lvim.builtin.terminal.active = true -lvim.builtin.nvimtree.side = "left" +lvim.builtin.nvimtree.setup.view.side = "left"  lvim.builtin.nvimtree.show_icons.git = 0  -- if you don't want all the parsers change this to a table of the ones you want diff --git a/utils/installer/config.example.lua b/utils/installer/config.example.lua index c2c75fbb..346fac98 100644 --- a/utils/installer/config.example.lua +++ b/utils/installer/config.example.lua @@ -11,8 +11,7 @@ an executable  -- general  lvim.log.level = "warn"  lvim.format_on_save = true -lvim.lint_on_save = true -lvim.colorscheme = "spacegray" +lvim.colorscheme = "onedarker"  -- keymappings [view all the defaults by pressing <leader>Lk]  lvim.leader = "space" @@ -42,21 +41,34 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"  --   name = "+Trouble",  --   r = { "<cmd>Trouble lsp_references<cr>", "References" },  --   f = { "<cmd>Trouble lsp_definitions<cr>", "Definitions" }, ---   d = { "<cmd>Trouble lsp_document_diagnostics<cr>", "Diagnosticss" }, +--   d = { "<cmd>Trouble lsp_document_diagnostics<cr>", "Diagnostics" },  --   q = { "<cmd>Trouble quickfix<cr>", "QuickFix" },  --   l = { "<cmd>Trouble loclist<cr>", "LocationList" }, ---   w = { "<cmd>Trouble lsp_workspace_diagnostics<cr>", "Diagnosticss" }, +--   w = { "<cmd>Trouble lsp_workspace_diagnostics<cr>", "Diagnostics" },  -- }  -- TODO: User Config for predefined plugins  -- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile  lvim.builtin.dashboard.active = true  lvim.builtin.terminal.active = true -lvim.builtin.nvimtree.side = "left" +lvim.builtin.nvimtree.setup.view.side = "left"  lvim.builtin.nvimtree.show_icons.git = 0  -- if you don't want all the parsers change this to a table of the ones you want -lvim.builtin.treesitter.ensure_installed = "maintained" +lvim.builtin.treesitter.ensure_installed = { +  "bash", +  "c", +  "javascript", +  "json", +  "lua", +  "python", +  "typescript", +  "css", +  "rust", +  "java", +  "yaml", +} +  lvim.builtin.treesitter.ignore_install = { "haskell" }  lvim.builtin.treesitter.highlight.enabled = true @@ -90,24 +102,22 @@ lvim.builtin.treesitter.highlight.enabled = true  -- lvim.lang.python.formatters = {  --   {  --     exe = "black", ---     args = {}  --   }  -- }  -- set an additional linter  -- lvim.lang.python.linters = {  --   {  --     exe = "flake8", ---     args = {}  --   }  -- }  -- Additional Plugins  -- lvim.plugins = { ---     {"folke/tokyonight.nvim"}, { ---         "ray-x/lsp_signature.nvim", ---         config = function() require"lsp_signature".on_attach() end, ---         event = "InsertEnter" ---     } +--     {"folke/tokyonight.nvim"}, +--     { +--       "folke/trouble.nvim", +--       cmd = "TroubleToggle", +--     },  -- }  -- Autocommands (https://neovim.io/doc/user/autocmd.html) diff --git a/utils/installer/install-neovim-from-release b/utils/installer/install-neovim-from-release index a2ba0513..e20a4804 100755 --- a/utils/installer/install-neovim-from-release +++ b/utils/installer/install-neovim-from-release @@ -52,7 +52,7 @@ function download_neovim() {  function verify_neovim() {    echo "Verifying the installation.." -  DOWNLOADED_SHA="$(sha256sum "$DOWNLOAD_DIR/$ARCHIVE_NAME.tar.gz" | awk '{print $1}')" +  DOWNLOADED_SHA="$(openssl dgst -sha256 "$DOWNLOAD_DIR/$ARCHIVE_NAME.tar.gz" | awk '{print $2}')"    if [ "$RELEASE_SHA" != "$DOWNLOADED_SHA" ]; then      echo "Error! checksum mis-match." diff --git a/utils/installer/install.ps1 b/utils/installer/install.ps1 new file mode 100644 index 00000000..9f861125 --- /dev/null +++ b/utils/installer/install.ps1 @@ -0,0 +1,279 @@ +$ErrorActionPreference = "Stop" # exit when command fails + +# set script variables +$LV_BRANCH = ($LV_BRANCH, "rolling", 1 -ne $null)[0] +$LV_REMOTE = ($LV_REMOTE, "lunarvim/lunarvim.git", 1 -ne $null)[0] +$INSTALL_PREFIX = ($INSTALL_PREFIX, "$HOME\.local", 1 -ne $null)[0] + +$env:XDG_DATA_HOME = ($env:XDG_DATA_HOME, "$env:APPDATA", 1 -ne $null)[0] +$env:XDG_CONFIG_HOME = ($env:XDG_CONFIG_HOME, "$LOCALAPPDATA", 1 -ne $null)[0] +$env:XDG_CACHE_HOME = ($env:XDG_CACHE_HOME, "$TEMP", 1 -ne $null)[0] +$env:LUNARVIM_RUNTIME_DIR = ($env:LUNARVIM_RUNTIME_DIR, "$env:XDG_DATA_HOME\lunarvim", 1 -ne $null)[0] +$env:LUNARVIM_CONFIG_DIR = ($env:LUNARVIM_CONFIG_DIR, "$env:XDG_CONFIG_HOME\lvim", 1 -ne $null)[0] +$env:LUNARVIM_CACHE_DIR = ($env:LUNARVIM_CACHE_DIR, "$env:XDG_CACHE_HOME\lvim", 1 -ne $null)[0] + + +$__lvim_dirs = ( +    "$env:LUNARVIM_CONFIG_DIR", +    "$env:LUNARVIM_RUNTIME_DIR", +    "$env:LUNARVIM_CACHE_DIR" +) + +function main($cliargs) { +    Write-Output "   + +		88\                                                   88\                +		88 |                                                  \__|               +		88 |88\   88\ 888888$\   888888\   888888\ 88\    88\ 88\ 888888\8888\   +		88 |88 |  88 |88  __88\  \____88\ 88  __88\\88\  88  |88 |88  _88  _88\  +		88 |88 |  88 |88 |  88 | 888888$ |88 |  \__|\88\88  / 88 |88 / 88 / 88 | +		88 |88 |  88 |88 |  88 |88  __88 |88 |       \88$  /  88 |88 | 88 | 88 | +		88 |\888888  |88 |  88 |\888888$ |88 |        \$  /   88 |88 | 88 | 88 | +		\__| \______/ \__|  \__| \_______|\__|         \_/    \__|\__| \__| \__| +   +  " +   +    __add_separator "80" +   +    # skip this in a Github workflow +    if ( $null -eq "$GITHUB_ACTIONS" ) { +        install_packer +        setup_shim +        exit +    } + +    __add_separator "80" + +    check_system_deps + +    Write-Output "Would you like to check lunarvim's NodeJS dependencies?" +    $answer = Read-Host "[y]es or [n]o (default: no) " +    if ("$answer" -eq "y" -or "$answer" -eq "Y") { +        install_nodejs_deps +    }  + +    Write-Output "Would you like to check lunarvim's Python dependencies?" +    $answer = Read-Host "[y]es or [n]o (default: no) " +    if ("$answer" -eq "y" -or "$answer" -eq "Y") { +        install_python_deps +    }  + +    __add_separator "80" + +    Write-Output "Backing up old LunarVim configuration" +    backup_old_config + +    __add_separator "80"  +   +    if ($cliargs.Contains("--overwrite")) { +        Write-Output "!!Warning!! -> Removing all lunarvim related config because of the --overwrite flag" +        $answer = Read-Host "Would you like to continue? [y]es or [n]o " +        if ("$answer" -ne "y" -and "$answer" -ne "Y") { +            exit 1 +        }  +		 +        foreach ($dir in $__lvim_dirs) { +            if (Test-Path "$dir") { +                Remove-Item -Force -Recurse "$dir" +            } +        } +    } +   +    if (Test-Path "$env:LUNARVIM_RUNTIME_DIR\site\pack\packer\start\packer.nvim") { +        Write-Output "Packer already installed" +    } +    else { +        install_packer +    } +   +    __add_separator "80" +   +    if (Test-Path "$env:LUNARVIM_RUNTIME_DIR\lvim\init.lua" ) { +        Write-Output "Updating LunarVim" +        update_lvim +    } +    else { +        if ($cliargs.Contains("--testing")) { +            copy_local_lvim_repository +        } +        else { +            clone_lvim +        } +        setup_lvim +    } +   +    __add_separator "80" +} + +function print_missing_dep_msg($dep) { +    Write-Output "[ERROR]: Unable to find dependency [$dep]" +    Write-Output "Please install it first and re-run the installer. Try: $RECOMMEND_INSTALL $dep" +} + +function install_system_package($dep) { +    if (Get-Command -Name "winget" -ErrorAction SilentlyContinue) { +        Write-Output "[INFO]: Attempting to install dependency [$dep] with winget" +        $install_cmd = "winget install --interactive" +    } +    elseif (Get-Command -Name "scoop" -ErrorAction SilentlyContinue) { +        Write-Output "[INFO]: Attempting to install dependency [$dep] with scoop" +        # TODO: check if it's fine to not run it with --global +        $install_cmd = "scoop install" +    } +    else { +        print_missing_dep_msg "$dep" +        exit 1 +    } + +    try { +        Invoke-Command $install_cmd $dep -ErrorAction Stop +    } +    catch { +        print_missing_dep_msg "$dep" +        exit 1 +    } +} + +function check_system_dep($dep) { +    try {  +        Get-Command -Name $dep -ErrorAction Stop | Out-Null  +    } +    catch {  +        install_system_package "$dep" +    } +} + +function check_system_deps() { +    Write-Output "[INFO]: Checking dependencies.." +    check_system_dep "git" +    check_system_dep "nvim" +	 +} + +function install_nodejs_deps() { +    try { +        check_system_dep "node" +        Invoke-Command npm install -g neovim tree-sitter-cli  -ErrorAction Break +    } +    catch { +        print_missing_dep_msg "$dep" +    } +} + +function install_python_deps() { +    try { +        check_system_dep "pip" +        Invoke-Command python -m pip install --user pynvim -ErrorAction Break +    } +    catch { +        print_missing_dep_msg "$dep" +    } +} + +function backup_old_config() { +    foreach ($dir in $__lvim_dirs) { +        # we create an empty folder for subsequent commands \ +        # that require an existing directory	  +        if ( Test-Path "$dir") { +            New-Item "$dir.bak" -ItemType Directory -Force +            Copy-Item -Recurse "$dir\*" "$dir.bak\." +        } +    } + +    Write-Output "Backup operation complete" +} + + +function install_packer() { +    Invoke-Command -ErrorAction Stop -ScriptBlock { git clone --progress --depth 1 "https://github.com/wbthomason/packer.nvim" "$env:LUNARVIM_RUNTIME_DIR\site\pack\packer\start\packer.nvim" } +} +   +function copy_local_lvim_repository() { +    Write-Output "Copy local LunarVim configuration" +    Copy-Item -Path "$((Get-Item $PWD).Parent.Parent.FullName)" -Destination "$env:LUNARVIM_RUNTIME_DIR/lvim" -Recurse +} + +function clone_lvim() { +    Write-Output "Cloning LunarVim configuration" +    try { +        Invoke-Command -ErrorAction Stop -ScriptBlock { git clone --progress --branch "$LV_BRANCH" --depth 1 "https://github.com/$LV_REMOTE" "$env:LUNARVIM_RUNTIME_DIR/lvim" }  +    } +    catch { +        Write-Output "Failed to clone repository. Installation failed." +        exit 1		 +    } +} + +function setup_shim() { +    if ((Test-Path "$INSTALL_PREFIX\bin") -eq $false) { +        New-Item "$INSTALL_PREFIX\bin" -ItemType Directory +    } +    Copy-Item "$env:LUNARVIM_RUNTIME_DIR\lvim\utils\bin\lvim.ps1" -Destination "$INSTALL_PREFIX\bin\lvim.ps1" -Force +} + +function setup_lvim() { +    Write-Output "Installing LunarVim shim" +   +    setup_shim +   +    Write-Output "Preparing Packer setup" + +    if ((Test-Path "$env:LUNARVIM_CONFIG_DIR") -eq $false) { +        New-Item "$env:LUNARVIM_CONFIG_DIR" -ItemType Directory +    } + +    Copy-Item "$env:LUNARVIM_RUNTIME_DIR\lvim\utils\installer\config.example-no-ts.lua" ` +        "$env:LUNARVIM_CONFIG_DIR\config.lua" +   +	Write-Output "Packer setup complete" +	 +	__add_separator "80" + +	Copy-Item "$env:LUNARVIM_RUNTIME_DIR\lvim\utils\installer\config.example.lua" "$env:LUNARVIM_CONFIG_DIR\config.lua" +   +	$answer = Read-Host $(` +	"Would you like to create an alias inside your Powershell profile?`n" +` +	"(This enables you to start lvim with the command 'lvim') [y]es or [n]o (default: no)" ) +	if ("$answer" -eq "y" -and "$answer" -eq "Y") { +		create_alias +	}  + +	__add_separator "80" + +    Write-Output "Thank you for installing LunarVim!!" +    Write-Output "You can start it by running: $INSTALL_PREFIX\bin\lvim.ps1" +    Write-Output "Do not forget to use a font with glyphs (icons) support [https://github.com/ryanoasis/nerd-fonts]" +} + + +function update_lvim() { +    try { +        Invoke-Command git -C "$env:LUNARVIM_RUNTIME_DIR/lvim" status -uno +    } +    catch { +        git -C "$env:LUNARVIM_RUNTIME_DIR/lvim" pull --ff-only --progress -or +        Write-Output "Unable to guarantee data integrity while updating. Please do that manually instead." +        exit 1 +    } +    Write-Output "Your LunarVim installation is now up to date!" +} + +function __add_separator($div_width) { +    "-" * $div_width +    Write-Output "" +} + +function create_alias { +	if($null -eq $(Get-Alias | Select-String "lvim")){ +		Add-Content -Path $PROFILE -Value $(-join @('Set-Alias lvim "', "$INSTALL_PREFIX", '\bin\lvim.ps1"')) +		 +		Write-Output "" +		Write-Host 'To use the new alias in this window reload your profile with ". $PROFILE".' -ForegroundColor Yellow + +	}else { +		Write-Output "Alias is already set and will not be reset." +	} +} + +main "$args" + diff --git a/utils/installer/install.sh b/utils/installer/install.sh index ec9813cf..aaee515d 100755 --- a/utils/installer/install.sh +++ b/utils/installer/install.sh @@ -2,7 +2,7 @@  set -eo pipefail  #Set branch to master unless specified by the user -declare -r LV_BRANCH="${LV_BRANCH:-rolling}" +declare LV_BRANCH="${LV_BRANCH:-"rolling"}"  declare -r LV_REMOTE="${LV_REMOTE:-lunarvim/lunarvim.git}"  declare -r INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}" @@ -10,16 +10,25 @@ declare -r XDG_DATA_HOME="${XDG_DATA_HOME:-"$HOME/.local/share"}"  declare -r XDG_CACHE_HOME="${XDG_CACHE_HOME:-"$HOME/.cache"}"  declare -r XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-"$HOME/.config"}" -# TODO: Use a dedicated cache directory #1256 -declare -r NEOVIM_CACHE_DIR="$XDG_CACHE_HOME/nvim" -  declare -r LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}"  declare -r LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}" +# TODO: Use a dedicated cache directory #1256 +declare -r LUNARVIM_CACHE_DIR="$XDG_CACHE_HOME/nvim" +declare -r LUNARVIM_PACK_DIR="$LUNARVIM_RUNTIME_DIR/site/pack" + +declare BASEDIR +BASEDIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)" +BASEDIR="$(dirname -- "$(dirname -- "$BASEDIR")")" +readonly BASEDIR + +declare ARGS_LOCAL=0 +declare ARGS_OVERWRITE=0 +declare ARGS_INSTALL_DEPENDENCIES=1  declare -a __lvim_dirs=(    "$LUNARVIM_CONFIG_DIR"    "$LUNARVIM_RUNTIME_DIR" -  "$NEOVIM_CACHE_DIR" # for now this is shared with neovim +  "$LUNARVIM_CACHE_DIR"  )  declare -a __npm_deps=( @@ -31,84 +40,96 @@ declare -a __pip_deps=(    "pynvim"  ) -function main() { -  cat <<'EOF' +function usage() { +  echo "Usage: install.sh [<options>]" +  echo "" +  echo "Options:" +  echo "    -h, --help                       Print this help message" +  echo "    -l, --local                      Install local copy of LunarVim" +  echo "    --overwrite                      Overwrite previous LunarVim configuration (a backup is always performed first)" +  echo "    --[no]-install-dependencies      Whether to prompt to install external dependencies (will prompt by default)" +} -      88\                                                   88\                -      88 |                                                  \__|               -      88 |88\   88\ 888888$\   888888\   888888\ 88\    88\ 88\ 888888\8888\   -      88 |88 |  88 |88  __88\  \____88\ 88  __88\\88\  88  |88 |88  _88  _88\  -      88 |88 |  88 |88 |  88 | 888888$ |88 |  \__|\88\88  / 88 |88 / 88 / 88 | -      88 |88 |  88 |88 |  88 |88  __88 |88 |       \88$  /  88 |88 | 88 | 88 | -      88 |\888888  |88 |  88 |\888888$ |88 |        \$  /   88 |88 | 88 | 88 | -      \__| \______/ \__|  \__| \_______|\__|         \_/    \__|\__| \__| \__| +function parse_arguments() { +  while [ "$#" -gt 0 ]; do +    case "$1" in +      -l | --local) +        ARGS_LOCAL=1 +        ;; +      --overwrite) +        ARGS_OVERWRITE=1 +        ;; +      --install-dependencies) +        ARGS_INSTALL_DEPENDENCIES=1 +        ;; +      --no-install-dependencies) +        ARGS_INSTALL_DEPENDENCIES=0 +        ;; +      -h | --help) +        usage +        exit 0 +        ;; +    esac +    shift +  done +} -EOF +function msg() { +  local text="$1" +  local div_width="80" +  printf "%${div_width}s\n" ' ' | tr ' ' - +  printf "%s\n" "$text" +} -  __add_separator "80" +function main() { +  parse_arguments "$@" -  echo "Detecting platform for managing any additional neovim dependencies" -  detect_platform +  print_logo -  if [ -n "$GITHUB_ACTIONS" ]; then -    install_packer -    setup_lvim -    exit 0 -  fi +  msg "Detecting platform for managing any additional neovim dependencies" +  detect_platform    check_system_deps -  __add_separator "80" - -  echo "Would you like to check lunarvim's NodeJS dependencies?" -  read -p "[y]es or [n]o (default: no) : " -r answer -  [ "$answer" != "${answer#[Yy]}" ] && install_nodejs_deps - -  echo "Would you like to check lunarvim's Python dependencies?" -  read -p "[y]es or [n]o (default: no) : " -r answer -  [ "$answer" != "${answer#[Yy]}" ] && install_python_deps +  if [ "$ARGS_INSTALL_DEPENDENCIES" -eq 1 ]; then +    msg "Would you like to install LunarVim's NodeJS dependencies?" +    read -p "[y]es or [n]o (default: no) : " -r answer +    [ "$answer" != "${answer#[Yy]}" ] && install_nodejs_deps -  echo "Would you like to check lunarvim's Rust dependencies?" -  read -p "[y]es or [n]o (default: no) : " -r answer -  [ "$answer" != "${answer#[Yy]}" ] && install_rust_deps +    msg "Would you like to install LunarVim's Python dependencies?" +    read -p "[y]es or [n]o (default: no) : " -r answer +    [ "$answer" != "${answer#[Yy]}" ] && install_python_deps -  __add_separator "80" +    msg "Would you like to install LunarVim's Rust dependencies?" +    read -p "[y]es or [n]o (default: no) : " -r answer +    [ "$answer" != "${answer#[Yy]}" ] && install_rust_deps +  fi -  echo "Backing up old LunarVim configuration" +  msg "Backing up old LunarVim configuration"    backup_old_config -  __add_separator "80" - -  case "$@" in -    *--overwrite*) -      echo "!!Warning!! -> Removing all lunarvim related config \ -        because of the --overwrite flag" -      read -p "Would you like to continue? [y]es or [n]o : " -r answer -      [ "$answer" == "${answer#[Yy]}" ] && exit 1 -      for dir in "${__lvim_dirs[@]}"; do -        [ -d "$dir" ] && rm -rf "$dir" -      done -      ;; -  esac - -  if [ -e "$LUNARVIM_RUNTIME_DIR/site/pack/packer/start/packer.nvim" ]; then -    echo "Packer already installed" -  else -    install_packer +  if [ "$ARGS_OVERWRITE" -eq 1 ]; then +    for dir in "${__lvim_dirs[@]}"; do +      [ -d "$dir" ] && rm -rf "$dir" +    done    fi -  __add_separator "80" +  install_packer    if [ -e "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" ]; then -    echo "Updating LunarVim"      update_lvim    else -    clone_lvim +    if [ "$ARGS_LOCAL" -eq 1 ]; then +      link_local_lvim +    else +      clone_lvim +    fi      setup_lvim    fi -  __add_separator "80" - +  msg "Thank you for installing LunarVim!!" +  echo "You can start it by running: $INSTALL_PREFIX/bin/lvim" +  echo "Do not forget to use a font with glyphs (icons) support [https://github.com/ryanoasis/nerd-fonts]"  }  function detect_platform() { @@ -136,14 +157,14 @@ function detect_platform() {  }  function print_missing_dep_msg() { -  echo "[ERROR]: Unable to find dependency [$1]" -  echo "Please install it first and re-run the installer. Try: $RECOMMEND_INSTALL $1" -} - -function check_dep() { -  if ! command -v "$1" &>/dev/null; then -    print_missing_dep_msg "$1" -    exit 1 +  if [ "$#" -eq 1 ]; then +    echo "[ERROR]: Unable to find dependency [$1]" +    echo "Please install it first and re-run the installer. Try: $RECOMMEND_INSTALL $1" +  else +    local cmds +    cmds=$(for i in "$@"; do echo "$RECOMMEND_INSTALL $i"; done) +    printf "[ERROR]: Unable to find dependencies [%s]" "$@" +    printf "Please install any one of the dependencies and re-run the installer. Try: \n%s\n" "$cmds"    fi  } @@ -158,8 +179,7 @@ function check_system_deps() {    fi  } -function install_nodejs_deps() { -  check_dep "npm" +function __install_nodejs_deps_npm() {    echo "Installing node modules with npm.."    for dep in "${__npm_deps[@]}"; do      if ! npm ls -g "$dep" &>/dev/null; then @@ -167,7 +187,25 @@ function install_nodejs_deps() {        npm install -g "$dep"      fi    done -  echo "All NodeJS dependencies are succesfully installed" +  echo "All NodeJS dependencies are successfully installed" +} + +function __install_nodejs_deps_yarn() { +  echo "Installing node modules with yarn.." +  yarn global add "${__npm_deps[@]}" +  echo "All NodeJS dependencies are successfully installed" +} + +function install_nodejs_deps() { +  local -a pkg_managers=("yarn" "npm") +  for pkg_manager in "${pkg_managers[@]}"; do +    if command -v "$pkg_manager" &>/dev/null; then +      eval "__install_nodejs_deps_$pkg_manager" +      return +    fi +  done +  print_missing_dep_msg "${pkg_managers[@]}" +  exit 1  }  function install_python_deps() { @@ -182,27 +220,28 @@ function install_python_deps() {    for dep in "${__pip_deps[@]}"; do      python3 -m pip install --user "$dep"    done -  echo "All Python dependencies are succesfully installed" +  echo "All Python dependencies are successfully installed"  }  function __attempt_to_install_with_cargo() { -  if ! command -v cargo &>/dev/null; then +  if command -v cargo &>/dev/null; then      echo "Installing missing Rust dependency with cargo"      cargo install "$1"    else -    echo "[WARN]: Unable to find fd. Make sure to install it to avoid any problems" +    echo "[WARN]: Unable to find cargo. Make sure to install it to avoid any problems" +    exit 1    fi  }  # we try to install the missing one with cargo even though it's unlikely to be found  function install_rust_deps() { -  if ! command -v fd &>/dev/null; then -    __attempt_to_install_with_cargo "fd-find" -  fi -  if ! command -v rg &>/dev/null; then -    __attempt_to_install_with_cargo "ripgrep" -  fi -  echo "All Rust dependencies are succesfully installed" +  local -a deps=("fd::fd-find" "rg::ripgrep") +  for dep in "${deps[@]}"; do +    if ! command -v "${dep%%::*}" &>/dev/null; then +      __attempt_to_install_with_cargo "${dep##*::}" +    fi +  done +  echo "All Rust dependencies are successfully installed"  }  function backup_old_config() { @@ -233,12 +272,19 @@ function backup_old_config() {  }  function install_packer() { -  git clone --depth 1 https://github.com/wbthomason/packer.nvim \ -    "$LUNARVIM_RUNTIME_DIR/site/pack/packer/start/packer.nvim" +  if [ -e "$LUNARVIM_PACK_DIR/packer/start/packer.nvim" ]; then +    msg "Packer already installed" +  else +    if ! git clone --depth 1 "https://github.com/wbthomason/packer.nvim" \ +      "$LUNARVIM_PACK_DIR/packer/start/packer.nvim"; then +      msg "Failed to clone Packer. Installation failed." +      exit 1 +    fi +  fi  }  function clone_lvim() { -  echo "Cloning LunarVim configuration" +  msg "Cloning LunarVim configuration"    if ! git clone --branch "$LV_BRANCH" \      --depth 1 "https://github.com/${LV_REMOTE}" "$LUNARVIM_RUNTIME_DIR/lvim"; then      echo "Failed to clone repository. Installation failed." @@ -246,6 +292,20 @@ function clone_lvim() {    fi  } +function link_local_lvim() { +  echo "Linking local LunarVim repo" + +  # Detect whether it's a symlink or a folder +  if [ -d "$LUNARVIM_RUNTIME_DIR/lvim" ]; then +    echo "Removing old installation files" +    rm -rf "$LUNARVIM_RUNTIME_DIR/lvim" +  fi + +  mkdir -p "$LUNARVIM_RUNTIME_DIR" +  echo "   - $BASEDIR -> $LUNARVIM_RUNTIME_DIR/lvim" +  ln -s -f "$BASEDIR" "$LUNARVIM_RUNTIME_DIR/lvim" +} +  function setup_shim() {    if [ ! -d "$INSTALL_PREFIX/bin" ]; then      mkdir -p "$INSTALL_PREFIX/bin" @@ -261,8 +321,24 @@ EOF    chmod +x "$INSTALL_PREFIX/bin/lvim"  } +function remove_old_cache_files() { +  local packer_cache="$LUNARVIM_CONFIG_DIR/plugin/packer_compiled.lua" +  if [ -e "$packer_cache" ]; then +    msg "Removing old packer cache file" +    rm -f "$packer_cache" +  fi + +  if [ -e "$LUNARVIM_CACHE_DIR/luacache" ] || [ -e "$LUNARVIM_CACHE_DIR/lvim_cache" ]; then +    msg "Removing old startup cache file" +    rm -f "$LUNARVIM_CACHE_DIR/{luacache,lvim_cache}" +  fi +} +  function setup_lvim() { -  echo "Installing LunarVim shim" + +  remove_old_cache_files + +  msg "Installing LunarVim shim"    setup_shim @@ -271,31 +347,32 @@ function setup_lvim() {    cp "$LUNARVIM_RUNTIME_DIR/lvim/utils/installer/config.example-no-ts.lua" \      "$LUNARVIM_CONFIG_DIR/config.lua" -  nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" --headless \ +  "$INSTALL_PREFIX/bin/lvim" --headless \      -c 'autocmd User PackerComplete quitall' \      -c 'PackerSync'    echo "Packer setup complete"    cp "$LUNARVIM_RUNTIME_DIR/lvim/utils/installer/config.example.lua" "$LUNARVIM_CONFIG_DIR/config.lua" - -  echo "Thank you for installing LunarVim!!" -  echo "You can start it by running: $INSTALL_PREFIX/bin/lvim" -  echo "Do not forget to use a font with glyphs (icons) support [https://github.com/ryanoasis/nerd-fonts]"  }  function update_lvim() { -  git -C "$LUNARVIM_RUNTIME_DIR/lvim" fetch --quiet -  if ! git -C "$LUNARVIM_RUNTIME_DIR/lvim" diff --quiet "@{upstream}"; then -    git -C "$LUNARVIM_RUNTIME_DIR/lvim" merge --ff-only --progress || -      echo "Unable to guarantee data integrity while updating. Please do that manually instead." && exit 1 -  fi -  echo "Your LunarVim installation is now up to date!" +  "$INSTALL_PREFIX/bin/lvim" --headless +'LvimUpdate' +q  } -function __add_separator() { -  local DIV_WIDTH="$1" -  printf "%${DIV_WIDTH}s\n" ' ' | tr ' ' - +function print_logo() { +  cat <<'EOF' + +      88\                                                   88\ +      88 |                                                  \__| +      88 |88\   88\ 888888$\   888888\   888888\ 88\    88\ 88\ 888888\8888\ +      88 |88 |  88 |88  __88\  \____88\ 88  __88\\88\  88  |88 |88  _88  _88\ +      88 |88 |  88 |88 |  88 | 888888$ |88 |  \__|\88\88  / 88 |88 / 88 / 88 | +      88 |88 |  88 |88 |  88 |88  __88 |88 |       \88$  /  88 |88 | 88 | 88 | +      88 |\888888  |88 |  88 |\888888$ |88 |        \$  /   88 |88 | 88 | 88 | +      \__| \______/ \__|  \__| \_______|\__|         \_/    \__|\__| \__| \__| + +EOF  }  main "$@" diff --git a/utils/installer/install_bin.sh b/utils/installer/install_bin.sh new file mode 100755 index 00000000..2438d5d1 --- /dev/null +++ b/utils/installer/install_bin.sh @@ -0,0 +1,33 @@ +#!/usr/bin/env bash +set -eo pipefail + +declare -r INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}" + +declare -r XDG_DATA_HOME="${XDG_DATA_HOME:-"$HOME/.local/share"}" +declare -r XDG_CACHE_HOME="${XDG_CACHE_HOME:-"$HOME/.cache"}" +declare -r XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-"$HOME/.config"}" + +declare -r LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}" +declare -r LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}" + +# TODO: Use a dedicated cache directory #1256 +declare -r LUNARVIM_CACHE_DIR="$XDG_CACHE_HOME/nvim" + +function setup_shim() { +  if [ ! -d "$INSTALL_PREFIX/bin" ]; then +    mkdir -p "$INSTALL_PREFIX/bin" +  fi +  cat >"$INSTALL_PREFIX/bin/lvim" <<EOF +#!/bin/sh + +export LUNARVIM_CONFIG_DIR="\${LUNARVIM_CONFIG_DIR:-$LUNARVIM_CONFIG_DIR}" +export LUNARVIM_RUNTIME_DIR="\${LUNARVIM_RUNTIME_DIR:-$LUNARVIM_RUNTIME_DIR}" +export LUNARVIM_CACHE_DIR="\${LUNARVIM_CACHE_DIR:-$LUNARVIM_CACHE_DIR}" + +exec nvim -u "\$LUNARVIM_RUNTIME_DIR/lvim/init.lua" "\$@" +EOF +  chmod +x "$INSTALL_PREFIX/bin/lvim" +} + +setup_shim "$@" +echo "You can start LunarVim by running: $INSTALL_PREFIX/bin/lvim" diff --git a/utils/installer/uninstall.ps1 b/utils/installer/uninstall.ps1 new file mode 100644 index 00000000..b362ff5a --- /dev/null +++ b/utils/installer/uninstall.ps1 @@ -0,0 +1 @@ +Remove-Item -Path "$HOME/.local/share/lunarvim" -Recurse -Force
\ No newline at end of file diff --git a/utils/installer/uninstall.sh b/utils/installer/uninstall.sh index 8d9d039a..09923bb1 100755 --- a/utils/installer/uninstall.sh +++ b/utils/installer/uninstall.sh @@ -1,5 +1,5 @@  #!/bin/sh -USER_BIN_DIR="/usr/local/bin" +USER_BIN_DIR="$HOME/.local/bin"  if [ -d "/data/data/com.termux" ]; then    sudo() {      eval "$@" diff --git a/utils/media/demo.png b/utils/media/demo.pngBinary files differ deleted file mode 100755 index 08e3dba1..00000000 --- a/utils/media/demo.png +++ /dev/null diff --git a/utils/media/demo1.png b/utils/media/demo1.pngBinary files differ new file mode 100755 index 00000000..f1591dd6 --- /dev/null +++ b/utils/media/demo1.png diff --git a/utils/media/demo2.png b/utils/media/demo2.pngBinary files differ new file mode 100755 index 00000000..9bc613e5 --- /dev/null +++ b/utils/media/demo2.png diff --git a/utils/media/demo3.png b/utils/media/demo3.pngBinary files differ new file mode 100755 index 00000000..29caa338 --- /dev/null +++ b/utils/media/demo3.png diff --git a/utils/media/lunarvim_logo_dark.png b/utils/media/lunarvim_logo_dark.pngBinary files differ index fae8e6af..f605b306 100644..100755 --- a/utils/media/lunarvim_logo_dark.png +++ b/utils/media/lunarvim_logo_dark.png diff --git a/utils/vscode_config/settings.json b/utils/vscode_config/settings.json index d8a91c0f..2cca67a5 100644 --- a/utils/vscode_config/settings.json +++ b/utils/vscode_config/settings.json @@ -362,7 +362,7 @@          },          {            "key": "P", -          "name": "Push", +          "name": "Pull",            "type": "command",            "command": "git.pull"          }, | 
