diff options
63 files changed, 2383 insertions, 1833 deletions
| diff --git a/.github/workflows/format.yaml b/.github/workflows/format.yaml index 22e56d61..142ba7f1 100644 --- a/.github/workflows/format.yaml +++ b/.github/workflows/format.yaml @@ -37,7 +37,8 @@ jobs:          run: |            GO111MODULE=on go get mvdan.cc/sh/v3/cmd/shfmt +      # https://google.github.io/styleguide/shellguide.html        - name: Check formatting          run: | -          shfmt -l -d . +          shfmt -f . | grep -v jdtls | xargs shfmt -i 2 -ci -l -d diff --git a/.github/workflows/install.yaml b/.github/workflows/install.yaml index 08801f1b..fa8bf0e3 100644 --- a/.github/workflows/install.yaml +++ b/.github/workflows/install.yaml @@ -1,11 +1,11 @@  name: install  on:    push: -    branches: '**' +    branches: "**"    pull_request:      branches: -      - 'master' -      - 'rolling' +      - "master" +      - "rolling"  jobs:    unixish: @@ -22,31 +22,32 @@ jobs:      if: github.event.pull_request.draft == false      steps:        - uses: actions/checkout@v2 -       -      - name: Install dependencies for Linux -        if: matrix.os == 'linux' -        run: | -          sudo add-apt-repository ppa:neovim-ppa/unstable -y -          sudo apt-get update -          sudo apt-get install neovim -y -      - name: Install dependencies for OSX +      # sha256sum is not available by default +      - name: Installl dependencies for OSX          if: matrix.os == 'osx'          run: | -          brew update >/dev/null -          brew install neovim +          echo "HOMEBREW_NO_AUTO_UPDATE=1" >> $GITHUB_ENV +          echo "$HOME/.local/bin" >> $GITHUB_PATH +          brew install coreutils + +      - name: Install neovim binary +        run: | +          bash ./utils/installer/install-neovim-from-release        - name: Install LunarVim          timeout-minutes: 4          run: | -          bash ./utils/installer/install.sh --testing +          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        - name: Test LunarVim PackerCompile -        run: if lvim --headless +PackerCompile -c ':qall' 2>&1|grep -q 'Error'; then false; fi +        run: if "$HOME"/.local/bin/lvim --headless +PackerCompile -c ':qall' 2>&1|grep -q 'Error'; then false; fi        - name: Test LunarVim Health -        run: if lvim --headless +checkhealth -c ':qall' 2>&1|grep -q 'Error'; then false; fi - +        run: if "$HOME"/.local/bin/lvim --headless +checkhealth -c ':qall' 2>&1|grep -q 'Error'; then false; fi  #   freebsd:  #     runs-on: macos-latest  #     if: github.event.pull_request.draft == false @@ -54,7 +55,7 @@ jobs:  #     name: "FreeBSD macos-latest"  #     steps:  #       - uses: actions/checkout@v2 -       +  #       - name: Install dependencies for FreeBSD  #         uses: vmactions/[email protected]  #         with: diff --git a/.github/workflows/lint.yaml b/.github/workflows/lint.yaml index 87f93a00..d187f497 100644 --- a/.github/workflows/lint.yaml +++ b/.github/workflows/lint.yaml @@ -22,17 +22,14 @@ jobs:        - name: Run luacheck          run: luacheck *.lua lua/ -     -  shell-linter: -    name: "Linting with shellcheck" -    runs-on: ubuntu-20.04 + +  shellcheck: +    name: Shellcheck +    runs-on: ubuntu-latest      steps: -      - uses: actions/checkout@v2 -       -      - name: Use shellcheck -        run: sudo apt-get install shellcheck -       -      - name: Run shellcheck -        run:  | -          pwd -          shellcheck $(find . -name "*.sh") +    - uses: actions/checkout@v2 +    - name: Run ShellCheck +      uses: ludeeus/action-shellcheck@master +      with: +       scandir: './utils' +       ignore: 'bin' diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..8ecda3bd --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,29 @@ +repos: +  - repo: local +    hooks: +      - id: shfmt +        name: shfmt +        minimum_pre_commit_version: 2.4.0 +        language: system +        types: [shell] +        entry: bash +        args: [-c, "shfmt -f $(git rev-parse --show-toplevel) | grep -v jdtls | xargs shfmt -i=2 -ci -w"] +      - id: shellcheck +        name: shellcheck +        language: system +        types: [shell] +        entry: bash +        args: +          [-c, "shfmt -f $(git rev-parse --show-toplevel) | grep -v jdtls | xargs shellcheck"] +      - id: stylua +        name: StyLua +        language: rust +        entry: stylua +        types: [lua] +        args: ['-'] +      - id: luacheck +        name: luacheck +        language: system +        entry: luacheck +        types: [lua] +        args: [.] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 7606fe46..45edf8c1 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -17,9 +17,19 @@ One of the best ways to begin contributing in a meaningful way is by helping fin  ## Setting up development tools -1. Install [stylua](https://github.com/johnnymorganz/stylua#installation) +### For editing Lua files -2. Install [shfmt](https://github.com/mvdan/sh#shfmt) +1. Formatter: [stylua](https://github.com/johnnymorganz/stylua#installation). +2. Linter:  [luacheck](https://github.com/luarocks/luacheck). + +### For editing shell scripts + +1. Formatter: [shfmt](https://github.com/mvdan/sh#shfmt). +2. Linter: [shellcheck](https://github.com/koalaman/shellcheck). + +### (Optional) + +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 @@ -28,10 +28,20 @@ Make sure you have the newest version of Neovim (0.5).  bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)  ``` -### Installing -The following command installs LunarVim.  Change `LVBRANCH` to the branch you'd like to install.  `master` for the stable branch and `rolling` for the latest changes. +### 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 +  ``` bash -LVBRANCH=rolling bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/rolling/utils/installer/install.sh) +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  ```  ### BREAKING CHANGE on rolling and master branches @@ -94,7 +104,7 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"  -- lvim.keys.insert_mode["po"] = {'<ESC>', { noremap = true }}  -- Use which-key to add extra bindings with the leader-key prefix --- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<CR>", "Projects" } +-- 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" }, diff --git a/ftdetect/nix.lua b/ftdetect/nix.lua new file mode 100644 index 00000000..a85bcfdf --- /dev/null +++ b/ftdetect/nix.lua @@ -0,0 +1 @@ +vim.cmd [[ au BufRead,BufNewFile *.nix set filetype=nix ]] diff --git a/ftplugin/elixir.lua b/ftplugin/elixir.lua index f8ae8b64..2d4c90e2 100644 --- a/ftplugin/elixir.lua +++ b/ftplugin/elixir.lua @@ -1,4 +1,5 @@  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) diff --git a/ftplugin/fortran.lua b/ftplugin/fortran.lua new file mode 100644 index 00000000..36f4f484 --- /dev/null +++ b/ftplugin/fortran.lua @@ -0,0 +1 @@ +require("lsp").setup "fortran" diff --git a/ftplugin/netrw.lua b/ftplugin/netrw.lua new file mode 100644 index 00000000..b2292870 --- /dev/null +++ b/ftplugin/netrw.lua @@ -0,0 +1,2 @@ +vim.cmd [[nmap <buffer> h -]] +vim.cmd [[nmap <buffer> l <cr>]] diff --git a/ftplugin/nix.lua b/ftplugin/nix.lua new file mode 100644 index 00000000..41152a75 --- /dev/null +++ b/ftplugin/nix.lua @@ -0,0 +1 @@ +require("lsp").setup "nix" @@ -1,50 +1,33 @@ -vim.cmd [[ -  set packpath-=~/.config/nvim -  set packpath-=~/.config/nvim/after -  set packpath-=~/.local/share/nvim/site -  set packpath^=~/.local/share/lunarvim/site -  set packpath^=~/.config/lvim +-- {{{ Bootstrap +local home_dir = vim.loop.os_homedir() -  set runtimepath-=~/.config/nvim -  set runtimepath-=~/.config/nvim/after -  set runtimepath+=~/.config/lvim -  set runtimepath^=~/.local/share/lunarvim/lvim/after -]] --- vim.opt.rtp:append() instead of vim.cmd ? +vim.opt.rtp:append(home_dir .. "/.local/share/lunarvim/lvim") -local function file_exists(name) -  local f = io.open(name, "r") -  if f ~= nil then -    io.close(f) -    return true -  else -    return false -  end -end +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") -local lvim_path = os.getenv "HOME" .. "/.config/lvim/" -USER_CONFIG_PATH = lvim_path .. "config.lua" -local config_exist = file_exists(USER_CONFIG_PATH) -if not config_exist then -  USER_CONFIG_PATH = lvim_path .. "lv-config.lua" -  print "Rename ~/.config/lvim/lv-config.lua to config.lua" -end +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") -require "default-config" -local autocmds = require "core.autocmds" -require("settings").load_options() +-- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp +vim.cmd [[let &packpath = &runtimepath]] +-- }}} -local status_ok, error = pcall(vim.cmd, "luafile " .. USER_CONFIG_PATH) -if not status_ok then -  print("something is wrong with your " .. USER_CONFIG_PATH) -  print(error) -end -require("settings").load_commands() -autocmds.define_augroups(lvim.autocommands) +local config = require "config" +config:init() +config:load()  local plugins = require "plugins"  local plugin_loader = require("plugin-loader").init()  plugin_loader:load { plugins, lvim.plugins } + +local Log = require "core.log" +Log:info "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) @@ -58,13 +41,13 @@ 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 {} +  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 = os.getenv "HOME" .. "/.config/lvim/lsp-settings", +    config_home = home_dir .. "/.config/lvim/lsp-settings",    }  end diff --git a/lua/default-config.lua b/lua/config/defaults.lua index bba21206..9bd1bdd8 100644 --- a/lua/default-config.lua +++ b/lua/config/defaults.lua @@ -1,4 +1,5 @@ -CONFIG_PATH = os.getenv "HOME" .. "/.local/share/lunarvim/lvim" +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" @@ -11,28 +12,11 @@ lvim = {    line_wrap_cursor_movement = true,    transparent_window = false,    format_on_save = true, -  vsnip_dir = os.getenv "HOME" .. "/.config/snippets", +  vsnip_dir = home_dir .. "/.config/snippets",    database = { save_location = "~/.config/lunarvim_db", auto_execute = 1 },    keys = {}, -  -- TODO why do we need this? -  builtin = { -    lspinstall = {}, -    telescope = {}, -    compe = {}, -    autopairs = {}, -    treesitter = {}, -    nvimtree = {}, -    gitsigns = {}, -    which_key = {}, -    comment = {}, -    rooter = {}, -    galaxyline = {}, -    bufferline = {}, -    dap = {}, -    dashboard = {}, -    terminal = {}, -  }, +  builtin = {},    log = {      ---@usage can be { "trace", "debug", "info", "warn", "error", "fatal" }, @@ -102,8 +86,9 @@ lvim = {      popup_border = "single",      on_attach_callback = nil,      on_init_callback = nil, -    ---@usage query the project directory from the language server and use it to set the CWD -    smart_cwd = true, +    null_ls = { +      setup = {}, +    },    },    plugins = { @@ -114,10 +99,6 @@ lvim = {  }  local schemas = nil -local lsp = require "lsp" -local common_on_attach = lsp.common_on_attach -local common_capabilities = lsp.common_capabilities() -local common_on_init = lsp.common_on_init  local status_ok, jsonls_settings = pcall(require, "nlspsettings.jsonls")  if status_ok then    schemas = jsonls_settings.get_default_schemas() @@ -127,11 +108,10 @@ end  lvim.lang = {    asm = {      formatters = { -      { -        -- @usage can be asmfmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "asmfmt", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -141,31 +121,29 @@ lvim.lang = {    },    beancount = {      formatters = { -      { -        -- @usage can be bean_format -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "bean_format", +      --   args = {}, +      -- },      },      linters = {},      lsp = {        provider = "beancount",        setup = {          cmd = { "beancount-langserver" }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    c = {      formatters = { -      { -        -- @usage can be clang_format or uncrustify -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "clang_format", +      --   args = {}, +      -- }, +      -- { +      --   exe = "uncrustify", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -179,20 +157,19 @@ lvim.lang = {            "--clang-tidy",            "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    cpp = {      formatters = { -      { -        -- @usage can be clang_format or uncrustify -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "clang_format", +      --   args = {}, +      -- }, +      -- { +      --   exe = "uncrustify", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -206,38 +183,34 @@ lvim.lang = {            "--clang-tidy",            "--clang-tidy-checks=-*,llvm-*,clang-analyzer-*",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    crystal = {      formatters = { -      { -        -- @usage can be crystal_format -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "crystal_format", +      --   args = {}, +      -- },      },      linters = {},      lsp = {        provider = "crystalline",        setup = {          cmd = { "crystalline" }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    cs = {      formatters = { -      { -        -- @usage can be clang_format or uncrustify -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "clang_format ", +      --   args = {}, +      -- }, +      -- { +      --   exe = "uncrustify", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -249,19 +222,15 @@ lvim.lang = {            "--hostPID",            tostring(vim.fn.getpid()),          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    cmake = {      formatters = { -      { -        -- @usage can be cmake_format -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "cmake_format", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -270,38 +239,31 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/cmake/venv/bin/cmake-language-server",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    clojure = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "clojure_lsp",        setup = {          cmd = {            DATA_PATH .. "/lspinstall/clojure/clojure-lsp", -          "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    css = {      formatters = { -      { -        -- @usage can be prettier or prettierd -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -312,19 +274,19 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    less = {      formatters = { -      { -        -- @usage can be prettier or prettierd -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -335,39 +297,30 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/css/vscode-css/css-language-features/server/dist/node/cssServerMain.js",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    d = {      formatters = { -      { -        -- @usage can be dfmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "dfmt", +      --   args = {}, +      -- },      },      linters = {},      lsp = {        provider = "serve_d",        setup = {          cmd = { "serve-d" }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    dart = {      formatters = { -      { -        -- @usage can be dart_format -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "dart_format", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -378,20 +331,11 @@ lvim.lang = {            "/usr/lib/dart/bin/snapshots/analysis_server.dart.snapshot",            "--lsp",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    docker = { -    formatters = { -      { -        exe = "", -        args = {}, -      }, -      -- @usage can be {"hadolint"} -    }, +    formatters = {},      linters = {},      lsp = {        provider = "dockerls", @@ -400,20 +344,15 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/dockerfile/node_modules/.bin/docker-langserver",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    elixir = {      formatters = { -      { -        -- @usage can be mix -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "mix", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -422,20 +361,15 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/elixir/elixir-ls/language_server.sh",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    elm = {      formatters = { -      { -        -- @usage can be elm_format -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "elm_format", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -444,8 +378,6 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-language-server",          }, -        on_attach = common_on_attach, -        on_init = common_on_init,          -- init_options = {          -- elmAnalyseTrigger = "change",          -- elmFormatPath = DATA_PATH .. "/lspinstall/elm/node_modules/.bin/elm-format", @@ -457,11 +389,10 @@ lvim.lang = {    },    erlang = {      formatters = { -      { -        -- @usage can be erlfmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "erlfmt", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -470,39 +401,49 @@ lvim.lang = {          cmd = {            "erlang_ls",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    emmet = { active = false },    fish = {      formatters = { -      { -        -- @usage can be fish_indent -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "fish_indent", +      --   args = {}, +      -- },      },      linters = {},      lsp = {        provider = "", +      setup = {}, +    }, +  }, +  fortran = { +    formatters = {}, +    linters = {}, +    lsp = { +      provider = "fortls",        setup = { -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities, +        cmd = { +          DATA_PATH .. "/lspinstall/fortran/venv/bin/fortls", +        },        },      },    },    go = {      formatters = { -      { -        -- @usage can be gofmt or goimports or gofumpt -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "gofmt", +      --   args = {}, +      -- }, +      -- { +      --   exe = "goimports", +      --   args = {}, +      -- }, +      -- { +      --   exe = "gofumpt", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -511,17 +452,11 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/go/gopls",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    graphql = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "graphql", @@ -532,35 +467,29 @@ lvim.lang = {            "-m",            "stream",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    haskell = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "hls",        setup = {          cmd = { DATA_PATH .. "/lspinstall/haskell/hls" }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    html = {      formatters = { -      { -        -- @usage can be prettier or prettierd -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -571,39 +500,42 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/html/vscode-html/html-language-features/server/dist/node/htmlServerMain.js",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    java = {      formatters = { -      { -        -- @usage can be clang_format or uncrustify -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "clang_format", +      --   args = {}, +      -- }, +      -- { +      --   exe = "uncrustify", +      --   args = {}, +      -- },      },      linters = {},      lsp = {        provider = "jdtls",        setup = {          cmd = { DATA_PATH .. "/lspinstall/java/jdtls.sh" }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    json = {      formatters = { -      { -        -- @usage can be json_tool or prettier or prettierd -        exe = "", -        args = {}, -        stdin = true, -      }, +      -- { +      --   exe = "json_tool", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -614,9 +546,6 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/json/vscode-json/json-language-features/server/dist/node/jsonServerMain.js",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,          settings = {            json = {              schemas = schemas, @@ -639,10 +568,7 @@ lvim.lang = {      },    },    julia = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "julials", @@ -654,17 +580,11 @@ lvim.lang = {            -- vim.fn.expand "~/.config/nvim/lua/lsp/julia/run.jl",            CONFIG_PATH .. "/utils/julia/run.jl",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    kotlin = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "kotlin_language_server", @@ -672,8 +592,6 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/kotlin/server/bin/kotlin-language-server",          }, -        on_attach = common_on_attach, -        on_init = common_on_init,          root_dir = function(fname)            local util = require "lspconfig/util" @@ -695,11 +613,14 @@ lvim.lang = {    },    lua = {      formatters = { -      { -        -- @usage can be stylua or lua_format -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "stylua", +      --   args = {}, +      -- }, +      -- { +      --   exe = "lua_format", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -710,9 +631,6 @@ lvim.lang = {            "-E",            DATA_PATH .. "/lspinstall/lua/main.lua",          }, -        capabilities = common_capabilities, -        on_attach = common_on_attach, -        on_init = common_on_init,          settings = {            Lua = {              runtime = { @@ -742,25 +660,23 @@ lvim.lang = {    },    nginx = {      formatters = { -      { -        -- @usage can be nginx_beautifier -        exe = "", -        args = { -          provider = "", -          setup = {}, -        }, -      }, +      -- { +      --   exe = "nginx_beautifier", +      --   args = { +      --     provider = "", +      --     setup = {}, +      --   }, +      -- },      },      linters = {},      lsp = {},    },    perl = {      formatters = { -      { -        -- @usage can be perltidy -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "perltidy", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -770,11 +686,10 @@ lvim.lang = {    },    sql = {      formatters = { -      { -        -- @usage can be sqlformat -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "sqlformat", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -786,11 +701,10 @@ lvim.lang = {    },    php = {      formatters = { -      { -        -- @usage can be phpcbf -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "phpcbf", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -800,8 +714,6 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/php/node_modules/.bin/intelephense",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init,          filetypes = { "php", "phtml" },          settings = {            intelephense = { @@ -814,27 +726,32 @@ lvim.lang = {      },    },    puppet = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "puppet",        setup = { -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities, +        cmd = { +          DATA_PATH .. "/lspinstall/puppet/puppet-editor-services/puppet-languageserver", +          "--stdio", +        },        },      },    },    javascript = { -    -- @usage can be prettier or prettier_d_slim or prettierd      formatters = { -      { -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettier_d_slim", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      },      -- @usage can be {"eslint"} or {"eslint_d"}      linters = {}, @@ -846,21 +763,24 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    javascriptreact = {      formatters = { -      { -        -- @usage can be prettier or prettier_d_slim or prettierd -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettier_d_slim", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      }, -    -- @usage can be {"eslint"} or {"eslint_d"}      linters = {},      lsp = {        provider = "tsserver", @@ -870,19 +790,19 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    python = {      formatters = { -      { -        -- @usage can be black or yapf or isort -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "yapf", +      --   args = {}, +      -- }, +      -- { +      --   exe = "isort", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -892,9 +812,6 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/python/node_modules/.bin/pyright-langserver",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    }, @@ -902,11 +819,10 @@ lvim.lang = {    -- R -e 'install.packages("readr",repos = "http://cran.us.r-project.org")'    r = {      formatters = { -      { -        -- @usage can be format_r -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "format_r", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -918,19 +834,15 @@ lvim.lang = {            "-e",            "languageserver::run()",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    ruby = {      formatters = { -      { -        -- @usage can be rufo -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "rufo", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -940,9 +852,6 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/ruby/solargraph/solargraph",            "stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,          filetypes = { "ruby" },          init_options = {            formatting = true, @@ -961,11 +870,10 @@ lvim.lang = {    },    rust = {      formatters = { -      { -        -- @usage can be rustfmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "rustfmt", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -974,37 +882,28 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/rust/rust-analyzer",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    scala = {      formatters = { -      { -        -- @usage can be scalafmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "scalafmt", +      --   args = {}, +      -- },      },      linters = { "" },      lsp = {        provider = "metals", -      setup = { -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities, -      }, +      setup = {},      },    },    sh = {      formatters = { -      { -        -- @usage can be shfmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "shfmt", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -1014,17 +913,11 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/bash/node_modules/.bin/bash-language-server",            "start",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    svelte = { -    formatters = { { -      exe = "", -      args = {}, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "svelte", @@ -1033,19 +926,15 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/svelte/node_modules/.bin/svelteserver",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    swift = {      formatters = { -      { -        -- @usage can be swiftformat -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "swiftformat", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -1055,9 +944,6 @@ lvim.lang = {            "xcrun",            "sourcekit-lsp",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    }, @@ -1075,11 +961,10 @@ lvim.lang = {    },    terraform = {      formatters = { -      { -        -- @usage can be terraform_fmt -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "terraform_fmt", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -1089,40 +974,33 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/terraform/terraform-ls",            "serve",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    tex = { -    formatters = { -      { -        exe = "", -        args = {}, -        stdin = false, -      }, -      -- @usage can be chktex or vale -    }, +    formatters = {},      linters = {},      lsp = {        provider = "texlab",        setup = {          cmd = { DATA_PATH .. "/lspinstall/latex/texlab" }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    typescript = {      formatters = { -      { -        -- @usage can be prettier or prettierd or prettier_d_slim -        exe = "", -        args = {}, -      }, -      -- @usage can be {"eslint"} or {"eslint_d"} +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettier_d_slim", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -1133,19 +1011,23 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    typescriptreact = {      formatters = { -      { -        -- @usage can be prettier or prettierd or prettier_d_slim -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettier_d_slim", +      --   args = {}, +      -- },      },      -- @usage can be {"eslint"} or {"eslint_d"}      linters = {}, @@ -1157,21 +1039,12 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/typescript/node_modules/.bin/typescript-language-server",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    vim = { -    formatters = { -      { -        exe = "", -        args = {}, -      }, -    }, -    -- @usage can be {"vint"} -    linters = { "" }, +    formatters = {}, +    linters = {},      lsp = {        provider = "vimls",        setup = { @@ -1179,21 +1052,24 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/vim/node_modules/.bin/vim-language-server",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    vue = {      formatters = { -      { -        -- @usage can be prettier or prettierd or prettier_d_slim -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettier_d_slim", +      --   args = {}, +      -- },      }, -    -- @usage can be {"eslint"} or {"eslint_d"}      linters = {},      lsp = {        provider = "vuels", @@ -1201,19 +1077,19 @@ lvim.lang = {          cmd = {            DATA_PATH .. "/lspinstall/vue/node_modules/.bin/vls",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    yaml = {      formatters = { -      { -        -- @usage can be prettier or prettierd -        exe = "", -        args = {}, -      }, +      -- { +      --   exe = "prettier", +      --   args = {}, +      -- }, +      -- { +      --   exe = "prettierd", +      --   args = {}, +      -- },      },      linters = {},      lsp = { @@ -1223,18 +1099,11 @@ lvim.lang = {            DATA_PATH .. "/lspinstall/yaml/node_modules/.bin/yaml-language-server",            "--stdio",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    },    zig = { -    formatters = { { -      exe = "", -      args = {}, -      stdin = false, -    } }, +    formatters = {},      linters = {},      lsp = {        provider = "zls", @@ -1242,9 +1111,6 @@ lvim.lang = {          cmd = {            "zls",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    }, @@ -1259,9 +1125,6 @@ lvim.lang = {            "localhost",            "6008",          }, -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities,        },      },    }, @@ -1272,24 +1135,29 @@ lvim.lang = {        provider = "powershell_es",        setup = {          bundle_path = "", -        on_attach = common_on_attach, -        on_init = common_on_init, -        capabilities = common_capabilities, +      }, +    }, +  }, +  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,        },      },    },  } - -require("keymappings").config() -require("core.which-key").config() -require "core.status_colors" -require("core.gitsigns").config() -require("core.compe").config() -require("core.dashboard").config() -require("core.dap").config() -require("core.terminal").config() -require("core.telescope").config() -require("core.treesitter").config() -require("core.nvimtree").config() -require("core.rooter").config() -require("core.bufferline").config() diff --git a/lua/config/init.lua b/lua/config/init.lua new file mode 100644 index 00000000..332460d3 --- /dev/null +++ b/lua/config/init.lua @@ -0,0 +1,49 @@ +local home_dir = vim.loop.os_homedir() +local M = { +  path = string.format("%s/.config/lvim/config.lua", home_dir), +} + +--- Initialize lvim default configuration +-- Define lvim global variable +function M:init() +  local utils = require "utils" + +  require "config.defaults" + +  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) + +    self.path = lv_config +  end +end + +--- Override the configuration with a user provided one +-- @param config_path The path to the configuration overrides +function M:load(config_path) +  local autocmds = require "core.autocmds" + +  config_path = config_path or self.path +  local ok, err = pcall(vim.cmd, "luafile " .. config_path) +  if not ok then +    print("Invalid configuration", config_path) +    print(err) +    return +  end + +  self.path = config_path + +  autocmds.define_augroups(lvim.autocommands) + +  local settings = require "config.settings" +  settings.load_commands() +end + +return M diff --git a/lua/settings.lua b/lua/config/settings.lua index d96c1338..ba71a922 100644 --- a/lua/settings.lua +++ b/lua/config/settings.lua @@ -1,8 +1,6 @@  local M = {}  M.load_options = function() -  local opt = vim.opt -    local default_options = {      backup = false, -- creates a backup file      clipboard = "unnamedplus", -- allows neovim to access the system clipboard @@ -51,7 +49,7 @@ M.load_options = function()    ---  SETTINGS  --- -  opt.shortmess:append "c" +  vim.opt.shortmess:append "c"    for k, v in pairs(default_options) do      vim.opt[k] = v diff --git a/lua/core/autocmds.lua b/lua/core/autocmds.lua index 91278544..041926e5 100644 --- a/lua/core/autocmds.lua +++ b/lua/core/autocmds.lua @@ -1,4 +1,5 @@  local autocommands = {} +local config = require "config"  lvim.autocommands = {    _general_settings = { @@ -8,6 +9,11 @@ lvim.autocommands = {        "lua require('utils.ft').do_filetype(vim.fn.expand(\"<amatch>\"))",      },      { +      "FileType", +      "qf", +      "nnoremap <silent> <buffer> q :q<CR>", +    }, +    {        "TextYankPost",        "*",        "lua require('vim.highlight').on_yank({higroup = 'Search', timeout = 200})", @@ -32,7 +38,7 @@ lvim.autocommands = {        "*",        "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",      }, -    { "BufWritePost", USER_CONFIG_PATH, "lua require('utils').reload_lv_config()" }, +    { "BufWritePost", config.path, "lua require('utils').reload_lv_config()" },      {        "FileType",        "qf", diff --git a/lua/core/autopairs.lua b/lua/core/autopairs.lua index a5f21a1b..24aa1875 100644 --- a/lua/core/autopairs.lua +++ b/lua/core/autopairs.lua @@ -1,54 +1,69 @@ --- if not package.loaded['nvim-autopairs'] then ---   return --- end -local Log = require "core.log" -local status_ok, _ = pcall(require, "nvim-autopairs") -if not status_ok then -  Log:get_default().error "Failed to load autopairs" -  return +local M = {} + +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", +    ---@usage check treesitter +    check_ts = true, +    ts_config = { +      lua = { "string" }, +      javascript = { "template_string" }, +      java = false, +    }, +  }  end -local npairs = require "nvim-autopairs" -local Rule = require "nvim-autopairs.rule" --- skip it, if you use another global object -_G.MUtils = {} +M.setup = function() +  -- skip it, if you use another global object +  _G.MUtils = {} +  local autopairs = require "nvim-autopairs" +  local Rule = require "nvim-autopairs.rule" -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"](npairs.esc "<cr>") +  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>" +      end      else -      return npairs.esc "<cr>" +      return autopairs.autopairs_cr()      end -  else -    return npairs.autopairs_cr()    end -end -if package.loaded["compe"] then -  local map_complete_optional = vim.bo.filetype ~= "tex" -  require("nvim-autopairs.completion.compe").setup { -    map_cr = true, --  map <CR> on insert mode -    map_complete = map_complete_optional, -- it will auto insert `(` after select function or method item +  if package.loaded["compe"] then +    require("nvim-autopairs.completion.compe").setup { +      map_cr = lvim.builtin.autopairs.map_cr, +      map_complete = lvim.builtin.autopairs.map_complete, +    } +  end + +  autopairs.setup { +    check_ts = lvim.builtin.autopairs.check_ts, +    ts_config = lvim.builtin.autopairs.ts_config,    } -end -npairs.setup { -  check_ts = true, -  ts_config = { -    lua = { "string" }, -- it will not add pair on that treesitter node -    javascript = { "template_string" }, -    java = false, -- don't check treesitter on java -  }, -} +  require("nvim-treesitter.configs").setup { autopairs = { enable = true } } + +  local ts_conds = require "nvim-autopairs.ts-conds" -require("nvim-treesitter.configs").setup { autopairs = { enable = true } } +  -- TODO: can these rules be safely added from "config.lua" ? +  -- press % => %% is only inside comment or string +  autopairs.add_rules { +    Rule("%", "%", "lua"):with_pair(ts_conds.is_ts_node { "string", "comment" }), +    Rule("$", "$", "lua"):with_pair(ts_conds.is_not_ts_node { "function" }), +  } -local ts_conds = require "nvim-autopairs.ts-conds" +  if lvim.builtin.autopairs.on_config_done then +    lvim.builtin.autopairs.on_config_done(autopairs) +  end +end --- press % => %% is only inside comment or string -npairs.add_rules { -  Rule("%", "%", "lua"):with_pair(ts_conds.is_ts_node { "string", "comment" }), -  Rule("$", "$", "lua"):with_pair(ts_conds.is_not_ts_node { "function" }), -} +return M diff --git a/lua/core/bufferline.lua b/lua/core/bufferline.lua index 8989ce21..e3f6b5de 100644 --- a/lua/core/bufferline.lua +++ b/lua/core/bufferline.lua @@ -3,6 +3,7 @@ local M = {}  M.config = function()    lvim.builtin.bufferline = {      active = true, +    on_config_done = nil,      keymap = {        normal_mode = {          ["<S-l>"] = ":BufferNext<CR>", @@ -15,6 +16,10 @@ end  M.setup = function()    local keymap = require "keymappings"    keymap.append_to_defaults(lvim.builtin.bufferline.keymap) + +  if lvim.builtin.bufferline.on_config_done then +    lvim.builtin.bufferline.on_config_done() +  end  end  return M diff --git a/lua/core/builtins/init.lua b/lua/core/builtins/init.lua new file mode 100644 index 00000000..32f96af5 --- /dev/null +++ b/lua/core/builtins/init.lua @@ -0,0 +1,29 @@ +local M = {} + +local builtins = { +  "keymappings", +  "core.which-key", +  "core.gitsigns", +  "core.compe", +  "core.dashboard", +  "core.dap", +  "core.terminal", +  "core.telescope", +  "core.treesitter", +  "core.nvimtree", +  "core.project", +  "core.bufferline", +  "core.autopairs", +  "core.comment", +  "core.lspinstall", +  "core.lualine", +} + +function M.config(config) +  for _, builtin_path in ipairs(builtins) do +    local builtin = require(builtin_path) +    builtin.config(config) +  end +end + +return M diff --git a/lua/core/comment.lua b/lua/core/comment.lua new file mode 100644 index 00000000..b98410ab --- /dev/null +++ b/lua/core/comment.lua @@ -0,0 +1,31 @@ +local M = {} + +function M.config() +  lvim.builtin.comment = { +    active = true, +    on_config_done = nil, +    -- Linters prefer comment and line to have a space in between markers +    marker_padding = true, +    -- should comment out empty or whitespace only lines +    comment_empty = false, +    -- Should key mappings be created +    create_mappings = true, +    -- Normal mode mapping left hand side +    line_mapping = "gcc", +    -- Visual/Operator mapping left hand side +    operator_mapping = "gc", +    -- Hook function to call before commenting takes place +    hook = nil, +  } +end + +function M.setup() +  local nvim_comment = require "nvim_comment" + +  nvim_comment.setup(lvim.builtin.comment) +  if lvim.builtin.comment.on_config_done then +    lvim.builtin.comment.on_config_done(nvim_comment) +  end +end + +return M diff --git a/lua/core/compe.lua b/lua/core/compe.lua index c2f97e27..9eb3dcfa 100644 --- a/lua/core/compe.lua +++ b/lua/core/compe.lua @@ -1,8 +1,9 @@  local M = {} -local Log = require "core.log" +  M.config = function()    lvim.builtin.compe = { -    enabled = true, +    active = true, +    on_config_done = nil,      autocomplete = true,      debug = false,      min_length = 1, @@ -61,11 +62,7 @@ end  M.setup = function()    vim.g.vsnip_snippet_dir = lvim.vsnip_dir -  local status_ok, compe = pcall(require, "compe") -  if not status_ok then -    Log:get_default().error "Failed to load compe" -    return -  end +  local compe = require "compe"    compe.setup(lvim.builtin.compe) @@ -82,6 +79,17 @@ M.setup = function()      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 @@ -92,8 +100,9 @@ M.setup = function()        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 vim.fn["compe#complete"]() -- < use this if you want <tab> to always offer completion        return t "<Tab>"      end    end @@ -115,6 +124,10 @@ M.setup = function()    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 4e21cc4c..5de3b7c4 100644 --- a/lua/core/dap.lua +++ b/lua/core/dap.lua @@ -1,8 +1,9 @@  local M = {} -local Log = require "core.log" +  M.config = function()    lvim.builtin.dap = {      active = false, +    on_config_done = nil,      breakpoint = {        text = "",        texthl = "LspDiagnosticsSignError", @@ -13,11 +14,7 @@ M.config = function()  end  M.setup = function() -  local status_ok, dap = pcall(require, "dap") -  if not status_ok then -    Log:get_default().error "Failed to load dap" -    return -  end +  local dap = require "dap"    vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint)    dap.defaults.fallback.terminal_win_cmd = "50vsplit new" @@ -38,6 +35,10 @@ M.setup = function()      s = { "<cmd>lua require'dap'.continue()<cr>", "Start" },      q = { "<cmd>lua require'dap'.close()<cr>", "Quit" },    } + +  if lvim.builtin.dap.on_config_done then +    lvim.builtin.dap.on_config_done(dap) +  end  end  -- TODO put this up there ^^^ call in ftplugin diff --git a/lua/core/dashboard.lua b/lua/core/dashboard.lua index d5e5bfe9..a613921f 100644 --- a/lua/core/dashboard.lua +++ b/lua/core/dashboard.lua @@ -1,8 +1,13 @@  local M = {} -M.config = function() +local home_dir = vim.loop.os_homedir() + +M.config = function(config)    lvim.builtin.dashboard = {      active = false, +    on_config_done = nil,      search_handler = "telescope", +    disable_at_vim_enter = 0, +    session_directory = home_dir .. "/.cache/lvim/sessions",      custom_header = {        "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣀⣀⣀⣀⣀⣀⣀⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",        "⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣤⣶⣾⠿⠿⠟⠛⠛⠛⠛⠿⠿⣿⣷⣤⣄⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀", @@ -30,20 +35,20 @@ M.config = function()          command = "Telescope find_files",        },        b = { +        description = { "  Recent Projects    " }, +        command = "Telescope projects", +      }, +      c = {          description = { "  Recently Used Files" },          command = "Telescope oldfiles",        }, -      -- c = { -      --   description = { "  Load Last Session  " }, -      --   command = "SessionLoad", -      -- }, -      c = { +      d = {          description = { "  Find Word          " },          command = "Telescope live_grep",        }, -      d = { -        description = { "  Settings           " }, -        command = ":e " .. USER_CONFIG_PATH, +      e = { +        description = { "  Configuration      " }, +        command = ":e " .. config.path,        },      }, @@ -52,7 +57,7 @@ M.config = function()  end  M.setup = function() -  vim.g.dashboard_disable_at_vimenter = 0 +  vim.g.dashboard_disable_at_vimenter = lvim.builtin.dashboard.disable_at_vim_enter    vim.g.dashboard_custom_header = lvim.builtin.dashboard.custom_header @@ -62,12 +67,8 @@ M.setup = function()    lvim.builtin.which_key.mappings[";"] = { "<cmd>Dashboard<CR>", "Dashboard" } -  -- f = { -  --   description = { "  Neovim Config Files" }, -  --   command = "Telescope find_files cwd=" .. CONFIG_PATH, -  -- }, -  -- e = {description = {'  Marks              '}, command = 'Telescope marks'} -  vim.cmd 'let g:dashboard_session_directory = "~/.config/lvim/.sessions"' +  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))"    vim.api.nvim_exec( @@ -77,11 +78,6 @@ M.setup = function()      false    ) -  -- file_browser = {description = {' File Browser'}, command = 'Telescope find_files'}, - -  -- vim.g.dashboard_session_directory = CACHE_PATH..'/session' -  -- vim.g.dashboard_custom_footer = lvim.dashboard.footer -    require("core.autocmds").define_augroups {      _dashboard = {        -- seems to be nobuflisted that makes my stuff disappear will do more testing @@ -98,6 +94,10 @@ M.setup = function()        { "FileType", "dashboard", "nnoremap <silent> <buffer> q :q<CR>" },      },    } + +  if lvim.builtin.dashboard.on_config_done then +    lvim.builtin.dashboard.on_config_done() +  end  end  return M diff --git a/lua/core/galaxyline.lua b/lua/core/galaxyline.lua deleted file mode 100644 index ee0a317d..00000000 --- a/lua/core/galaxyline.lua +++ /dev/null @@ -1,320 +0,0 @@ --- if not package.loaded['galaxyline'] then ---   return --- end -local Log = require "core.log" -local status_ok, gl = pcall(require, "galaxyline") -if not status_ok then -  Log:get_default().error "Failed to load galaxyline" -  return -end - --- NOTE: if someone defines colors but doesn't have them then this will break -local palette_status_ok, colors = pcall(require, lvim.colorscheme .. ".palette") -if not palette_status_ok then -  colors = lvim.builtin.galaxyline.colors -end - -local condition = require "galaxyline.condition" -local gls = gl.section -gl.short_line_list = { "NvimTree", "vista", "dbui", "packer" } - -table.insert(gls.left, { -  ViMode = { -    provider = function() -      -- auto change color according the vim mode -      local mode_color = { -        n = colors.blue, -        i = colors.green, -        v = colors.purple, -        [""] = colors.purple, -        V = colors.purple, -        c = colors.magenta, -        no = colors.blue, -        s = colors.orange, -        S = colors.orange, -        [""] = colors.orange, -        ic = colors.yellow, -        R = colors.red, -        Rv = colors.red, -        cv = colors.blue, -        ce = colors.blue, -        r = colors.cyan, -        rm = colors.cyan, -        ["r?"] = colors.cyan, -        ["!"] = colors.blue, -        t = colors.blue, -      } -      vim.api.nvim_command("hi GalaxyViMode guifg=" .. mode_color[vim.fn.mode()]) -      return "▊" -    end, -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { "NONE", colors.alt_bg }, -  }, -}) --- print(vim.fn.getbufvar(0, 'ts')) -vim.fn.getbufvar(0, "ts") - -table.insert(gls.left, { -  GitIcon = { -    provider = function() -      return "  " -    end, -    condition = condition.check_git_workspace, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.orange, colors.alt_bg }, -  }, -}) - -table.insert(gls.left, { -  GitBranch = { -    provider = "GitBranch", -    condition = condition.check_git_workspace, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.left, { -  DiffAdd = { -    provider = "DiffAdd", -    condition = condition.hide_in_width, -    icon = "  ", -    highlight = { colors.green, colors.alt_bg }, -  }, -}) - -table.insert(gls.left, { -  DiffModified = { -    provider = "DiffModified", -    condition = condition.hide_in_width, -    icon = " 柳", -    highlight = { colors.blue, colors.alt_bg }, -  }, -}) - -table.insert(gls.left, { -  DiffRemove = { -    provider = "DiffRemove", -    condition = condition.hide_in_width, -    icon = "  ", -    highlight = { colors.red, colors.alt_bg }, -  }, -}) - -table.insert(gls.left, { -  Filler = { -    provider = function() -      return " " -    end, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) --- get output from shell command -function os.capture(cmd, raw) -  local f = assert(io.popen(cmd, "r")) -  local s = assert(f:read "*a") -  f:close() -  if raw then -    return s -  end -  s = string.gsub(s, "^%s+", "") -  s = string.gsub(s, "%s+$", "") -  s = string.gsub(s, "[\n\r]+", " ") -  return s -end --- cleanup virtual env -local function env_cleanup(venv) -  if string.find(venv, "/") then -    local final_venv = venv -    for w in venv:gmatch "([^/]+)" do -      final_venv = w -    end -    venv = final_venv -  end -  return venv -end -local PythonEnv = function() -  if vim.bo.filetype == "python" then -    local venv = os.getenv "CONDA_DEFAULT_ENV" -    if venv ~= nil then -      return "  (" .. env_cleanup(venv) .. ")" -    end -    venv = os.getenv "VIRTUAL_ENV" -    if venv ~= nil then -      return "  (" .. env_cleanup(venv) .. ")" -    end -    return "" -  end -  return "" -end -table.insert(gls.left, { -  VirtualEnv = { -    provider = PythonEnv, -    event = "BufEnter", -    highlight = { colors.green, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  DiagnosticError = { -    provider = "DiagnosticError", -    icon = "  ", -    highlight = { colors.red, colors.alt_bg }, -  }, -}) -table.insert(gls.right, { -  DiagnosticWarn = { -    provider = "DiagnosticWarn", -    icon = "  ", -    highlight = { colors.orange, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  DiagnosticInfo = { -    provider = "DiagnosticInfo", -    icon = "  ", -    highlight = { colors.yellow, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  DiagnosticHint = { -    provider = "DiagnosticHint", -    icon = "  ", -    highlight = { colors.blue, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  TreesitterIcon = { -    provider = function() -      if next(vim.treesitter.highlighter.active) ~= nil then -        return "  " -      end -      return "" -    end, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.green, colors.alt_bg }, -  }, -}) - -local function get_attached_provider_name(msg) -  msg = msg or "LSP Inactive" -  local buf_clients = vim.lsp.buf_get_clients() -  if next(buf_clients) == nil then -    return msg -  end -  local buf_ft = vim.bo.filetype -  local buf_client_names = {} -  local null_ls_providers = require("lsp.null-ls").get_registered_providers_by_filetype(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, null_ls_providers) -  return table.concat(buf_client_names, ", ") -end - -table.insert(gls.right, { -  ShowLspClient = { -    provider = get_attached_provider_name, -    condition = function() -      local tbl = { ["dashboard"] = true, [" "] = true } -      if tbl[vim.bo.filetype] then -        return false -      end -      return true -    end, -    icon = " ", -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  LineInfo = { -    provider = "LineColumn", -    separator = "  ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  PerCent = { -    provider = "LinePercent", -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  Tabstop = { -    provider = function() -      local label = "Spaces: " -      if not vim.api.nvim_buf_get_option(0, "expandtab") then -        label = "Tab size: " -      end -      return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " " -    end, -    condition = condition.hide_in_width, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  BufferType = { -    provider = "FileTypeName", -    condition = condition.hide_in_width, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  FileEncode = { -    provider = "FileEncode", -    condition = condition.hide_in_width, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.right, { -  Space = { -    provider = function() -      return " " -    end, -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.grey, colors.alt_bg }, -  }, -}) - -table.insert(gls.short_line_left, { -  BufferType = { -    provider = "FileTypeName", -    separator = " ", -    separator_highlight = { "NONE", colors.alt_bg }, -    highlight = { colors.alt_bg, colors.alt_bg }, -  }, -}) - -table.insert(gls.short_line_left, { -  SFileName = { -    provider = "SFileName", -    condition = condition.buffer_not_empty, -    highlight = { colors.alt_bg, colors.alt_bg }, -  }, -}) - ---table.insert(gls.short_line_right[1] = {BufferIcon = {provider = 'BufferIcon', highlight = {colors.grey, colors.alt_bg}}}) diff --git a/lua/core/gitsigns.lua b/lua/core/gitsigns.lua index 9e023762..bb9d088b 100644 --- a/lua/core/gitsigns.lua +++ b/lua/core/gitsigns.lua @@ -1,60 +1,64 @@  local M = {} -local Log = require "core.log" +  M.config = function()    lvim.builtin.gitsigns = { -    signs = { -      add = { -        hl = "GitSignsAdd", -        text = "▎", -        numhl = "GitSignsAddNr", -        linehl = "GitSignsAddLn", -      }, -      change = { -        hl = "GitSignsChange", -        text = "▎", -        numhl = "GitSignsChangeNr", -        linehl = "GitSignsChangeLn", -      }, -      delete = { -        hl = "GitSignsDelete", -        text = "契", -        numhl = "GitSignsDeleteNr", -        linehl = "GitSignsDeleteLn", +    active = true, +    on_config_done = nil, +    opts = { +      signs = { +        add = { +          hl = "GitSignsAdd", +          text = "▎", +          numhl = "GitSignsAddNr", +          linehl = "GitSignsAddLn", +        }, +        change = { +          hl = "GitSignsChange", +          text = "▎", +          numhl = "GitSignsChangeNr", +          linehl = "GitSignsChangeLn", +        }, +        delete = { +          hl = "GitSignsDelete", +          text = "契", +          numhl = "GitSignsDeleteNr", +          linehl = "GitSignsDeleteLn", +        }, +        topdelete = { +          hl = "GitSignsDelete", +          text = "契", +          numhl = "GitSignsDeleteNr", +          linehl = "GitSignsDeleteLn", +        }, +        changedelete = { +          hl = "GitSignsChange", +          text = "▎", +          numhl = "GitSignsChangeNr", +          linehl = "GitSignsChangeLn", +        },        }, -      topdelete = { -        hl = "GitSignsDelete", -        text = "契", -        numhl = "GitSignsDeleteNr", -        linehl = "GitSignsDeleteLn", +      numhl = false, +      linehl = false, +      keymaps = { +        -- Default keymap options +        noremap = true, +        buffer = true,        }, -      changedelete = { -        hl = "GitSignsChange", -        text = "▎", -        numhl = "GitSignsChangeNr", -        linehl = "GitSignsChangeLn", -      }, -    }, -    numhl = false, -    linehl = false, -    keymaps = { -      -- Default keymap options -      noremap = true, -      buffer = true, +      watch_index = { interval = 1000 }, +      sign_priority = 6, +      update_debounce = 200, +      status_formatter = nil, -- Use default      }, -    watch_index = { interval = 1000 }, -    sign_priority = 6, -    update_debounce = 200, -    status_formatter = nil, -- Use default    }  end  M.setup = function() -  local status_ok, gitsigns = pcall(require, "gitsigns") -  if not status_ok then -    Log:get_default().error "Failed to load gitsigns" -    return +  local gitsigns = require "gitsigns" + +  gitsigns.setup(lvim.builtin.gitsigns.opts) +  if lvim.builtin.gitsigns.on_config_done then +    lvim.builtin.gitsigns.on_config_done(gitsigns)    end -  gitsigns.setup(lvim.builtin.gitsigns)  end  return M diff --git a/lua/core/info.lua b/lua/core/info.lua index 56fc3ca2..67e45d1c 100644 --- a/lua/core/info.lua +++ b/lua/core/info.lua @@ -1,222 +1,186 @@ -local M = {} -local u = require "utils" -local null_ls_handler = require "lsp.null-ls" -local indent = "  " - -M.banner = { -  " ", -  indent -    .. "⠀⣿⡟⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀   ⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀  ⠀⠀     ⠀⠀⠀   ⠀⠀ ⣺⡿⠀⠀⠀⠀⠀⠀⠀ ⠀⠀⠀", -  indent -    .. "⠀⣿⠇⠀⠀⠀⠀⠀⣤⡄⠀⠀⢠⣤⡄⠀.⣠⣤⣤⣤⡀⠀⠀⢀⣤⣤⣤⣤⡄⠀⠀⠀⣤⣄⣤⣤⣤⠀⠀ ⣿⣯  ⣿⡟⠀   ⣤⣤⠀⠀⠀⠀⣠⣤⣤⣤⣄⣤⣤", -  indent -    .. "⢠⣿⠀⠀⠀⠀⠀⠀⣿⠃⠀⠀⣸⣿⠁⠀⣿⣿⠉⠀⠈⣿⡇⠀⠀⠛⠋⠀⠀⢹⣿⠀⠀⠀⣿⠏⠀⠸⠿⠃⠀⣿⣿⠀⣰⡟⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⠀⣿⡟⢸⣿⡇⢀⣿", -  indent -    .. "⣸⡇⠀⠀⠀⠀⠀⢸⣿⠀⠀⠀⣿⡟⠀⢠⣿⡇⠀⠀⢰⣿⡇⠀⣰⣾⠟⠛⠛⣻⡇⠀⠀⢸⡿⠀⠀⠀⠀⠀⠀⢻⣿⢰⣿⠀⠀⠀⠀⠀⠀⣾⡇⠀⠀⠀⢸⣿⠇⢸⣿⠀⢸⡏", -  indent -    .. "⣿⣧⣤⣤⣤⡄⠀⠘⣿⣤⣤⡤⣿⠇⠀⢸⣿⠁⠀⠀⣼⣿⠀⠀⢿⣿⣤⣤⠔⣿⠃⠀⠀⣾⡇⠀⠀⠀⠀⠀⠀⢸⣿⣿⠋⠀⠀⠀⢠⣤⣤⣿⣥⣤⡄⠀⣼⣿⠀⣸⡏⠀⣿⠃", -  indent -    .. "⠉⠉⠉⠉⠉⠁⠀⠀⠈⠉⠉⠀⠉⠀⠀⠈⠉⠀⠀⠀⠉⠉⠀⠀⠀⠉⠉⠁⠈⠉⠀⠀⠀⠉⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠀⠀⠀⠀⠈⠉⠉⠉⠉⠉⠁⠀⠉⠁⠀⠉⠁⠀⠉⠀", -  "", +local M = { +  banner = { +    "", +    [[    __                          _    ___         ]], +    [[   / /   __  ______  ____ _____| |  / (_)___ ___ ]], +    [[  / /   / / / / __ \/ __ `/ ___/ | / / / __ `__ \]], +    [[ / /___/ /_/ / / / / /_/ / /   | |/ / / / / / / /]], +    [[/_____/\__,_/_/ /_/\__,_/_/    |___/_/_/ /_/ /_/ ]], +  },  } +local fmt = string.format +  local function str_list(list) -  return "[ " .. table.concat(list, ", ") .. " ]" +  return fmt("[ %s ]", table.concat(list, ", "))  end  local function get_formatter_suggestion_msg(ft) -  local supported_formatters = u.get_supported_formatters_by_filetype(ft) -  return { -    indent -      .. "───────────────────────────────────────────────────────────────────", -    "", -    indent .. " HINT ", -    "", -    indent .. "* List of supported formatters: " .. str_list(supported_formatters), -    indent .. "* Configured formatter needs to be installed and executable.", -    indent .. "* Enable installed formatter(s) with following config in ~/.config/lvim/config.lua", -    "", -    indent .. "  lvim.lang." .. tostring(ft) .. [[.formatting = { { exe = ']] .. table.concat( -      supported_formatters, -      "│" -    ) .. [[' } }]], +  local config = require "config" +  local null_formatters = require "lsp.null-ls.formatters" +  local supported_formatters = null_formatters.list_available(ft) +  local section = { +    " HINT ",      "", +    fmt("* List of supported formatters: %s", str_list(supported_formatters)),    } + +  if not vim.tbl_isempty(supported_formatters) then +    vim.list_extend(section, { +      "* Configured formatter needs to be installed and executable.", +      fmt("* Enable installed formatter(s) with following config in %s", config.path), +      "", +      fmt("  lvim.lang.%s.formatters = { { exe = '%s' } }", ft, table.concat(supported_formatters, "│")), +    }) +  end + +  return section  end  local function get_linter_suggestion_msg(ft) -  local supported_linters = u.get_supported_linters_by_filetype(ft) -  return { -    indent -      .. "───────────────────────────────────────────────────────────────────", -    "", -    indent .. " HINT ", -    "", -    indent .. "* List of supported linters: " .. str_list(supported_linters), -    indent .. "* Configured linter needs to be installed and executable.", -    indent .. "* Enable installed linter(s) with following config in ~/.config/lvim/config.lua", -    "", -    indent -      .. "  lvim.lang." -      .. tostring(ft) -      .. [[.linters = { { exe = ']] -      .. table.concat(supported_linters, "│") -      .. [[' } }]], +  local config = require "config" +  local null_linters = require "lsp.null-ls.linters" +  local supported_linters = null_linters.list_available(ft) +  local section = { +    " HINT ",      "", +    fmt("* List of supported linters: %s", str_list(supported_linters)),    } -end ----creates an average size popup ----@param buf_lines a list of lines to print ----@param callback could be used to set syntax highlighting rules for example ----@return bufnr buffer number of the created buffer ----@return win_id window ID of the created popup -function M.create_simple_popup(buf_lines, callback) -  -- runtime/lua/vim/lsp/util.lua -  local bufnr = vim.api.nvim_create_buf(false, true) -  local height_percentage = 0.9 -  local width_percentage = 0.8 -  local row_start_percentage = (1 - height_percentage) / 2 -  local col_start_percentage = (1 - width_percentage) / 2 -  local opts = {} -  opts.relative = "editor" -  opts.height = math.min(math.ceil(vim.o.lines * height_percentage), #buf_lines) -  opts.row = math.ceil(vim.o.lines * row_start_percentage) -  opts.col = math.floor(vim.o.columns * col_start_percentage) -  opts.width = math.floor(vim.o.columns * width_percentage) -  opts.style = "minimal" -  opts.border = "rounded" -  --[[ -  opts.border = { -    lvim.builtin.telescope.defaults.borderchars[5], -- "┌", -    lvim.builtin.telescope.defaults.borderchars[3], -- "-", -    lvim.builtin.telescope.defaults.borderchars[6], -- "┐", -    lvim.builtin.telescope.defaults.borderchars[2], -- "|", -    lvim.builtin.telescope.defaults.borderchars[7], -- "┘", -    lvim.builtin.telescope.defaults.borderchars[3], -- "-", -    lvim.builtin.telescope.defaults.borderchars[8], -- "└", -    lvim.builtin.telescope.defaults.borderchars[4], -- "|", -  } -  --]] - -  local win_id = vim.api.nvim_open_win(bufnr, true, opts) - -  vim.api.nvim_win_set_buf(win_id, bufnr) -  -- this needs to be window option! -  vim.api.nvim_win_set_option(win_id, "number", false) -  vim.cmd "setlocal nocursorcolumn" -  vim.cmd "setlocal wrap" -  -- set buffer options -  vim.api.nvim_buf_set_option(bufnr, "filetype", "lspinfo") -  vim.lsp.util.close_preview_autocmd({ "BufHidden", "BufLeave" }, win_id) -  buf_lines = vim.lsp.util._trim(buf_lines, {}) -  vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, buf_lines) -  vim.api.nvim_buf_set_option(bufnr, "modifiable", false) -  if type(callback) == "function" then -    callback() +  if not vim.tbl_isempty(supported_linters) then +    vim.list_extend(section, { +      "* Configured linter needs to be installed and executable.", +      fmt("* Enable installed linter(s) with following config in %s", config.path), +      "", +      fmt("  lvim.lang.%s.linters = { { exe = '%s' } }", ft, table.concat(supported_linters, "│")), +    })    end -  return bufnr, win_id + +  return section  end  local function tbl_set_highlight(terms, highlight_group) -  if type(terms) ~= "table" then -    return -  end -    for _, v in pairs(terms) do -    vim.cmd('let m=matchadd("' .. highlight_group .. '", "' .. v .. '")') +    vim.cmd('let m=matchadd("' .. highlight_group .. '", "' .. v .. "[ ,│']\")")    end  end  function M.toggle_popup(ft) -  local client = u.get_active_client_by_ft(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 -  local missing_linters = {} -  local missing_formatters = {} -  local num_caps = 0 -  local null_ls_providers = null_ls_handler.get_registered_providers_by_filetype(ft)    if client ~= nil then      is_client_active = not client.is_stopped()      client_enabled_caps = require("lsp").get_ls_capabilities(client.id) -    num_caps = vim.tbl_count(client_enabled_caps)      client_name = client.name      client_id = client.id      document_formatting = client.resolved_capabilities.document_formatting    end -  if lvim.lang[ft] ~= nil then -    missing_linters = lvim.lang[ft].linters._failed_requests or {} -    missing_formatters = lvim.lang[ft].formatters._failed_requests or {} -  end - -  local buf_lines = {} -  vim.list_extend(buf_lines, M.banner)    local header = { -    indent .. "Detected filetype:     " .. tostring(ft), -    indent .. "Treesitter active:     " .. tostring(next(vim.treesitter.highlighter.active) ~= nil), -    "", +    fmt("Detected filetype:      %s", ft), +    fmt("Treesitter active:      %s", tostring(next(vim.treesitter.highlighter.active) ~= nil)),    } -  vim.list_extend(buf_lines, header) +  local text = require "interface.text"    local lsp_info = { -    indent .. "Language Server Protocol (LSP) info", -    indent .. "* Associated server:   " .. client_name, -    indent .. "* Active:              " .. tostring(is_client_active) .. " (id: " .. tostring(client_id) .. ")", -    indent .. "* Supports formatting: " .. tostring(document_formatting), -    indent .. "* Capabilities list:   " .. table.concat(vim.list_slice(client_enabled_caps, 1, num_caps / 2), ", "), -    indent .. indent .. indent .. table.concat(vim.list_slice(client_enabled_caps, ((num_caps / 2) + 1)), ", "), -    "", +    "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)),    } -  vim.list_extend(buf_lines, lsp_info) - +  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) +  end +  local null_ls = require "lsp.null-ls" +  local registered_providers = null_ls.list_supported_provider_names(ft) +  local registered_count = vim.tbl_count(registered_providers)    local null_ls_info = { -    indent .. "Formatters and linters", -    indent .. "* Configured providers: " .. table.concat(null_ls_providers, "  , ") .. "  ", +    "Formatters and linters", +    fmt( +      "* Configured providers: %s%s", +      table.concat(registered_providers, "  , "), +      registered_count > 0 and "  " or "" +    ),    } -  vim.list_extend(buf_lines, null_ls_info) -  local missing_formatters_status -  if vim.tbl_count(missing_formatters) > 0 then +  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 = { -      indent .. "* Missing formatters:   " .. table.concat(missing_formatters, "  , ") .. "  ", +      fmt("* Missing formatters:   %s", table.concat(missing_formatters, "  , ") .. "  "),      } -    vim.list_extend(buf_lines, missing_formatters_status)    end -  local missing_linters_status -  if vim.tbl_count(missing_linters) > 0 then +  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 = { -      indent .. "* Missing linters:      " .. table.concat(missing_linters, "  , ") .. "  ", +      fmt("* Missing linters:      %s", table.concat(missing_linters, "  , ") .. "  "),      } -    vim.list_extend(buf_lines, missing_linters_status)    end -  vim.list_extend(buf_lines, { "" }) - -  vim.list_extend(buf_lines, get_formatter_suggestion_msg(ft)) - -  vim.list_extend(buf_lines, get_linter_suggestion_msg(ft)) +  local content_provider = function(popup) +    local content = {} + +    for _, section in ipairs { +      M.banner, +      { "" }, +      { "" }, +      header, +      { "" }, +      lsp_info, +      { "" }, +      null_ls_info, +      missing_formatters_status, +      missing_linters_status, +      { "" }, +      { "" }, +      get_formatter_suggestion_msg(ft), +      { "" }, +      { "" }, +      get_linter_suggestion_msg(ft), +    } do +      vim.list_extend(content, section) +    end + +    return text.align(popup, content, 0.5) +  end    local function set_syntax_hl()      vim.cmd [[highlight LvimInfoIdentifier gui=bold]]      vim.cmd [[highlight link LvimInfoHeader Type]] -    vim.cmd [[let m=matchadd("DashboardHeader", "Language Server Protocol (LSP) info")]] -    vim.cmd [[let m=matchadd("DashboardHeader", "Formatters and linters")]] +    vim.cmd [[let m=matchadd("LvimInfoHeader", "Language Server Protocol (LSP) info")]] +    vim.cmd [[let m=matchadd("LvimInfoHeader", "Formatters and linters")]]      vim.cmd('let m=matchadd("LvimInfoIdentifier", " ' .. ft .. '$")')      vim.cmd 'let m=matchadd("string", "true")'      vim.cmd 'let m=matchadd("error", "false")' -    tbl_set_highlight(null_ls_providers, "LvimInfoIdentifier") +    tbl_set_highlight(registered_providers, "LvimInfoIdentifier")      tbl_set_highlight(missing_formatters, "LvimInfoIdentifier")      tbl_set_highlight(missing_linters, "LvimInfoIdentifier") -    -- tbl_set_highlight(u.get_supported_formatters_by_filetype(ft), "LvimInfoIdentifier") -    -- tbl_set_highlight(u.get_supported_linters_by_filetype(ft), "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 -  return M.create_simple_popup(buf_lines, set_syntax_hl) +  local Popup = require("interface.popup"):new { +    win_opts = { number = false }, +    buf_opts = { modifiable = false, filetype = "lspinfo" }, +  } +  Popup:display(content_provider) +  set_syntax_hl() + +  return Popup  end  return M diff --git a/lua/core/log.lua b/lua/core/log.lua index 5dd5622e..1eb786ba 100644 --- a/lua/core/log.lua +++ b/lua/core/log.lua @@ -1,29 +1,59 @@  local Log = {} ---- Creates a log handle based on Plenary.log ----@param opts these are passed verbatim to Plenary.log ----@return log handle -function Log:new(opts) -  local status_ok, _ = pcall(require, "plenary.log") -  if not status_ok then -    return nil +--- Adds a log entry using Plenary.log +---@param msg any +---@param level string [same as vim.log.log_levels] +function Log:add_entry(msg, level) +  assert(type(level) == "string") +  if self.__handle then +    -- plenary uses lower-case log levels +    self.__handle[level:lower()](msg)    end +  local status_ok, plenary = pcall(require, "plenary") +  if status_ok then +    local default_opts = { plugin = "lunarvim", level = lvim.log.level } +    local handle = plenary.log.new(default_opts) +    handle[level:lower()](msg) +    self.__handle = handle +  end +  -- don't do anything if plenary is not available +end -  local obj = require("plenary.log").new(opts) -  local path = string.format("%s/%s.log", vim.api.nvim_call_function("stdpath", { "cache" }), opts.plugin) +---Retrieves the path of the logfile +---@return string path of the logfile +function Log:get_path() +  return string.format("%s/%s.log", vim.fn.stdpath "cache", "lunarvim") +end -  obj.get_path = function() -    return path -  end +---Add a log entry at TRACE level +---@param msg any +function Log:trace(msg) +  self:add_entry(msg, "TRACE") +end + +---Add a log entry at DEBUG level +---@param msg any +function Log:debug(msg) +  self:add_entry(msg, "DEBUG") +end + +---Add a log entry at INFO level +---@param msg any +function Log:info(msg) +  self:add_entry(msg, "INFO") +end -  return obj +---Add a log entry at WARN level +---@param msg any +function Log:warn(msg) +  self:add_entry(msg, "WARN")  end ---- Creates or retrieves a log handle for the default logfile ---- based on Plenary.log ----@return log handle -function Log:get_default() -  return Log:new { plugin = "lunarvim", level = lvim.log.level } +---Add a log entry at ERROR level +---@param msg any +function Log:error(msg) +  self:add_entry(msg, "ERROR")  end +setmetatable({}, Log)  return Log diff --git a/lua/core/lspinstall.lua b/lua/core/lspinstall.lua new file mode 100644 index 00000000..0bb59e0e --- /dev/null +++ b/lua/core/lspinstall.lua @@ -0,0 +1,19 @@ +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/colors.lua b/lua/core/lualine/colors.lua new file mode 100644 index 00000000..4984cd1f --- /dev/null +++ b/lua/core/lualine/colors.lua @@ -0,0 +1,16 @@ +local colors = { +  bg = "#202328", +  fg = "#bbc2cf", +  yellow = "#ECBE7B", +  cyan = "#008080", +  darkblue = "#081633", +  green = "#98be65", +  orange = "#FF8800", +  violet = "#a9a1e1", +  magenta = "#c678dd", +  purple = "#c678dd", +  blue = "#51afef", +  red = "#ec5f67", +} + +return colors diff --git a/lua/core/lualine/components.lua b/lua/core/lualine/components.lua new file mode 100644 index 00000000..894d9e9b --- /dev/null +++ b/lua/core/lualine/components.lua @@ -0,0 +1,152 @@ +local conditions = require "core.lualine.conditions" +local colors = require "core.lualine.colors" + +local function diff_source() +  local gitsigns = vim.b.gitsigns_status_dict +  if gitsigns then +    return { +      added = gitsigns.added, +      modified = gitsigns.changed, +      removed = gitsigns.removed, +    } +  end +end + +return { +  mode = { +    function() +      return " " +    end, +    left_padding = 0, +    right_padding = 0, +    color = {}, +    condition = nil, +  }, +  branch = { +    "b:gitsigns_head", +    icon = " ", +    color = { gui = "bold" }, +    condition = conditions.hide_in_width, +  }, +  filename = { +    "filename", +    color = {}, +    condition = 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 }, +    color = {}, +    condition = nil, +  }, +  python_env = { +    function() +      local utils = require "core.lualine.utils" +      if vim.bo.filetype == "python" then +        local venv = os.getenv "CONDA_DEFAULT_ENV" +        if venv then +          return string.format("  (%s)", utils.env_cleanup(venv)) +        end +        venv = os.getenv "VIRTUAL_ENV" +        if venv then +          return string.format("  (%s)", utils.env_cleanup(venv)) +        end +        return "" +      end +      return "" +    end, +    color = { fg = colors.green }, +    condition = conditions.hide_in_width, +  }, +  diagnostics = { +    "diagnostics", +    sources = { "nvim_lsp" }, +    symbols = { error = " ", warn = " ", info = " ", hint = " " }, +    color = {}, +    condition = conditions.hide_in_width, +  }, +  treesitter = { +    function() +      if next(vim.treesitter.highlighter.active) then +        return "  " +      end +      return "" +    end, +    color = { fg = colors.green }, +    condition = conditions.hide_in_width, +  }, +  lsp = { +    function(msg) +      msg = msg or "LSP Inactive" +      local buf_clients = vim.lsp.buf_get_clients() +      if next(buf_clients) == nil then +        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" +      local supported_formatters = formatters.list_supported_names(buf_ft) +      vim.list_extend(buf_client_names, supported_formatters) + +      -- add linter +      local linters = require "lsp.null-ls.linters" +      local supported_linters = linters.list_supported_names(buf_ft) +      vim.list_extend(buf_client_names, supported_linters) + +      return table.concat(buf_client_names, ", ") +    end, +    icon = " ", +    color = { gui = "bold" }, +    condition = conditions.hide_in_width, +  }, +  location = { "location", condition = conditions.hide_in_width, color = {} }, +  progress = { "progress", condition = conditions.hide_in_width, color = {} }, +  spaces = { +    function() +      local label = "Spaces: " +      if not vim.api.nvim_buf_get_option(0, "expandtab") then +        label = "Tab size: " +      end +      return label .. vim.api.nvim_buf_get_option(0, "shiftwidth") .. " " +    end, +    condition = conditions.hide_in_width, +    color = {}, +  }, +  encoding = { +    "o:encoding", +    upper = true, +    color = {}, +    condition = conditions.hide_in_width, +  }, +  filetype = { "filetype", condition = conditions.hide_in_width, color = {} }, +  scrollbar = { +    function() +      local current_line = vim.fn.line "." +      local total_lines = vim.fn.line "$" +      local chars = { "__", "▁▁", "▂▂", "▃▃", "▄▄", "▅▅", "▆▆", "▇▇", "██" } +      local line_ratio = current_line / total_lines +      local index = math.ceil(line_ratio * #chars) +      return chars[index] +    end, +    left_padding = 0, +    right_padding = 0, +    color = { fg = colors.yellow, bg = colors.bg }, +    condition = nil, +  }, +} diff --git a/lua/core/lualine/conditions.lua b/lua/core/lualine/conditions.lua new file mode 100644 index 00000000..3ee4fbb8 --- /dev/null +++ b/lua/core/lualine/conditions.lua @@ -0,0 +1,17 @@ +local window_width_limit = 80 + +local conditions = { +  buffer_not_empty = function() +    return vim.fn.empty(vim.fn.expand "%:t") ~= 1 +  end, +  hide_in_width = function() +    return vim.fn.winwidth(0) > window_width_limit +  end, +  -- check_git_workspace = function() +  --   local filepath = vim.fn.expand "%:p:h" +  --   local gitdir = vim.fn.finddir(".git", filepath .. ";") +  --   return gitdir and #gitdir > 0 and #gitdir < #filepath +  -- end, +} + +return conditions diff --git a/lua/core/lualine/init.lua b/lua/core/lualine/init.lua new file mode 100644 index 00000000..aa6fe098 --- /dev/null +++ b/lua/core/lualine/init.lua @@ -0,0 +1,47 @@ +local M = {} +M.config = function() +  lvim.builtin.lualine = { +    active = true, +    style = "lvim", +    options = { +      icons_enabled = nil, +      component_separators = nil, +      section_separators = nil, +      theme = nil, +      disabled_filetypes = nil, +    }, +    sections = { +      lualine_a = nil, +      lualine_b = nil, +      lualine_c = nil, +      lualine_x = nil, +      lualine_y = nil, +      lualine_z = nil, +    }, +    inactive_sections = { +      lualine_a = nil, +      lualine_b = nil, +      lualine_c = nil, +      lualine_x = nil, +      lualine_y = nil, +      lualine_z = nil, +    }, +    tabline = nil, +    extensions = nil, +    on_config_done = nil, +  } +end + +M.setup = function() +  require("core.lualine.styles").update() +  require("core.lualine.utils").validate_theme() + +  local lualine = require "lualine" +  lualine.setup(lvim.builtin.lualine) + +  if lvim.builtin.lualine.on_config_done then +    lvim.builtin.lualine.on_config_done(lualine) +  end +end + +return M diff --git a/lua/core/lualine/styles.lua b/lua/core/lualine/styles.lua new file mode 100644 index 00000000..3595e5e3 --- /dev/null +++ b/lua/core/lualine/styles.lua @@ -0,0 +1,137 @@ +local M = {} +local components = require "core.lualine.components" + +local styles = { +  lvim = nil, +  default = nil, +  none = nil, +} + +styles.none = { +  style = "none", +  options = { +    icons_enabled = true, +    component_separators = "", +    section_separators = "", +    disabled_filetypes = {}, +  }, +  sections = { +    lualine_a = {}, +    lualine_b = {}, +    lualine_c = {}, +    lualine_x = {}, +    lualine_y = {}, +    lualine_z = {}, +  }, +  inactive_sections = { +    lualine_a = {}, +    lualine_b = {}, +    lualine_c = {}, +    lualine_x = {}, +    lualine_y = {}, +    lualine_z = {}, +  }, +  tabline = {}, +  extensions = {}, +} + +styles.default = { +  style = "default", +  options = { +    icons_enabled = true, +    component_separators = { "", "" }, +    section_separators = { "", "" }, +    disabled_filetypes = {}, +  }, +  sections = { +    lualine_a = { "mode" }, +    lualine_b = { "branch" }, +    lualine_c = { "filename" }, +    lualine_x = { "encoding", "fileformat", "filetype" }, +    lualine_y = { "progress" }, +    lualine_z = { "location" }, +  }, +  inactive_sections = { +    lualine_a = {}, +    lualine_b = {}, +    lualine_c = { "filename" }, +    lualine_x = { "location" }, +    lualine_y = {}, +    lualine_z = {}, +  }, +  tabline = {}, +  extensions = {}, +} + +styles.lvim = { +  style = "lvim", +  options = { +    icons_enabled = true, +    component_separators = "", +    section_separators = "", +    disabled_filetypes = { "dashboard", "NvimTree", "Outline" }, +  }, +  sections = { +    lualine_a = { +      components.mode, +    }, +    lualine_b = { +      components.branch, +      components.filename, +    }, +    lualine_c = { +      components.diff, +      components.python_env, +    }, +    lualine_x = { +      components.diagnostics, +      components.treesitter, +      components.lsp, +      components.filetype, +    }, +    lualine_y = {}, +    lualine_z = { +      components.scrollbar, +    }, +  }, +  inactive_sections = { +    lualine_a = { +      "filename", +    }, +    lualine_b = {}, +    lualine_c = {}, +    lualine_x = {}, +    lualine_y = {}, +    lualine_z = {}, +  }, +  tabline = {}, +  extensions = { "nvim-tree" }, +} + +function M.get_style(style) +  local style_keys = vim.tbl_keys(styles) +  if not vim.tbl_contains(style_keys, style) then +    local Log = require "core.log" +    Log:error( +      "Invalid lualine style", +      string.format('"%s"', style), +      "options are: ", +      string.format('"%s"', table.concat(style_keys, '", "')) +    ) +    Log:debug '"lvim" style is applied.' +    style = "lvim" +  end + +  return vim.deepcopy(styles[style]) +end + +function M.update() +  local style = M.get_style(lvim.builtin.lualine.style) +  if lvim.builtin.lualine.options.theme == nil then +    lvim.builtin.lualine.options.theme = lvim.colorscheme +  end + +  lvim.builtin.lualine = vim.tbl_deep_extend("keep", lvim.builtin.lualine, style) +end + +return M diff --git a/lua/core/lualine/utils.lua b/lua/core/lualine/utils.lua new file mode 100644 index 00000000..cf80a99e --- /dev/null +++ b/lua/core/lualine/utils.lua @@ -0,0 +1,27 @@ +local M = {} + +function M.validate_theme() +  local theme = lvim.builtin.lualine.options.theme +  if type(theme) == "table" then +    return +  end + +  local lualine_loader = require "lualine.utils.loader" +  local ok = pcall(lualine_loader.load_theme, theme) +  if not ok then +    lvim.builtin.lualine.options.theme = "auto" +  end +end + +function M.env_cleanup(venv) +  if string.find(venv, "/") then +    local final_venv = venv +    for w in venv:gmatch "([^/]+)" do +      final_venv = w +    end +    venv = final_venv +  end +  return venv +end + +return M diff --git a/lua/core/nvimtree.lua b/lua/core/nvimtree.lua index 4d15b1b5..6aa5401d 100644 --- a/lua/core/nvimtree.lua +++ b/lua/core/nvimtree.lua @@ -1,8 +1,10 @@  local M = {}  local Log = require "core.log" --- -M.config = function() + +function M.config()    lvim.builtin.nvimtree = { +    active = true, +    on_config_done = nil,      side = "left",      width = 30,      show_icons = { @@ -13,7 +15,7 @@ M.config = function()        tree_width = 30,      },      ignore = { ".git", "node_modules", ".cache" }, -    auto_open = 1, +    auto_open = 0,      auto_close = 1,      quit_on_open = 0,      follow = 1, @@ -46,11 +48,11 @@ M.config = function()      },    }  end --- -M.setup = function() + +function M.setup()    local status_ok, nvim_tree_config = pcall(require, "nvim-tree.config")    if not status_ok then -    Log:get_default().error "Failed to load nvim-tree.config" +    Log:error "Failed to load nvim-tree.config"      return    end    local g = vim.g @@ -59,6 +61,15 @@ M.setup = function()      g["nvim_tree_" .. opt] = val    end +  -- 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 +    vim.g.netrw_banner = 0 +  end +    local tree_cb = nvim_tree_config.nvim_tree_callback    if not g.nvim_tree_bindings then @@ -68,61 +79,44 @@ M.setup = function()        { key = "v", cb = tree_cb "vsplit" },      }    end -end --- -M.focus_or_close = function() -  local view_status_ok, view = pcall(require, "nvim-tree.view") -  if not view_status_ok then -    return + +  lvim.builtin.which_key.mappings["e"] = { "<cmd>NvimTreeToggle<CR>", "Explorer" } + +  local tree_view = require "nvim-tree.view" + +  -- Add nvim_tree open callback +  local open = tree_view.open +  tree_view.open = function() +    M.on_open() +    open()    end -  local a = vim.api -  local curwin = a.nvim_get_current_win() -  local curbuf = a.nvim_win_get_buf(curwin) -  local bufnr = view.View.bufnr -  local winnr = view.get_winnr() +  vim.cmd "au WinClosed * lua require('core.nvimtree').on_close()" -  if view.win_open() then -    if curwin == winnr and curbuf == bufnr then -      view.close() -      if package.loaded["bufferline.state"] then -        require("bufferline.state").set_offset(0) -      end -    else -      view.focus() -    end -  else -    view.open() -    if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then -      -- require'bufferline.state'.set_offset(lvim.builtin.nvimtree.width + 1, 'File Explorer') -      require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "") -    end +  if lvim.builtin.nvimtree.on_config_done then +    lvim.builtin.nvimtree.on_config_done(nvim_tree_config)    end  end --- -M.toggle_tree = function() -  local view_status_ok, view = pcall(require, "nvim-tree.view") -  if not view_status_ok then -    return + +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, "")    end -  if view.win_open() then -    require("nvim-tree").close() -    if package.loaded["bufferline.state"] then -      require("bufferline.state").set_offset(0) -    end -  else -    if package.loaded["bufferline.state"] and lvim.builtin.nvimtree.side == "left" then -      -- require'bufferline.state'.set_offset(lvim.builtin.nvimtree.width + 1, 'File Explorer') -      require("bufferline.state").set_offset(lvim.builtin.nvimtree.width + 1, "") -    end -    require("nvim-tree").toggle() +end + +function M.on_close() +  local buf = tonumber(vim.fn.expand "<abuf>") +  local ft = vim.api.nvim_buf_get_option(buf, "filetype") +  if ft == "NvimTree" and package.loaded["bufferline.state"] then +    require("bufferline.state").set_offset(0)    end  end --- +  function M.change_tree_dir(dir) -  if vim.g.loaded_tree then -    require("nvim-tree.lib").change_dir(dir) +  local lib_status_ok, lib = pcall(require, "nvim-tree.lib") +  if lib_status_ok then +    lib.change_dir(dir)    end  end --- +  return M diff --git a/lua/core/project.lua b/lua/core/project.lua new file mode 100644 index 00000000..7fb04933 --- /dev/null +++ b/lua/core/project.lua @@ -0,0 +1,51 @@ +local M = {} + +function M.config() +  lvim.builtin.project = { +    ---@usage set to false to disable project.nvim. +    --- This is on by default since it's currently the expected behavior. +    active = true, + +    on_config_done = nil, + +    ---@usage set to true to disable setting the current-woriking directory +    --- Manual mode doesn't automatically change your root directory, so you have +    --- the option to manually do so using `:ProjectRoot` command. +    manual_mode = false, + +    ---@usage Methods of detecting the root directory +    --- Allowed values: **"lsp"** uses the native neovim lsp +    --- **"pattern"** uses vim-rooter like glob pattern matching. Here +    --- order matters: if one is not detected, the other is used as fallback. You +    --- can also delete or rearangne the detection methods. +    detection_methods = { "lsp", "pattern" }, + +    ---@usage patterns used to detect root dir, when **"pattern"** is in detection_methods +    patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json" }, + +    ---@ Show hidden files in telescope when searching for files in a project +    show_hidden = false, + +    ---@usage When set to false, you will get a message when project.nvim changes your directory. +    -- When set to false, you will get a message when project.nvim changes your directory. +    silent_chdir = true, + +    ---@usage list of lsp client names to ignore when using **lsp** detection. eg: { "efm", ... } +    ignore_lsp = {}, + +    ---@type string +    ---@usage path to store the project history for use in telescope +    datapath = CACHE_PATH, +  } +end + +function M.setup() +  local project = require "project_nvim" + +  project.setup(lvim.builtin.project) +  if lvim.builtin.project.on_config_done then +    lvim.builtin.project.on_config_done(project) +  end +end + +return M diff --git a/lua/core/rooter.lua b/lua/core/rooter.lua deleted file mode 100644 index 8ebdf7cc..00000000 --- a/lua/core/rooter.lua +++ /dev/null @@ -1,15 +0,0 @@ -local M = {} -function M.config() -  lvim.builtin.rooter = { -    --- This is on by default since it's currently the expected behavior. -    ---@usage set to false to disable vim-rooter. -    active = true, -    silent_chdir = 1, -    manual_only = 0, -  } -end -function M.setup() -  vim.g.rooter_silent_chdir = lvim.builtin.rooter.silent_chdir -  vim.g.rooter_manual_only = lvim.builtin.rooter.manual_only -end -return M diff --git a/lua/core/status_colors.lua b/lua/core/status_colors.lua deleted file mode 100644 index 37e9d7c9..00000000 --- a/lua/core/status_colors.lua +++ /dev/null @@ -1,19 +0,0 @@ -lvim.builtin.galaxyline = { -  active = true, -  colors = { -    alt_bg = "#2E2E2E", -    grey = "#858585", -    blue = "#569CD6", -    green = "#608B4E", -    yellow = "#DCDCAA", -    orange = "#FF8800", -    purple = "#C586C0", -    magenta = "#D16D9E", -    cyan = "#4EC9B0", -    red = "#D16969", -    error_red = "#F44747", -    warning_orange = "#FF8800", -    info_yellow = "#FFCC66", -    hint_blue = "#9CDCFE", -  }, -} diff --git a/lua/core/telescope.lua b/lua/core/telescope.lua index f4d154b0..4ae56df0 100644 --- a/lua/core/telescope.lua +++ b/lua/core/telescope.lua @@ -1,13 +1,19 @@  local M = {} -local Log = require "core.log" -M.config = function() + +function M.config() +  -- Define this minimal config so that it's available if telescope is not yet available. +  lvim.builtin.telescope = { +    ---@usage disable telescope completely [not recommeded] +    active = true, +    on_config_done = nil, +  } +    local status_ok, actions = pcall(require, "telescope.actions")    if not status_ok then      return    end -  lvim.builtin.telescope = { -    active = false, +  lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {      defaults = {        prompt_prefix = " ",        selection_caret = " ", @@ -60,8 +66,8 @@ M.config = function()            -- ["<CR>"] = actions.select_default + actions.center + my_cool_custom_action,          },          n = { -          ["<C-j>"] = actions.move_selection_next, -          ["<C-k>"] = actions.move_selection_previous, +          ["<C-n>"] = actions.move_selection_next, +          ["<C-p>"] = actions.move_selection_previous,            ["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,            -- ["<c-t>"] = trouble.open_with_trouble,            -- ["<C-i>"] = my_cool_custom_action, @@ -74,16 +80,54 @@ M.config = function()          override_file_sorter = true,        },      }, +  }) +end + +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_title = "~ LunarVim files ~", +    cwd = CONFIG_PATH, +    find_command = { "git", "ls-files" },    } +  opts = vim.tbl_deep_extend("force", theme_opts, opts) +  require("telescope.builtin").find_files(opts)  end -M.setup = function() -  local status_ok, telescope = pcall(require, "telescope") -  if not status_ok then -    Log:get_default().error "Failed to load telescope" -    return -  end +function M.grep_lunarvim_files(opts) +  opts = opts or {} +  local themes = require "telescope.themes" +  local theme_opts = themes.get_ivy { +    sorting_strategy = "ascending", +    layout_strategy = "bottom_pane", +    prompt = ">> ", +    prompt_title = "~ search LunarVim ~", +    cwd = CONFIG_PATH, +  } +  opts = vim.tbl_deep_extend("force", theme_opts, opts) +  require("telescope.builtin").live_grep(opts) +end + +function M.setup() +  local telescope = require "telescope" +    telescope.setup(lvim.builtin.telescope) +  if lvim.builtin.project.active then +    telescope.load_extension "projects" +  end + +  if lvim.builtin.telescope.on_config_done then +    lvim.builtin.telescope.on_config_done(telescope) +  end  end  return M diff --git a/lua/core/terminal.lua b/lua/core/terminal.lua index 818038fd..f9be8734 100644 --- a/lua/core/terminal.lua +++ b/lua/core/terminal.lua @@ -1,9 +1,9 @@  local M = {} -local Log = require "core.log"  local utils = require "utils"  M.config = function()    lvim.builtin["terminal"] = { +    on_config_done = nil,      -- size can be a number or function which is passed the current terminal      size = 20,      -- open_mapping = [[<c-\>]], @@ -46,20 +46,15 @@ M.config = function()  end  M.setup = function() -  local status_ok, terminal = pcall(require, "toggleterm") -  if not status_ok then -    Log:get_default().error "Failed to load toggleterm" -    print(terminal) -    return -  end +  local terminal = require "toggleterm"    for _, exec in pairs(lvim.builtin.terminal.execs) do      require("core.terminal").add_exec(exec[1], exec[2], exec[3])    end    terminal.setup(lvim.builtin.terminal) -end -local function is_installed(exe) -  return vim.fn.executable(exe) == 1 +  if lvim.builtin.terminal.on_config_done then +    lvim.builtin.terminal.on_config_done(terminal) +  end  end  M.add_exec = function(exec, keymap, name) @@ -85,8 +80,9 @@ end  M._exec_toggle = function(exec)    local binary = M._split(exec)[1] -  if is_installed(binary) ~= true then -    print("Please install executable " .. binary .. ". Check documentation for more information") +  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    local Terminal = require("toggleterm.terminal").Terminal @@ -126,7 +122,7 @@ M.toggle_log_view = function(name)    local Terminal = require("toggleterm.terminal").Terminal    local log_view = Terminal:new(term_opts) -  -- require("core.log"):get_default().debug("term", vim.inspect(term_opts)) +  -- require("core.log"):debug("term", vim.inspect(term_opts))    log_view:toggle()  end diff --git a/lua/core/treesitter.lua b/lua/core/treesitter.lua index 0a8a2ff2..d63024e6 100644 --- a/lua/core/treesitter.lua +++ b/lua/core/treesitter.lua @@ -1,7 +1,9 @@  local M = {}  local Log = require "core.log" +  M.config = function()    lvim.builtin.treesitter = { +    on_config_done = nil,      ensure_installed = {}, -- one of "all", "maintained" (parsers with maintainers), or a list of languages      ignore_install = {},      matchup = { @@ -70,6 +72,10 @@ M.setup = function()    end    treesitter_configs.setup(lvim.builtin.treesitter) + +  if lvim.builtin.treesitter.on_config_done then +    lvim.builtin.treesitter.on_config_done(treesitter_configs) +  end  end  return M diff --git a/lua/core/which-key.lua b/lua/core/which-key.lua index 96f3a8f7..71c0b695 100644 --- a/lua/core/which-key.lua +++ b/lua/core/which-key.lua @@ -1,8 +1,10 @@  local M = {} -local Log = require "core.log" +  M.config = function()    lvim.builtin.which_key = { -    active = false, +    ---@usage disable which-key completely [not recommeded] +    active = true, +    on_config_done = nil,      setup = {        plugins = {          marks = true, -- shows a list of your marks on ' and ` @@ -66,7 +68,6 @@ M.config = function()        ["q"] = { "<cmd>q!<CR>", "Quit" },        ["/"] = { "<cmd>CommentToggle<CR>", "Comment" },        ["c"] = { "<cmd>BufferClose!<CR>", "Close Buffer" }, -      ["e"] = { "<cmd>lua require'core.nvimtree'.toggle_tree()<CR>", "Explorer" },        ["f"] = { "<cmd>Telescope find_files<CR>", "Find File" },        ["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },        b = { @@ -169,6 +170,18 @@ M.config = function()        },        L = {          name = "+LunarVim", +        c = { +          "<cmd>edit ~/.config/lvim/config.lua<cr>", +          "Edit config.lua", +        }, +        f = { +          "<cmd>lua require('core.telescope').find_lunarvim_files()<cr>", +          "Find LunarVim files", +        }, +        g = { +          "<cmd>lua require('core.telescope').grep_lunarvim_files()<cr>", +          "Grep LunarVim files", +        },          k = { "<cmd>lua require('keymappings').print()<cr>", "View LunarVim's default keymappings" },          i = {            "<cmd>lua require('core.info').toggle_popup(vim.bo.filetype)<cr>", @@ -218,14 +231,7 @@ M.config = function()  end  M.setup = function() -  -- if not package.loaded['which-key'] then -  --  return -  -- end -  local status_ok, which_key = pcall(require, "which-key") -  if not status_ok then -    Log:get_default "Failed to load whichkey" -    return -  end +  local which_key = require "which-key"    which_key.setup(lvim.builtin.which_key.setup) @@ -235,10 +241,12 @@ M.setup = function()    local mappings = lvim.builtin.which_key.mappings    local vmappings = lvim.builtin.which_key.vmappings -  local wk = require "which-key" +  which_key.register(mappings, opts) +  which_key.register(vmappings, vopts) -  wk.register(mappings, opts) -  wk.register(vmappings, vopts) +  if lvim.builtin.which_key.on_config_done then +    lvim.builtin.which_key.on_config_done(which_key) +  end  end  return M diff --git a/lua/interface/popup.lua b/lua/interface/popup.lua new file mode 100644 index 00000000..b628125c --- /dev/null +++ b/lua/interface/popup.lua @@ -0,0 +1,62 @@ +local Popup = {} + +--- Create a new floating window +-- @param config The configuration passed to vim.api.nvim_open_win +-- @param win_opts The options registered with vim.api.nvim_win_set_option +-- @param buf_opts The options registered with vim.api.nvim_buf_set_option +-- @return A new popup +function Popup:new(opts) +  opts = opts or {} +  opts.layout = opts.layout or {} +  opts.win_opts = opts.win_opts or {} +  opts.buf_opts = opts.buf_opts or {} + +  Popup.__index = Popup + +  local editor_layout = { +    height = vim.o.lines - vim.o.cmdheight - 2, -- Add margin for status and buffer line +    width = vim.o.columns, +  } +  local popup_layout = { +    relative = "editor", +    height = math.floor(editor_layout.height * 0.9), +    width = math.floor(editor_layout.width * 0.8), +    style = "minimal", +    border = "rounded", +  } +  popup_layout.row = math.floor((editor_layout.height - popup_layout.height) / 2) +  popup_layout.col = math.floor((editor_layout.width - popup_layout.width) / 2) + +  local obj = { +    buffer = vim.api.nvim_create_buf(false, true), +    layout = vim.tbl_deep_extend("force", popup_layout, opts.layout), +    win_opts = opts.win_opts, +    buf_opts = opts.buf_opts, +  } + +  setmetatable(obj, Popup) + +  return obj +end + +--- Display the popup with the provided content +-- @param content_provider A function accepting the popup's layout and returning the content to display +function Popup:display(content_provider) +  self.win_id = vim.api.nvim_open_win(self.buffer, true, self.layout) +  vim.lsp.util.close_preview_autocmd({ "BufHidden", "BufLeave" }, self.win_id) + +  local lines = content_provider(self.layout) +  vim.api.nvim_buf_set_lines(self.bufnr, 0, -1, false, lines) + +  -- window options +  for key, value in pairs(self.win_opts) do +    vim.api.nvim_win_set_option(self.win_id, key, value) +  end + +  -- buffer options +  for key, value in pairs(self.buf_opts) do +    vim.api.nvim_buf_set_option(self.buffer, key, value) +  end +end + +return Popup diff --git a/lua/interface/text.lua b/lua/interface/text.lua new file mode 100644 index 00000000..f68cc491 --- /dev/null +++ b/lua/interface/text.lua @@ -0,0 +1,79 @@ +local M = {} + +local function max_len_line(lines) +  local max_len = 0 + +  for _, line in ipairs(lines) do +    local line_len = line:len() +    if line_len > max_len then +      max_len = line_len +    end +  end + +  return max_len +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(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) +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) +  local output = {} +  local padding = string.rep(" ", amount) + +  for _, line in ipairs(lines) do +    table.insert(output, padding .. line) +  end + +  return output +end + +--- Pretty format tables +-- @param entries The table to format +-- @param col_count The number of column to span the table on +-- @param col_sep The separator between each colummn, default: " " +function M.format_table(entries, col_count, col_sep) +  col_sep = col_sep or " " + +  local col_rows = math.ceil(vim.tbl_count(entries) / col_count) +  local cols = {} +  local count = 0 + +  for i, entry in ipairs(entries) do +    if ((i - 1) % col_rows) == 0 then +      table.insert(cols, {}) +      count = count + 1 +    end +    table.insert(cols[count], entry) +  end + +  local col_max_len = {} +  for _, col in ipairs(cols) do +    table.insert(col_max_len, max_len_line(col)) +  end + +  local output = {} +  for i, col in ipairs(cols) do +    for j, entry in ipairs(col) do +      if not output[j] then +        output[j] = entry +      else +        local padding = string.rep(" ", col_max_len[i - 1] - cols[i - 1][j]:len()) +        output[j] = output[j] .. padding .. col_sep .. entry +      end +    end +  end + +  return output +end + +return M diff --git a/lua/keymappings.lua b/lua/keymappings.lua index e82df5ae..557e0bde 100644 --- a/lua/keymappings.lua +++ b/lua/keymappings.lua @@ -8,6 +8,7 @@ local generic_opts = {    normal_mode = generic_opts_any,    visual_mode = generic_opts_any,    visual_block_mode = generic_opts_any, +  command_mode = generic_opts_any,    term_mode = { silent = true },  } @@ -17,6 +18,7 @@ local mode_adapters = {    term_mode = "t",    visual_mode = "v",    visual_block_mode = "x", +  command_mode = "c",  }  -- Append key mappings to lunarvim's defaults for a given mode @@ -142,6 +144,14 @@ function M.config()        ["<A-j>"] = ":m '>+1<CR>gv-gv",        ["<A-k>"] = ":m '<-2<CR>gv-gv",      }, + +    ---@usage change or add keymappings for command mode +    command_mode = { +      -- 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 } }, +    },    }    if vim.fn.has "mac" == 1 then @@ -149,9 +159,7 @@ function M.config()      lvim.keys.normal_mode["<A-Down>"] = lvim.keys.normal_mode["<C-Down>"]      lvim.keys.normal_mode["<A-Left>"] = lvim.keys.normal_mode["<C-Left>"]      lvim.keys.normal_mode["<A-Right>"] = lvim.keys.normal_mode["<C-Right>"] -    if Log:get_default() then -      Log:get_default().info "Activated mac keymappings" -    end +    Log:debug "Activated mac keymappings"    end  end diff --git a/lua/lsp/init.lua b/lua/lsp/init.lua index e4ea02db..9c948803 100644 --- a/lua/lsp/init.lua +++ b/lua/lsp/init.lua @@ -1,5 +1,6 @@  local M = {}  local Log = require "core.log" +  function M.config()    vim.lsp.protocol.CompletionItemKind = lvim.lsp.completion.item_kind @@ -33,13 +34,17 @@ local function lsp_highlight_document(client)  end  local function add_lsp_buffer_keybindings(bufnr) -  local wk = require "which-key" +  local status_ok, wk = pcall(require, "which-key") +  if not status_ok 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" }, +    ["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"] = { @@ -50,14 +55,6 @@ local function add_lsp_buffer_keybindings(bufnr)    wk.register(keys, { mode = "n", buffer = bufnr })  end -local function set_smart_cwd(client) -  local proj_dir = client.config.root_dir -  if lvim.lsp.smart_cwd and proj_dir ~= "/" then -    vim.api.nvim_set_current_dir(proj_dir) -    require("core.nvimtree").change_tree_dir(proj_dir) -  end -end -  function M.common_capabilities()    local capabilities = vim.lsp.protocol.make_client_capabilities()    capabilities.textDocument.completion.completionItem.snippetSupport = true @@ -102,14 +99,14 @@ end  function M.common_on_init(client, bufnr)    if lvim.lsp.on_init_callback then      lvim.lsp.on_init_callback(client, bufnr) -    Log:get_default().info "Called lsp.on_init_callback" +    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:get_default().info( +    Log:debug(        string.format("Overriding language server [%s] with format provider [%s]", client.name, formatters[1].exe)      )    end @@ -118,22 +115,21 @@ end  function M.common_on_attach(client, bufnr)    if lvim.lsp.on_attach_callback then      lvim.lsp.on_attach_callback(client, bufnr) -    Log:get_default().info "Called lsp.on_init_callback" +    Log:debug "Called lsp.on_init_callback"    end    lsp_highlight_document(client)    add_lsp_buffer_keybindings(bufnr) -  set_smart_cwd(client)    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 require("utils").check_lsp_client_active(lsp.provider) then +  if lsp_utils.is_client_active(lsp.provider) then      return    end    local overrides = lvim.lsp.override -    if type(overrides) == "table" then      if vim.tbl_contains(overrides, lang) then        return @@ -142,6 +138,17 @@ function M.setup(lang)    if lsp.provider ~= nil and lsp.provider ~= "" then      local lspconfig = require "lspconfig" + +    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 +      lspconfig[lsp.provider].setup(lsp.setup)    end  end diff --git a/lua/lsp/null-ls.lua b/lua/lsp/null-ls.lua deleted file mode 100644 index 697eac39..00000000 --- a/lua/lsp/null-ls.lua +++ /dev/null @@ -1,142 +0,0 @@ -local M = {} -local Log = require "core.log" - -local null_ls = require "null-ls" - -local nodejs_local_providers = { "prettier", "prettierd", "prettier_d_slim", "eslint_d", "eslint" } - -M.requested_providers = {} - -function M.get_registered_providers_by_filetype(ft) -  local matches = {} -  for _, provider in pairs(M.requested_providers) do -    if vim.tbl_contains(provider.filetypes, ft) then -      local provider_name = provider.name -      -- special case: show "eslint_d" instead of eslint -      -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint -      if string.find(provider._opts.command, "eslint_d") then -        provider_name = "eslint_d" -      end -      table.insert(matches, provider_name) -    end -  end - -  return matches -end - -function M.get_missing_providers_by_filetype(ft) -  local matches = {} -  for _, provider in pairs(M.requested_providers) do -    if vim.tbl_contains(provider.filetypes, ft) then -      local provider_name = provider.name - -      table.insert(matches, provider_name) -    end -  end - -  return matches -end - -local function register_failed_request(ft, provider, operation) -  if not lvim.lang[ft][operation]._failed_requests then -    lvim.lang[ft][operation]._failed_requests = {} -  end -  table.insert(lvim.lang[ft][operation]._failed_requests, provider) -end - -local function validate_nodejs_provider(provider) -  local command_path -  local root_dir -  if lvim.builtin.rooter.active then -    --- use vim-rooter to set root_dir -    vim.cmd "let root_dir = FindRootDirectory()" -    root_dir = vim.api.nvim_get_var "root_dir" -  else -    --- use LSP to set root_dir -    local ts_client = require("utils").get_active_client_by_ft "typescript" -    if ts_client == nil then -      Log:get_default().error "Unable to determine root directory since tsserver didn't start correctly" -      return -    end -    root_dir = ts_client.config.root_dir -  end -  local local_nodejs_command = root_dir .. "/node_modules/.bin/" .. provider._opts.command -  Log:get_default().debug("checking for local node module: ", vim.inspect(provider)) - -  if vim.fn.executable(local_nodejs_command) == 1 then -    command_path = local_nodejs_command -  elseif vim.fn.executable(provider._opts.command) == 1 then -    Log:get_default().debug("checking in global path instead for node module", provider._opts.command) -    command_path = provider._opts.command -  else -    Log:get_default().debug("Unable to find node module", provider._opts.command) -  end -  return command_path -end - -local function validate_provider_request(provider) -  if provider == "" or provider == nil then -    return -  end -  -- NOTE: we can't use provider.name because eslint_d uses eslint name -  if vim.tbl_contains(nodejs_local_providers, provider._opts.command) then -    return validate_nodejs_provider(provider) -  end -  if vim.fn.executable(provider._opts.command) ~= 1 then -    Log:get_default().debug("Unable to find the path for", vim.inspect(provider)) -    Log:get_default().warn("Unable to find the path for ", provider._opts.command) -    return -  end -  return provider._opts.command -end - --- TODO: for linters and formatters with spaces and '-' replace with '_' -function M.setup(filetype) -  for _, formatter in pairs(lvim.lang[filetype].formatters) do -    Log:get_default().debug("validating format provider: ", formatter.exe) -    local builtin_formatter = null_ls.builtins.formatting[formatter.exe] -    if not vim.tbl_contains(M.requested_providers, builtin_formatter) then -      -- FIXME: why doesn't this work? -      -- builtin_formatter._opts.args = formatter.args or builtin_formatter._opts.args -      -- builtin_formatter._opts.to_stdin = formatter.stdin or builtin_formatter._opts.to_stdin -      local resolved_path = validate_provider_request(builtin_formatter) -      if resolved_path then -        builtin_formatter._opts.command = resolved_path -        table.insert(M.requested_providers, builtin_formatter) -        Log:get_default().info("Using format provider", builtin_formatter.name) -      else -        -- mark it here to avoid re-doing the lookup again -        register_failed_request(filetype, formatter.exe, "formatters") -      end -    end -  end - -  for _, linter in pairs(lvim.lang[filetype].linters) do -    local builtin_diagnoser = null_ls.builtins.diagnostics[linter.exe] -    Log:get_default().debug("validating lint provider: ", linter.exe) -    -- special case: fallback to "eslint" -    -- https://github.com/jose-elias-alvarez/null-ls.nvim/blob/9b8458bd1648e84169a7e8638091ba15c2f20fc0/doc/BUILTINS.md#eslint -    -- if provider.exe -    if linter.exe == "eslint_d" then -      builtin_diagnoser = null_ls.builtins.diagnostics.eslint.with { command = "eslint_d" } -    end -    if not vim.tbl_contains(M.requested_providers, builtin_diagnoser) then -      -- FIXME: why doesn't this work? -      -- builtin_diagnoser._opts.args = linter.args or builtin_diagnoser._opts.args -      -- builtin_diagnoser._opts.to_stdin = linter.stdin or builtin_diagnoser._opts.to_stdin -      local resolved_path = validate_provider_request(builtin_diagnoser) -      if resolved_path then -        builtin_diagnoser._opts.command = resolved_path -        table.insert(M.requested_providers, builtin_diagnoser) -        Log:get_default().info("Using linter provider", builtin_diagnoser.name) -      else -        -- mark it here to avoid re-doing the lookup again -        register_failed_request(filetype, linter.exe, "linters") -      end -    end -  end - -  null_ls.register { sources = M.requested_providers } -end - -return M diff --git a/lua/lsp/null-ls/formatters.lua b/lua/lsp/null-ls/formatters.lua new file mode 100644 index 00000000..26be00da --- /dev/null +++ b/lua/lsp/null-ls/formatters.lua @@ -0,0 +1,74 @@ +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" }) +end + +function M.list_available(filetype) +  local formatters = {} +  for _, provider in pairs(null_ls.builtins.formatting) do +    -- TODO: Add support for wildcard filetypes +    if vim.tbl_contains(provider.filetypes or {}, filetype) then +      table.insert(formatters, provider.name) +    end +  end + +  return formatters +end + +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] + +    if not formatter then +      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) +        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 } +      end +    end +  end + +  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 +    return +  end + +  formatters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].formatters) +  null_ls.register { sources = formatters_by_ft[filetype].supported } +end + +return M diff --git a/lua/lsp/null-ls/init.lua b/lua/lsp/null-ls/init.lua new file mode 100644 index 00000000..ce4c07d9 --- /dev/null +++ b/lua/lsp/null-ls/init.lua @@ -0,0 +1,44 @@ +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" +    return +  end + +  local formatters = require "lsp.null-ls.formatters" +  local linters = require "lsp.null-ls.linters" + +  formatters.setup(filetype, options) +  linters.setup(filetype, options) +end + +return M diff --git a/lua/lsp/null-ls/linters.lua b/lua/lsp/null-ls/linters.lua new file mode 100644 index 00000000..bc191d7e --- /dev/null +++ b/lua/lsp/null-ls/linters.lua @@ -0,0 +1,74 @@ +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" }) +end + +function M.list_available(filetype) +  local linters = {} +  for _, provider in pairs(null_ls.builtins.diagnostics) do +    -- TODO: Add support for wildcard filetypes +    if vim.tbl_contains(provider.filetypes or {}, filetype) then +      table.insert(linters, provider.name) +    end +  end + +  return linters +end + +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] + +    if not linter then +      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) +        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 } +      end +    end +  end + +  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 +    return +  end + +  linters_by_ft[filetype] = M.list_configured(lvim.lang[filetype].linters) +  null_ls.register { sources = linters_by_ft[filetype].supported } +end + +return M diff --git a/lua/lsp/null-ls/services.lua b/lua/lsp/null-ls/services.lua new file mode 100644 index 00000000..a1e3a06c --- /dev/null +++ b/lua/lsp/null-ls/services.lua @@ -0,0 +1,47 @@ +local M = {} + +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 +    return ts_client.config.root_dir +  end +  local dirname = vim.fn.expand "%:p:h" +  return util.root_pattern "package.json"(dirname) +end + +local function from_node_modules(command) +  local root_dir = find_root_dir() + +  if not root_dir then +    return nil +  end + +  return root_dir .. "/node_modules/.bin/" .. command +end + +local local_providers = { +  prettier = { find = from_node_modules }, +  prettierd = { find = from_node_modules }, +  prettier_d_slim = { find = from_node_modules }, +  eslint_d = { find = from_node_modules }, +  eslint = { find = from_node_modules }, +} + +function M.find_command(command) +  if local_providers[command] then +    local local_command = local_providers[command].find(command) +    if local_command and vim.fn.executable(local_command) == 1 then +      return local_command +    end +  end + +  if vim.fn.executable(command) == 1 then +    return command +  end +  return nil +end + +return M diff --git a/lua/lsp/utils.lua b/lua/lsp/utils.lua new file mode 100644 index 00000000..17b9c3bc --- /dev/null +++ b/lua/lsp/utils.lua @@ -0,0 +1,28 @@ +local M = {} + +function M.is_client_active(name) +  local clients = vim.lsp.get_active_clients() +  for _, client in pairs(clients) do +    if client.name == name then +      return true, client +    end +  end +  return false +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 +  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 +    end +  end +  return nil +end + +return M diff --git a/lua/plugin-loader.lua b/lua/plugin-loader.lua index b7e68a1e..aa1e888d 100644 --- a/lua/plugin-loader.lua +++ b/lua/plugin-loader.lua @@ -1,13 +1,10 @@  local plugin_loader = {}  function plugin_loader:init() -  local execute = vim.api.nvim_command -  local fn = vim.fn -    local install_path = "~/.local/share/lunarvim/site/pack/packer/start/packer.nvim" -  if fn.empty(fn.glob(install_path)) > 0 then -    execute("!git clone https://github.com/wbthomason/packer.nvim " .. install_path) -    execute "packadd packer.nvim" +  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.cmd "packadd packer.nvim"    end    local packer_ok, packer = pcall(require, "packer") @@ -23,7 +20,7 @@ function plugin_loader:init()      git = { clone_timeout = 300 },      display = {        open_fn = function() -        return util.float { border = "single" } +        return util.float { border = "rounded" }        end,      },    } diff --git a/lua/plugins.lua b/lua/plugins.lua index 8e497075..8a0692f2 100644 --- a/lua/plugins.lua +++ b/lua/plugins.lua @@ -4,15 +4,13 @@ return {    { "neovim/nvim-lspconfig" },    { "tamago324/nlsp-settings.nvim" },    { "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 "lspinstall" +      local lspinstall = require "core.lspinstall"        lspinstall.setup() -      if lvim.builtin.lspinstall.on_config_done then -        lvim.builtin.lspinstall.on_config_done(lspinstall) -      end      end,    }, @@ -23,10 +21,8 @@ return {      "nvim-telescope/telescope.nvim",      config = function()        require("core.telescope").setup() -      if lvim.builtin.telescope.on_config_done then -        lvim.builtin.telescope.on_config_done(require "telescope") -      end      end, +    disable = not lvim.builtin.telescope.active,    },    -- Completion & Snippets @@ -35,10 +31,8 @@ return {      event = "InsertEnter",      config = function()        require("core.compe").setup() -      if lvim.builtin.compe.on_config_done then -        lvim.builtin.compe.on_config_done(require "compe") -      end      end, +    disable = not lvim.builtin.compe.active,      -- wants = "vim-vsnip",      -- requires = {      -- { @@ -56,10 +50,12 @@ return {      "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,    },    -- Autopairs @@ -68,11 +64,9 @@ return {      -- event = "InsertEnter",      after = "nvim-compe",      config = function() -      require "core.autopairs" -      if lvim.builtin.autopairs.on_config_done then -        lvim.builtin.autopairs.on_config_done(require "nvim-autopairs") -      end +      require("core.autopairs").setup()      end, +    disable = not lvim.builtin.autopairs.active or not lvim.builtin.compe.active,    },    -- Treesitter @@ -82,9 +76,6 @@ return {      -- run = ":TSUpdate",      config = function()        require("core.treesitter").setup() -      if lvim.builtin.treesitter.on_config_done then -        lvim.builtin.treesitter.on_config_done(require "nvim-treesitter.configs") -      end      end,    }, @@ -96,10 +87,8 @@ return {      -- commit = "fd7f60e242205ea9efc9649101c81a07d5f458bb",      config = function()        require("core.nvimtree").setup() -      if lvim.builtin.nvimtree.on_config_done then -        lvim.builtin.nvimtree.on_config_done(require "nvim-tree.config") -      end      end, +    disable = not lvim.builtin.nvimtree.active,    },    { @@ -107,11 +96,9 @@ return {      config = function()        require("core.gitsigns").setup() -      if lvim.builtin.gitsigns.on_config_done then -        lvim.builtin.gitsigns.on_config_done(require "gitsigns") -      end      end,      event = "BufRead", +    disable = not lvim.builtin.gitsigns.active,    },    -- Whichkey @@ -119,11 +106,9 @@ return {      "folke/which-key.nvim",      config = function()        require("core.which-key").setup() -      if lvim.builtin.which_key.on_config_done then -        lvim.builtin.which_key.on_config_done(require "which-key") -      end      end,      event = "BufWinEnter", +    disable = not lvim.builtin.which_key.active,    },    -- Comments @@ -131,30 +116,18 @@ return {      "terrortylor/nvim-comment",      event = "BufRead",      config = function() -      local status_ok, nvim_comment = pcall(require, "nvim_comment") -      if not status_ok then -        local Log = require "core.log" -        Log:get_default().error "Failed to load nvim-comment" -        return -      end -      nvim_comment.setup() -      if lvim.builtin.comment.on_config_done then -        lvim.builtin.comment.on_config_done(nvim_comment) -      end +      require("nvim_comment").setup()      end, +    disable = not lvim.builtin.comment.active,    }, -  -- vim-rooter +  -- project.nvim    { -    "airblade/vim-rooter", -    -- event = "BufReadPre", +    "ahmedkhalf/project.nvim",      config = function() -      require("core.rooter").setup() -      if lvim.builtin.rooter.on_config_done then -        lvim.builtin.rooter.on_config_done() -      end +      require("core.project").setup()      end, -    disable = not lvim.builtin.rooter.active, +    disable = not lvim.builtin.project.active,    },    -- Icons @@ -162,24 +135,19 @@ return {    -- Status Line and Bufferline    { -    "glepnir/galaxyline.nvim", +    -- "hoob3rt/lualine.nvim", +    "shadmansaleh/lualine.nvim", +    -- "Lunarvim/lualine.nvim",      config = function() -      require "core.galaxyline" -      if lvim.builtin.galaxyline.on_config_done then -        lvim.builtin.galaxyline.on_config_done(require "galaxyline") -      end +      require("core.lualine").setup()      end, -    event = "BufWinEnter", -    disable = not lvim.builtin.galaxyline.active, +    disable = not lvim.builtin.lualine.active,    },    {      "romgrk/barbar.nvim",      config = function()        require("core.bufferline").setup() -      if lvim.builtin.bufferline.on_config_done then -        lvim.builtin.bufferline.on_config_done() -      end      end,      event = "BufWinEnter",      disable = not lvim.builtin.bufferline.active, @@ -191,9 +159,6 @@ return {      -- event = "BufWinEnter",      config = function()        require("core.dap").setup() -      if lvim.builtin.dap.on_config_done then -        lvim.builtin.dap.on_config_done(require "dap") -      end      end,      disable = not lvim.builtin.dap.active,    }, @@ -212,9 +177,6 @@ return {      event = "BufWinEnter",      config = function()        require("core.dashboard").setup() -      if lvim.builtin.dashboard.on_config_done then -        lvim.builtin.dashboard.on_config_done(require "dashboard") -      end      end,      disable = not lvim.builtin.dashboard.active,    }, @@ -225,9 +187,6 @@ return {      event = "BufWinEnter",      config = function()        require("core.terminal").setup() -      if lvim.builtin.terminal.on_config_done then -        lvim.builtin.terminal.on_config_done(require "toggleterm") -      end      end,      disable = not lvim.builtin.terminal.active,    }, diff --git a/lua/utils/init.lua b/lua/utils/init.lua index 8264189d..8ea842ca 100644 --- a/lua/utils/init.lua +++ b/lua/utils/init.lua @@ -70,9 +70,7 @@ function utils.toggle_autoformat()          },        },      } -    if Log:get_default() then -      Log:get_default().info "Format on save active" -    end +    Log:debug "Format on save active"    end    if not lvim.format_on_save then @@ -81,15 +79,16 @@ function utils.toggle_autoformat()          :autocmd! autoformat        endif      ]] -    if Log:get_default() then -      Log:get_default().info "Format on save off" -    end +    Log:debug "Format on save off"    end  end  function utils.reload_lv_config() -  vim.cmd "source ~/.local/share/lunarvim/lvim/lua/settings.lua" -  vim.cmd("source " .. USER_CONFIG_PATH) +  require("core.lualine").config() + +  local config = require "config" +  config:load() +    require("keymappings").setup() -- this should be done before loading the plugins    vim.cmd "source ~/.local/share/lunarvim/lvim/lua/plugins.lua"    local plugins = require "plugins" @@ -99,55 +98,9 @@ function utils.reload_lv_config()    vim.cmd ":PackerCompile"    vim.cmd ":PackerInstall"    -- vim.cmd ":PackerClean" -  Log:get_default().info "Reloaded configuration" -end - -function utils.check_lsp_client_active(name) -  local clients = vim.lsp.get_active_clients() -  for _, client in pairs(clients) do -    if client.name == name then -      return true -    end -  end -  return false -end - -function utils.get_active_client_by_ft(filetype) -  local clients = vim.lsp.get_active_clients() -  for _, client in pairs(clients) do -    if client.name == lvim.lang[filetype].lsp.provider then -      return client -    end -  end -  return nil -end - --- TODO: consider porting this logic to null-ls instead -function utils.get_supported_linters_by_filetype(filetype) -  local null_ls = require "null-ls" -  local matches = {} -  for _, provider in pairs(null_ls.builtins.diagnostics) do -    if vim.tbl_contains(provider.filetypes, filetype) then -      local provider_name = provider.name - -      table.insert(matches, provider_name) -    end -  end - -  return matches -end - -function utils.get_supported_formatters_by_filetype(filetype) -  local null_ls = require "null-ls" -  local matches = {} -  for _, provider in pairs(null_ls.builtins.formatting) do -    if provider.filetypes and vim.tbl_contains(provider.filetypes, filetype) then -      -- table.insert(matches, { provider.name, ft }) -      table.insert(matches, provider.name) -    end -  end - -  return matches +  local null_ls = require "lsp.null-ls" +  null_ls.setup(vim.bo.filetype, { force_reload = true }) +  Log:info "Reloaded configuration"  end  function utils.unrequire(m) diff --git a/utils/bin/install-latest-neovim b/utils/bin/install-latest-neovim deleted file mode 100755 index 8d1d95fd..00000000 --- a/utils/bin/install-latest-neovim +++ /dev/null @@ -1,9 +0,0 @@ -!#/bin/bash -cd ~ -sudo rm -r neovim -git clone --branch master --depth 1 https://github.com/neovim/neovim -cd neovim -sudo make CMAKE_BUILD_TYPE=Release install -cd ~ -sudo rm -r neovim - diff --git a/utils/bin/lvim b/utils/bin/lvim index b94d544f..2303be3c 100755..100644 --- a/utils/bin/lvim +++ b/utils/bin/lvim @@ -1,3 +1,6 @@  #!/bin/sh -exec nvim -u ~/.local/share/lunarvim/lvim/init.lua --cmd "set runtimepath+=~/.local/share/lunarvim/lvim" "$@" +export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-$HOME/.local/share/lunarvim}" +export LUNARVIM_CONFIG_DIR="${LUNARVIM_RUNTIME_DIR:-$HOME/.config/lvim}" + +exec nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" "$@" diff --git a/utils/installer/config.example-no-ts.lua b/utils/installer/config.example-no-ts.lua index 4303d264..aad13fe0 100644 --- a/utils/installer/config.example-no-ts.lua +++ b/utils/installer/config.example-no-ts.lua @@ -14,8 +14,21 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"  -- edit a default keymapping  -- lvim.keys.normal_mode["<C-q>"] = ":q<cr>" +-- Change Telescope navigation to use j and k for navigation and n and p for history in both input and normal mode. +-- lvim.builtin.telescope.on_config_done = function() +--   local actions = require "telescope.actions" +--   -- for input mode +--   lvim.builtin.telescope.defaults.mappings.i["<C-j>"] = actions.move_selection_next +--   lvim.builtin.telescope.defaults.mappings.i["<C-k>"] = actions.move_selection_previous +--   lvim.builtin.telescope.defaults.mappings.i["<C-n>"] = actions.cycle_history_next +--   lvim.builtin.telescope.defaults.mappings.i["<C-p>"] = actions.cycle_history_prev +--   -- for normal mode +--   lvim.builtin.telescope.defaults.mappings.n["<C-j>"] = actions.move_selection_next +--   lvim.builtin.telescope.defaults.mappings.n["<C-k>"] = actions.move_selection_previous +-- end +  -- Use which-key to add extra bindings with the leader-key prefix --- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<CR>", "Projects" } +-- 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" }, @@ -48,6 +61,21 @@ lvim.builtin.treesitter.highlight.enabled = true  --   --Enable completion triggered by <c-x><c-o>  --   buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")  -- end +-- you can overwrite the null_ls setup table (useful for setting the root_dir function) +-- lvim.lsp.null_ls.setup = { +--   root_dir = require("lspconfig").util.root_pattern("Makefile", ".git", "node_modules"), +-- } +-- or if you need something more advanced +-- lvim.lsp.null_ls.setup.root_dir = function(fname) +--   if vim.bo.filetype == "javascript" then +--     return require("lspconfig/util").root_pattern("Makefile", ".git", "node_modules")(fname) +--       or require("lspconfig/util").path.dirname(fname) +--   elseif vim.bo.filetype == "php" then +--     return require("lspconfig/util").root_pattern("Makefile", ".git", "composer.json")(fname) or vim.fn.getcwd() +--   else +--     return require("lspconfig/util").root_pattern("Makefile", ".git")(fname) or require("lspconfig/util").path.dirname(fname) +--   end +-- end  -- set a formatter if you want to override the default lsp one (if it exists)  -- lvim.lang.python.formatters = { diff --git a/utils/installer/config.example.lua b/utils/installer/config.example.lua index 0aee0275..c2c75fbb 100644 --- a/utils/installer/config.example.lua +++ b/utils/installer/config.example.lua @@ -23,8 +23,21 @@ lvim.keys.normal_mode["<C-s>"] = ":w<cr>"  -- edit a default keymapping  -- lvim.keys.normal_mode["<C-q>"] = ":q<cr>" +-- Change Telescope navigation to use j and k for navigation and n and p for history in both input and normal mode. +-- lvim.builtin.telescope.on_config_done = function() +--   local actions = require "telescope.actions" +--   -- for input mode +--   lvim.builtin.telescope.defaults.mappings.i["<C-j>"] = actions.move_selection_next +--   lvim.builtin.telescope.defaults.mappings.i["<C-k>"] = actions.move_selection_previous +--   lvim.builtin.telescope.defaults.mappings.i["<C-n>"] = actions.cycle_history_next +--   lvim.builtin.telescope.defaults.mappings.i["<C-p>"] = actions.cycle_history_prev +--   -- for normal mode +--   lvim.builtin.telescope.defaults.mappings.n["<C-j>"] = actions.move_selection_next +--   lvim.builtin.telescope.defaults.mappings.n["<C-k>"] = actions.move_selection_previous +-- end +  -- Use which-key to add extra bindings with the leader-key prefix --- lvim.builtin.which_key.mappings["P"] = { "<cmd>lua require'telescope'.extensions.project.project{}<CR>", "Projects" } +-- 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" }, @@ -57,6 +70,21 @@ lvim.builtin.treesitter.highlight.enabled = true  --   --Enable completion triggered by <c-x><c-o>  --   buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")  -- end +-- you can overwrite the null_ls setup table (useful for setting the root_dir function) +-- lvim.lsp.null_ls.setup = { +--   root_dir = require("lspconfig").util.root_pattern("Makefile", ".git", "node_modules"), +-- } +-- or if you need something more advanced +-- lvim.lsp.null_ls.setup.root_dir = function(fname) +--   if vim.bo.filetype == "javascript" then +--     return require("lspconfig/util").root_pattern("Makefile", ".git", "node_modules")(fname) +--       or require("lspconfig/util").path.dirname(fname) +--   elseif vim.bo.filetype == "php" then +--     return require("lspconfig/util").root_pattern("Makefile", ".git", "composer.json")(fname) or vim.fn.getcwd() +--   else +--     return require("lspconfig/util").root_pattern("Makefile", ".git")(fname) or require("lspconfig/util").path.dirname(fname) +--   end +-- end  -- set a formatter if you want to override the default lsp one (if it exists)  -- lvim.lang.python.formatters = { diff --git a/utils/installer/install-neovim-from-release b/utils/installer/install-neovim-from-release new file mode 100755 index 00000000..a2ba0513 --- /dev/null +++ b/utils/installer/install-neovim-from-release @@ -0,0 +1,83 @@ +#!/usr/bin/env bash + +set -eu pipefall + +declare -r LV_INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}" +declare -r RELEASE_VER="${RELEASE_VER:-latest}" # can be set to nightly + +declare ARCHIVE_NAME +declare RELEASE_NAME +declare OS + +OS="$(uname -s)" + +if [ "$OS" == "Linux" ]; then +  ARCHIVE_NAME="nvim-linux64" +  RELEASE_NAME="nvim-linux64" +elif [ "$OS" == "Darwin" ]; then +  ARCHIVE_NAME="nvim-macos" +  # for some reason the archive has a different name +  RELEASE_NAME="nvim-osx64" +else +  echo "$OS platform is not supported currently" +  exit 1 +fi + +declare -r RELEASE_URL="https://github.com/neovim/neovim/releases/$RELEASE_VER/download/$ARCHIVE_NAME.tar.gz" +declare -r CHECKSUM_URL="$RELEASE_URL.sha256sum" + +DOWNLOAD_DIR="$(mktemp -d)" +readonly DOWNLOAD_DIR + +RELEASE_SHA="$(curl -Ls "$CHECKSUM_URL" | awk '{print $1}')" +readonly RELEASE_SHA + +function main() { +  if [ ! -d "$LV_INSTALL_PREFIX" ]; then +    mkdir -p "$LV_INSTALL_PREFIX" || __invalid__prefix__handler +  fi +  download_neovim +  verify_neovim +  install_neovim +} + +function download_neovim() { +  echo "Downloading Neovim's binary from $RELEASE_VER release.." +  if ! curl --progress-bar --fail -L "$RELEASE_URL" -o "$DOWNLOAD_DIR/$ARCHIVE_NAME.tar.gz"; then +    echo "Download failed.  Check that the release/filename are correct." +    exit 1 +  fi +  echo "Download complete!" +} + +function verify_neovim() { +  echo "Verifying the installation.." +  DOWNLOADED_SHA="$(sha256sum "$DOWNLOAD_DIR/$ARCHIVE_NAME.tar.gz" | awk '{print $1}')" + +  if [ "$RELEASE_SHA" != "$DOWNLOADED_SHA" ]; then +    echo "Error! checksum mis-match." +    echo "Expected: $RELEASE_SHA but got: $DOWNLOADED_SHA" +    exit 1 +  fi +  echo "Verification complete!" +} + +function install_neovim() { + +  echo "Installing Neovim.." +  pushd "$DOWNLOAD_DIR" +  tar -xzf "$DOWNLOAD_DIR/$ARCHIVE_NAME.tar.gz" +  popd +  # https://dev.to/ackshaey/macos-vs-linux-the-cp-command-will-trip-you-up-2p00 +  cp -r "$DOWNLOAD_DIR/$RELEASE_NAME/." "$LV_INSTALL_PREFIX" +  echo "Installation complete!" +  echo "Now you can run $LV_INSTALL_PREFIX/bin/nvim" +} + +function __invalid__prefix__handler() { +  echo "Error! Invalid value for LV_INSTALL_PREFIX: [$INSTALL_PREFIX]" +  echo "Please verify that the folder exists and re-run the installer!" +  exit 1 +} + +main "$@" diff --git a/utils/installer/install.sh b/utils/installer/install.sh index 25b67f12..9e198274 100755 --- a/utils/installer/install.sh +++ b/utils/installer/install.sh @@ -1,272 +1,289 @@ -#!/bin/sh -#Set Variable to master is not set differently -LVBRANCH="${LVBRANCH:-master}" -USER_BIN_DIR="/usr/local/bin" -set -o nounset # error when referencing undefined variable -set -o errexit # exit when command fails - -installnodemac() { -	brew install lua -	brew install node -	brew install yarn -} +#!/usr/bin/env bash +set -eo pipefail -installnodeubuntu() { -	sudo apt install nodejs -	sudo apt install npm -} +#Set branch to master unless specified by the user +declare -r LV_BRANCH="${LV_BRANCH:-rolling}" +declare -r LV_REMOTE="${LV_REMOTE:-lunarvim/lunarvim.git}" +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"}" -installnodetermux() { -	apt install nodejs -} +# TODO: Use a dedicated cache directory #1256 +declare -r NEOVIM_CACHE_DIR="$XDG_CACHE_HOME/nvim" -moveoldlvim() { -	echo "Not installing LunarVim" -	echo "Please move your ~/.local/share/lunarvim folder before installing" -	exit -} +declare -r LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}" +declare -r LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}" -installnodearch() { -	sudo pacman -S nodejs -	sudo pacman -S npm -} +declare -a __lvim_dirs=( +  "$LUNARVIM_CONFIG_DIR" +  "$LUNARVIM_RUNTIME_DIR" +  "$NEOVIM_CACHE_DIR" # for now this is shared with neovim +) + +declare -a __npm_deps=( +  "neovim" +  "tree-sitter-cli" +) + +declare -a __pip_deps=( +  "pynvim" +) + +function main() { +  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 + +  __add_separator "80" + +  echo "Detecting platform for managing any additional neovim dependencies" +  detect_platform + +  if [ -n "$GITHUB_ACTIONS" ]; then +    install_packer +    setup_lvim +    exit 0 +  fi + +  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 + +  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 + +  __add_separator "80" + +  echo "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 +  fi + +  __add_separator "80" + +  if [ -e "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" ]; then +    echo "Updating LunarVim" +    update_lvim +  else +    clone_lvim +    setup_lvim +  fi + +  __add_separator "80" -installnodefedora() { -	sudo dnf install -y nodejs -	sudo dnf install -y npm  } -installnodegentoo() { -	echo "Printing current node status..." -	emerge -pqv net-libs/nodejs -	echo "Make sure the npm USE flag is enabled for net-libs/nodejs" -	echo "If it isn't enabled, would you like to enable it with flaggie? (Y/N)" -	read -r answer -	[ "$answer" != "${answer#[Yy]}" ] && sudo flaggie net-libs/nodejs +npm -	sudo emerge -avnN net-libs/nodejs +function detect_platform() { +  OS="$(uname -s)" +  case "$OS" in +    Linux) +      if [ -f "/etc/arch-release" ] || [ -f "/etc/artix-release" ]; then +        RECOMMEND_INSTALL="sudo pacman -S" +      elif [ -f "/etc/fedora-release" ] || [ -f "/etc/redhat-release" ]; then +        RECOMMEND_INSTALL="sudo dnf install -y" +      elif [ -f "/etc/gentoo-release" ]; then +        RECOMMEND_INSTALL="emerge install -y" +      else # assume debian based +        RECOMMEND_INSTALL="sudo apt install -y" +      fi +      ;; +    Darwin) +      RECOMMEND_INSTALL="brew install" +      ;; +    *) +      echo "OS $OS is not currently supported." +      exit 1 +      ;; +  esac  } -installnode() { -	echo "Installing node..." -	[ "$(uname)" = "Darwin" ] && installnodemac -	grep -q Ubuntu /etc/os-release && installnodeubuntu -	[ -f "/etc/arch-release" ] && installnodearch -	[ -f "/etc/artix-release" ] && installnodearch -	[ -f "/etc/fedora-release" ] && installnodefedora -	[ -f "/etc/gentoo-release" ] && installnodegentoo -	[ -d "/data/data/com.termux" ] && installnodetermux -	[ "$(uname -s | cut -c 1-10)" = "MINGW64_NT" ] && echo "Windows not currently supported" -	sudo npm i -g neovim +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"  } -installpiponmac() { -	sudo curl https://bootstrap.pypa.io/get-pip.py -o get-pip.py -	python3 get-pip.py -	rm get-pip.py +function check_dep() { +  if ! command -v "$1" &>/dev/null; then +    print_missing_dep_msg "$1" +    exit 1 +  fi  } -installpiponubuntu() { -	sudo apt install python3-pip >/dev/null +function check_system_deps() { +  if ! command -v git &>/dev/null; then +    print_missing_dep_msg "git" +    exit 1 +  fi +  if ! command -v nvim &>/dev/null; then +    print_missing_dep_msg "neovim" +    exit 1 +  fi  } -installpipontermux() { -	apt install python +function install_nodejs_deps() { +  check_dep "npm" +  echo "Installing node modules with npm.." +  for dep in "${__npm_deps[@]}"; do +    if ! npm ls -g "$dep" &>/dev/null; then +      printf "installing %s .." "$dep" +      npm install -g "$dep" +    fi +  done +  echo "All NodeJS dependencies are succesfully installed"  } -installpiponarch() { -	sudo pacman -S python-pip +function install_python_deps() { +  echo "Verifying that pip is available.." +  if ! python3 -m ensurepip &>/dev/null; then +    if ! python3 -m pip --version &>/dev/null; then +      print_missing_dep_msg "pip" +      exit 1 +    fi +  fi +  echo "Installing with pip.." +  for dep in "${__pip_deps[@]}"; do +    python3 -m pip install --user "$dep" +  done +  echo "All Python dependencies are succesfully installed"  } -installpiponfedora() { -	sudo dnf install -y pip >/dev/null +function __attempt_to_install_with_cargo() { +  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" +  fi  } -installpipongentoo() { -	sudo emerge -avn dev-python/pip +# 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"  } -installpip() { -	echo "Installing pip..." -	[ "$(uname)" = "Darwin" ] && installpiponmac -	grep -q Ubuntu /etc/os-release && installpiponubuntu -	[ -f "/etc/arch-release" ] && installpiponarch -	[ -f "/etc/fedora-release" ] && installpiponfedora -	[ -f "/etc/gentoo-release" ] && installpipongentoo -	[ -d "/data/data/com.termux" ] && installpipontermux -	[ "$(uname -s | cut -c 1-10)" = "MINGW64_NT" ] && echo "Windows not currently supported" +function backup_old_config() { +  for dir in "${__lvim_dirs[@]}"; do +    # we create an empty folder for subsequent commands \ +    # that require an existing directory +    mkdir -p "$dir" "$dir.bak" +    if command -v rsync &>/dev/null; then +      rsync --archive -hh --partial --progress --cvs-exclude \ +        --modify-window=1 "$dir"/ "$dir.bak" +    else +      cp -R "$dir/*" "$dir.bak/." +    fi +  done +  echo "Backup operation complete"  } -installpynvim() { -	echo "Installing pynvim..." -	if [ -f "/etc/gentoo-release" ]; then -		echo "Installing using Portage" -		sudo emerge -avn dev-python/pynvim -	else -		pip3 install pynvim --user -	fi +function install_packer() { +  git clone --depth 1 https://github.com/wbthomason/packer.nvim \ +    "$LUNARVIM_RUNTIME_DIR/site/pack/packer/start/packer.nvim"  } -installpacker() { -	git clone https://github.com/wbthomason/packer.nvim ~/.local/share/lunarvim/site/pack/packer/start/packer.nvim +function clone_lvim() { +  echo "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." +    exit 1 +  fi  } -cloneconfig() { -	if [ -d "/data/data/com.termux" ]; then -		sudo() { -			eval "$@" -		} -		USER_BIN_DIR="$HOME/../usr/bin" -	fi -	echo "Cloning LunarVim configuration" -	mkdir -p ~/.local/share/lunarvim -	case "$@" in - -	*--testing*) -		cp -r "$(pwd)" ~/.local/share/lunarvim/lvim -		;; -	*) -		git clone --branch "$LVBRANCH" https://github.com/lunarvim/lunarvim.git ~/.local/share/lunarvim/lvim -		;; -	esac -	mkdir -p "$HOME/.config/lvim" -	sudo cp "$HOME/.local/share/lunarvim/lvim/utils/bin/lvim" "$USER_BIN_DIR" -	sudo chmod a+rx "$USER_BIN_DIR"/lvim -	cp "$HOME/.local/share/lunarvim/lvim/utils/installer/config.example-no-ts.lua" "$HOME/.config/lvim/config.lua" - -	nvim -u ~/.local/share/lunarvim/lvim/init.lua --cmd "set runtimepath+=~/.local/share/lunarvim/lvim" --headless \ -		+'autocmd User PackerComplete sleep 100m | qall' \ -		+PackerInstall - -	nvim -u ~/.local/share/lunarvim/lvim/init.lua --cmd "set runtimepath+=~/.local/share/lunarvim/lvim" --headless \ -		+'autocmd User PackerComplete sleep 100m | qall' \ -		+PackerSync - -	printf "\nCompile Complete\n" - -	if [ -e "$HOME/.local/share/lunarvim/lvim/init.lua" ]; then -		echo 'config.lua already present' -	else -		cp "$HOME/.local/share/lunarvim/lvim/utils/installer/config.example.lua" "$HOME/.config/lvim/config.lua" -	fi +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}" -asktoinstallnode() { -	echo "node not found" -	printf "Would you like to install node now (y/n)? " -	read -r answer -	[ "$answer" != "${answer#[Yy]}" ] && installnode +exec nvim -u "\$LUNARVIM_RUNTIME_DIR/lvim/init.lua" "\$@" +EOF +  chmod +x "$INSTALL_PREFIX/bin/lvim"  } -asktoinstallgit() { -	echo "git not found, please install git" -	exit -} +function setup_lvim() { +  echo "Installing LunarVim shim" -asktoinstallpip() { -	# echo "pip not found" -	# echo -n "Would you like to install pip now (y/n)? " -	# read answer -	# [ "$answer" != "${answer#[Yy]}" ] && installpip -	echo "Please install pip3 before continuing with install" -	exit -} +  setup_shim -installonmac() { -	brew install ripgrep fzf -	npm install -g tree-sitter-cli -} +  echo "Preparing Packer setup" -installonubuntu() { -	sudo apt install ripgrep fzf -	sudo apt install libjpeg8-dev zlib1g-dev python-dev python3-dev libxtst-dev -	pip3 install neovim-remote -	npm install -g tree-sitter-cli -} +  cp "$LUNARVIM_RUNTIME_DIR/lvim/utils/installer/config.example-no-ts.lua" \ +    "$LUNARVIM_CONFIG_DIR/config.lua" -installtermux() { -	apt install ripgrep fzf -	pip install neovim-remote -	npm install -g tree-sitter-cli -} +  nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" --headless \ +    -c 'autocmd User PackerComplete quitall' \ +    -c 'PackerSync' -installonarch() { -	sudo pacman -S ripgrep fzf -	pip3 install neovim-remote -	npm install -g tree-sitter-cli -} +  echo "Packer setup complete" + +  cp "$LUNARVIM_RUNTIME_DIR/lvim/utils/installer/config.example.lua" "$LUNARVIM_CONFIG_DIR/config.lua" -installonfedora() { -	sudo dnf groupinstall "X Software Development" -	sudo dnf install -y fzf ripgrep +  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]"  } -installongentoo() { -	sudo emerge -avn sys-apps/ripgrep app-shells/fzf dev-python/neovim-remote virtual/jpeg sys-libs/zlib -	npm install -g tree-sitter-cli +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!"  } -installextrapackages() { -	[ "$(uname)" = "Darwin" ] && installonmac -	grep -q Ubuntu /etc/os-release && installonubuntu -	[ -f "/etc/arch-release" ] && installonarch -	[ -f "/etc/artix-release" ] && installonarch -	[ -f "/etc/fedora-release" ] && installonfedora -	[ -f "/etc/gentoo-release" ] && installongentoo -	[ -d "/data/data/com.termux" ] && installtermux -	[ "$(uname -s | cut -c 1-10)" = "MINGW64_NT" ] && echo "Windows not currently supported" +function __add_separator() { +  local DIV_WIDTH="$1" +  printf "%${DIV_WIDTH}s\n" ' ' | tr ' ' -  } -# Welcome -echo 'Installing LunarVim' - -case "$@" in -*--overwrite*) -	echo '!!Warning!! -> Removing all lunarvim related config because of the --overwrite flag' -	rm -rf "$HOME/.local/share/lunarvim" -	rm -rf "$HOME/.cache/nvim" -	rm -rf "$HOME/.config/lvim" -	;; -esac - -# move old lvim directory if it exists -[ -d "$HOME/.local/share/lunarvim" ] && moveoldlvim - -# install node and neovim support -(command -v git >/dev/null && echo "git installed, moving on...") || asktoinstallgit - -# install pip -(command -v pip3 >/dev/null && echo "pip installed, moving on...") || asktoinstallpip - -# install node and neovim support -(command -v node >/dev/null && echo "node installed, moving on...") || asktoinstallnode - -# install pynvim -(pip3 list | grep pynvim >/dev/null && echo "pynvim installed, moving on...") || installpynvim - -if [ -e "$HOME/.local/share/lunarvim/site/pack/packer/start/packer.nvim" ]; then -	echo 'packer already installed' -else -	installpacker -fi - -if [ -e "$HOME/.local/share/lunarvim/lvim/init.lua" ]; then -	echo 'LunarVim already installed' -else -	# clone config down -	cloneconfig "$@" -	# echo 'export PATH=$HOME/.config/nvim/utils/bin:$PATH' >>~/.zshrc -	# echo 'export PATH=$HOME/.config/lunarvim/utils/bin:$PATH' >>~/.bashrc -fi - -if [ "$(uname)" != "Darwin" ]; then -	if [ -e "$HOME/.local/share/applications/lvim.desktop" ]; then -		echo 'Desktop file already available' -	else -		mkdir -p "$HOME/.local/share/applications" -		cp "$HOME/.local/share/lunarvim/lvim/utils/desktop/lvim.desktop" "$HOME/.local/share/applications/lvim.desktop" -	fi -fi - -echo "I recommend you also install and activate a font from here: https://github.com/ryanoasis/nerd-fonts" -# echo 'export PATH=/home/$USER/.config/lunarvim/utils/bin:$PATH appending to zshrc/bashrc' +main "$@" diff --git a/utils/installer/install_stylua.sh b/utils/installer/install_stylua.sh index 2a33de7e..963416ea 100755 --- a/utils/installer/install_stylua.sh +++ b/utils/installer/install_stylua.sh @@ -11,53 +11,53 @@ declare -r FILENAME="stylua-$RELEASE-$OS"  declare -a __deps=("curl" "unzip")  function check_deps() { -	for dep in "${__deps[@]}"; do -		if ! command -v "$dep" >/dev/null; then -			echo "Missing depdendecy!" -			echo "The \"$dep\" command was not found!. Please install and try again." -		fi -	done +  for dep in "${__deps[@]}"; do +    if ! command -v "$dep" >/dev/null; then +      echo "Missing depdendecy!" +      echo "The \"$dep\" command was not found!. Please install and try again." +    fi +  done  }  function download_stylua() { -	local DOWNLOAD_DIR -	local URL="https://github.com/JohnnyMorganz/StyLua/releases/download/v$RELEASE/$FILENAME.zip" - -	DOWNLOAD_DIR="$(mktemp -d)" -	echo "Initiating download for Stylua v$RELEASE" -	if ! curl --progress-bar --fail -L "$URL" -o "$DOWNLOAD_DIR/$FILENAME.zip"; then -		echo "Download failed.  Check that the release/filename are correct." -		exit 1 -	fi - -	echo "Installation in progress.." -	unzip -q "$DOWNLOAD_DIR/$FILENAME.zip" -d "$DOWNLOAD_DIR" - -	if [ -f "$DOWNLOAD_DIR/stylua" ]; then -		mv "$DOWNLOAD_DIR/stylua" "$INSTALL_DIR/stylua" -	else -		mv "$DOWNLOAD_DIR/$FILENAME/stylua" "$INSTALL_DIR/." -	fi - -	chmod u+x "$INSTALL_DIR/stylua" +  local DOWNLOAD_DIR +  local URL="https://github.com/JohnnyMorganz/StyLua/releases/download/v$RELEASE/$FILENAME.zip" + +  DOWNLOAD_DIR="$(mktemp -d)" +  echo "Initiating download for Stylua v$RELEASE" +  if ! curl --progress-bar --fail -L "$URL" -o "$DOWNLOAD_DIR/$FILENAME.zip"; then +    echo "Download failed.  Check that the release/filename are correct." +    exit 1 +  fi + +  echo "Installation in progress.." +  unzip -q "$DOWNLOAD_DIR/$FILENAME.zip" -d "$DOWNLOAD_DIR" + +  if [ -f "$DOWNLOAD_DIR/stylua" ]; then +    mv "$DOWNLOAD_DIR/stylua" "$INSTALL_DIR/stylua" +  else +    mv "$DOWNLOAD_DIR/$FILENAME/stylua" "$INSTALL_DIR/." +  fi + +  chmod u+x "$INSTALL_DIR/stylua"  }  function verify_install() { -	echo "Verifying installation.." -	local DOWNLOADED_VER -	DOWNLOADED_VER="$("$INSTALL_DIR/stylua" -V | awk '{ print $2 }')" -	if [ "$DOWNLOADED_VER" != "$RELEASE" ]; then -		echo "Mismatched version!" -		echo "Expected: v$RELEASE but got v$DOWNLOADED_VER" -		exit 1 -	fi -	echo "Verification complete!" +  echo "Verifying installation.." +  local DOWNLOADED_VER +  DOWNLOADED_VER="$("$INSTALL_DIR/stylua" -V | awk '{ print $2 }')" +  if [ "$DOWNLOADED_VER" != "$RELEASE" ]; then +    echo "Mismatched version!" +    echo "Expected: v$RELEASE but got v$DOWNLOADED_VER" +    exit 1 +  fi +  echo "Verification complete!"  }  function main() { -	check_deps -	download_stylua -	verify_install +  check_deps +  download_stylua +  verify_install  }  main "$@" diff --git a/utils/installer/uninstall.sh b/utils/installer/uninstall.sh index b9a27252..8d9d039a 100755 --- a/utils/installer/uninstall.sh +++ b/utils/installer/uninstall.sh @@ -1,10 +1,10 @@  #!/bin/sh  USER_BIN_DIR="/usr/local/bin"  if [ -d "/data/data/com.termux" ]; then -	sudo() { -		eval "$@" -	} -	USER_BIN_DIR="$HOME/../usr/bin" +  sudo() { +    eval "$@" +  } +  USER_BIN_DIR="$HOME/../usr/bin"  fi  rm -rf ~/.local/share/lunarvim  sudo rm "$USER_BIN_DIR"/lvim | 
