From a9cbaf78023ff7623c0daea6c7c54793c5d8f223 Mon Sep 17 00:00:00 2001 From: Matt Leong Date: Tue, 19 Oct 2021 10:19:33 -0700 Subject: [PATCH] =?UTF-8?q?Init=20=F0=9F=9A=80?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .gitignore | 5 + init.lua | 1 + lua/cosmic/core/file-explorer/init.lua | 47 ++ lua/cosmic/core/file-explorer/mappings.lua | 4 + lua/cosmic/core/file-navigation/init.lua | 123 +++++ lua/cosmic/core/file-navigation/mappings.lua | 30 ++ lua/cosmic/core/statusline/init.lua | 451 +++++++++++++++++++ lua/cosmic/core/terminal/init.lua | 9 + lua/cosmic/core/terminal/mappings.lua | 8 + lua/cosmic/core/theme/colors.lua | 22 + lua/cosmic/core/theme/highlights.lua | 46 ++ lua/cosmic/core/theme/icons.lua | 40 ++ lua/cosmic/core/theme/ui.lua | 58 +++ lua/cosmic/core/treesitter/init.lua | 33 ++ lua/cosmic/disabled.lua | 24 + lua/cosmic/editor.lua | 75 +++ lua/cosmic/init.lua | 5 + lua/cosmic/lsp/autocomplete.lua | 77 ++++ lua/cosmic/lsp/diagnostics.lua | 67 +++ lua/cosmic/lsp/init.lua | 7 + lua/cosmic/lsp/mappings.lua | 31 ++ lua/cosmic/lsp/providers/defaults.lua | 51 +++ lua/cosmic/lsp/providers/efm.lua | 39 ++ lua/cosmic/lsp/providers/eslint.lua | 15 + lua/cosmic/lsp/providers/init.lua | 42 ++ lua/cosmic/lsp/providers/jsonls.lua | 49 ++ lua/cosmic/lsp/providers/lua.lua | 32 ++ lua/cosmic/lsp/providers/tsserver.lua | 52 +++ lua/cosmic/mappings.lua | 14 + lua/cosmic/packer.lua | 47 ++ lua/cosmic/pluginsInit.lua | 193 ++++++++ lua/cosmic/utils.lua | 43 ++ readme.md | 74 +++ 33 files changed, 1814 insertions(+) create mode 100644 .gitignore create mode 100644 init.lua create mode 100644 lua/cosmic/core/file-explorer/init.lua create mode 100644 lua/cosmic/core/file-explorer/mappings.lua create mode 100644 lua/cosmic/core/file-navigation/init.lua create mode 100644 lua/cosmic/core/file-navigation/mappings.lua create mode 100644 lua/cosmic/core/statusline/init.lua create mode 100644 lua/cosmic/core/terminal/init.lua create mode 100644 lua/cosmic/core/terminal/mappings.lua create mode 100644 lua/cosmic/core/theme/colors.lua create mode 100644 lua/cosmic/core/theme/highlights.lua create mode 100644 lua/cosmic/core/theme/icons.lua create mode 100644 lua/cosmic/core/theme/ui.lua create mode 100644 lua/cosmic/core/treesitter/init.lua create mode 100644 lua/cosmic/disabled.lua create mode 100644 lua/cosmic/editor.lua create mode 100644 lua/cosmic/init.lua create mode 100644 lua/cosmic/lsp/autocomplete.lua create mode 100644 lua/cosmic/lsp/diagnostics.lua create mode 100644 lua/cosmic/lsp/init.lua create mode 100644 lua/cosmic/lsp/mappings.lua create mode 100644 lua/cosmic/lsp/providers/defaults.lua create mode 100644 lua/cosmic/lsp/providers/efm.lua create mode 100644 lua/cosmic/lsp/providers/eslint.lua create mode 100644 lua/cosmic/lsp/providers/init.lua create mode 100644 lua/cosmic/lsp/providers/jsonls.lua create mode 100644 lua/cosmic/lsp/providers/lua.lua create mode 100644 lua/cosmic/lsp/providers/tsserver.lua create mode 100644 lua/cosmic/mappings.lua create mode 100644 lua/cosmic/packer.lua create mode 100644 lua/cosmic/pluginsInit.lua create mode 100644 lua/cosmic/utils.lua create mode 100644 readme.md diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..50d063e --- /dev/null +++ b/.gitignore @@ -0,0 +1,5 @@ +pack/** +sessions/** +.netrwhist +plugin/ +lua/cosmic/compiled.lua diff --git a/init.lua b/init.lua new file mode 100644 index 0000000..853b79b --- /dev/null +++ b/init.lua @@ -0,0 +1 @@ +require('cosmic') diff --git a/lua/cosmic/core/file-explorer/init.lua b/lua/cosmic/core/file-explorer/init.lua new file mode 100644 index 0000000..7f7de94 --- /dev/null +++ b/lua/cosmic/core/file-explorer/init.lua @@ -0,0 +1,47 @@ +local g = vim.g +local icons = require('cosmic.core.theme.icons') +local M = {} + +function M.init() + -- settings + g.nvim_tree_git_hl = 1 + g.nvim_tree_refresh_wait = 300 + + g.nvim_tree_special_files = {} + g.nvim_tree_show_icons = { + git = 1, + folders = 1, + files = 1, + folder_arrows = 1, + } + + g.nvim_tree_icons = { + default = '๎˜’', + symlink = icons.symlink, + git = icons.git, + folder = icons.folder, + + lsp = { + hint = icons.hint, + info = icons.info, + warning = icons.warn, + error = icons.error, + }, + } + + -- set up args + local args = { + auto_close = true, + diagnostics = { + enable = true, + }, + update_focused_file = { + enable = true, + ignore_list = {}, + }, + } + + require('nvim-tree').setup(args) +end + +return M diff --git a/lua/cosmic/core/file-explorer/mappings.lua b/lua/cosmic/core/file-explorer/mappings.lua new file mode 100644 index 0000000..76544ea --- /dev/null +++ b/lua/cosmic/core/file-explorer/mappings.lua @@ -0,0 +1,4 @@ +local map = require('cosmic.utils').map + +map('n', '', ':NvimTreeToggle', { noremap = true }) +map('n', 'r', ':NvimTreeRefresh', { noremap = true }) diff --git a/lua/cosmic/core/file-navigation/init.lua b/lua/cosmic/core/file-navigation/init.lua new file mode 100644 index 0000000..92a2046 --- /dev/null +++ b/lua/cosmic/core/file-navigation/init.lua @@ -0,0 +1,123 @@ +local actions = require('telescope.actions') +local mappings = require('cosmic.core.file-navigation.mappings').mappings() +local icons = require('cosmic.core.theme.icons') + +require('telescope').setup({ + defaults = { + prompt_prefix = '๐Ÿ” ', + selection_caret = icons.folder.arrow_closed, + file_ignore_patterns = { + '.git/', + }, + vimgrep_arguments = { + 'rg', + '--ignore', + '--hidden', + '--color=never', + '--no-heading', + '--with-filename', + '--line-number', + '--column', + '--smart-case', + }, + }, + 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" + -- the default case_mode is "smart_case" + }, + }, + pickers = { + buffers = { + prompt_title = 'โœจ Search Buffers โœจ', + mappings = { + n = { + ['d'] = actions.delete_buffer, + }, + }, + sort_mru = true, + -- sort_lastused = true, + preview_title = false, + }, + lsp_references = { + -- mappings = mappings.normal, + initial_mode = 'normal', + sorting_strategy = 'ascending', + layout_strategy = 'cursor', + preview_title = '', + -- dynamic_preview_title = true, + results_title = false, + prompt_title = 'References', + layout_config = { + width = 0.4, + height = 0.4, + }, + }, + lsp_code_actions = { + initial_mode = 'normal', + sorting_strategy = 'ascending', + layout_strategy = 'cursor', + preview = false, + prompt_title = 'Code Actions', + results_title = '', + layout_config = { + width = 0.2, + height = 0.3, + }, + }, + lsp_range_code_actions = { + initial_mode = 'normal', + sorting_strategy = 'ascending', + layout_strategy = 'cursor', + preview = false, + prompt_title = 'Code Actions', + results_title = '', + layout_config = { + width = 0.3, + height = 0.3, + }, + }, + lsp_document_diagnostics = { + initial_mode = 'normal', + sorting_strategy = 'ascending', + layout_strategy = 'cursor', + prompt_title = 'Diagnostics', + results_title = '', + layout_config = { + width = 0.5, + height = 0.5, + }, + mappings = mappings, + }, + lsp_definitions = { + layout_strategy = 'cursor', + prompt_title = 'Definitions', + preview_title = false, + results_title = false, + layout_config = { + width = 0.5, + height = 0.5, + }, + mappings = mappings, + }, + find_files = { + prompt_title = 'โœจ Search Project โœจ', + mappings = mappings, + hidden = true, + }, + git_files = { + prompt_title = 'โœจ Search Git Project โœจ', + mappings = mappings, + hidden = true, + }, + live_grep = { + prompt_title = 'โœจ Live Grep โœจ', + mappings = mappings, + }, + }, +}) + +require('telescope').load_extension('fzf') diff --git a/lua/cosmic/core/file-navigation/mappings.lua b/lua/cosmic/core/file-navigation/mappings.lua new file mode 100644 index 0000000..22ff8da --- /dev/null +++ b/lua/cosmic/core/file-navigation/mappings.lua @@ -0,0 +1,30 @@ +local map = require('cosmic.utils').map +local M = {} + +function M.init() + map('n', 'p', ':Telescope find_files', { noremap = true }) + map('n', 'f', ':Telescope git_files', { noremap = true }) + map('n', 'k', ':Telescope buffers', { noremap = true }) + map('n', 's', ':Telescope live_grep', { noremap = true }) + map('n', 'gc', ':Telescope git_commits', { noremap = true }) + map('n', 'gs', ':Telescope git_status', { noremap = true }) +end + +function M.mappings() + local actions = require('telescope.actions') + local normal = { + n = { + ['Q'] = actions.smart_add_to_qflist + actions.open_qflist, + ['q'] = actions.smart_send_to_qflist + actions.open_qflist, + [''] = actions.toggle_selection + actions.move_selection_next, + [''] = actions.toggle_selection + actions.move_selection_previous, + ['v'] = actions.file_vsplit, + ['s'] = actions.file_split, + [''] = actions.file_edit, + }, + } + + return normal +end + +return M diff --git a/lua/cosmic/core/statusline/init.lua b/lua/cosmic/core/statusline/init.lua new file mode 100644 index 0000000..09e979c --- /dev/null +++ b/lua/cosmic/core/statusline/init.lua @@ -0,0 +1,451 @@ +local galaxy = require('galaxyline') +local gls = galaxy.section +local diag = require('galaxyline.providers.diagnostic') +local condition = require('galaxyline.condition') +local fileinfo = require('galaxyline.providers.fileinfo') +local utils = require('cosmic.utils') +local colors = require('cosmic.core.theme.colors') +local highlight = utils.highlight +local icons = require('cosmic.core.theme.icons') + +local get_mode = function() + local mode_colors = { + [110] = { 'NORMAL', colors.blue, colors.bg_highlight }, + [105] = { 'INSERT', colors.hint, colors.bg_highlight }, + [99] = { 'COMMAND', colors.orange, colors.bg_highlight }, + [116] = { 'TERMINAL', colors.blue, colors.bg_highlight }, + [118] = { 'VISUAL', colors.purple, colors.bg_highlight }, + [22] = { 'V-BLOCK', colors.purple, colors.bg_highlight }, + [86] = { 'V-LINE', colors.purple, colors.bg_highlight }, + [82] = { 'REPLACE', colors.red, colors.bg_highlight }, + [115] = { 'SELECT', colors.red, colors.bg_highlight }, + [83] = { 'S-LINE', colors.red, colors.bg_highlight }, + } + + local mode_data = mode_colors[vim.fn.mode():byte()] + if mode_data ~= nil then + return mode_data + end +end + +local check_width_and_git_and_buffer = function() + return condition.check_git_workspace() and condition.buffer_not_empty() +end + +local check_git_and_width = function() + return condition.buffer_not_empty() and condition.hide_in_width() +end + +local check_buffer_and_width = function() + return condition.buffer_not_empty() and condition.hide_in_width() +end + +local FilePathShortProvider = function() + local fp = vim.fn.fnamemodify(vim.fn.expand('%'), ':~:.:h') + local tbl = utils.split(fp, '/') + local len = #tbl + + if len > 2 and tbl[1] ~= '~' then + return icons.dotdotdot .. '/' .. table.concat(tbl, '/', len - 1) .. '/' + else + return fp .. '/' + end +end + +local LineColumnProvider = function() + local line_column = fileinfo.line_column() + line_column = line_column:gsub('%s+', '') + return ' ' .. icons.line_number .. line_column +end + +local PercentProvider = function() + local line_column = fileinfo.current_line_percent() + line_column = line_column:gsub('%s+', '') + return line_column .. ' โ˜ฐ' +end + +local BracketProvider = function(icon, cond) + return function() + local result + + if cond == true or cond == false then + result = cond + else + result = cond() + end + + if result ~= nil and result ~= '' then + return icon + end + end +end + +galaxy.short_line_list = { + 'packer', + 'NvimTree', + 'floaterm', + 'fugitive', + 'fugitiveblame', +} + +gls.left = { + { + GhostLeftBracket = { + provider = BracketProvider(icons.rounded_left_filled, true), + highlight = 'GalaxyViModeNestedInv', + }, + }, + { + Ghost = { + provider = BracketProvider(icons.ghost, true), + highlight = 'GalaxyViModeInv', + }, + }, + { + ViModeLeftBracket = { + provider = BracketProvider(icons.rounded_right_filled, true), + highlight = 'GalaxyViMode', + }, + }, + { + ViMode = { + provider = function() + local m = get_mode() + if m == nil then + return + end + + local label, mode_color, mode_nested = unpack(m) + highlight('GalaxyViMode', mode_color, mode_nested) + highlight('GalaxyViModeInv', mode_nested, mode_color) + highlight('GalaxyViModeNested', mode_nested, colors.bg) + highlight('GalaxyViModeNestedInv', colors.bg, mode_nested) + highlight('GalaxyPercentBracket', colors.bg, mode_color) + + highlight('GalaxyGitLCBracket', mode_nested, mode_color) + + if condition.buffer_not_empty() then + highlight('GalaxyViModeBracket', mode_nested, mode_color) + else + if condition.check_git_workspace() then + highlight('GalaxyGitLCBracket', colors.bg, mode_color) + end + highlight('GalaxyViModeBracket', colors.bg, mode_color) + end + return ' ' .. label .. ' ' + end, + }, + }, + { + ViModeBracket = { + provider = BracketProvider(icons.arrow_right_filled, true), + highlight = 'GalaxyViModeBracket', + }, + }, + { + GitIcon = { + provider = BracketProvider(' ' .. icons.branch .. ' ', true), + condition = check_width_and_git_and_buffer, + highlight = 'GalaxyViModeInv', + }, + }, + { + GitBranch = { + provider = function() + local vcs = require('galaxyline.providers.vcs') + local branch_name = vcs.get_git_branch() + if not branch_name then + return ' no git ' + end + if string.len(branch_name) > 28 then + return string.sub(branch_name, 1, 25) .. icons.dotdotdot + end + return branch_name .. ' ' + end, + condition = check_width_and_git_and_buffer, + highlight = 'GalaxyViModeInv', + separator = icons.arrow_right, + separator_highlight = 'GalaxyViModeInv', + }, + }, + { + FileIcon = { + provider = function() + local icon = fileinfo.get_file_icon() + if condition.check_git_workspace() then + return ' ' .. icon + end + + return ' ' .. icon + end, + condition = condition.buffer_not_empty, + highlight = 'GalaxyViModeInv', + }, + }, + { + FilePath = { + provider = FilePathShortProvider, + condition = check_buffer_and_width, + highlight = 'GalaxyViModeInv', + }, + }, + { + FileName = { + provider = 'FileName', + condition = condition.buffer_not_empty, + highlight = 'GalaxyViModeInv', + separator = icons.arrow_right_filled, + separator_highlight = 'GalaxyViModeNestedInv', + }, + }, + { + DiffAdd = { + provider = 'DiffAdd', + icon = ' ๏‘— ', + condition = check_width_and_git_and_buffer, + highlight = { colors.diffAdd, colors.bg }, + }, + }, + { + DiffModified = { + provider = 'DiffModified', + condition = check_width_and_git_and_buffer, + icon = ' ๏‘™ ', + highlight = { colors.diffModified, colors.bg }, + }, + }, + { + DiffRemove = { + provider = 'DiffRemove', + condition = check_width_and_git_and_buffer, + icon = ' ๏‘˜ ', + highlight = { colors.diffDeleted, colors.bg }, + }, + }, + { + WSpace = { + provider = 'WhiteSpace', + highlight = { colors.bg, colors.bg }, + }, + }, +} + +gls.right = { + { + DiagnosticErrorLeftBracket = { + provider = BracketProvider(icons.rounded_left_filled, diag.get_diagnostic_error), + highlight = 'GalaxyDiagnosticErrorInv', + condition = condition.buffer_not_empty, + }, + }, + { + DiagnosticError = { + provider = function() + local error_result = diag.get_diagnostic_error() + highlight('GalaxyDiagnosticError', colors.error, colors.bg) + highlight('GalaxyDiagnosticErrorInv', colors.bg, colors.error) + + if error_result ~= '' and error_result ~= nil then + return error_result + end + end, + icon = icons.error .. ' ', + highlight = 'GalaxyDiagnosticError', + condition = condition.buffer_not_empty, + }, + }, + { + DiagnosticErrorRightBracket = { + provider = { + BracketProvider(icons.rounded_right_filled, diag.get_diagnostic_error), + BracketProvider(' ', diag.get_diagnostic_error), + }, + highlight = 'GalaxyDiagnosticErrorInv', + condition = condition.buffer_not_empty, + }, + }, + { + DiagnosticWarnLeftBracket = { + provider = BracketProvider(icons.rounded_left_filled, diag.get_diagnostic_warn), + highlight = 'GalaxyDiagnosticWarnInv', + condition = condition.buffer_not_empty, + }, + }, + { + DiagnosticWarn = { + provider = function() + local warn_result = diag.get_diagnostic_warn() + highlight('GalaxyDiagnosticWarn', colors.warn, colors.bg) + highlight('GalaxyDiagnosticWarnInv', colors.bg, colors.warn) + + if warn_result ~= '' and warn_result ~= nil then + return warn_result + end + end, + highlight = 'GalaxyDiagnosticWarn', + icon = icons.warn .. ' ', + condition = condition.buffer_not_empty, + }, + }, + { + DiagnosticWarnRightBracket = { + provider = { + BracketProvider(icons.rounded_right_filled, diag.get_diagnostic_warn), + BracketProvider(' ', diag.get_diagnostic_warn), + }, + highlight = 'GalaxyDiagnosticWarnInv', + condition = condition.buffer_not_empty, + }, + }, + { + DiagnosticInfoLeftBracket = { + provider = BracketProvider(icons.rounded_left_filled, diag.get_diagnostic_info), + highlight = 'GalaxyDiagnosticInfoInv', + }, + }, + { + DiagnosticInfo = { + provider = function() + local info_result = diag.get_diagnostic_info() + highlight('GalaxyDiagnosticInfo', colors.info, colors.bg) + highlight('GalaxyDiagnosticInfoInv', colors.bg, colors.info) + + if info_result ~= '' and info_result ~= nil then + return info_result + end + end, + icon = icons.info .. ' ', + highlight = 'GalaxyDiagnosticInfo', + condition = check_width_and_git_and_buffer, + }, + }, + { + DiagnosticInfoRightBracket = { + provider = { + BracketProvider(icons.rounded_right_filled, diag.get_diagnostic_info), + BracketProvider(' ', diag.get_diagnostic_info), + }, + highlight = 'GalaxyDiagnosticInfoInv', + condition = condition.buffer_not_empty, + }, + }, + { + GitBranchRightBracket = { + provider = BracketProvider(icons.arrow_left_filled, true), + condition = check_git_and_width, + highlight = 'GalaxyViModeNestedInv', + }, + }, + { + GitRoot = { + provider = utils.get_git_root, + condition = check_git_and_width, + icon = ' ' .. icons.file .. ' ', + highlight = 'GalaxyViModeInv', + }, + }, + { + LineColumn = { + provider = { + LineColumnProvider, + function() + return ' ' + end, + }, + highlight = 'GalaxyViMode', + separator = icons.arrow_left_filled, + separator_highlight = 'GalaxyGitLCBracket', + }, + }, + { + PerCent = { + provider = { + PercentProvider, + }, + highlight = 'GalaxyViMode', + separator = icons.arrow_left .. ' ', + separator_highlight = 'GalaxyViModeLeftBracket', + }, + }, + { + PercentRightBracket = { + provider = BracketProvider(icons.rounded_right_filled, true), + highlight = 'GalaxyPercentBracket', + }, + }, +} + +gls.short_line_left = { + { + GhostLeftBracketShort = { + provider = BracketProvider(icons.rounded_left_filled, true), + highlight = { colors.white, colors.bg }, + }, + }, + { + GhostShort = { + provider = BracketProvider(icons.ghost, true), + highlight = { colors.bg, colors.white }, + }, + }, + { + GhostRightBracketShort = { + provider = BracketProvider(icons.rounded_right_filled, true), + highlight = { colors.white, colors.bg }, + }, + }, + { + FileIconShort = { + provider = { + function() + return ' ' + end, + 'FileIcon', + }, + condition = condition.buffer_not_empty, + highlight = { + require('galaxyline.providers.fileinfo').get_file_icon, + colors.bg, + }, + }, + }, + { + FilePathShort = { + provider = FilePathShortProvider, + condition = condition.buffer_not_empty, + highlight = { colors.white, colors.bg }, + }, + }, + { + FileNameShort = { + provider = 'FileName', + condition = condition.buffer_not_empty, + highlight = { colors.white, colors.bg }, + }, + }, +} + +gls.short_line_right = { + { + GitRootShortLeftBracket = { + provider = BracketProvider(icons.arrow_left_filled, true), + condition = condition.buffer_not_empty, + highlight = { colors.white, colors.bg }, + }, + }, + { + GitRootShort = { + provider = utils.get_git_root, + condition = condition.buffer_not_empty, + icon = ' ' .. icons.file .. ' ', + highlight = { colors.bg, colors.white }, + }, + }, + { + GitRootShortRightBracket = { + provider = BracketProvider(icons.rounded_right_filled, true), + condition = condition.buffer_not_empty, + highlight = { colors.white, colors.bg }, + }, + }, +} diff --git a/lua/cosmic/core/terminal/init.lua b/lua/cosmic/core/terminal/init.lua new file mode 100644 index 0000000..8178c31 --- /dev/null +++ b/lua/cosmic/core/terminal/init.lua @@ -0,0 +1,9 @@ +local colors = require('cosmic.core.theme.colors') +local highlight = require('cosmic.utils').highlight +local g = vim.g + +g.floaterm_width = 0.8 +g.floaterm_height = 0.8 +g.floaterm_title = '|๐Ÿ‘พ ($1/$2)|' +g.floaterm_opener = 'vsplit' +highlight('FloatermBorder', 'None', colors.floatBorder) diff --git a/lua/cosmic/core/terminal/mappings.lua b/lua/cosmic/core/terminal/mappings.lua new file mode 100644 index 0000000..7f42828 --- /dev/null +++ b/lua/cosmic/core/terminal/mappings.lua @@ -0,0 +1,8 @@ +local map = require('cosmic.utils').map + +map('n', '', ':FloatermToggle', { noremap = true }) +map('t', '', [[]], { noremap = true }) +map('t', 'l', [[:FloatermNext]], { noremap = true }) +map('t', 'h', [[:FloatermPrev]], { noremap = true }) +map('t', 'n', [[:FloatermNew]], { noremap = true }) +map('t', 'c', [[:FloatermKill]], { noremap = true }) diff --git a/lua/cosmic/core/theme/colors.lua b/lua/cosmic/core/theme/colors.lua new file mode 100644 index 0000000..429151e --- /dev/null +++ b/lua/cosmic/core/theme/colors.lua @@ -0,0 +1,22 @@ +local themeColors = require('tokyonight.colors').setup() + +local colors = { + white = themeColors.fg_dark, + bg = themeColors.bg, + bg_highlight = themeColors.bg_highlight, + blue = themeColors.blue, + purple = themeColors.magenta, + orange = themeColors.orange, + hint = themeColors.teal, + red = themeColors.red, + diffAdd = themeColors.git.add, + diffModified = themeColors.git.change, + diffDeleted = themeColors.git.delete, + info = themeColors.green2, + error = themeColors.magenta2, + warn = themeColors.orange, + floatBorder = themeColors.border_highlight, + selection_caret = themeColors.purple, +} + +return colors diff --git a/lua/cosmic/core/theme/highlights.lua b/lua/cosmic/core/theme/highlights.lua new file mode 100644 index 0000000..9110e74 --- /dev/null +++ b/lua/cosmic/core/theme/highlights.lua @@ -0,0 +1,46 @@ +local colors = require('cosmic.core.theme.colors') +local highlight = require('cosmic.utils').highlight +local M = {} + +function M.init() + -- diagnostic colors + -- sign colors + highlight('LspDiagnosticsSignError', 'None', colors.error) + highlight('LspDiagnosticsSignWarning', 'None', colors.warn) + highlight('LspDiagnosticsSignInformation', 'None', colors.info) + highlight('LspDiagnosticsSignHint', 'None', colors.hint) + + --highlight('DiagnosticUnderlineError', 'None', colors.error) + --highlight('DiagnosticUnderlineWarning', 'None', colors.warn) + --highlight('DiagnosticUnderlineInformation', 'None', colors.info) + --highlight('DiagnosticUnderlineHint', 'None', colors.hint) + + -- legacy lsp colors + highlight('LspDiagnosticsError', 'None', colors.error) + highlight('LspDiagnosticsWarn', 'None', colors.warn) + highlight('LspDiagnosticsInfo', 'None', colors.info) + highlight('LspDiagnosticsHint', 'None', colors.hint) + + highlight('DiagnosticError', 'None', colors.error) + highlight('DiagnosticWarn', 'None', colors.warn) + highlight('DiagnosticInfo', 'None', colors.info) + highlight('DiagnosticHint', 'None', colors.hint) + + highlight('Error', 'None', colors.error) + highlight('ErrorMsg', 'None', colors.error) + highlight('WarningMsg', 'None', colors.error) + + -- signature highlight color + highlight('LspSignatureActiveParameter', 'None', colors.orange) + + -- currently not working + highlight('TelescopeSelectionCaret', 'None', colors.selection_caret) + + -- needs to highlight after lsp start, why? idk + vim.cmd([[ + highlight clear NormalFloat + highlight link NormalFloat Normal + ]]) +end + +return M diff --git a/lua/cosmic/core/theme/icons.lua b/lua/cosmic/core/theme/icons.lua new file mode 100644 index 0000000..47e0cdb --- /dev/null +++ b/lua/cosmic/core/theme/icons.lua @@ -0,0 +1,40 @@ +local icons = { + rounded_left_filled = '๎‚ถ', + rounded_right_filled = '๎‚ด', + arrow_left_filled = '๎‚ฒ', -- e0b2 + arrow_right_filled = '๎‚ฐ', -- e0b0 + arrow_left = '๎‚ณ', -- e0b3 + arrow_right = '๎‚ฑ', -- e0b1 + ghost = '๏žŸ', + warn = '๏ฑ', + info = '๏š', + error = '๏—', + hint = '๏ ต', + branch = '๏žก', + file = '๏Š', + dotdotdot = 'โ€ฆ', + information = '๏‘‰', + symlink = '๏’', + line_number = '๎‚ก', + git = { + unstaged = 'โœ—', + staged = 'โœ“', + unmerged = '๎œง', + renamed = 'โžœ', + untracked = 'โ˜…', + deleted = '๏‘˜', + ignored = 'โ—Œ', + }, + folder = { + arrow_open = '๏‘ผ', + arrow_closed = '๏‘ ', + default = '๎—ฟ', + open = '๎—พ', + empty = '๏„”', + empty_open = '๏„•', + symlink = '๏’‚', + symlink_open = '๎—พ', + }, +} + +return icons diff --git a/lua/cosmic/core/theme/ui.lua b/lua/cosmic/core/theme/ui.lua new file mode 100644 index 0000000..bccc7de --- /dev/null +++ b/lua/cosmic/core/theme/ui.lua @@ -0,0 +1,58 @@ +local colors = require('cosmic.core.theme.colors') +local icons = require('cosmic.core.theme.icons') +local highlight = require('cosmic.utils').highlight +local M = {} + +local api = vim.api +local lsp = vim.lsp +local buf, win +local prompt_str = ' ' .. icons.folder.arrow_closed .. ' ' + +function M.rename() + local map_opts = { noremap = true, silent = true } + local opts = { + style = 'minimal', + border = 'single', + relative = 'cursor', + width = 25, + height = 1, + row = 1, + col = 1, + } + buf, win = api.nvim_create_buf(false, true) + api.nvim_buf_set_option(buf, 'bufhidden', 'wipe') + + api.nvim_open_win(buf, true, opts) + api.nvim_win_set_option(win, 'scrolloff', 0) + api.nvim_win_set_option(win, 'sidescrolloff', 0) + api.nvim_buf_set_option(buf, 'modifiable', true) + api.nvim_buf_set_option(buf, 'buftype', 'prompt') + api.nvim_buf_add_highlight(buf, -1, "LspRenamePrompt", 0, 0, #prompt_str) + highlight('LspRenamePrompt', 'None', colors.selection_caret) + + vim.fn.prompt_setprompt(buf, prompt_str) + + vim.api.nvim_command('startinsert!') + api.nvim_buf_set_keymap(buf, 'i', '', 'stopinsert q!', map_opts) + api.nvim_buf_set_keymap( + buf, + 'i', + '', + "stopinsert lua require('cosmic.core.theme.ui')._rename()", + map_opts + ) + + function M._rename() + local newName = vim.trim(vim.fn.getline('.'):sub(5, -1)) + vim.cmd([[q!]]) + local params = lsp.util.make_position_params() + local currName = vim.fn.expand('') + if not (newName and #newName > 0) or newName == currName then + return + end + params.newName = newName + lsp.buf_request(0, 'textDocument/rename', params) + end +end + +return M diff --git a/lua/cosmic/core/treesitter/init.lua b/lua/cosmic/core/treesitter/init.lua new file mode 100644 index 0000000..7f6f4c4 --- /dev/null +++ b/lua/cosmic/core/treesitter/init.lua @@ -0,0 +1,33 @@ +require('nvim-treesitter.configs').setup({ + ensure_installed = { + 'typescript', + 'javascript', + 'tsx', + 'html', + 'css', + 'bash', + 'lua', + 'json', + 'python', + 'php', + 'scss', + 'go', + }, + highlight = { + enable = true, + use_languagetree = true, + }, + indent = { + enable = true, + }, + autotag = { + enable = true, + }, + context_commentstring = { + enable = true, + }, + refactor = { + highlight_definitions = { enable = true }, + highlight_current_scope = { enable = false }, + }, +}) diff --git a/lua/cosmic/disabled.lua b/lua/cosmic/disabled.lua new file mode 100644 index 0000000..a020426 --- /dev/null +++ b/lua/cosmic/disabled.lua @@ -0,0 +1,24 @@ +local disabled_built_ins = { + 'netrw', + 'netrwPlugin', + 'netrwSettings', + 'netrwFileHandlers', + 'gzip', + 'zip', + 'zipPlugin', + 'tar', + 'tarPlugin', + 'getscript', + 'getscriptPlugin', + 'vimball', + 'vimballPlugin', + '2html_plugin', + 'logipat', + 'rrhelper', + 'spellfile_plugin', + 'matchit', +} + +for _, plugin in pairs(disabled_built_ins) do + vim.g['loaded_' .. plugin] = 1 +end diff --git a/lua/cosmic/editor.lua b/lua/cosmic/editor.lua new file mode 100644 index 0000000..90ffe50 --- /dev/null +++ b/lua/cosmic/editor.lua @@ -0,0 +1,75 @@ +local cmd = vim.cmd +local opt = vim.opt +local indent = 2 + +cmd([[ + filetype plugin indent on + autocmd BufWritePre * :%s/\s\+$//e +]]) + +-- misc +opt.syntax = 'enable' +opt.hidden = true +opt.encoding = 'utf-8' +opt.clipboard = 'unnamedplus' +opt.backspace = { 'eol', 'start', 'indent' } +opt.matchpairs = { '(:)', '{:}', '[:]', '<:>' } + +-- indention +opt.autoindent = true +opt.smartindent = true + +-- tabs +opt.tabstop = indent +opt.softtabstop = indent +opt.shiftwidth = indent +opt.expandtab = true + +-- search +opt.wildmenu = true +opt.ignorecase = true +opt.smartcase = true +opt.wildignore = opt.wildignore + { '*/node_modules/*', '*/wp-includes/*', '*/wp-admin/*', '*/vendor/*' } +opt.hlsearch = false + +-- ui +opt.number = true +opt.rnu = true +opt.cursorline = true +opt.signcolumn = 'yes' +opt.laststatus = 2 +opt.wrap = false +opt.scrolloff = 18 +opt.sidescrolloff = 3 -- Lines to scroll horizontally +opt.list = true +opt.listchars = { + tab = 'โ˜-', + trail = 'ยท', + lead = 'ยท', + extends = 'ยป', + precedes = 'ยซ', + nbsp = 'ร—', +} +opt.showmode = false +opt.lazyredraw = true +opt.mouse = 'a' +opt.splitright = true -- Open new split to the right +opt.splitbelow = true -- Open new split below + +-- backups +opt.swapfile = false +opt.backup = false +opt.writebackup = false + +-- autocomplete +opt.completeopt = { 'menu', 'menuone', 'noselect' } +opt.shortmess = opt.shortmess + { c = true } + +-- perfomance +opt.updatetime = 100 +opt.timeoutlen = 400 +opt.redrawtime = 1500 +opt.ttimeoutlen = 10 + +-- theme +opt.termguicolors = true diff --git a/lua/cosmic/init.lua b/lua/cosmic/init.lua new file mode 100644 index 0000000..7e468ce --- /dev/null +++ b/lua/cosmic/init.lua @@ -0,0 +1,5 @@ +require('cosmic.compiled') +require('cosmic.disabled') +require('cosmic.pluginsInit') +require('cosmic.mappings') +require('cosmic.editor') diff --git a/lua/cosmic/lsp/autocomplete.lua b/lua/cosmic/lsp/autocomplete.lua new file mode 100644 index 0000000..be184f5 --- /dev/null +++ b/lua/cosmic/lsp/autocomplete.lua @@ -0,0 +1,77 @@ +local cmp = require('cmp') + +vim.cmd([[ +autocmd FileType TelescopePrompt lua require('cmp').setup.buffer { enabled = false } +]]) + +cmp.setup({ + snippet = { + expand = function(args) + require'luasnip'.lsp_expand(args.body) + end, + }, + mapping = { + [''] = cmp.mapping.scroll_docs(-4), + [''] = cmp.mapping.scroll_docs(4), + [''] = cmp.mapping.complete(), + [''] = cmp.mapping.close(), + [''] = cmp.mapping.confirm({ + behavior = cmp.ConfirmBehavior.Replace, + select = true, + }), + [''] = function(fallback) + if cmp.visible() then + cmp.select_next_item() + else + fallback() + end + end, + [''] = function(fallback) + if cmp.visible() then + cmp.select_prev_item() + else + fallback() + end + end, + }, + documentation = { + border = 'single', + winhighlight = 'FloatBorder:FloatBorder,Normal:Normal', + }, + experimental = { + ghost_text = true, + }, + sources = { + { name = 'nvim_lsp' }, + { name = 'buffer' }, + { name = 'luasnip' }, + { name = 'nvim_lua' }, + { name = 'path' }, + }, + formatting = { + format = require('lspkind').cmp_format({ + with_text = true, + menu = { + nvim_lsp = '[LSP]', + buffer = '[Buf]', + luasnip = '[LSnip]', + nvim_lua = '[Lua]', + }, + }), + }, +}) + +require('nvim-autopairs').setup({ + disable_filetype = { 'TelescopePrompt', 'vim' }, +}) + +require('nvim-autopairs.completion.cmp').setup({ + map_cr = true, -- map on insert mode + map_complete = true, -- it will auto insert `(` (map_char) after select function or method item + auto_select = true, -- automatically select the first item + insert = false, -- use insert confirm behavior instead of replace + map_char = { -- modifies the function or method delimiter by filetypes + all = '(', + tex = '{', + }, +}) diff --git a/lua/cosmic/lsp/diagnostics.lua b/lua/cosmic/lsp/diagnostics.lua new file mode 100644 index 0000000..85a07c4 --- /dev/null +++ b/lua/cosmic/lsp/diagnostics.lua @@ -0,0 +1,67 @@ +local icons = require('cosmic.core.theme.icons') +local M = {} + +function M.init() + vim.diagnostic.config({ + underline = true, + update_in_insert = false, + virtual_text = { + spacing = 4, + source = 'always', + -- severity = 'error' + -- prefix = '๐Ÿ‘พ', + }, + signs = true, + severity_sort = true, + }) + + local function do_diagnostic_signs() + local signs = { + Error = icons.error .. ' ', + Warn = icons.warn .. ' ', + Hint = icons.hint .. ' ', + Info = icons.info .. ' ', + } + + local t = vim.fn.sign_getdefined('DiagnosticSignWarn') + if vim.tbl_isempty(t) then + for type, icon in pairs(signs) do + local hl = 'DiagnosticSign' .. type + vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = '' }) + end + end + end + + local function do_legacy_diagnostic_signs() + local signs = { + Error = icons.error .. ' ', + Warning = icons.warn .. ' ', + Hint = icons.hint .. ' ', + Information = icons.info .. ' ', + } + local h = vim.fn.sign_getdefined('LspDiagnosticsSignWarn') + if vim.tbl_isempty(h) then + for type, icon in pairs(signs) do + local hl = 'LspDiagnosticsSign' .. type + vim.fn.sign_define(hl, { text = icon, texthl = hl, numhl = '' }) + end + end + end + + do_diagnostic_signs() + do_legacy_diagnostic_signs() +end + +function M.trouble() + require('trouble').setup({ + mode = 'lsp_document_diagnostics', -- "lsp_workspace_diagnostics", "lsp_document_diagnostics", "quickfix", "lsp_references", "loclist" + signs = { + error = icons.error .. ' ', + warning = icons.warn .. ' ', + hint = icons.hint .. ' ', + information = icons.info .. ' ', + }, + }) +end + +return M diff --git a/lua/cosmic/lsp/init.lua b/lua/cosmic/lsp/init.lua new file mode 100644 index 0000000..5064203 --- /dev/null +++ b/lua/cosmic/lsp/init.lua @@ -0,0 +1,7 @@ +require('cosmic.lsp.providers') +require('cosmic.lsp.diagnostics').init() + +vim.lsp.handlers['textDocument/signatureHelp'] = vim.lsp.with(vim.lsp.handlers.signature_help, { border = 'single' }) +vim.lsp.handlers['textDocument/hover'] = vim.lsp.with(vim.lsp.handlers.hover, { + border = 'single', +}) diff --git a/lua/cosmic/lsp/mappings.lua b/lua/cosmic/lsp/mappings.lua new file mode 100644 index 0000000..2049512 --- /dev/null +++ b/lua/cosmic/lsp/mappings.lua @@ -0,0 +1,31 @@ +local map = require('cosmic.utils').map + +-- Mappings. +local opts = { noremap = true, silent = true } +local popup_opts = '{ border = "single", focusable = false, }' +local win_opts = '{ popup_opts = ' .. popup_opts .. '}' + +-- See `:help vim.lsp.*` for documentation on any of the below functions +map('n', 'gd', 'lua vim.lsp.buf.definition()', opts) +map('n', 'gD', 'lua vim.lsp.buf.declaration()', opts) +map('n', 'gi', 'lua vim.lsp.buf.implementation()', opts) +map('n', 'gt', 'lua vim.lsp.buf.type_definition()', opts) +map('n', 'gr', 'lua require("telescope.builtin").lsp_references()', opts) +map('n', 'gn', 'lua require("cosmic.core.theme.ui").rename()', opts) +map('n', '[g', 'lua vim.lsp.diagnostic.goto_prev(' .. win_opts .. ')', opts) +map('n', ']g', 'lua vim.lsp.diagnostic.goto_next(' .. win_opts .. ')', opts) +map('n', 'ge', 'lua vim.lsp.diagnostic.show_line_diagnostics(' .. popup_opts .. ')', opts) +map('n', 'K', 'lua vim.lsp.buf.hover()', opts) +map('n', 'ga', 'lua require("telescope.builtin").lsp_code_actions()', opts) +map('v', 'ga', 'lua require("telescope.builtin").lsp_range_code_actions()', opts) +map('n', 'gf', 'lua vim.lsp.buf.formatting()', opts) +map('n', '', 'lua require("lsp_signature").signature()', opts) + +map('n', 'wa', 'lua vim.lsp.buf.add_workspace_folder()', opts) +map('n', 'wr', 'lua vim.lsp.buf.remove_workspace_folder()', opts) +map('n', 'wl', 'lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))', opts) + +-- no default maps, so you may want to define some here +map('n', 'gr', ':TSLspRenameFile', opts) +map('n', 'go', ':TSLspOrganize', opts) +map('n', 'gi', ':TSLspImportAll', opts) diff --git a/lua/cosmic/lsp/providers/defaults.lua b/lua/cosmic/lsp/providers/defaults.lua new file mode 100644 index 0000000..1d906a2 --- /dev/null +++ b/lua/cosmic/lsp/providers/defaults.lua @@ -0,0 +1,51 @@ +local M = {} + +function M.on_attach(client, bufnr) + local function buf_set_option(...) + vim.api.nvim_buf_set_option(bufnr, ...) + end + + -- Enable completion triggered by + buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc') + + require('cosmic.lsp.mappings') + + -- So that the only client with format capabilities is efm + if client.name ~= 'efm' then + client.resolved_capabilities.document_formatting = false + client.resolved_capabilities.document_range_formatting = false + end + + -- need to set eslint formatting manually + if client.name == 'eslint' then + client.resolved_capabilities.document_formatting = true + client.resolved_capabilities.document_range_formatting = true + end + + require('lsp_signature').on_attach({ + bind = true, -- This is mandatory, otherwise border config won't get registered. + handler_opts = { + border = 'single', + }, + }, bufnr) + + -- for some reason, highlights have to happen here + require('cosmic.core.theme.highlights').init() +end + +M.flags = { + debounce_text_changes = 150, +} + +M.capabilities = require('cmp_nvim_lsp').update_capabilities(vim.lsp.protocol.make_client_capabilities()) + +M.root_dir = function(fname) + local util = require('lspconfig').util + return util.root_pattern('.git')(fname) + or util.root_pattern('tsconfig.base.json')(fname) + or util.root_pattern('package.json')(fname) + or util.root_pattern('.eslintrc.js')(fname) + or util.root_pattern('tsconfig.json')(fname) +end + +return M diff --git a/lua/cosmic/lsp/providers/efm.lua b/lua/cosmic/lsp/providers/efm.lua new file mode 100644 index 0000000..942cbf2 --- /dev/null +++ b/lua/cosmic/lsp/providers/efm.lua @@ -0,0 +1,39 @@ +local util = require('lspconfig').util + +local stylua = { + formatCommand = 'stylua -s --quote-style AutoPreferSingle --indent-type Spaces --indent-width 2 -', + formatStdin = true, +} + +local prettier = { + -- formatCommand = 'prettier --stdin-filepath ${INPUT}', + formatCommand = 'prettierd "${INPUT}"', + formatStdin = true, +} + +local filetypes = { + css = { prettier }, + html = { prettier }, + lua = { stylua }, + javascript = { prettier }, + javascriptreact = { prettier }, + json = { prettier }, + markdown = { prettier }, + scss = { prettier }, + typescript = { prettier }, + typescriptreact = { prettier }, + yaml = { prettier }, +} + +return { + init_options = { documentFormatting = true, codeAction = true }, + root_dir = function(fname) + return util.root_pattern('.git')(fname) + or util.root_pattern('tsconfig.base.json')(fname) + or util.root_pattern('package.json')(fname) + or util.root_pattern('.eslintrc.js')(fname) + or util.root_pattern('tsconfig.json')(fname) + end, + filetypes = vim.tbl_keys(filetypes), + settings = { languages = filetypes }, +} diff --git a/lua/cosmic/lsp/providers/eslint.lua b/lua/cosmic/lsp/providers/eslint.lua new file mode 100644 index 0000000..5464885 --- /dev/null +++ b/lua/cosmic/lsp/providers/eslint.lua @@ -0,0 +1,15 @@ +local util = require('lspconfig').util + +return { + settings = { + packageManager = 'yarn', + format = true, + }, + root_dir = function(fname) + return util.root_pattern('.git')(fname) + or util.root_pattern('tsconfig.base.json')(fname) + or util.root_pattern('package.json')(fname) + or util.root_pattern('.eslintrc.js')(fname) + or util.root_pattern('tsconfig.json')(fname) + end, +} diff --git a/lua/cosmic/lsp/providers/init.lua b/lua/cosmic/lsp/providers/init.lua new file mode 100644 index 0000000..93e2e6c --- /dev/null +++ b/lua/cosmic/lsp/providers/init.lua @@ -0,0 +1,42 @@ +local default_config = require('cosmic.lsp.providers.defaults') +local lsp_installer = require('nvim-lsp-installer') + +lsp_installer.settings({ + ui = { + keymaps = { + -- Keymap to expand a server in the UI + toggle_server_expand = 'i', + -- Keymap to install a server + install_server = '', + -- Keymap to reinstall/update a server + update_server = 'u', + -- Keymap to uninstall a server + uninstall_server = 'x', + }, + }, +}) + +lsp_installer.on_server_ready(function(server) + local opts = default_config + + if server.name == 'sumneko_lua' then + local config = require('cosmic.lsp.providers.lua') + opts = vim.tbl_deep_extend('force', opts, config) + elseif server.name == 'tsserver' then + local config = require('cosmic.lsp.providers.tsserver') + opts = vim.tbl_deep_extend('force', opts, config) + elseif server.name == 'efm' then + local config = require('cosmic.lsp.providers.efm') + opts = vim.tbl_deep_extend('force', opts, config) + elseif server.name == 'jsonls' then + local config = require('cosmic.lsp.providers.jsonls') + opts = vim.tbl_deep_extend('force', opts, config) + elseif server.name == 'eslint' then + local config = require('cosmic.lsp.providers.eslint') + opts = vim.tbl_deep_extend('force', opts, config) + end + + -- This setup() function is exactly the same as lspconfig's setup function (:help lspconfig-quickstart) + server:setup(opts) + vim.cmd([[ do User LspAttachBuffers ]]) +end) diff --git a/lua/cosmic/lsp/providers/jsonls.lua b/lua/cosmic/lsp/providers/jsonls.lua new file mode 100644 index 0000000..370a5f8 --- /dev/null +++ b/lua/cosmic/lsp/providers/jsonls.lua @@ -0,0 +1,49 @@ +return { + settings = { + json = { + -- Schemas https://www.schemastore.org + schemas = { + { + fileMatch = { 'package.json' }, + url = 'https://json.schemastore.org/package.json', + }, + { + fileMatch = { 'tsconfig*.json' }, + url = 'https://json.schemastore.org/tsconfig.json', + }, + { + fileMatch = { + '.prettierrc', + '.prettierrc.json', + 'prettier.config.json', + }, + url = 'https://json.schemastore.org/prettierrc.json', + }, + { + fileMatch = { '.eslintrc', '.eslintrc.json' }, + url = 'https://json.schemastore.org/eslintrc.json', + }, + { + fileMatch = { '.babelrc', '.babelrc.json', 'babel.config.json' }, + url = 'https://json.schemastore.org/babelrc.json', + }, + { + fileMatch = { 'lerna.json' }, + url = 'https://json.schemastore.org/lerna.json', + }, + { + fileMatch = { 'now.json', 'vercel.json' }, + url = 'https://json.schemastore.org/now.json', + }, + { + fileMatch = { + '.stylelintrc', + '.stylelintrc.json', + 'stylelint.config.json', + }, + url = 'http://json.schemastore.org/stylelintrc.json', + }, + }, + }, + }, +} diff --git a/lua/cosmic/lsp/providers/lua.lua b/lua/cosmic/lsp/providers/lua.lua new file mode 100644 index 0000000..681f24e --- /dev/null +++ b/lua/cosmic/lsp/providers/lua.lua @@ -0,0 +1,32 @@ +local sumneko_binary_path = vim.fn.exepath('lua-language-server') +local sumneko_root_path = vim.fn.fnamemodify(sumneko_binary_path, ':h:h:h') + +local runtime_path = vim.split(package.path, ';') +table.insert(runtime_path, 'lua/?.lua') +table.insert(runtime_path, 'lua/?/init.lua') + +return { + cmd = { sumneko_binary_path, '-E', sumneko_root_path .. '/main.lua' }, + settings = { + Lua = { + runtime = { + -- Tell the language server which version of Lua you're using (most likely LuaJIT in the case of Neovim) + version = 'LuaJIT', + -- Setup your lua path + path = runtime_path, + }, + diagnostics = { + -- Get the language server to recognize the `vim` global + globals = { 'vim' }, + }, + workspace = { + -- Make the server aware of Neovim runtime files + library = vim.api.nvim_get_runtime_file('', true), + }, + -- Do not send telemetry data containing a randomized but unique identifier + telemetry = { + enable = false, + }, + }, + }, +} diff --git a/lua/cosmic/lsp/providers/tsserver.lua b/lua/cosmic/lsp/providers/tsserver.lua new file mode 100644 index 0000000..bb736f2 --- /dev/null +++ b/lua/cosmic/lsp/providers/tsserver.lua @@ -0,0 +1,52 @@ +local default_on_attach = require('cosmic.lsp.providers.defaults').on_attach +local M = {} + +function M.on_attach(client, bufnr) + default_on_attach(client, bufnr) + + local ts_utils = require('nvim-lsp-ts-utils') + + -- defaults + ts_utils.setup({ + debug = false, + disable_commands = false, + enable_import_on_completion = true, + + -- import all + import_all_timeout = 5000, -- ms + import_all_priorities = { + buffers = 4, -- loaded buffer names + buffer_content = 3, -- loaded buffer content + local_files = 2, -- git files or files with relative path markers + same_file = 1, -- add to existing import statement + }, + import_all_scan_buffers = 100, + import_all_select_source = false, + + -- eslint + eslint_enable_code_actions = false, + eslint_enable_disable_comments = false, + eslint_bin = 'eslint_d', + eslint_enable_diagnostics = false, + eslint_opts = {}, + + -- formatting + enable_formatting = false, + formatter = 'prettierd', + formatter_opts = {}, + + -- update imports on file move + update_imports_on_move = true, + require_confirmation_on_move = false, + watch_dir = nil, + + -- filter diagnostics + filter_out_diagnostics_by_severity = {}, + filter_out_diagnostics_by_code = {}, + }) + + -- required to fix code action ranges and filter diagnostics + ts_utils.setup_client(client) +end + +return M diff --git a/lua/cosmic/mappings.lua b/lua/cosmic/mappings.lua new file mode 100644 index 0000000..c6b36f3 --- /dev/null +++ b/lua/cosmic/mappings.lua @@ -0,0 +1,14 @@ +local g = vim.g +local map = require('cosmic.utils').map + +g.mapleader = ' ' + +-- Quickfix +map('n', 'ck', ':cexpr []', { noremap = true }) +map('n', 'cc', ':cclose ', { noremap = true }) +map('n', 'co', ':copen ', { noremap = true }) +map('n', 'cf', ':cfdo %s/', { noremap = true }) + +require('cosmic.core.file-navigation.mappings').init() +require('cosmic.core.file-explorer.mappings') +require('cosmic.core.terminal.mappings') diff --git a/lua/cosmic/packer.lua b/lua/cosmic/packer.lua new file mode 100644 index 0000000..90c2373 --- /dev/null +++ b/lua/cosmic/packer.lua @@ -0,0 +1,47 @@ +local cmd = vim.cmd + +cmd('packadd packer.nvim') + +local present, packer = pcall(require, 'packer') + +if not present then + local packer_path = vim.fn.stdpath('data') .. '/site/pack/packer/opt/packer.nvim' + + print('Cloning packer..') + -- remove the dir before cloning + vim.fn.delete(packer_path, 'rf') + vim.fn.system({ + 'git', + 'clone', + 'https://github.com/wbthomason/packer.nvim', + '--depth', + '20', + packer_path, + }) + + cmd('packadd packer.nvim') + present, packer = pcall(require, 'packer') + + if present then + print('Packer cloned successfully.') + else + error("Couldn't clone packer !\nPacker path: " .. packer_path .. '\n' .. packer) + end +end + +packer.init({ + display = { + open_fn = function() + return require('packer.util').float({ border = 'single' }) + end, + prompt_border = 'single', + }, + git = { + clone_timeout = 800, -- Timeout, in seconds, for git clones + }, + compile_path = vim.fn.stdpath('config')..'/lua/cosmic/compiled.lua', + auto_clean = true, + compile_on_sync = true, +}) + +return packer diff --git a/lua/cosmic/pluginsInit.lua b/lua/cosmic/pluginsInit.lua new file mode 100644 index 0000000..23af6be --- /dev/null +++ b/lua/cosmic/pluginsInit.lua @@ -0,0 +1,193 @@ +local present, packer = pcall(require, "cosmic.packer") + +if not present then + return false +end + +local use = packer.use + +return packer.startup(function() + use('wbthomason/packer.nvim') + + use({ + 'lewis6991/impatient.nvim', + config = function() + require('impatient') + end + }) + + use({ -- color scheme + 'folke/tokyonight.nvim', + config = function() + vim.g.tokyonight_style = 'night' + vim.g.tokyonight_sidebars = { 'qf', 'packer' } + vim.cmd('color tokyonight') + end, + }) + + use({ -- icons + 'kyazdani42/nvim-web-devicons', + after = 'tokyonight.nvim', + }) + + -- theme stuff + use({ -- statusline + 'NTBBloodbath/galaxyline.nvim', + branch = 'main', + requires = { 'kyazdani42/nvim-web-devicons', opt = true }, + config = function() + require('cosmic.core.statusline') + end, + after = 'nvim-web-devicons', + }) + + -- file explorer + use({ + 'kyazdani42/nvim-tree.lua', + config = function() + require('cosmic.core.file-explorer').init() + end, + opt = true, + cmd = { + 'NvimTreeClipboard', + 'NvimTreeClose', + 'NvimTreeFindFile', + 'NvimTreeOpen', + 'NvimTreeRefresh', + 'NvimTreeToggle', + }, + }) + + use({ -- lsp + 'williamboman/nvim-lsp-installer', + requires = { + 'neovim/nvim-lspconfig', + 'ray-x/lsp_signature.nvim', + 'jose-elias-alvarez/nvim-lsp-ts-utils', + }, + config = function() + require('cosmic.lsp') + end, + }) + + -- autocompletion + use({ + 'hrsh7th/nvim-cmp', + config = function() + require('cosmic.lsp.autocomplete') + end, + requires = { + 'hrsh7th/cmp-nvim-lsp', + 'hrsh7th/cmp-buffer', + 'hrsh7th/cmp-path', + 'hrsh7th/nvim-cmp', + 'L3MON4D3/LuaSnip', + 'saadparwaiz1/cmp_luasnip', + 'windwp/nvim-autopairs', + 'onsails/lspkind-nvim', + }, + }) + + -- diagnostics + use({ + 'folke/trouble.nvim', + opt = true, + config = function() + require('cosmic.lsp.diagnostics').trouble() + end, + cmd = { + 'Trouble', + 'TroubleClose', + 'TroubleToggle', + 'TroubleRefresh', + }, + }) + + -- git commands + use({ + 'tpope/vim-fugitive', + opt = true, + cmd = 'Git', + }) + + -- git column signs + use({ + 'lewis6991/gitsigns.nvim', + requires = { 'nvim-lua/plenary.nvim' }, + event = 'BufRead', + config = function() + require('gitsigns').setup() + end, + }) + + -- floating terminal + use({ + 'voldikss/vim-floaterm', + opt = true, + cmd = { 'FloatermToggle', 'FloatermNew', 'FloatermSend' }, + config = function() + require('cosmic.core.terminal') + end, + }) + + -- file navigation + use({ + 'nvim-telescope/telescope.nvim', + requires = { + 'nvim-lua/popup.nvim', + 'nvim-lua/plenary.nvim', + { + 'nvim-telescope/telescope-fzf-native.nvim', + run = 'make', + }, + }, + config = function() + require('cosmic.core.file-navigation') + end, + event = 'BufRead', + }) + + -- session management + use({ + 'rmagatti/auto-session', + event = 'VimEnter', + config = function() + require('auto-session').setup({ + pre_save_cmds = { 'NvimTreeClose', 'TroubleClose', 'cclose' }, + }) + end, + }) + + -- lang/syntax stuff + use({ + 'nvim-treesitter/nvim-treesitter', + requires = { + 'windwp/nvim-ts-autotag', + 'JoosepAlviste/nvim-ts-context-commentstring', + 'nvim-treesitter/nvim-treesitter-refactor', + }, + run = ':TSUpdate', + config = function() + require('cosmic.core.treesitter') + end, + }) + + -- comments and stuff + use({ + 'numToStr/Comment.nvim', + config = function() + require('Comment').setup() + end, + event = 'BufRead', + }) + + -- colorized hex codes + use({ + 'norcalli/nvim-colorizer.lua', + opt = true, + cmd = { 'ColorizerToggle' }, + config = function() + require('colorizer').setup() + end, + }) +end) diff --git a/lua/cosmic/utils.lua b/lua/cosmic/utils.lua new file mode 100644 index 0000000..1b5ab6b --- /dev/null +++ b/lua/cosmic/utils.lua @@ -0,0 +1,43 @@ +local M = {} + +local function get_basename(file) + return file:match('^.+/(.+)$') +end + +function M.map(mode, lhs, rhs, opts) + local options = { noremap = true } + if opts then + options = vim.tbl_extend('force', options, opts) + end + vim.api.nvim_set_keymap(mode, lhs, rhs, options) +end + +function M.get_git_root() + local git_dir = require('galaxyline.providers.vcs').get_git_dir() + if not git_dir then + return 'not a git dir ' + end + + local git_root = git_dir:gsub('/.git/?$', '') + return get_basename(git_root) .. ' ' +end + +function M.split(str, sep) + local res = {} + for w in str:gmatch('([^' .. sep .. ']*)') do + if w ~= '' then + table.insert(res, w) + end + end + return res +end + +function M.highlight(group, bg, fg, gui) + if gui ~= nil and gui ~= '' then + vim.api.nvim_command(string.format('hi %s guibg=%s guifg=%s gui=%s', group, bg, fg, gui)) + else + vim.api.nvim_command(string.format('hi %s guibg=%s guifg=%s', group, bg, fg)) + end +end + +return M diff --git a/readme.md b/readme.md new file mode 100644 index 0000000..6236cb7 --- /dev/null +++ b/readme.md @@ -0,0 +1,74 @@ +# โœจ CosmicNvim โœจ + +A lightweight and opinionated Neovim configuration for web development specifically designed to provide a COSMIC programming experience! + +## ๐Ÿš€ Stellar Features + +#### Native LSP + +Full featured native LSP functionality! + +- ๐Ÿ“˜ Go-to definition +- ๐Ÿ” Find references/type def/declaration +- ๐Ÿ’ก Code actions +- ๐Ÿšจ Statusline diagnostics +- โš ๏ธ Linting thanks to [eslint](https://github.com/williamboman/nvim-lsp-installer/blob/main/lua/nvim-lsp-installer/servers/eslint/README.md) +- ๐Ÿ”ง Formatting thanks to [efm](https://github.com/mattn/efm-langserver) + +##### Additional features + +- Amazing colors thanks to [tokyonight.nvim](https://github.com/folke/tokyonight.nvim) +- Enhanced syntax highlighting with [nvim-treesitter](https://github.com/nvim-treesitter/nvim-treesitter) +- Hand-built statusline with [galaxyline](https://github.com/NTBBloodbath/galaxyline.nvim) +- Explore files with [nvim-tree](https://github.com/kyazdani42/nvim-tree.lua) +- Fuzzy finder and some LSP actions with [Telescope](https://github.com/nvim-telescope/telescope.nvim) +- Floating terminal with [vim-floatterm](https://github.com/voldikss/vim-floaterm) +- Easy LSP installation with [nvim-lsp-installer](https://github.com/williamboman/nvim-lsp-installer) +- Autocompletion provided by [nvim-cmp](https://github.com/hrsh7th/nvim-cmp) +- Session management with [auto-session](https://github.com/rmagatti/auto-session) +- Floating windows for references, renaming, diagnostics, code actions and more! + +_While CosmicNvim is geared specifically toward TypeScript/JavaScript development, it should be able to provide a great experience with any LSP supported language._ + +### How to install + +Using [stow](https://www.gnu.org/software/stow/) + +``` + $ git clone git@github.com:mattleong/CosmicNvim.git + $ mkdir ~/.config/nvim + $ stow -t ~/.config/nvim CosmicNvim +``` + +Symlinking (don't use relative pathing) + +``` + $ git clone git@github.com:mattleong/CosmicNvim.git + $ ln -s ~/.config/nvim ~/CosmicNvim +``` + +## ๐Ÿ“ท Screenshots + +### Statusline +![insert](https://user-images.githubusercontent.com/3721204/137990345-d036c2d1-0f9e-4d4e-bd6c-13e051609f61.png) +![normal](https://user-images.githubusercontent.com/3721204/137990346-8f614b6b-63da-471a-b5be-635b587f10a1.png) +![replace](https://user-images.githubusercontent.com/3721204/137990347-b59428d6-b5fe-4edb-8ceb-ab37b69b7e76.png) +![visual](https://user-images.githubusercontent.com/3721204/137990348-6eb29e9b-e912-4d6e-8a5e-e763816613d7.png) + +### Autocomplete +![autocomplete](https://user-images.githubusercontent.com/3721204/137990341-39251a51-7fb8-47cc-a92e-b3893ef6cb34.png) + +### Rename +![rename](https://user-images.githubusercontent.com/3721204/137995308-b8260fe6-a2e8-427d-aa21-5df0bfecf72f.png) + +### Hover +![lsp hover3](https://user-images.githubusercontent.com/3721204/137989460-91b094d5-e47e-4775-a252-39442cf398d9.png) + +### Find Reference +![lsp ref](https://user-images.githubusercontent.com/3721204/137989929-12036575-4b63-471e-ab44-ac6ad31bb478.png) + +### File Navigation +![telescope](https://user-images.githubusercontent.com/3721204/137989935-30f3bf57-435e-4e5c-8817-2d8c6c6dd9b1.png) + +### Floating Terminal +![terminal](https://user-images.githubusercontent.com/3721204/137989938-70a72dca-c6e6-4bb2-91fe-89ed94614824.png)