├── .github
├── FUNDING.yml
└── workflows
│ └── ci.yml
├── .stylua.toml
├── LICENSE
├── README.md
├── bin
└── dope
├── init.lua
├── lua
├── core
│ ├── cli.lua
│ ├── helper.lua
│ ├── init.lua
│ ├── keymap.lua
│ ├── options.lua
│ └── pack.lua
├── keymap
│ └── init.lua
└── modules
│ ├── completion
│ ├── config.lua
│ └── package.lua
│ ├── editor
│ ├── config.lua
│ └── package.lua
│ ├── tools
│ ├── config.lua
│ └── package.lua
│ └── ui
│ ├── config.lua
│ └── package.lua
├── snippets
├── lua.json
├── lua.lua
└── package.json
└── static
└── neovim.cat
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: glepnir
2 | custom: ['https://www.paypal.me/bobbyhub']
3 |
4 |
--------------------------------------------------------------------------------
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | name: ci
2 |
3 | on:
4 | push:
5 | branches:
6 | - main
7 |
8 | pull_request:
9 | branches:
10 | - main
11 |
12 | jobs:
13 | lint:
14 | runs-on: ubuntu-latest
15 |
16 | steps:
17 | - uses: actions/checkout@v3
18 |
19 | - name: Stylua
20 | uses: JohnnyMorganz/stylua-action@v1.1.2
21 | with:
22 | token: ${{ secrets.GITHUB_TOKEN }}
23 | args: --check .
24 |
--------------------------------------------------------------------------------
/.stylua.toml:
--------------------------------------------------------------------------------
1 | column_width = 120
2 | line_endings = "Unix"
3 | indent_type = "Spaces"
4 | indent_width = 2
5 | quote_style = "AutoPreferSingle"
6 | call_parentheses = "Always"
7 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Raphael
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
7 | dope
8 |
13 |
14 |
15 |
16 |
17 |
21 |
22 |
23 |
27 |
28 |
29 |
33 |
34 |
35 |
36 |
37 |
41 |
42 |
43 | ## What is dope
44 |
45 | Many people are interested in my [personal configuration](https://github.com/glepnir/nvim). So I created dope.
46 |
47 | What does dope do? dope wants vimers to have their own config with high performance
48 |
49 | fast speed and modernity.
50 |
51 | ## Structure
52 |
53 | ```
54 | ├── init.lua
55 | ├── lua
56 | │ ├── core
57 | │ │ ├── cli.lua
58 | │ │ ├── helper.lua
59 | │ │ ├── init.lua
60 | │ │ ├── keymap.lua
61 | │ │ ├── options.lua
62 | │ │ └── pack.lua
63 | │ ├── keymap
64 | │ │ ├── config.lua
65 | │ │ └── init.lua
66 | │ └── modules
67 | │ ├── completion
68 | │ │ ├── config.lua
69 | │ │ └── package.lua
70 | │ ├── editor
71 | │ │ ├── config.lua
72 | │ │ └── package.lua
73 | │ ├── tools
74 | │ │ ├── config.lua
75 | │ │ └── package.lua
76 | │ └── ui
77 | │ ├── config.lua
78 | │ └── package.lua
79 | ├── snippets
80 | │ ├── lua.json
81 | │ ├── lua.lua
82 | │ └── package.json
83 | ```
84 |
85 | - `core` heart of dope it include the api of dope
86 | - `modlues` plugin module and config in this folder
87 | - `snippets` vscode snippets json file
88 |
89 | ## Usage
90 |
91 | - Click button `Use this template` It will generate a new repo based on dope on your GitHub
92 |
93 | ### Cli tool
94 |
95 | `bin/dope` is a cli tool for dope config. run `./bin/dope help` check more detail
96 |
97 | you can use `/bin/dope debug ui,editor` for debug modues. when you get trouble
98 | this is useful for your debug, this command mean disable `ui editor` modules.Then
99 | the plugins in `ui,editor` modules not load.
100 |
101 | ## How to install plugins
102 |
103 | dope use [lazy.nvim](https://github.com/folk/lazy.nvim) as package management plugin. register a plugin in `package.lua` by using dope api `require('core.pack').package`. more usage check the
104 | lazy.nvim doc and you can some examples in package.lua file.
105 |
106 | ### How to create module
107 |
108 | create a fold inside `modlues` folder and `package.lua` file you must created inside your module.
109 | dope will auto read this file at startup.
110 |
111 |
112 | ### How to config keymap
113 |
114 | In dope there are some apis that make it easy to set keymap. All apis are defined in `core/keymap.lua`.
115 |
116 | ```lua
117 | keymap.(n/i/c/v/x/t)map -- function to generate keymap by vim.keymap.set
118 | keymap.new_opts -- generate opts into vim.keymap.set
119 | -- function type that work with keymap.new_opts
120 | keymap.silent keymap.noremap keymap.expr keymap.nowait keymap.remap
121 | keymap.cmd -- just return string with and
122 | keymap.cu -- work like cmd but for visual map
123 | ```
124 |
125 | Use these apis to config your keymap in `keymap` folder. In this folder `keymap/init.lua` is necessary but if you
126 |
127 | have many vim mode remap you can config them in `keymap/other-file.lua` in dope is `config.lua` just an
128 |
129 | example file. Then config plugins keymap in `keymap/init.lua`. the example of api usage
130 |
131 | ```lua
132 | -- generate keymap in noremal mode
133 | nmap {
134 | -- packer
135 | {'pu',cmd('Lazy update'),opts(noremap,silent,'Lazy update')},
136 | {"",'h',opts(noremap)},
137 |
138 | }
139 |
140 | also you can pass a table not include sub table to `map` like
141 |
142 | ```lua
143 | nmap {'key','rhs',opts(noremap,silent)}
144 | ```
145 |
146 | use `:h vim.keymap.set` to know more about.
147 |
148 | ## Tips
149 |
150 | - Improve key repeat
151 |
152 | ```
153 | mac os need restart
154 | defaults write NSGlobalDomain KeyRepeat -int 1
155 | defaults write NSGlobalDomain InitialKeyRepeat -int 10
156 |
157 | linux
158 | xset r rate 210 40
159 | ```
160 |
161 | ## Donate
162 |
163 | [](https://paypal.me/bobbyhub)
164 |
165 | If you'd like to support my work financially, buy me a drink through [paypal](https://paypal.me/bobbyhub)
166 |
167 | ## License MIT
168 |
--------------------------------------------------------------------------------
/bin/dope:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env lua
2 |
3 | local arguments = {
4 | install = true,
5 | update = true,
6 | clean = true,
7 | doctor = true,
8 | debug = true,
9 | help = true,
10 | modules = true,
11 | }
12 |
13 | local argument
14 |
15 | if #arg == 0 then
16 | argument = 'install'
17 | else
18 | if #arg > 1 and (arg[1] ~= 'debug' and arg[1] ~= 'doctor') then
19 | error('passed multiple arguments.')
20 | end
21 |
22 | if not arguments[arg[1]] then
23 | error('unknow argument ' .. arg[1])
24 | end
25 | argument = arg[1]
26 |
27 | if arg[1] == 'debug' then
28 | local modules = [[let g:disable_modules="]]
29 | ---@diagnostic disable-next-line: deprecated
30 | for _, k in pairs({ table.unpack(arg, 2, #arg) } or {}) do
31 | modules = modules .. ',' .. 'modules/' .. k .. '/plugins'
32 | end
33 | modules = modules .. '"'
34 | os.execute("nvim --cmd '" .. modules .. "'")
35 | return
36 | end
37 | end
38 |
39 | local handle
40 | handle = assert(io.popen([[nvim --clean --headless --cmd 'echo $VIMRUNTIME|q' 2>&1]], 'r'))
41 | if not handle then
42 | return
43 | end
44 |
45 | local rtp = handle:read('*a')
46 | handle:close()
47 |
48 | -- read config path
49 | handle = assert(io.popen([[nvim --clean --headless --cmd 'echo stdpath("config")|q' 2>&1]], 'r'))
50 | local config_path = handle:read('*a')
51 | handle:close()
52 |
53 | -- set the poackage path
54 | package.path = package.path .. ';' .. rtp .. '/lua/vim/?.lua;' .. config_path .. '/lua/?.lua'
55 |
56 | if argument == 'help' then
57 | local helper = require('core.helper')
58 | helper.green('Dope usage')
59 | local usage = {
60 | { '\tinstall', ' install Plugins' },
61 | { '\tupdate ', ' update Plugins' },
62 | { '\tclean ', ' clean the directories' },
63 | { '\tdoctor ', ' check the plugins info' },
64 | { '\tmodules', ' Show all modules' },
65 | { '\tdebug ', ' dynamic disable modules for debug' },
66 | { '\thelp ', ' show the usage of bot' },
67 | }
68 | for _, msg in pairs(usage) do
69 | helper.write('blue')(msg[1])
70 | helper.write('white')(msg[2])
71 | print()
72 | end
73 | os.exit()
74 | end
75 |
76 | -- read data path
77 | handle = assert(io.popen([[nvim --clean --headless --cmd 'echo stdpath("data")|q' 2>&1]], 'r'))
78 | local data_path = handle:read('*a')
79 | handle:close()
80 |
81 | local cli = require('core.cli')
82 |
83 | cli.rtp = rtp
84 | cli.config_path = config_path
85 | cli.data_path = data_path
86 |
87 | -- env init
88 | cli:env_init()
89 |
90 | cli:meta(argument)(table.unpack(arg, 2))
91 |
--------------------------------------------------------------------------------
/init.lua:
--------------------------------------------------------------------------------
1 | require('core')
2 |
--------------------------------------------------------------------------------
/lua/core/cli.lua:
--------------------------------------------------------------------------------
1 | local cli = {}
2 | local helper = require('core.helper')
3 |
4 | function cli:env_init()
5 | self.module_path = helper.path_join(self.config_path, 'lua', 'modules')
6 | self.lazy_dir = helper.path_join(self.data_path, 'lazy')
7 |
8 | package.path = package.path
9 | .. ';'
10 | .. self.rtp
11 | .. '/lua/vim/?.lua;'
12 | .. self.module_path
13 | .. '/?.lua;'
14 | local shared = assert(loadfile(helper.path_join(self.rtp, 'lua', 'vim', 'shared.lua')))
15 | _G.vim = shared()
16 | end
17 |
18 | function cli:get_all_packages()
19 | local pack = require('core.pack')
20 | local p = io.popen('find "' .. cli.module_path .. '" -type f')
21 | if not p then
22 | return
23 | end
24 |
25 | for file in p:lines() do
26 | if file:find('package.lua') then
27 | local module = file:match(cli.module_path .. '/(.+).lua$')
28 | require(module)
29 | end
30 | end
31 | p:close()
32 |
33 | local lazy_keyword = {
34 | 'keys',
35 | 'ft',
36 | 'cmd',
37 | 'event',
38 | 'lazy',
39 | }
40 |
41 | local function generate_node(tbl, list)
42 | local node = tbl[1]
43 | list[node] = {}
44 | list[node].type = tbl.dev and 'Local Plugin' or 'Remote Plugin'
45 |
46 | local check_lazy = function(t, data)
47 | vim.tbl_filter(function(k)
48 | if vim.tbl_contains(lazy_keyword, k) then
49 | data.load = type(t[k]) == 'table' and table.concat(t[k], ',') or t[k]
50 | return true
51 | end
52 | return false
53 | end, vim.tbl_keys(t))
54 | end
55 |
56 | check_lazy(tbl, list[node])
57 |
58 | if tbl.dependencies then
59 | for _, v in pairs(tbl.dependencies) do
60 | if type(v) == 'string' then
61 | v = { v }
62 | end
63 |
64 | list[v[1]] = {
65 | from_depend = true,
66 | load_after = node,
67 | }
68 |
69 | list[v[1]].type = v.dev and 'Local Plugin' or 'Remote Plugin'
70 | check_lazy(v, list[v[1]])
71 | end
72 | end
73 | end
74 |
75 | local list = {}
76 | for _, data in pairs(pack.repos or {}) do
77 | if type(data) == string then
78 | data = { data }
79 | end
80 | generate_node(data, list)
81 | end
82 |
83 | return list
84 | end
85 |
86 | function cli:boot_strap()
87 | helper.blue('🔸 Search plugin management lazy.nvim in local')
88 | if helper.isdir(self.lazy_dir) then
89 | helper.green('🔸 Found lazy.nvim skip download')
90 | return
91 | end
92 | helper.run_git('lazy.nvim', 'git clone https://github.com/folke/lazy.nvim ' .. self.lazy_dir, 'Install')
93 | helper.success('lazy.nvim')
94 | end
95 |
96 | function cli:installer(type)
97 | cli:boot_strap()
98 |
99 | local packages = cli:get_all_packages()
100 | ---@diagnostic disable-next-line: unused-local, param-type-mismatch
101 | local res = {}
102 | for name, v in pairs(packages or {}) do
103 | if v.type:find('Remote') then
104 | local non_user_name = vim.split(name, '/')[2]
105 | local path = self.lazy_dir .. helper.path_sep .. non_user_name
106 | if helper.isdir(path) and type == 'install' then
107 | helper.purple('\t🥯 Skip already in plugin ' .. name)
108 | else
109 | local url = 'git clone https://github.com/'
110 | local cmd = type == 'install' and url .. name .. ' ' .. path or 'git -C ' .. path .. ' pull'
111 | local failed = helper.run_git(name, cmd, type)
112 | table.insert(res, failed)
113 | end
114 | else
115 | helper.purple('\t🥯 Skip local plugin ' .. name)
116 | end
117 | end
118 | if not vim.tbl_contains(res, true) then
119 | helper.green('🎉 Congratulations Config install or update success. Enjoy ^^')
120 | return
121 | end
122 | helper.red('Some plugins not install or update success please run install again')
123 | end
124 |
125 | function cli.install()
126 | cli:installer('install')
127 | end
128 |
129 | function cli.update()
130 | cli:installer('update')
131 | end
132 |
133 | function cli.clean()
134 | os.execute('rm -rf ' .. cli.lazy_dir)
135 | end
136 |
137 | function cli.doctor(pack_name)
138 | local list = cli:get_all_packages()
139 | if not list then
140 | return
141 | end
142 |
143 | helper.yellow('🔹 Total: ' .. vim.tbl_count(list) + 1 .. ' Plugins')
144 | local packs = pack_name and { [pack_name] = list[pack_name] } or list
145 | for k, v in pairs(packs) do
146 | helper.blue('\t' .. '✨' .. k)
147 | if v.type then
148 | helper.write('purple')('\tType: ')
149 | helper.write('white')(v.type)
150 | print()
151 | end
152 | if v.load then
153 | helper.write('purple')('\tLoad: ')
154 | helper.write('white')(v.load)
155 | print()
156 | end
157 |
158 | if v.from_depend then
159 | helper.write('purple')('\tDepend: ')
160 | helper.write('white')(v.load_after)
161 | print()
162 | end
163 | end
164 | end
165 |
166 | function cli.modules()
167 | local p = io.popen('find "' .. cli.module_path .. '" -type d')
168 | if not p then
169 | return
170 | end
171 | local res = {}
172 |
173 | for dict in p:lines() do
174 | dict = vim.split(dict, helper.path_sep)
175 | if dict[#dict] ~= 'modules' then
176 | table.insert(res, dict[#dict])
177 | end
178 | end
179 |
180 | helper.green('Found ' .. #res .. ' Modules in Local')
181 | for _, v in pairs(res) do
182 | helper.write('yellow')('\t✅ ' .. v)
183 | print()
184 | end
185 | end
186 |
187 | function cli:meta(arg)
188 | return function(data)
189 | self[arg](data)
190 | end
191 | end
192 |
193 | return cli
194 |
--------------------------------------------------------------------------------
/lua/core/helper.lua:
--------------------------------------------------------------------------------
1 | local helper = {}
2 | helper.path_sep = package.config:sub(1, 1) == '\\' and '\\' or '/'
3 |
4 | function helper.path_join(...)
5 | return table.concat({ ... }, helper.path_sep)
6 | end
7 |
8 | function helper.data_path()
9 | local cli = require('core.cli')
10 | if cli.config_path then
11 | return cli.config_path
12 | end
13 | return vim.fn.stdpath('data')
14 | end
15 |
16 | function helper.config_path()
17 | local cli = require('core.cli')
18 | if cli.data_path then
19 | return cli.data_path
20 | end
21 | return vim.fn.stdpath('config')
22 | end
23 |
24 | local function get_color(color)
25 | local tbl = {
26 | black = '\027[90m',
27 | red = '\027[91m',
28 | green = '\027[92m',
29 | yellow = '\027[93m',
30 | blue = '\027[94m',
31 | purple = '\027[95m',
32 | cyan = '\027[96m',
33 | white = '\027[97m',
34 | }
35 | return tbl[color]
36 | end
37 |
38 | local function color_print(color)
39 | local rgb = get_color(color)
40 | return function(text)
41 | print(rgb .. text .. '\027[m')
42 | end
43 | end
44 |
45 | function helper.write(color)
46 | local rgb = get_color(color)
47 | return function(text)
48 | io.write(rgb .. text .. '\027[m')
49 | end
50 | end
51 |
52 | function helper.success(msg)
53 | color_print('green')('\t🍻 ' .. msg .. ' Success ‼️ ')
54 | end
55 |
56 | function helper.error(msg)
57 | color_print('red')(msg)
58 | end
59 |
60 | function helper.run_git(name, cmd, type)
61 | local pip = assert(io.popen(cmd .. ' 2>&1'))
62 | color_print('green')('\t🍻 ' .. type .. ' ' .. name)
63 | local failed = false
64 | for line in pip:lines() do
65 | if line:find('fatal') then
66 | failed = true
67 | end
68 | io.write('\t ' .. line)
69 | io.write('\n')
70 | end
71 |
72 | pip:close()
73 | return failed
74 | end
75 |
76 | local function exists(file)
77 | local ok, _, code = os.rename(file, file)
78 | if not ok then
79 | if code == 13 then
80 | return true
81 | end
82 | end
83 | return ok
84 | end
85 |
86 | --- Check if a directory exists in this path
87 | function helper.isdir(path)
88 | return exists(path .. '/')
89 | end
90 |
91 | setmetatable(helper, {
92 | __index = function(_, k)
93 | return color_print(k)
94 | end,
95 | })
96 |
97 | return helper
98 |
--------------------------------------------------------------------------------
/lua/core/init.lua:
--------------------------------------------------------------------------------
1 | local g, fn = vim.g, vim.fn
2 | local helper = require('core.helper')
3 | -- remove check is windows because I only use mac or linux
4 | local cache_dir = helper.path_join(vim.fn.stdpath('cache'), 'nvim')
5 |
6 | -- Create cache dir and subs dir
7 | local createdir = function()
8 | local data_dir = {
9 | cache_dir .. 'backup',
10 | cache_dir .. 'session',
11 | cache_dir .. 'swap',
12 | cache_dir .. 'tags',
13 | cache_dir .. 'undo',
14 | }
15 | -- There only check once that If cache_dir exists
16 | -- Then I don't want to check subs dir exists
17 | if fn.isdirectory(cache_dir) == 0 then
18 | os.execute('mkdir -p ' .. cache_dir)
19 | for _, v in pairs(data_dir) do
20 | if fn.isdirectory(v) == 0 then
21 | os.execute('mkdir -p ' .. v)
22 | end
23 | end
24 | end
25 | end
26 |
27 | createdir()
28 |
29 | --disable_distribution_plugins
30 | g.loaded_gzip = 1
31 | g.loaded_tar = 1
32 | g.loaded_tarPlugin = 1
33 | g.loaded_zip = 1
34 | g.loaded_zipPlugin = 1
35 | g.loaded_getscript = 1
36 | g.loaded_getscriptPlugin = 1
37 | g.loaded_vimball = 1
38 | g.loaded_vimballPlugin = 1
39 | g.loaded_matchit = 1
40 | g.loaded_matchparen = 1
41 | g.loaded_2html_plugin = 1
42 | g.loaded_logiPat = 1
43 | g.loaded_rrhelper = 1
44 | g.loaded_netrw = 1
45 | g.loaded_netrwPlugin = 1
46 | g.loaded_netrwSettings = 1
47 | g.loaded_netrwFileHandlers = 1
48 |
49 | require('core.pack'):boot_strap()
50 | require('core.options')
51 | require('keymap')
52 |
--------------------------------------------------------------------------------
/lua/core/keymap.lua:
--------------------------------------------------------------------------------
1 | local keymap = {}
2 | local opts = {}
3 |
4 | function opts:new(instance)
5 | instance = instance
6 | or {
7 | options = {
8 | silent = false,
9 | nowait = false,
10 | expr = false,
11 | noremap = false,
12 | },
13 | }
14 | setmetatable(instance, self)
15 | self.__index = self
16 | return instance
17 | end
18 |
19 | function keymap.silent(opt)
20 | return function()
21 | opt.silent = true
22 | end
23 | end
24 |
25 | function keymap.noremap(opt)
26 | return function()
27 | opt.noremap = true
28 | end
29 | end
30 |
31 | function keymap.expr(opt)
32 | return function()
33 | opt.expr = true
34 | end
35 | end
36 |
37 | function keymap.remap(opt)
38 | return function()
39 | opt.remap = true
40 | end
41 | end
42 |
43 | function keymap.nowait(opt)
44 | return function()
45 | opt.nowait = true
46 | end
47 | end
48 |
49 | function keymap.new_opts(...)
50 | local args = { ... }
51 | local o = opts:new()
52 |
53 | if #args == 0 then
54 | return o.options
55 | end
56 |
57 | for _, arg in pairs(args) do
58 | if type(arg) == 'string' then
59 | o.options.desc = arg
60 | else
61 | arg(o.options)()
62 | end
63 | end
64 | return o.options
65 | end
66 |
67 | function keymap.cmd(str)
68 | return '' .. str .. ''
69 | end
70 |
71 | -- visual
72 | function keymap.cu(str)
73 | return '' .. str .. ''
74 | end
75 |
76 | --@private
77 | local keymap_set = function(mode, tbl)
78 | vim.validate({
79 | tbl = { tbl, 'table' },
80 | })
81 | local len = #tbl
82 | if len < 2 then
83 | vim.notify('keymap must has rhs')
84 | return
85 | end
86 |
87 | local options = len == 3 and tbl[3] or keymap.new_opts()
88 |
89 | vim.keymap.set(mode, tbl[1], tbl[2], options)
90 | end
91 |
92 | local function map(mod)
93 | return function(tbl)
94 | vim.validate({
95 | tbl = { tbl, 'table' },
96 | })
97 |
98 | if type(tbl[1]) == 'table' and type(tbl[2]) == 'table' then
99 | for _, v in pairs(tbl) do
100 | keymap_set(mod, v)
101 | end
102 | else
103 | keymap_set(mod, tbl)
104 | end
105 | end
106 | end
107 |
108 | keymap.nmap = map('n')
109 | keymap.imap = map('i')
110 | keymap.cmap = map('c')
111 | keymap.vmap = map('v')
112 | keymap.xmap = map('x')
113 | keymap.tmap = map('t')
114 |
115 | return keymap
116 |
--------------------------------------------------------------------------------
/lua/core/options.lua:
--------------------------------------------------------------------------------
1 | local opt = vim.opt
2 | local cache_dir = vim.env.HOME .. '/.cache/nvim/'
3 |
4 | opt.termguicolors = true
5 | opt.hidden = true
6 | opt.magic = true
7 | opt.virtualedit = 'block'
8 | opt.clipboard = 'unnamedplus'
9 | opt.wildignorecase = true
10 | opt.swapfile = false
11 | opt.directory = cache_dir .. 'swap/'
12 | opt.undodir = cache_dir .. 'undo/'
13 | opt.backupdir = cache_dir .. 'backup/'
14 | opt.viewdir = cache_dir .. 'view/'
15 | opt.spellfile = cache_dir .. 'spell/en.uft-8.add'
16 | opt.history = 2000
17 | opt.timeout = true
18 | opt.ttimeout = true
19 | opt.timeoutlen = 500
20 | opt.ttimeoutlen = 10
21 | opt.updatetime = 100
22 | opt.redrawtime = 1500
23 | opt.ignorecase = true
24 | opt.smartcase = true
25 | opt.infercase = true
26 |
27 | if vim.fn.executable('rg') == 1 then
28 | opt.grepformat = '%f:%l:%c:%m,%f:%l:%m'
29 | opt.grepprg = 'rg --vimgrep --no-heading --smart-case'
30 | end
31 |
32 | opt.completeopt = 'menu,menuone,noselect'
33 | opt.showmode = false
34 | opt.shortmess = 'aoOTIcF'
35 | opt.scrolloff = 2
36 | opt.sidescrolloff = 5
37 | opt.ruler = false
38 | opt.showtabline = 0
39 | opt.winwidth = 30
40 | opt.pumheight = 15
41 | opt.showcmd = false
42 |
43 | opt.cmdheight = 0
44 | opt.laststatus = 3
45 | opt.list = true
46 | opt.listchars = 'tab:»·,nbsp:+,trail:·,extends:→,precedes:←'
47 | opt.pumblend = 10
48 | opt.winblend = 10
49 | opt.undofile = true
50 |
51 | opt.smarttab = true
52 | opt.expandtab = true
53 | opt.autoindent = true
54 | opt.tabstop = 2
55 | opt.shiftwidth = 2
56 |
57 | -- wrap
58 | opt.linebreak = true
59 | opt.whichwrap = 'h,l,<,>,[,],~'
60 | opt.breakindentopt = 'shift:2,min:20'
61 | opt.showbreak = '↳ '
62 |
63 | opt.foldlevelstart = 99
64 | opt.foldmethod = 'marker'
65 |
66 | opt.number = true
67 | opt.signcolumn = 'yes'
68 | opt.spelloptions = 'camel'
69 |
70 | opt.textwidth = 100
71 | opt.colorcolumn = '100'
72 | if vim.loop.os_uname().sysname == 'Darwin' then
73 | vim.g.clipboard = {
74 | name = 'macOS-clipboard',
75 | copy = {
76 | ['+'] = 'pbcopy',
77 | ['*'] = 'pbcopy',
78 | },
79 | paste = {
80 | ['+'] = 'pbpaste',
81 | ['*'] = 'pbpaste',
82 | },
83 | cache_enabled = 0,
84 | }
85 | vim.g.python_host_prog = '/usr/bin/python'
86 | vim.g.python3_host_prog = '/usr/local/bin/python3'
87 | end
88 |
--------------------------------------------------------------------------------
/lua/core/pack.lua:
--------------------------------------------------------------------------------
1 | local uv, api, fn = vim.loop, vim.api, vim.fn
2 |
3 | local pack = {}
4 | pack.__index = pack
5 |
6 | function pack:load_modules_packages()
7 | local modules_dir = self.helper.path_join(self.config_path, 'lua', 'modules')
8 | self.repos = {}
9 |
10 | local list = vim.fs.find('package.lua', { path = modules_dir, type = 'file', limit = 10 })
11 | if #list == 0 then
12 | return
13 | end
14 |
15 | local disable_modules = {}
16 |
17 | if fn.exists('g:disable_modules') == 1 then
18 | disable_modules = vim.split(vim.g.disable_modules, ',', { trimempty = true })
19 | end
20 |
21 | for _, f in pairs(list) do
22 | local _, pos = f:find(modules_dir)
23 | f = f:sub(pos - 6, #f - 4)
24 | if not vim.tbl_contains(disable_modules, f) then
25 | require(f)
26 | end
27 | end
28 | end
29 |
30 | function pack:boot_strap()
31 | self.helper = require('core.helper')
32 | self.data_path = self.helper.data_path()
33 | self.config_path = self.helper.config_path()
34 | local lazy_path = self.helper.path_join(self.data_path, 'lazy', 'lazy.nvim')
35 | local state = uv.fs_stat(lazy_path)
36 | if not state then
37 | local cmd = '!git clone https://github.com/folke/lazy.nvim ' .. lazy_path
38 | api.nvim_command(cmd)
39 | end
40 | vim.opt.runtimepath:prepend(lazy_path)
41 | local lazy = require('lazy')
42 | local opts = {
43 | lockfile = self.helper.path_join(self.data_path, 'lazy-lock.json'),
44 | }
45 | self:load_modules_packages()
46 | lazy.setup(self.repos, opts)
47 |
48 | for k, v in pairs(self) do
49 | if type(v) ~= 'function' then
50 | self[k] = nil
51 | end
52 | end
53 | end
54 |
55 | function pack.package(repo)
56 | if not pack.repos then
57 | pack.repos = {}
58 | end
59 | table.insert(pack.repos, repo)
60 | end
61 |
62 | return pack
63 |
--------------------------------------------------------------------------------
/lua/keymap/init.lua:
--------------------------------------------------------------------------------
1 | local keymap = require('core.keymap')
2 | local nmap, imap, cmap, xmap = keymap.nmap, keymap.imap, keymap.cmap, keymap.xmap
3 | local silent, noremap = keymap.silent, keymap.noremap
4 | local opts = keymap.new_opts
5 | local cmd = keymap.cmd
6 |
7 | -- Use space as leader key
8 | vim.g.mapleader = ' '
9 |
10 | -- leaderkey
11 | nmap({ ' ', '', opts(noremap) })
12 | xmap({ ' ', '', opts(noremap) })
13 |
14 | -- usage example
15 | nmap({
16 | -- noremal remap
17 | -- close buffer
18 | { 'k', cmd('bdelete'), opts(noremap, silent) },
19 | -- save
20 | { '', cmd('write'), opts(noremap) },
21 | -- yank
22 | { 'Y', 'y$', opts(noremap) },
23 | -- buffer jump
24 | { ']b', cmd('bn'), opts(noremap) },
25 | { '[b', cmd('bp'), opts(noremap) },
26 | -- remove trailing white space
27 | { 't', cmd('TrimTrailingWhitespace'), opts(noremap) },
28 | -- window jump
29 | { '', 'h', opts(noremap) },
30 | { '', 'l', opts(noremap) },
31 | { '', 'j', opts(noremap) },
32 | { '', 'k', opts(noremap) },
33 | })
34 |
35 | imap({
36 | -- insert mode
37 | { '', '', opts(noremap) },
38 | { '', '', opts(noremap) },
39 | })
40 |
41 | -- commandline remap
42 | cmap({ '', '', opts(noremap) })
43 | -- usage of plugins
44 | nmap({
45 | -- plugin manager: Lazy.nvim
46 | { 'pu', cmd('Lazy update'), opts(noremap, silent) },
47 | { 'pi', cmd('Lazy install'), opts(noremap, silent) },
48 | -- dashboard
49 | { 'n', cmd('DashboardNewFile'), opts(noremap, silent) },
50 | { 'ss', cmd('SessionSave'), opts(noremap, silent) },
51 | { 'sl', cmd('SessionLoad'), opts(noremap, silent) },
52 | -- nvimtree
53 | { 'e', cmd('NvimTreeToggle'), opts(noremap, silent) },
54 | -- Telescope
55 | { 'b', cmd('Telescope buffers'), opts(noremap, silent) },
56 | { 'fa', cmd('Telescope live_grep'), opts(noremap, silent) },
57 | { 'ff', cmd('Telescope find_files'), opts(noremap, silent) },
58 | })
59 |
--------------------------------------------------------------------------------
/lua/modules/completion/config.lua:
--------------------------------------------------------------------------------
1 | local config = {}
2 |
3 | -- config server in this function
4 | function config.nvim_lsp() end
5 |
6 | function config.nvim_cmp()
7 | local cmp = require('cmp')
8 |
9 | cmp.setup({
10 | preselect = cmp.PreselectMode.Item,
11 | window = {
12 | completion = cmp.config.window.bordered(),
13 | documentation = cmp.config.window.bordered(),
14 | },
15 | })
16 | end
17 |
18 | function config.lua_snip()
19 | local ls = require('luasnip')
20 | local types = require('luasnip.util.types')
21 | ls.config.set_config({
22 | history = true,
23 | enable_autosnippets = true,
24 | updateevents = 'TextChanged,TextChangedI',
25 | ext_opts = {
26 | [types.choiceNode] = {
27 | active = {
28 | virt_text = { { '<- choiceNode', 'Comment' } },
29 | },
30 | },
31 | },
32 | })
33 | require('luasnip.loaders.from_lua').lazy_load({ paths = vim.fn.stdpath('config') .. '/snippets' })
34 | require('luasnip.loaders.from_vscode').lazy_load()
35 | require('luasnip.loaders.from_vscode').lazy_load({
36 | paths = { './snippets/' },
37 | })
38 | end
39 |
40 | function config.lspsaga()
41 | require('lspsaga').setup({})
42 | end
43 | return config
44 |
--------------------------------------------------------------------------------
/lua/modules/completion/package.lua:
--------------------------------------------------------------------------------
1 | local package = require('core.pack').package
2 | local conf = require('modules.completion.config')
3 |
4 | package({
5 | 'neovim/nvim-lspconfig',
6 | -- used filetype to lazyload lsp
7 | -- config your language filetype in here
8 | ft = { 'lua', 'rust', 'c', 'cpp' },
9 | config = conf.nvim_lsp,
10 | })
11 |
12 | package({
13 | 'glepnir/lspsaga.nvim',
14 | event = 'BufRead',
15 | dev = false,
16 | config = conf.lspsaga,
17 | })
18 |
19 | package({
20 | 'hrsh7th/nvim-cmp',
21 | event = 'InsertEnter',
22 | config = conf.nvim_cmp,
23 | dependencies = {
24 | { 'hrsh7th/cmp-nvim-lsp' },
25 | { 'hrsh7th/cmp-path' },
26 | { 'hrsh7th/cmp-buffer' },
27 | { 'saadparwaiz1/cmp_luasnip' },
28 | },
29 | })
30 |
31 | package({ 'L3MON4D3/LuaSnip', event = 'InsertCharPre', config = conf.lua_snip })
32 |
--------------------------------------------------------------------------------
/lua/modules/editor/config.lua:
--------------------------------------------------------------------------------
1 | local config = {}
2 |
3 | function config.nvim_treesitter()
4 | vim.api.nvim_command('set foldmethod=expr')
5 | vim.api.nvim_command('set foldexpr=nvim_treesitter#foldexpr()')
6 | require('nvim-treesitter.configs').setup({
7 | ensure_installed = 'all',
8 | ignore_install = { 'phpdoc' },
9 | highlight = {
10 | enable = true,
11 | },
12 | textobjects = {
13 | select = {
14 | enable = true,
15 | keymaps = {
16 | ['af'] = '@function.outer',
17 | ['if'] = '@function.inner',
18 | ['ac'] = '@class.outer',
19 | ['ic'] = '@class.inner',
20 | },
21 | },
22 | },
23 | })
24 | end
25 |
26 | return config
27 |
--------------------------------------------------------------------------------
/lua/modules/editor/package.lua:
--------------------------------------------------------------------------------
1 | local package = require('core.pack').package
2 | local conf = require('modules.editor.config')
3 |
4 | package({
5 | 'nvim-treesitter/nvim-treesitter',
6 | event = 'BufRead',
7 | run = ':TSUpdate',
8 | config = conf.nvim_treesitter,
9 | dependencies = {
10 | 'nvim-treesitter/nvim-treesitter-textobjects',
11 | },
12 | })
13 |
--------------------------------------------------------------------------------
/lua/modules/tools/config.lua:
--------------------------------------------------------------------------------
1 | local config = {}
2 |
3 | function config.telescope()
4 | require('telescope').setup({
5 | defaults = {
6 | layout_config = {
7 | horizontal = { prompt_position = 'top', results_width = 0.6 },
8 | vertical = { mirror = false },
9 | },
10 | sorting_strategy = 'ascending',
11 | file_previewer = require('telescope.previewers').vim_buffer_cat.new,
12 | grep_previewer = require('telescope.previewers').vim_buffer_vimgrep.new,
13 | qflist_previewer = require('telescope.previewers').vim_buffer_qflist.new,
14 | },
15 | extensions = {
16 | fzy_native = {
17 | override_generic_sorter = false,
18 | override_file_sorter = true,
19 | },
20 | },
21 | })
22 | require('telescope').load_extension('fzy_native')
23 | end
24 |
25 | return config
26 |
--------------------------------------------------------------------------------
/lua/modules/tools/package.lua:
--------------------------------------------------------------------------------
1 | local package = require('core.pack').package
2 | local conf = require('modules.tools.config')
3 |
4 | package({
5 | 'nvim-telescope/telescope.nvim',
6 | cmd = 'Telescope',
7 | config = conf.telescope,
8 | dependencies = {
9 | { 'nvim-lua/plenary.nvim' },
10 | { 'nvim-telescope/telescope-fzy-native.nvim' },
11 | },
12 | })
13 |
14 | package({
15 | 'glepnir/hlsearch.nvim',
16 | event = 'BufRead',
17 | config = function()
18 | require('hlsearch').setup()
19 | end,
20 | })
21 |
--------------------------------------------------------------------------------
/lua/modules/ui/config.lua:
--------------------------------------------------------------------------------
1 | local config = {}
2 |
3 | function config.zephyr()
4 | vim.cmd('colorscheme zephyr')
5 | end
6 |
7 | function config.dashboard()
8 | local db = require('dashboard')
9 | db.setup({
10 | theme = 'hyper',
11 | config = {
12 | week_header = {
13 | enable = true,
14 | },
15 | shortcut = {
16 | { desc = ' Update', group = '@property', action = 'Lazy update', key = 'u' },
17 | {
18 | desc = ' Files',
19 | group = 'Label',
20 | action = 'Telescope find_files',
21 | key = 'f',
22 | },
23 | {
24 | desc = ' Apps',
25 | group = 'DiagnosticHint',
26 | action = 'Telescope app',
27 | key = 'a',
28 | },
29 | {
30 | desc = ' dotfiles',
31 | group = 'Number',
32 | action = 'Telescope dotfiles',
33 | key = 'd',
34 | },
35 | },
36 | },
37 | })
38 | end
39 |
40 | function config.nvim_bufferline()
41 | require('bufferline').setup({
42 | options = {
43 | modified_icon = '✥',
44 | buffer_close_icon = '',
45 | always_show_bufferline = false,
46 | },
47 | })
48 | end
49 |
50 | function config.indent_blankline()
51 | require('indent_blankline').setup({
52 | char = '│',
53 | use_treesitter_scope = true,
54 | show_first_indent_level = true,
55 | show_current_context = false,
56 | show_current_context_start = false,
57 | show_current_context_start_on_current_line = false,
58 | filetype_exclude = {
59 | 'dashboard',
60 | 'log',
61 | 'TelescopePrompt',
62 | },
63 | buftype_exclude = { 'terminal', 'nofile', 'prompt' },
64 | })
65 | end
66 |
67 | return config
68 |
--------------------------------------------------------------------------------
/lua/modules/ui/package.lua:
--------------------------------------------------------------------------------
1 | local package = require('core.pack').package
2 | local conf = require('modules.ui.config')
3 |
4 | package({ 'glepnir/zephyr-nvim', config = conf.zephyr })
5 |
6 | package({ 'glepnir/dashboard-nvim', config = conf.dashboard })
7 |
8 | package({
9 | 'akinsho/nvim-bufferline.lua',
10 | config = conf.nvim_bufferline,
11 | dependencies = { 'nvim-tree/nvim-web-devicons' },
12 | })
13 |
14 | package({
15 | 'lukas-reineke/indent-blankline.nvim',
16 | event = 'BufRead',
17 | config = conf.indent_blankline,
18 | })
19 |
--------------------------------------------------------------------------------
/snippets/lua.json:
--------------------------------------------------------------------------------
1 | {
2 | "_G": {
3 | "body": "_G(${0:...})",
4 | "description": "5.1,5.2,5.3\n\n_G",
5 | "prefix": "_G",
6 | "scope": "source.lua"
7 | },
8 | "assert": {
9 | "body": "assert(${1:v}${2:[, message]})",
10 | "description": "5.1,5.2,5.3\n\nassert()",
11 | "prefix": "assert",
12 | "scope": "source.lua"
13 | },
14 | "collectgarbage": {
15 | "body": "collectgarbage(${1:[opt]}${2:[, arg]})",
16 | "description": "5.1,5.2,5.3\n\ncollectgarbage()",
17 | "prefix": "collectgarbage",
18 | "scope": "source.lua"
19 | },
20 | "coroutine.create": {
21 | "body": "coroutine.create( ${1:function} )",
22 | "description": "5.1,5.2,5.3\n\ncoroutine.create",
23 | "prefix": "coroutine.create",
24 | "scope": "source.lua"
25 | },
26 | "coroutine.isyieldable": {
27 | "body": "coroutine.isyieldable( )",
28 | "description": "5.3\n\ncoroutine.isyieldable",
29 | "prefix": "coroutine.isyieldable",
30 | "scope": "source.lua"
31 | },
32 | "coroutine.resume": {
33 | "body": "coroutine.resume( ${1:co}${2:[, val1, \u00b7\u00b7\u00b7]} )",
34 | "description": "5.1,5.2,5.3\n\ncoroutine.resume",
35 | "prefix": "coroutine.resume",
36 | "scope": "source.lua"
37 | },
38 | "coroutine.running": {
39 | "body": "coroutine.running( )",
40 | "description": "5.1,5.2,5.3\n\ncoroutine.running",
41 | "prefix": "coroutine.running",
42 | "scope": "source.lua"
43 | },
44 | "coroutine.status": {
45 | "body": "coroutine.status( ${1:co} )",
46 | "description": "5.1,5.2,5.3\n\ncoroutine.status",
47 | "prefix": "coroutine.status",
48 | "scope": "source.lua"
49 | },
50 | "coroutine.wrap": {
51 | "body": "coroutine.wrap( ${1:function} )",
52 | "description": "5.1,5.2,5.3\n\ncoroutine.wrap",
53 | "prefix": "coroutine.wrap",
54 | "scope": "source.lua"
55 | },
56 | "coroutine.yield": {
57 | "body": "coroutine.yield( ${1:...} )",
58 | "description": "5.1,5.2,5.3\n\ncoroutine.yield",
59 | "prefix": "coroutine.yield",
60 | "scope": "source.lua"
61 | },
62 | "for": {
63 | "body": "for ${1:i}=${2:1},${3:10} do\n\t${0:print(i)}\nend",
64 | "description": "for i=1,10",
65 | "prefix": "for",
66 | "scope": "source.lua"
67 | },
68 | "fori": {
69 | "body": "for ${1:i},${2:v} in ipairs(${3:table_name}) do\n\t${0:print(i,v)}\nend",
70 | "description": "for i,v in ipairs()",
71 | "prefix": "fori",
72 | "scope": "source.lua"
73 | },
74 | "forp": {
75 | "body": "for ${1:k},${2:v} in pairs(${3:table_name}) do\n\t${0:print(k,v)}\nend",
76 | "description": "for k,v in pairs()",
77 | "prefix": "forp",
78 | "scope": "source.lua"
79 | },
80 | "fun": {
81 | "body": "function ${1:function_name}( ${2:...} )\n\t${0:-- body}\nend",
82 | "description": "function",
83 | "prefix": "fun",
84 | "scope": "source.lua"
85 | },
86 | "function": {
87 | "body": "function ${1:function_name}( ${2:...} )\n\t${0:-- body}\nend",
88 | "description": "function",
89 | "prefix": "function",
90 | "scope": "source.lua"
91 | },
92 | "getfenv": {
93 | "body": "getfenv(${0:...})",
94 | "description": "5.1\n\ngetfenv ([f])",
95 | "prefix": "getfenv",
96 | "scope": "source.lua"
97 | },
98 | "getmetatable": {
99 | "body": "getmetatable(${1:object})",
100 | "description": "5.1,5.2,5.3\n\ngetmetatable (object)",
101 | "prefix": "getmetatable",
102 | "scope": "source.lua"
103 | },
104 | "if": {
105 | "body": "if ${1:condition} then\n\t${0:-- body}\nend",
106 | "description": "if",
107 | "prefix": "if",
108 | "scope": "source.lua"
109 | },
110 | "ifel": {
111 | "body": "if ${1:condition} then\n\t${2:-- body}\nelse\n\t${0:-- body}\nend",
112 | "description": "ifel",
113 | "prefix": "ifel",
114 | "scope": "source.lua"
115 | }
116 | }
117 |
--------------------------------------------------------------------------------
/snippets/lua.lua:
--------------------------------------------------------------------------------
1 | return {
2 | -- e.g. local bar = require("foo.bar")
3 | s(
4 | 'require',
5 | fmt([[local {} = require("{}")]], {
6 | d(2, function(args)
7 | local modules = vim.split(args[1][1], '%.')
8 | return sn(nil, { i(1, modules[#modules]) })
9 | end, { 1 }),
10 | i(1),
11 | })
12 | ),
13 | }
14 |
--------------------------------------------------------------------------------
/snippets/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "contributes": {
3 | "snippets": [
4 | {
5 | "language": "lua",
6 | "path": "./lua.json"
7 | }
8 | ]
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/static/neovim.cat:
--------------------------------------------------------------------------------
1 |
2 |
3 | [48;5;0m [38;2;167;201;171m
4 | [38;2;31;107;152m███████████ [38;2;57;108;63m█████[38;2;167;201;171m ██
5 | [38;2;34;115;163m███████████ [38;2;61;116;68m█████
6 | [38;2;36;122;174m███████[48;5;0m██[38;2;20;69;110m[38;2;122;187;225m███████ ███[38;2;65;124;72m████████ [38;2;152;192;157m███ ███████
7 | [38;2;38;130;184m█████████[38;2;132;191;226m███████[48;5;0m ████[38;2;69;132;76m████████ [38;2;160;196;164m█████ ██████████████
8 | [38;2;40;138;195m█████████[38;2;142;196;228m█████[48;5;0m[38;2;20;69;110m██[38;2;142;196;228m██████[38;2;73;140;81m███████ [38;2;167;201;171m█████ █████ ████ █████
9 | [38;2;43;145;206m███████████[38;2;151;200;229m█████████████████[38;2;77;147;86m██████ [38;2;175;205;179m█████ █████ ████ █████
10 | [38;2;45;153;217m██████ ███ [38;2;160;204;231m█████████████████ [38;2;81;155;90m████ [38;2;183;209;186m█████ █████ ████ ██████
11 | [38;2;20;69;110m██████ ██ ███████████████ [38;2;46;78;42m██ █████████████████
12 | ██████ ██ ███████████████ ██ █████████████████
13 |
--------------------------------------------------------------------------------