trying to fix embedded git
This commit is contained in:
parent
15f8b52459
commit
dcb2009f4c
|
@ -0,0 +1,32 @@
|
|||
plugin/
|
||||
dein
|
||||
tags*
|
||||
.netrwhist
|
||||
pythonpath.vim
|
||||
nodepath.vim
|
||||
autoload/plugged/*
|
||||
vimspector-config/gadgets/*
|
||||
paths.vim
|
||||
session
|
||||
wiki/
|
||||
pack/
|
||||
utils/java/*
|
||||
lv-config.lua
|
||||
lua-language-server/
|
||||
eclipse.jdt.ls/
|
||||
.language-servers/
|
||||
.debuggers/
|
||||
spell/
|
||||
nv-settings.lua
|
||||
lv-settings.lua
|
||||
lua/lv-user/
|
||||
lua/lv-user-config/
|
||||
|
||||
*.tmp
|
||||
*.temp
|
||||
*.bak
|
||||
*.backup
|
||||
*.old
|
||||
|
||||
.luarc.json
|
||||
.luacheckcache
|
|
@ -0,0 +1,42 @@
|
|||
-- vim: ft=lua tw=80
|
||||
|
||||
stds.nvim = {
|
||||
globals = {
|
||||
"lvim",
|
||||
vim = { fields = { "g" } },
|
||||
"TERMINAL",
|
||||
"USER",
|
||||
"C",
|
||||
"Config",
|
||||
"WORKSPACE_PATH",
|
||||
"JAVA_LS_EXECUTABLE",
|
||||
"MUtils",
|
||||
"USER_CONFIG_PATH",
|
||||
os = { fields = { "capture" } },
|
||||
},
|
||||
read_globals = {
|
||||
"jit",
|
||||
"os",
|
||||
"vim",
|
||||
"join_paths",
|
||||
"get_runtime_dir",
|
||||
"get_config_dir",
|
||||
"get_cache_dir",
|
||||
"get_lvim_base_dir",
|
||||
"require_clean",
|
||||
},
|
||||
}
|
||||
std = "lua51+nvim"
|
||||
|
||||
files["tests/*_spec.lua"].std = "lua51+nvim+busted"
|
||||
|
||||
-- Don't report unused self arguments of methods.
|
||||
self = false
|
||||
|
||||
-- Rerun tests only if their modification time changed.
|
||||
cache = true
|
||||
|
||||
ignore = {
|
||||
"631", -- max_line_length
|
||||
"212/_.*", -- unused argument, for vars with "_" prefix
|
||||
}
|
|
@ -0,0 +1,34 @@
|
|||
repos:
|
||||
- repo: local
|
||||
hooks:
|
||||
- id: shfmt
|
||||
name: shfmt
|
||||
minimum_pre_commit_version: 2.4.0
|
||||
language: system
|
||||
types: [shell]
|
||||
entry: bash
|
||||
args: [-c, make lint-sh]
|
||||
- id: shellcheck
|
||||
name: shellcheck
|
||||
language: system
|
||||
types: [shell]
|
||||
entry: bash
|
||||
args: [-c, make style-sh]
|
||||
- id: stylua
|
||||
name: StyLua
|
||||
language: rust
|
||||
entry: stylua
|
||||
types: [lua]
|
||||
args: ["-"]
|
||||
- id: luacheck
|
||||
name: luacheck
|
||||
language: system
|
||||
entry: luacheck
|
||||
types: [lua]
|
||||
args: [.]
|
||||
- id: commitlint
|
||||
name: commitlint
|
||||
language: system
|
||||
entry: bash
|
||||
args: [./utils/ci/run_commitlint.sh]
|
||||
stages: [commit-msg]
|
|
@ -0,0 +1,6 @@
|
|||
column_width = 120
|
||||
line_endings = "Unix"
|
||||
indent_type = "Spaces"
|
||||
indent_width = 2
|
||||
quote_style = "AutoPreferDouble"
|
||||
no_call_parentheses = true
|
|
@ -0,0 +1,283 @@
|
|||
# Changelog
|
||||
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [unreleased]
|
||||
|
||||
### <!-- 1 --> Features
|
||||
|
||||
- _(cmp)_ documentation is deprecated in favor of window.documentation ([#2461](https://github.com/lunarvim/lunarvim/pull/2461))
|
||||
- _(cmp)_ add option to disable friendly-snippets ([#2660](https://github.com/lunarvim/lunarvim/pull/2660))
|
||||
- _(codelens)_ cursorhold is too much intrusive for codelens ([#2600](https://github.com/lunarvim/lunarvim/pull/2600))
|
||||
- _(icons)_ make it possible to disable icons ([#2529](https://github.com/lunarvim/lunarvim/pull/2529))
|
||||
- _(installer)_ ensure correct responses when prompting user ([#2506](https://github.com/lunarvim/lunarvim/pull/2506))
|
||||
- _(installer)_ add verify-plugins hook ([#2751](https://github.com/lunarvim/lunarvim/pull/2751))
|
||||
- _(lua-dev)_ use the newer lua-dev branch till folke comes back ([#2538](https://github.com/lunarvim/lunarvim/pull/2538))
|
||||
- _(neovim)_ neovim 0.8 compatibility ([#2544](https://github.com/lunarvim/lunarvim/pull/2544))
|
||||
- _(peek)_ make sure max width and height are customizable ([#2492](https://github.com/lunarvim/lunarvim/pull/2492))
|
||||
- _(plugins)_ add support for packer snapshots ([#2351](https://github.com/lunarvim/lunarvim/pull/2351))
|
||||
- _(quit)_ make sure to ask before discarding changes ([#2554](https://github.com/lunarvim/lunarvim/pull/2554))
|
||||
- _(which-key)_ added search command for colour highlights ([#2693](https://github.com/lunarvim/lunarvim/pull/2693))
|
||||
- lock nvim <0.7 to a specific tag ([#2491](https://github.com/lunarvim/lunarvim/pull/2491))
|
||||
- gitsigns yadm support ([#2535](https://github.com/lunarvim/lunarvim/pull/2535))
|
||||
- add cmp-tmux to the list of sources ([#2542](https://github.com/lunarvim/lunarvim/pull/2542))
|
||||
- prompt when closing modified/term buffers ([#2658](https://github.com/lunarvim/lunarvim/pull/2658))
|
||||
- fix a couple of issues ([#2750](https://github.com/lunarvim/lunarvim/pull/2750))
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- _(autocmd)_ actually use the format wrapper ([#2560](https://github.com/lunarvim/lunarvim/pull/2560))
|
||||
- _(autocmds)_ make sure we are using codelens correctly ([#2576](https://github.com/lunarvim/lunarvim/pull/2576))
|
||||
- _(autocmds)_ disable commentstring_calc on cursor-hold ([#2581](https://github.com/lunarvim/lunarvim/pull/2581))
|
||||
- _(autocmds)_ toggle format-on-save properly ([#2659](https://github.com/lunarvim/lunarvim/pull/2659))
|
||||
- _(cmp)_ update nvim-cmp to the latest version ([#2467](https://github.com/lunarvim/lunarvim/pull/2467))
|
||||
- _(cmp)_ hotfix nvim-cmp version
|
||||
- _(cmp)_ bring back default keybindings ([#2470](https://github.com/lunarvim/lunarvim/pull/2470))
|
||||
- _(cmp)_ update nvim-cmp to the latest version ([#2467](https://github.com/lunarvim/lunarvim/pull/2467)) ([#2469](https://github.com/lunarvim/lunarvim/pull/2469))
|
||||
- _(dap)_ temporarily use dap-buddy dev branch which has older code ([#2567](https://github.com/lunarvim/lunarvim/pull/2567))
|
||||
- _(dap)_ pause key binding commmand ([#2573](https://github.com/lunarvim/lunarvim/pull/2573))
|
||||
- _(impatient)_ avoid get_options in fast handler ([#2451](https://github.com/lunarvim/lunarvim/pull/2451))
|
||||
- _(installer)_ latest and specified release version for neovim have different urls ([#2484](https://github.com/lunarvim/lunarvim/pull/2484))
|
||||
- _(installer/pwsh)_ fixes some details on installer and uninstaller ([#2404](https://github.com/lunarvim/lunarvim/pull/2404))
|
||||
- _(log)_ add date to the timestamp of logs ([#2669](https://github.com/lunarvim/lunarvim/pull/2669))
|
||||
- _(lsp)_ undo stdpath overload to avoid datarace ([#2540](https://github.com/lunarvim/lunarvim/pull/2540))
|
||||
- _(lualine)_ color theme gaps in some components ([#2465](https://github.com/lunarvim/lunarvim/pull/2465))
|
||||
- _(lualine)_ unique buf client names ([#2683](https://github.com/lunarvim/lunarvim/pull/2683))
|
||||
- _(luasnip)_ make sure all snippets are loaded ([#2447](https://github.com/lunarvim/lunarvim/pull/2447))
|
||||
- _(luasnip)_ only use user snippets if the folder exists ([#2481](https://github.com/lunarvim/lunarvim/pull/2481))
|
||||
- _(nvimtree)_ escape the dot character in custom filter ([#2493](https://github.com/lunarvim/lunarvim/pull/2493))
|
||||
- _(nvimtree)_ make sure on_config_done is using the correct require ([#2509](https://github.com/lunarvim/lunarvim/pull/2509))
|
||||
- _(nvimtree)_ add latest changes from nvimtree ([#2537](https://github.com/lunarvim/lunarvim/pull/2537))
|
||||
- _(nvimtree)_ update nvim-tree setup ([#2681](https://github.com/lunarvim/lunarvim/pull/2681))
|
||||
- _(readme)_ update lsp server ignore syntax
|
||||
- _(readme)_ remove black as linter ([#2510](https://github.com/lunarvim/lunarvim/pull/2510))
|
||||
- _(telescope)_ set <cr> binding to actions.select_default only ([#2395](https://github.com/lunarvim/lunarvim/pull/2395))
|
||||
- _(theme)_ make sure the new theme is fully loaded ([#2392](https://github.com/lunarvim/lunarvim/pull/2392))
|
||||
- _(windows)_ specify required powershell version for the installation script ([#2376](https://github.com/lunarvim/lunarvim/pull/2376))
|
||||
- update deprecated methods in example configuration for trouble.nvim ([#2416](https://github.com/lunarvim/lunarvim/pull/2416))
|
||||
- use correct cache path ([#2593](https://github.com/lunarvim/lunarvim/pull/2593))
|
||||
- load notify's telescope extension properly ([#2586](https://github.com/lunarvim/lunarvim/pull/2586))
|
||||
- skip calling nvim-tree.setup() more than once ([#2707](https://github.com/lunarvim/lunarvim/pull/2707))
|
||||
|
||||
### <!-- 3 --> Refactor
|
||||
|
||||
- _(lsp)_ replace deprecated ocamllsp with ocamlls ([#2402](https://github.com/lunarvim/lunarvim/pull/2402))
|
||||
- _(lsp)_ cleanup servers' override configuration ([#2243](https://github.com/lunarvim/lunarvim/pull/2243))
|
||||
- _(lsp)_ decouple the installer setup-hook ([#2536](https://github.com/lunarvim/lunarvim/pull/2536))
|
||||
- _(telescope)_ don't overwrite default cmd to show hidden files
|
||||
- re-enable packer.sync() in LvimReload ([#2410](https://github.com/lunarvim/lunarvim/pull/2410))
|
||||
- update impatient ([#2477](https://github.com/lunarvim/lunarvim/pull/2477))
|
||||
- lock new installations to nvim v0.7+ ([#2526](https://github.com/lunarvim/lunarvim/pull/2526))
|
||||
- use api-autocmds for lsp functions ([#2549](https://github.com/lunarvim/lunarvim/pull/2549))
|
||||
- [**breaking**] load the default options once ([#2592](https://github.com/lunarvim/lunarvim/pull/2592))
|
||||
- remove redundant ftdetects ([#2651](https://github.com/lunarvim/lunarvim/pull/2651))
|
||||
|
||||
### <!-- 4 --> Documentation
|
||||
|
||||
- _(README)_ change forgotten breaking change in example ([#2377](https://github.com/lunarvim/lunarvim/pull/2377))
|
||||
- _(windows)_ use alpha in config_win.example.lua ([#2452](https://github.com/lunarvim/lunarvim/pull/2452))
|
||||
|
||||
### <!-- 5 --> Revert
|
||||
|
||||
- do not run packer.sync() on every reload ([#2548](https://github.com/lunarvim/lunarvim/pull/2548))
|
||||
|
||||
## [1.1.3]
|
||||
|
||||
### <!-- 1 --> Features
|
||||
|
||||
- add alpha.nvim integration (#1906)
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- _(alpha)_ globalstatus after openning files from dashboard (#2366)
|
||||
- _(bufferline)_ add an additional space before diagnostics (#2367)
|
||||
- _(lualine)_ conditional theme loading (#2363)
|
||||
- _(peek)_ make sure popup_options are positive (#2373)
|
||||
- _(peek)_ print error if lsp is unable to get file contents (#2379)
|
||||
- _(terminal)_ whichkey -> which-key (#2380)
|
||||
- _(terminal)_ weird lazygit commit message bug (#2382)
|
||||
- _(windows)_ use correct validation for the alias (#2371)
|
||||
- nvim-tree taking half the window on open (#2357)
|
||||
- correct typo in backup function (#2358)
|
||||
- automatically set colorscheme (#2370)
|
||||
|
||||
### <!-- 3 --> Refactor
|
||||
|
||||
- load onedarker theme externally (#2359)
|
||||
|
||||
### <!-- 4 --> Documentation
|
||||
|
||||
- update demo images on the main readme (#2386)
|
||||
|
||||
## [1.1.2]
|
||||
|
||||
### <!-- 1 --> Features
|
||||
|
||||
- _(installer)_ Use pnpm to install nodejs dependencies(#2279) (#2280)
|
||||
- _(windows)_ Add custom config_win.example.lua (#2330)
|
||||
- Add option to automatically answer 'yes' for sh install script (#2306)
|
||||
- Enable nlsp-settings schemas (#2322)
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- _(nlsp-settings)_ Cross platform issue (#2335)
|
||||
- _(timeoutlen)_ This has caused way too many issues in the past (#2287)
|
||||
- Disable the default intro message (#2340)
|
||||
|
||||
### <!-- 3 --> Refactor
|
||||
|
||||
- _(nvim-tree)_ Update settings structure (#2304)
|
||||
|
||||
### <!-- 4 --> Documentation
|
||||
|
||||
- _(readme)_ Fix typo in example config (#2333)
|
||||
|
||||
## [1.1.1]
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- Add tsx to treesitter ensure_installed list (#2268)
|
||||
- Correct a path to bufferline module (#2270)
|
||||
|
||||
## [1.1.0]
|
||||
|
||||
### <!-- 1 --> Features
|
||||
|
||||
- _(vue)_ Set volar as default language server instead of vuels (#2230)
|
||||
- Use schemastore.nvim to provide extended json schema support (#2239)
|
||||
- Use bufferline instead of barbar (#2254)
|
||||
- Add a minimal implementation of bbye (#2267)
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- _(autopairs)_ Remove weird tex rules from autopairs (#2206)
|
||||
- _(diag)_ Show lsp-diag code in open_float (#2180)
|
||||
- _(installer)_ Usernames can contain @ symbol (#2167)
|
||||
- _(installer)_ Universal bash (#2241)
|
||||
- _(logging)_ Disable insane amount of logging inside lvim.log (#2205)
|
||||
- _(lsp)_ No need to stop clients on LvimReload (#2160)
|
||||
- _(lsp)_ Use temporary fork of lua-dev (#2187)
|
||||
- _(lsp)_ Avoid accessing undefined user_data (#2216)
|
||||
- _(lualine)_ Add space to diff components (#1897)
|
||||
- _(lualine)_ Compacter size for treesitter icon (#2247)
|
||||
- _(lualine)_ Use 1-char width symbol for changed (#2246)
|
||||
- _(which-key)_ The PR has been merged to the original repo (#2172)
|
||||
- _(zsh)_ Don't set filetype to sh (#2035)
|
||||
- Added -ScriptBlock to run commands ```install.ps1``` (#2188)
|
||||
|
||||
### <!-- 3 --> Refactor
|
||||
|
||||
- _(nvim-tree)_ Cleanup and update settings (#2182)
|
||||
- _(nvim-tree)_ Remove unused code (#2266)
|
||||
- Remove unused outdated files (#2184)
|
||||
|
||||
### <!-- 4 --> Documentation
|
||||
|
||||
- _(readme)_ Add powershell installer script for Windows (#2208)
|
||||
|
||||
## [1.0.0]
|
||||
|
||||
### <!-- 1 --> Features
|
||||
|
||||
- _(info)_ Display overridden servers for filetype (#2155)
|
||||
- _(luadev)_ Better vim api completion (#2043)
|
||||
- Add lualine config for darkplus
|
||||
- Last updates before 1.0.0 (#1953)
|
||||
- Use Telescope's git_files with fallback (#2089)
|
||||
- Plugin version bump (#2120)
|
||||
- Lazyload notify's configuration (#1855)
|
||||
- Plugin version bump (#2131)
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- _(gitsigns)_ Rounded border (#2142)
|
||||
- _(install)_ Avoid data-races for `on_packer_complete` (#2157)
|
||||
- _(installer)_ Backup linked files with rsync (#2081)
|
||||
- _(installer)_ Check if npm-prefix is writable (#2091)
|
||||
- _(installer)_ More robust yarn validation (#2113)
|
||||
- _(lsp)_ Set the handlers opts for v0.6 as well (#2109)
|
||||
- _(lsp)_ Formatter now use new null-ls api function (#2135)
|
||||
- _(lsp)_ Formatter now use new null-ls api function (#2135)
|
||||
- _(null-ls)_ Avoid sending invalid opts.args (#2154)
|
||||
- _(which-key)_ Temporary solution for which-key (#2150)
|
||||
- Remove autopairs cmp completion (#2083)
|
||||
- Remove "error" message from git tag (#2141)
|
||||
|
||||
### <!-- 3 --> Refactor
|
||||
|
||||
- _(bootstrap)_ More robust git module (#2127)
|
||||
- _(info)_ Use new null-ls api for sources (#2125)
|
||||
- _(install.sh)_ Fix typo in node error message (#2107)
|
||||
- _(null-ls)_ Allow passing full list of options for sources (#2137)
|
||||
- _(settings)_ Add headless-mode settings (#2134)
|
||||
- _(term)_ Leave the first few ids unassigned (#2156)
|
||||
- _(test)_ Cleanup test utilities (#2132)
|
||||
- Deprecate lvim.lang.FOO (#1913) (#1914)
|
||||
- Remove unused old language configs (#2094)
|
||||
- Uplift neovim's minimum version requirement to 0.6.0 (#2093)
|
||||
- Avoid running ts.setup in headless (#2119)
|
||||
- More consistent autocmds (#2133)
|
||||
- Use a static lvim binary template (#1444)
|
||||
|
||||
## [1.0.0-rc]
|
||||
|
||||
### <!-- 1 --> Features
|
||||
|
||||
- _(installer)_ Nicer rsync output (#2067)
|
||||
- _(terminal)_ Lazygit can now be toggled (#2039)
|
||||
- Add lualine config for darkplus
|
||||
- Last updates before 1.0.0 (#1953)
|
||||
- Support new null-ls (#1955)
|
||||
- Empty for empty buffers instead of Buffer <#>
|
||||
- Improved LSP grouping in lualine
|
||||
- Decrease hide in width limit for lualine
|
||||
- Add support for fsharp (#2021)
|
||||
- Add some messages in uninstall.sh (#1945)
|
||||
- Null-ls code_actions interface (#2008)
|
||||
- Full compatibility with neovim v0.6 (#2037)
|
||||
- Multiple enhancements to lvim-reload (#2054)
|
||||
- Bump plugin versions (#2064)
|
||||
- Update lsp-installer and lspconfig hashes to enable solidity_ls language server (#2072)
|
||||
|
||||
### <!-- 2 --> Bugfix
|
||||
|
||||
- _(autopairs)_ Add missing configuration entries (#2030)
|
||||
- _(bootstrap)_ Remove hard-coded spellfile option (#2061)
|
||||
- _(cmp)_ Revert broken sequential loading (#2002)
|
||||
- _(installer)_ Better handling of existing files (#2066)
|
||||
- _(lsp)_ Avoid installing an overridden server (#1981)
|
||||
- _(lsp)_ Prevent repeated setup call (#2048)
|
||||
- _(lsp)_ Correct client_id parsing in lvim-info (#2071)
|
||||
- _(lsp)_ Allow overriding servers with custom providers (#2070)
|
||||
- _(lualine)_ Change `fg` of section `a` in onedarker (#1909)
|
||||
- _(null-ls)_ Allow the same linter and formatter (#1968)
|
||||
- _(nvimtree)_ Update settings (#2001)
|
||||
- _(nvimtree)_ Restore default mappings + make them customizable (#2007)
|
||||
- _(nvimtree)_ Handle paths containing spaces (#2027)
|
||||
- _(plugins)_ Typo of pin commit of `treesitter` (#2046)
|
||||
- _(terminal)_ Allow disabling the open binding for toggleterm
|
||||
- _(windows)_ Autocmd requires forward slashes (#1967)
|
||||
- _(windows)_ Remove redundant `resolve` call (#1974)
|
||||
- Bump nvim-tree version
|
||||
- Formatting
|
||||
- Remove duplicate lint messages
|
||||
- Allow LunarVim changelog to work outside the lvim directory (#1952)
|
||||
- Use an indepdent shadafile from neovim (#1910)
|
||||
- Packersync issue when you have large number of plugins (#1922)
|
||||
- No idea why this breaks barbar
|
||||
- Lsp root can get very annoying when working with multiple languages. User is still able to turn it on.
|
||||
- Update jdtls script
|
||||
- Correct order for cmp's setup (#1999)
|
||||
- Dont close if next char is a close pair and no pairs in same line (#2017)
|
||||
- More accessible changelog (#2019)
|
||||
- Better default, ignore `.git` in `live_grep` (#2020)
|
||||
- No restart required when changing colorscheme (#2026)
|
||||
- No longer treat lazygit missing as an error (#2051)
|
||||
|
||||
### <!-- 3 --> Refactor
|
||||
|
||||
- Deprecate lvim.lang.FOO (#1913) (#1914)
|
||||
- More configurable format-on-save (#1937)
|
||||
- Load the default keymaps once (#1965)
|
||||
|
||||
<!-- generated by git-cliff -->
|
|
@ -0,0 +1,115 @@
|
|||
# Contributing to LunarVim
|
||||
|
||||
Welcome to the LunarVim contributing guide. We are excited about the prospect of you joining our [community](https://github.com/lunarvim/LunarVim/graphs/contributors)!
|
||||
|
||||
There are many opportunities to contributing to the project at any level. Every contribution is highly valued and no contribution is too small.
|
||||
|
||||
You do not need to write code to contribute to this project. Documentation, demos, and feature design advancements are a key part of this project's growth.
|
||||
|
||||
One of the best ways to begin contributing in a meaningful way is by helping find bugs and filing issues for them.
|
||||
|
||||
## Getting Started
|
||||
|
||||
1. Follow the [Installation](https://www.lunarvim.org/01-installing.html) guide
|
||||
2. Link your fork with the repository `git remote add upstream https://github.com/lunarvim/LunarVim.git`, or use `gh fork`
|
||||
3. That's it! You can now `git fetch upstream` and `git rebase [-i] upstream/rolling` to update your branches with the latest contributions.
|
||||
|
||||
<br />
|
||||
|
||||
## Setting up development tools
|
||||
|
||||
### For editing Lua files
|
||||
|
||||
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.
|
||||
|
||||
<br />
|
||||
|
||||
## Code Conventions
|
||||
|
||||
All lua code is formatted with [Stylua](https://github.com/JohnnyMorganz/StyLua).
|
||||
```bash
|
||||
# configurations are already stored in .stylua.toml
|
||||
stylua -c .
|
||||
```
|
||||
|
||||
All shell code is formatted according to [Google Shell Style Guide](https://google.github.io/styleguide/shellguide.html)
|
||||
* use two spaces instead of tabs
|
||||
```bash
|
||||
shfmt -i 2 -ci -bn -l -d .
|
||||
```
|
||||
|
||||
<br />
|
||||
|
||||
## Pull Requests (PRs)
|
||||
|
||||
- To avoid duplicate work, create a draft pull request.
|
||||
- Your PR must pass all the [automated-ci-tests](https://github.com/neovim/neovim/actions).
|
||||
- Use a [git-feature-branch](https://www.atlassian.com/git/tutorials/comparing-workflows) instead of the master/rolling branch.
|
||||
- Use a [rebase-workflow](http://git-scm.com/book/en/v2/Git-Branching-Rebasing).
|
||||
|
||||
### Commit Messages
|
||||
* Commit header is limited to 72 characters.
|
||||
* Commit body and footer is limited to 100 characters per line.
|
||||
|
||||
**Commit header format:**
|
||||
```
|
||||
<type>(<scope>?): <summary>
|
||||
│ │ │
|
||||
│ │ └─> Present tense. 'add something...'(O) vs 'added something...'(X)
|
||||
│ │ Imperative mood. 'move cursor to...'(O) vs 'moves cursor to...'(X)
|
||||
│ │ Not capitalized.
|
||||
│ │ No period at the end.
|
||||
│ │
|
||||
│ └─> Commit Scope is optional, but strongly recommended.
|
||||
│ Use lower case.
|
||||
│ 'plugin', 'file', or 'directory' name is suggested, but not limited.
|
||||
│
|
||||
└─> Commit Type: build|ci|docs|feat|fix|perf|refactor|test
|
||||
```
|
||||
|
||||
##### Commit Type Guideline
|
||||
|
||||
* **build**: changes that affect the build system or external dependencies (example scopes: npm, pip, rg)
|
||||
* **ci**: changes to CI configuration files and scripts (example scopes: format, lint, issue_templates)
|
||||
* **docs**: changes to the documentation only
|
||||
* **feat**: new feature for the user
|
||||
* **fix**: bug fix
|
||||
* **perf**: performance improvement
|
||||
* **refactor**: code change that neither fixes a bug nor adds a feature
|
||||
* **test**: adding missing tests or correcting existing tests
|
||||
* **chore**: all the rest, including version bump for plugins
|
||||
|
||||
**Real world examples:**
|
||||
```
|
||||
feat(quickfix): add 'q' binding to quit quickfix window when focused
|
||||
```
|
||||
```
|
||||
fix(installer): add missing "HOME" variable
|
||||
```
|
||||
|
||||
|
||||
### Branch Naming
|
||||
|
||||
Name your branches meaningfully.
|
||||
|
||||
ex)
|
||||
```(feature|bugfix|hotfix)/what-my-pr-does```
|
||||
|
||||
<br />
|
||||
|
||||
## Communication
|
||||
|
||||
Members of the community have multiple ways to collaborate on the project.
|
||||
We encourage you to join the community:
|
||||
- [Discord server](https://discord.gg/Xb9B4Ny)
|
||||
- [Matrix server](https://matrix.to/#/#atmachine-neovim:matrix.org)
|
|
@ -0,0 +1,674 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
|
@ -0,0 +1,42 @@
|
|||
SHELL := /usr/bin/env bash
|
||||
|
||||
install:
|
||||
@echo starting LunarVim installer
|
||||
bash ./utils/installer/install.sh
|
||||
|
||||
install-bin:
|
||||
@echo starting LunarVim bin-installer
|
||||
bash ./utils/installer/install_bin.sh
|
||||
|
||||
install-neovim-binary:
|
||||
@echo installing Neovim from github releases
|
||||
bash ./utils/installer/install-neovim-from-release
|
||||
|
||||
uninstall:
|
||||
@echo starting LunarVim uninstaller
|
||||
bash ./utils/installer/uninstall.sh
|
||||
|
||||
generate_new_lockfile:
|
||||
@echo generating core-plugins latest lockfile
|
||||
bash ./utils/ci/generate_new_lockfile.sh
|
||||
|
||||
lint: lint-lua lint-sh
|
||||
|
||||
lint-lua:
|
||||
luacheck *.lua lua/* tests/*
|
||||
|
||||
lint-sh:
|
||||
shfmt -f . | grep -v jdtls | xargs shellcheck
|
||||
|
||||
style: style-lua style-sh
|
||||
|
||||
style-lua:
|
||||
stylua --config-path .stylua.toml --check .
|
||||
|
||||
style-sh:
|
||||
shfmt -f . | grep -v jdtls | xargs shfmt -i 2 -ci -bn -l -d
|
||||
|
||||
test:
|
||||
bash ./utils/ci/run_test.sh "$(TEST)"
|
||||
|
||||
.PHONY: install install-neovim-binary uninstall lint style test
|
|
@ -0,0 +1,167 @@
|
|||
![lunarvim_logo_dark](https://user-images.githubusercontent.com/59826753/159940098-54284f26-f1da-4481-8b03-1deb34c57533.png)
|
||||
|
||||
<div align="center"><p>
|
||||
<a href="https://github.com/lunarvim/LunarVim/releases/latest">
|
||||
<img alt="Latest release" src="https://img.shields.io/github/v/release/lunarvim/LunarVim" />
|
||||
</a>
|
||||
<a href="https://github.com/lunarvim/LunarVim/pulse">
|
||||
<img alt="Last commit" src="https://img.shields.io/github/last-commit/lunarvim/LunarVim"/>
|
||||
</a>
|
||||
<a href="https://github.com/lunarvim/LunarVim/blob/main/LICENSE">
|
||||
<img src="https://img.shields.io/github/license/lunarvim/lunarvim?style=flat-square&logo=GNU&label=License" alt="License"
|
||||
/>
|
||||
<a href="https://patreon.com/chrisatmachine" title="Donate to this project using Patreon">
|
||||
<img src="https://img.shields.io/badge/patreon-donate-yellow.svg" alt="Patreon donate button" />
|
||||
</a>
|
||||
<a href="https://twitter.com/intent/follow?screen_name=chrisatmachine">
|
||||
<img src="https://img.shields.io/twitter/follow/chrisatmachine?style=social&logo=twitter" alt="follow on Twitter">
|
||||
</a>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
|
||||
## Showcase
|
||||
![intro1](https://user-images.githubusercontent.com/59826753/159939936-3a9a8e94-05ea-48fa-8c46-69378276451b.png)
|
||||
![info](https://user-images.githubusercontent.com/59826753/159939984-ac0190d7-a3fb-46c0-95ca-a6fec626bbac.png)
|
||||
|
||||
![demo1](https://user-images.githubusercontent.com/59826753/159940004-84975294-5703-4bf1-aa98-2cc97cb38d96.png)
|
||||
![demo2](https://user-images.githubusercontent.com/59826753/159940040-375a0a28-4c81-4fdf-80f2-62853edf9b4f.png)
|
||||
|
||||
## Install In One Command!
|
||||
|
||||
Make sure you have the release version of Neovim (0.7+).
|
||||
|
||||
### Linux:
|
||||
|
||||
```bash
|
||||
bash <(curl -s https://raw.githubusercontent.com/lunarvim/lunarvim/master/utils/installer/install.sh)
|
||||
```
|
||||
|
||||
To run the install script without any interaction you can pass the `-y` flag to automatically install all dependencies and have no prompts. This is particularly useful in automated installations.
|
||||
|
||||
The same way, you can use `--no-install-dependencies` to skip the dependency installation.
|
||||
|
||||
### Windows (Powershell 7+):
|
||||
|
||||
Powershell v7+ is required for this script. For instructions on how to install, [click here.](https://docs.microsoft.com/en-us/powershell/scripting/install/installing-powershell?view=powershell-7.2)
|
||||
|
||||
```powershell
|
||||
Invoke-WebRequest https://raw.githubusercontent.com/LunarVim/LunarVim/master/utils/installer/install.ps1 -UseBasicParsing | Invoke-Expression
|
||||
```
|
||||
|
||||
## Automatic LSP support
|
||||
|
||||
By default, most supported language servers will get automatically installed once you open the supported file-type, e.g, opening a Python file for the first time will install `Pyright` and configure it automatically for you.
|
||||
|
||||
## Configuration file
|
||||
|
||||
To install plugins configure LunarVim use the `config.lua` located here: `~/.config/lvim/config.lua`
|
||||
|
||||
Example:
|
||||
|
||||
```lua
|
||||
-- general
|
||||
lvim.format_on_save = true
|
||||
lvim.colorscheme = "onedarker"
|
||||
|
||||
lvim.leader = "space"
|
||||
-- add your own keymapping
|
||||
lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
|
||||
-- unmap a default keymapping
|
||||
-- lvim.keys.normal_mode["<C-Up>"] = ""
|
||||
-- edit a default keymapping
|
||||
-- lvim.keys.normal_mode["<C-q>"] = ":q<cr>"
|
||||
-- set keymap with custom opts
|
||||
-- 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>Telescope projects<CR>", "Projects" }
|
||||
|
||||
-- Configure builtin plugins
|
||||
lvim.builtin.alpha.active = true
|
||||
lvim.builtin.notify.active = true
|
||||
lvim.builtin.terminal.active = true
|
||||
|
||||
-- Treesitter parsers change this to a table of the languages you want i.e. {"java", "python", javascript}
|
||||
lvim.builtin.treesitter.ensure_installed = "maintained"
|
||||
lvim.builtin.treesitter.ignore_install = { "haskell" }
|
||||
|
||||
-- Disable virtual text
|
||||
lvim.lsp.diagnostics.virtual_text = false
|
||||
|
||||
-- Select which servers should be configured manually. Requires `:LvimCacheReset` to take effect.
|
||||
-- See the full default list `:lua print(vim.inspect(lvim.lsp.override))`
|
||||
vim.list_extend(lvim.lsp.automatic_configuration.skipped_servers, { "pyright" })
|
||||
|
||||
-- set a formatter, this will override the language server formatting capabilities (if it exists)
|
||||
local formatters = require "lvim.lsp.null-ls.formatters"
|
||||
formatters.setup {
|
||||
{ command = "black" },
|
||||
{
|
||||
command = "prettier",
|
||||
---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
|
||||
filetypes = { "typescript", "typescriptreact" },
|
||||
},
|
||||
}
|
||||
|
||||
-- set additional linters
|
||||
local linters = require "lvim.lsp.null-ls.linters"
|
||||
linters.setup {
|
||||
{
|
||||
command = "eslint_d",
|
||||
---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
|
||||
filetypes = { "javascript", "javascriptreact" },
|
||||
},
|
||||
}
|
||||
|
||||
-- Additional Plugins
|
||||
lvim.plugins = {
|
||||
{"lunarvim/colorschemes"},
|
||||
{"folke/tokyonight.nvim"}, {
|
||||
"ray-x/lsp_signature.nvim",
|
||||
config = function() require"lsp_signature".on_attach() end,
|
||||
event = "BufRead"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Updating LunarVim
|
||||
|
||||
- inside LunarVim `:LvimUpdate`
|
||||
- from the command-line `lvim +LvimUpdate +q`
|
||||
|
||||
### Update the plugins
|
||||
|
||||
- inside LunarVim `:PackerUpdate`
|
||||
|
||||
## Breaking changes
|
||||
|
||||
- `lvim.lang.FOO` is no longer supported. Refer to <https://www.lunarvim.org/languages> for up-to-date instructions.
|
||||
- `lvim.lsp.popup_border` has been deprecated in favor of `lvim.lsp.float.border` and `lvim.lsp.diagnostics.float.border`.
|
||||
- `lvim.builtin.dashboard` has been replaced with `lvim.builtin.alpha`, see <https://github.com/LunarVim/LunarVim/pull/1906>
|
||||
|
||||
## Resources
|
||||
|
||||
- [Documentation](https://www.lunarvim.org)
|
||||
|
||||
- [YouTube](https://www.youtube.com/channel/UCS97tchJDq17Qms3cux8wcA)
|
||||
|
||||
- [Discord](https://discord.gg/Xb9B4Ny)
|
||||
|
||||
- [Twitter](https://twitter.com/chrisatmachine)
|
||||
|
||||
## Testimonials
|
||||
|
||||
> "I have the processing power of a potato with 4 gb of ram and LunarVim runs perfectly."
|
||||
>
|
||||
> - @juanCortelezzi, LunarVim user.
|
||||
|
||||
> "My minimal config with a good amount less code than LunarVim loads 40ms slower. Time to switch."
|
||||
>
|
||||
> - @mvllow, Potential LunarVim user.
|
||||
|
||||
<div align="center" id="madewithlua">
|
||||
|
||||
[![Lua](https://img.shields.io/badge/Made%20with%20Lua-blue.svg?style=for-the-badge&logo=lua)](#madewithlua)
|
||||
|
||||
</div>
|
|
@ -0,0 +1,3 @@
|
|||
vim.cmd [[
|
||||
au BufRead,BufNewFile tsconfig.json set filetype=jsonc
|
||||
]]
|
|
@ -0,0 +1 @@
|
|||
vim.cmd [[ au BufRead,BufNewFile *.tex set filetype=tex ]]
|
|
@ -0,0 +1,3 @@
|
|||
vim.cmd [[
|
||||
au BufRead,BufNewFile *.zir set filetype=zir
|
||||
]]
|
|
@ -0,0 +1,21 @@
|
|||
local init_path = debug.getinfo(1, "S").source:sub(2)
|
||||
local base_dir = init_path:match("(.*[/\\])"):sub(1, -2)
|
||||
|
||||
if not vim.tbl_contains(vim.opt.rtp:get(), base_dir) then
|
||||
vim.opt.rtp:append(base_dir)
|
||||
end
|
||||
|
||||
require("lvim.bootstrap"):init(base_dir)
|
||||
|
||||
require("lvim.config"):load()
|
||||
|
||||
local plugins = require "lvim.plugins"
|
||||
require("lvim.plugin-loader").load { plugins, lvim.plugins }
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
Log:debug "Starting LunarVim"
|
||||
|
||||
local commands = require "lvim.core.commands"
|
||||
commands.load(commands.defaults)
|
||||
|
||||
require("lvim.lsp").setup()
|
|
@ -0,0 +1,130 @@
|
|||
local M = {}
|
||||
|
||||
if vim.fn.has "nvim-0.7" ~= 1 then
|
||||
vim.notify("Please upgrade your Neovim base installation. Lunarvim requires v0.7+", vim.log.levels.WARN)
|
||||
vim.wait(5000, function()
|
||||
return false
|
||||
end)
|
||||
vim.cmd "cquit"
|
||||
end
|
||||
|
||||
local uv = vim.loop
|
||||
local path_sep = uv.os_uname().version:match "Windows" and "\\" or "/"
|
||||
local in_headless = #vim.api.nvim_list_uis() == 0
|
||||
|
||||
---Join path segments that were passed as input
|
||||
---@return string
|
||||
function _G.join_paths(...)
|
||||
local result = table.concat({ ... }, path_sep)
|
||||
return result
|
||||
end
|
||||
|
||||
---Require a module in protected mode without relying on its cached value
|
||||
---@param module string
|
||||
---@return any
|
||||
function _G.require_clean(module)
|
||||
package.loaded[module] = nil
|
||||
_G[module] = nil
|
||||
local _, requested = pcall(require, module)
|
||||
return requested
|
||||
end
|
||||
|
||||
---Get the full path to `$LUNARVIM_RUNTIME_DIR`
|
||||
---@return string
|
||||
function _G.get_runtime_dir()
|
||||
local lvim_runtime_dir = os.getenv "LUNARVIM_RUNTIME_DIR"
|
||||
if not lvim_runtime_dir then
|
||||
-- when nvim is used directly
|
||||
return vim.call("stdpath", "data")
|
||||
end
|
||||
return lvim_runtime_dir
|
||||
end
|
||||
|
||||
---Get the full path to `$LUNARVIM_CONFIG_DIR`
|
||||
---@return string
|
||||
function _G.get_config_dir()
|
||||
local lvim_config_dir = os.getenv "LUNARVIM_CONFIG_DIR"
|
||||
if not lvim_config_dir then
|
||||
return vim.call("stdpath", "config")
|
||||
end
|
||||
return lvim_config_dir
|
||||
end
|
||||
|
||||
---Get the full path to `$LUNARVIM_CACHE_DIR`
|
||||
---@return string
|
||||
function _G.get_cache_dir()
|
||||
local lvim_cache_dir = os.getenv "LUNARVIM_CACHE_DIR"
|
||||
if not lvim_cache_dir then
|
||||
return vim.call("stdpath", "cache")
|
||||
end
|
||||
return lvim_cache_dir
|
||||
end
|
||||
|
||||
---Initialize the `&runtimepath` variables and prepare for startup
|
||||
---@return table
|
||||
function M:init(base_dir)
|
||||
self.runtime_dir = get_runtime_dir()
|
||||
self.config_dir = get_config_dir()
|
||||
self.cache_dir = get_cache_dir()
|
||||
self.pack_dir = join_paths(self.runtime_dir, "site", "pack")
|
||||
self.packer_install_dir = join_paths(self.runtime_dir, "site", "pack", "packer", "start", "packer.nvim")
|
||||
self.packer_cache_path = join_paths(self.config_dir, "plugin", "packer_compiled.lua")
|
||||
|
||||
---@meta overridden to use LUNARVIM_CACHE_DIR instead, since a lot of plugins call this function interally
|
||||
---NOTE: changes to "data" are currently unstable, see #2507
|
||||
vim.fn.stdpath = function(what)
|
||||
if what == "cache" then
|
||||
return _G.get_cache_dir()
|
||||
end
|
||||
return vim.call("stdpath", what)
|
||||
end
|
||||
|
||||
---Get the full path to LunarVim's base directory
|
||||
---@return string
|
||||
function _G.get_lvim_base_dir()
|
||||
return base_dir
|
||||
end
|
||||
|
||||
if os.getenv "LUNARVIM_RUNTIME_DIR" then
|
||||
-- vim.opt.rtp:append(os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim")
|
||||
vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site"))
|
||||
vim.opt.rtp:remove(join_paths(vim.call("stdpath", "data"), "site", "after"))
|
||||
vim.opt.rtp:prepend(join_paths(self.runtime_dir, "site"))
|
||||
vim.opt.rtp:append(join_paths(self.runtime_dir, "site", "after"))
|
||||
|
||||
vim.opt.rtp:remove(vim.call("stdpath", "config"))
|
||||
vim.opt.rtp:remove(join_paths(vim.call("stdpath", "config"), "after"))
|
||||
vim.opt.rtp:prepend(self.config_dir)
|
||||
vim.opt.rtp:append(join_paths(self.config_dir, "after"))
|
||||
-- TODO: we need something like this: vim.opt.packpath = vim.opt.rtp
|
||||
|
||||
vim.cmd [[let &packpath = &runtimepath]]
|
||||
end
|
||||
|
||||
-- FIXME: currently unreliable in unit-tests
|
||||
if not in_headless then
|
||||
_G.PLENARY_DEBUG = false
|
||||
require "lvim.impatient"
|
||||
end
|
||||
|
||||
require("lvim.config"):init()
|
||||
|
||||
require("lvim.plugin-loader").init {
|
||||
package_root = self.pack_dir,
|
||||
install_path = self.packer_install_dir,
|
||||
}
|
||||
|
||||
return self
|
||||
end
|
||||
|
||||
---Update LunarVim
|
||||
---pulls the latest changes from github and, resets the startup cache
|
||||
function M:update()
|
||||
require_clean("lvim.utils.hooks").run_pre_update()
|
||||
local ret = require_clean("lvim.utils.git").update_base_lvim()
|
||||
if ret then
|
||||
require_clean("lvim.utils.hooks").run_post_update()
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,42 @@
|
|||
return {
|
||||
leader = "space",
|
||||
colorscheme = "onedarker",
|
||||
transparent_window = false,
|
||||
format_on_save = {
|
||||
---@usage pattern string pattern used for the autocommand (Default: '*')
|
||||
pattern = "*",
|
||||
---@usage timeout number timeout in ms for the format request (Default: 1000)
|
||||
timeout = 1000,
|
||||
---@usage filter func to select client
|
||||
filter = require("lvim.lsp.handlers").format_filter,
|
||||
},
|
||||
keys = {},
|
||||
|
||||
use_icons = true,
|
||||
|
||||
builtin = {},
|
||||
|
||||
plugins = {
|
||||
-- use config.lua for this not put here
|
||||
},
|
||||
|
||||
autocommands = {},
|
||||
lang = {},
|
||||
log = {
|
||||
---@usage can be { "trace", "debug", "info", "warn", "error", "fatal" },
|
||||
level = "warn",
|
||||
viewer = {
|
||||
---@usage this will fallback on "less +F" if not found
|
||||
cmd = "lnav",
|
||||
layout_config = {
|
||||
---@usage direction = 'vertical' | 'horizontal' | 'window' | 'float',
|
||||
direction = "horizontal",
|
||||
open_mapping = "",
|
||||
size = 40,
|
||||
float_opts = {},
|
||||
},
|
||||
},
|
||||
-- currently disabled due to instabilities
|
||||
override_notify = false,
|
||||
},
|
||||
}
|
|
@ -0,0 +1,149 @@
|
|||
local utils = require "lvim.utils"
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local M = {}
|
||||
local user_config_dir = get_config_dir()
|
||||
local user_config_file = utils.join_paths(user_config_dir, "config.lua")
|
||||
|
||||
---Get the full path to the user configuration file
|
||||
---@return string
|
||||
function M:get_user_config_path()
|
||||
return user_config_file
|
||||
end
|
||||
|
||||
--- Initialize lvim default configuration and variables
|
||||
function M:init()
|
||||
lvim = vim.deepcopy(require "lvim.config.defaults")
|
||||
|
||||
require("lvim.keymappings").load_defaults()
|
||||
|
||||
local builtins = require "lvim.core.builtins"
|
||||
builtins.config { user_config_file = user_config_file }
|
||||
|
||||
local settings = require "lvim.config.settings"
|
||||
settings.load_defaults()
|
||||
|
||||
local autocmds = require "lvim.core.autocmds"
|
||||
autocmds.load_defaults()
|
||||
|
||||
local lvim_lsp_config = require "lvim.lsp.config"
|
||||
lvim.lsp = vim.deepcopy(lvim_lsp_config)
|
||||
|
||||
---@deprecated replaced with lvim.builtin.alpha
|
||||
lvim.builtin.dashboard = {
|
||||
active = false,
|
||||
on_config_done = nil,
|
||||
search_handler = "",
|
||||
disable_at_vim_enter = 0,
|
||||
session_directory = "",
|
||||
custom_header = {},
|
||||
custom_section = {},
|
||||
footer = {},
|
||||
}
|
||||
|
||||
lvim.builtin.luasnip = {
|
||||
sources = {
|
||||
friendly_snippets = true,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
local function handle_deprecated_settings()
|
||||
local function deprecation_notice(setting, new_setting)
|
||||
local in_headless = #vim.api.nvim_list_uis() == 0
|
||||
if in_headless then
|
||||
return
|
||||
end
|
||||
|
||||
local msg = string.format(
|
||||
"Deprecation notice: [%s] setting is no longer supported. %s",
|
||||
setting,
|
||||
new_setting or "See https://github.com/LunarVim/LunarVim#breaking-changes"
|
||||
)
|
||||
vim.schedule(function()
|
||||
vim.notify_once(msg, vim.log.levels.WARN)
|
||||
end)
|
||||
end
|
||||
|
||||
---lvim.lang.FOO.lsp
|
||||
for lang, entry in pairs(lvim.lang) do
|
||||
local deprecated_config = entry.formatters or entry.linters or {}
|
||||
if not vim.tbl_isempty(deprecated_config) then
|
||||
deprecation_notice(string.format("lvim.lang.%s", lang))
|
||||
end
|
||||
end
|
||||
|
||||
-- lvim.lsp.override
|
||||
if lvim.lsp.override and not vim.tbl_isempty(lvim.lsp.override) then
|
||||
deprecation_notice("lvim.lsp.override", "Use `lvim.lsp.automatic_configuration.skipped_servers` instead")
|
||||
vim.tbl_map(function(c)
|
||||
if not vim.tbl_contains(lvim.lsp.automatic_configuration.skipped_servers, c) then
|
||||
table.insert(lvim.lsp.automatic_configuration.skipped_servers, c)
|
||||
end
|
||||
end, lvim.lsp.override)
|
||||
end
|
||||
|
||||
-- lvim.lsp.popup_border
|
||||
if vim.tbl_contains(vim.tbl_keys(lvim.lsp), "popup_border") then
|
||||
deprecation_notice "lvim.lsp.popup_border"
|
||||
end
|
||||
|
||||
-- dashboard.nvim
|
||||
if lvim.builtin.dashboard.active then
|
||||
deprecation_notice("lvim.builtin.dashboard", "Use `lvim.builtin.alpha` instead. See LunarVim#1906")
|
||||
end
|
||||
|
||||
if lvim.autocommands.custom_groups then
|
||||
deprecation_notice(
|
||||
"lvim.autocommands.custom_groups",
|
||||
"Use vim.api.nvim_create_autocmd instead or check LunarVim#2592 to learn about the new syntax"
|
||||
)
|
||||
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 "lvim.core.autocmds"
|
||||
config_path = config_path or self:get_user_config_path()
|
||||
local ok, err = pcall(dofile, config_path)
|
||||
if not ok then
|
||||
if utils.is_file(user_config_file) then
|
||||
Log:warn("Invalid configuration: " .. err)
|
||||
else
|
||||
vim.notify_once(string.format("Unable to find configuration file [%s]", config_path), vim.log.levels.WARN)
|
||||
end
|
||||
end
|
||||
|
||||
handle_deprecated_settings()
|
||||
|
||||
autocmds.define_autocmds(lvim.autocommands)
|
||||
|
||||
vim.g.mapleader = (lvim.leader == "space" and " ") or lvim.leader
|
||||
|
||||
require("lvim.keymappings").load(lvim.keys)
|
||||
|
||||
if lvim.transparent_window then
|
||||
autocmds.enable_transparent_mode()
|
||||
end
|
||||
end
|
||||
|
||||
--- Override the configuration with a user provided one
|
||||
-- @param config_path The path to the configuration overrides
|
||||
function M:reload()
|
||||
vim.schedule(function()
|
||||
require_clean("lvim.utils.hooks").run_pre_reload()
|
||||
|
||||
M:load()
|
||||
|
||||
require("lvim.core.autocmds").configure_format_on_save()
|
||||
|
||||
local plugins = require "lvim.plugins"
|
||||
local plugin_loader = require "lvim.plugin-loader"
|
||||
|
||||
plugin_loader.reload { plugins, lvim.plugins }
|
||||
require_clean("lvim.utils.hooks").run_post_reload()
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,84 @@
|
|||
local M = {}
|
||||
|
||||
M.load_default_options = function()
|
||||
local utils = require "lvim.utils"
|
||||
local join_paths = utils.join_paths
|
||||
|
||||
local undodir = join_paths(get_cache_dir(), "undo")
|
||||
|
||||
if not utils.is_directory(undodir) then
|
||||
vim.fn.mkdir(undodir, "p")
|
||||
end
|
||||
|
||||
local default_options = {
|
||||
backup = false, -- creates a backup file
|
||||
clipboard = "unnamedplus", -- allows neovim to access the system clipboard
|
||||
cmdheight = 2, -- more space in the neovim command line for displaying messages
|
||||
colorcolumn = "99999", -- fixes indentline for now
|
||||
completeopt = { "menuone", "noselect" },
|
||||
conceallevel = 0, -- so that `` is visible in markdown files
|
||||
fileencoding = "utf-8", -- the encoding written to a file
|
||||
foldmethod = "manual", -- folding, set to "expr" for treesitter based folding
|
||||
foldexpr = "", -- set to "nvim_treesitter#foldexpr()" for treesitter based folding
|
||||
guifont = "monospace:h17", -- the font used in graphical neovim applications
|
||||
hidden = true, -- required to keep multiple buffers and open multiple buffers
|
||||
hlsearch = true, -- highlight all matches on previous search pattern
|
||||
ignorecase = true, -- ignore case in search patterns
|
||||
mouse = "a", -- allow the mouse to be used in neovim
|
||||
pumheight = 10, -- pop up menu height
|
||||
showmode = false, -- we don't need to see things like -- INSERT -- anymore
|
||||
showtabline = 2, -- always show tabs
|
||||
smartcase = true, -- smart case
|
||||
smartindent = true, -- make indenting smarter again
|
||||
splitbelow = true, -- force all horizontal splits to go below current window
|
||||
splitright = true, -- force all vertical splits to go to the right of current window
|
||||
swapfile = false, -- creates a swapfile
|
||||
termguicolors = true, -- set term gui colors (most terminals support this)
|
||||
timeoutlen = 250, -- time to wait for a mapped sequence to complete (in milliseconds)
|
||||
title = true, -- set the title of window to the value of the titlestring
|
||||
-- opt.titlestring = "%<%F%=%l/%L - nvim" -- what the title of the window will be set to
|
||||
undodir = undodir, -- set an undo directory
|
||||
undofile = true, -- enable persistent undo
|
||||
updatetime = 300, -- faster completion
|
||||
writebackup = false, -- if a file is being edited by another program (or was written to file while editing with another program), it is not allowed to be edited
|
||||
expandtab = true, -- convert tabs to spaces
|
||||
shiftwidth = 2, -- the number of spaces inserted for each indentation
|
||||
tabstop = 2, -- insert 2 spaces for a tab
|
||||
cursorline = true, -- highlight the current line
|
||||
number = true, -- set numbered lines
|
||||
relativenumber = false, -- set relative numbered lines
|
||||
numberwidth = 4, -- set number column width to 2 {default 4}
|
||||
signcolumn = "yes", -- always show the sign column, otherwise it would shift the text each time
|
||||
wrap = false, -- display lines as one long line
|
||||
shadafile = join_paths(get_cache_dir(), "lvim.shada"),
|
||||
scrolloff = 8, -- minimal number of screen lines to keep above and below the cursor.
|
||||
sidescrolloff = 8, -- minimal number of screen lines to keep left and right of the cursor.
|
||||
}
|
||||
|
||||
--- SETTINGS ---
|
||||
vim.opt.shortmess:append "c" -- don't show redundant messages from ins-completion-menu
|
||||
vim.opt.shortmess:append "I" -- don't show the default intro message
|
||||
vim.opt.whichwrap:append "<,>,[,],h,l"
|
||||
|
||||
for k, v in pairs(default_options) do
|
||||
vim.opt[k] = v
|
||||
end
|
||||
end
|
||||
|
||||
M.load_headless_options = function()
|
||||
vim.opt.shortmess = "" -- try to prevent echom from cutting messages off or prompting
|
||||
vim.opt.more = false -- don't pause listing when screen is filled
|
||||
vim.opt.cmdheight = 9999 -- helps avoiding |hit-enter| prompts.
|
||||
vim.opt.columns = 9999 -- set the widest screen possible
|
||||
vim.opt.swapfile = false -- don't use a swap file
|
||||
end
|
||||
|
||||
M.load_defaults = function()
|
||||
if #vim.api.nvim_list_uis() == 0 then
|
||||
M.load_headless_options()
|
||||
return
|
||||
end
|
||||
M.load_default_options()
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,81 @@
|
|||
local M = {}
|
||||
|
||||
function M.config()
|
||||
local lvim_dashboard = require "lvim.core.alpha.dashboard"
|
||||
local lvim_startify = require "lvim.core.alpha.startify"
|
||||
lvim.builtin.alpha = {
|
||||
dashboard = { config = {}, section = lvim_dashboard.get_sections() },
|
||||
startify = { config = {}, section = lvim_startify.get_sections() },
|
||||
active = true,
|
||||
mode = "dashboard",
|
||||
}
|
||||
end
|
||||
|
||||
local function resolve_buttons(theme_name, entries)
|
||||
local selected_theme = require("alpha.themes." .. theme_name)
|
||||
local val = {}
|
||||
for _, entry in pairs(entries) do
|
||||
local on_press = function()
|
||||
local sc_ = entry[1]:gsub("%s", ""):gsub("SPC", "<leader>")
|
||||
local key = vim.api.nvim_replace_termcodes(sc_, true, false, true)
|
||||
vim.api.nvim_feedkeys(key, "normal", false)
|
||||
end
|
||||
local button_element = selected_theme.button(entry[1], entry[2], entry[3])
|
||||
-- this became necessary after recent changes in alpha.nvim (06ade3a20ca9e79a7038b98d05a23d7b6c016174)
|
||||
button_element.on_press = on_press
|
||||
table.insert(val, button_element)
|
||||
end
|
||||
return val
|
||||
end
|
||||
|
||||
local function resolve_config(theme_name)
|
||||
local selected_theme = require("alpha.themes." .. theme_name)
|
||||
local resolved_section = selected_theme.section
|
||||
local section = lvim.builtin.alpha[theme_name].section
|
||||
|
||||
for name, el in pairs(section) do
|
||||
for k, v in pairs(el) do
|
||||
if name:match "buttons" and k == "entries" then
|
||||
resolved_section[name].val = resolve_buttons(theme_name, v)
|
||||
elseif v then
|
||||
resolved_section[name][k] = v
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return selected_theme.config
|
||||
end
|
||||
|
||||
local function configure_additional_autocmds()
|
||||
local group = "_dashboard_settings"
|
||||
vim.api.nvim_create_augroup(group, {})
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
group = group,
|
||||
pattern = "alpha",
|
||||
command = "set showtabline=0 | autocmd BufLeave <buffer> set showtabline=" .. vim.opt.showtabline._value,
|
||||
})
|
||||
if not lvim.builtin.lualine.options.globalstatus then
|
||||
-- https://github.com/goolord/alpha-nvim/issues/42
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
group = group,
|
||||
pattern = "alpha",
|
||||
command = "set laststatus=0 | autocmd BufUnload <buffer> set laststatus=" .. vim.opt.laststatus._value,
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
local alpha = require "alpha"
|
||||
local mode = lvim.builtin.alpha.mode
|
||||
local config = lvim.builtin.alpha[mode].config
|
||||
|
||||
-- this makes it easier to use a completely custom configuration
|
||||
if vim.tbl_isempty(config) then
|
||||
config = resolve_config(mode)
|
||||
end
|
||||
|
||||
alpha.setup(config)
|
||||
configure_additional_autocmds()
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,75 @@
|
|||
local M = {}
|
||||
|
||||
function M.get_sections()
|
||||
local header = {
|
||||
type = "text",
|
||||
val = {
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣠⣴⣶⣿⣿⣿⣷⣶⣤⡀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣴⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣧⡀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀",
|
||||
"⠀⣀⣴⣶⣶⣶⣶⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡄⠀⠀⠀",
|
||||
"⣰⣿⣿⠿⠛⠿⢿⣿⣿⣷⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠀⠀⠀⠀",
|
||||
"⣿⣿⡇⠀⠀⠀⠀⠈⠛⢿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣰⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⡟⠀⠀⠀⠀",
|
||||
"⠹⣿⣧⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣦⣄⠀⠀⠀⠀⠀⠀⠀⢀⣿⣿⣿⣿⣿⣿⣿⡿⠛⠉⠀⢀⣿⣿⣿⣿⣿⣿⣿⠟⠀⠀⠀⠀⠀",
|
||||
"⠀⠙⢿⣧⡀⠀⠀⠀⠀⠀⠀⠀⠙⢿⣿⣿⣿⣷⣶⣶⣶⣶⣶⣿⣿⣿⣿⣿⣿⣿⣿⣷⣤⣤⣶⣿⣿⣿⣿⣿⡿⠟⠁⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠉⠻⠷⡄⠀⠀⠀⠀⠀⠀⠀⠈⠛⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠛⠉⠀⢀⣠⣤⣤⣄⡀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⠿⠋⠁⠀⠀⠀⠀⢠⣿⣿⣿⣿⣿⣿⣷⡀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣠⣾⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⣄⡀⠀⠀⠀⠀⣿⠟⠉⠉⠙⢿⣿⣿⣷",
|
||||
"⠀⠀⠀⣀⣠⣤⣤⣤⣶⣶⣶⣤⣤⠀⣴⣿⣿⣿⡿⠟⠛⠛⠛⢿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠉⠀⠀⠀⢀⣼⣿⣿⡿",
|
||||
"⠀⠀⠀⠈⠉⠉⠉⠉⠉⠉⠛⠻⠏⣼⣿⣿⡿⣋⣀⣤⣤⣴⣶⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣶⣤⣄⣀⣠⣴⣾⣿⣿⡿⠁",
|
||||
"⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣾⣿⡿⠋⠘⠿⠟⠛⠛⢻⣿⣿⣿⠋⠁⠈⠉⢿⣿⣿⣧⠀⠙⠻⢿⣿⣿⣿⣿⣿⣿⣿⡿⠟⠉⠀⠀",
|
||||
"⠙⣷⣤⣀⠀⠀⠀⢀⣀⣤⣶⣿⡿⠋⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⡟⠀⠀⠀⢠⣿⣿⣿⡟⠀⠀⠀⠀⠀⠉⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠈⠛⠿⢿⣿⣿⣿⠿⠿⠛⠉⠀⠀⠀⠀⠀⠀⠀⠀⠀⢸⣿⣿⣿⡀⠀⢠⣿⣿⣿⣿⠃⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣷⣶⣶⣶⣶⣦⣤⣀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⣙⠿⣿⣿⣿⣿⣿⣿⣿⣿⣿⣦⡀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠐⢶⣦⣤⣶⣾⣿⣿⡶⠈⠉⠛⠿⣿⣿⣿⣿⣿⣷⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠈⠉⠉⠉⠉⠀⠀⠀⠀⠀⠀⠀⠙⣿⣿⣿⣿⡇⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⣼⣿⣿⡿⠁⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
"⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⢀⣤⣤⣶⡿⠿⠟⠋⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀⠀",
|
||||
},
|
||||
opts = {
|
||||
position = "center",
|
||||
hl = "Label",
|
||||
},
|
||||
}
|
||||
|
||||
local text = require "lvim.interface.text"
|
||||
local lvim_version = require("lvim.utils.git").get_lvim_version()
|
||||
|
||||
local footer = {
|
||||
type = "text",
|
||||
val = text.align_center({ width = 0 }, {
|
||||
"",
|
||||
"lunarvim.org",
|
||||
lvim_version,
|
||||
}, 0.5),
|
||||
opts = {
|
||||
position = "center",
|
||||
hl = "Number",
|
||||
},
|
||||
}
|
||||
|
||||
local buttons = {
|
||||
entries = {
|
||||
{ "SPC f", " Find File", "<CMD>Telescope find_files<CR>" },
|
||||
{ "SPC n", " New File", "<CMD>ene!<CR>" },
|
||||
{ "SPC P", " Recent Projects ", "<CMD>Telescope projects<CR>" },
|
||||
{ "SPC s r", " Recently Used Files", "<CMD>Telescope oldfiles<CR>" },
|
||||
{ "SPC s t", " Find Word", "<CMD>Telescope live_grep<CR>" },
|
||||
{
|
||||
"SPC L c",
|
||||
" Configuration",
|
||||
"<CMD>edit " .. require("lvim.config"):get_user_config_path() .. " <CR>",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return {
|
||||
header = header,
|
||||
buttons = buttons,
|
||||
footer = footer,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,48 @@
|
|||
local M = {}
|
||||
|
||||
function M.get_sections()
|
||||
local header = {
|
||||
type = "text",
|
||||
val = {
|
||||
[[ __ _ ___ ]],
|
||||
[[ / / __ ______ ____ _____| | / (_)___ ___ ]],
|
||||
[[ / / / / / / __ \/ __ `/ ___/ | / / / __ `__ \]],
|
||||
[[ / /___/ /_/ / / / / /_/ / / | |/ / / / / / / /]],
|
||||
[[/_____/\__,_/_/ /_/\__,_/_/ |___/_/_/ /_/ /_/ ]],
|
||||
},
|
||||
opts = {
|
||||
hl = "Label",
|
||||
shrink_margin = false,
|
||||
-- wrap = "overflow";
|
||||
},
|
||||
}
|
||||
|
||||
local top_buttons = {
|
||||
entries = {
|
||||
{ "e", " New File", "<CMD>ene!<CR>" },
|
||||
},
|
||||
val = {},
|
||||
}
|
||||
|
||||
local bottom_buttons = {
|
||||
entries = {
|
||||
{ "q", "Quit", "<CMD>quit<CR>" },
|
||||
},
|
||||
val = {},
|
||||
}
|
||||
|
||||
local footer = {
|
||||
type = "group",
|
||||
val = {},
|
||||
}
|
||||
|
||||
return {
|
||||
header = header,
|
||||
top_buttons = top_buttons,
|
||||
bottom_buttons = bottom_buttons,
|
||||
-- this is probably broken
|
||||
footer = footer,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,191 @@
|
|||
local M = {}
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
--- Load the default set of autogroups and autocommands.
|
||||
function M.load_defaults()
|
||||
local user_config_file = require("lvim.config"):get_user_config_path()
|
||||
|
||||
if vim.loop.os_uname().version:match "Windows" then
|
||||
-- autocmds require forward slashes even on windows
|
||||
user_config_file = user_config_file:gsub("\\", "/")
|
||||
end
|
||||
|
||||
local definitions = {
|
||||
{
|
||||
"TextYankPost",
|
||||
{
|
||||
group = "_general_settings",
|
||||
pattern = "*",
|
||||
desc = "Highlight text on yank",
|
||||
callback = function()
|
||||
require("vim.highlight").on_yank { higroup = "Search", timeout = 200 }
|
||||
end,
|
||||
},
|
||||
},
|
||||
{
|
||||
"BufWritePost",
|
||||
{
|
||||
group = "_general_settings",
|
||||
pattern = user_config_file,
|
||||
desc = "Trigger LvimReload on saving " .. vim.fn.expand "%:~",
|
||||
callback = function()
|
||||
require("lvim.config"):reload()
|
||||
end,
|
||||
},
|
||||
},
|
||||
{
|
||||
"FileType",
|
||||
{
|
||||
group = "_filetype_settings",
|
||||
pattern = "qf",
|
||||
command = "set nobuflisted",
|
||||
},
|
||||
},
|
||||
{
|
||||
"FileType",
|
||||
{
|
||||
group = "_filetype_settings",
|
||||
pattern = { "gitcommit", "markdown" },
|
||||
command = "setlocal wrap spell",
|
||||
},
|
||||
},
|
||||
{
|
||||
"FileType",
|
||||
{
|
||||
group = "_buffer_mappings",
|
||||
pattern = { "qf", "help", "man", "floaterm", "lspinfo", "lsp-installer", "null-ls-info" },
|
||||
command = "nnoremap <silent> <buffer> q :close<CR>",
|
||||
},
|
||||
},
|
||||
{
|
||||
{ "BufWinEnter", "BufRead", "BufNewFile" },
|
||||
{
|
||||
group = "_format_options",
|
||||
pattern = "*",
|
||||
command = "setlocal formatoptions-=c formatoptions-=r formatoptions-=o",
|
||||
},
|
||||
},
|
||||
{
|
||||
"VimResized",
|
||||
{
|
||||
group = "_auto_resize",
|
||||
pattern = "*",
|
||||
command = "tabdo wincmd =",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
M.define_autocmds(definitions)
|
||||
end
|
||||
|
||||
local get_format_on_save_opts = function()
|
||||
local defaults = require("lvim.config.defaults").format_on_save
|
||||
-- accept a basic boolean `lvim.format_on_save=true`
|
||||
if type(lvim.format_on_save) ~= "table" then
|
||||
return defaults
|
||||
end
|
||||
|
||||
return {
|
||||
pattern = lvim.format_on_save.pattern or defaults.pattern,
|
||||
timeout = lvim.format_on_save.timeout or defaults.timeout,
|
||||
}
|
||||
end
|
||||
|
||||
function M.enable_format_on_save()
|
||||
local opts = get_format_on_save_opts()
|
||||
vim.api.nvim_create_augroup("lsp_format_on_save", {})
|
||||
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||
group = "lsp_format_on_save",
|
||||
pattern = opts.pattern,
|
||||
callback = function()
|
||||
require("lvim.lsp.utils").format { timeout_ms = opts.timeout, filter = opts.filter }
|
||||
end,
|
||||
})
|
||||
Log:debug "enabled format-on-save"
|
||||
end
|
||||
|
||||
function M.disable_format_on_save()
|
||||
M.clear_augroup "lsp_format_on_save"
|
||||
Log:debug "disabled format-on-save"
|
||||
end
|
||||
|
||||
function M.configure_format_on_save()
|
||||
if lvim.format_on_save then
|
||||
M.enable_format_on_save()
|
||||
else
|
||||
M.disable_format_on_save()
|
||||
end
|
||||
end
|
||||
|
||||
function M.toggle_format_on_save()
|
||||
local exists, autocmds = pcall(vim.api.nvim_get_autocmds, {
|
||||
group = "lsp_format_on_save",
|
||||
event = "BufWritePre",
|
||||
})
|
||||
if not exists or #autocmds == 0 then
|
||||
M.enable_format_on_save()
|
||||
else
|
||||
M.disable_format_on_save()
|
||||
end
|
||||
end
|
||||
|
||||
function M.enable_transparent_mode()
|
||||
vim.api.nvim_create_autocmd("ColorScheme", {
|
||||
pattern = "*",
|
||||
callback = function()
|
||||
local hl_groups = {
|
||||
"Normal",
|
||||
"SignColumn",
|
||||
"NormalNC",
|
||||
"TelescopeBorder",
|
||||
"NvimTreeNormal",
|
||||
"EndOfBuffer",
|
||||
"MsgArea",
|
||||
}
|
||||
for _, name in ipairs(hl_groups) do
|
||||
vim.cmd(string.format("highlight %s ctermbg=none guibg=none", name))
|
||||
end
|
||||
end,
|
||||
})
|
||||
vim.opt.fillchars = "eob: "
|
||||
end
|
||||
|
||||
--- Clean autocommand in a group if it exists
|
||||
--- This is safer than trying to delete the augroup itself
|
||||
---@param name string the augroup name
|
||||
function M.clear_augroup(name)
|
||||
-- defer the function in case the autocommand is still in-use
|
||||
local exists, _ = pcall(vim.api.nvim_get_autocmds, { group = name })
|
||||
if not exists then
|
||||
Log:debug("ignoring request to clear autocmds from non-existent group " .. name)
|
||||
return
|
||||
end
|
||||
vim.schedule(function()
|
||||
local status_ok, _ = xpcall(function()
|
||||
vim.api.nvim_clear_autocmds { group = name }
|
||||
end, debug.traceback)
|
||||
if not status_ok then
|
||||
Log:warn("problems detected while clearing autocmds from " .. name)
|
||||
Log:debug(debug.traceback())
|
||||
end
|
||||
end)
|
||||
end
|
||||
|
||||
--- Create autocommand groups based on the passed definitions
|
||||
--- Also creates the augroup automatically if it doesn't exist
|
||||
---@param definitions table contains a tuple of event, opts, see `:h nvim_create_autocmd`
|
||||
function M.define_autocmds(definitions)
|
||||
for _, entry in ipairs(definitions) do
|
||||
local event = entry[1]
|
||||
local opts = entry[2]
|
||||
if type(opts.group) == "string" and opts.group ~= "" then
|
||||
local exists, _ = pcall(vim.api.nvim_get_autocmds, { group = opts.group })
|
||||
if not exists then
|
||||
vim.api.nvim_create_augroup(opts.group, {})
|
||||
end
|
||||
end
|
||||
vim.api.nvim_create_autocmd(event, opts)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,84 @@
|
|||
local M = {}
|
||||
|
||||
function M.config()
|
||||
lvim.builtin.autopairs = {
|
||||
active = true,
|
||||
on_config_done = nil,
|
||||
---@usage modifies the function or method delimiter by filetypes
|
||||
map_char = {
|
||||
all = "(",
|
||||
tex = "{",
|
||||
},
|
||||
---@usage check bracket in same line
|
||||
enable_check_bracket_line = false,
|
||||
---@usage check treesitter
|
||||
check_ts = true,
|
||||
ts_config = {
|
||||
lua = { "string", "source" },
|
||||
javascript = { "string", "template_string" },
|
||||
java = false,
|
||||
},
|
||||
disable_filetype = { "TelescopePrompt", "spectre_panel" },
|
||||
ignored_next_char = string.gsub([[ [%w%%%'%[%"%.] ]], "%s+", ""),
|
||||
enable_moveright = true,
|
||||
---@usage disable when recording or executing a macro
|
||||
disable_in_macro = false,
|
||||
---@usage add bracket pairs after quote
|
||||
enable_afterquote = true,
|
||||
---@usage map the <BS> key
|
||||
map_bs = true,
|
||||
---@usage map <c-w> to delete a pair if possible
|
||||
map_c_w = false,
|
||||
---@usage disable when insert after visual block mode
|
||||
disable_in_visualblock = false,
|
||||
---@usage change default fast_wrap
|
||||
fast_wrap = {
|
||||
map = "<M-e>",
|
||||
chars = { "{", "[", "(", '"', "'" },
|
||||
pattern = string.gsub([[ [%'%"%)%>%]%)%}%,] ]], "%s+", ""),
|
||||
offset = 0, -- Offset from pattern match
|
||||
end_key = "$",
|
||||
keys = "qwertyuiopzxcvbnmasdfghjkl",
|
||||
check_comma = true,
|
||||
highlight = "Search",
|
||||
highlight_grey = "Comment",
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
local autopairs = require "nvim-autopairs"
|
||||
local Rule = require "nvim-autopairs.rule"
|
||||
|
||||
autopairs.setup {
|
||||
check_ts = lvim.builtin.autopairs.check_ts,
|
||||
enable_check_bracket_line = lvim.builtin.autopairs.enable_check_bracket_line,
|
||||
ts_config = lvim.builtin.autopairs.ts_config,
|
||||
disable_filetype = lvim.builtin.autopairs.disable_filetype,
|
||||
disable_in_macro = lvim.builtin.autopairs.disable_in_macro,
|
||||
ignored_next_char = lvim.builtin.autopairs.ignored_next_char,
|
||||
enable_moveright = lvim.builtin.autopairs.enable_moveright,
|
||||
enable_afterquote = lvim.builtin.autopairs.enable_afterquote,
|
||||
map_c_w = lvim.builtin.autopairs.map_c_w,
|
||||
map_bs = lvim.builtin.autopairs.map_bs,
|
||||
disable_in_visualblock = lvim.builtin.autopairs.disable_in_visualblock,
|
||||
fast_wrap = lvim.builtin.autopairs.fast_wrap,
|
||||
}
|
||||
|
||||
require("nvim-treesitter.configs").setup { autopairs = { enable = true } }
|
||||
|
||||
local ts_conds = require "nvim-autopairs.ts-conds"
|
||||
|
||||
-- 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" }),
|
||||
}
|
||||
|
||||
if lvim.builtin.autopairs.on_config_done then
|
||||
lvim.builtin.autopairs.on_config_done(autopairs)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,221 @@
|
|||
local M = {}
|
||||
|
||||
local function is_ft(b, ft)
|
||||
return vim.bo[b].filetype == ft
|
||||
end
|
||||
|
||||
local function diagnostics_indicator(num, _, diagnostics, _)
|
||||
local result = {}
|
||||
local symbols = { error = "", warning = "", info = "" }
|
||||
if not lvim.use_icons then
|
||||
return "(" .. num .. ")"
|
||||
end
|
||||
for name, count in pairs(diagnostics) do
|
||||
if symbols[name] and count > 0 then
|
||||
table.insert(result, symbols[name] .. " " .. count)
|
||||
end
|
||||
end
|
||||
result = table.concat(result, " ")
|
||||
return #result > 0 and result or ""
|
||||
end
|
||||
|
||||
local function custom_filter(buf, buf_nums)
|
||||
local logs = vim.tbl_filter(function(b)
|
||||
return is_ft(b, "log")
|
||||
end, buf_nums)
|
||||
if vim.tbl_isempty(logs) then
|
||||
return true
|
||||
end
|
||||
local tab_num = vim.fn.tabpagenr()
|
||||
local last_tab = vim.fn.tabpagenr "$"
|
||||
local is_log = is_ft(buf, "log")
|
||||
if last_tab == 1 then
|
||||
return true
|
||||
end
|
||||
-- only show log buffers in secondary tabs
|
||||
return (tab_num == last_tab and is_log) or (tab_num ~= last_tab and not is_log)
|
||||
end
|
||||
|
||||
M.config = function()
|
||||
lvim.builtin.bufferline = {
|
||||
active = true,
|
||||
on_config_done = nil,
|
||||
keymap = {
|
||||
normal_mode = {},
|
||||
},
|
||||
highlights = {
|
||||
background = {
|
||||
gui = "italic",
|
||||
},
|
||||
buffer_selected = {
|
||||
gui = "bold",
|
||||
},
|
||||
},
|
||||
options = {
|
||||
numbers = "none", -- can be "none" | "ordinal" | "buffer_id" | "both" | function
|
||||
close_command = "bdelete! %d", -- can be a string | function, see "Mouse actions"
|
||||
right_mouse_command = "vert sbuffer %d", -- can be a string | function, see "Mouse actions"
|
||||
left_mouse_command = "buffer %d", -- can be a string | function, see "Mouse actions"
|
||||
middle_mouse_command = nil, -- can be a string | function, see "Mouse actions"
|
||||
-- NOTE: this plugin is designed with this icon in mind,
|
||||
-- and so changing this is NOT recommended, this is intended
|
||||
-- as an escape hatch for people who cannot bear it for whatever reason
|
||||
indicator_icon = "▎",
|
||||
buffer_close_icon = "",
|
||||
modified_icon = "●",
|
||||
close_icon = "",
|
||||
left_trunc_marker = "",
|
||||
right_trunc_marker = "",
|
||||
--- name_formatter can be used to change the buffer's label in the bufferline.
|
||||
--- Please note some names can/will break the
|
||||
--- bufferline so use this at your discretion knowing that it has
|
||||
--- some limitations that will *NOT* be fixed.
|
||||
name_formatter = function(buf) -- buf contains a "name", "path" and "bufnr"
|
||||
-- remove extension from markdown files for example
|
||||
if buf.name:match "%.md" then
|
||||
return vim.fn.fnamemodify(buf.name, ":t:r")
|
||||
end
|
||||
end,
|
||||
max_name_length = 18,
|
||||
max_prefix_length = 15, -- prefix used when a buffer is de-duplicated
|
||||
tab_size = 18,
|
||||
diagnostics = "nvim_lsp",
|
||||
diagnostics_update_in_insert = false,
|
||||
diagnostics_indicator = diagnostics_indicator,
|
||||
-- NOTE: this will be called a lot so don't do any heavy processing here
|
||||
custom_filter = custom_filter,
|
||||
offsets = {
|
||||
{
|
||||
filetype = "undotree",
|
||||
text = "Undotree",
|
||||
highlight = "PanelHeading",
|
||||
padding = 1,
|
||||
},
|
||||
{
|
||||
filetype = "NvimTree",
|
||||
text = "Explorer",
|
||||
highlight = "PanelHeading",
|
||||
padding = 1,
|
||||
},
|
||||
{
|
||||
filetype = "DiffviewFiles",
|
||||
text = "Diff View",
|
||||
highlight = "PanelHeading",
|
||||
padding = 1,
|
||||
},
|
||||
{
|
||||
filetype = "flutterToolsOutline",
|
||||
text = "Flutter Outline",
|
||||
highlight = "PanelHeading",
|
||||
},
|
||||
{
|
||||
filetype = "packer",
|
||||
text = "Packer",
|
||||
highlight = "PanelHeading",
|
||||
padding = 1,
|
||||
},
|
||||
},
|
||||
show_buffer_icons = lvim.use_icons, -- disable filetype icons for buffers
|
||||
show_buffer_close_icons = lvim.use_icons,
|
||||
show_close_icon = false,
|
||||
show_tab_indicators = true,
|
||||
persist_buffer_sort = true, -- whether or not custom sorted buffers should persist
|
||||
-- can also be a table containing 2 custom separators
|
||||
-- [focused and unfocused]. eg: { '|', '|' }
|
||||
separator_style = "thin",
|
||||
enforce_regular_tabs = false,
|
||||
always_show_bufferline = false,
|
||||
sort_by = "id",
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
require("lvim.keymappings").load(lvim.builtin.bufferline.keymap)
|
||||
require("bufferline").setup {
|
||||
options = lvim.builtin.bufferline.options,
|
||||
highlights = lvim.builtin.bufferline.highlights,
|
||||
}
|
||||
|
||||
if lvim.builtin.bufferline.on_config_done then
|
||||
lvim.builtin.bufferline.on_config_done()
|
||||
end
|
||||
end
|
||||
|
||||
--stylua: ignore
|
||||
|
||||
-- Common kill function for bdelete and bwipeout
|
||||
-- credits: based on bbye and nvim-bufdel
|
||||
---@param kill_command? string defaults to "bd"
|
||||
---@param bufnr? number defaults to the current buffer
|
||||
---@param force? boolean defaults to false
|
||||
function M.buf_kill(kill_command, bufnr, force)
|
||||
kill_command = kill_command or "bd"
|
||||
|
||||
local bo = vim.bo
|
||||
local api = vim.api
|
||||
local fmt = string.format
|
||||
local fnamemodify = vim.fn.fnamemodify
|
||||
|
||||
if bufnr == 0 or bufnr == nil then
|
||||
bufnr = api.nvim_get_current_buf()
|
||||
end
|
||||
|
||||
local bufname = api.nvim_buf_get_name(bufnr)
|
||||
|
||||
if not force then
|
||||
local warning
|
||||
if bo[bufnr].modified then
|
||||
warning = fmt([[No write since last change for (%s)]], fnamemodify(bufname, ":t"))
|
||||
elseif api.nvim_buf_get_option(bufnr, "buftype") == "terminal" then
|
||||
warning = fmt([[Terminal %s will be killed]], bufname)
|
||||
end
|
||||
if warning then
|
||||
vim.ui.input({
|
||||
prompt = string.format([[%s. Close it anyway? [y]es or [n]o (default: no): ]], warning),
|
||||
}, function(choice)
|
||||
if choice:match "ye?s?" then force = true end
|
||||
end)
|
||||
if not force then return end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get list of windows IDs with the buffer to close
|
||||
local windows = vim.tbl_filter(function(win)
|
||||
return api.nvim_win_get_buf(win) == bufnr
|
||||
end, api.nvim_list_wins())
|
||||
|
||||
if #windows == 0 then return end
|
||||
|
||||
if force then
|
||||
kill_command = kill_command .. "!"
|
||||
end
|
||||
|
||||
-- Get list of active buffers
|
||||
local buffers = vim.tbl_filter(function(buf)
|
||||
return api.nvim_buf_is_valid(buf) and bo[buf].buflisted
|
||||
end, api.nvim_list_bufs())
|
||||
|
||||
-- If there is only one buffer (which has to be the current one), vim will
|
||||
-- create a new buffer on :bd.
|
||||
-- For more than one buffer, pick the previous buffer (wrapping around if necessary)
|
||||
if #buffers > 1 then
|
||||
for i, v in ipairs(buffers) do
|
||||
if v == bufnr then
|
||||
local prev_buf_idx = i == 1 and (#buffers - 1) or (i - 1)
|
||||
local prev_buffer = buffers[prev_buf_idx]
|
||||
for _, win in ipairs(windows) do
|
||||
api.nvim_win_set_buf(win, prev_buffer)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Check if buffer still exists, to ensure the target buffer wasn't killed
|
||||
-- due to options like bufhidden=wipe.
|
||||
if api.nvim_buf_is_valid(bufnr) and bo[bufnr].buflisted then
|
||||
vim.cmd(string.format("%s %d", kill_command, bufnr))
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,28 @@
|
|||
local M = {}
|
||||
|
||||
local builtins = {
|
||||
"lvim.core.which-key",
|
||||
"lvim.core.gitsigns",
|
||||
"lvim.core.cmp",
|
||||
"lvim.core.dap",
|
||||
"lvim.core.terminal",
|
||||
"lvim.core.telescope",
|
||||
"lvim.core.treesitter",
|
||||
"lvim.core.nvimtree",
|
||||
"lvim.core.project",
|
||||
"lvim.core.bufferline",
|
||||
"lvim.core.autopairs",
|
||||
"lvim.core.comment",
|
||||
"lvim.core.notify",
|
||||
"lvim.core.lualine",
|
||||
"lvim.core.alpha",
|
||||
}
|
||||
|
||||
function M.config(config)
|
||||
for _, builtin_path in ipairs(builtins) do
|
||||
local builtin = require(builtin_path)
|
||||
builtin.config(config)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,318 @@
|
|||
local M = {}
|
||||
M.methods = {}
|
||||
|
||||
---checks if the character preceding the cursor is a space character
|
||||
---@return boolean true if it is a space character, false otherwise
|
||||
local check_backspace = function()
|
||||
local col = vim.fn.col "." - 1
|
||||
return col == 0 or vim.fn.getline("."):sub(col, col):match "%s"
|
||||
end
|
||||
M.methods.check_backspace = check_backspace
|
||||
|
||||
local function T(str)
|
||||
return vim.api.nvim_replace_termcodes(str, true, true, true)
|
||||
end
|
||||
|
||||
---wraps vim.fn.feedkeys while replacing key codes with escape codes
|
||||
---Ex: feedkeys("<CR>", "n") becomes feedkeys("^M", "n")
|
||||
---@param key string
|
||||
---@param mode string
|
||||
local function feedkeys(key, mode)
|
||||
vim.fn.feedkeys(T(key), mode)
|
||||
end
|
||||
M.methods.feedkeys = feedkeys
|
||||
|
||||
---checks if emmet_ls is available and active in the buffer
|
||||
---@return boolean true if available, false otherwise
|
||||
local is_emmet_active = function()
|
||||
local clients = vim.lsp.buf_get_clients()
|
||||
|
||||
for _, client in pairs(clients) do
|
||||
if client.name == "emmet_ls" then
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
M.methods.is_emmet_active = is_emmet_active
|
||||
|
||||
---when inside a snippet, seeks to the nearest luasnip field if possible, and checks if it is jumpable
|
||||
---@param dir number 1 for forward, -1 for backward; defaults to 1
|
||||
---@return boolean true if a jumpable luasnip field is found while inside a snippet
|
||||
local function jumpable(dir)
|
||||
local luasnip_ok, luasnip = pcall(require, "luasnip")
|
||||
if not luasnip_ok then
|
||||
return
|
||||
end
|
||||
|
||||
local win_get_cursor = vim.api.nvim_win_get_cursor
|
||||
local get_current_buf = vim.api.nvim_get_current_buf
|
||||
|
||||
local function inside_snippet()
|
||||
-- for outdated versions of luasnip
|
||||
if not luasnip.session.current_nodes then
|
||||
return false
|
||||
end
|
||||
|
||||
local node = luasnip.session.current_nodes[get_current_buf()]
|
||||
if not node then
|
||||
return false
|
||||
end
|
||||
|
||||
local snip_begin_pos, snip_end_pos = node.parent.snippet.mark:pos_begin_end()
|
||||
local pos = win_get_cursor(0)
|
||||
pos[1] = pos[1] - 1 -- LuaSnip is 0-based not 1-based like nvim for rows
|
||||
return pos[1] >= snip_begin_pos[1] and pos[1] <= snip_end_pos[1]
|
||||
end
|
||||
|
||||
---sets the current buffer's luasnip to the one nearest the cursor
|
||||
---@return boolean true if a node is found, false otherwise
|
||||
local function seek_luasnip_cursor_node()
|
||||
-- for outdated versions of luasnip
|
||||
if not luasnip.session.current_nodes then
|
||||
return false
|
||||
end
|
||||
|
||||
local pos = win_get_cursor(0)
|
||||
pos[1] = pos[1] - 1
|
||||
local node = luasnip.session.current_nodes[get_current_buf()]
|
||||
if not node then
|
||||
return false
|
||||
end
|
||||
|
||||
local snippet = node.parent.snippet
|
||||
local exit_node = snippet.insert_nodes[0]
|
||||
|
||||
-- exit early if we're past the exit node
|
||||
if exit_node then
|
||||
local exit_pos_end = exit_node.mark:pos_end()
|
||||
if (pos[1] > exit_pos_end[1]) or (pos[1] == exit_pos_end[1] and pos[2] > exit_pos_end[2]) then
|
||||
snippet:remove_from_jumplist()
|
||||
luasnip.session.current_nodes[get_current_buf()] = nil
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
node = snippet.inner_first:jump_into(1, true)
|
||||
while node ~= nil and node.next ~= nil and node ~= snippet do
|
||||
local n_next = node.next
|
||||
local next_pos = n_next and n_next.mark:pos_begin()
|
||||
local candidate = n_next ~= snippet and next_pos and (pos[1] < next_pos[1])
|
||||
or (pos[1] == next_pos[1] and pos[2] < next_pos[2])
|
||||
|
||||
-- Past unmarked exit node, exit early
|
||||
if n_next == nil or n_next == snippet.next then
|
||||
snippet:remove_from_jumplist()
|
||||
luasnip.session.current_nodes[get_current_buf()] = nil
|
||||
|
||||
return false
|
||||
end
|
||||
|
||||
if candidate then
|
||||
luasnip.session.current_nodes[get_current_buf()] = node
|
||||
return true
|
||||
end
|
||||
|
||||
local ok
|
||||
ok, node = pcall(node.jump_from, node, 1, true) -- no_move until last stop
|
||||
if not ok then
|
||||
snippet:remove_from_jumplist()
|
||||
luasnip.session.current_nodes[get_current_buf()] = nil
|
||||
|
||||
return false
|
||||
end
|
||||
end
|
||||
|
||||
-- No candidate, but have an exit node
|
||||
if exit_node then
|
||||
-- to jump to the exit node, seek to snippet
|
||||
luasnip.session.current_nodes[get_current_buf()] = snippet
|
||||
return true
|
||||
end
|
||||
|
||||
-- No exit node, exit from snippet
|
||||
snippet:remove_from_jumplist()
|
||||
luasnip.session.current_nodes[get_current_buf()] = nil
|
||||
return false
|
||||
end
|
||||
|
||||
if dir == -1 then
|
||||
return inside_snippet() and luasnip.jumpable(-1)
|
||||
else
|
||||
return inside_snippet() and seek_luasnip_cursor_node() and luasnip.jumpable()
|
||||
end
|
||||
end
|
||||
M.methods.jumpable = jumpable
|
||||
|
||||
M.config = function()
|
||||
local status_cmp_ok, cmp = pcall(require, "cmp")
|
||||
if not status_cmp_ok then
|
||||
return
|
||||
end
|
||||
local status_luasnip_ok, luasnip = pcall(require, "luasnip")
|
||||
if not status_luasnip_ok then
|
||||
return
|
||||
end
|
||||
|
||||
lvim.builtin.cmp = {
|
||||
confirm_opts = {
|
||||
behavior = cmp.ConfirmBehavior.Replace,
|
||||
select = false,
|
||||
},
|
||||
completion = {
|
||||
---@usage The minimum length of a word to complete on.
|
||||
keyword_length = 1,
|
||||
},
|
||||
experimental = {
|
||||
ghost_text = true,
|
||||
native_menu = false,
|
||||
},
|
||||
formatting = {
|
||||
fields = { "kind", "abbr", "menu" },
|
||||
max_width = 0,
|
||||
kind_icons = {
|
||||
Class = " ",
|
||||
Color = " ",
|
||||
Constant = "ﲀ ",
|
||||
Constructor = " ",
|
||||
Enum = "練",
|
||||
EnumMember = " ",
|
||||
Event = " ",
|
||||
Field = " ",
|
||||
File = "",
|
||||
Folder = " ",
|
||||
Function = " ",
|
||||
Interface = "ﰮ ",
|
||||
Keyword = " ",
|
||||
Method = " ",
|
||||
Module = " ",
|
||||
Operator = "",
|
||||
Property = " ",
|
||||
Reference = " ",
|
||||
Snippet = " ",
|
||||
Struct = " ",
|
||||
Text = " ",
|
||||
TypeParameter = " ",
|
||||
Unit = "塞",
|
||||
Value = " ",
|
||||
Variable = " ",
|
||||
},
|
||||
source_names = {
|
||||
nvim_lsp = "(LSP)",
|
||||
emoji = "(Emoji)",
|
||||
path = "(Path)",
|
||||
calc = "(Calc)",
|
||||
cmp_tabnine = "(Tabnine)",
|
||||
vsnip = "(Snippet)",
|
||||
luasnip = "(Snippet)",
|
||||
buffer = "(Buffer)",
|
||||
tmux = "(TMUX)",
|
||||
},
|
||||
duplicates = {
|
||||
buffer = 1,
|
||||
path = 1,
|
||||
nvim_lsp = 0,
|
||||
luasnip = 1,
|
||||
},
|
||||
duplicates_default = 0,
|
||||
format = function(entry, vim_item)
|
||||
local max_width = lvim.builtin.cmp.formatting.max_width
|
||||
if max_width ~= 0 and #vim_item.abbr > max_width then
|
||||
vim_item.abbr = string.sub(vim_item.abbr, 1, max_width - 1) .. "…"
|
||||
end
|
||||
if lvim.use_icons then
|
||||
vim_item.kind = lvim.builtin.cmp.formatting.kind_icons[vim_item.kind]
|
||||
end
|
||||
vim_item.menu = lvim.builtin.cmp.formatting.source_names[entry.source.name]
|
||||
vim_item.dup = lvim.builtin.cmp.formatting.duplicates[entry.source.name]
|
||||
or lvim.builtin.cmp.formatting.duplicates_default
|
||||
return vim_item
|
||||
end,
|
||||
},
|
||||
snippet = {
|
||||
expand = function(args)
|
||||
require("luasnip").lsp_expand(args.body)
|
||||
end,
|
||||
},
|
||||
window = {
|
||||
completion = cmp.config.window.bordered(),
|
||||
documentation = cmp.config.window.bordered(),
|
||||
},
|
||||
sources = {
|
||||
{ name = "nvim_lsp" },
|
||||
{ name = "path" },
|
||||
{ name = "luasnip" },
|
||||
{ name = "cmp_tabnine" },
|
||||
{ name = "nvim_lua" },
|
||||
{ name = "buffer" },
|
||||
{ name = "calc" },
|
||||
{ name = "emoji" },
|
||||
{ name = "treesitter" },
|
||||
{ name = "crates" },
|
||||
{ name = "tmux" },
|
||||
},
|
||||
mapping = cmp.mapping.preset.insert {
|
||||
["<C-k>"] = cmp.mapping.select_prev_item(),
|
||||
["<C-j>"] = cmp.mapping.select_next_item(),
|
||||
["<C-d>"] = cmp.mapping.scroll_docs(-4),
|
||||
["<C-f>"] = cmp.mapping.scroll_docs(4),
|
||||
-- TODO: potentially fix emmet nonsense
|
||||
["<Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_next_item()
|
||||
elseif luasnip.expandable() then
|
||||
luasnip.expand()
|
||||
elseif jumpable() then
|
||||
luasnip.jump(1)
|
||||
elseif check_backspace() then
|
||||
fallback()
|
||||
elseif is_emmet_active() then
|
||||
return vim.fn["cmp#complete"]()
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, {
|
||||
"i",
|
||||
"s",
|
||||
}),
|
||||
["<S-Tab>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() then
|
||||
cmp.select_prev_item()
|
||||
elseif jumpable(-1) then
|
||||
luasnip.jump(-1)
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end, {
|
||||
"i",
|
||||
"s",
|
||||
}),
|
||||
|
||||
["<C-Space>"] = cmp.mapping.complete(),
|
||||
["<C-e>"] = cmp.mapping.abort(),
|
||||
["<CR>"] = cmp.mapping(function(fallback)
|
||||
if cmp.visible() and cmp.confirm(lvim.builtin.cmp.confirm_opts) then
|
||||
if jumpable() then
|
||||
luasnip.jump(1)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
if jumpable() then
|
||||
if not luasnip.jump(1) then
|
||||
fallback()
|
||||
end
|
||||
else
|
||||
fallback()
|
||||
end
|
||||
end),
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
require("cmp").setup(lvim.builtin.cmp)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,78 @@
|
|||
local M = {}
|
||||
|
||||
vim.cmd [[
|
||||
function! QuickFixToggle()
|
||||
if empty(filter(getwininfo(), 'v:val.quickfix'))
|
||||
copen
|
||||
else
|
||||
cclose
|
||||
endif
|
||||
endfunction
|
||||
]]
|
||||
|
||||
M.defaults = {
|
||||
{
|
||||
name = "BufferKill",
|
||||
fn = function()
|
||||
require("lvim.core.bufferline").buf_kill "bd"
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimToggleFormatOnSave",
|
||||
fn = function()
|
||||
require("lvim.core.autocmds").toggle_format_on_save()
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimInfo",
|
||||
fn = function()
|
||||
require("lvim.core.info").toggle_popup(vim.bo.filetype)
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimCacheReset",
|
||||
fn = function()
|
||||
require("lvim.utils.hooks").reset_cache()
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimReload",
|
||||
fn = function()
|
||||
require("lvim.config"):reload()
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimUpdate",
|
||||
fn = function()
|
||||
require("lvim.bootstrap"):update()
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimSyncCorePlugins",
|
||||
fn = function()
|
||||
require("lvim.plugin-loader").sync_core_plugins()
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimChangelog",
|
||||
fn = function()
|
||||
require("lvim.core.telescope.custom-finders").view_lunarvim_changelog()
|
||||
end,
|
||||
},
|
||||
{
|
||||
name = "LvimVersion",
|
||||
fn = function()
|
||||
print(require("lvim.utils.git").get_lvim_version())
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
function M.load(collection)
|
||||
local common_opts = { force = true }
|
||||
for _, cmd in pairs(collection) do
|
||||
local opts = vim.tbl_deep_extend("force", common_opts, cmd.opts or {})
|
||||
vim.api.nvim_create_user_command(cmd.name, cmd.fn, opts)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,71 @@
|
|||
local M = {}
|
||||
|
||||
function M.config()
|
||||
local pre_hook = nil
|
||||
if lvim.builtin.treesitter.context_commentstring.enable then
|
||||
pre_hook = function(_ctx)
|
||||
return require("ts_context_commentstring.internal").calculate_commentstring()
|
||||
end
|
||||
end
|
||||
lvim.builtin.comment = {
|
||||
active = true,
|
||||
on_config_done = nil,
|
||||
---Add a space b/w comment and the line
|
||||
---@type boolean
|
||||
padding = true,
|
||||
|
||||
---Lines to be ignored while comment/uncomment.
|
||||
---Could be a regex string or a function that returns a regex string.
|
||||
---Example: Use '^$' to ignore empty lines
|
||||
---@type string|function
|
||||
ignore = "^$",
|
||||
|
||||
---Whether to create basic (operator-pending) and extra mappings for NORMAL/VISUAL mode
|
||||
---@type table
|
||||
mappings = {
|
||||
---operator-pending mapping
|
||||
---Includes `gcc`, `gcb`, `gc[count]{motion}` and `gb[count]{motion}`
|
||||
basic = true,
|
||||
---extended mapping
|
||||
---Includes `g>`, `g<`, `g>[count]{motion}` and `g<[count]{motion}`
|
||||
extra = false,
|
||||
},
|
||||
|
||||
---LHS of line and block comment toggle mapping in NORMAL/VISUAL mode
|
||||
---@type table
|
||||
toggler = {
|
||||
---line-comment toggle
|
||||
line = "gcc",
|
||||
---block-comment toggle
|
||||
block = "gbc",
|
||||
},
|
||||
|
||||
---LHS of line and block comment operator-mode mapping in NORMAL/VISUAL mode
|
||||
---@type table
|
||||
opleader = {
|
||||
---line-comment opfunc mapping
|
||||
line = "gc",
|
||||
---block-comment opfunc mapping
|
||||
block = "gb",
|
||||
},
|
||||
|
||||
---Pre-hook, called before commenting the line
|
||||
---@type function|nil
|
||||
pre_hook = pre_hook,
|
||||
|
||||
---Post-hook, called after commenting is done
|
||||
---@type function|nil
|
||||
post_hook = nil,
|
||||
}
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
local nvim_comment = require "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
|
|
@ -0,0 +1,78 @@
|
|||
local M = {}
|
||||
|
||||
M.config = function()
|
||||
lvim.builtin.dap = {
|
||||
active = false,
|
||||
on_config_done = nil,
|
||||
breakpoint = {
|
||||
text = "",
|
||||
texthl = "LspDiagnosticsSignError",
|
||||
linehl = "",
|
||||
numhl = "",
|
||||
},
|
||||
breakpoint_rejected = {
|
||||
text = "",
|
||||
texthl = "LspDiagnosticsSignHint",
|
||||
linehl = "",
|
||||
numhl = "",
|
||||
},
|
||||
stopped = {
|
||||
text = "",
|
||||
texthl = "LspDiagnosticsSignInformation",
|
||||
linehl = "DiagnosticUnderlineInfo",
|
||||
numhl = "LspDiagnosticsSignInformation",
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
local dap = require "dap"
|
||||
|
||||
if lvim.use_icons then
|
||||
vim.fn.sign_define("DapBreakpoint", lvim.builtin.dap.breakpoint)
|
||||
vim.fn.sign_define("DapBreakpointRejected", lvim.builtin.dap.breakpoint_rejected)
|
||||
vim.fn.sign_define("DapStopped", lvim.builtin.dap.stopped)
|
||||
end
|
||||
|
||||
dap.defaults.fallback.terminal_win_cmd = "50vsplit new"
|
||||
|
||||
lvim.builtin.which_key.mappings["d"] = {
|
||||
name = "Debug",
|
||||
t = { "<cmd>lua require'dap'.toggle_breakpoint()<cr>", "Toggle Breakpoint" },
|
||||
b = { "<cmd>lua require'dap'.step_back()<cr>", "Step Back" },
|
||||
c = { "<cmd>lua require'dap'.continue()<cr>", "Continue" },
|
||||
C = { "<cmd>lua require'dap'.run_to_cursor()<cr>", "Run To Cursor" },
|
||||
d = { "<cmd>lua require'dap'.disconnect()<cr>", "Disconnect" },
|
||||
g = { "<cmd>lua require'dap'.session()<cr>", "Get Session" },
|
||||
i = { "<cmd>lua require'dap'.step_into()<cr>", "Step Into" },
|
||||
o = { "<cmd>lua require'dap'.step_over()<cr>", "Step Over" },
|
||||
u = { "<cmd>lua require'dap'.step_out()<cr>", "Step Out" },
|
||||
p = { "<cmd>lua require'dap'.pause()<cr>", "Pause" },
|
||||
r = { "<cmd>lua require'dap'.repl.toggle()<cr>", "Toggle Repl" },
|
||||
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
|
||||
|
||||
-- M.dap = function()
|
||||
-- if lvim.plugin.dap.active then
|
||||
-- local dap_install = require "dap-install"
|
||||
-- dap_install.config("python_dbg", {})
|
||||
-- end
|
||||
-- end
|
||||
--
|
||||
-- M.dap = function()
|
||||
-- -- gem install readapt ruby-debug-ide
|
||||
-- if lvim.plugin.dap.active then
|
||||
-- local dap_install = require "dap-install"
|
||||
-- dap_install.config("ruby_vsc_dbg", {})
|
||||
-- end
|
||||
-- end
|
||||
|
||||
return M
|
|
@ -0,0 +1,90 @@
|
|||
local M = {}
|
||||
|
||||
M.config = function()
|
||||
lvim.builtin.gitsigns = {
|
||||
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",
|
||||
},
|
||||
},
|
||||
numhl = false,
|
||||
linehl = false,
|
||||
keymaps = {
|
||||
-- Default keymap options
|
||||
noremap = true,
|
||||
buffer = true,
|
||||
},
|
||||
signcolumn = true,
|
||||
word_diff = false,
|
||||
attach_to_untracked = true,
|
||||
current_line_blame = false, -- Toggle with `:Gitsigns toggle_current_line_blame`
|
||||
current_line_blame_opts = {
|
||||
virt_text = true,
|
||||
virt_text_pos = "eol", -- 'eol' | 'overlay' | 'right_align'
|
||||
delay = 1000,
|
||||
ignore_whitespace = false,
|
||||
},
|
||||
current_line_blame_formatter_opts = {
|
||||
relative_time = false,
|
||||
},
|
||||
max_file_length = 40000,
|
||||
preview_config = {
|
||||
-- Options passed to nvim_open_win
|
||||
border = "rounded",
|
||||
style = "minimal",
|
||||
relative = "cursor",
|
||||
row = 0,
|
||||
col = 1,
|
||||
},
|
||||
watch_gitdir = {
|
||||
interval = 1000,
|
||||
follow_files = true,
|
||||
},
|
||||
sign_priority = 6,
|
||||
update_debounce = 200,
|
||||
status_formatter = nil, -- Use default
|
||||
yadm = { enable = false },
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
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
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,222 @@
|
|||
local M = {
|
||||
banner = {
|
||||
"",
|
||||
[[ __ _ ___ ]],
|
||||
[[ / / __ ______ ____ _____| | / (_)___ ___ ]],
|
||||
[[ / / / / / / __ \/ __ `/ ___/ | / / / __ `__ \]],
|
||||
[[ / /___/ /_/ / / / / /_/ / / | |/ / / / / / / /]],
|
||||
[[/_____/\__,_/_/ /_/\__,_/_/ |___/_/_/ /_/ /_/ ]],
|
||||
},
|
||||
}
|
||||
|
||||
local fmt = string.format
|
||||
local text = require "lvim.interface.text"
|
||||
local lsp_utils = require "lvim.lsp.utils"
|
||||
|
||||
local function str_list(list)
|
||||
return #list == 1 and list[1] or fmt("[%s]", table.concat(list, ", "))
|
||||
end
|
||||
|
||||
local function make_formatters_info(ft)
|
||||
local null_formatters = require "lvim.lsp.null-ls.formatters"
|
||||
local registered_formatters = null_formatters.list_registered(ft)
|
||||
local supported_formatters = null_formatters.list_supported(ft)
|
||||
local section = {
|
||||
"Formatters info",
|
||||
fmt(
|
||||
"* Active: %s%s",
|
||||
table.concat(registered_formatters, " , "),
|
||||
vim.tbl_count(registered_formatters) > 0 and " " or ""
|
||||
),
|
||||
fmt("* Supported: %s", str_list(supported_formatters)),
|
||||
}
|
||||
|
||||
return section
|
||||
end
|
||||
|
||||
local function make_code_actions_info(ft)
|
||||
local null_actions = require "lvim.lsp.null-ls.code_actions"
|
||||
local registered_actions = null_actions.list_registered(ft)
|
||||
local section = {
|
||||
"Code actions info",
|
||||
fmt(
|
||||
"* Active: %s%s",
|
||||
table.concat(registered_actions, " , "),
|
||||
vim.tbl_count(registered_actions) > 0 and " " or ""
|
||||
),
|
||||
}
|
||||
|
||||
return section
|
||||
end
|
||||
|
||||
local function make_linters_info(ft)
|
||||
local null_linters = require "lvim.lsp.null-ls.linters"
|
||||
local supported_linters = null_linters.list_supported(ft)
|
||||
local registered_linters = null_linters.list_registered(ft)
|
||||
local section = {
|
||||
"Linters info",
|
||||
fmt(
|
||||
"* Active: %s%s",
|
||||
table.concat(registered_linters, " , "),
|
||||
vim.tbl_count(registered_linters) > 0 and " " or ""
|
||||
),
|
||||
fmt("* Supported: %s", str_list(supported_linters)),
|
||||
}
|
||||
|
||||
return section
|
||||
end
|
||||
|
||||
local function tbl_set_highlight(terms, highlight_group)
|
||||
for _, v in pairs(terms) do
|
||||
vim.cmd('let m=matchadd("' .. highlight_group .. '", "' .. v .. "[ ,│']\")")
|
||||
vim.cmd('let m=matchadd("' .. highlight_group .. '", ", ' .. v .. '")')
|
||||
end
|
||||
end
|
||||
|
||||
local function make_client_info(client)
|
||||
if client.name == "null-ls" then
|
||||
return
|
||||
end
|
||||
local client_enabled_caps = lsp_utils.get_client_capabilities(client.id)
|
||||
local name = client.name
|
||||
local id = client.id
|
||||
local filetypes = lsp_utils.get_supported_filetypes(name)
|
||||
local attached_buffers_list = str_list(vim.lsp.get_buffers_by_client_id(client.id))
|
||||
local client_info = {
|
||||
fmt("* name: %s", name),
|
||||
fmt("* id: %s", tostring(id)),
|
||||
fmt("* supported filetype(s): %s", str_list(filetypes)),
|
||||
fmt("* attached buffers: %s", tostring(attached_buffers_list)),
|
||||
fmt("* root_dir pattern: %s", tostring(attached_buffers_list)),
|
||||
}
|
||||
if not vim.tbl_isempty(client_enabled_caps) then
|
||||
local caps_text = "* capabilities: "
|
||||
local caps_text_len = caps_text:len()
|
||||
local enabled_caps = text.format_table(client_enabled_caps, 3, " | ")
|
||||
enabled_caps = text.shift_right(enabled_caps, caps_text_len)
|
||||
enabled_caps[1] = fmt("%s%s", caps_text, enabled_caps[1]:sub(caps_text_len + 1))
|
||||
vim.list_extend(client_info, enabled_caps)
|
||||
end
|
||||
|
||||
return client_info
|
||||
end
|
||||
|
||||
local function make_auto_lsp_info(ft)
|
||||
local skipped_filetypes = lvim.lsp.automatic_configuration.skipped_filetypes
|
||||
local skipped_servers = lvim.lsp.automatic_configuration.skipped_servers
|
||||
local info_lines = { "Automatic LSP info" }
|
||||
|
||||
if vim.tbl_contains(skipped_filetypes, ft) then
|
||||
vim.list_extend(info_lines, { "* Status: disabled for " .. ft })
|
||||
return info_lines
|
||||
end
|
||||
|
||||
local available = lsp_utils.get_supported_servers_per_filetype(ft)
|
||||
local skipped = vim.tbl_filter(function(name)
|
||||
return vim.tbl_contains(available, name)
|
||||
end, skipped_servers)
|
||||
|
||||
if #skipped == 0 then
|
||||
return { "" }
|
||||
end
|
||||
|
||||
vim.list_extend(info_lines, { fmt("* Skipped servers: %s", str_list(skipped)) })
|
||||
|
||||
return info_lines
|
||||
end
|
||||
|
||||
function M.toggle_popup(ft)
|
||||
local clients = vim.lsp.get_active_clients()
|
||||
local client_names = {}
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local ts_active_buffers = vim.tbl_keys(vim.treesitter.highlighter.active)
|
||||
local is_treesitter_active = function()
|
||||
local status = "inactive"
|
||||
if vim.tbl_contains(ts_active_buffers, bufnr) then
|
||||
status = "active"
|
||||
end
|
||||
return status
|
||||
end
|
||||
local header = {
|
||||
"Buffer info",
|
||||
fmt("* filetype: %s", ft),
|
||||
fmt("* bufnr: %s", bufnr),
|
||||
fmt("* treesitter status: %s", is_treesitter_active()),
|
||||
}
|
||||
|
||||
local lsp_info = {
|
||||
"Active client(s)",
|
||||
}
|
||||
|
||||
for _, client in pairs(clients) do
|
||||
local client_info = make_client_info(client)
|
||||
if client_info then
|
||||
vim.list_extend(lsp_info, client_info)
|
||||
end
|
||||
table.insert(client_names, client.name)
|
||||
end
|
||||
|
||||
local auto_lsp_info = make_auto_lsp_info(ft)
|
||||
|
||||
local formatters_info = make_formatters_info(ft)
|
||||
|
||||
local linters_info = make_linters_info(ft)
|
||||
|
||||
local code_actions_info = make_code_actions_info(ft)
|
||||
|
||||
local content_provider = function(popup)
|
||||
local content = {}
|
||||
|
||||
for _, section in ipairs {
|
||||
M.banner,
|
||||
{ "" },
|
||||
{ "" },
|
||||
header,
|
||||
{ "" },
|
||||
lsp_info,
|
||||
{ "" },
|
||||
auto_lsp_info,
|
||||
{ "" },
|
||||
formatters_info,
|
||||
{ "" },
|
||||
linters_info,
|
||||
{ "" },
|
||||
code_actions_info,
|
||||
} do
|
||||
vim.list_extend(content, section)
|
||||
end
|
||||
|
||||
return text.align_left(popup, content, 0.5)
|
||||
end
|
||||
|
||||
local function set_syntax_hl()
|
||||
vim.cmd [[highlight LvimInfoIdentifier gui=bold]]
|
||||
vim.cmd [[highlight link LvimInfoHeader Type]]
|
||||
vim.fn.matchadd("LvimInfoHeader", "Buffer info")
|
||||
vim.fn.matchadd("LvimInfoHeader", "Active client(s)")
|
||||
vim.fn.matchadd("LvimInfoHeader", fmt("Overridden %s server(s)", ft))
|
||||
vim.fn.matchadd("LvimInfoHeader", "Formatters info")
|
||||
vim.fn.matchadd("LvimInfoHeader", "Linters info")
|
||||
vim.fn.matchadd("LvimInfoHeader", "Code actions info")
|
||||
vim.fn.matchadd("LvimInfoHeader", "Automatic LSP info")
|
||||
vim.fn.matchadd("LvimInfoIdentifier", " " .. ft .. "$")
|
||||
vim.fn.matchadd("string", "true")
|
||||
vim.fn.matchadd("string", "active")
|
||||
vim.fn.matchadd("string", "")
|
||||
vim.fn.matchadd("boolean", "inactive")
|
||||
vim.fn.matchadd("error", "false")
|
||||
tbl_set_highlight(require("lvim.lsp.null-ls.formatters").list_registered(ft), "LvimInfoIdentifier")
|
||||
tbl_set_highlight(require("lvim.lsp.null-ls.linters").list_registered(ft), "LvimInfoIdentifier")
|
||||
tbl_set_highlight(require("lvim.lsp.null-ls.code_actions").list_registered(ft), "LvimInfoIdentifier")
|
||||
end
|
||||
|
||||
local Popup = require("lvim.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
|
|
@ -0,0 +1,207 @@
|
|||
local Log = {}
|
||||
|
||||
Log.levels = {
|
||||
TRACE = 1,
|
||||
DEBUG = 2,
|
||||
INFO = 3,
|
||||
WARN = 4,
|
||||
ERROR = 5,
|
||||
}
|
||||
vim.tbl_add_reverse_lookup(Log.levels)
|
||||
|
||||
local notify_opts = {}
|
||||
|
||||
function Log:set_level(level)
|
||||
-- package.loaded["lvim.core.log"] = nil
|
||||
local log_level = Log.levels[level:upper()]
|
||||
local status_ok, logger = pcall(require("structlog").get_logger, "lvim")
|
||||
if status_ok then
|
||||
for _, s in ipairs(logger.sinks) do
|
||||
s.level = log_level
|
||||
end
|
||||
end
|
||||
|
||||
package.loaded["packer.log"] = nil
|
||||
require("packer.log").new { level = lvim.log.level }
|
||||
end
|
||||
|
||||
function Log:init()
|
||||
local status_ok, structlog = pcall(require, "structlog")
|
||||
if not status_ok then
|
||||
return nil
|
||||
end
|
||||
|
||||
local log_level = Log.levels[(lvim.log.level):upper() or "WARN"]
|
||||
local lvim_log = {
|
||||
lvim = {
|
||||
sinks = {
|
||||
structlog.sinks.Console(log_level, {
|
||||
async = false,
|
||||
processors = {
|
||||
structlog.processors.Namer(),
|
||||
structlog.processors.StackWriter({ "line", "file" }, { max_parents = 0, stack_level = 2 }),
|
||||
structlog.processors.Timestamper "%H:%M:%S",
|
||||
},
|
||||
formatter = structlog.formatters.FormatColorizer( --
|
||||
"%s [%-5s] %s: %-30s",
|
||||
{ "timestamp", "level", "logger_name", "msg" },
|
||||
{ level = structlog.formatters.FormatColorizer.color_level() }
|
||||
),
|
||||
}),
|
||||
structlog.sinks.File(log_level, self:get_path(), {
|
||||
processors = {
|
||||
structlog.processors.Namer(),
|
||||
structlog.processors.StackWriter({ "line", "file" }, { max_parents = 3, stack_level = 2 }),
|
||||
structlog.processors.Timestamper "%F %H:%M:%S",
|
||||
},
|
||||
formatter = structlog.formatters.Format( --
|
||||
"%s [%-5s] %s: %-30s",
|
||||
{ "timestamp", "level", "logger_name", "msg" }
|
||||
),
|
||||
}),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
structlog.configure(lvim_log)
|
||||
local logger = structlog.get_logger "lvim"
|
||||
|
||||
-- Overwrite `vim.notify` to use the logger
|
||||
if lvim.log.override_notify then
|
||||
vim.notify = function(msg, vim_log_level, opts)
|
||||
notify_opts = opts or {}
|
||||
|
||||
-- vim_log_level can be omitted
|
||||
if vim_log_level == nil then
|
||||
vim_log_level = Log.levels["INFO"]
|
||||
elseif type(vim_log_level) == "string" then
|
||||
vim_log_level = Log.levels[(vim_log_level):upper()] or Log.levels["INFO"]
|
||||
else
|
||||
-- https://github.com/neovim/neovim/blob/685cf398130c61c158401b992a1893c2405cd7d2/runtime/lua/vim/lsp/log.lua#L5
|
||||
vim_log_level = vim_log_level + 1
|
||||
end
|
||||
|
||||
logger:log(vim_log_level, msg)
|
||||
end
|
||||
end
|
||||
|
||||
return logger
|
||||
end
|
||||
|
||||
--- Configure the sink in charge of logging notifications
|
||||
---@param notif_handle table The implementation used by the sink for displaying the notifications
|
||||
function Log:configure_notifications(notif_handle)
|
||||
local status_ok, structlog = pcall(require, "structlog")
|
||||
if not status_ok then
|
||||
return
|
||||
end
|
||||
|
||||
local default_namer = function(logger, entry)
|
||||
entry["title"] = logger.name
|
||||
return entry
|
||||
end
|
||||
|
||||
local notify_opts_injecter = function(_, entry)
|
||||
for key, value in pairs(notify_opts) do
|
||||
entry[key] = value
|
||||
end
|
||||
notify_opts = {}
|
||||
return entry
|
||||
end
|
||||
|
||||
local sink = structlog.sinks.NvimNotify(Log.levels.INFO, {
|
||||
processors = {
|
||||
default_namer,
|
||||
notify_opts_injecter,
|
||||
},
|
||||
formatter = structlog.formatters.Format( --
|
||||
"%s",
|
||||
{ "msg" },
|
||||
{ blacklist_all = true }
|
||||
),
|
||||
-- This should probably not be hard-coded
|
||||
params_map = {
|
||||
icon = "icon",
|
||||
keep = "keep",
|
||||
on_open = "on_open",
|
||||
on_close = "on_close",
|
||||
timeout = "timeout",
|
||||
title = "title",
|
||||
},
|
||||
impl = notif_handle,
|
||||
})
|
||||
|
||||
table.insert(self.__handle.sinks, sink)
|
||||
end
|
||||
|
||||
--- Adds a log entry using Plenary.log
|
||||
---@param msg any
|
||||
---@param level string [same as vim.log.log_levels]
|
||||
function Log:add_entry(level, msg, event)
|
||||
local logger = self:get_logger()
|
||||
if not logger then
|
||||
return
|
||||
end
|
||||
logger:log(level, vim.inspect(msg), event)
|
||||
end
|
||||
|
||||
---Retrieves the handle of the logger object
|
||||
---@return table|nil logger handle if found
|
||||
function Log:get_logger()
|
||||
if self.__handle then
|
||||
return self.__handle
|
||||
end
|
||||
|
||||
local logger = self:init()
|
||||
if not logger then
|
||||
return
|
||||
end
|
||||
|
||||
self.__handle = logger
|
||||
return logger
|
||||
end
|
||||
|
||||
---Retrieves the path of the logfile
|
||||
---@return string path of the logfile
|
||||
function Log:get_path()
|
||||
return string.format("%s/%s.log", get_cache_dir(), "lvim")
|
||||
end
|
||||
|
||||
---Add a log entry at TRACE level
|
||||
---@param msg any
|
||||
---@param event any
|
||||
function Log:trace(msg, event)
|
||||
self:add_entry(self.levels.TRACE, msg, event)
|
||||
end
|
||||
|
||||
---Add a log entry at DEBUG level
|
||||
---@param msg any
|
||||
---@param event any
|
||||
function Log:debug(msg, event)
|
||||
self:add_entry(self.levels.DEBUG, msg, event)
|
||||
end
|
||||
|
||||
---Add a log entry at INFO level
|
||||
---@param msg any
|
||||
---@param event any
|
||||
function Log:info(msg, event)
|
||||
self:add_entry(self.levels.INFO, msg, event)
|
||||
end
|
||||
|
||||
---Add a log entry at WARN level
|
||||
---@param msg any
|
||||
---@param event any
|
||||
function Log:warn(msg, event)
|
||||
self:add_entry(self.levels.WARN, msg, event)
|
||||
end
|
||||
|
||||
---Add a log entry at ERROR level
|
||||
---@param msg any
|
||||
---@param event any
|
||||
function Log:error(msg, event)
|
||||
self:add_entry(self.levels.ERROR, msg, event)
|
||||
end
|
||||
|
||||
setmetatable({}, Log)
|
||||
|
||||
return Log
|
|
@ -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
|
|
@ -0,0 +1,155 @@
|
|||
local conditions = require "lvim.core.lualine.conditions"
|
||||
local colors = require "lvim.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,
|
||||
padding = { left = 0, right = 0 },
|
||||
color = {},
|
||||
cond = nil,
|
||||
},
|
||||
branch = {
|
||||
"b:gitsigns_head",
|
||||
icon = " ",
|
||||
color = { gui = "bold" },
|
||||
cond = conditions.hide_in_width,
|
||||
},
|
||||
filename = {
|
||||
"filename",
|
||||
color = {},
|
||||
cond = nil,
|
||||
},
|
||||
diff = {
|
||||
"diff",
|
||||
source = diff_source,
|
||||
symbols = { added = " ", modified = " ", removed = " " },
|
||||
diff_color = {
|
||||
added = { fg = colors.green },
|
||||
modified = { fg = colors.yellow },
|
||||
removed = { fg = colors.red },
|
||||
},
|
||||
cond = nil,
|
||||
},
|
||||
python_env = {
|
||||
function()
|
||||
local utils = require "lvim.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 },
|
||||
cond = conditions.hide_in_width,
|
||||
},
|
||||
diagnostics = {
|
||||
"diagnostics",
|
||||
sources = { "nvim_diagnostic" },
|
||||
symbols = { error = " ", warn = " ", info = " ", hint = " " },
|
||||
cond = conditions.hide_in_width,
|
||||
},
|
||||
treesitter = {
|
||||
function()
|
||||
local b = vim.api.nvim_get_current_buf()
|
||||
if next(vim.treesitter.highlighter.active[b]) then
|
||||
return ""
|
||||
end
|
||||
return ""
|
||||
end,
|
||||
color = { fg = colors.green },
|
||||
cond = conditions.hide_in_width,
|
||||
},
|
||||
lsp = {
|
||||
function(msg)
|
||||
msg = msg or "LS Inactive"
|
||||
local buf_clients = vim.lsp.buf_get_clients()
|
||||
if next(buf_clients) == nil then
|
||||
-- TODO: clean up this if statement
|
||||
if type(msg) == "boolean" or #msg == 0 then
|
||||
return "LS Inactive"
|
||||
end
|
||||
return msg
|
||||
end
|
||||
local buf_ft = vim.bo.filetype
|
||||
local buf_client_names = {}
|
||||
|
||||
-- add client
|
||||
for _, client in pairs(buf_clients) do
|
||||
if client.name ~= "null-ls" then
|
||||
table.insert(buf_client_names, client.name)
|
||||
end
|
||||
end
|
||||
|
||||
-- add formatter
|
||||
local formatters = require "lvim.lsp.null-ls.formatters"
|
||||
local supported_formatters = formatters.list_registered(buf_ft)
|
||||
vim.list_extend(buf_client_names, supported_formatters)
|
||||
|
||||
-- add linter
|
||||
local linters = require "lvim.lsp.null-ls.linters"
|
||||
local supported_linters = linters.list_registered(buf_ft)
|
||||
vim.list_extend(buf_client_names, supported_linters)
|
||||
|
||||
local unique_client_names = vim.fn.uniq(buf_client_names)
|
||||
return "[" .. table.concat(unique_client_names, ", ") .. "]"
|
||||
end,
|
||||
color = { gui = "bold" },
|
||||
cond = conditions.hide_in_width,
|
||||
},
|
||||
location = { "location", cond = conditions.hide_in_width, color = {} },
|
||||
progress = { "progress", cond = conditions.hide_in_width, color = {} },
|
||||
spaces = {
|
||||
function()
|
||||
if not vim.api.nvim_buf_get_option(0, "expandtab") then
|
||||
return "Tab size: " .. vim.api.nvim_buf_get_option(0, "tabstop") .. " "
|
||||
end
|
||||
local size = vim.api.nvim_buf_get_option(0, "shiftwidth")
|
||||
if size == 0 then
|
||||
size = vim.api.nvim_buf_get_option(0, "tabstop")
|
||||
end
|
||||
return "Spaces: " .. size .. " "
|
||||
end,
|
||||
cond = conditions.hide_in_width,
|
||||
color = {},
|
||||
},
|
||||
encoding = {
|
||||
"o:encoding",
|
||||
fmt = string.upper,
|
||||
color = {},
|
||||
cond = conditions.hide_in_width,
|
||||
},
|
||||
filetype = { "filetype", cond = conditions.hide_in_width },
|
||||
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,
|
||||
padding = { left = 0, right = 0 },
|
||||
color = { fg = colors.yellow, bg = colors.bg },
|
||||
cond = nil,
|
||||
},
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
local window_width_limit = 70
|
||||
|
||||
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
|
|
@ -0,0 +1,54 @@
|
|||
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,
|
||||
globalstatus = false,
|
||||
},
|
||||
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()
|
||||
-- avoid running in headless mode since it's harder to detect failures
|
||||
if #vim.api.nvim_list_uis() == 0 then
|
||||
local Log = require "lvim.core.log"
|
||||
Log:debug "headless mode detected, skipping running setup for lualine"
|
||||
return
|
||||
end
|
||||
|
||||
require("lvim.core.lualine.styles").update()
|
||||
|
||||
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
|
|
@ -0,0 +1,137 @@
|
|||
local M = {}
|
||||
local components = require "lvim.core.lualine.components"
|
||||
|
||||
local styles = {
|
||||
lvim = nil,
|
||||
default = nil,
|
||||
none = nil,
|
||||
}
|
||||
|
||||
styles.none = {
|
||||
style = "none",
|
||||
options = {
|
||||
theme = "auto",
|
||||
icons_enabled = lvim.use_icons,
|
||||
component_separators = { left = "", right = "" },
|
||||
section_separators = { left = "", right = "" },
|
||||
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 = {
|
||||
theme = "auto",
|
||||
icons_enabled = lvim.use_icons,
|
||||
component_separators = { left = "", right = "" },
|
||||
section_separators = { left = "", right = "" },
|
||||
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 = {
|
||||
theme = "auto",
|
||||
icons_enabled = lvim.use_icons,
|
||||
component_separators = { left = "", right = "" },
|
||||
section_separators = { left = "", right = "" },
|
||||
disabled_filetypes = { "alpha", "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 "lvim.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)
|
||||
|
||||
lvim.builtin.lualine = vim.tbl_deep_extend("keep", lvim.builtin.lualine, style)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,14 @@
|
|||
local M = {}
|
||||
|
||||
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
|
|
@ -0,0 +1,68 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local defaults = {
|
||||
active = false,
|
||||
on_config_done = nil,
|
||||
opts = {
|
||||
---@usage Animation style one of { "fade", "slide", "fade_in_slide_out", "static" }
|
||||
stages = "slide",
|
||||
|
||||
---@usage Function called when a new window is opened, use for changing win settings/config
|
||||
on_open = nil,
|
||||
|
||||
---@usage Function called when a window is closed
|
||||
on_close = nil,
|
||||
|
||||
---@usage timeout for notifications in ms, default 5000
|
||||
timeout = 5000,
|
||||
|
||||
-- Render function for notifications. See notify-render()
|
||||
render = "default",
|
||||
|
||||
---@usage highlight behind the window for stages that change opacity
|
||||
background_colour = "Normal",
|
||||
|
||||
---@usage minimum width for notification windows
|
||||
minimum_width = 50,
|
||||
|
||||
---@usage Icons for the different levels
|
||||
icons = {
|
||||
ERROR = "",
|
||||
WARN = "",
|
||||
INFO = "",
|
||||
DEBUG = "",
|
||||
TRACE = "✎",
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
function M.config()
|
||||
if not lvim.use_icons then
|
||||
defaults.opts.icons = {
|
||||
ERROR = "[ERROR]",
|
||||
WARN = "[WARNING]",
|
||||
INFO = "[INFo]",
|
||||
DEBUG = "[DEBUG]",
|
||||
TRACE = "[TRACE]",
|
||||
}
|
||||
end
|
||||
lvim.builtin.notify = vim.tbl_deep_extend("force", defaults, lvim.builtin.notify or {})
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
if #vim.api.nvim_list_uis() == 0 then
|
||||
-- no need to configure notifications in headless
|
||||
return
|
||||
end
|
||||
|
||||
local opts = lvim.builtin.notify and lvim.builtin.notify.opts or defaults
|
||||
local notify = require "notify"
|
||||
|
||||
notify.setup(opts)
|
||||
vim.notify = notify
|
||||
Log:configure_notifications(notify)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,212 @@
|
|||
local M = {}
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
function M.config()
|
||||
lvim.builtin.nvimtree = {
|
||||
active = true,
|
||||
on_config_done = nil,
|
||||
setup = {
|
||||
disable_netrw = true,
|
||||
hijack_netrw = true,
|
||||
open_on_setup = false,
|
||||
open_on_setup_file = false,
|
||||
sort_by = "name",
|
||||
ignore_buffer_on_setup = false,
|
||||
ignore_ft_on_setup = {
|
||||
"startify",
|
||||
"dashboard",
|
||||
"alpha",
|
||||
},
|
||||
auto_reload_on_write = true,
|
||||
hijack_unnamed_buffer_when_opening = false,
|
||||
hijack_directories = {
|
||||
enable = true,
|
||||
auto_open = true,
|
||||
},
|
||||
open_on_tab = false,
|
||||
hijack_cursor = false,
|
||||
update_cwd = false,
|
||||
diagnostics = {
|
||||
enable = lvim.use_icons,
|
||||
show_on_dirs = false,
|
||||
icons = {
|
||||
hint = "",
|
||||
info = "",
|
||||
warning = "",
|
||||
error = "",
|
||||
},
|
||||
},
|
||||
update_focused_file = {
|
||||
enable = true,
|
||||
update_cwd = true,
|
||||
ignore_list = {},
|
||||
},
|
||||
system_open = {
|
||||
cmd = nil,
|
||||
args = {},
|
||||
},
|
||||
git = {
|
||||
enable = true,
|
||||
ignore = false,
|
||||
timeout = 200,
|
||||
},
|
||||
view = {
|
||||
width = 30,
|
||||
height = 30,
|
||||
hide_root_folder = false,
|
||||
side = "left",
|
||||
preserve_window_proportions = false,
|
||||
mappings = {
|
||||
custom_only = false,
|
||||
list = {},
|
||||
},
|
||||
number = false,
|
||||
relativenumber = false,
|
||||
signcolumn = "yes",
|
||||
},
|
||||
renderer = {
|
||||
indent_markers = {
|
||||
enable = false,
|
||||
icons = {
|
||||
corner = "└ ",
|
||||
edge = "│ ",
|
||||
none = " ",
|
||||
},
|
||||
},
|
||||
icons = {
|
||||
webdev_colors = lvim.use_icons,
|
||||
show = {
|
||||
git = lvim.use_icons,
|
||||
folder = lvim.use_icons,
|
||||
file = lvim.use_icons,
|
||||
folder_arrow = lvim.use_icons,
|
||||
},
|
||||
glyphs = {
|
||||
default = "",
|
||||
symlink = "",
|
||||
git = {
|
||||
unstaged = "",
|
||||
staged = "S",
|
||||
unmerged = "",
|
||||
renamed = "➜",
|
||||
deleted = "",
|
||||
untracked = "U",
|
||||
ignored = "◌",
|
||||
},
|
||||
folder = {
|
||||
default = "",
|
||||
open = "",
|
||||
empty = "",
|
||||
empty_open = "",
|
||||
symlink = "",
|
||||
},
|
||||
},
|
||||
},
|
||||
highlight_git = true,
|
||||
root_folder_modifier = ":t",
|
||||
},
|
||||
filters = {
|
||||
dotfiles = false,
|
||||
custom = { "node_modules", "\\.cache" },
|
||||
exclude = {},
|
||||
},
|
||||
trash = {
|
||||
cmd = "trash",
|
||||
require_confirm = true,
|
||||
},
|
||||
log = {
|
||||
enable = false,
|
||||
truncate = false,
|
||||
types = {
|
||||
all = false,
|
||||
config = false,
|
||||
copy_paste = false,
|
||||
diagnostics = false,
|
||||
git = false,
|
||||
profile = false,
|
||||
},
|
||||
},
|
||||
actions = {
|
||||
use_system_clipboard = true,
|
||||
change_dir = {
|
||||
enable = true,
|
||||
global = false,
|
||||
restrict_above_cwd = false,
|
||||
},
|
||||
open_file = {
|
||||
quit_on_open = false,
|
||||
resize_window = false,
|
||||
window_picker = {
|
||||
enable = true,
|
||||
chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890",
|
||||
exclude = {
|
||||
filetype = { "notify", "packer", "qf", "diff", "fugitive", "fugitiveblame" },
|
||||
buftype = { "nofile", "terminal", "help" },
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
local status_ok, nvim_tree = pcall(require, "nvim-tree")
|
||||
if not status_ok then
|
||||
Log:error "Failed to load nvim-tree"
|
||||
return
|
||||
end
|
||||
|
||||
if lvim.builtin.nvimtree._setup_called then
|
||||
Log:debug "ignoring repeated setup call for nvim-tree, see kyazdani42/nvim-tree.lua#1308"
|
||||
return
|
||||
end
|
||||
|
||||
-- lvim.builtin.which_key.mappings["e"] = { "<cmd>NvimTreeToggle<CR>", "Explorer" }
|
||||
lvim.builtin.nvimtree._setup_called = true
|
||||
|
||||
-- Implicitly update nvim-tree when project module is active
|
||||
if lvim.builtin.project.active then
|
||||
lvim.builtin.nvimtree.setup.respect_buf_cwd = true
|
||||
lvim.builtin.nvimtree.setup.update_cwd = true
|
||||
lvim.builtin.nvimtree.setup.update_focused_file = { enable = true, update_cwd = true }
|
||||
end
|
||||
|
||||
local function telescope_find_files(_)
|
||||
require("lvim.core.nvimtree").start_telescope "find_files"
|
||||
end
|
||||
|
||||
local function telescope_live_grep(_)
|
||||
require("lvim.core.nvimtree").start_telescope "live_grep"
|
||||
end
|
||||
|
||||
-- Add useful keymaps
|
||||
if #lvim.builtin.nvimtree.setup.view.mappings.list == 0 then
|
||||
lvim.builtin.nvimtree.setup.view.mappings.list = {
|
||||
{ key = { "l", "<CR>", "o" }, action = "edit", mode = "n" },
|
||||
{ key = "h", action = "close_node" },
|
||||
{ key = "v", action = "vsplit" },
|
||||
{ key = "C", action = "cd" },
|
||||
{ key = "gtf", action = "telescope_find_files", action_cb = telescope_find_files },
|
||||
{ key = "gtg", action = "telescope_live_grep", action_cb = telescope_live_grep },
|
||||
}
|
||||
end
|
||||
|
||||
nvim_tree.setup(lvim.builtin.nvimtree.setup)
|
||||
|
||||
if lvim.builtin.nvimtree.on_config_done then
|
||||
lvim.builtin.nvimtree.on_config_done(nvim_tree)
|
||||
end
|
||||
end
|
||||
|
||||
function M.start_telescope(telescope_mode)
|
||||
local node = require("nvim-tree.lib").get_node_at_cursor()
|
||||
local abspath = node.link_to or node.absolute_path
|
||||
local is_folder = node.open ~= nil
|
||||
local basedir = is_folder and abspath or vim.fn.fnamemodify(abspath, ":h")
|
||||
require("telescope.builtin")[telescope_mode] {
|
||||
cwd = basedir,
|
||||
}
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,52 @@
|
|||
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" }, -- NOTE: lsp detection will get annoying with multiple langs in one project
|
||||
detection_methods = { "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 = get_cache_dir(),
|
||||
}
|
||||
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
|
|
@ -0,0 +1,150 @@
|
|||
local M = {}
|
||||
|
||||
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 recommended]
|
||||
active = true,
|
||||
on_config_done = nil,
|
||||
}
|
||||
|
||||
local ok, actions = pcall(require, "telescope.actions")
|
||||
if not ok then
|
||||
return
|
||||
end
|
||||
lvim.builtin.telescope = vim.tbl_extend("force", lvim.builtin.telescope, {
|
||||
defaults = {
|
||||
prompt_prefix = " ",
|
||||
selection_caret = " ",
|
||||
entry_prefix = " ",
|
||||
initial_mode = "insert",
|
||||
selection_strategy = "reset",
|
||||
sorting_strategy = "descending",
|
||||
layout_strategy = "horizontal",
|
||||
layout_config = {
|
||||
width = 0.75,
|
||||
preview_cutoff = 120,
|
||||
horizontal = {
|
||||
preview_width = function(_, cols, _)
|
||||
if cols < 120 then
|
||||
return math.floor(cols * 0.5)
|
||||
end
|
||||
return math.floor(cols * 0.6)
|
||||
end,
|
||||
mirror = false,
|
||||
},
|
||||
vertical = { mirror = false },
|
||||
},
|
||||
vimgrep_arguments = {
|
||||
"rg",
|
||||
"--color=never",
|
||||
"--no-heading",
|
||||
"--with-filename",
|
||||
"--line-number",
|
||||
"--column",
|
||||
"--smart-case",
|
||||
"--hidden",
|
||||
"--glob=!.git/",
|
||||
},
|
||||
mappings = {
|
||||
i = {
|
||||
["<C-n>"] = actions.move_selection_next,
|
||||
["<C-p>"] = actions.move_selection_previous,
|
||||
["<C-c>"] = actions.close,
|
||||
["<C-j>"] = actions.cycle_history_next,
|
||||
["<C-k>"] = actions.cycle_history_prev,
|
||||
["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
|
||||
["<CR>"] = actions.select_default,
|
||||
},
|
||||
n = {
|
||||
["<C-n>"] = actions.move_selection_next,
|
||||
["<C-p>"] = actions.move_selection_previous,
|
||||
["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
|
||||
},
|
||||
},
|
||||
file_ignore_patterns = {},
|
||||
path_display = { shorten = 5 },
|
||||
winblend = 0,
|
||||
border = {},
|
||||
borderchars = { "─", "│", "─", "│", "╭", "╮", "╯", "╰" },
|
||||
color_devicons = true,
|
||||
set_env = { ["COLORTERM"] = "truecolor" }, -- default = nil,
|
||||
},
|
||||
pickers = {
|
||||
find_files = {
|
||||
hidden = true,
|
||||
},
|
||||
live_grep = {
|
||||
--@usage don't include the filename in the search results
|
||||
only_sort_text = true,
|
||||
},
|
||||
},
|
||||
extensions = {
|
||||
fzf = {
|
||||
fuzzy = true, -- false will only do exact matching
|
||||
override_generic_sorter = true, -- override the generic sorter
|
||||
override_file_sorter = true, -- override the file sorter
|
||||
case_mode = "smart_case", -- or "ignore_case" or "respect_case"
|
||||
},
|
||||
},
|
||||
})
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
local previewers = require "telescope.previewers"
|
||||
local sorters = require "telescope.sorters"
|
||||
local actions = require "telescope.actions"
|
||||
|
||||
lvim.builtin.telescope = vim.tbl_extend("keep", {
|
||||
file_previewer = previewers.vim_buffer_cat.new,
|
||||
grep_previewer = previewers.vim_buffer_vimgrep.new,
|
||||
qflist_previewer = previewers.vim_buffer_qflist.new,
|
||||
file_sorter = sorters.get_fuzzy_file,
|
||||
generic_sorter = sorters.get_generic_fuzzy_sorter,
|
||||
---@usage Mappings are fully customizable. Many familiar mapping patterns are setup as defaults.
|
||||
mappings = {
|
||||
i = {
|
||||
["<C-n>"] = actions.move_selection_next,
|
||||
["<C-p>"] = actions.move_selection_previous,
|
||||
["<C-c>"] = actions.close,
|
||||
["<C-j>"] = actions.cycle_history_next,
|
||||
["<C-k>"] = actions.cycle_history_prev,
|
||||
["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
|
||||
["<CR>"] = actions.select_default + actions.center,
|
||||
},
|
||||
n = {
|
||||
["<C-n>"] = actions.move_selection_next,
|
||||
["<C-p>"] = actions.move_selection_previous,
|
||||
["<C-q>"] = actions.smart_send_to_qflist + actions.open_qflist,
|
||||
},
|
||||
},
|
||||
}, lvim.builtin.telescope)
|
||||
|
||||
local telescope = require "telescope"
|
||||
telescope.setup(lvim.builtin.telescope)
|
||||
|
||||
if lvim.builtin.project.active then
|
||||
pcall(function()
|
||||
require("telescope").load_extension "projects"
|
||||
end)
|
||||
end
|
||||
|
||||
if lvim.builtin.notify.active then
|
||||
pcall(function()
|
||||
require("telescope").load_extension "notify"
|
||||
end)
|
||||
end
|
||||
|
||||
if lvim.builtin.telescope.on_config_done then
|
||||
lvim.builtin.telescope.on_config_done(telescope)
|
||||
end
|
||||
|
||||
if lvim.builtin.telescope.extensions and lvim.builtin.telescope.extensions.fzf then
|
||||
pcall(function()
|
||||
require("telescope").load_extension "fzf"
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,97 @@
|
|||
local M = {}
|
||||
|
||||
local _, builtin = pcall(require, "telescope.builtin")
|
||||
local _, finders = pcall(require, "telescope.finders")
|
||||
local _, pickers = pcall(require, "telescope.pickers")
|
||||
local _, sorters = pcall(require, "telescope.sorters")
|
||||
local _, themes = pcall(require, "telescope.themes")
|
||||
local _, actions = pcall(require, "telescope.actions")
|
||||
local _, previewers = pcall(require, "telescope.previewers")
|
||||
local _, make_entry = pcall(require, "telescope.make_entry")
|
||||
|
||||
local utils = require "lvim.utils"
|
||||
|
||||
function M.find_lunarvim_files(opts)
|
||||
opts = opts or {}
|
||||
local theme_opts = themes.get_ivy {
|
||||
sorting_strategy = "ascending",
|
||||
layout_strategy = "bottom_pane",
|
||||
prompt_prefix = ">> ",
|
||||
prompt_title = "~ LunarVim files ~",
|
||||
cwd = get_runtime_dir(),
|
||||
search_dirs = { utils.join_paths(get_runtime_dir(), "lvim"), lvim.lsp.templates_dir },
|
||||
}
|
||||
opts = vim.tbl_deep_extend("force", theme_opts, opts)
|
||||
builtin.find_files(opts)
|
||||
end
|
||||
|
||||
function M.grep_lunarvim_files(opts)
|
||||
opts = opts or {}
|
||||
local theme_opts = themes.get_ivy {
|
||||
sorting_strategy = "ascending",
|
||||
layout_strategy = "bottom_pane",
|
||||
prompt_prefix = ">> ",
|
||||
prompt_title = "~ search LunarVim ~",
|
||||
cwd = get_runtime_dir(),
|
||||
search_dirs = { utils.join_paths(get_runtime_dir(), "lvim"), lvim.lsp.templates_dir },
|
||||
}
|
||||
opts = vim.tbl_deep_extend("force", theme_opts, opts)
|
||||
builtin.live_grep(opts)
|
||||
end
|
||||
|
||||
local copy_to_clipboard_action = function(prompt_bufnr)
|
||||
local _, action_state = pcall(require, "telescope.actions.state")
|
||||
local entry = action_state.get_selected_entry()
|
||||
local version = entry.value
|
||||
vim.fn.setreg("+", version)
|
||||
vim.fn.setreg('"', version)
|
||||
vim.notify("Copied " .. version .. " to clipboard", vim.log.levels.INFO)
|
||||
actions.close(prompt_bufnr)
|
||||
end
|
||||
|
||||
function M.view_lunarvim_changelog()
|
||||
local opts = themes.get_ivy {
|
||||
cwd = get_lvim_base_dir(),
|
||||
}
|
||||
opts.entry_maker = make_entry.gen_from_git_commits(opts)
|
||||
|
||||
pickers.new(opts, {
|
||||
prompt_title = "~ LunarVim Changelog ~",
|
||||
|
||||
finder = finders.new_oneshot_job(
|
||||
vim.tbl_flatten {
|
||||
"git",
|
||||
"log",
|
||||
"--pretty=oneline",
|
||||
"--abbrev-commit",
|
||||
},
|
||||
opts
|
||||
),
|
||||
previewer = {
|
||||
previewers.git_commit_diff_as_was.new(opts),
|
||||
},
|
||||
|
||||
--TODO: consider opening a diff view when pressing enter
|
||||
attach_mappings = function(_, map)
|
||||
map("i", "<enter>", copy_to_clipboard_action)
|
||||
map("n", "<enter>", copy_to_clipboard_action)
|
||||
map("i", "<esc>", actions._close)
|
||||
map("n", "<esc>", actions._close)
|
||||
map("n", "q", actions._close)
|
||||
return true
|
||||
end,
|
||||
sorter = sorters.generic_sorter,
|
||||
}):find()
|
||||
end
|
||||
|
||||
-- Smartly opens either git_files or find_files, depending on whether the working directory is
|
||||
-- contained in a Git repo.
|
||||
function M.find_project_files()
|
||||
local ok = pcall(builtin.git_files)
|
||||
|
||||
if not ok then
|
||||
builtin.find_files()
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,127 @@
|
|||
local M = {}
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
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-\>]],
|
||||
open_mapping = [[<c-t>]],
|
||||
hide_numbers = true, -- hide the number column in toggleterm buffers
|
||||
shade_filetypes = {},
|
||||
shade_terminals = true,
|
||||
shading_factor = 2, -- the degree by which to darken to terminal colour, default: 1 for dark backgrounds, 3 for light
|
||||
start_in_insert = true,
|
||||
insert_mappings = true, -- whether or not the open mapping applies in insert mode
|
||||
persist_size = false,
|
||||
-- direction = 'vertical' | 'horizontal' | 'window' | 'float',
|
||||
direction = "float",
|
||||
close_on_exit = true, -- close the terminal window when the process exits
|
||||
shell = vim.o.shell, -- change the default shell
|
||||
-- This field is only relevant if direction is set to 'float'
|
||||
float_opts = {
|
||||
-- The border key is *almost* the same as 'nvim_win_open'
|
||||
-- see :h nvim_win_open for details on borders however
|
||||
-- the 'curved' border is a custom border type
|
||||
-- not natively supported but implemented in this plugin.
|
||||
-- border = 'single' | 'double' | 'shadow' | 'curved' | ... other options supported by win open
|
||||
border = "curved",
|
||||
-- width = <value>,
|
||||
-- height = <value>,
|
||||
winblend = 0,
|
||||
highlights = {
|
||||
border = "Normal",
|
||||
background = "Normal",
|
||||
},
|
||||
},
|
||||
-- Add executables on the config.lua
|
||||
-- { exec, keymap, name}
|
||||
-- lvim.builtin.terminal.execs = {{}} to overwrite
|
||||
-- lvim.builtin.terminal.execs[#lvim.builtin.terminal.execs+1] = {"gdb", "tg", "GNU Debugger"}
|
||||
execs = {
|
||||
{ "lazygit", "<leader>gg", "LazyGit", "float" },
|
||||
{ "lazygit", "<c-\\><c-g>", "LazyGit", "float" },
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
local terminal = require "toggleterm"
|
||||
terminal.setup(lvim.builtin.terminal)
|
||||
|
||||
for i, exec in pairs(lvim.builtin.terminal.execs) do
|
||||
local opts = {
|
||||
cmd = exec[1],
|
||||
keymap = exec[2],
|
||||
label = exec[3],
|
||||
-- NOTE: unable to consistently bind id/count <= 9, see #2146
|
||||
count = i + 100,
|
||||
direction = exec[4] or lvim.builtin.terminal.direction,
|
||||
size = lvim.builtin.terminal.size,
|
||||
}
|
||||
|
||||
M.add_exec(opts)
|
||||
end
|
||||
|
||||
if lvim.builtin.terminal.on_config_done then
|
||||
lvim.builtin.terminal.on_config_done(terminal)
|
||||
end
|
||||
end
|
||||
|
||||
M.add_exec = function(opts)
|
||||
local binary = opts.cmd:match "(%S+)"
|
||||
if vim.fn.executable(binary) ~= 1 then
|
||||
Log:debug("Skipping configuring executable " .. binary .. ". Please make sure it is installed properly.")
|
||||
return
|
||||
end
|
||||
|
||||
local exec_func = string.format(
|
||||
"<cmd>lua require('lvim.core.terminal')._exec_toggle({ cmd = '%s', count = %d, direction = '%s'})<CR>",
|
||||
opts.cmd,
|
||||
opts.count,
|
||||
opts.direction
|
||||
)
|
||||
|
||||
require("lvim.keymappings").load {
|
||||
normal_mode = { [opts.keymap] = exec_func },
|
||||
term_mode = { [opts.keymap] = exec_func },
|
||||
}
|
||||
|
||||
local wk_status_ok, wk = pcall(require, "which-key")
|
||||
if not wk_status_ok then
|
||||
return
|
||||
end
|
||||
wk.register({ [opts.keymap] = { opts.label } }, { mode = "n" })
|
||||
end
|
||||
|
||||
M._exec_toggle = function(opts)
|
||||
local Terminal = require("toggleterm.terminal").Terminal
|
||||
local term = Terminal:new { cmd = opts.cmd, count = opts.count, direction = opts.direction }
|
||||
term:toggle(lvim.builtin.terminal.size, opts.direction)
|
||||
end
|
||||
|
||||
---Toggles a log viewer according to log.viewer.layout_config
|
||||
---@param logfile string the fullpath to the logfile
|
||||
M.toggle_log_view = function(logfile)
|
||||
local log_viewer = lvim.log.viewer.cmd
|
||||
if vim.fn.executable(log_viewer) ~= 1 then
|
||||
log_viewer = "less +F"
|
||||
end
|
||||
Log:debug("attempting to open: " .. logfile)
|
||||
log_viewer = log_viewer .. " " .. logfile
|
||||
local term_opts = vim.tbl_deep_extend("force", lvim.builtin.terminal, {
|
||||
cmd = log_viewer,
|
||||
open_mapping = lvim.log.viewer.layout_config.open_mapping,
|
||||
direction = lvim.log.viewer.layout_config.direction,
|
||||
-- TODO: this might not be working as expected
|
||||
size = lvim.log.viewer.layout_config.size,
|
||||
float_opts = lvim.log.viewer.layout_config.float_opts,
|
||||
})
|
||||
|
||||
local Terminal = require("toggleterm.terminal").Terminal
|
||||
local log_view = Terminal:new(term_opts)
|
||||
log_view:toggle()
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,97 @@
|
|||
local M = {}
|
||||
local Log = require "lvim.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 = {
|
||||
enable = false, -- mandatory, false will disable the whole extension
|
||||
-- disable = { "c", "ruby" }, -- optional, list of language that will be disabled
|
||||
},
|
||||
highlight = {
|
||||
enable = true, -- false will disable the whole extension
|
||||
additional_vim_regex_highlighting = false,
|
||||
disable = { "latex" },
|
||||
},
|
||||
context_commentstring = {
|
||||
enable = true,
|
||||
enable_autocmd = false,
|
||||
config = {
|
||||
-- Languages that have a single comment style
|
||||
typescript = "// %s",
|
||||
css = "/* %s */",
|
||||
scss = "/* %s */",
|
||||
html = "<!-- %s -->",
|
||||
svelte = "<!-- %s -->",
|
||||
vue = "<!-- %s -->",
|
||||
json = "",
|
||||
},
|
||||
},
|
||||
indent = { enable = true, disable = { "yaml", "python" } },
|
||||
autotag = { enable = false },
|
||||
textobjects = {
|
||||
swap = {
|
||||
enable = false,
|
||||
-- swap_next = textobj_swap_keymaps,
|
||||
},
|
||||
-- move = textobj_move_keymaps,
|
||||
select = {
|
||||
enable = false,
|
||||
-- keymaps = textobj_sel_keymaps,
|
||||
},
|
||||
},
|
||||
textsubjects = {
|
||||
enable = false,
|
||||
keymaps = { ["."] = "textsubjects-smart", [";"] = "textsubjects-big" },
|
||||
},
|
||||
playground = {
|
||||
enable = false,
|
||||
disable = {},
|
||||
updatetime = 25, -- Debounced time for highlighting nodes in the playground from source code
|
||||
persist_queries = false, -- Whether the query persists across vim sessions
|
||||
keybindings = {
|
||||
toggle_query_editor = "o",
|
||||
toggle_hl_groups = "i",
|
||||
toggle_injected_languages = "t",
|
||||
toggle_anonymous_nodes = "a",
|
||||
toggle_language_display = "I",
|
||||
focus_language = "f",
|
||||
unfocus_language = "F",
|
||||
update = "R",
|
||||
goto_node = "<cr>",
|
||||
show_help = "?",
|
||||
},
|
||||
},
|
||||
rainbow = {
|
||||
enable = false,
|
||||
extended_mode = true, -- Highlight also non-parentheses delimiters, boolean or table: lang -> boolean
|
||||
max_file_lines = 1000, -- Do not enable for files with more than 1000 lines, int
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
-- avoid running in headless mode since it's harder to detect failures
|
||||
if #vim.api.nvim_list_uis() == 0 then
|
||||
Log:debug "headless mode detected, skipping running setup for treesitter"
|
||||
return
|
||||
end
|
||||
|
||||
local status_ok, treesitter_configs = pcall(require, "nvim-treesitter.configs")
|
||||
if not status_ok then
|
||||
Log:error "Failed to load nvim-treesitter.configs"
|
||||
return
|
||||
end
|
||||
|
||||
local opts = vim.deepcopy(lvim.builtin.treesitter)
|
||||
|
||||
treesitter_configs.setup(opts)
|
||||
|
||||
if lvim.builtin.treesitter.on_config_done then
|
||||
lvim.builtin.treesitter.on_config_done(treesitter_configs)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,286 @@
|
|||
local M = {}
|
||||
|
||||
M.config = function()
|
||||
lvim.builtin.which_key = {
|
||||
---@usage disable which-key completely [not recommended]
|
||||
active = true,
|
||||
on_config_done = nil,
|
||||
setup = {
|
||||
plugins = {
|
||||
marks = true, -- shows a list of your marks on ' and `
|
||||
registers = true, -- shows your registers on " in NORMAL or <C-r> in INSERT mode
|
||||
-- the presets plugin, adds help for a bunch of default keybindings in Neovim
|
||||
-- No actual key bindings are created
|
||||
presets = {
|
||||
operators = false, -- adds help for operators like d, y, ...
|
||||
motions = false, -- adds help for motions
|
||||
text_objects = false, -- help for text objects triggered after entering an operator
|
||||
windows = false, -- default bindings on <c-w>
|
||||
nav = true, -- misc bindings to work with windows
|
||||
z = true, -- bindings for folds, spelling and others prefixed with z
|
||||
g = true, -- bindings for prefixed with g
|
||||
},
|
||||
spelling = { enabled = true, suggestions = 20 }, -- use which-key for spelling hints
|
||||
},
|
||||
icons = {
|
||||
breadcrumb = "»", -- symbol used in the command line area that shows your active key combo
|
||||
separator = "➜", -- symbol used between a key and it's label
|
||||
group = "+", -- symbol prepended to a group
|
||||
},
|
||||
popup_mappings = {
|
||||
scroll_down = "<c-d>", -- binding to scroll down inside the popup
|
||||
scroll_up = "<c-u>", -- binding to scroll up inside the popup
|
||||
},
|
||||
window = {
|
||||
border = "single", -- none, single, double, shadow
|
||||
position = "bottom", -- bottom, top
|
||||
margin = { 1, 0, 1, 0 }, -- extra window margin [top, right, bottom, left]
|
||||
padding = { 2, 2, 2, 2 }, -- extra window padding [top, right, bottom, left]
|
||||
winblend = 0,
|
||||
},
|
||||
layout = {
|
||||
height = { min = 4, max = 25 }, -- min and max height of the columns
|
||||
width = { min = 20, max = 50 }, -- min and max width of the columns
|
||||
spacing = 3, -- spacing between columns
|
||||
align = "left", -- align columns left, center or right
|
||||
},
|
||||
hidden = { "<silent>", "<cmd>", "<Cmd>", "<CR>", "call", "lua", "^:", "^ " }, -- hide mapping boilerplate
|
||||
ignore_missing = false, -- enable this to hide mappings for which you didn't specify a label
|
||||
show_help = true, -- show help message on the command line when the popup is visible
|
||||
triggers = "auto", -- automatically setup triggers
|
||||
-- triggers = {"<leader>"} -- or specify a list manually
|
||||
triggers_blacklist = {
|
||||
-- list of mode / prefixes that should never be hooked by WhichKey
|
||||
-- this is mostly relevant for key maps that start with a native binding
|
||||
-- most people should not need to change this
|
||||
i = { "j", "k" },
|
||||
v = { "j", "k" },
|
||||
},
|
||||
},
|
||||
|
||||
opts = {
|
||||
mode = "n", -- NORMAL mode
|
||||
prefix = "<leader>",
|
||||
buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
|
||||
silent = true, -- use `silent` when creating keymaps
|
||||
noremap = true, -- use `noremap` when creating keymaps
|
||||
nowait = true, -- use `nowait` when creating keymaps
|
||||
},
|
||||
vopts = {
|
||||
mode = "v", -- VISUAL mode
|
||||
prefix = "<leader>",
|
||||
buffer = nil, -- Global mappings. Specify a buffer number for buffer local mappings
|
||||
silent = true, -- use `silent` when creating keymaps
|
||||
noremap = true, -- use `noremap` when creating keymaps
|
||||
nowait = true, -- use `nowait` when creating keymaps
|
||||
},
|
||||
-- NOTE: Prefer using : over <cmd> as the latter avoids going back in normal-mode.
|
||||
-- see https://neovim.io/doc/user/map.html#:map-cmd
|
||||
vmappings = {
|
||||
["/"] = { "<ESC><CMD>lua require('Comment.api').toggle_linewise_op(vim.fn.visualmode())<CR>", "Comment" },
|
||||
},
|
||||
mappings = {
|
||||
[";"] = { "<cmd>Alpha<CR>", "Dashboard" },
|
||||
["w"] = { "<cmd>w!<CR>", "Save" },
|
||||
["q"] = { "<cmd>lua require('lvim.utils.functions').smart_quit()<CR>", "Quit" },
|
||||
["/"] = { "<cmd>lua require('Comment.api').toggle_current_linewise()<CR>", "Comment" },
|
||||
["c"] = { "<cmd>BufferKill<CR>", "Close Buffer" },
|
||||
["f"] = { require("lvim.core.telescope.custom-finders").find_project_files, "Find File" },
|
||||
["h"] = { "<cmd>nohlsearch<CR>", "No Highlight" },
|
||||
b = {
|
||||
name = "Buffers",
|
||||
j = { "<cmd>BufferLinePick<cr>", "Jump" },
|
||||
f = { "<cmd>Telescope buffers<cr>", "Find" },
|
||||
b = { "<cmd>BufferLineCyclePrev<cr>", "Previous" },
|
||||
-- w = { "<cmd>BufferWipeout<cr>", "Wipeout" }, -- TODO: implement this for bufferline
|
||||
e = {
|
||||
"<cmd>BufferLinePickClose<cr>",
|
||||
"Pick which buffer to close",
|
||||
},
|
||||
h = { "<cmd>BufferLineCloseLeft<cr>", "Close all to the left" },
|
||||
l = {
|
||||
"<cmd>BufferLineCloseRight<cr>",
|
||||
"Close all to the right",
|
||||
},
|
||||
D = {
|
||||
"<cmd>BufferLineSortByDirectory<cr>",
|
||||
"Sort by directory",
|
||||
},
|
||||
L = {
|
||||
"<cmd>BufferLineSortByExtension<cr>",
|
||||
"Sort by language",
|
||||
},
|
||||
},
|
||||
p = {
|
||||
name = "Packer",
|
||||
c = { "<cmd>PackerCompile<cr>", "Compile" },
|
||||
i = { "<cmd>PackerInstall<cr>", "Install" },
|
||||
r = { "<cmd>lua require('lvim.plugin-loader').recompile()<cr>", "Re-compile" },
|
||||
s = { "<cmd>PackerSync<cr>", "Sync" },
|
||||
S = { "<cmd>PackerStatus<cr>", "Status" },
|
||||
u = { "<cmd>PackerUpdate<cr>", "Update" },
|
||||
},
|
||||
|
||||
-- " Available Debug Adapters:
|
||||
-- " https://microsoft.github.io/debug-adapter-protocol/implementors/adapters/
|
||||
-- " Adapter configuration and installation instructions:
|
||||
-- " https://github.com/mfussenegger/nvim-dap/wiki/Debug-Adapter-installation
|
||||
-- " Debug Adapter protocol:
|
||||
-- " https://microsoft.github.io/debug-adapter-protocol/
|
||||
-- " Debugging
|
||||
g = {
|
||||
name = "Git",
|
||||
j = { "<cmd>lua require 'gitsigns'.next_hunk()<cr>", "Next Hunk" },
|
||||
k = { "<cmd>lua require 'gitsigns'.prev_hunk()<cr>", "Prev Hunk" },
|
||||
l = { "<cmd>lua require 'gitsigns'.blame_line()<cr>", "Blame" },
|
||||
p = { "<cmd>lua require 'gitsigns'.preview_hunk()<cr>", "Preview Hunk" },
|
||||
r = { "<cmd>lua require 'gitsigns'.reset_hunk()<cr>", "Reset Hunk" },
|
||||
R = { "<cmd>lua require 'gitsigns'.reset_buffer()<cr>", "Reset Buffer" },
|
||||
s = { "<cmd>lua require 'gitsigns'.stage_hunk()<cr>", "Stage Hunk" },
|
||||
u = {
|
||||
"<cmd>lua require 'gitsigns'.undo_stage_hunk()<cr>",
|
||||
"Undo Stage Hunk",
|
||||
},
|
||||
o = { "<cmd>Telescope git_status<cr>", "Open changed file" },
|
||||
b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },
|
||||
c = { "<cmd>Telescope git_commits<cr>", "Checkout commit" },
|
||||
C = {
|
||||
"<cmd>Telescope git_bcommits<cr>",
|
||||
"Checkout commit(for current file)",
|
||||
},
|
||||
d = {
|
||||
"<cmd>Gitsigns diffthis HEAD<cr>",
|
||||
"Git Diff",
|
||||
},
|
||||
},
|
||||
l = {
|
||||
name = "LSP",
|
||||
a = { "<cmd>lua vim.lsp.buf.code_action()<cr>", "Code Action" },
|
||||
d = { "<cmd>Telescope diagnostics bufnr=0 theme=get_ivy<cr>", "Buffer Diagnostics" },
|
||||
w = { "<cmd>Telescope diagnostics<cr>", "Diagnostics" },
|
||||
f = { require("lvim.lsp.utils").format, "Format" },
|
||||
i = { "<cmd>LspInfo<cr>", "Info" },
|
||||
I = { "<cmd>LspInstallInfo<cr>", "Installer Info" },
|
||||
j = {
|
||||
vim.diagnostic.goto_next,
|
||||
"Next Diagnostic",
|
||||
},
|
||||
k = {
|
||||
vim.diagnostic.goto_prev,
|
||||
"Prev Diagnostic",
|
||||
},
|
||||
l = { vim.lsp.codelens.run, "CodeLens Action" },
|
||||
p = {
|
||||
name = "Peek",
|
||||
d = { "<cmd>lua require('lvim.lsp.peek').Peek('definition')<cr>", "Definition" },
|
||||
t = { "<cmd>lua require('lvim.lsp.peek').Peek('typeDefinition')<cr>", "Type Definition" },
|
||||
i = { "<cmd>lua require('lvim.lsp.peek').Peek('implementation')<cr>", "Implementation" },
|
||||
},
|
||||
q = { vim.diagnostic.setloclist, "Quickfix" },
|
||||
r = { vim.lsp.buf.rename, "Rename" },
|
||||
s = { "<cmd>Telescope lsp_document_symbols<cr>", "Document Symbols" },
|
||||
S = {
|
||||
"<cmd>Telescope lsp_dynamic_workspace_symbols<cr>",
|
||||
"Workspace Symbols",
|
||||
},
|
||||
e = { "<cmd>Telescope quickfix<cr>", "Telescope Quickfix" },
|
||||
},
|
||||
L = {
|
||||
name = "+LunarVim",
|
||||
c = {
|
||||
"<cmd>edit " .. get_config_dir() .. "/config.lua<cr>",
|
||||
"Edit config.lua",
|
||||
},
|
||||
f = {
|
||||
"<cmd>lua require('lvim.core.telescope.custom-finders').find_lunarvim_files()<cr>",
|
||||
"Find LunarVim files",
|
||||
},
|
||||
g = {
|
||||
"<cmd>lua require('lvim.core.telescope.custom-finders').grep_lunarvim_files()<cr>",
|
||||
"Grep LunarVim files",
|
||||
},
|
||||
k = { "<cmd>Telescope keymaps<cr>", "View LunarVim's keymappings" },
|
||||
i = {
|
||||
"<cmd>lua require('lvim.core.info').toggle_popup(vim.bo.filetype)<cr>",
|
||||
"Toggle LunarVim Info",
|
||||
},
|
||||
I = {
|
||||
"<cmd>lua require('lvim.core.telescope.custom-finders').view_lunarvim_changelog()<cr>",
|
||||
"View LunarVim's changelog",
|
||||
},
|
||||
l = {
|
||||
name = "+logs",
|
||||
d = {
|
||||
"<cmd>lua require('lvim.core.terminal').toggle_log_view(require('lvim.core.log').get_path())<cr>",
|
||||
"view default log",
|
||||
},
|
||||
D = {
|
||||
"<cmd>lua vim.fn.execute('edit ' .. require('lvim.core.log').get_path())<cr>",
|
||||
"Open the default logfile",
|
||||
},
|
||||
l = {
|
||||
"<cmd>lua require('lvim.core.terminal').toggle_log_view(vim.lsp.get_log_path())<cr>",
|
||||
"view lsp log",
|
||||
},
|
||||
L = { "<cmd>lua vim.fn.execute('edit ' .. vim.lsp.get_log_path())<cr>", "Open the LSP logfile" },
|
||||
n = {
|
||||
"<cmd>lua require('lvim.core.terminal').toggle_log_view(os.getenv('NVIM_LOG_FILE'))<cr>",
|
||||
"view neovim log",
|
||||
},
|
||||
N = { "<cmd>edit $NVIM_LOG_FILE<cr>", "Open the Neovim logfile" },
|
||||
p = {
|
||||
"<cmd>lua require('lvim.core.terminal').toggle_log_view(get_cache_dir() .. '/packer.nvim.log')<cr>",
|
||||
"view packer log",
|
||||
},
|
||||
P = { "<cmd>edit $LUNARVIM_CACHE_DIR/packer.nvim.log<cr>", "Open the Packer logfile" },
|
||||
},
|
||||
n = { "<cmd>Telescope notify<cr>", "View Notifications" },
|
||||
r = { "<cmd>LvimReload<cr>", "Reload LunarVim's configuration" },
|
||||
u = { "<cmd>LvimUpdate<cr>", "Update LunarVim" },
|
||||
},
|
||||
s = {
|
||||
name = "Search",
|
||||
b = { "<cmd>Telescope git_branches<cr>", "Checkout branch" },
|
||||
c = { "<cmd>Telescope colorscheme<cr>", "Colorscheme" },
|
||||
f = { "<cmd>Telescope find_files<cr>", "Find File" },
|
||||
h = { "<cmd>Telescope help_tags<cr>", "Find Help" },
|
||||
H = { "<cmd>Telescope highlights<cr>", "Find highlight groups" },
|
||||
M = { "<cmd>Telescope man_pages<cr>", "Man Pages" },
|
||||
r = { "<cmd>Telescope oldfiles<cr>", "Open Recent File" },
|
||||
R = { "<cmd>Telescope registers<cr>", "Registers" },
|
||||
t = { "<cmd>Telescope live_grep<cr>", "Text" },
|
||||
k = { "<cmd>Telescope keymaps<cr>", "Keymaps" },
|
||||
C = { "<cmd>Telescope commands<cr>", "Commands" },
|
||||
p = {
|
||||
"<cmd>lua require('telescope.builtin.internal').colorscheme({enable_preview = true})<cr>",
|
||||
"Colorscheme with Preview",
|
||||
},
|
||||
},
|
||||
T = {
|
||||
name = "Treesitter",
|
||||
i = { ":TSConfigInfo<cr>", "Info" },
|
||||
},
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
M.setup = function()
|
||||
local which_key = require "which-key"
|
||||
|
||||
which_key.setup(lvim.builtin.which_key.setup)
|
||||
|
||||
local opts = lvim.builtin.which_key.opts
|
||||
local vopts = lvim.builtin.which_key.vopts
|
||||
|
||||
local mappings = lvim.builtin.which_key.mappings
|
||||
local vmappings = lvim.builtin.which_key.vmappings
|
||||
|
||||
which_key.register(mappings, opts)
|
||||
which_key.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
|
|
@ -0,0 +1,364 @@
|
|||
-- modified version from https://github.com/lewis6991/impatient.nvim
|
||||
|
||||
local vim = vim
|
||||
local api = vim.api
|
||||
local uv = vim.loop
|
||||
local _loadfile = loadfile
|
||||
local get_runtime = api.nvim__get_runtime
|
||||
local fs_stat = uv.fs_stat
|
||||
local mpack = vim.mpack
|
||||
|
||||
local appdir = os.getenv "APPDIR"
|
||||
|
||||
local M = {
|
||||
chunks = {
|
||||
cache = {},
|
||||
profile = nil,
|
||||
dirty = false,
|
||||
path = vim.fn.stdpath "cache" .. "/luacache_chunks",
|
||||
},
|
||||
modpaths = {
|
||||
cache = {},
|
||||
profile = nil,
|
||||
dirty = false,
|
||||
path = vim.fn.stdpath "cache" .. "/luacache_modpaths",
|
||||
},
|
||||
log = {},
|
||||
}
|
||||
|
||||
_G.__luacache = M
|
||||
|
||||
if not get_runtime then
|
||||
-- nvim 0.5 compat
|
||||
get_runtime = function(paths, all, _)
|
||||
local r = {}
|
||||
for _, path in ipairs(paths) do
|
||||
local found = api.nvim_get_runtime_file(path, all)
|
||||
for i = 1, #found do
|
||||
r[#r + 1] = found[i]
|
||||
end
|
||||
end
|
||||
return r
|
||||
end
|
||||
end
|
||||
|
||||
local function log(...)
|
||||
M.log[#M.log + 1] = table.concat({ string.format(...) }, " ")
|
||||
end
|
||||
|
||||
function M.print_log()
|
||||
for _, l in ipairs(M.log) do
|
||||
print(l)
|
||||
end
|
||||
end
|
||||
|
||||
function M.enable_profile()
|
||||
local P = require "lvim.impatient.profile"
|
||||
|
||||
M.chunks.profile = {}
|
||||
M.modpaths.profile = {}
|
||||
|
||||
P.setup(M.modpaths.profile)
|
||||
|
||||
M.print_profile = function()
|
||||
P.print_profile(M)
|
||||
end
|
||||
|
||||
vim.cmd [[command! LuaCacheProfile lua _G.__luacache.print_profile()]]
|
||||
end
|
||||
|
||||
local function hash(modpath)
|
||||
local stat = fs_stat(modpath)
|
||||
if stat then
|
||||
return stat.mtime.sec .. stat.mtime.nsec .. stat.size
|
||||
end
|
||||
error("Could not hash " .. modpath)
|
||||
end
|
||||
|
||||
local function modpath_mangle(modpath)
|
||||
if appdir then
|
||||
modpath = modpath:gsub(appdir, "/$APPDIR")
|
||||
end
|
||||
return modpath
|
||||
end
|
||||
|
||||
local function modpath_unmangle(modpath)
|
||||
if appdir then
|
||||
modpath = modpath:gsub("/$APPDIR", appdir)
|
||||
end
|
||||
return modpath
|
||||
end
|
||||
|
||||
local function profile(m, entry, name, loader)
|
||||
if m.profile then
|
||||
local mp = m.profile
|
||||
mp[entry] = mp[entry] or {}
|
||||
if not mp[entry].loader and loader then
|
||||
mp[entry].loader = loader
|
||||
end
|
||||
if not mp[entry][name] then
|
||||
mp[entry][name] = uv.hrtime()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local function mprofile(mod, name, loader)
|
||||
profile(M.modpaths, mod, name, loader)
|
||||
end
|
||||
|
||||
local function cprofile(path, name, loader)
|
||||
profile(M.chunks, path, name, loader)
|
||||
end
|
||||
|
||||
local function get_runtime_file(basename, paths)
|
||||
-- Look in the cache to see if we have already loaded a parent module.
|
||||
-- If we have then try looking in the parents directory first.
|
||||
local parents = vim.split(basename, "/")
|
||||
for i = #parents, 1, -1 do
|
||||
local parent = table.concat(vim.list_slice(parents, 1, i), "/")
|
||||
local ppath = M.modpaths.cache[parent]
|
||||
if ppath then
|
||||
if ppath:sub(-9) == "/init.lua" then
|
||||
ppath = ppath:sub(1, -10) -- a/b/init.lua -> a/b
|
||||
else
|
||||
ppath = ppath:sub(1, -5) -- a/b.lua -> a/b
|
||||
end
|
||||
|
||||
for _, path in ipairs(paths) do
|
||||
-- path should be of form 'a/b/c.lua' or 'a/b/c/init.lua'
|
||||
local modpath = ppath .. "/" .. path:sub(#("lua/" .. parent) + 2)
|
||||
if fs_stat(modpath) then
|
||||
return modpath, "cache(p)"
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- What Neovim does by default; slowest
|
||||
local modpath = get_runtime(paths, false, { is_lua = true })[1]
|
||||
return modpath, "standard"
|
||||
end
|
||||
|
||||
local function get_runtime_file_cached(basename, paths)
|
||||
local mp = M.modpaths
|
||||
if mp.cache[basename] then
|
||||
local modpath = mp.cache[basename]
|
||||
if fs_stat(modpath) then
|
||||
mprofile(basename, "resolve_end", "cache")
|
||||
return modpath
|
||||
end
|
||||
mp.cache[basename] = nil
|
||||
mp.dirty = true
|
||||
end
|
||||
|
||||
local modpath, loader = get_runtime_file(basename, paths)
|
||||
if modpath then
|
||||
mprofile(basename, "resolve_end", loader)
|
||||
log("Creating cache for module %s", basename)
|
||||
mp.cache[basename] = modpath_mangle(modpath)
|
||||
mp.dirty = true
|
||||
end
|
||||
return modpath
|
||||
end
|
||||
|
||||
local function extract_basename(pats)
|
||||
local basename
|
||||
|
||||
-- Deconstruct basename from pats
|
||||
for _, pat in ipairs(pats) do
|
||||
for i, npat in ipairs {
|
||||
-- Ordered by most specific
|
||||
"lua/(.*)/init%.lua",
|
||||
"lua/(.*)%.lua",
|
||||
} do
|
||||
local m = pat:match(npat)
|
||||
if i == 2 and m and m:sub(-4) == "init" then
|
||||
m = m:sub(0, -6)
|
||||
end
|
||||
if not basename then
|
||||
if m then
|
||||
basename = m
|
||||
end
|
||||
elseif m and m ~= basename then
|
||||
-- matches are inconsistent
|
||||
return
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return basename
|
||||
end
|
||||
|
||||
local function get_runtime_cached(pats, all, opts)
|
||||
local fallback = false
|
||||
if all or not opts or not opts.is_lua then
|
||||
-- Fallback
|
||||
fallback = true
|
||||
end
|
||||
|
||||
local basename
|
||||
|
||||
if not fallback then
|
||||
basename = extract_basename(pats)
|
||||
end
|
||||
|
||||
if fallback or not basename then
|
||||
return get_runtime(pats, all, opts)
|
||||
end
|
||||
|
||||
return { get_runtime_file_cached(basename, pats) }
|
||||
end
|
||||
|
||||
-- Copied from neovim/src/nvim/lua/vim.lua with two lines changed
|
||||
local function load_package(name)
|
||||
local basename = name:gsub("%.", "/")
|
||||
local paths = { "lua/" .. basename .. ".lua", "lua/" .. basename .. "/init.lua" }
|
||||
|
||||
-- Original line:
|
||||
-- local found = vim.api.nvim__get_runtime(paths, false, {is_lua=true})
|
||||
local found = { get_runtime_file_cached(basename, paths) }
|
||||
if #found > 0 then
|
||||
local f, err = loadfile(found[1])
|
||||
return f or error(err)
|
||||
end
|
||||
|
||||
local so_paths = {}
|
||||
for _, trail in ipairs(vim._so_trails) do
|
||||
local path = "lua" .. trail:gsub("?", basename) -- so_trails contains a leading slash
|
||||
table.insert(so_paths, path)
|
||||
end
|
||||
|
||||
-- Original line:
|
||||
-- found = vim.api.nvim__get_runtime(so_paths, false, {is_lua=true})
|
||||
found = { get_runtime_file_cached(basename, so_paths) }
|
||||
if #found > 0 then
|
||||
-- Making function name in Lua 5.1 (see src/loadlib.c:mkfuncname) is
|
||||
-- a) strip prefix up to and including the first dash, if any
|
||||
-- b) replace all dots by underscores
|
||||
-- c) prepend "luaopen_"
|
||||
-- So "foo-bar.baz" should result in "luaopen_bar_baz"
|
||||
local dash = name:find("-", 1, true)
|
||||
local modname = dash and name:sub(dash + 1) or name
|
||||
local f, err = package.loadlib(found[1], "luaopen_" .. modname:gsub("%.", "_"))
|
||||
return f or error(err)
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
local function load_from_cache(path)
|
||||
local mc = M.chunks
|
||||
|
||||
if not mc.cache[path] then
|
||||
return nil, string.format("No cache for path %s", path)
|
||||
end
|
||||
|
||||
local mhash, codes = unpack(mc.cache[path])
|
||||
|
||||
if mhash ~= hash(modpath_unmangle(path)) then
|
||||
mc.cache[path] = nil
|
||||
mc.dirty = true
|
||||
return nil, string.format("Stale cache for path %s", path)
|
||||
end
|
||||
|
||||
local chunk = loadstring(codes)
|
||||
|
||||
if not chunk then
|
||||
mc.cache[path] = nil
|
||||
mc.dirty = true
|
||||
return nil, string.format("Cache error for path %s", path)
|
||||
end
|
||||
|
||||
return chunk
|
||||
end
|
||||
|
||||
local function loadfile_cached(path)
|
||||
cprofile(path, "load_start")
|
||||
|
||||
local chunk, err = load_from_cache(path)
|
||||
if chunk and not err then
|
||||
log("Loaded cache for path %s", path)
|
||||
cprofile(path, "load_end", "cache")
|
||||
return chunk
|
||||
end
|
||||
log(err)
|
||||
|
||||
chunk, err = _loadfile(path)
|
||||
|
||||
if not err then
|
||||
log("Creating cache for path %s", path)
|
||||
M.chunks.cache[modpath_mangle(path)] = { hash(path), string.dump(chunk) }
|
||||
M.chunks.dirty = true
|
||||
end
|
||||
|
||||
cprofile(path, "load_end", "standard")
|
||||
return chunk, err
|
||||
end
|
||||
|
||||
function M.save_cache()
|
||||
local function _save_cache(t)
|
||||
if t.dirty then
|
||||
log("Updating chunk cache file: %s", t.path)
|
||||
local f = io.open(t.path, "w+b")
|
||||
f:write(mpack.encode(t.cache))
|
||||
f:flush()
|
||||
t.dirty = false
|
||||
end
|
||||
end
|
||||
_save_cache(M.chunks)
|
||||
_save_cache(M.modpaths)
|
||||
end
|
||||
|
||||
function M.clear_cache()
|
||||
local function _clear_cache(t)
|
||||
t.cache = {}
|
||||
os.remove(t.path)
|
||||
end
|
||||
_clear_cache(M.chunks)
|
||||
_clear_cache(M.modpaths)
|
||||
end
|
||||
|
||||
local function init_cache()
|
||||
local function _init_cache(t)
|
||||
if fs_stat(t.path) then
|
||||
log("Loading cache file %s", t.path)
|
||||
local f = io.open(t.path, "rb")
|
||||
local ok
|
||||
ok, t.cache = pcall(function()
|
||||
return mpack.decode(f:read "*a")
|
||||
end)
|
||||
|
||||
if not ok then
|
||||
log("Corrupted cache file, %s. Invalidating...", t.path)
|
||||
os.remove(t.path)
|
||||
t.cache = {}
|
||||
end
|
||||
t.dirty = not ok
|
||||
end
|
||||
end
|
||||
|
||||
_init_cache(M.chunks)
|
||||
_init_cache(M.modpaths)
|
||||
end
|
||||
|
||||
local function setup()
|
||||
init_cache()
|
||||
|
||||
-- Override default functions
|
||||
vim._load_package = load_package
|
||||
vim.api.nvim__get_runtime = get_runtime_cached
|
||||
-- luacheck: ignore 121
|
||||
loadfile = loadfile_cached
|
||||
|
||||
vim.cmd [[
|
||||
augroup impatient
|
||||
autocmd VimEnter,VimLeave * lua _G.__luacache.save_cache()
|
||||
augroup END
|
||||
|
||||
command! LuaCacheClear lua _G.__luacache.clear_cache()
|
||||
command! LuaCacheLog lua _G.__luacache.print_log()
|
||||
]]
|
||||
end
|
||||
|
||||
setup()
|
||||
|
||||
return M
|
|
@ -0,0 +1,242 @@
|
|||
local M = {}
|
||||
|
||||
local api, uv = vim.api, vim.loop
|
||||
|
||||
local std_data = vim.fn.stdpath "data"
|
||||
local std_config = vim.fn.stdpath "config"
|
||||
local vimruntime = os.getenv "VIMRUNTIME"
|
||||
local lvim_runtime = get_runtime_dir()
|
||||
local lvim_config = get_config_dir()
|
||||
|
||||
local function load_buffer(title, lines)
|
||||
local bufnr = api.nvim_create_buf(false, false)
|
||||
api.nvim_buf_set_lines(bufnr, 0, 0, false, lines)
|
||||
api.nvim_buf_set_option(bufnr, "bufhidden", "wipe")
|
||||
api.nvim_buf_set_option(bufnr, "buftype", "nofile")
|
||||
api.nvim_buf_set_option(bufnr, "swapfile", false)
|
||||
api.nvim_buf_set_option(bufnr, "modifiable", false)
|
||||
api.nvim_buf_set_name(bufnr, title)
|
||||
api.nvim_set_current_buf(bufnr)
|
||||
end
|
||||
|
||||
local function mod_path(path)
|
||||
if not path then
|
||||
return "?"
|
||||
end
|
||||
path = path:gsub(std_data .. "/site/pack/packer/", "<PACKER>/")
|
||||
path = path:gsub(std_data .. "/", "<STD_DATA>/")
|
||||
path = path:gsub(std_config .. "/", "<STD_CONFIG>/")
|
||||
path = path:gsub(vimruntime .. "/", "<VIMRUNTIME>/")
|
||||
path = path:gsub(lvim_runtime .. "/", "<LVIM_RUNTIME>/")
|
||||
path = path:gsub(lvim_config .. "/", "<LVIM_CONFIG>/")
|
||||
return path
|
||||
end
|
||||
|
||||
local function time_tostr(x)
|
||||
if x == 0 then
|
||||
return "?"
|
||||
end
|
||||
return string.format("%8.3fms", x)
|
||||
end
|
||||
|
||||
local function mem_tostr(x)
|
||||
local unit = ""
|
||||
for _, u in ipairs { "K", "M", "G" } do
|
||||
if x < 1000 then
|
||||
break
|
||||
end
|
||||
x = x / 1000
|
||||
unit = u
|
||||
end
|
||||
return string.format("%1.1f%s", x, unit)
|
||||
end
|
||||
|
||||
function M.print_profile(I)
|
||||
local mod_profile = I.modpaths.profile
|
||||
local chunk_profile = I.chunks.profile
|
||||
|
||||
if not mod_profile and not chunk_profile then
|
||||
print "Error: profiling was not enabled"
|
||||
return
|
||||
end
|
||||
|
||||
local total_resolve = 0
|
||||
local total_load = 0
|
||||
local modules = {}
|
||||
|
||||
for path, m in pairs(chunk_profile) do
|
||||
m.load = m.load_end - m.load_start
|
||||
m.load = m.load / 1000000
|
||||
m.path = mod_path(path)
|
||||
end
|
||||
|
||||
local module_content_width = 0
|
||||
|
||||
for module, m in pairs(mod_profile) do
|
||||
m.resolve = 0
|
||||
if m.resolve_end then
|
||||
m.resolve = m.resolve_end - m.resolve_start
|
||||
m.resolve = m.resolve / 1000000
|
||||
end
|
||||
|
||||
m.module = module:gsub("/", ".")
|
||||
m.loader = m.loader or m.loader_guess
|
||||
|
||||
local path = I.modpaths.cache[module]
|
||||
local path_prof = chunk_profile[path]
|
||||
m.path = mod_path(path)
|
||||
|
||||
if path_prof then
|
||||
chunk_profile[path] = nil
|
||||
m.load = path_prof.load
|
||||
m.ploader = path_prof.loader
|
||||
else
|
||||
m.load = 0
|
||||
m.ploader = "NA"
|
||||
end
|
||||
|
||||
total_resolve = total_resolve + m.resolve
|
||||
total_load = total_load + m.load
|
||||
|
||||
if #module > module_content_width then
|
||||
module_content_width = #module
|
||||
end
|
||||
|
||||
modules[#modules + 1] = m
|
||||
end
|
||||
|
||||
table.sort(modules, function(a, b)
|
||||
return (a.resolve + a.load) > (b.resolve + b.load)
|
||||
end)
|
||||
|
||||
local paths = {}
|
||||
|
||||
local total_paths_load = 0
|
||||
for _, m in pairs(chunk_profile) do
|
||||
paths[#paths + 1] = m
|
||||
total_paths_load = total_paths_load + m.load
|
||||
end
|
||||
|
||||
table.sort(paths, function(a, b)
|
||||
return a.load > b.load
|
||||
end)
|
||||
|
||||
local lines = {}
|
||||
local function add(fmt, ...)
|
||||
local args = { ... }
|
||||
for i, a in ipairs(args) do
|
||||
if type(a) == "number" then
|
||||
args[i] = time_tostr(a)
|
||||
end
|
||||
end
|
||||
|
||||
lines[#lines + 1] = string.format(fmt, unpack(args))
|
||||
end
|
||||
|
||||
local time_cell_width = 12
|
||||
local loader_cell_width = 11
|
||||
local time_content_width = time_cell_width - 2
|
||||
local loader_content_width = loader_cell_width - 2
|
||||
local module_cell_width = module_content_width + 2
|
||||
|
||||
local tcwl = string.rep("─", time_cell_width)
|
||||
local lcwl = string.rep("─", loader_cell_width)
|
||||
local mcwl = string.rep("─", module_cell_width + 2)
|
||||
|
||||
local n = string.rep("─", 200)
|
||||
|
||||
local module_cell_format = "%-" .. module_cell_width .. "s"
|
||||
local loader_format = "%-" .. loader_content_width .. "s"
|
||||
local line_format = "%s │ %s │ %s │ %s │ %s │ %s"
|
||||
|
||||
local row_fmt = line_format:format(
|
||||
" %" .. time_content_width .. "s",
|
||||
loader_format,
|
||||
"%" .. time_content_width .. "s",
|
||||
loader_format,
|
||||
module_cell_format,
|
||||
"%s"
|
||||
)
|
||||
|
||||
local title_fmt = line_format:format(
|
||||
" %-" .. time_content_width .. "s",
|
||||
loader_format,
|
||||
"%-" .. time_content_width .. "s",
|
||||
loader_format,
|
||||
module_cell_format,
|
||||
"%s"
|
||||
)
|
||||
|
||||
local title1_width = time_cell_width + loader_cell_width - 1
|
||||
local title1_fmt = ("%s │ %s │"):format(" %-" .. title1_width .. "s", "%-" .. title1_width .. "s")
|
||||
|
||||
add "Note: this report is not a measure of startup time. Only use this for comparing"
|
||||
add "between cached and uncached loads of Lua modules"
|
||||
add ""
|
||||
|
||||
add "Cache files:"
|
||||
for _, f in ipairs { I.chunks.path, I.modpaths.path } do
|
||||
local size = vim.loop.fs_stat(f).size
|
||||
add(" %s %s", f, mem_tostr(size))
|
||||
end
|
||||
add ""
|
||||
|
||||
add("%s─%s┬%s─%s┐", tcwl, lcwl, tcwl, lcwl)
|
||||
add(title1_fmt, "Resolve", "Load")
|
||||
add("%s┬%s┼%s┬%s┼%s┬%s", tcwl, lcwl, tcwl, lcwl, mcwl, n)
|
||||
add(title_fmt, "Time", "Method", "Time", "Method", "Module", "Path")
|
||||
add("%s┼%s┼%s┼%s┼%s┼%s", tcwl, lcwl, tcwl, lcwl, mcwl, n)
|
||||
add(row_fmt, total_resolve, "", total_load, "", "Total", "")
|
||||
add("%s┼%s┼%s┼%s┼%s┼%s", tcwl, lcwl, tcwl, lcwl, mcwl, n)
|
||||
for _, p in ipairs(modules) do
|
||||
add(row_fmt, p.resolve, p.loader, p.load, p.ploader, p.module, p.path)
|
||||
end
|
||||
add("%s┴%s┴%s┴%s┴%s┴%s", tcwl, lcwl, tcwl, lcwl, mcwl, n)
|
||||
|
||||
if #paths > 0 then
|
||||
add ""
|
||||
add(n)
|
||||
local f3 = " %" .. time_content_width .. "s │ %" .. loader_content_width .. "s │ %s"
|
||||
add "Files loaded with no associated module"
|
||||
add("%s┬%s┬%s", tcwl, lcwl, n)
|
||||
add(f3, "Time", "Loader", "Path")
|
||||
add("%s┼%s┼%s", tcwl, lcwl, n)
|
||||
add(f3, total_paths_load, "", "Total")
|
||||
add("%s┼%s┼%s", tcwl, lcwl, n)
|
||||
for _, p in ipairs(paths) do
|
||||
add(f3, p.load, p.loader, p.path)
|
||||
end
|
||||
add("%s┴%s┴%s", tcwl, lcwl, n)
|
||||
add ""
|
||||
end
|
||||
|
||||
load_buffer("Impatient Profile Report", lines)
|
||||
end
|
||||
|
||||
M.setup = function(profile)
|
||||
local _require = require
|
||||
|
||||
-- luacheck: ignore 121
|
||||
require = function(mod)
|
||||
local basename = mod:gsub("%.", "/")
|
||||
if not profile[basename] then
|
||||
profile[basename] = {}
|
||||
profile[basename].resolve_start = uv.hrtime()
|
||||
profile[basename].loader_guess = "C"
|
||||
end
|
||||
return _require(mod)
|
||||
end
|
||||
|
||||
-- Add profiling around all the loaders
|
||||
local pl = package.loaders
|
||||
for i = 1, #pl do
|
||||
local l = pl[i]
|
||||
pl[i] = function(mod)
|
||||
local basename = mod:gsub("%.", "/")
|
||||
profile[basename].loader_guess = i == 1 and "preloader" or "loader #" .. i
|
||||
return l(mod)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,64 @@
|
|||
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.api.nvim_command(
|
||||
string.format("autocmd BufHidden,BufLeave <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)", self.win_id)
|
||||
)
|
||||
|
||||
local lines = content_provider(self.layout)
|
||||
vim.api.nvim_buf_set_lines(self.bufnr or 0, 0, -1, false, lines)
|
||||
|
||||
-- window options
|
||||
for key, value in pairs(self.win_opts) do
|
||||
vim.api.nvim_win_set_option(self.win_id or 0, 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
|
|
@ -0,0 +1,95 @@
|
|||
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
|
||||
|
||||
--- Left align lines relatively to the parent container
|
||||
-- @param container The container where lines will be displayed
|
||||
-- @param lines The text to align
|
||||
-- @param alignment The alignment value, range: [0-1]
|
||||
function M.align_left(container, lines, alignment)
|
||||
local max_len = max_len_line(lines)
|
||||
local indent_amount = math.ceil(math.max(container.width - max_len, 0) * alignment)
|
||||
return M.shift_right(lines, indent_amount)
|
||||
end
|
||||
|
||||
--- Center align lines relatively to the parent container
|
||||
-- @param container The container where lines will be displayed
|
||||
-- @param lines The text to align
|
||||
-- @param alignment The alignment value, range: [0-1]
|
||||
function M.align_center(container, lines, alignment)
|
||||
local output = {}
|
||||
local max_len = max_len_line(lines)
|
||||
|
||||
for _, line in ipairs(lines) do
|
||||
local padding = string.rep(" ", (math.max(container.width, max_len) - line:len()) * alignment)
|
||||
table.insert(output, padding .. line)
|
||||
end
|
||||
|
||||
return output
|
||||
end
|
||||
|
||||
--- Shift lines by a given amount
|
||||
-- @params lines The lines the shift
|
||||
-- @param amount The amount of spaces to add
|
||||
function M.shift_right(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 column, 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
|
|
@ -0,0 +1,203 @@
|
|||
local M = {}
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local generic_opts_any = { noremap = true, silent = true }
|
||||
|
||||
local generic_opts = {
|
||||
insert_mode = generic_opts_any,
|
||||
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 },
|
||||
}
|
||||
|
||||
local mode_adapters = {
|
||||
insert_mode = "i",
|
||||
normal_mode = "n",
|
||||
term_mode = "t",
|
||||
visual_mode = "v",
|
||||
visual_block_mode = "x",
|
||||
command_mode = "c",
|
||||
}
|
||||
|
||||
---@class Keys
|
||||
---@field insert_mode table
|
||||
---@field normal_mode table
|
||||
---@field terminal_mode table
|
||||
---@field visual_mode table
|
||||
---@field visual_block_mode table
|
||||
---@field command_mode table
|
||||
|
||||
local defaults = {
|
||||
insert_mode = {
|
||||
-- 'jk' for quitting insert mode
|
||||
["jk"] = "<ESC>",
|
||||
-- 'kj' for quitting insert mode
|
||||
["kj"] = "<ESC>",
|
||||
-- 'jj' for quitting insert mode
|
||||
["jj"] = "<ESC>",
|
||||
-- Move current line / block with Alt-j/k ala vscode.
|
||||
["<A-j>"] = "<Esc>:m .+1<CR>==gi",
|
||||
-- Move current line / block with Alt-j/k ala vscode.
|
||||
["<A-k>"] = "<Esc>:m .-2<CR>==gi",
|
||||
-- navigation
|
||||
["<A-Up>"] = "<C-\\><C-N><C-w>k",
|
||||
["<A-Down>"] = "<C-\\><C-N><C-w>j",
|
||||
["<A-Left>"] = "<C-\\><C-N><C-w>h",
|
||||
["<A-Right>"] = "<C-\\><C-N><C-w>l",
|
||||
},
|
||||
|
||||
normal_mode = {
|
||||
-- Better window movement
|
||||
["<C-h>"] = "<C-w>h",
|
||||
["<C-j>"] = "<C-w>j",
|
||||
["<C-k>"] = "<C-w>k",
|
||||
["<C-l>"] = "<C-w>l",
|
||||
|
||||
-- Resize with arrows
|
||||
["<C-Up>"] = ":resize -2<CR>",
|
||||
["<C-Down>"] = ":resize +2<CR>",
|
||||
["<C-Left>"] = ":vertical resize -2<CR>",
|
||||
["<C-Right>"] = ":vertical resize +2<CR>",
|
||||
|
||||
-- Tab switch buffer
|
||||
["<S-l>"] = ":BufferLineCycleNext<CR>",
|
||||
["<S-h>"] = ":BufferLineCyclePrev<CR>",
|
||||
|
||||
-- Move current line / block with Alt-j/k a la vscode.
|
||||
["<A-j>"] = ":m .+1<CR>==",
|
||||
["<A-k>"] = ":m .-2<CR>==",
|
||||
|
||||
-- QuickFix
|
||||
["]q"] = ":cnext<CR>",
|
||||
["[q"] = ":cprev<CR>",
|
||||
["<C-q>"] = ":call QuickFixToggle()<CR>",
|
||||
},
|
||||
|
||||
term_mode = {
|
||||
-- Terminal window navigation
|
||||
["<C-h>"] = "<C-\\><C-N><C-w>h",
|
||||
["<C-j>"] = "<C-\\><C-N><C-w>j",
|
||||
["<C-k>"] = "<C-\\><C-N><C-w>k",
|
||||
["<C-l>"] = "<C-\\><C-N><C-w>l",
|
||||
},
|
||||
|
||||
visual_mode = {
|
||||
-- Better indenting
|
||||
["<"] = "<gv",
|
||||
[">"] = ">gv",
|
||||
|
||||
-- ["p"] = '"0p',
|
||||
-- ["P"] = '"0P',
|
||||
},
|
||||
|
||||
visual_block_mode = {
|
||||
-- Move selected line / block of text in visual mode
|
||||
["K"] = ":move '<-2<CR>gv-gv",
|
||||
["J"] = ":move '>+1<CR>gv-gv",
|
||||
|
||||
-- Move current line / block with Alt-j/k ala vscode.
|
||||
["<A-j>"] = ":m '>+1<CR>gv-gv",
|
||||
["<A-k>"] = ":m '<-2<CR>gv-gv",
|
||||
},
|
||||
|
||||
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
|
||||
defaults.normal_mode["<A-Up>"] = defaults.normal_mode["<C-Up>"]
|
||||
defaults.normal_mode["<A-Down>"] = defaults.normal_mode["<C-Down>"]
|
||||
defaults.normal_mode["<A-Left>"] = defaults.normal_mode["<C-Left>"]
|
||||
defaults.normal_mode["<A-Right>"] = defaults.normal_mode["<C-Right>"]
|
||||
Log:debug "Activated mac keymappings"
|
||||
end
|
||||
|
||||
-- Unsets all keybindings defined in keymaps
|
||||
-- @param keymaps The table of key mappings containing a list per mode (normal_mode, insert_mode, ..)
|
||||
function M.clear(keymaps)
|
||||
local default = M.get_defaults()
|
||||
for mode, mappings in pairs(keymaps) do
|
||||
local translated_mode = mode_adapters[mode] or mode
|
||||
for key, _ in pairs(mappings) do
|
||||
-- some plugins may override default bindings that the user hasn't manually overridden
|
||||
if default[mode][key] ~= nil or (default[translated_mode] ~= nil and default[translated_mode][key] ~= nil) then
|
||||
pcall(vim.keymap.del, translated_mode, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Unsets all keybindings defined in keymaps
|
||||
-- @param keymaps The table of key mappings containing a list per mode (normal_mode, insert_mode, ..)
|
||||
function M.clear(keymaps)
|
||||
local default = M.get_defaults()
|
||||
for mode, mappings in pairs(keymaps) do
|
||||
local translated_mode = mode_adapters[mode] and mode_adapters[mode] or mode
|
||||
for key, _ in pairs(mappings) do
|
||||
-- some plugins may override default bindings that the user hasn't manually overriden
|
||||
if default[mode][key] ~= nil or (default[translated_mode] ~= nil and default[translated_mode][key] ~= nil) then
|
||||
pcall(vim.api.nvim_del_keymap, translated_mode, key)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Set key mappings individually
|
||||
-- @param mode The keymap mode, can be one of the keys of mode_adapters
|
||||
-- @param key The key of keymap
|
||||
-- @param val Can be form as a mapping or tuple of mapping and user defined opt
|
||||
function M.set_keymaps(mode, key, val)
|
||||
local opt = generic_opts[mode] or generic_opts_any
|
||||
if type(val) == "table" then
|
||||
opt = val[2]
|
||||
val = val[1]
|
||||
end
|
||||
if val then
|
||||
vim.keymap.set(mode, key, val, opt)
|
||||
else
|
||||
pcall(vim.api.nvim_del_keymap, mode, key)
|
||||
end
|
||||
end
|
||||
|
||||
-- Load key mappings for a given mode
|
||||
-- @param mode The keymap mode, can be one of the keys of mode_adapters
|
||||
-- @param keymaps The list of key mappings
|
||||
function M.load_mode(mode, keymaps)
|
||||
mode = mode_adapters[mode] or mode
|
||||
for k, v in pairs(keymaps) do
|
||||
M.set_keymaps(mode, k, v)
|
||||
end
|
||||
end
|
||||
|
||||
-- Load key mappings for all provided modes
|
||||
-- @param keymaps A list of key mappings for each mode
|
||||
function M.load(keymaps)
|
||||
keymaps = keymaps or {}
|
||||
for mode, mapping in pairs(keymaps) do
|
||||
M.load_mode(mode, mapping)
|
||||
end
|
||||
end
|
||||
|
||||
-- Load the default keymappings
|
||||
function M.load_defaults()
|
||||
M.load(M.get_defaults())
|
||||
lvim.keys = lvim.keys or {}
|
||||
for idx, _ in pairs(defaults) do
|
||||
if not lvim.keys[idx] then
|
||||
lvim.keys[idx] = {}
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
-- Get the default keymappings
|
||||
function M.get_defaults()
|
||||
return defaults
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,128 @@
|
|||
local skipped_servers = {
|
||||
"angularls",
|
||||
"ansiblels",
|
||||
"ccls",
|
||||
"csharp_ls",
|
||||
"cssmodules_ls",
|
||||
"denols",
|
||||
"ember",
|
||||
"emmet_ls",
|
||||
"eslint",
|
||||
"eslintls",
|
||||
"golangci_lint_ls",
|
||||
"graphql",
|
||||
"jedi_language_server",
|
||||
"ltex",
|
||||
"ocamlls",
|
||||
"phpactor",
|
||||
"psalm",
|
||||
"pylsp",
|
||||
"quick_lint_js",
|
||||
"rome",
|
||||
"reason_ls",
|
||||
"scry",
|
||||
"solang",
|
||||
"solidity_ls",
|
||||
"sorbet",
|
||||
"sourcekit",
|
||||
"sourcery",
|
||||
"spectral",
|
||||
"sqlls",
|
||||
"sqls",
|
||||
"stylelint_lsp",
|
||||
"tailwindcss",
|
||||
"tflint",
|
||||
"svlangserver",
|
||||
"verible",
|
||||
"vuels",
|
||||
}
|
||||
|
||||
local skipped_filetypes = { "markdown", "rst", "plaintext" }
|
||||
|
||||
return {
|
||||
templates_dir = join_paths(get_runtime_dir(), "site", "after", "ftplugin"),
|
||||
diagnostics = {
|
||||
signs = {
|
||||
active = true,
|
||||
values = {
|
||||
{ name = "DiagnosticSignError", text = "" },
|
||||
{ name = "DiagnosticSignWarn", text = "" },
|
||||
{ name = "DiagnosticSignHint", text = "" },
|
||||
{ name = "DiagnosticSignInfo", text = "" },
|
||||
},
|
||||
},
|
||||
virtual_text = true,
|
||||
update_in_insert = false,
|
||||
underline = true,
|
||||
severity_sort = true,
|
||||
float = {
|
||||
focusable = false,
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
source = "always",
|
||||
header = "",
|
||||
prefix = "",
|
||||
format = function(d)
|
||||
local t = vim.deepcopy(d)
|
||||
local code = d.code or (d.user_data and d.user_data.lsp.code)
|
||||
if code then
|
||||
t.message = string.format("%s [%s]", t.message, code):gsub("1. ", "")
|
||||
end
|
||||
return t.message
|
||||
end,
|
||||
},
|
||||
},
|
||||
document_highlight = true,
|
||||
code_lens_refresh = true,
|
||||
float = {
|
||||
focusable = true,
|
||||
style = "minimal",
|
||||
border = "rounded",
|
||||
},
|
||||
peek = {
|
||||
max_height = 15,
|
||||
max_width = 30,
|
||||
context = 10,
|
||||
},
|
||||
on_attach_callback = nil,
|
||||
on_init_callback = nil,
|
||||
automatic_servers_installation = true,
|
||||
automatic_configuration = {
|
||||
---@usage list of servers that the automatic installer will skip
|
||||
skipped_servers = skipped_servers,
|
||||
---@usage list of filetypes that the automatic installer will skip
|
||||
skipped_filetypes = skipped_filetypes,
|
||||
},
|
||||
buffer_mappings = {
|
||||
normal_mode = {
|
||||
["K"] = { vim.lsp.buf.hover, "Show hover" },
|
||||
["gd"] = { vim.lsp.buf.definition, "Goto Definition" },
|
||||
["gD"] = { vim.lsp.buf.declaration, "Goto declaration" },
|
||||
["gr"] = { vim.lsp.buf.references, "Goto references" },
|
||||
["gI"] = { vim.lsp.buf.implementation, "Goto Implementation" },
|
||||
["gs"] = { vim.lsp.buf.signature_help, "show signature help" },
|
||||
["gp"] = {
|
||||
function()
|
||||
require("lvim.lsp.peek").Peek "definition"
|
||||
end,
|
||||
"Peek definition",
|
||||
},
|
||||
["gl"] = {
|
||||
function()
|
||||
local config = lvim.lsp.diagnostics.float
|
||||
config.scope = "line"
|
||||
vim.diagnostic.open_float(0, config)
|
||||
end,
|
||||
"Show line diagnostics",
|
||||
},
|
||||
},
|
||||
insert_mode = {},
|
||||
visual_mode = {},
|
||||
},
|
||||
null_ls = {
|
||||
setup = {},
|
||||
config = {},
|
||||
},
|
||||
---@deprecated use automatic_configuration.skipped_servers instead
|
||||
override = {},
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
-- Set Default Prefix.
|
||||
-- Note: You can set a prefix per lsp server in the lv-globals.lua file
|
||||
local M = {}
|
||||
|
||||
function M.setup()
|
||||
local config = { -- your config
|
||||
virtual_text = lvim.lsp.diagnostics.virtual_text,
|
||||
signs = lvim.lsp.diagnostics.signs,
|
||||
underline = lvim.lsp.diagnostics.underline,
|
||||
update_in_insert = lvim.lsp.diagnostics.update_in_insert,
|
||||
severity_sort = lvim.lsp.diagnostics.severity_sort,
|
||||
float = lvim.lsp.diagnostics.float,
|
||||
}
|
||||
vim.diagnostic.config(config)
|
||||
vim.lsp.handlers["textDocument/hover"] = vim.lsp.with(vim.lsp.handlers.hover, lvim.lsp.float)
|
||||
vim.lsp.handlers["textDocument/signatureHelp"] = vim.lsp.with(vim.lsp.handlers.signature_help, lvim.lsp.float)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,135 @@
|
|||
local M = {}
|
||||
local Log = require "lvim.core.log"
|
||||
local utils = require "lvim.utils"
|
||||
local autocmds = require "lvim.core.autocmds"
|
||||
|
||||
local function add_lsp_buffer_keybindings(bufnr)
|
||||
local mappings = {
|
||||
normal_mode = "n",
|
||||
insert_mode = "i",
|
||||
visual_mode = "v",
|
||||
}
|
||||
|
||||
if lvim.builtin.which_key.active then
|
||||
-- Remap using which_key
|
||||
local status_ok, wk = pcall(require, "which-key")
|
||||
if not status_ok then
|
||||
return
|
||||
end
|
||||
for mode_name, mode_char in pairs(mappings) do
|
||||
wk.register(lvim.lsp.buffer_mappings[mode_name], { mode = mode_char, buffer = bufnr })
|
||||
end
|
||||
else
|
||||
-- Remap using nvim api
|
||||
for mode_name, mode_char in pairs(mappings) do
|
||||
for key, remap in pairs(lvim.lsp.buffer_mappings[mode_name]) do
|
||||
vim.api.nvim_buf_set_keymap(bufnr, mode_char, key, remap[1], { noremap = true, silent = true })
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function M.common_capabilities()
|
||||
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
||||
capabilities.textDocument.completion.completionItem.snippetSupport = true
|
||||
capabilities.textDocument.completion.completionItem.resolveSupport = {
|
||||
properties = {
|
||||
"documentation",
|
||||
"detail",
|
||||
"additionalTextEdits",
|
||||
},
|
||||
}
|
||||
|
||||
local status_ok, cmp_nvim_lsp = pcall(require, "cmp_nvim_lsp")
|
||||
if status_ok then
|
||||
capabilities = cmp_nvim_lsp.update_capabilities(capabilities)
|
||||
end
|
||||
|
||||
return capabilities
|
||||
end
|
||||
|
||||
function M.common_on_exit(_, _)
|
||||
if lvim.lsp.document_highlight then
|
||||
autocmds.clear_augroup "lsp_document_highlight"
|
||||
end
|
||||
if lvim.lsp.code_lens_refresh then
|
||||
autocmds.clear_augroup "lsp_code_lens_refresh"
|
||||
end
|
||||
end
|
||||
|
||||
function M.common_on_init(client, bufnr)
|
||||
if lvim.lsp.on_init_callback then
|
||||
lvim.lsp.on_init_callback(client, bufnr)
|
||||
Log:debug "Called lsp.on_init_callback"
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
function M.common_on_attach(client, bufnr)
|
||||
if lvim.lsp.on_attach_callback then
|
||||
lvim.lsp.on_attach_callback(client, bufnr)
|
||||
Log:debug "Called lsp.on_attach_callback"
|
||||
end
|
||||
local lu = require "lvim.lsp.utils"
|
||||
if lvim.lsp.document_highlight then
|
||||
lu.setup_document_highlight(client, bufnr)
|
||||
end
|
||||
if lvim.lsp.code_lens_refresh then
|
||||
lu.setup_codelens_refresh(client, bufnr)
|
||||
end
|
||||
add_lsp_buffer_keybindings(bufnr)
|
||||
end
|
||||
|
||||
local function bootstrap_nlsp(opts)
|
||||
opts = opts or {}
|
||||
local lsp_settings_status_ok, lsp_settings = pcall(require, "nlspsettings")
|
||||
if lsp_settings_status_ok then
|
||||
lsp_settings.setup(opts)
|
||||
end
|
||||
end
|
||||
|
||||
function M.get_common_opts()
|
||||
return {
|
||||
on_attach = M.common_on_attach,
|
||||
on_init = M.common_on_init,
|
||||
on_exit = M.common_on_exit,
|
||||
capabilities = M.common_capabilities(),
|
||||
}
|
||||
end
|
||||
|
||||
function M.setup()
|
||||
Log:debug "Setting up LSP support"
|
||||
|
||||
local lsp_status_ok, _ = pcall(require, "lspconfig")
|
||||
if not lsp_status_ok then
|
||||
return
|
||||
end
|
||||
|
||||
if lvim.use_icons then
|
||||
for _, sign in ipairs(lvim.lsp.diagnostics.signs.values) do
|
||||
vim.fn.sign_define(sign.name, { texthl = sign.name, text = sign.text, numhl = sign.name })
|
||||
end
|
||||
end
|
||||
|
||||
require("lvim.lsp.handlers").setup()
|
||||
|
||||
if not utils.is_directory(lvim.lsp.templates_dir) then
|
||||
require("lvim.lsp.templates").generate_templates()
|
||||
end
|
||||
|
||||
bootstrap_nlsp {
|
||||
config_home = utils.join_paths(get_config_dir(), "lsp-settings"),
|
||||
append_default_schemas = true,
|
||||
}
|
||||
|
||||
require("nvim-lsp-installer").setup {
|
||||
-- use the default nvim_data_dir, since the server binaries are independent
|
||||
install_root_dir = utils.join_paths(vim.call("stdpath", "data"), "lsp_servers"),
|
||||
}
|
||||
|
||||
require("lvim.lsp.null-ls").setup()
|
||||
|
||||
autocmds.configure_format_on_save()
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,99 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
local lvim_lsp_utils = require "lvim.lsp.utils"
|
||||
|
||||
---Resolve the configuration for a server by merging with the default config
|
||||
---@param server_name string
|
||||
---@vararg any config table [optional]
|
||||
---@return table
|
||||
local function resolve_config(server_name, ...)
|
||||
local defaults = {
|
||||
on_attach = require("lvim.lsp").common_on_attach,
|
||||
on_init = require("lvim.lsp").common_on_init,
|
||||
on_exit = require("lvim.lsp").common_on_exit,
|
||||
capabilities = require("lvim.lsp").common_capabilities(),
|
||||
}
|
||||
|
||||
local has_custom_provider, custom_config = pcall(require, "lvim/lsp/providers/" .. server_name)
|
||||
if has_custom_provider then
|
||||
Log:debug("Using custom configuration for requested server: " .. server_name)
|
||||
defaults = vim.tbl_deep_extend("force", defaults, custom_config)
|
||||
end
|
||||
|
||||
defaults = vim.tbl_deep_extend("force", defaults, ...)
|
||||
|
||||
return defaults
|
||||
end
|
||||
|
||||
-- manually start the server and don't wait for the usual filetype trigger from lspconfig
|
||||
local function buf_try_add(server_name, bufnr)
|
||||
bufnr = bufnr or vim.api.nvim_get_current_buf()
|
||||
require("lspconfig")[server_name].manager.try_add_wrapper(bufnr)
|
||||
end
|
||||
|
||||
-- check if the manager autocomd has already been configured since some servers can take a while to initialize
|
||||
-- this helps guarding against a data-race condition where a server can get configured twice
|
||||
-- which seems to occur only when attaching to single-files
|
||||
local function client_is_configured(server_name, ft)
|
||||
ft = ft or vim.bo.filetype
|
||||
local active_autocmds = vim.split(vim.fn.execute("autocmd FileType " .. ft), "\n")
|
||||
for _, result in ipairs(active_autocmds) do
|
||||
if result:match(server_name) then
|
||||
Log:debug(string.format("[%q] is already configured", server_name))
|
||||
return true
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
local function launch_server(server_name, config)
|
||||
pcall(function()
|
||||
require("lspconfig")[server_name].setup(config)
|
||||
buf_try_add(server_name)
|
||||
end)
|
||||
end
|
||||
|
||||
---Setup a language server by providing a name
|
||||
---@param server_name string name of the language server
|
||||
---@param user_config table? when available it will take predence over any default configurations
|
||||
function M.setup(server_name, user_config)
|
||||
vim.validate { name = { server_name, "string" } }
|
||||
user_config = user_config or {}
|
||||
|
||||
if lvim_lsp_utils.is_client_active(server_name) or client_is_configured(server_name) then
|
||||
return
|
||||
end
|
||||
|
||||
local servers = require "nvim-lsp-installer.servers"
|
||||
local server_available, server = servers.get_server(server_name)
|
||||
|
||||
if not server_available then
|
||||
local config = resolve_config(server_name, user_config)
|
||||
launch_server(server_name, config)
|
||||
return
|
||||
end
|
||||
|
||||
local install_in_progress = false
|
||||
|
||||
if not server:is_installed() then
|
||||
if lvim.lsp.automatic_servers_installation then
|
||||
Log:debug "Automatic server installation detected"
|
||||
server:install()
|
||||
install_in_progress = true
|
||||
else
|
||||
Log:debug(server.name .. " is not managed by the automatic installer")
|
||||
end
|
||||
end
|
||||
|
||||
server:on_ready(function()
|
||||
if install_in_progress then
|
||||
vim.notify(string.format("Installation complete for [%s] server", server.name), vim.log.levels.INFO)
|
||||
end
|
||||
install_in_progress = false
|
||||
local config = resolve_config(server_name, server:get_default_options(), user_config)
|
||||
launch_server(server_name, config)
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,26 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local null_ls = require "null-ls"
|
||||
local services = require "lvim.lsp.null-ls.services"
|
||||
local method = null_ls.methods.CODE_ACTION
|
||||
|
||||
function M.list_registered(filetype)
|
||||
local registered_providers = services.list_registered_providers_names(filetype)
|
||||
return registered_providers[method] or {}
|
||||
end
|
||||
|
||||
function M.setup(actions_configs)
|
||||
if vim.tbl_isempty(actions_configs) then
|
||||
return
|
||||
end
|
||||
|
||||
local registered = services.register_sources(actions_configs, method)
|
||||
|
||||
if #registered > 0 then
|
||||
Log:debug("Registered the following action-handlers: " .. unpack(registered))
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,33 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local null_ls = require "null-ls"
|
||||
local services = require "lvim.lsp.null-ls.services"
|
||||
local method = null_ls.methods.FORMATTING
|
||||
|
||||
function M.list_registered(filetype)
|
||||
local registered_providers = services.list_registered_providers_names(filetype)
|
||||
return registered_providers[method] or {}
|
||||
end
|
||||
|
||||
function M.list_supported(filetype)
|
||||
local s = require "null-ls.sources"
|
||||
local supported_formatters = s.get_supported(filetype, "formatting")
|
||||
table.sort(supported_formatters)
|
||||
return supported_formatters
|
||||
end
|
||||
|
||||
function M.setup(formatter_configs)
|
||||
if vim.tbl_isempty(formatter_configs) then
|
||||
return
|
||||
end
|
||||
|
||||
local registered = services.register_sources(formatter_configs, method)
|
||||
|
||||
if #registered > 0 then
|
||||
Log:debug("Registered the following formatters: " .. unpack(registered))
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,16 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
function M.setup()
|
||||
local status_ok, null_ls = pcall(require, "null-ls")
|
||||
if not status_ok then
|
||||
Log:error "Missing null-ls dependency"
|
||||
return
|
||||
end
|
||||
|
||||
local default_opts = require("lvim.lsp").get_common_opts()
|
||||
null_ls.setup(vim.tbl_deep_extend("force", default_opts, lvim.lsp.null_ls.setup))
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,33 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local null_ls = require "null-ls"
|
||||
local services = require "lvim.lsp.null-ls.services"
|
||||
local method = null_ls.methods.DIAGNOSTICS
|
||||
|
||||
function M.list_registered(filetype)
|
||||
local registered_providers = services.list_registered_providers_names(filetype)
|
||||
return registered_providers[method] or {}
|
||||
end
|
||||
|
||||
function M.list_supported(filetype)
|
||||
local s = require "null-ls.sources"
|
||||
local supported_linters = s.get_supported(filetype, "diagnostics")
|
||||
table.sort(supported_linters)
|
||||
return supported_linters
|
||||
end
|
||||
|
||||
function M.setup(linter_configs)
|
||||
if vim.tbl_isempty(linter_configs) then
|
||||
return
|
||||
end
|
||||
|
||||
local registered = services.register_sources(linter_configs, method)
|
||||
|
||||
if #registered > 0 then
|
||||
Log:debug("Registered the following linters: " .. unpack(registered))
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,104 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
|
||||
local function find_root_dir()
|
||||
local util = require "lspconfig/util"
|
||||
local lsp_utils = require "lvim.lsp.utils"
|
||||
|
||||
local ts_client = lsp_utils.is_client_active "typescript"
|
||||
if ts_client then
|
||||
return ts_client.config.root_dir
|
||||
end
|
||||
local dirname = vim.fn.expand "%:p:h"
|
||||
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
|
||||
|
||||
local join_paths = require("lvim.utils").join_paths
|
||||
return join_paths(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 },
|
||||
stylelint = { 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 command and vim.fn.executable(command) == 1 then
|
||||
return command
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
function M.list_registered_providers_names(filetype)
|
||||
local s = require "null-ls.sources"
|
||||
local available_sources = s.get_available(filetype)
|
||||
local registered = {}
|
||||
for _, source in ipairs(available_sources) do
|
||||
for method in pairs(source.methods) do
|
||||
registered[method] = registered[method] or {}
|
||||
table.insert(registered[method], source.name)
|
||||
end
|
||||
end
|
||||
return registered
|
||||
end
|
||||
|
||||
function M.register_sources(configs, method)
|
||||
local null_ls = require "null-ls"
|
||||
local is_registered = require("null-ls.sources").is_registered
|
||||
|
||||
local sources, registered_names = {}, {}
|
||||
|
||||
for _, config in ipairs(configs) do
|
||||
local cmd = config.exe or config.command
|
||||
local name = config.name or cmd:gsub("-", "_")
|
||||
local type = method == null_ls.methods.CODE_ACTION and "code_actions" or null_ls.methods[method]:lower()
|
||||
local source = type and null_ls.builtins[type][name]
|
||||
Log:debug(string.format("Received request to register [%s] as a %s source", name, type))
|
||||
if not source then
|
||||
Log:error("Not a valid source: " .. name)
|
||||
elseif is_registered { name = source.name or name, method = method } then
|
||||
Log:trace(string.format("Skipping registering [%s] more than once", name))
|
||||
else
|
||||
local command = M.find_command(source._opts.command) or source._opts.command
|
||||
|
||||
-- treat `args` as `extra_args` for backwards compatibility. Can otherwise use `generator_opts.args`
|
||||
local compat_opts = vim.deepcopy(config)
|
||||
if config.args then
|
||||
compat_opts.extra_args = config.args or config.extra_args
|
||||
compat_opts.args = nil
|
||||
end
|
||||
|
||||
local opts = vim.tbl_deep_extend("keep", { command = command }, compat_opts)
|
||||
Log:debug("Registering source " .. name)
|
||||
Log:trace(vim.inspect(opts))
|
||||
table.insert(sources, source.with(opts))
|
||||
vim.list_extend(registered_names, { source.name })
|
||||
end
|
||||
end
|
||||
|
||||
if #sources > 0 then
|
||||
null_ls.register { sources = sources }
|
||||
end
|
||||
return registered_names
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,157 @@
|
|||
local M = {
|
||||
floating_buf = nil,
|
||||
floating_win = nil,
|
||||
prev_result = nil,
|
||||
}
|
||||
|
||||
local function create_floating_file(location, opts)
|
||||
vim.validate {
|
||||
location = { location, "t" },
|
||||
opts = { opts, "t", true },
|
||||
}
|
||||
|
||||
-- Set some defaults
|
||||
opts = opts or {}
|
||||
local close_events = opts.close_events or { "CursorMoved", "CursorMovedI", "BufHidden", "InsertCharPre" }
|
||||
|
||||
-- location may be LocationLink or Location
|
||||
local uri = location.targetUri or location.uri
|
||||
if uri == nil then
|
||||
return
|
||||
end
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
if not vim.api.nvim_buf_is_loaded(bufnr) then
|
||||
vim.fn.bufload(bufnr)
|
||||
end
|
||||
|
||||
local range = location.targetRange or location.range
|
||||
|
||||
local contents = vim.api.nvim_buf_get_lines(
|
||||
bufnr,
|
||||
range.start.line,
|
||||
math.min(
|
||||
range["end"].line + 1 + (opts.context or lvim.lsp.peek.max_height),
|
||||
range.start.line + (opts.max_height or lvim.lsp.peek.max_height)
|
||||
),
|
||||
false
|
||||
)
|
||||
if next(contents) == nil then
|
||||
vim.notify("peek: Unable to get contents of the file!", vim.log.levels.WARN)
|
||||
return
|
||||
end
|
||||
local width, height = vim.lsp.util._make_floating_popup_size(contents, opts)
|
||||
local if_nil = vim.F.if_nil
|
||||
opts = vim.lsp.util.make_floating_popup_options(
|
||||
if_nil(width, lvim.lsp.peek.max_width),
|
||||
if_nil(height, lvim.lsp.peek.max_height),
|
||||
opts
|
||||
)
|
||||
-- Don't make it minimal as it is meant to be fully featured
|
||||
opts["style"] = nil
|
||||
|
||||
vim.api.nvim_buf_set_option(bufnr, "bufhidden", "wipe")
|
||||
|
||||
local winnr = vim.api.nvim_open_win(bufnr, false, opts)
|
||||
vim.api.nvim_win_set_option(winnr, "winblend", 0)
|
||||
|
||||
vim.api.nvim_win_set_cursor(winnr, { range.start.line + 1, range.start.character })
|
||||
vim.api.nvim_buf_set_var(bufnr, "lsp_floating_window", winnr)
|
||||
|
||||
-- Set some autocmds to close the window
|
||||
vim.api.nvim_command(
|
||||
string.format("autocmd %s <buffer> ++once lua pcall(vim.api.nvim_win_close, %d, true)", unpack(close_events), winnr)
|
||||
)
|
||||
|
||||
return bufnr, winnr
|
||||
end
|
||||
|
||||
local function preview_location_callback(result)
|
||||
if result == nil or vim.tbl_isempty(result) then
|
||||
return nil
|
||||
end
|
||||
|
||||
local opts = {
|
||||
border = "rounded",
|
||||
context = lvim.lsp.peek.context,
|
||||
}
|
||||
|
||||
if vim.tbl_islist(result) then
|
||||
M.prev_result = result[1]
|
||||
M.floating_buf, M.floating_win = create_floating_file(result[1], opts)
|
||||
else
|
||||
M.prev_result = result
|
||||
M.floating_buf, M.floating_win = create_floating_file(result, opts)
|
||||
end
|
||||
end
|
||||
|
||||
local function preview_location_callback_new_signature(_, result)
|
||||
return preview_location_callback(result)
|
||||
end
|
||||
|
||||
function M.open_file()
|
||||
-- Get the file currently open in the floating window
|
||||
local filepath = vim.fn.expand "%:."
|
||||
|
||||
if not filepath then
|
||||
vim.notify("peek: Unable to open the file!", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
-- Close the floating window
|
||||
pcall(vim.api.nvim_win_close, M.floating_win, true)
|
||||
|
||||
-- Edit the file
|
||||
vim.cmd("edit " .. filepath)
|
||||
|
||||
local winnr = vim.api.nvim_get_current_win()
|
||||
|
||||
-- Set the cursor at the right position
|
||||
M.set_cursor_to_prev_pos(winnr)
|
||||
end
|
||||
|
||||
function M.set_cursor_to_prev_pos(winnr)
|
||||
-- Get position of the thing to peek at
|
||||
local location = M.prev_result
|
||||
local range = location.targetRange or location.range
|
||||
local cursor_pos = { range.start.line + 1, range.start.character }
|
||||
|
||||
-- Set the winnr to the floating window if none was passed in
|
||||
winnr = winnr or M.floating_win
|
||||
-- Set the cursor at the correct position in the floating window
|
||||
vim.api.nvim_win_set_cursor(winnr, cursor_pos)
|
||||
end
|
||||
|
||||
function M.Peek(what)
|
||||
-- If a window already exists, focus it at the right position!
|
||||
if vim.tbl_contains(vim.api.nvim_list_wins(), M.floating_win) then
|
||||
local success_1, _ = pcall(vim.api.nvim_set_current_win, M.floating_win)
|
||||
if not success_1 then
|
||||
vim.notify("peek: You cannot edit the current file in a preview!", vim.log.levels.ERROR)
|
||||
return
|
||||
end
|
||||
|
||||
-- Set the cursor at the correct position in the floating window
|
||||
M.set_cursor_to_prev_pos()
|
||||
|
||||
vim.api.nvim_buf_set_keymap(
|
||||
M.floating_buf,
|
||||
"n",
|
||||
"<CR>",
|
||||
":lua require('lvim.lsp.peek').open_file()<CR>",
|
||||
{ noremap = true, silent = true }
|
||||
)
|
||||
else
|
||||
-- Make a new request and then create the new window in the callback
|
||||
local params = vim.lsp.util.make_position_params()
|
||||
local preview_callback = preview_location_callback_new_signature
|
||||
local success, _ = pcall(vim.lsp.buf_request, 0, "textDocument/" .. what, params, preview_callback)
|
||||
if not success then
|
||||
vim.notify(
|
||||
'peek: Error calling LSP method "textDocument/' .. what .. '". The current language lsp might not support it.',
|
||||
vim.log.levels.ERROR
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,23 @@
|
|||
local full_schemas = vim.tbl_deep_extend(
|
||||
"force",
|
||||
require("schemastore").json.schemas(),
|
||||
require("nlspsettings.jsonls").get_default_schemas()
|
||||
)
|
||||
local opts = {
|
||||
settings = {
|
||||
json = {
|
||||
schemas = full_schemas,
|
||||
},
|
||||
},
|
||||
setup = {
|
||||
commands = {
|
||||
Format = {
|
||||
function()
|
||||
vim.lsp.buf.range_formatting({}, { 0, 0 }, { vim.fn.line "$", 0 })
|
||||
end,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return opts
|
|
@ -0,0 +1,34 @@
|
|||
local opts = {
|
||||
settings = {
|
||||
Lua = {
|
||||
diagnostics = {
|
||||
globals = { "vim", "lvim", "packer_plugins" },
|
||||
},
|
||||
workspace = {
|
||||
library = {
|
||||
[require("lvim.utils").join_paths(get_runtime_dir(), "lvim", "lua")] = true,
|
||||
},
|
||||
maxPreload = 100000,
|
||||
preloadFileSize = 10000,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
local lua_dev_loaded, lua_dev = pcall(require, "lua-dev")
|
||||
if not lua_dev_loaded then
|
||||
return opts
|
||||
end
|
||||
|
||||
local dev_opts = {
|
||||
library = {
|
||||
vimruntime = true, -- runtime path
|
||||
types = true, -- full signature, docs and completion of vim.api, vim.treesitter, vim.lsp and others
|
||||
-- plugins = true, -- installed opt or start plugins in packpath
|
||||
-- you can also specify the list of plugins to make available as a workspace library
|
||||
plugins = { "plenary.nvim" },
|
||||
},
|
||||
lspconfig = opts,
|
||||
}
|
||||
|
||||
return lua_dev.setup(dev_opts)
|
|
@ -0,0 +1,26 @@
|
|||
local opts = {
|
||||
setup = {
|
||||
root_dir = function(fname)
|
||||
local util = require "lvim.lspconfig/util"
|
||||
return util.root_pattern "package.json"(fname) or util.root_pattern "vue.config.js"(fname) or vim.fn.getcwd()
|
||||
end,
|
||||
init_options = {
|
||||
config = {
|
||||
vetur = {
|
||||
completion = {
|
||||
autoImport = true,
|
||||
tagCasing = "kebab",
|
||||
useScaffoldSnippets = true,
|
||||
},
|
||||
useWorkspaceDependencies = true,
|
||||
validation = {
|
||||
script = true,
|
||||
style = true,
|
||||
template = true,
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
return opts
|
|
@ -0,0 +1,30 @@
|
|||
local opts = {
|
||||
settings = {
|
||||
yaml = {
|
||||
hover = true,
|
||||
completion = true,
|
||||
validate = true,
|
||||
schemaStore = {
|
||||
enable = true,
|
||||
url = "https://www.schemastore.org/api/json/catalog.json",
|
||||
},
|
||||
schemas = {
|
||||
kubernetes = {
|
||||
"daemon.{yml,yaml}",
|
||||
"manager.{yml,yaml}",
|
||||
"restapi.{yml,yaml}",
|
||||
"role.{yml,yaml}",
|
||||
"role_binding.{yml,yaml}",
|
||||
"*onfigma*.{yml,yaml}",
|
||||
"*ngres*.{yml,yaml}",
|
||||
"*ecre*.{yml,yaml}",
|
||||
"*eployment*.{yml,yaml}",
|
||||
"*ervic*.{yml,yaml}",
|
||||
"kubectl-edit*.yaml",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
return opts
|
|
@ -0,0 +1,77 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
local utils = require "lvim.utils"
|
||||
local lvim_lsp_utils = require "lvim.lsp.utils"
|
||||
|
||||
local ftplugin_dir = lvim.lsp.templates_dir
|
||||
|
||||
local join_paths = _G.join_paths
|
||||
|
||||
function M.remove_template_files()
|
||||
-- remove any outdated files
|
||||
for _, file in ipairs(vim.fn.glob(ftplugin_dir .. "/*.lua", 1, 1)) do
|
||||
vim.fn.delete(file)
|
||||
end
|
||||
end
|
||||
|
||||
local skipped_filetypes = lvim.lsp.automatic_configuration.skipped_filetypes
|
||||
local skipped_servers = lvim.lsp.automatic_configuration.skipped_servers
|
||||
|
||||
---Generates an ftplugin file based on the server_name in the selected directory
|
||||
---@param server_name string name of a valid language server, e.g. pyright, gopls, tsserver, etc.
|
||||
---@param dir string the full path to the desired directory
|
||||
function M.generate_ftplugin(server_name, dir)
|
||||
if vim.tbl_contains(skipped_servers, server_name) then
|
||||
return
|
||||
end
|
||||
|
||||
-- get the supported filetypes and remove any ignored ones
|
||||
local filetypes = vim.tbl_filter(function(ft)
|
||||
return not vim.tbl_contains(skipped_filetypes, ft)
|
||||
end, lvim_lsp_utils.get_supported_filetypes(server_name) or {})
|
||||
|
||||
if not filetypes then
|
||||
return
|
||||
end
|
||||
|
||||
for _, filetype in ipairs(filetypes) do
|
||||
local filename = join_paths(dir, filetype .. ".lua")
|
||||
local setup_cmd = string.format([[require("lvim.lsp.manager").setup(%q)]], server_name)
|
||||
-- print("using setup_cmd: " .. setup_cmd)
|
||||
-- overwrite the file completely
|
||||
utils.write_file(filename, setup_cmd .. "\n", "a")
|
||||
end
|
||||
end
|
||||
|
||||
---Generates ftplugin files based on a list of server_names
|
||||
---The files are generated to a runtimepath: "$LUNARVIM_RUNTIME_DIR/site/after/ftplugin/template.lua"
|
||||
---@param servers_names? table list of servers to be enabled. Will add all by default
|
||||
function M.generate_templates(servers_names)
|
||||
servers_names = servers_names or {}
|
||||
|
||||
Log:debug "Templates installation in progress"
|
||||
|
||||
M.remove_template_files()
|
||||
|
||||
if vim.tbl_isempty(servers_names) then
|
||||
local available_servers = require("nvim-lsp-installer.servers").get_available_servers()
|
||||
|
||||
for _, server in pairs(available_servers) do
|
||||
table.insert(servers_names, server.name)
|
||||
table.sort(servers_names)
|
||||
end
|
||||
end
|
||||
|
||||
-- create the directory if it didn't exist
|
||||
if not utils.is_directory(lvim.lsp.templates_dir) then
|
||||
vim.fn.mkdir(ftplugin_dir, "p")
|
||||
end
|
||||
|
||||
for _, server in ipairs(servers_names) do
|
||||
M.generate_ftplugin(server, ftplugin_dir)
|
||||
end
|
||||
Log:debug "Templates installation is complete"
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,194 @@
|
|||
local M = {}
|
||||
|
||||
local tbl = require "lvim.utils.table"
|
||||
|
||||
function M.is_client_active(name)
|
||||
local clients = vim.lsp.get_active_clients()
|
||||
return tbl.find_first(clients, function(client)
|
||||
return client.name == name
|
||||
end)
|
||||
end
|
||||
|
||||
function M.get_active_clients_by_ft(filetype)
|
||||
local matches = {}
|
||||
local clients = vim.lsp.get_active_clients()
|
||||
for _, client in pairs(clients) do
|
||||
local supported_filetypes = client.config.filetypes or {}
|
||||
if client.name ~= "null-ls" and vim.tbl_contains(supported_filetypes, filetype) then
|
||||
table.insert(matches, client)
|
||||
end
|
||||
end
|
||||
return matches
|
||||
end
|
||||
|
||||
function M.get_client_capabilities(client_id)
|
||||
local client
|
||||
if not client_id then
|
||||
local buf_clients = vim.lsp.buf_get_clients()
|
||||
for _, buf_client in pairs(buf_clients) do
|
||||
if buf_client.name ~= "null-ls" then
|
||||
client = buf_client
|
||||
break
|
||||
end
|
||||
end
|
||||
else
|
||||
client = vim.lsp.get_client_by_id(tonumber(client_id))
|
||||
end
|
||||
if not client then
|
||||
error "Unable to determine client_id"
|
||||
return
|
||||
end
|
||||
|
||||
local enabled_caps = {}
|
||||
for capability, status in pairs(client.server_capabilities or client.resolved_capabilities) do
|
||||
if status == true then
|
||||
table.insert(enabled_caps, capability)
|
||||
end
|
||||
end
|
||||
|
||||
return enabled_caps
|
||||
end
|
||||
|
||||
---Get supported filetypes per server
|
||||
---@param server_name string can be any server supported by nvim-lsp-installer
|
||||
---@return table supported filestypes as a list of strings
|
||||
function M.get_supported_filetypes(server_name)
|
||||
local status_ok, lsp_installer_servers = pcall(require, "nvim-lsp-installer.servers")
|
||||
if not status_ok then
|
||||
return {}
|
||||
end
|
||||
|
||||
local server_available, requested_server = lsp_installer_servers.get_server(server_name)
|
||||
if not server_available then
|
||||
return {}
|
||||
end
|
||||
|
||||
return requested_server:get_supported_filetypes()
|
||||
end
|
||||
|
||||
---Get supported servers per filetype
|
||||
---@param filetype string
|
||||
---@return table list of names of supported servers
|
||||
function M.get_supported_servers_per_filetype(filetype)
|
||||
local filetype_server_map = require "nvim-lsp-installer._generated.filetype_map"
|
||||
return filetype_server_map[filetype]
|
||||
end
|
||||
|
||||
---Get all supported filetypes by nvim-lsp-installer
|
||||
---@return table supported filestypes as a list of strings
|
||||
function M.get_all_supported_filetypes()
|
||||
local status_ok, lsp_installer_filetypes = pcall(require, "nvim-lsp-installer._generated.filetype_map")
|
||||
if not status_ok then
|
||||
return {}
|
||||
end
|
||||
return vim.tbl_keys(lsp_installer_filetypes or {})
|
||||
end
|
||||
|
||||
function M.setup_document_highlight(client, bufnr)
|
||||
local status_ok, highlight_supported = pcall(function()
|
||||
return client.supports_method "textDocument/documentHighlight"
|
||||
end)
|
||||
if not status_ok or not highlight_supported then
|
||||
return
|
||||
end
|
||||
local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, {
|
||||
group = "lsp_document_highlight",
|
||||
})
|
||||
if not augroup_exist then
|
||||
vim.api.nvim_create_augroup("lsp_document_highlight", {})
|
||||
end
|
||||
vim.api.nvim_create_autocmd({ "CursorHold", "CursorHoldI" }, {
|
||||
group = "lsp_document_highlight",
|
||||
buffer = bufnr,
|
||||
callback = vim.lsp.buf.document_highlight,
|
||||
})
|
||||
vim.api.nvim_create_autocmd("CursorMoved", {
|
||||
group = "lsp_document_highlight",
|
||||
buffer = bufnr,
|
||||
callback = vim.lsp.buf.clear_references,
|
||||
})
|
||||
end
|
||||
|
||||
function M.setup_codelens_refresh(client, bufnr)
|
||||
local status_ok, codelens_supported = pcall(function()
|
||||
return client.supports_method "textDocument/codeLens"
|
||||
end)
|
||||
if not status_ok or not codelens_supported then
|
||||
return
|
||||
end
|
||||
local augroup_exist, _ = pcall(vim.api.nvim_get_autocmds, {
|
||||
group = "lsp_code_lens_refresh",
|
||||
})
|
||||
if not augroup_exist then
|
||||
vim.api.nvim_create_augroup("lsp_code_lens_refresh", {})
|
||||
end
|
||||
vim.api.nvim_create_autocmd({ "BufEnter", "InsertLeave" }, {
|
||||
group = "lsp_code_lens_refresh",
|
||||
buffer = bufnr,
|
||||
callback = vim.lsp.codelens.refresh,
|
||||
})
|
||||
end
|
||||
|
||||
---filter passed to vim.lsp.buf.format
|
||||
---gives higher priority to null-ls
|
||||
---@param clients table clients attached to a buffer
|
||||
---@return table chosen clients
|
||||
function M.format_filter(clients)
|
||||
return vim.tbl_filter(function(client)
|
||||
local status_ok, formatting_supported = pcall(function()
|
||||
return client.supports_method "textDocument/formatting"
|
||||
end)
|
||||
-- give higher prio to null-ls
|
||||
if status_ok and formatting_supported and client.name == "null-ls" then
|
||||
return "null-ls"
|
||||
else
|
||||
return status_ok and formatting_supported and client.name
|
||||
end
|
||||
end, clients)
|
||||
end
|
||||
|
||||
---Provide vim.lsp.buf.format for nvim <0.8
|
||||
---@param opts table
|
||||
function M.format(opts)
|
||||
opts = opts or { filter = M.format_filter }
|
||||
|
||||
if vim.lsp.buf.format then
|
||||
return vim.lsp.buf.format(opts)
|
||||
end
|
||||
|
||||
local bufnr = opts.bufnr or vim.api.nvim_get_current_buf()
|
||||
local clients = vim.lsp.buf_get_clients(bufnr)
|
||||
|
||||
if opts.filter then
|
||||
clients = opts.filter(clients)
|
||||
elseif opts.id then
|
||||
clients = vim.tbl_filter(function(client)
|
||||
return client.id == opts.id
|
||||
end, clients)
|
||||
elseif opts.name then
|
||||
clients = vim.tbl_filter(function(client)
|
||||
return client.name == opts.name
|
||||
end, clients)
|
||||
end
|
||||
|
||||
clients = vim.tbl_filter(function(client)
|
||||
return client.supports_method "textDocument/formatting"
|
||||
end, clients)
|
||||
|
||||
if #clients == 0 then
|
||||
vim.notify_once "[LSP] Format request failed, no matching language servers."
|
||||
end
|
||||
|
||||
local timeout_ms = opts.timeout_ms or 1000
|
||||
for _, client in pairs(clients) do
|
||||
local params = vim.lsp.util.make_formatting_params(opts.formatting_options)
|
||||
local result, err = client.request_sync("textDocument/formatting", params, timeout_ms, bufnr)
|
||||
if result and result.result then
|
||||
vim.lsp.util.apply_text_edits(result.result, bufnr, client.offset_encoding)
|
||||
elseif err then
|
||||
vim.notify(string.format("[LSP][%s] %s", client.name, err), vim.log.levels.WARN)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,166 @@
|
|||
local plugin_loader = {}
|
||||
|
||||
local utils = require "lvim.utils"
|
||||
local Log = require "lvim.core.log"
|
||||
local join_paths = utils.join_paths
|
||||
local in_headless = #vim.api.nvim_list_uis() == 0
|
||||
|
||||
-- we need to reuse this outside of init()
|
||||
local compile_path = join_paths(get_config_dir(), "plugin", "packer_compiled.lua")
|
||||
local snapshot_path = join_paths(get_cache_dir(), "snapshots")
|
||||
local default_snapshot = join_paths(get_lvim_base_dir(), "snapshots", "default.json")
|
||||
|
||||
function plugin_loader.init(opts)
|
||||
opts = opts or {}
|
||||
|
||||
local install_path = opts.install_path
|
||||
or join_paths(vim.fn.stdpath "data", "site", "pack", "packer", "start", "packer.nvim")
|
||||
|
||||
local init_opts = {
|
||||
package_root = opts.package_root or join_paths(vim.fn.stdpath "data", "site", "pack"),
|
||||
compile_path = compile_path,
|
||||
snapshot_path = snapshot_path,
|
||||
log = { level = "warn" },
|
||||
git = {
|
||||
clone_timeout = 300,
|
||||
},
|
||||
display = {
|
||||
open_fn = function()
|
||||
return require("packer.util").float { border = "rounded" }
|
||||
end,
|
||||
},
|
||||
}
|
||||
|
||||
if in_headless then
|
||||
init_opts.display = nil
|
||||
end
|
||||
|
||||
if not utils.is_directory(install_path) then
|
||||
vim.fn.system { "git", "clone", "--depth", "1", "https://github.com/wbthomason/packer.nvim", install_path }
|
||||
vim.cmd "packadd packer.nvim"
|
||||
-- IMPORTANT: we only set this the very first time to avoid constantly triggering the rollback function
|
||||
-- https://github.com/wbthomason/packer.nvim/blob/c576ab3f1488ee86d60fd340d01ade08dcabd256/lua/packer.lua#L998-L995
|
||||
init_opts.snapshot = default_snapshot
|
||||
end
|
||||
|
||||
local status_ok, packer = pcall(require, "packer")
|
||||
if status_ok then
|
||||
packer.on_complete = vim.schedule_wrap(function()
|
||||
require("lvim.utils.hooks").run_on_packer_complete()
|
||||
end)
|
||||
packer.init(init_opts)
|
||||
end
|
||||
end
|
||||
|
||||
-- packer expects a space separated list
|
||||
local function pcall_packer_command(cmd, kwargs)
|
||||
local status_ok, msg = pcall(function()
|
||||
require("packer")[cmd](unpack(kwargs or {}))
|
||||
end)
|
||||
if not status_ok then
|
||||
Log:warn(cmd .. " failed with: " .. vim.inspect(msg))
|
||||
Log:trace(vim.inspect(vim.fn.eval "v:errmsg"))
|
||||
end
|
||||
end
|
||||
|
||||
function plugin_loader.cache_clear()
|
||||
if vim.fn.delete(compile_path) == 0 then
|
||||
Log:debug "deleted packer_compiled.lua"
|
||||
end
|
||||
end
|
||||
|
||||
function plugin_loader.recompile()
|
||||
plugin_loader.cache_clear()
|
||||
pcall_packer_command "compile"
|
||||
if utils.is_file(compile_path) then
|
||||
Log:debug "generated packer_compiled.lua"
|
||||
end
|
||||
end
|
||||
|
||||
function plugin_loader.reload(configurations)
|
||||
_G.packer_plugins = _G.packer_plugins or {}
|
||||
for k, v in pairs(_G.packer_plugins) do
|
||||
if k ~= "packer.nvim" then
|
||||
_G.packer_plugins[v] = nil
|
||||
end
|
||||
end
|
||||
plugin_loader.load(configurations)
|
||||
|
||||
plugin_loader.ensure_plugins()
|
||||
end
|
||||
|
||||
function plugin_loader.load(configurations)
|
||||
Log:debug "loading plugins configuration"
|
||||
local packer_available, packer = pcall(require, "packer")
|
||||
if not packer_available then
|
||||
Log:warn "skipping loading plugins until Packer is installed"
|
||||
return
|
||||
end
|
||||
local status_ok, _ = xpcall(function()
|
||||
packer.reset()
|
||||
packer.startup(function(use)
|
||||
for _, plugins in ipairs(configurations) do
|
||||
for _, plugin in ipairs(plugins) do
|
||||
use(plugin)
|
||||
end
|
||||
end
|
||||
end)
|
||||
-- colorscheme must get called after plugins are loaded or it will break new installs.
|
||||
vim.g.colors_name = lvim.colorscheme
|
||||
vim.cmd("colorscheme " .. lvim.colorscheme)
|
||||
end, debug.traceback)
|
||||
if not status_ok then
|
||||
Log:warn "problems detected while loading plugins' configurations"
|
||||
Log:trace(debug.traceback())
|
||||
end
|
||||
end
|
||||
|
||||
function plugin_loader.get_core_plugins()
|
||||
local list = {}
|
||||
local plugins = require "lvim.plugins"
|
||||
for _, item in pairs(plugins) do
|
||||
if not item.disable then
|
||||
table.insert(list, item[1]:match "/(%S*)")
|
||||
end
|
||||
end
|
||||
return list
|
||||
end
|
||||
|
||||
function plugin_loader.load_snapshot(snapshot_file)
|
||||
snapshot_file = snapshot_file or default_snapshot
|
||||
if not in_headless then
|
||||
vim.notify("Syncing core plugins is in progress..", vim.log.levels.INFO, { title = "lvim" })
|
||||
end
|
||||
Log:debug(string.format("Using snapshot file [%s]", snapshot_file))
|
||||
local core_plugins = plugin_loader.get_core_plugins()
|
||||
require("packer").rollback(snapshot_file, unpack(core_plugins))
|
||||
end
|
||||
|
||||
function plugin_loader.sync_core_plugins()
|
||||
-- problem: rollback() will get stuck if a plugin directory doesn't exist
|
||||
-- solution: call sync() beforehand
|
||||
-- see https://github.com/wbthomason/packer.nvim/issues/862
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "PackerComplete",
|
||||
once = true,
|
||||
callback = function()
|
||||
require("lvim.plugin-loader").load_snapshot(default_snapshot)
|
||||
end,
|
||||
})
|
||||
pcall_packer_command "sync"
|
||||
end
|
||||
|
||||
function plugin_loader.ensure_plugins()
|
||||
vim.api.nvim_create_autocmd("User", {
|
||||
pattern = "PackerComplete",
|
||||
once = true,
|
||||
callback = function()
|
||||
Log:debug "calling packer.clean()"
|
||||
pcall_packer_command "clean"
|
||||
end,
|
||||
})
|
||||
Log:debug "calling packer.install()"
|
||||
pcall_packer_command "install"
|
||||
end
|
||||
|
||||
return plugin_loader
|
|
@ -0,0 +1,265 @@
|
|||
local core_plugins = {
|
||||
-- Packer can manage itself as an optional plugin
|
||||
{ "wbthomason/packer.nvim" },
|
||||
{ "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
|
||||
{
|
||||
"williamboman/nvim-lsp-installer",
|
||||
},
|
||||
{
|
||||
"lunarvim/onedarker.nvim",
|
||||
config = function()
|
||||
pcall(function()
|
||||
if lvim and lvim.colorscheme == "onedarker" then
|
||||
require("onedarker").setup()
|
||||
lvim.builtin.lualine.options.theme = "onedarker"
|
||||
end
|
||||
end)
|
||||
end,
|
||||
disable = lvim.colorscheme ~= "onedarker",
|
||||
},
|
||||
{
|
||||
"rcarriga/nvim-notify",
|
||||
config = function()
|
||||
require("lvim.core.notify").setup()
|
||||
end,
|
||||
requires = { "nvim-telescope/telescope.nvim" },
|
||||
disable = not lvim.builtin.notify.active or not lvim.builtin.telescope.active,
|
||||
},
|
||||
{ "Tastyep/structlog.nvim" },
|
||||
|
||||
{ "nvim-lua/popup.nvim" },
|
||||
{ "nvim-lua/plenary.nvim" },
|
||||
-- Telescope
|
||||
{
|
||||
"nvim-telescope/telescope.nvim",
|
||||
config = function()
|
||||
require("lvim.core.telescope").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.telescope.active,
|
||||
},
|
||||
{
|
||||
"nvim-telescope/telescope-fzf-native.nvim",
|
||||
requires = { "nvim-telescope/telescope.nvim" },
|
||||
run = "make",
|
||||
disable = not lvim.builtin.telescope.active,
|
||||
},
|
||||
-- Install nvim-cmp, and buffer source as a dependency
|
||||
{
|
||||
"hrsh7th/nvim-cmp",
|
||||
config = function()
|
||||
if lvim.builtin.cmp then
|
||||
require("lvim.core.cmp").setup()
|
||||
end
|
||||
end,
|
||||
requires = {
|
||||
"L3MON4D3/LuaSnip",
|
||||
},
|
||||
},
|
||||
{
|
||||
"rafamadriz/friendly-snippets",
|
||||
disable = not lvim.builtin.luasnip.sources.friendly_snippets,
|
||||
},
|
||||
{
|
||||
"L3MON4D3/LuaSnip",
|
||||
config = function()
|
||||
local utils = require "lvim.utils"
|
||||
local paths = {}
|
||||
if lvim.builtin.luasnip.sources.friendly_snippets then
|
||||
paths[#paths + 1] = utils.join_paths(get_runtime_dir(), "site", "pack", "packer", "start", "friendly-snippets")
|
||||
end
|
||||
local user_snippets = utils.join_paths(get_config_dir(), "snippets")
|
||||
if utils.is_directory(user_snippets) then
|
||||
paths[#paths + 1] = user_snippets
|
||||
end
|
||||
require("luasnip.loaders.from_lua").lazy_load()
|
||||
require("luasnip.loaders.from_vscode").lazy_load {
|
||||
paths = paths,
|
||||
}
|
||||
require("luasnip.loaders.from_snipmate").lazy_load()
|
||||
end,
|
||||
},
|
||||
{
|
||||
"hrsh7th/cmp-nvim-lsp",
|
||||
},
|
||||
{
|
||||
"saadparwaiz1/cmp_luasnip",
|
||||
},
|
||||
{
|
||||
"hrsh7th/cmp-buffer",
|
||||
},
|
||||
{
|
||||
"hrsh7th/cmp-path",
|
||||
},
|
||||
{
|
||||
-- NOTE: Temporary fix till folke comes back
|
||||
"max397574/lua-dev.nvim",
|
||||
module = "lua-dev",
|
||||
},
|
||||
|
||||
-- Autopairs
|
||||
{
|
||||
"windwp/nvim-autopairs",
|
||||
-- event = "InsertEnter",
|
||||
config = function()
|
||||
require("lvim.core.autopairs").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.autopairs.active,
|
||||
},
|
||||
|
||||
-- Treesitter
|
||||
{
|
||||
"nvim-treesitter/nvim-treesitter",
|
||||
-- run = ":TSUpdate",
|
||||
config = function()
|
||||
require("lvim.core.treesitter").setup()
|
||||
end,
|
||||
},
|
||||
{
|
||||
"JoosepAlviste/nvim-ts-context-commentstring",
|
||||
event = "BufReadPost",
|
||||
},
|
||||
|
||||
-- NvimTree
|
||||
{
|
||||
"kyazdani42/nvim-tree.lua",
|
||||
-- event = "BufWinOpen",
|
||||
-- cmd = "NvimTreeToggle",
|
||||
config = function()
|
||||
require("lvim.core.nvimtree").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.nvimtree.active,
|
||||
},
|
||||
|
||||
{
|
||||
"lewis6991/gitsigns.nvim",
|
||||
|
||||
config = function()
|
||||
require("lvim.core.gitsigns").setup()
|
||||
end,
|
||||
event = "BufRead",
|
||||
disable = not lvim.builtin.gitsigns.active,
|
||||
},
|
||||
|
||||
-- Whichkey
|
||||
{
|
||||
"max397574/which-key.nvim",
|
||||
config = function()
|
||||
require("lvim.core.which-key").setup()
|
||||
end,
|
||||
event = "BufWinEnter",
|
||||
disable = not lvim.builtin.which_key.active,
|
||||
},
|
||||
|
||||
-- Comments
|
||||
{
|
||||
"numToStr/Comment.nvim",
|
||||
event = "BufRead",
|
||||
config = function()
|
||||
require("lvim.core.comment").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.comment.active,
|
||||
},
|
||||
|
||||
-- project.nvim
|
||||
{
|
||||
"ahmedkhalf/project.nvim",
|
||||
config = function()
|
||||
require("lvim.core.project").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.project.active,
|
||||
},
|
||||
|
||||
-- Icons
|
||||
{
|
||||
"kyazdani42/nvim-web-devicons",
|
||||
disable = not lvim.use_icons,
|
||||
},
|
||||
|
||||
-- Status Line and Bufferline
|
||||
{
|
||||
-- "hoob3rt/lualine.nvim",
|
||||
"nvim-lualine/lualine.nvim",
|
||||
-- "Lunarvim/lualine.nvim",
|
||||
config = function()
|
||||
require("lvim.core.lualine").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.lualine.active,
|
||||
},
|
||||
|
||||
{
|
||||
"akinsho/bufferline.nvim",
|
||||
config = function()
|
||||
require("lvim.core.bufferline").setup()
|
||||
end,
|
||||
branch = "main",
|
||||
event = "BufWinEnter",
|
||||
disable = not lvim.builtin.bufferline.active,
|
||||
},
|
||||
|
||||
-- Debugging
|
||||
{
|
||||
"mfussenegger/nvim-dap",
|
||||
-- event = "BufWinEnter",
|
||||
config = function()
|
||||
require("lvim.core.dap").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.dap.active,
|
||||
},
|
||||
|
||||
-- Debugger management
|
||||
{
|
||||
"Pocco81/dap-buddy.nvim",
|
||||
branch = "dev",
|
||||
-- event = "BufWinEnter",
|
||||
-- event = "BufRead",
|
||||
disable = not lvim.builtin.dap.active,
|
||||
},
|
||||
|
||||
-- alpha
|
||||
{
|
||||
"goolord/alpha-nvim",
|
||||
config = function()
|
||||
require("lvim.core.alpha").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.alpha.active,
|
||||
},
|
||||
|
||||
-- Terminal
|
||||
{
|
||||
"akinsho/toggleterm.nvim",
|
||||
event = "BufWinEnter",
|
||||
branch = "main",
|
||||
config = function()
|
||||
require("lvim.core.terminal").setup()
|
||||
end,
|
||||
disable = not lvim.builtin.terminal.active,
|
||||
},
|
||||
|
||||
-- SchemaStore
|
||||
{
|
||||
"b0o/schemastore.nvim",
|
||||
},
|
||||
}
|
||||
|
||||
local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json")
|
||||
local content = vim.fn.readfile(default_snapshot_path)
|
||||
local default_sha1 = vim.fn.json_decode(content)
|
||||
|
||||
local get_default_sha1 = function(spec)
|
||||
local short_name, _ = require("packer.util").get_plugin_short_name(spec)
|
||||
return default_sha1[short_name] and default_sha1[short_name].commit
|
||||
end
|
||||
|
||||
for _, spec in ipairs(core_plugins) do
|
||||
if not vim.env.LVIM_DEV_MODE then
|
||||
-- Manually lock the commit hash since Packer's snapshots are unreliable in headless mode
|
||||
spec["commit"] = get_default_sha1(spec)
|
||||
end
|
||||
end
|
||||
|
||||
return core_plugins
|
|
@ -0,0 +1,107 @@
|
|||
local M = {}
|
||||
local uv = vim.loop
|
||||
|
||||
-- recursive Print (structure, limit, separator)
|
||||
local function r_inspect_settings(structure, limit, separator)
|
||||
limit = limit or 100 -- default item limit
|
||||
separator = separator or "." -- indent string
|
||||
if limit < 1 then
|
||||
print "ERROR: Item limit reached."
|
||||
return limit - 1
|
||||
end
|
||||
if structure == nil then
|
||||
io.write("-- O", separator:sub(2), " = nil\n")
|
||||
return limit - 1
|
||||
end
|
||||
local ts = type(structure)
|
||||
|
||||
if ts == "table" then
|
||||
for k, v in pairs(structure) do
|
||||
-- replace non alpha keys with ["key"]
|
||||
if tostring(k):match "[^%a_]" then
|
||||
k = '["' .. tostring(k) .. '"]'
|
||||
end
|
||||
limit = r_inspect_settings(v, limit, separator .. "." .. tostring(k))
|
||||
if limit < 0 then
|
||||
break
|
||||
end
|
||||
end
|
||||
return limit
|
||||
end
|
||||
|
||||
if ts == "string" then
|
||||
-- escape sequences
|
||||
structure = string.format("%q", structure)
|
||||
end
|
||||
separator = separator:gsub("%.%[", "%[")
|
||||
if type(structure) == "function" then
|
||||
-- don't print functions
|
||||
io.write("-- lvim", separator:sub(2), " = function ()\n")
|
||||
else
|
||||
io.write("lvim", separator:sub(2), " = ", tostring(structure), "\n")
|
||||
end
|
||||
return limit - 1
|
||||
end
|
||||
|
||||
function M.generate_settings()
|
||||
-- Opens a file in append mode
|
||||
local file = io.open("lv-settings.lua", "w")
|
||||
|
||||
-- sets the default output file as test.lua
|
||||
io.output(file)
|
||||
|
||||
-- write all `lvim` related settings to `lv-settings.lua` file
|
||||
r_inspect_settings(lvim, 10000, ".")
|
||||
|
||||
-- closes the open file
|
||||
io.close(file)
|
||||
end
|
||||
|
||||
--- Returns a table with the default values that are missing.
|
||||
--- either parameter can be empty.
|
||||
--@param config (table) table containing entries that take priority over defaults
|
||||
--@param default_config (table) table contatining default values if found
|
||||
function M.apply_defaults(config, default_config)
|
||||
config = config or {}
|
||||
default_config = default_config or {}
|
||||
local new_config = vim.tbl_deep_extend("keep", vim.empty_dict(), config)
|
||||
new_config = vim.tbl_deep_extend("keep", new_config, default_config)
|
||||
return new_config
|
||||
end
|
||||
|
||||
--- Checks whether a given path exists and is a file.
|
||||
--@param path (string) path to check
|
||||
--@returns (bool)
|
||||
function M.is_file(path)
|
||||
local stat = uv.fs_stat(path)
|
||||
return stat and stat.type == "file" or false
|
||||
end
|
||||
|
||||
--- Checks whether a given path exists and is a directory
|
||||
--@param path (string) path to check
|
||||
--@returns (bool)
|
||||
function M.is_directory(path)
|
||||
local stat = uv.fs_stat(path)
|
||||
return stat and stat.type == "directory" or false
|
||||
end
|
||||
|
||||
M.join_paths = _G.join_paths
|
||||
|
||||
---Write data to a file
|
||||
---@param path string can be full or relative to `cwd`
|
||||
---@param txt string|table text to be written, uses `vim.inspect` internally for tables
|
||||
---@param flag string used to determine access mode, common flags: "w" for `overwrite` or "a" for `append`
|
||||
function M.write_file(path, txt, flag)
|
||||
local data = type(txt) == "string" and txt or vim.inspect(txt)
|
||||
uv.fs_open(path, flag, 438, function(open_err, fd)
|
||||
assert(not open_err, open_err)
|
||||
uv.fs_write(fd, data, -1, function(write_err)
|
||||
assert(not write_err, write_err)
|
||||
uv.fs_close(fd, function(close_err)
|
||||
assert(not close_err, close_err)
|
||||
end)
|
||||
end)
|
||||
end)
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,19 @@
|
|||
local M = {}
|
||||
|
||||
function M.smart_quit()
|
||||
local bufnr = vim.api.nvim_get_current_buf()
|
||||
local modified = vim.api.nvim_buf_get_option(bufnr, "modified")
|
||||
if modified then
|
||||
vim.ui.input({
|
||||
prompt = "You have unsaved changes. Quit anyway? (y/n) ",
|
||||
}, function(input)
|
||||
if input == "y" then
|
||||
vim.cmd "q!"
|
||||
end
|
||||
end)
|
||||
else
|
||||
vim.cmd "q!"
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,140 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
local if_nil = vim.F.if_nil
|
||||
|
||||
local function git_cmd(opts)
|
||||
local plenary_loaded, Job = pcall(require, "plenary.job")
|
||||
if not plenary_loaded then
|
||||
return 1, { "" }
|
||||
end
|
||||
|
||||
opts = opts or {}
|
||||
opts.cwd = opts.cwd or get_lvim_base_dir()
|
||||
|
||||
local stderr = {}
|
||||
local stdout, ret = Job
|
||||
:new({
|
||||
command = "git",
|
||||
args = opts.args,
|
||||
cwd = opts.cwd,
|
||||
on_stderr = function(_, data)
|
||||
table.insert(stderr, data)
|
||||
end,
|
||||
})
|
||||
:sync()
|
||||
|
||||
if not vim.tbl_isempty(stderr) then
|
||||
Log:debug(stderr)
|
||||
end
|
||||
|
||||
if not vim.tbl_isempty(stdout) then
|
||||
Log:debug(stdout)
|
||||
end
|
||||
|
||||
return ret, stdout
|
||||
end
|
||||
|
||||
local function safe_deep_fetch()
|
||||
local ret, result = git_cmd { args = { "rev-parse", "--is-shallow-repository" } }
|
||||
if ret ~= 0 then
|
||||
Log:error "Git fetch failed! Check the log for further information"
|
||||
return
|
||||
end
|
||||
-- git fetch --unshallow will cause an error on a a complete clone
|
||||
local fetch_mode = result[1] == "true" and "--unshallow" or "--all"
|
||||
ret = git_cmd { args = { "fetch", fetch_mode } }
|
||||
if ret ~= 0 then
|
||||
Log:error "Git fetch failed! Check the log for further information"
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
---pulls the latest changes from github
|
||||
function M.update_base_lvim()
|
||||
Log:info "Checking for updates"
|
||||
|
||||
local ret = git_cmd { args = { "fetch" } }
|
||||
if ret ~= 0 then
|
||||
Log:error "Update failed! Check the log for further information"
|
||||
return
|
||||
end
|
||||
|
||||
ret = git_cmd { args = { "diff", "--quiet", "@{upstream}" } }
|
||||
if ret == 0 then
|
||||
Log:info "LunarVim is already up-to-date"
|
||||
return
|
||||
end
|
||||
|
||||
ret = git_cmd { args = { "merge", "--ff-only", "--progress" } }
|
||||
if ret ~= 0 then
|
||||
Log:error "Update failed! Please pull the changes manually instead."
|
||||
return
|
||||
end
|
||||
|
||||
return true
|
||||
end
|
||||
|
||||
---Switch Lunarvim to the specified development branch
|
||||
---@param branch string
|
||||
function M.switch_lvim_branch(branch)
|
||||
if not safe_deep_fetch() then
|
||||
return
|
||||
end
|
||||
local args = { "switch", branch }
|
||||
|
||||
if branch:match "^[0-9]" then
|
||||
-- avoids producing an error for tags
|
||||
vim.list_extend(args, { "--detach" })
|
||||
end
|
||||
|
||||
local ret = git_cmd { args = args }
|
||||
if ret ~= 0 then
|
||||
Log:error "Unable to switch branches! Check the log for further information"
|
||||
return
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
---Get the current Lunarvim development branch
|
||||
---@return string|nil
|
||||
function M.get_lvim_branch()
|
||||
local _, results = git_cmd { args = { "rev-parse", "--abbrev-ref", "HEAD" } }
|
||||
local branch = if_nil(results[1], "")
|
||||
return branch
|
||||
end
|
||||
|
||||
---Get currently checked-out tag of Lunarvim
|
||||
---@return string
|
||||
function M.get_lvim_tag()
|
||||
local args = { "describe", "--tags", "--abbrev=0" }
|
||||
|
||||
local _, results = git_cmd { args = args }
|
||||
local tag = if_nil(results[1], "")
|
||||
return tag
|
||||
end
|
||||
|
||||
---Get currently running version of Lunarvim
|
||||
---@return string
|
||||
function M.get_lvim_version()
|
||||
local current_branch = M.get_lvim_branch()
|
||||
|
||||
local lvim_version
|
||||
if current_branch ~= "HEAD" or "" then
|
||||
lvim_version = current_branch .. "-" .. M.get_lvim_current_sha()
|
||||
else
|
||||
lvim_version = "v" .. M.get_lvim_tag()
|
||||
end
|
||||
return lvim_version
|
||||
end
|
||||
|
||||
---Get the commit hash of currently checked-out commit of Lunarvim
|
||||
---@return string|nil
|
||||
function M.get_lvim_current_sha()
|
||||
local _, log_results = git_cmd { args = { "log", "--pretty=format:%h", "-1" } }
|
||||
local abbrev_version = if_nil(log_results[1], "")
|
||||
return abbrev_version
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,87 @@
|
|||
local M = {}
|
||||
|
||||
local Log = require "lvim.core.log"
|
||||
local in_headless = #vim.api.nvim_list_uis() == 0
|
||||
|
||||
function M.run_pre_update()
|
||||
Log:debug "Starting pre-update hook"
|
||||
end
|
||||
|
||||
function M.run_pre_reload()
|
||||
Log:debug "Starting pre-reload hook"
|
||||
end
|
||||
|
||||
function M.run_on_packer_complete()
|
||||
Log:debug "Packer operation complete"
|
||||
vim.api.nvim_exec_autocmds("User", { pattern = "PackerComplete" })
|
||||
|
||||
vim.g.colors_name = lvim.colorscheme
|
||||
pcall(vim.cmd, "colorscheme " .. lvim.colorscheme)
|
||||
|
||||
if M._reload_triggered then
|
||||
Log:info "Reloaded configuration"
|
||||
M._reload_triggered = nil
|
||||
end
|
||||
end
|
||||
|
||||
function M.run_post_reload()
|
||||
Log:debug "Starting post-reload hook"
|
||||
M.reset_cache()
|
||||
M._reload_triggered = true
|
||||
end
|
||||
|
||||
---Reset any startup cache files used by Packer and Impatient
|
||||
---It also forces regenerating any template ftplugin files
|
||||
---Tip: Useful for clearing any outdated settings
|
||||
function M.reset_cache()
|
||||
local impatient = _G.__luacache
|
||||
if impatient then
|
||||
impatient.clear_cache()
|
||||
end
|
||||
local lvim_modules = {}
|
||||
for module, _ in pairs(package.loaded) do
|
||||
if module:match "lvim.core" or module:match "lvim.lsp" then
|
||||
package.loaded[module] = nil
|
||||
table.insert(lvim_modules, module)
|
||||
end
|
||||
end
|
||||
Log:trace(string.format("Cache invalidated for core modules: { %s }", table.concat(lvim_modules, ", ")))
|
||||
require("lvim.lsp.templates").generate_templates()
|
||||
end
|
||||
|
||||
function M.run_post_update()
|
||||
Log:debug "Starting post-update hook"
|
||||
|
||||
if vim.fn.has "nvim-0.7" ~= 1 then
|
||||
local compat_tag = "1.1.3"
|
||||
vim.notify(
|
||||
"Please upgrade your Neovim base installation. Newer version of Lunarvim requires v0.7+",
|
||||
vim.log.levels.WARN
|
||||
)
|
||||
vim.wait(1000, function()
|
||||
return false
|
||||
end)
|
||||
local ret = require_clean("lvim.utils.git").switch_lvim_branch(compat_tag)
|
||||
if ret then
|
||||
vim.notify("Reverted to the last known compatibile version: " .. compat_tag, vim.log.levels.WARN)
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
M.reset_cache()
|
||||
|
||||
Log:debug "Syncing core plugins"
|
||||
require("lvim.plugin-loader").sync_core_plugins()
|
||||
|
||||
if not in_headless then
|
||||
vim.schedule(function()
|
||||
if package.loaded["nvim-treesitter"] then
|
||||
vim.cmd [[ TSUpdateSync ]]
|
||||
end
|
||||
-- TODO: add a changelog
|
||||
vim.notify("Update complete", vim.log.levels.INFO)
|
||||
end)
|
||||
end
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,24 @@
|
|||
local Table = {}
|
||||
|
||||
--- Find the first entry for which the predicate returns true.
|
||||
-- @param t The table
|
||||
-- @param predicate The function called for each entry of t
|
||||
-- @return The entry for which the predicate returned True or nil
|
||||
function Table.find_first(t, predicate)
|
||||
for _, entry in pairs(t) do
|
||||
if predicate(entry) then
|
||||
return entry
|
||||
end
|
||||
end
|
||||
return nil
|
||||
end
|
||||
|
||||
--- Check if the predicate returns True for at least one entry of the table.
|
||||
-- @param t The table
|
||||
-- @param predicate The function called for each entry of t
|
||||
-- @return True if predicate returned True at least once, false otherwise
|
||||
function Table.contains(t, predicate)
|
||||
return Table.find_first(t, predicate) ~= nil
|
||||
end
|
||||
|
||||
return Table
|
|
@ -0,0 +1,113 @@
|
|||
{
|
||||
"Comment.nvim": {
|
||||
"commit": "3c69bab"
|
||||
},
|
||||
"FixCursorHold.nvim": {
|
||||
"commit": "1bfb32e"
|
||||
},
|
||||
"LuaSnip": {
|
||||
"commit": "79b2019"
|
||||
},
|
||||
"alpha-nvim": {
|
||||
"commit": "ef27a59"
|
||||
},
|
||||
"bufferline.nvim": {
|
||||
"commit": "c78b3ec"
|
||||
},
|
||||
"cmp-buffer": {
|
||||
"commit": "12463cf"
|
||||
},
|
||||
"cmp-nvim-lsp": {
|
||||
"commit": "affe808"
|
||||
},
|
||||
"cmp-path": {
|
||||
"commit": "466b6b8"
|
||||
},
|
||||
"cmp_luasnip": {
|
||||
"commit": "a9de941"
|
||||
},
|
||||
"dap-buddy.nvim": {
|
||||
"commit": "bbda2b0"
|
||||
},
|
||||
"friendly-snippets": {
|
||||
"commit": "d27a83a"
|
||||
},
|
||||
"gitsigns.nvim": {
|
||||
"commit": "c18e016"
|
||||
},
|
||||
"lua-dev.nvim": {
|
||||
"commit": "54149d1"
|
||||
},
|
||||
"lualine.nvim": {
|
||||
"commit": "3362b28"
|
||||
},
|
||||
"nlsp-settings.nvim": {
|
||||
"commit": "62d72bc"
|
||||
},
|
||||
"null-ls.nvim": {
|
||||
"commit": "ff40739"
|
||||
},
|
||||
"nvim-autopairs": {
|
||||
"commit": "fa6876f"
|
||||
},
|
||||
"nvim-cmp": {
|
||||
"commit": "df6734a"
|
||||
},
|
||||
"nvim-dap": {
|
||||
"commit": "014ebd5"
|
||||
},
|
||||
"nvim-lsp-installer": {
|
||||
"commit": "2408a0f"
|
||||
},
|
||||
"nvim-lspconfig": {
|
||||
"commit": "10c3934"
|
||||
},
|
||||
"nvim-notify": {
|
||||
"commit": "8960269"
|
||||
},
|
||||
"nvim-tree.lua": {
|
||||
"commit": "bdb6d4a"
|
||||
},
|
||||
"nvim-treesitter": {
|
||||
"commit": "518e275"
|
||||
},
|
||||
"nvim-ts-context-commentstring": {
|
||||
"commit": "8834375"
|
||||
},
|
||||
"nvim-web-devicons": {
|
||||
"commit": "8d2c533"
|
||||
},
|
||||
"onedarker.nvim": {
|
||||
"commit": "b00dd21"
|
||||
},
|
||||
"packer.nvim": {
|
||||
"commit": "00ec5ad"
|
||||
},
|
||||
"plenary.nvim": {
|
||||
"commit": "968a4b9"
|
||||
},
|
||||
"popup.nvim": {
|
||||
"commit": "b7404d3"
|
||||
},
|
||||
"project.nvim": {
|
||||
"commit": "541115e"
|
||||
},
|
||||
"schemastore.nvim": {
|
||||
"commit": "a32911d"
|
||||
},
|
||||
"structlog.nvim": {
|
||||
"commit": "232a8e2"
|
||||
},
|
||||
"telescope-fzf-native.nvim": {
|
||||
"commit": "6a33ece"
|
||||
},
|
||||
"telescope.nvim": {
|
||||
"commit": "d96eaa9"
|
||||
},
|
||||
"toggleterm.nvim": {
|
||||
"commit": "aaeed9e"
|
||||
},
|
||||
"which-key.nvim": {
|
||||
"commit": "f03a259"
|
||||
}
|
||||
}
|
|
@ -0,0 +1,48 @@
|
|||
local M = {}
|
||||
|
||||
function M.search_file(file, args)
|
||||
local Job = require "plenary.job"
|
||||
local stderr = {}
|
||||
local stdout, ret = Job
|
||||
:new({
|
||||
command = "grep",
|
||||
args = { args, file },
|
||||
cwd = get_cache_dir(),
|
||||
on_stderr = function(_, data)
|
||||
table.insert(stderr, data)
|
||||
end,
|
||||
})
|
||||
:sync()
|
||||
return ret, stdout, stderr
|
||||
end
|
||||
|
||||
function M.file_contains(file, query)
|
||||
local ret, stdout, stderr = M.search_file(file, query)
|
||||
if ret == 0 then
|
||||
return true
|
||||
end
|
||||
if not vim.tbl_isempty(stderr) then
|
||||
error(vim.inspect(stderr))
|
||||
end
|
||||
if not vim.tbl_isempty(stdout) then
|
||||
error(vim.inspect(stdout))
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
function M.log_contains(query)
|
||||
local logfile = require("lvim.core.log"):get_path()
|
||||
local ret, stdout, stderr = M.search_file(logfile, query)
|
||||
if ret == 0 then
|
||||
return true
|
||||
end
|
||||
if not vim.tbl_isempty(stderr) then
|
||||
error(vim.inspect(stderr))
|
||||
end
|
||||
if not vim.tbl_isempty(stdout) then
|
||||
error(vim.inspect(stdout))
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
||||
return M
|
|
@ -0,0 +1,12 @@
|
|||
local path_sep = vim.loop.os_uname().version:match "Windows" and "\\" or "/"
|
||||
local base_dir = os.getenv "LUNARVIM_RUNTIME_DIR" .. path_sep .. "lvim"
|
||||
local tests_dir = base_dir .. path_sep .. "tests"
|
||||
|
||||
vim.opt.rtp:append(tests_dir)
|
||||
vim.opt.rtp:append(base_dir)
|
||||
|
||||
require("lvim.bootstrap"):init(base_dir)
|
||||
|
||||
-- NOTE: careful about name collisions
|
||||
-- see https://github.com/nvim-lualine/lualine.nvim/pull/621
|
||||
require "tests.lvim.helpers"
|
|
@ -0,0 +1,114 @@
|
|||
local on_windows = vim.loop.os_uname().version:match "Windows"
|
||||
|
||||
local function join_paths(...)
|
||||
local path_sep = on_windows and "\\" or "/"
|
||||
local result = table.concat({ ... }, path_sep)
|
||||
return result
|
||||
end
|
||||
|
||||
vim.cmd [[set runtimepath=$VIMRUNTIME]]
|
||||
|
||||
local temp_dir = vim.loop.os_getenv "TEMP" or "/tmp"
|
||||
|
||||
vim.cmd("set packpath=" .. join_paths(temp_dir, "nvim", "site"))
|
||||
|
||||
local package_root = join_paths(temp_dir, "nvim", "site", "pack")
|
||||
local install_path = join_paths(package_root, "packer", "start", "packer.nvim")
|
||||
local compile_path = join_paths(install_path, "plugin", "packer_compiled.lua")
|
||||
|
||||
-- Choose whether to use the executable that's managed by lsp-installer
|
||||
local use_lsp_installer = true
|
||||
|
||||
local function load_plugins()
|
||||
require("packer").startup {
|
||||
{
|
||||
"wbthomason/packer.nvim",
|
||||
"neovim/nvim-lspconfig",
|
||||
{ "williamboman/nvim-lsp-installer", disable = not use_lsp_installer },
|
||||
},
|
||||
config = {
|
||||
package_root = package_root,
|
||||
compile_path = compile_path,
|
||||
},
|
||||
}
|
||||
end
|
||||
|
||||
function _G.dump(...)
|
||||
local objects = vim.tbl_map(vim.inspect, { ... })
|
||||
print(unpack(objects))
|
||||
return ...
|
||||
end
|
||||
|
||||
_G.load_config = function()
|
||||
vim.lsp.set_log_level "trace"
|
||||
require("vim.lsp.log").set_format_func(vim.inspect)
|
||||
local nvim_lsp = require "lspconfig"
|
||||
local on_attach = function(_, bufnr)
|
||||
local function buf_set_keymap(...)
|
||||
vim.api.nvim_buf_set_keymap(bufnr, ...)
|
||||
end
|
||||
local function buf_set_option(...)
|
||||
vim.api.nvim_buf_set_option(bufnr, ...)
|
||||
end
|
||||
|
||||
buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
|
||||
|
||||
-- Mappings.
|
||||
local opts = { noremap = true, silent = true }
|
||||
buf_set_keymap("n", "gD", "<Cmd>lua vim.lsp.buf.declaration()<CR>", opts)
|
||||
buf_set_keymap("n", "gd", "<Cmd>lua vim.lsp.buf.definition()<CR>", opts)
|
||||
buf_set_keymap("n", "K", "<Cmd>lua vim.lsp.buf.hover()<CR>", opts)
|
||||
buf_set_keymap("n", "gi", "<cmd>lua vim.lsp.buf.implementation()<CR>", opts)
|
||||
buf_set_keymap("n", "<C-k>", "<cmd>lua vim.lsp.buf.signature_help()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>wa", "<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>wr", "<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>wl", "<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>", opts)
|
||||
buf_set_keymap("n", "<space>lD", "<cmd>lua vim.lsp.buf.type_definition()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>lr", "<cmd>lua vim.lsp.buf.rename()<CR>", opts)
|
||||
buf_set_keymap("n", "gr", "<cmd>lua vim.lsp.buf.references()<CR>", opts)
|
||||
buf_set_keymap("n", "gl", "<cmd>lua vim.diagnostic.open_float(0,{scope='line'})<CR>", opts)
|
||||
buf_set_keymap("n", "<space>lk", "<cmd>lua vim.diagnostic.goto_prev()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>lj", "<cmd>lua vim.diagnostic.goto_next()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>lq", "<cmd>lua vim.diagnostic.setloclist()<CR>", opts)
|
||||
buf_set_keymap("n", "<space>li", "<cmd>LspInfo<CR>", opts)
|
||||
buf_set_keymap("n", "<space>lI", "<cmd>LspInstallInfo<CR>", opts)
|
||||
end
|
||||
|
||||
-- Add the server that troubles you here, e.g. "clangd", "pyright", "tsserver"
|
||||
local name = "sumneko_lua"
|
||||
|
||||
local setup_opts = {
|
||||
on_attach = on_attach,
|
||||
}
|
||||
|
||||
if use_lsp_installer then
|
||||
local server_available, server = require("nvim-lsp-installer.servers").get_server(name)
|
||||
if not server_available then
|
||||
server:install()
|
||||
end
|
||||
local default_opts = server:get_default_options()
|
||||
setup_opts = vim.tbl_deep_extend("force", setup_opts, default_opts)
|
||||
end
|
||||
|
||||
if not name then
|
||||
print "You have not defined a server name, please edit minimal_init.lua"
|
||||
end
|
||||
if not nvim_lsp[name].document_config.default_config.cmd and not setup_opts.cmd then
|
||||
print [[You have not defined a server default cmd for a server
|
||||
that requires it please edit minimal_init.lua]]
|
||||
end
|
||||
|
||||
nvim_lsp[name].setup(setup_opts)
|
||||
print [[You can find your log at $HOME/.cache/nvim/lsp.log. Please paste in a github issue under a details tag as described in the issue template.]]
|
||||
end
|
||||
|
||||
if vim.fn.isdirectory(install_path) == 0 then
|
||||
vim.fn.system { "git", "clone", "https://github.com/wbthomason/packer.nvim", install_path }
|
||||
load_plugins()
|
||||
require("packer").sync()
|
||||
vim.cmd [[autocmd User PackerComplete ++once lua load_config()]]
|
||||
else
|
||||
load_plugins()
|
||||
require("packer").sync()
|
||||
_G.load_config()
|
||||
end
|
|
@ -0,0 +1,42 @@
|
|||
local a = require "plenary.async_lib.tests"
|
||||
local uv = vim.loop
|
||||
local home_dir = uv.os_homedir()
|
||||
|
||||
a.describe("initial start", function()
|
||||
local lvim_config_path = get_config_dir()
|
||||
local lvim_runtime_path = get_runtime_dir()
|
||||
local lvim_cache_path = get_cache_dir()
|
||||
|
||||
a.it("should be able to detect test environment", function()
|
||||
assert.truthy(os.getenv "LVIM_TEST_ENV")
|
||||
assert.falsy(package.loaded["lvim.impatient"])
|
||||
end)
|
||||
|
||||
a.it("should be able to use lunarvim cache directory using vim.fn", function()
|
||||
assert.equal(lvim_cache_path, vim.fn.stdpath "cache")
|
||||
end)
|
||||
|
||||
a.it("should be to retrieve default neovim directories", function()
|
||||
local xdg_config = os.getenv "XDG_CONFIG_HOME" or join_paths(home_dir, ".config")
|
||||
assert.equal(join_paths(xdg_config, "nvim"), vim.call("stdpath", "config"))
|
||||
end)
|
||||
|
||||
a.it("should be able to read lunarvim directories", function()
|
||||
local rtp_list = vim.opt.rtp:get()
|
||||
assert.truthy(vim.tbl_contains(rtp_list, lvim_runtime_path .. "/lvim"))
|
||||
assert.truthy(vim.tbl_contains(rtp_list, lvim_config_path))
|
||||
end)
|
||||
|
||||
a.it("should be able to run treesitter without errors", function()
|
||||
assert.truthy(vim.treesitter.highlighter.active)
|
||||
end)
|
||||
|
||||
a.it("should be able to pass basic checkhealth without errors", function()
|
||||
vim.cmd "set cmdheight&"
|
||||
vim.cmd "checkhealth nvim"
|
||||
local errmsg = vim.fn.eval "v:errmsg"
|
||||
local exception = vim.fn.eval "v:exception"
|
||||
assert.equal("", errmsg) -- v:errmsg was not updated.
|
||||
assert.equal("", exception)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,55 @@
|
|||
local a = require "plenary.async_lib.tests"
|
||||
local config = require "lvim.config"
|
||||
local fmt = string.format
|
||||
|
||||
a.describe("config-loader", function()
|
||||
local user_config_path = join_paths(get_config_dir(), "config.lua")
|
||||
local default_config_path = join_paths(get_lvim_base_dir(), "utils", "installer", "config.example.lua")
|
||||
|
||||
before_each(function()
|
||||
os.execute(fmt("cp -f %s %s", default_config_path, user_config_path))
|
||||
vim.cmd [[
|
||||
let v:errmsg = ""
|
||||
let v:errors = []
|
||||
]]
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
local errmsg = vim.fn.eval "v:errmsg"
|
||||
local exception = vim.fn.eval "v:exception"
|
||||
local errors = vim.fn.eval "v:errors"
|
||||
assert.equal("", errmsg)
|
||||
assert.equal("", exception)
|
||||
assert.True(vim.tbl_isempty(errors))
|
||||
end)
|
||||
|
||||
a.it("should be able to find user-config", function()
|
||||
assert.equal(user_config_path, get_config_dir() .. "/config.lua")
|
||||
end)
|
||||
|
||||
a.it("should be able to load user-config without errors", function()
|
||||
config:load(user_config_path)
|
||||
end)
|
||||
|
||||
a.it("should be able to reload user-config without errors", function()
|
||||
config:load(user_config_path)
|
||||
local test_path = "/tmp/lvim"
|
||||
os.execute(string.format([[echo "vim.opt.undodir = '%s'" >> %s]], test_path, user_config_path))
|
||||
config:reload()
|
||||
vim.schedule(function()
|
||||
assert.equal(vim.opt.undodir:get()[1], test_path)
|
||||
end)
|
||||
end)
|
||||
|
||||
a.it("should not get interrupted by errors in user-config", function()
|
||||
local test_path = "/tmp/lunarvim"
|
||||
os.execute(string.format([[echo "vim.opt.undodir = '%s'" >> %s]], test_path, user_config_path))
|
||||
config:load(user_config_path)
|
||||
assert.equal(vim.opt.undodir:get()[1], test_path)
|
||||
require("lvim.core.log"):set_level "error"
|
||||
os.execute(string.format("echo 'invalid_function()' >> %s", user_config_path))
|
||||
config:load(user_config_path)
|
||||
require("lvim.core.log"):set_level "error"
|
||||
assert.equal(vim.opt.undodir:get()[1], test_path)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,82 @@
|
|||
local a = require "plenary.async_lib.tests"
|
||||
local utils = require "lvim.utils"
|
||||
local helpers = require "tests.lvim.helpers"
|
||||
local spy = require "luassert.spy"
|
||||
|
||||
a.describe("lsp workflow", function()
|
||||
before_each(function()
|
||||
vim.cmd [[
|
||||
let v:errmsg = ""
|
||||
let v:errors = []
|
||||
]]
|
||||
end)
|
||||
|
||||
after_each(function()
|
||||
local errmsg = vim.fn.eval "v:errmsg"
|
||||
local exception = vim.fn.eval "v:exception"
|
||||
local errors = vim.fn.eval "v:errors"
|
||||
assert.equal("", errmsg)
|
||||
assert.equal("", exception)
|
||||
assert.True(vim.tbl_isempty(errors))
|
||||
end)
|
||||
|
||||
lvim.lsp.templates_dir = join_paths(get_cache_dir(), "artifacts")
|
||||
|
||||
a.it("should be able to delete ftplugin templates", function()
|
||||
if utils.is_directory(lvim.lsp.templates_dir) then
|
||||
assert.equal(vim.fn.delete(lvim.lsp.templates_dir, "rf"), 0)
|
||||
end
|
||||
assert.False(utils.is_directory(lvim.lsp.templates_dir))
|
||||
end)
|
||||
|
||||
a.it("should be able to generate ftplugin templates", function()
|
||||
if utils.is_directory(lvim.lsp.templates_dir) then
|
||||
assert.equal(vim.fn.delete(lvim.lsp.templates_dir, "rf"), 0)
|
||||
end
|
||||
|
||||
require("lvim.lsp").setup()
|
||||
|
||||
assert.True(utils.is_directory(lvim.lsp.templates_dir))
|
||||
end)
|
||||
|
||||
a.it("should not include blacklisted servers in the generated templates", function()
|
||||
require("lvim.lsp").setup()
|
||||
|
||||
for _, file in ipairs(vim.fn.glob(lvim.lsp.templates_dir .. "/*.lua", 1, 1)) do
|
||||
for _, server_name in ipairs(lvim.lsp.override) do
|
||||
local setup_cmd = string.format([[require("lvim.lsp.manager").setup(%q)]], server_name)
|
||||
assert.False(helpers.file_contains(file, setup_cmd))
|
||||
end
|
||||
end
|
||||
end)
|
||||
|
||||
a.it("should only include one server per generated template", function()
|
||||
require("lvim.lsp").setup()
|
||||
|
||||
for _, file in ipairs(vim.fn.glob(lvim.lsp.templates_dir .. "/*.lua", 1, 1)) do
|
||||
local content = {}
|
||||
for entry in io.lines(file) do
|
||||
table.insert(content, entry)
|
||||
end
|
||||
local err_msg = ""
|
||||
if #content > 1 then
|
||||
err_msg = string.format(
|
||||
"found more than one server for [%q]: \n{\n %q \n}",
|
||||
file:match "[^/]*.lua$",
|
||||
table.concat(content, ", ")
|
||||
)
|
||||
end
|
||||
assert.equal(err_msg, "")
|
||||
end
|
||||
end)
|
||||
|
||||
a.it("should not attempt to re-generate ftplugin templates", function()
|
||||
local s = spy.on(require "lvim.lsp.templates", "generate_templates")
|
||||
local plugins = require "lvim.plugins"
|
||||
require("lvim.plugin-loader").load { plugins, lvim.plugins }
|
||||
|
||||
require("lvim.lsp").setup()
|
||||
assert.spy(s).was_not_called()
|
||||
s:revert()
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,74 @@
|
|||
local a = require "plenary.async_lib.tests"
|
||||
|
||||
a.describe("plugin-loader", function()
|
||||
local plugins = require "lvim.plugins"
|
||||
local loader = require "lvim.plugin-loader"
|
||||
|
||||
pcall(function()
|
||||
lvim.log.level = "debug"
|
||||
package.loaded["packer.log"] = nil
|
||||
package.loaded["lvim.core.log"] = nil
|
||||
end)
|
||||
|
||||
a.it("should be able to load default packages without errors", function()
|
||||
loader.load { plugins, lvim.plugins }
|
||||
|
||||
-- TODO: maybe there's a way to avoid hard-coding the names of the modules?
|
||||
local startup_plugins = {
|
||||
"packer",
|
||||
}
|
||||
|
||||
for _, plugin in ipairs(startup_plugins) do
|
||||
assert.truthy(package.loaded[plugin])
|
||||
end
|
||||
end)
|
||||
|
||||
a.it("should be able to load lsp packages without errors", function()
|
||||
loader.load { plugins, lvim.plugins }
|
||||
|
||||
require("lvim.lsp").setup()
|
||||
|
||||
local lsp_packages = {
|
||||
"lspconfig",
|
||||
"nlspsettings",
|
||||
"null-ls",
|
||||
}
|
||||
|
||||
for _, plugin in ipairs(lsp_packages) do
|
||||
assert.truthy(package.loaded[plugin])
|
||||
end
|
||||
end)
|
||||
|
||||
pending("should be able to rollback plugins without errors", function()
|
||||
local plugin = { name = "onedarker.nvim" }
|
||||
plugin.path = vim.tbl_filter(function(package)
|
||||
return package:match(plugin.name)
|
||||
end, vim.api.nvim_list_runtime_paths())[1]
|
||||
|
||||
local get_current_sha = function(repo)
|
||||
local res = vim.fn.system(string.format("git -C %s log -1 --pretty=%%h", repo)):gsub("\n", "")
|
||||
return res
|
||||
end
|
||||
plugin.test_sha = "316b1c9"
|
||||
_G.locked_sha = get_current_sha(plugin.path)
|
||||
loader.load { plugins, lvim.plugins }
|
||||
|
||||
os.execute(string.format("git -C %s fetch --deepen 999 --quiet", plugin.path))
|
||||
os.execute(string.format("git -C %s checkout %s --quiet", plugin.path, plugin.test_sha))
|
||||
assert.equal(plugin.test_sha, get_current_sha(plugin.path))
|
||||
_G.completed = false
|
||||
_G.verify_sha = function()
|
||||
if _G.locked_sha ~= get_current_sha(plugin.path) then
|
||||
error "unmached results!"
|
||||
else
|
||||
_G.completed = true
|
||||
end
|
||||
end
|
||||
vim.cmd [[autocmd User PackerComplete ++once lua _G.verify_sha()]]
|
||||
loader.load_snapshot()
|
||||
local ret = vim.wait(30 * 10 * 1000, function()
|
||||
return _G.completed == true
|
||||
end, 200)
|
||||
assert.True(ret)
|
||||
end)
|
||||
end)
|
|
@ -0,0 +1,62 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
# NOTE:
|
||||
# This doesn't work as is on Windows. You'll need to create an equivalent `.bat` file instead
|
||||
#
|
||||
# NOTE:
|
||||
# If you're not using Linux you'll need to adjust the `-configuration` option
|
||||
# to point to the `config_mac' or `config_win` folders depending on your system.
|
||||
|
||||
case Darwin in
|
||||
Linux)
|
||||
CONFIG="$HOME/.local/share/nvim/lsp_servers/jdtls/config_linux"
|
||||
;;
|
||||
Darwin)
|
||||
CONFIG="$HOME/.local/share/nvim/lsp_servers/jdtls/config_mac"
|
||||
;;
|
||||
esac
|
||||
|
||||
# Determine the Java command to use to start the JVM.
|
||||
if [ -n "$JAVA_HOME" ]; then
|
||||
if [ -x "$JAVA_HOME/jre/sh/java" ]; then
|
||||
# IBM's JDK on AIX uses strange locations for the executables
|
||||
JAVACMD="$JAVA_HOME/jre/sh/java"
|
||||
else
|
||||
JAVACMD="$JAVA_HOME/bin/java"
|
||||
fi
|
||||
if [ ! -x "$JAVACMD" ]; then
|
||||
die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
else
|
||||
JAVACMD="java"
|
||||
which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
|
||||
|
||||
Please set the JAVA_HOME variable in your environment to match the
|
||||
location of your Java installation."
|
||||
fi
|
||||
|
||||
# JAR="$HOME/.config/nvim/.language-servers/eclipse.jdt.ls/org.eclipse.jdt.ls.product/target/repository/plugins/org.eclipse.equinox.launcher_*.jar"
|
||||
JAR="$HOME/.local/share/nvim/lsp_servers/jdtls/plugins/org.eclipse.equinox.launcher_*.jar"
|
||||
GRADLE_HOME=$HOME/gradle "$JAVACMD" \
|
||||
-Declipse.application=org.eclipse.jdt.ls.core.id1 \
|
||||
-Dosgi.bundles.defaultStartLevel=4 \
|
||||
-Declipse.product=org.eclipse.jdt.ls.core.product \
|
||||
-Dlog.protocol=true \
|
||||
-Dlog.level=ALL \
|
||||
-javaagent:$HOME/.local/share/nvim/lsp_servers/jdtls/lombok.jar \
|
||||
-Xms1g \
|
||||
-Xmx2G \
|
||||
-jar $(echo "$JAR") \
|
||||
-configuration "$CONFIG" \
|
||||
-data "${1:-$HOME/workspace}" \
|
||||
--add-modules=ALL-SYSTEM \
|
||||
--add-opens java.base/java.util=ALL-UNNAMED \
|
||||
--add-opens java.base/java.lang=ALL-UNNAMED
|
||||
|
||||
# for older java versions if you wanna use lombok
|
||||
# -Xbootclasspath/a:/usr/local/share/lombok/lombok.jar \
|
||||
|
||||
# -javaagent:/usr/local/share/lombok/lombok.jar \
|
|
@ -0,0 +1,13 @@
|
|||
#Requires -Version 7.1
|
||||
$ErrorActionPreference = "Stop" # exit when command fails
|
||||
|
||||
$env:XDG_DATA_HOME = $env:XDG_DATA_HOME ?? $env:APPDATA
|
||||
$env:XDG_CONFIG_HOME = $env:XDG_CONFIG_HOME ?? $env:LOCALAPPDATA
|
||||
$env:XDG_CACHE_HOME = $env:XDG_CACHE_HOME ?? $env:TEMP
|
||||
|
||||
$env:LUNARVIM_RUNTIME_DIR = $env:LUNARVIM_RUNTIME_DIR ?? "$env:XDG_DATA_HOME\lunarvim"
|
||||
$env:LUNARVIM_CONFIG_DIR = $env:LUNARVIM_CONFIG_DIR ?? "$env:XDG_CONFIG_HOME\lvim"
|
||||
$env:LUNARVIM_CACHE_DIR = $env:LUNARVIM_CACHE_DIR ?? "$env:XDG_CACHE_HOME\lvim"
|
||||
$env:LUNARVIM_BASE_DIR = $env:LUNARVIM_BASE_DIR ?? "$env:LUNARVIM_RUNTIME_DIR\lvim"
|
||||
|
||||
nvim -u "$env:LUNARVIM_RUNTIME_DIR\lvim\init.lua" @args
|
|
@ -0,0 +1,7 @@
|
|||
#!/bin/sh
|
||||
|
||||
export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-RUNTIME_DIR_VAR}"
|
||||
export LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-CONFIG_DIR_VAR}"
|
||||
export LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-CACHE_DIR_VAR}"
|
||||
|
||||
exec nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/init.lua" "$@"
|
|
@ -0,0 +1,115 @@
|
|||
local sp = os.getenv "SNAPSHOT_PATH"
|
||||
|
||||
local function call_proc(process, opts, cb)
|
||||
local output, error_output = "", ""
|
||||
local handle_stdout = function(err, chunk)
|
||||
assert(not err, err)
|
||||
if chunk then
|
||||
output = output .. chunk
|
||||
end
|
||||
end
|
||||
|
||||
local handle_stderr = function(err, chunk)
|
||||
assert(not err, err)
|
||||
if chunk then
|
||||
error_output = error_output .. chunk
|
||||
end
|
||||
end
|
||||
|
||||
local uv = vim.loop
|
||||
local handle
|
||||
|
||||
local stdout = uv.new_pipe(false)
|
||||
local stderr = uv.new_pipe(false)
|
||||
|
||||
local stdio = { nil, stdout, stderr }
|
||||
|
||||
handle = uv.spawn(
|
||||
process,
|
||||
{ args = opts.args, cwd = opts.cwd or uv.cwd(), stdio = stdio },
|
||||
vim.schedule_wrap(function(code)
|
||||
if code ~= 0 then
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
end
|
||||
|
||||
local check = uv.new_check()
|
||||
check:start(function()
|
||||
for _, pipe in ipairs(stdio) do
|
||||
if pipe and not pipe:is_closing() then
|
||||
return
|
||||
end
|
||||
end
|
||||
check:stop()
|
||||
handle:close()
|
||||
cb(code, output, error_output)
|
||||
end)
|
||||
end)
|
||||
)
|
||||
|
||||
uv.read_start(stdout, handle_stdout)
|
||||
uv.read_start(stderr, handle_stderr)
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
local plugins_list = {}
|
||||
|
||||
local completed = 0
|
||||
|
||||
local function write_lockfile(verbose)
|
||||
local default_plugins = {}
|
||||
local active_jobs = {}
|
||||
|
||||
local core_plugins = require "lvim.plugins"
|
||||
for _, plugin in pairs(core_plugins) do
|
||||
local name = plugin[1]:match "/(%S*)"
|
||||
local url = "https://github.com/" .. plugin[1]
|
||||
local commit = ""
|
||||
table.insert(default_plugins, {
|
||||
name = name,
|
||||
url = url,
|
||||
commit = commit,
|
||||
})
|
||||
end
|
||||
|
||||
table.sort(default_plugins, function(a, b)
|
||||
return a.name < b.name
|
||||
end)
|
||||
|
||||
for _, entry in pairs(default_plugins) do
|
||||
local on_done = function(success, result, errors)
|
||||
completed = completed + 1
|
||||
if not success then
|
||||
print("error: " .. errors)
|
||||
return
|
||||
end
|
||||
local latest_sha = result:gsub("\tHEAD\n", ""):sub(1, 7)
|
||||
plugins_list[entry.name] = {
|
||||
commit = latest_sha,
|
||||
}
|
||||
end
|
||||
|
||||
local handle = call_proc("git", { args = { "ls-remote", entry.url, "HEAD" } }, on_done)
|
||||
assert(handle)
|
||||
table.insert(active_jobs, handle)
|
||||
end
|
||||
|
||||
print("active: " .. #active_jobs)
|
||||
print("plugins: " .. #default_plugins)
|
||||
|
||||
vim.wait(#active_jobs * 60 * 1000, function()
|
||||
return completed == #active_jobs
|
||||
end)
|
||||
|
||||
if verbose then
|
||||
print(vim.inspect(plugins_list))
|
||||
end
|
||||
|
||||
local fd = assert(io.open(sp, "w"))
|
||||
fd:write(vim.json.encode(plugins_list), "\n")
|
||||
fd:flush()
|
||||
end
|
||||
|
||||
write_lockfile()
|
||||
vim.cmd "q"
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
REPO_DIR=$(git rev-parse --show-toplevel)
|
||||
|
||||
export SNAPSHOT_NAME="default.json"
|
||||
export SNAPSHOT_DIR="${REPO_DIR}/snapshots"
|
||||
|
||||
mkdir -p "${SNAPSHOT_DIR}"
|
||||
|
||||
export SNAPSHOT_PATH="${REPO_DIR}/snapshots/${SNAPSHOT_NAME}"
|
||||
|
||||
time lvim --headless \
|
||||
-c "luafile ./utils/ci/generate_new_lockfile.lua"
|
||||
|
||||
temp=$(mktemp)
|
||||
|
||||
jq --sort-keys . "${SNAPSHOT_PATH}" >"${temp}"
|
||||
mv "${temp}" "${SNAPSHOT_PATH}"
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
REPO_DIR="$(git rev-parse --show-toplevel)"
|
||||
HELP_URL="https://github.com/LunarVim/LunarVim/blob/rolling/CONTRIBUTING.md#commit-messages"
|
||||
CONFIG="$REPO_DIR/.github/workflows/commitlint.config.js"
|
||||
|
||||
if ! npx commitlint --edit --verbose --help-url "$HELP_URL" --config "$CONFIG"; then
|
||||
exit 1
|
||||
fi
|
|
@ -0,0 +1,26 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
export LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$HOME/.local/share/lunarvim"}"
|
||||
|
||||
export LVIM_TEST_ENV=true
|
||||
|
||||
# we should start with an empty configuration
|
||||
LUNARVIM_CONFIG_DIR="$(mktemp -d)"
|
||||
LUNARVIM_CACHE_DIR="$(mktemp -d)"
|
||||
|
||||
export LUNARVIM_CONFIG_DIR LUNARVIM_CACHE_DIR
|
||||
|
||||
echo "cache: $LUNARVIM_CACHE_DIR
|
||||
|
||||
config: $LUNARVIM_CONFIG_DIR"
|
||||
|
||||
lvim() {
|
||||
nvim -u "$LUNARVIM_RUNTIME_DIR/lvim/tests/minimal_init.lua" --cmd "set runtimepath+=$LUNARVIM_RUNTIME_DIR/lvim" "$@"
|
||||
}
|
||||
|
||||
if [ -n "$1" ]; then
|
||||
lvim --headless -c "lua require('plenary.busted').run('$1')"
|
||||
else
|
||||
lvim --headless -c "PlenaryBustedDirectory tests/specs { minimal_init = './tests/minimal_init.lua' }"
|
||||
fi
|
|
@ -0,0 +1,15 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
BRANCH="$(git rev-parse --abbrev-ref HEAD)"
|
||||
|
||||
if [ "$BRANCH" != "master" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
REPO_DIR="$(git rev-parse --show-toplevel)"
|
||||
LATEST_TAG="$(git describe --tags --abbrev=0)"
|
||||
CONFIG_FILE="$REPO_DIR/.github/workflows/cliff.toml"
|
||||
CHANGELOG="$REPO_DIR/CHANGELOG.md"
|
||||
|
||||
git -C "$REPO_DIR" cliff "$LATEST_TAG"..HEAD -u -c "$CONFIG_FILE" -p "$CHANGELOG"
|
|
@ -0,0 +1,134 @@
|
|||
local completed = 0
|
||||
local collection = {}
|
||||
local active_jobs = {}
|
||||
|
||||
local fmt = string.format
|
||||
local core_plugins = require "lvim.plugins"
|
||||
|
||||
local default_snapshot_path = join_paths(get_lvim_base_dir(), "snapshots", "default.json")
|
||||
local fd = io.open(default_snapshot_path, "rb")
|
||||
local content
|
||||
if fd then
|
||||
content = fd:read "*a"
|
||||
end
|
||||
local default_sha1 = vim.json.decode(content)
|
||||
|
||||
local get_short_name = function(spec)
|
||||
return spec[1]:match "/(%S*)"
|
||||
end
|
||||
|
||||
local get_default_sha1 = function(spec)
|
||||
local short_name, _ = get_short_name(spec)
|
||||
assert(default_sha1[short_name])
|
||||
return default_sha1[short_name].commit
|
||||
end
|
||||
|
||||
local is_directory = require("lvim.utils").is_directory
|
||||
-- see packer.init()
|
||||
local packdir = join_paths(get_runtime_dir(), "site", "pack", "packer")
|
||||
local packer_config = { opt_dir = join_paths(packdir, "opt"), start_dir = join_paths(packdir, "start") }
|
||||
local is_optional = function(spec)
|
||||
return spec.opt or spec.event or spec.cmd or spec.module
|
||||
end
|
||||
local get_install_path = function(spec)
|
||||
local prefix = is_optional(spec) and packer_config.opt_dir or packer_config.start_dir
|
||||
local path = join_paths(prefix, get_short_name(spec))
|
||||
assert(is_directory(path))
|
||||
return path
|
||||
end
|
||||
|
||||
local function call_proc(process, opts, cb)
|
||||
local output, error_output = "", ""
|
||||
local handle_stdout = function(err, chunk)
|
||||
assert(not err, err)
|
||||
if chunk then
|
||||
output = output .. chunk
|
||||
end
|
||||
end
|
||||
|
||||
local handle_stderr = function(err, chunk)
|
||||
assert(not err, err)
|
||||
if chunk then
|
||||
error_output = error_output .. chunk
|
||||
end
|
||||
end
|
||||
|
||||
local uv = vim.loop
|
||||
local handle
|
||||
|
||||
local stdout = uv.new_pipe(false)
|
||||
local stderr = uv.new_pipe(false)
|
||||
|
||||
local stdio = { nil, stdout, stderr }
|
||||
|
||||
handle = uv.spawn(
|
||||
process,
|
||||
{ args = opts.args, cwd = opts.cwd or uv.cwd(), stdio = stdio },
|
||||
vim.schedule_wrap(function(code)
|
||||
if code ~= 0 then
|
||||
stdout:read_stop()
|
||||
stderr:read_stop()
|
||||
end
|
||||
|
||||
local check = uv.new_check()
|
||||
check:start(function()
|
||||
for _, pipe in ipairs(stdio) do
|
||||
if pipe and not pipe:is_closing() then
|
||||
return
|
||||
end
|
||||
end
|
||||
check:stop()
|
||||
handle:close()
|
||||
cb(code, output, error_output)
|
||||
end)
|
||||
end)
|
||||
)
|
||||
|
||||
uv.read_start(stdout, handle_stdout)
|
||||
uv.read_start(stderr, handle_stderr)
|
||||
|
||||
return handle
|
||||
end
|
||||
|
||||
local function verify_core_plugins(verbose)
|
||||
for _, spec in pairs(core_plugins) do
|
||||
if not spec.disable then
|
||||
table.insert(collection, {
|
||||
name = get_short_name(spec),
|
||||
commit = get_default_sha1(spec),
|
||||
path = get_install_path(spec),
|
||||
})
|
||||
end
|
||||
end
|
||||
|
||||
for _, entry in pairs(collection) do
|
||||
local on_done = function(code, result, errors)
|
||||
completed = completed + 1
|
||||
if code ~= 0 then
|
||||
io.write(errors .. "\n")
|
||||
-- os.exit(code)
|
||||
else
|
||||
if verbose then
|
||||
io.write(fmt("verified [%s]\n", entry.name))
|
||||
end
|
||||
end
|
||||
local current_commit = result:gsub("\n", ""):gsub([[']], [[]])
|
||||
-- just in case there are some extra qutoes or it's a longer commit hash
|
||||
if current_commit ~= entry.commit then
|
||||
io.write(fmt("mismatch at [%s]: expected [%s], got [%s]\n", entry.name, entry.commit, current_commit))
|
||||
os.exit(1)
|
||||
end
|
||||
end
|
||||
|
||||
local handle = call_proc("git", { args = { "log", "--pretty='%h'", "-1" }, cwd = entry.path }, on_done)
|
||||
assert(handle)
|
||||
table.insert(active_jobs, handle)
|
||||
end
|
||||
|
||||
vim.wait(#active_jobs * 60 * 1000, function()
|
||||
return completed == #active_jobs
|
||||
end)
|
||||
end
|
||||
|
||||
verify_core_plugins()
|
||||
vim.cmd "q"
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/env bash
|
||||
set -e
|
||||
|
||||
BASEDIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
||||
BASEDIR="$(dirname -- "$(dirname -- "$BASEDIR")")"
|
||||
|
||||
LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-"$BASEDIR"}"
|
||||
|
||||
lvim --headless \
|
||||
-c "luafile ${LUNARVIM_BASE_DIR}/utils/ci/verify_plugins.lua"
|
|
@ -0,0 +1,13 @@
|
|||
[Desktop Entry]
|
||||
Name=LunarVim
|
||||
GenericName=Text Editor
|
||||
Comment=An IDE layer for Neovim with sane defaults. Completely free and community driven.
|
||||
TryExec=lvim
|
||||
Exec=lvim %F
|
||||
Terminal=true
|
||||
Type=Application
|
||||
Keywords=Text;editor;
|
||||
Icon=nvim
|
||||
Categories=Utility;TextEditor;
|
||||
StartupNotify=false
|
||||
MimeType=text/english;text/plain;text/x-makefile;text/x-c++hdr;text/x-c++src;text/x-chdr;text/x-csrc;text/x-java;text/x-moc;text/x-pascal;text/x-tcl;text/x-tex;application/x-shellscript;text/x-c;text/x-c++;
|
|
@ -0,0 +1,27 @@
|
|||
# To run this file execute:
|
||||
# docker build -f <Path to this file> <Path to Lunarvim basedir> -t Lunarvim:local
|
||||
|
||||
FROM ubuntu:latest
|
||||
|
||||
# Set environment correctly
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV PATH="/root/.local/bin:/root/.cargo/bin:/root/.npm-global/bin${PATH}"
|
||||
|
||||
# Copy in local directory
|
||||
COPY --chown=root:root . /LunarVim
|
||||
|
||||
# Install dependencies and LunarVim
|
||||
RUN apt update && \
|
||||
apt -y install sudo curl build-essential git fzf python3-dev python3-pip cargo && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \
|
||||
apt update && \
|
||||
apt -y install nodejs && \
|
||||
apt clean && rm -rf /var/lib/apt/lists/* /tmp/* && \
|
||||
/LunarVim/utils/installer/install-neovim-from-release && \
|
||||
/LunarVim/utils/installer/install.sh --local --no-install-dependencies
|
||||
|
||||
# Setup LVIM to run on startup
|
||||
ENTRYPOINT ["/bin/bash"]
|
||||
CMD ["lvim"]
|
||||
|
||||
# vim: ft=dockerfile:
|
|
@ -0,0 +1,27 @@
|
|||
# To run this file execute:
|
||||
# docker build -f Dockerfile.remote . -t Lunarvim:remote
|
||||
|
||||
FROM ubuntu:latest
|
||||
|
||||
# Build argument to point to correct branch on GitHub
|
||||
ARG LV_BRANCH=rolling
|
||||
|
||||
# Set environment correctly
|
||||
ENV DEBIAN_FRONTEND=noninteractive
|
||||
ENV PATH="/root/.local/bin:/root/.cargo/bin:/root/.npm-global/bin${PATH}"
|
||||
|
||||
# Install dependencies and LunarVim
|
||||
RUN apt update && \
|
||||
apt -y install sudo curl build-essential git fzf python3-dev python3-pip cargo && \
|
||||
curl -fsSL https://deb.nodesource.com/setup_16.x | bash - && \
|
||||
apt update && \
|
||||
apt -y install nodejs && \
|
||||
apt clean && rm -rf /var/lib/apt/lists/* /tmp/* && \
|
||||
curl -LSs https://raw.githubusercontent.com/lunarvim/lunarvim/${LV_BRANCH}/utils/installer/install-neovim-from-release | bash && \
|
||||
LV_BRANCH=${LV_BRANCH} curl -LSs https://raw.githubusercontent.com/lunarvim/lunarvim/${LV_BRANCH}/utils/installer/install.sh | bash -s -- --no-install-dependencies
|
||||
|
||||
# Setup LVIM to run on startup
|
||||
ENTRYPOINT ["/bin/bash"]
|
||||
CMD ["lvim"]
|
||||
|
||||
# vim: ft=dockerfile:
|
|
@ -0,0 +1,167 @@
|
|||
--[[
|
||||
lvim is the global options object
|
||||
|
||||
Linters should be
|
||||
filled in as strings with either
|
||||
a global executable or a path to
|
||||
an executable
|
||||
]]
|
||||
-- THESE ARE EXAMPLE CONFIGS FEEL FREE TO CHANGE TO WHATEVER YOU WANT
|
||||
|
||||
-- general
|
||||
lvim.log.level = "warn"
|
||||
lvim.format_on_save = true
|
||||
lvim.colorscheme = "onedarker"
|
||||
-- to disable icons and use a minimalist setup, uncomment the following
|
||||
-- lvim.use_icons = false
|
||||
|
||||
-- keymappings [view all the defaults by pressing <leader>Lk]
|
||||
lvim.leader = "space"
|
||||
-- add your own keymapping
|
||||
lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
|
||||
-- unmap a default keymapping
|
||||
-- vim.keymap.del("n", "<C-Up>")
|
||||
-- override a default keymapping
|
||||
-- lvim.keys.normal_mode["<C-q>"] = ":q<cr>" -- or vim.keymap.set("n", "<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.
|
||||
-- we use protected-mode (pcall) just in case the plugin wasn't loaded yet.
|
||||
-- local _, actions = pcall(require, "telescope.actions")
|
||||
-- lvim.builtin.telescope.defaults.mappings = {
|
||||
-- -- for input mode
|
||||
-- i = {
|
||||
-- ["<C-j>"] = actions.move_selection_next,
|
||||
-- ["<C-k>"] = actions.move_selection_previous,
|
||||
-- ["<C-n>"] = actions.cycle_history_next,
|
||||
-- ["<C-p>"] = actions.cycle_history_prev,
|
||||
-- },
|
||||
-- -- for normal mode
|
||||
-- n = {
|
||||
-- ["<C-j>"] = actions.move_selection_next,
|
||||
-- ["<C-k>"] = actions.move_selection_previous,
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Use which-key to add extra bindings with the leader-key prefix
|
||||
-- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }
|
||||
-- lvim.builtin.which_key.mappings["t"] = {
|
||||
-- name = "+Trouble",
|
||||
-- r = { "<cmd>Trouble lsp_references<cr>", "References" },
|
||||
-- f = { "<cmd>Trouble lsp_definitions<cr>", "Definitions" },
|
||||
-- d = { "<cmd>Trouble document_diagnostics<cr>", "Diagnostics" },
|
||||
-- q = { "<cmd>Trouble quickfix<cr>", "QuickFix" },
|
||||
-- l = { "<cmd>Trouble loclist<cr>", "LocationList" },
|
||||
-- w = { "<cmd>Trouble workspace_diagnostics<cr>", "Wordspace Diagnostics" },
|
||||
-- }
|
||||
|
||||
-- TODO: User Config for predefined plugins
|
||||
-- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile
|
||||
lvim.builtin.alpha.active = true
|
||||
lvim.builtin.alpha.mode = "dashboard"
|
||||
lvim.builtin.notify.active = true
|
||||
lvim.builtin.terminal.active = true
|
||||
lvim.builtin.nvimtree.setup.view.side = "left"
|
||||
lvim.builtin.nvimtree.setup.renderer.icons.show.git = false
|
||||
|
||||
-- if you don't want all the parsers change this to a table of the ones you want
|
||||
lvim.builtin.treesitter.ensure_installed = {
|
||||
"bash",
|
||||
"c",
|
||||
"javascript",
|
||||
"json",
|
||||
"lua",
|
||||
"python",
|
||||
"typescript",
|
||||
"tsx",
|
||||
"css",
|
||||
"rust",
|
||||
"java",
|
||||
"yaml",
|
||||
}
|
||||
|
||||
lvim.builtin.treesitter.ignore_install = { "haskell" }
|
||||
lvim.builtin.treesitter.highlight.enabled = true
|
||||
|
||||
-- generic LSP settings
|
||||
|
||||
-- ---@usage disable automatic installation of servers
|
||||
-- lvim.lsp.automatic_servers_installation = false
|
||||
|
||||
-- ---configure a server manually. !!Requires `:LvimCacheReset` to take effect!!
|
||||
-- ---see the full default list `:lua print(vim.inspect(lvim.lsp.automatic_configuration.skipped_servers))`
|
||||
-- vim.list_extend(lvim.lsp.automatic_configuration.skipped_servers, { "pyright" })
|
||||
-- local opts = {} -- check the lspconfig documentation for a list of all possible options
|
||||
-- require("lvim.lsp.manager").setup("pyright", opts)
|
||||
|
||||
-- ---remove a server from the skipped list, e.g. eslint, or emmet_ls. !!Requires `:LvimCacheReset` to take effect!!
|
||||
-- ---`:LvimInfo` lists which server(s) are skiipped for the current filetype
|
||||
-- vim.tbl_map(function(server)
|
||||
-- return server ~= "emmet_ls"
|
||||
-- end, lvim.lsp.automatic_configuration.skipped_servers)
|
||||
|
||||
-- -- you can set a custom on_attach function that will be used for all the language servers
|
||||
-- -- See <https://github.com/neovim/nvim-lspconfig#keybindings-and-completion>
|
||||
-- lvim.lsp.on_attach_callback = function(client, bufnr)
|
||||
-- local function buf_set_option(...)
|
||||
-- vim.api.nvim_buf_set_option(bufnr, ...)
|
||||
-- end
|
||||
-- --Enable completion triggered by <c-x><c-o>
|
||||
-- buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
|
||||
-- end
|
||||
|
||||
-- -- set a formatter, this will override the language server formatting capabilities (if it exists)
|
||||
-- local formatters = require "lvim.lsp.null-ls.formatters"
|
||||
-- formatters.setup {
|
||||
-- { command = "black", filetypes = { "python" } },
|
||||
-- { command = "isort", filetypes = { "python" } },
|
||||
-- {
|
||||
-- -- each formatter accepts a list of options identical to https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md#Configuration
|
||||
-- command = "prettier",
|
||||
-- ---@usage arguments to pass to the formatter
|
||||
-- -- these cannot contain whitespaces, options such as `--line-width 80` become either `{'--line-width', '80'}` or `{'--line-width=80'}`
|
||||
-- extra_args = { "--print-with", "100" },
|
||||
-- ---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
|
||||
-- filetypes = { "typescript", "typescriptreact" },
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- -- set additional linters
|
||||
-- local linters = require "lvim.lsp.null-ls.linters"
|
||||
-- linters.setup {
|
||||
-- { command = "flake8", filetypes = { "python" } },
|
||||
-- {
|
||||
-- -- each linter accepts a list of options identical to https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md#Configuration
|
||||
-- command = "shellcheck",
|
||||
-- ---@usage arguments to pass to the formatter
|
||||
-- -- these cannot contain whitespaces, options such as `--line-width 80` become either `{'--line-width', '80'}` or `{'--line-width=80'}`
|
||||
-- extra_args = { "--severity", "warning" },
|
||||
-- },
|
||||
-- {
|
||||
-- command = "codespell",
|
||||
-- ---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
|
||||
-- filetypes = { "javascript", "python" },
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Additional Plugins
|
||||
-- lvim.plugins = {
|
||||
-- {"folke/tokyonight.nvim"},
|
||||
-- {
|
||||
-- "folke/trouble.nvim",
|
||||
-- cmd = "TroubleToggle",
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Autocommands (https://neovim.io/doc/user/autocmd.html)
|
||||
-- vim.api.nvim_create_autocmd("BufEnter", {
|
||||
-- pattern = { "*.json", "*.jsonc" },
|
||||
-- -- enable wrap mode for json files only
|
||||
-- command = "setlocal wrap",
|
||||
-- })
|
||||
-- vim.api.nvim_create_autocmd("FileType", {
|
||||
-- pattern = "zsh",
|
||||
-- callback = function()
|
||||
-- -- let treesitter use bash highlight for zsh files as well
|
||||
-- require("nvim-treesitter.highlight").attach(0, "bash")
|
||||
-- end,
|
||||
-- })
|
|
@ -0,0 +1,182 @@
|
|||
--[[
|
||||
THESE ARE EXAMPLE CONFIGS FEEL FREE TO CHANGE TO WHATEVER YOU WANT
|
||||
`lvim` is the global options object
|
||||
]]
|
||||
|
||||
-- Enable powershell as your default shell
|
||||
vim.opt.shell = "pwsh.exe -NoLogo"
|
||||
vim.opt.shellcmdflag =
|
||||
"-NoLogo -NoProfile -ExecutionPolicy RemoteSigned -Command [Console]::InputEncoding=[Console]::OutputEncoding=[System.Text.Encoding]::UTF8;"
|
||||
vim.cmd [[
|
||||
let &shellredir = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
|
||||
let &shellpipe = '2>&1 | Out-File -Encoding UTF8 %s; exit $LastExitCode'
|
||||
set shellquote= shellxquote=
|
||||
]]
|
||||
|
||||
-- Set a compatible clipboard manager
|
||||
vim.g.clipboard = {
|
||||
copy = {
|
||||
["+"] = "win32yank.exe -i --crlf",
|
||||
["*"] = "win32yank.exe -i --crlf",
|
||||
},
|
||||
paste = {
|
||||
["+"] = "win32yank.exe -o --lf",
|
||||
["*"] = "win32yank.exe -o --lf",
|
||||
},
|
||||
}
|
||||
|
||||
-- general
|
||||
lvim.log.level = "warn"
|
||||
lvim.format_on_save = true
|
||||
lvim.colorscheme = "onedarker"
|
||||
-- to disable icons and use a minimalist setup, uncomment the following
|
||||
-- lvim.use_icons = false
|
||||
|
||||
-- keymappings [view all the defaults by pressing <leader>Lk]
|
||||
lvim.leader = "space"
|
||||
-- add your own keymapping
|
||||
lvim.keys.normal_mode["<C-s>"] = ":w<cr>"
|
||||
-- unmap a default keymapping
|
||||
-- vim.keymap.del("n", "<C-Up>")
|
||||
-- override a default keymapping
|
||||
-- lvim.keys.normal_mode["<C-q>"] = ":q<cr>" -- or vim.keymap.set("n", "<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.
|
||||
-- we use protected-mode (pcall) just in case the plugin wasn't loaded yet.
|
||||
-- local _, actions = pcall(require, "telescope.actions")
|
||||
-- lvim.builtin.telescope.defaults.mappings = {
|
||||
-- -- for input mode
|
||||
-- i = {
|
||||
-- ["<C-j>"] = actions.move_selection_next,
|
||||
-- ["<C-k>"] = actions.move_selection_previous,
|
||||
-- ["<C-n>"] = actions.cycle_history_next,
|
||||
-- ["<C-p>"] = actions.cycle_history_prev,
|
||||
-- },
|
||||
-- -- for normal mode
|
||||
-- n = {
|
||||
-- ["<C-j>"] = actions.move_selection_next,
|
||||
-- ["<C-k>"] = actions.move_selection_previous,
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Use which-key to add extra bindings with the leader-key prefix
|
||||
-- lvim.builtin.which_key.mappings["P"] = { "<cmd>Telescope projects<CR>", "Projects" }
|
||||
-- lvim.builtin.which_key.mappings["t"] = {
|
||||
-- name = "+Trouble",
|
||||
-- r = { "<cmd>Trouble lsp_references<cr>", "References" },
|
||||
-- f = { "<cmd>Trouble lsp_definitions<cr>", "Definitions" },
|
||||
-- d = { "<cmd>Trouble document_diagnostics<cr>", "Diagnostics" },
|
||||
-- q = { "<cmd>Trouble quickfix<cr>", "QuickFix" },
|
||||
-- l = { "<cmd>Trouble loclist<cr>", "LocationList" },
|
||||
-- w = { "<cmd>Trouble workspace_diagnostics<cr>", "Workspace Diagnostics" },
|
||||
-- }
|
||||
|
||||
-- After changing plugin config exit and reopen LunarVim, Run :PackerInstall :PackerCompile
|
||||
lvim.builtin.alpha.active = true
|
||||
lvim.builtin.alpha.mode = "dashboard"
|
||||
lvim.builtin.notify.active = true
|
||||
lvim.builtin.terminal.active = false
|
||||
-- lvim.builtin.terminal.shell = "pwsh.exe -NoLogo"
|
||||
|
||||
-- nvim-tree has some performance issues on windows, see kyazdani42/nvim-tree.lua#549
|
||||
lvim.builtin.nvimtree.setup.diagnostics.enable = false
|
||||
lvim.builtin.nvimtree.setup.filters.custom = false
|
||||
lvim.builtin.nvimtree.setup.git.enable = false
|
||||
lvim.builtin.nvimtree.setup.update_cwd = false
|
||||
lvim.builtin.nvimtree.setup.update_focused_file.update_cwd = false
|
||||
lvim.builtin.nvimtree.setup.view.side = "left"
|
||||
lvim.builtin.nvimtree.setup.renderer.highlight_git = false
|
||||
lvim.builtin.nvimtree.setup.renderer.icons.show.git = false
|
||||
|
||||
-- if you don't want all the parsers change this to a table of the ones you want
|
||||
lvim.builtin.treesitter.ensure_installed = {
|
||||
"c",
|
||||
"lua",
|
||||
}
|
||||
|
||||
lvim.builtin.treesitter.ignore_install = { "haskell" }
|
||||
lvim.builtin.treesitter.highlight.enabled = true
|
||||
|
||||
-- generic LSP settings
|
||||
|
||||
-- ---@usage disable automatic installation of servers
|
||||
-- lvim.lsp.automatic_servers_installation = false
|
||||
|
||||
-- ---configure a server manually. !!Requires `:LvimCacheReset` to take effect!!
|
||||
-- ---see the full default list `:lua print(vim.inspect(lvim.lsp.automatic_configuration.skipped_servers))`
|
||||
-- vim.list_extend(lvim.lsp.automatic_configuration.skipped_servers, { "pyright" })
|
||||
-- local opts = {} -- check the lspconfig documentation for a list of all possible options
|
||||
-- require("lvim.lsp.manager").setup("pyright", opts)
|
||||
|
||||
-- ---remove a server from the skipped list, e.g. eslint, or emmet_ls. !!Requires `:LvimCacheReset` to take effect!!
|
||||
-- ---`:LvimInfo` lists which server(s) are skiipped for the current filetype
|
||||
-- vim.tbl_map(function(server)
|
||||
-- return server ~= "emmet_ls"
|
||||
-- end, lvim.lsp.automatic_configuration.skipped_servers)
|
||||
|
||||
-- -- you can set a custom on_attach function that will be used for all the language servers
|
||||
-- -- See <https://github.com/neovim/nvim-lspconfig#keybindings-and-completion>
|
||||
-- lvim.lsp.on_attach_callback = function(client, bufnr)
|
||||
-- local function buf_set_option(...)
|
||||
-- vim.api.nvim_buf_set_option(bufnr, ...)
|
||||
-- end
|
||||
-- --Enable completion triggered by <c-x><c-o>
|
||||
-- buf_set_option("omnifunc", "v:lua.vim.lsp.omnifunc")
|
||||
-- end
|
||||
|
||||
-- -- set a formatter, this will override the language server formatting capabilities (if it exists)
|
||||
-- local formatters = require "lvim.lsp.null-ls.formatters"
|
||||
-- formatters.setup {
|
||||
-- { command = "black", filetypes = { "python" } },
|
||||
-- { command = "isort", filetypes = { "python" } },
|
||||
-- {
|
||||
-- -- each formatter accepts a list of options identical to https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md#Configuration
|
||||
-- command = "prettier",
|
||||
-- ---@usage arguments to pass to the formatter
|
||||
-- -- these cannot contain whitespaces, options such as `--line-width 80` become either `{'--line-width', '80'}` or `{'--line-width=80'}`
|
||||
-- extra_args = { "--print-with", "100" },
|
||||
-- ---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
|
||||
-- filetypes = { "typescript", "typescriptreact" },
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- -- set additional linters
|
||||
-- local linters = require "lvim.lsp.null-ls.linters"
|
||||
-- linters.setup {
|
||||
-- { command = "flake8", filetypes = { "python" } },
|
||||
-- {
|
||||
-- -- each linter accepts a list of options identical to https://github.com/jose-elias-alvarez/null-ls.nvim/blob/main/doc/BUILTINS.md#Configuration
|
||||
-- command = "shellcheck",
|
||||
-- ---@usage arguments to pass to the formatter
|
||||
-- -- these cannot contain whitespaces, options such as `--line-width 80` become either `{'--line-width', '80'}` or `{'--line-width=80'}`
|
||||
-- extra_args = { "--severity", "warning" },
|
||||
-- },
|
||||
-- {
|
||||
-- command = "codespell",
|
||||
-- ---@usage specify which filetypes to enable. By default a providers will attach to all the filetypes it supports.
|
||||
-- filetypes = { "javascript", "python" },
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Additional Plugins
|
||||
-- lvim.plugins = {
|
||||
-- {"folke/tokyonight.nvim"},
|
||||
-- {
|
||||
-- "folke/trouble.nvim",
|
||||
-- cmd = "TroubleToggle",
|
||||
-- },
|
||||
-- }
|
||||
|
||||
-- Autocommands (https://neovim.io/doc/user/autocmd.html)
|
||||
-- vim.api.nvim_create_autocmd("BufEnter", {
|
||||
-- pattern = { "*.json", "*.jsonc" },
|
||||
-- -- enable wrap mode for json files only
|
||||
-- command = "setlocal wrap",
|
||||
-- })
|
||||
-- vim.api.nvim_create_autocmd("FileType", {
|
||||
-- pattern = "zsh",
|
||||
-- callback = function()
|
||||
-- -- let treesitter use bash highlight for zsh files as well
|
||||
-- require("nvim-treesitter.highlight").attach(0, "bash")
|
||||
-- end,
|
||||
-- })
|
|
@ -0,0 +1,87 @@
|
|||
#!/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
|
||||
|
||||
if [[ "${RELEASE_VER}" == "latest" ]]; then
|
||||
declare -r RELEASE_URL="https://github.com/neovim/neovim/releases/${RELEASE_VER}/download/${ARCHIVE_NAME}.tar.gz"
|
||||
else
|
||||
declare -r RELEASE_URL="https://github.com/neovim/neovim/releases/download/${RELEASE_VER}/${ARCHIVE_NAME}.tar.gz"
|
||||
fi
|
||||
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="$(openssl dgst -sha256 "$DOWNLOAD_DIR/$ARCHIVE_NAME.tar.gz" | awk '{print $2}')"
|
||||
|
||||
if [ "$RELEASE_SHA" != "$DOWNLOADED_SHA" ]; then
|
||||
echo "Error! checksum mismatch."
|
||||
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 "$@"
|
|
@ -0,0 +1,290 @@
|
|||
#Requires -Version 7.1
|
||||
$ErrorActionPreference = "Stop" # exit when command fails
|
||||
|
||||
# set script variables
|
||||
$LV_BRANCH = $LV_BRANCH ?? "rolling"
|
||||
$LV_REMOTE = $LV_REMOTE ?? "lunarvim/lunarvim.git"
|
||||
$INSTALL_PREFIX = $INSTALL_PREFIX ?? "$HOME\.local"
|
||||
|
||||
$env:XDG_DATA_HOME = $env:XDG_DATA_HOME ?? $env:APPDATA
|
||||
$env:XDG_CONFIG_HOME = $env:XDG_CONFIG_HOME ?? $env:LOCALAPPDATA
|
||||
$env:XDG_CACHE_HOME = $env:XDG_CACHE_HOME ?? $env:TEMP
|
||||
|
||||
$env:LUNARVIM_RUNTIME_DIR = $env:LUNARVIM_RUNTIME_DIR ?? "$env:XDG_DATA_HOME\lunarvim"
|
||||
$env:LUNARVIM_CONFIG_DIR = $env:LUNARVIM_CONFIG_DIR ?? "$env:XDG_CONFIG_HOME\lvim"
|
||||
$env:LUNARVIM_CACHE_DIR = $env:LUNARVIM_CACHE_DIR ?? "$env:XDG_CACHE_HOME\lvim"
|
||||
$env:LUNARVIM_BASE_DIR = $env:LUNARVIM_BASE_DIR ?? "$env:LUNARVIM_RUNTIME_DIR\lvim"
|
||||
|
||||
$__lvim_dirs = (
|
||||
$env:LUNARVIM_BASE_DIR,
|
||||
$env:LUNARVIM_RUNTIME_DIR,
|
||||
$env:LUNARVIM_CONFIG_DIR,
|
||||
$env:LUNARVIM_CACHE_DIR
|
||||
)
|
||||
|
||||
function __add_separator($div_width) {
|
||||
"-" * $div_width
|
||||
Write-Output ""
|
||||
}
|
||||
|
||||
function msg($text){
|
||||
Write-Output $text
|
||||
__add_separator "80"
|
||||
}
|
||||
|
||||
function main($cliargs) {
|
||||
|
||||
print_logo
|
||||
|
||||
verify_lvim_dirs
|
||||
|
||||
if ($cliargs.Contains("--overwrite")) {
|
||||
Write-Output "!!Warning!! -> Removing all lunarvim related config because of the --overwrite flag"
|
||||
$answer = Read-Host "Would you like to continue? [y]es or [n]o "
|
||||
if ("$answer" -ne "y" -and "$answer" -ne "Y") {
|
||||
exit 1
|
||||
}
|
||||
uninstall_lvim
|
||||
}
|
||||
if ($cliargs.Contains("--local") -or $cliargs.Contains("--testing")) {
|
||||
msg "Using local LunarVim installation"
|
||||
local_install
|
||||
exit
|
||||
}
|
||||
|
||||
msg "Checking dependencies.."
|
||||
check_system_deps
|
||||
|
||||
$answer = Read-Host "Would you like to check lunarvim's NodeJS dependencies? [y]es or [n]o (default: no) "
|
||||
if ("$answer" -eq "y" -or "$answer" -eq "Y") {
|
||||
install_nodejs_deps
|
||||
}
|
||||
|
||||
$answer = Read-Host "Would you like to check lunarvim's Python dependencies? [y]es or [n]o (default: no) "
|
||||
if ("$answer" -eq "y" -or "$answer" -eq "Y") {
|
||||
install_python_deps
|
||||
}
|
||||
|
||||
|
||||
if (Test-Path "$env:LUNARVIM_BASE_DIR\init.lua" ) {
|
||||
msg "Updating LunarVim"
|
||||
validate_lunarvim_files
|
||||
}
|
||||
else {
|
||||
msg "Cloning Lunarvim"
|
||||
clone_lvim
|
||||
setup_lvim
|
||||
}
|
||||
}
|
||||
|
||||
function print_missing_dep_msg($dep) {
|
||||
Write-Output "[ERROR]: Unable to find dependency [$dep]"
|
||||
Write-Output "Please install it first and re-run the installer."
|
||||
}
|
||||
|
||||
$winget_package_matrix=@{"git" = "Git.Git"; "nvim" = "Neovim.Neovim"; "make" = "GnuWin32.Make"; "node" = "OpenJS.NodeJS"; "pip" = "Python.Python.3"}
|
||||
$scoop_package_matrix=@{"git" = "git"; "nvim" = "neovim-nightly"; "make" = "make"; "node" = "nodejs"; "pip" = "python3"}
|
||||
|
||||
function install_system_package($dep) {
|
||||
if (Get-Command -Name "winget" -ErrorAction SilentlyContinue) {
|
||||
Write-Output "Attempting to install dependency [$dep] with winget"
|
||||
$install_cmd = "winget install --interactive $winget_package_matrix[$dep]"
|
||||
}
|
||||
elseif (Get-Command -Name "scoop" -ErrorAction SilentlyContinue) {
|
||||
Write-Output "Attempting to install dependency [$dep] with scoop"
|
||||
# TODO: check if it's fine to not run it with --global
|
||||
$install_cmd = "scoop install $scoop_package_matrix[$dep]"
|
||||
}
|
||||
else {
|
||||
print_missing_dep_msg "$dep"
|
||||
exit 1
|
||||
}
|
||||
|
||||
try {
|
||||
Invoke-Command $install_cmd -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
print_missing_dep_msg "$dep"
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
function check_system_dep($dep) {
|
||||
try {
|
||||
Get-Command -Name $dep -ErrorAction Stop | Out-Null
|
||||
}
|
||||
catch {
|
||||
install_system_package "$dep"
|
||||
}
|
||||
}
|
||||
|
||||
function check_system_deps() {
|
||||
check_system_dep "git"
|
||||
check_system_dep "nvim"
|
||||
check_system_dep "make"
|
||||
}
|
||||
|
||||
function install_nodejs_deps() {
|
||||
$dep = "node"
|
||||
try {
|
||||
check_system_dep "$dep"
|
||||
Invoke-Command -ScriptBlock { npm install --global neovim tree-sitter-cli } -ErrorAction Break
|
||||
}
|
||||
catch {
|
||||
print_missing_dep_msg "$dep"
|
||||
}
|
||||
}
|
||||
|
||||
function install_python_deps() {
|
||||
$dep = "pip"
|
||||
try {
|
||||
check_system_dep "$dep"
|
||||
Invoke-Command -ScriptBlock { python -m pip install --user pynvim } -ErrorAction Break
|
||||
}
|
||||
catch {
|
||||
print_missing_dep_msg "$dep"
|
||||
}
|
||||
}
|
||||
|
||||
function backup_old_config() {
|
||||
$src = "$env:LUNARVIM_CONFIG_DIR"
|
||||
if (Test-Path $src) {
|
||||
New-Item "$src.old" -ItemType Directory -Force | Out-Null
|
||||
Copy-Item -Force -Recurse "$src\*" "$src.old\." | Out-Null
|
||||
}
|
||||
msg "Backup operation complete"
|
||||
}
|
||||
|
||||
|
||||
function local_install() {
|
||||
verify_lvim_dirs
|
||||
$repoDir = git rev-parse --show-toplevel
|
||||
$gitLocalCloneCmd = git clone --progress "$repoDir" "$env:LUNARVIM_BASE_DIR"
|
||||
Invoke-Command -ErrorAction Stop -ScriptBlock { $gitLocalCloneCmd; setup_lvim }
|
||||
}
|
||||
|
||||
function clone_lvim() {
|
||||
try {
|
||||
$gitCloneCmd = git clone --progress --depth 1 --branch "$LV_BRANCH" `
|
||||
"https://github.com/$LV_REMOTE" `
|
||||
"$env:LUNARVIM_BASE_DIR"
|
||||
Invoke-Command -ErrorAction Stop -ScriptBlock { $gitCloneCmd }
|
||||
}
|
||||
catch {
|
||||
msg "Failed to clone repository. Installation failed."
|
||||
exit 1
|
||||
}
|
||||
}
|
||||
|
||||
function setup_shim() {
|
||||
if ((Test-Path "$INSTALL_PREFIX\bin") -eq $false) {
|
||||
New-Item "$INSTALL_PREFIX\bin" -ItemType Directory | Out-Null
|
||||
}
|
||||
|
||||
Copy-Item -Force "$env:LUNARVIM_BASE_DIR\utils\bin\lvim.ps1" "$INSTALL_PREFIX\bin\lvim.ps1"
|
||||
}
|
||||
|
||||
function uninstall_lvim() {
|
||||
foreach ($dir in $__lvim_dirs) {
|
||||
if (Test-Path "$dir") {
|
||||
Remove-Item -Force -Recurse "$dir"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function verify_lvim_dirs() {
|
||||
foreach ($dir in $__lvim_dirs) {
|
||||
if ((Test-Path "$dir") -eq $false) {
|
||||
New-Item "$dir" -ItemType Directory | Out-Null
|
||||
}
|
||||
}
|
||||
backup_old_config
|
||||
}
|
||||
|
||||
|
||||
function setup_lvim() {
|
||||
msg "Installing LunarVim shim"
|
||||
setup_shim
|
||||
|
||||
msg "Installing sample configuration"
|
||||
|
||||
if (Test-Path "$env:LUNARVIM_CONFIG_DIR\config.lua") {
|
||||
Move-Item "$env:LUNARVIM_CONFIG_DIR\config.lua" "$env:LUNARVIM_CONFIG_DIR\config.lua.old"
|
||||
}
|
||||
|
||||
New-Item -ItemType File -Path "$env:LUNARVIM_CONFIG_DIR\config.lua" | Out-Null
|
||||
|
||||
$exampleConfig = "$env:LUNARVIM_BASE_DIR\utils\installer\config_win.example.lua"
|
||||
Copy-Item -Force "$exampleConfig" "$env:LUNARVIM_CONFIG_DIR\config.lua"
|
||||
|
||||
# FIXME: this has never worked
|
||||
# Invoke-Expression "$INSTALL_PREFIX\bin\lvim.ps1 --headless -c 'autocmd User PackerComplete quitall' -c 'PackerSync'"
|
||||
|
||||
Write-Host "Make sure to run `:PackerSync` at first launch" -ForegroundColor Green
|
||||
|
||||
create_alias
|
||||
|
||||
msg "Thank you for installing LunarVim!!"
|
||||
|
||||
Write-Output "You can start it by running: $INSTALL_PREFIX\bin\lvim.ps1"
|
||||
Write-Output "Do not forget to use a font with glyphs (icons) support [https://github.com/ryanoasis/nerd-fonts]"
|
||||
}
|
||||
|
||||
|
||||
function validate_lunarvim_files() {
|
||||
Set-Alias lvim "$INSTALL_PREFIX\bin\lvim.ps1"
|
||||
try {
|
||||
$verify_version_cmd='if v:errmsg != "" | cquit | else | quit | endif'
|
||||
Invoke-Command -ScriptBlock { lvim --headless -c 'LvimUpdate' -c "$verify_version_cmd" } -ErrorAction SilentlyContinue
|
||||
}
|
||||
catch {
|
||||
Write-Output "Unable to guarantee data integrity while updating. Please run `:LvimUpdate` manually instead."
|
||||
exit 1
|
||||
}
|
||||
Write-Output "Your LunarVim installation is now up to date!"
|
||||
}
|
||||
|
||||
function create_alias {
|
||||
try {
|
||||
$answer = Read-Host $(`
|
||||
"Would you like to create an alias inside your Powershell profile?`n" + `
|
||||
"(This enables you to start lvim with the command 'lvim') [y]es or [n]o (default: no)" )
|
||||
}
|
||||
catch {
|
||||
msg "Non-interactive mode detected. Skipping alias creation"
|
||||
return
|
||||
}
|
||||
|
||||
if ("$answer" -ne "y" -or "$answer" -ne "Y") {
|
||||
return
|
||||
}
|
||||
|
||||
$lvim_bin="$INSTALL_PREFIX\bin\lvim.ps1"
|
||||
$lvim_alias = Get-Alias lvim -ErrorAction SilentlyContinue
|
||||
|
||||
if ($lvim_alias.Definition -eq $lvim_bin) {
|
||||
Write-Output "Alias is already set and will not be reset."
|
||||
return
|
||||
}
|
||||
|
||||
Add-Content -Path $PROFILE -Value $("`r`nSet-Alias lvim $lvim_bin")
|
||||
|
||||
Write-Host 'To use the new alias in this window reload your profile with: `. $PROFILE`' -ForegroundColor Green
|
||||
}
|
||||
|
||||
function print_logo(){
|
||||
Write-Output "
|
||||
|
||||
88\ 88\
|
||||
88 | \__|
|
||||
88 |88\ 88\ 888888$\ 888888\ 888888\ 88\ 88\ 88\ 888888\8888\
|
||||
88 |88 | 88 |88 __88\ \____88\ 88 __88\\88\ 88 |88 |88 _88 _88\
|
||||
88 |88 | 88 |88 | 88 | 888888$ |88 | \__|\88\88 / 88 |88 / 88 / 88 |
|
||||
88 |88 | 88 |88 | 88 |88 __88 |88 | \88$ / 88 |88 | 88 | 88 |
|
||||
88 |\888888 |88 | 88 |\888888$ |88 | \$ / 88 |88 | 88 | 88 |
|
||||
\__| \______/ \__| \__| \_______|\__| \_/ \__|\__| \__| \__|
|
||||
|
||||
"
|
||||
}
|
||||
|
||||
main "$args"
|
|
@ -0,0 +1,449 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
#Set branch to master unless specified by the user
|
||||
declare LV_BRANCH="${LV_BRANCH:-"master"}"
|
||||
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"}"
|
||||
|
||||
declare -r LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}"
|
||||
declare -r LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}"
|
||||
declare -r LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-"$XDG_CACHE_HOME/lvim"}"
|
||||
declare -r LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-"$LUNARVIM_RUNTIME_DIR/lvim"}"
|
||||
|
||||
declare BASEDIR
|
||||
BASEDIR="$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")" &>/dev/null && pwd)"
|
||||
BASEDIR="$(dirname -- "$(dirname -- "$BASEDIR")")"
|
||||
readonly BASEDIR
|
||||
|
||||
declare ARGS_LOCAL=0
|
||||
declare ARGS_OVERWRITE=0
|
||||
declare ARGS_INSTALL_DEPENDENCIES=1
|
||||
declare INTERACTIVE_MODE=1
|
||||
|
||||
declare -a __lvim_dirs=(
|
||||
"$LUNARVIM_CONFIG_DIR"
|
||||
"$LUNARVIM_RUNTIME_DIR"
|
||||
"$LUNARVIM_CACHE_DIR"
|
||||
)
|
||||
|
||||
declare -a __npm_deps=(
|
||||
"neovim"
|
||||
"tree-sitter-cli"
|
||||
)
|
||||
|
||||
declare -a __pip_deps=(
|
||||
"pynvim"
|
||||
)
|
||||
|
||||
function usage() {
|
||||
echo "Usage: install.sh [<options>]"
|
||||
echo ""
|
||||
echo "Options:"
|
||||
echo " -h, --help Print this help message"
|
||||
echo " -l, --local Install local copy of LunarVim"
|
||||
echo " -y, --yes Disable confirmation prompts (answer yes to all questions)"
|
||||
echo " --overwrite Overwrite previous LunarVim configuration (a backup is always performed first)"
|
||||
echo " --[no]-install-dependencies Whether to automatically install external dependencies (will prompt by default)"
|
||||
}
|
||||
|
||||
function parse_arguments() {
|
||||
while [ "$#" -gt 0 ]; do
|
||||
case "$1" in
|
||||
-l | --local)
|
||||
ARGS_LOCAL=1
|
||||
;;
|
||||
--overwrite)
|
||||
ARGS_OVERWRITE=1
|
||||
;;
|
||||
-y | --yes)
|
||||
INTERACTIVE_MODE=0
|
||||
;;
|
||||
--install-dependencies)
|
||||
ARGS_INSTALL_DEPENDENCIES=1
|
||||
;;
|
||||
--no-install-dependencies)
|
||||
ARGS_INSTALL_DEPENDENCIES=0
|
||||
;;
|
||||
-h | --help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
}
|
||||
|
||||
function msg() {
|
||||
local text="$1"
|
||||
local div_width="80"
|
||||
printf "%${div_width}s\n" ' ' | tr ' ' -
|
||||
printf "%s\n" "$text"
|
||||
}
|
||||
|
||||
function confirm() {
|
||||
local question="$1"
|
||||
while true; do
|
||||
msg "$question"
|
||||
read -p "[y]es or [n]o (default: no) : " -r answer
|
||||
case "$answer" in
|
||||
y | Y | yes | YES | Yes)
|
||||
return 0
|
||||
;;
|
||||
n | N | no | NO | No | *[[:blank:]]* | "")
|
||||
return 1
|
||||
;;
|
||||
*)
|
||||
msg "Please answer [y]es or [n]o."
|
||||
;;
|
||||
esac
|
||||
done
|
||||
}
|
||||
|
||||
function main() {
|
||||
parse_arguments "$@"
|
||||
|
||||
print_logo
|
||||
|
||||
msg "Detecting platform for managing any additional neovim dependencies"
|
||||
detect_platform
|
||||
|
||||
check_system_deps
|
||||
|
||||
if [ "$ARGS_INSTALL_DEPENDENCIES" -eq 1 ]; then
|
||||
if [ "$INTERACTIVE_MODE" -eq 1 ]; then
|
||||
if confirm "Would you like to install LunarVim's NodeJS dependencies?"; then
|
||||
install_nodejs_deps
|
||||
fi
|
||||
if confirm "Would you like to install LunarVim's Python dependencies?"; then
|
||||
install_python_deps
|
||||
fi
|
||||
if confirm "Would you like to install LunarVim's Rust dependencies?"; then
|
||||
install_rust_deps
|
||||
fi
|
||||
else
|
||||
install_nodejs_deps
|
||||
install_python_deps
|
||||
install_rust_deps
|
||||
fi
|
||||
fi
|
||||
|
||||
backup_old_config
|
||||
|
||||
verify_lvim_dirs
|
||||
|
||||
if [ "$ARGS_LOCAL" -eq 1 ]; then
|
||||
link_local_lvim
|
||||
elif [ -d "$LUNARVIM_BASE_DIR" ]; then
|
||||
validate_lunarvim_files
|
||||
else
|
||||
clone_lvim
|
||||
fi
|
||||
|
||||
setup_lvim
|
||||
|
||||
msg "Thank you for installing LunarVim!!"
|
||||
echo "You can start it by running: $INSTALL_PREFIX/bin/lvim"
|
||||
echo "Do not forget to use a font with glyphs (icons) support [https://github.com/ryanoasis/nerd-fonts]"
|
||||
}
|
||||
|
||||
function detect_platform() {
|
||||
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 -tv"
|
||||
else # assume debian based
|
||||
RECOMMEND_INSTALL="sudo apt install -y"
|
||||
fi
|
||||
;;
|
||||
FreeBSD)
|
||||
RECOMMEND_INSTALL="sudo pkg install -y"
|
||||
;;
|
||||
NetBSD)
|
||||
RECOMMEND_INSTALL="sudo pkgin install"
|
||||
;;
|
||||
OpenBSD)
|
||||
RECOMMEND_INSTALL="doas pkg_add"
|
||||
;;
|
||||
Darwin)
|
||||
RECOMMEND_INSTALL="brew install"
|
||||
;;
|
||||
*)
|
||||
echo "OS $OS is not currently supported."
|
||||
exit 1
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
function print_missing_dep_msg() {
|
||||
if [ "$#" -eq 1 ]; then
|
||||
echo "[ERROR]: Unable to find dependency [$1]"
|
||||
echo "Please install it first and re-run the installer. Try: $RECOMMEND_INSTALL $1"
|
||||
else
|
||||
local cmds
|
||||
cmds=$(for i in "$@"; do echo "$RECOMMEND_INSTALL $i"; done)
|
||||
printf "[ERROR]: Unable to find dependencies [%s]" "$@"
|
||||
printf "Please install any one of the dependencies and re-run the installer. Try: \n%s\n" "$cmds"
|
||||
fi
|
||||
}
|
||||
|
||||
function check_neovim_min_version() {
|
||||
local verify_version_cmd='if !has("nvim-0.7") | cquit | else | quit | endif'
|
||||
|
||||
# exit with an error if min_version not found
|
||||
if ! nvim --headless -u NONE -c "$verify_version_cmd"; then
|
||||
echo "[ERROR]: LunarVim requires at least Neovim v0.7 or higher"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function verify_core_plugins() {
|
||||
msg "Verifying core plugins"
|
||||
if ! bash "$LUNARVIM_BASE_DIR/utils/ci/verify_plugins.sh"; then
|
||||
echo "[ERROR]: Unable to verify plugins, makde sure to manually run ':PackerSync' when starting lvim for the first time."
|
||||
exit 1
|
||||
fi
|
||||
echo "Verification complete!"
|
||||
}
|
||||
|
||||
function validate_lunarvim_files() {
|
||||
local verify_version_cmd='if v:errmsg != "" | cquit | else | quit | endif'
|
||||
if ! "$INSTALL_PREFIX/bin/lvim" --headless -c 'LvimUpdate' -c "$verify_version_cmd" &>/dev/null; then
|
||||
msg "Removing old installation files"
|
||||
rm -rf "$LUNARVIM_BASE_DIR"
|
||||
clone_lvim
|
||||
fi
|
||||
}
|
||||
|
||||
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
|
||||
check_neovim_min_version
|
||||
}
|
||||
|
||||
function __install_nodejs_deps_pnpm() {
|
||||
echo "Installing node modules with pnpm.."
|
||||
pnpm install -g "${__npm_deps[@]}"
|
||||
echo "All NodeJS dependencies are successfully installed"
|
||||
}
|
||||
|
||||
function __install_nodejs_deps_npm() {
|
||||
echo "Installing node modules with npm.."
|
||||
for dep in "${__npm_deps[@]}"; do
|
||||
if ! npm ls -g "$dep" &>/dev/null; then
|
||||
printf "installing %s .." "$dep"
|
||||
npm install -g "$dep"
|
||||
fi
|
||||
done
|
||||
|
||||
echo "All NodeJS dependencies are successfully installed"
|
||||
}
|
||||
|
||||
function __install_nodejs_deps_yarn() {
|
||||
echo "Installing node modules with yarn.."
|
||||
yarn global add "${__npm_deps[@]}"
|
||||
echo "All NodeJS dependencies are successfully installed"
|
||||
}
|
||||
|
||||
function __validate_node_installation() {
|
||||
local pkg_manager="$1"
|
||||
local manager_home
|
||||
|
||||
if ! command -v "$pkg_manager" &>/dev/null; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$pkg_manager" == "npm" ]; then
|
||||
manager_home="$(npm config get prefix 2>/dev/null)"
|
||||
elif [ "$pkg_manager" == "pnpm" ]; then
|
||||
manager_home="$(pnpm config get prefix 2>/dev/null)"
|
||||
else
|
||||
manager_home="$(yarn global bin 2>/dev/null)"
|
||||
fi
|
||||
|
||||
if [ ! -d "$manager_home" ] || [ ! -w "$manager_home" ]; then
|
||||
echo "[ERROR] Unable to install using [$pkg_manager] without administrative privileges."
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
function install_nodejs_deps() {
|
||||
local -a pkg_managers=("pnpm" "yarn" "npm")
|
||||
for pkg_manager in "${pkg_managers[@]}"; do
|
||||
if __validate_node_installation "$pkg_manager"; then
|
||||
eval "__install_nodejs_deps_$pkg_manager"
|
||||
return
|
||||
fi
|
||||
done
|
||||
print_missing_dep_msg "${pkg_managers[@]}"
|
||||
exit 1
|
||||
}
|
||||
|
||||
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 successfully installed"
|
||||
}
|
||||
|
||||
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 cargo. Make sure to install it to avoid any problems"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
# we try to install the missing one with cargo even though it's unlikely to be found
|
||||
function install_rust_deps() {
|
||||
local -a deps=("fd::fd-find" "rg::ripgrep")
|
||||
for dep in "${deps[@]}"; do
|
||||
if ! command -v "${dep%%::*}" &>/dev/null; then
|
||||
__attempt_to_install_with_cargo "${dep##*::}"
|
||||
fi
|
||||
done
|
||||
echo "All Rust dependencies are successfully installed"
|
||||
}
|
||||
|
||||
function verify_lvim_dirs() {
|
||||
if [ "$ARGS_OVERWRITE" -eq 1 ]; then
|
||||
for dir in "${__lvim_dirs[@]}"; do
|
||||
[ -d "$dir" ] && rm -rf "$dir"
|
||||
done
|
||||
fi
|
||||
|
||||
for dir in "${__lvim_dirs[@]}"; do
|
||||
mkdir -p "$dir"
|
||||
done
|
||||
}
|
||||
|
||||
function backup_old_config() {
|
||||
local src="$LUNARVIM_CONFIG_DIR"
|
||||
if [ ! -d "$src" ]; then
|
||||
return
|
||||
fi
|
||||
mkdir -p "$src.old"
|
||||
touch "$src/ignore"
|
||||
msg "Backing up old $src to $src.old"
|
||||
if command -v rsync &>/dev/null; then
|
||||
rsync --archive -hh --stats --partial --copy-links --cvs-exclude "$src"/ "$src.old"
|
||||
else
|
||||
OS="$(uname -s)"
|
||||
case "$OS" in
|
||||
Linux | *BSD)
|
||||
cp -r "$src/"* "$src.old/."
|
||||
;;
|
||||
Darwin)
|
||||
cp -R "$src/"* "$src.old/."
|
||||
;;
|
||||
*)
|
||||
echo "OS $OS is not currently supported."
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
msg "Backup operation complete"
|
||||
}
|
||||
|
||||
function clone_lvim() {
|
||||
msg "Cloning LunarVim configuration"
|
||||
if ! git clone --branch "$LV_BRANCH" \
|
||||
--depth 1 "https://github.com/${LV_REMOTE}" "$LUNARVIM_BASE_DIR"; then
|
||||
echo "Failed to clone repository. Installation failed."
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
function link_local_lvim() {
|
||||
echo "Linking local LunarVim repo"
|
||||
|
||||
# Detect whether it's a symlink or a folder
|
||||
if [ -d "$LUNARVIM_BASE_DIR" ]; then
|
||||
echo "Removing old installation files"
|
||||
rm -rf "$LUNARVIM_BASE_DIR"
|
||||
fi
|
||||
|
||||
echo " - $BASEDIR -> $LUNARVIM_BASE_DIR"
|
||||
ln -s -f "$BASEDIR" "$LUNARVIM_BASE_DIR"
|
||||
}
|
||||
|
||||
function setup_shim() {
|
||||
make -C "$LUNARVIM_BASE_DIR" install-bin
|
||||
}
|
||||
|
||||
function remove_old_cache_files() {
|
||||
local packer_cache="$LUNARVIM_CONFIG_DIR/plugin/packer_compiled.lua"
|
||||
if [ -e "$packer_cache" ]; then
|
||||
msg "Removing old packer cache file"
|
||||
rm -f "$packer_cache"
|
||||
fi
|
||||
|
||||
if [ -e "$LUNARVIM_CACHE_DIR/luacache" ] || [ -e "$LUNARVIM_CACHE_DIR/lvim_cache" ]; then
|
||||
msg "Removing old startup cache file"
|
||||
rm -f "$LUNARVIM_CACHE_DIR/{luacache,lvim_cache}"
|
||||
fi
|
||||
}
|
||||
|
||||
function setup_lvim() {
|
||||
|
||||
remove_old_cache_files
|
||||
|
||||
msg "Installing LunarVim shim"
|
||||
|
||||
setup_shim
|
||||
|
||||
cp "$LUNARVIM_BASE_DIR/utils/installer/config.example.lua" "$LUNARVIM_CONFIG_DIR/config.lua"
|
||||
|
||||
echo "Preparing Packer setup"
|
||||
|
||||
"$INSTALL_PREFIX/bin/lvim" --headless \
|
||||
-c 'autocmd User PackerComplete quitall' \
|
||||
-c 'PackerSync'
|
||||
|
||||
echo "Packer setup complete"
|
||||
|
||||
verify_core_plugins
|
||||
}
|
||||
|
||||
function print_logo() {
|
||||
cat <<'EOF'
|
||||
|
||||
88\ 88\
|
||||
88 | \__|
|
||||
88 |88\ 88\ 888888$\ 888888\ 888888\ 88\ 88\ 88\ 888888\8888\
|
||||
88 |88 | 88 |88 __88\ \____88\ 88 __88\\88\ 88 |88 |88 _88 _88\
|
||||
88 |88 | 88 |88 | 88 | 888888$ |88 | \__|\88\88 / 88 |88 / 88 / 88 |
|
||||
88 |88 | 88 |88 | 88 |88 __88 |88 | \88$ / 88 |88 | 88 | 88 |
|
||||
88 |\888888 |88 | 88 |\888888$ |88 | \$ / 88 |88 | 88 | 88 |
|
||||
\__| \______/ \__| \__| \_______|\__| \_/ \__|\__| \__| \__|
|
||||
|
||||
EOF
|
||||
}
|
||||
|
||||
main "$@"
|
|
@ -0,0 +1,37 @@
|
|||
#!/usr/bin/env bash
|
||||
set -eo pipefail
|
||||
|
||||
INSTALL_PREFIX="${INSTALL_PREFIX:-"$HOME/.local"}"
|
||||
|
||||
XDG_DATA_HOME="${XDG_DATA_HOME:-"$HOME/.local/share"}"
|
||||
XDG_CACHE_HOME="${XDG_CACHE_HOME:-"$HOME/.cache"}"
|
||||
XDG_CONFIG_HOME="${XDG_CONFIG_HOME:-"$HOME/.config"}"
|
||||
|
||||
LUNARVIM_RUNTIME_DIR="${LUNARVIM_RUNTIME_DIR:-"$XDG_DATA_HOME/lunarvim"}"
|
||||
LUNARVIM_CONFIG_DIR="${LUNARVIM_CONFIG_DIR:-"$XDG_CONFIG_HOME/lvim"}"
|
||||
LUNARVIM_CACHE_DIR="${LUNARVIM_CACHE_DIR:-"$XDG_CACHE_HOME/lvim"}"
|
||||
|
||||
LUNARVIM_BASE_DIR="${LUNARVIM_BASE_DIR:-"$LUNARVIM_RUNTIME_DIR/lvim"}"
|
||||
|
||||
function setup_shim() {
|
||||
local src="$LUNARVIM_BASE_DIR/utils/bin/lvim.template"
|
||||
local dst="$INSTALL_PREFIX/bin/lvim"
|
||||
|
||||
[ ! -d "$INSTALL_PREFIX/bin" ] && mkdir -p "$INSTALL_PREFIX/bin"
|
||||
|
||||
# remove outdated installation so that `cp` doesn't complain
|
||||
rm -f "$dst"
|
||||
|
||||
cp "$src" "$dst"
|
||||
|
||||
sed -e s"#RUNTIME_DIR_VAR#\"${LUNARVIM_RUNTIME_DIR}\"#"g \
|
||||
-e s"#CONFIG_DIR_VAR#\"${LUNARVIM_CONFIG_DIR}\"#"g \
|
||||
-e s"#CACHE_DIR_VAR#\"${LUNARVIM_CACHE_DIR}\"#"g "$src" \
|
||||
| tee "$dst" >/dev/null
|
||||
|
||||
chmod u+x "$dst"
|
||||
}
|
||||
|
||||
setup_shim "$@"
|
||||
|
||||
echo "You can start LunarVim by running: $INSTALL_PREFIX/bin/lvim"
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue