├── .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 | Stargazers 21 | 22 | 23 | Issues 27 | 28 | 29 | Contributors 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://img.shields.io/badge/PayPal-00457C?style=for-the-badge&logo=paypal&logoColor=white)](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 |   4 | ███████████ █████ ██ 5 | ███████████ █████  6 | ████████████████ ███████████ ███ ███████ 7 | ████████████████ ████████████ █████ ██████████████ 8 | █████████████████████████████ █████ █████ ████ █████ 9 | ██████████████████████████████████ █████ █████ ████ █████ 10 | ██████ ███ █████████████████ ████ █████ █████ ████ ██████ 11 | ██████ ██ ███████████████ ██ █████████████████ 12 | ██████ ██ ███████████████ ██ █████████████████ 13 | --------------------------------------------------------------------------------