diff --git a/init.lua b/init.lua index 0d380e8d..571e72d3 100644 --- a/init.lua +++ b/init.lua @@ -91,7 +91,7 @@ vim.g.mapleader = ' ' vim.g.maplocalleader = ' ' -- Set to true if you have a Nerd Font installed and selected in the terminal -vim.g.have_nerd_font = false +vim.g.have_nerd_font = true -- [[ Setting options ]] -- See `:help vim.opt` @@ -876,19 +876,19 @@ require('lazy').setup({ -- Here are some example plugins that I've included in the Kickstart repository. -- Uncomment any of the lines below to enable them (you will need to restart nvim). -- - -- require 'kickstart.plugins.debug', - -- require 'kickstart.plugins.indent_line', - -- require 'kickstart.plugins.lint', - -- require 'kickstart.plugins.autopairs', - -- require 'kickstart.plugins.neo-tree', - -- require 'kickstart.plugins.gitsigns', -- adds gitsigns recommend keymaps + require 'kickstart.plugins.debug', + require 'kickstart.plugins.indent_line', + require 'kickstart.plugins.lint', + require 'kickstart.plugins.autopairs', + require 'kickstart.plugins.neo-tree', + require 'kickstart.plugins.gitsigns', -- adds gitsigns recommend keymaps -- NOTE: The import below can automatically add your own plugins, configuration, etc from `lua/custom/plugins/*.lua` -- This is the easiest way to modularize your config. -- -- Uncomment the following line and add your plugins to `lua/custom/plugins/*.lua` to get going. -- For additional information, see `:help lazy.nvim-lazy.nvim-structuring-your-plugins` - -- { import = 'custom.plugins' }, + { import = 'custom.plugins' }, }, { ui = { -- If you are using a Nerd Font: set icons to an empty table which will use the diff --git a/lua/custom/plugins/init.lua b/lua/custom/plugins/init.lua index be0eb9d8..a06452ef 100644 --- a/lua/custom/plugins/init.lua +++ b/lua/custom/plugins/init.lua @@ -1,5 +1,598 @@ --- You can add your own plugins here or in other files in this directory! +-- You can add your own plugins here or in other files in this directory!custom -- I promise not to create any merge conflicts in this directory :) -- -- See the kickstart.nvim README for more information -return {} +vim.cmd [[ let g:neo_tree_remove_legacy_commands = 1 ]] + +vim.keymap.set({ 'n', 'v' }, 'y', [["+y]], { desc = 'Yank to clipboard' }) +vim.keymap.set('n', 'Y', [["+Y]], { desc = 'Yank to clipboard' }) +vim.keymap.set('i', '', '') +vim.keymap.set('n', 'rw', [[:%s/\<\>//gI]]) +vim.keymap.set('n', 'mq', ":%s/^/'/c | %s/$/',/c", { desc = 'Add quotes and commas' }) +vim.keymap.set('i', 'jk', '') +vim.keymap.set('n', 'x', ':qa!', { desc = 'Quit' }) +vim.keymap.set('n', 'sc', require('telescope.builtin').commands, { desc = '[S]earch [C]ommands' }) + +vim.opt.spell = false +vim.opt.spelllang = 'pt_br,en_us' + +vim.g.have_nerd_font = true + +require('which-key').add { + { 'j', group = '[J]ump' }, + { 'd', group = '[C-t]est' }, + { 'g', group = '[G]it' }, + { 'm', group = '[M]agestic Scripts' }, +} + +require('telescope').setup { + defaults = { + file_ignore_patterns = { + 'node_modules', + }, + }, + pickers = { + find_files = { + hidden = true, + }, + colorscheme = { + enable_preview = true, + }, + }, +} + +local lint = require 'lint' +lint.linters_by_ft = { + ruby = { 'ruby' }, + dockerfile = { 'hadolint' }, + typescript = { 'eslint_d' }, +} + +local conform = require 'conform' +conform.formatters_by_ft = { + javascript = { 'prettierd ' }, + typescript = { 'prettierd ' }, + ruby = { 'rubocop' }, +} + +return { + { + 'folke/tokyonight.nvim', + lazy = false, + priority = 1000, + }, + { + 'tpope/vim-fugitive', + keys = { + { 'g', [[Git]], { desc = 'Git' } }, + }, + }, + { + 'tpope/vim-rhubarb', + }, + { + 'https://github.com/rafamadriz/friendly-snippets', + }, + { + 'rafamadriz/friendly-snippets', + config = function() + require('luasnip.loaders.from_vscode').lazy_load() + end, + }, + { + 'nvim-telescope/telescope-live-grep-args.nvim', + -- This will not install any breaking changes. + -- For major updates, this must be adjusted manually. + version = '^1.0.0', + config = function() + require('telescope').load_extension 'live_grep_args' + end, + }, + { + 'pmizio/typescript-tools.nvim', + dependencies = { 'nvim-lua/plenary.nvim', 'neovim/nvim-lspconfig' }, + opts = {}, + }, + { 'tpope/vim-dispatch' }, + { 'rebelot/kanagawa.nvim' }, + { + 'tpope/vim-rails', + ft = { 'ruby' }, + keys = { + { 'ja', [[:execute "e " . eval('rails#buffer().alternate()')]], desc = 'Jump rails alternate' }, + }, + }, + { + 'ThePrimeagen/harpoon', + branch = 'harpoon2', + dependencies = { 'nvim-lua/plenary.nvim' }, + config = function() + local harpoon = require 'harpoon' + harpoon:setup() + + vim.keymap.set('n', 'a', function() + harpoon:list():append() + end) + vim.keymap.set('n', '', function() + harpoon.ui:toggle_quick_menu(harpoon:list()) + end) + + vim.keymap.set('n', '', function() + harpoon:list():select(1) + end) + vim.keymap.set('n', '', function() + harpoon:list():select(2) + end) + vim.keymap.set('n', '', function() + harpoon:list():select(3) + end) + vim.keymap.set('n', '', function() + harpoon:list():select(4) + end) + + -- Toggle previous & next buffers stored within Harpoon list + vim.keymap.set('n', '', function() + harpoon:list():prev() + end) + vim.keymap.set('n', '', function() + harpoon:list():next() + end) + end, + }, + { + 'catppuccin/nvim', + name = 'catppuccin', + priority = 1000, + event = 'VimEnter', + config = function() + require('catppuccin').setup { + transparent_background = false, + } + end, + }, + { + 'projekt0n/github-nvim-theme', + lazy = false, -- make sure we load this during startup if it is your main colorscheme + priority = 1000, -- make sure to load this before all the other start plugins + config = function() + require('github-theme').setup { + -- ... + } + end, + }, + { + 'iamcco/markdown-preview.nvim', + keys = { + { 'mp', ':MarkdownPreview', { + noremap = true, + silent = true, + desc = 'Markdown Preview', + } }, + }, + ft = 'markdown', + cmd = { 'MarkdownPreview', 'MarkdownPreviewStop' }, + build = function() + vim.fn['mkdp#util#install']() + end, + }, + -- { + -- 'nvim-neotest/neotest', + -- dependencies = { + -- 'nvim-neotest/nvim-nio', + -- 'nvim-lua/plenary.nvim', + -- 'nvim-neotest/neotest-go', + -- 'nvim-neotest/neotest-jest', + -- 'marilari88/neotest-vitest', + -- 'olimorris/neotest-rspec', + -- 'antoinemadec/FixCursorHold.nvim', + -- 'nvim-treesitter/nvim-treesitter', + -- }, + -- config = function() + -- local neotest_ns = vim.api.nvim_create_namespace 'neotest' + -- vim.diagnostic.config({ + -- virtual_text = { + -- format = function(diagnostic) + -- local message = diagnostic.message:gsub('\n', ' '):gsub('\t', ' '):gsub('%s+', ' '):gsub('^%s+', '') + -- return message + -- end, + -- }, + -- }, neotest_ns) + -- require('neotest').setup { + -- adapters = { + -- require 'neotest-vitest' { + -- filter_dir = function(name, rel_path, root) + -- return name ~= 'node_modules' + -- end, + -- }, + -- require 'neotest-jest' { + -- jestCommand = 'npm test --', + -- jestConfigFile = 'custom.jest.config.ts', + -- env = { CI = true }, + -- cwd = function(path) + -- return vim.fn.getcwd() + -- end, + -- }, + -- require 'neotest-go' { + -- recursive_run = true, + -- experimental = { + -- test_table = true, + -- }, + -- args = { '-v', '-count=1' }, + -- }, + -- require 'neotest-rspec' { + -- rspec_cmd = function() + -- return vim.tbl_flatten { + -- 'bundle', + -- 'exec', + -- 'rspec', + -- } + -- end, + -- }, + -- }, + -- } + -- + -- vim.keymap.set('n', 'fnn', function() + -- require('neotest').run.run() + -- end, { desc = 'Test Nearest' }) + -- vim.keymap.set('n', 'fnf', function() + -- require('neotest').run.run(vim.fn.expand '%') + -- end, { desc = 'Test File' }) + -- vim.keymap.set('n', 'fns', function() + -- require('neotest').run.run(vim.fn.getcwd()) + -- end, { desc = 'Test Suite' }) + -- vim.keymap.set('n', 'fnp', function() + -- require('neotest').output_panel.toggle() + -- require('neotest').summary.toggle() + -- end, { desc = 'Toggle Neotest Panel' }) + -- end, + -- }, + { + 'vim-test/vim-test', + config = function() + vim.cmd [[ let g:test#strategy = 'neovim' ]] + vim.cmd [[ let g:test#neovim#start_normal = 1 ]] + vim.cmd [[ let g:test#neovim#term_position = "vert botright" ]] + vim.cmd [[ let g:test#javascript#runner = 'jest' ]] + vim.cmd [[ let g:test#preserve_screen = 1 ]] + vim.cmd [[ let g:test#ruby#rspec#executable = 'bundle exec rspec' ]] + vim.cmd [[ let g:test#ruby#rspec#options = '--format documentation --color' ]] + end, + keys = { + { 'n', ':TestNearest', { desc = 'Test Nearest' } }, + { 'f', ':TestFile', { desc = 'Test File' } }, + { 's', ':TestSuite', { desc = 'Test Suite' } }, + { 'l', ':TestLast', { desc = 'Test Last' } }, + { 'v', ':TestVisit', { desc = 'TestVist' } }, + }, + }, + { 'EdenEast/nightfox.nvim' }, + { 'xiyaowong/transparent.nvim' }, + { 'ellisonleao/gruvbox.nvim' }, + { + 'vhyrro/luarocks.nvim', + priority = 1000, + config = true, + opts = { + rocks = { 'lua-curl', 'nvim-nio', 'mimetypes', 'xml2lua' }, + }, + }, + { + 'rest-nvim/rest.nvim', + ft = 'http', + dependencies = { 'luarocks.nvim' }, + config = function() + require('rest-nvim').setup() + end, + }, + { 'fatih/vim-go', ft = 'go' }, + { + 'zbirenbaum/copilot.lua', + cmd = 'Copilot', + event = 'InsertEnter', + config = function() + require('copilot').setup { + suggestion = { + enabled = true, + }, + panel = { + enabled = false, + }, + filetypes = { + markdown = true, + }, + } + end, + }, + { + 'epwalsh/obsidian.nvim', + version = '*', -- recommended, use latest release instead of latest commit + event = 'VimEnter', + lazy = false, + -- Replace the above line with this if you only want to load obsidian.nvim for markdown files in your vault: + -- event = { + -- -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand'. + -- -- E.g. "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/**.md" + -- "BufReadPre path/to/my-vault/**.md", + -- "BufNewFile path/to/my-vault/**.md", + -- }, + dependencies = { + -- Required. + 'nvim-lua/plenary.nvim', + + -- see below for full list of optional dependencies 👇 + }, + opts = { + workspaces = { + { + name = 'personal', + path = '~/vaults/personal', + }, + { + name = 'work', + path = '~/vaults/work', + }, + }, + completion = { + -- Set to false to disable completion. + nvim_cmp = true, + -- Trigger completion at 2 chars. + min_chars = 2, + }, + mappings = { + -- Overrides the 'gf' mapping to work on markdown/wiki links within your vault. + ['gf'] = { + action = function() + return require('obsidian').util.gf_passthrough() + end, + opts = { noremap = false, expr = true, buffer = true }, + }, + -- Toggle check-boxes. + ['ch'] = { + action = function() + return require('obsidian').util.toggle_checkbox() + end, + opts = { buffer = true }, + }, + -- Smart action depending on context, either follow link or toggle checkbox. + [''] = { + action = function() + return require('obsidian').util.smart_action() + end, + opts = { buffer = true, expr = true }, + }, + }, + -- Optional, customize how note IDs are generated given an optional title. + ---@param title string|? + ---@return string + note_id_func = function(title) + -- Create note IDs in a Zettelkasten format with a timestamp and a suffix. + -- In this case a note with the title 'My new note' will be given an ID that looks + -- like '1657296016-my-new-note', and therefore the file name '1657296016-my-new-note.md' + local suffix = '' + if title ~= nil then + -- If title is given, transform it into valid file name. + suffix = title:gsub(' ', '-'):gsub('[^A-Za-z0-9-]', ''):lower() + else + -- If title is nil, just add 4 random uppercase letters to the suffix. + for _ = 1, 4 do + suffix = suffix .. string.char(math.random(65, 90)) + end + end + return tostring(os.time()) .. '-' .. suffix + end, + + -- Optional, customize how note file names are generated given the ID, target directory, and title. + ---@param spec { id: string, dir: obsidian.Path, title: string|? } + ---@return string|obsidian.Path The full path to the new note. + note_path_func = function(spec) + -- This is equivalent to the default behavior. + local path = spec.dir / tostring(spec.id) + return path:with_suffix '.md' + end, + + -- Optional, customize how wiki links are formatted. You can set this to one of: + -- * "use_alias_only", e.g. '[[Foo Bar]]' + -- * "prepend_note_id", e.g. '[[foo-bar|Foo Bar]]' + -- * "prepend_note_path", e.g. '[[foo-bar.md|Foo Bar]]' + -- * "use_path_only", e.g. '[[foo-bar.md]]' + -- Or you can set it to a function that takes a table of options and returns a string, like this: + wiki_link_func = function(opts) + return require('obsidian.util').wiki_link_id_prefix(opts) + end, + + -- Optional, customize how markdown links are formatted. + markdown_link_func = function(opts) + return require('obsidian.util').markdown_link(opts) + end, + + -- Either 'wiki' or 'markdown'. + preferred_link_style = 'wiki', + + -- Optional, customize the default name or prefix when pasting images via `:ObsidianPasteImg`. + ---@return string + image_name_func = function() + -- Prefix image names with timestamp. + return string.format('%s-', os.time()) + end, + + -- Optional, boolean or a function that takes a filename and returns a boolean. + -- `true` indicates that you don't want obsidian.nvim to manage frontmatter. + disable_frontmatter = false, + + -- Optional, alternatively you can customize the frontmatter data. + ---@return table + note_frontmatter_func = function(note) + -- Add the title of the note as an alias. + if note.title then + note:add_alias(note.title) + end + + local out = { id = note.id, aliases = note.aliases, tags = note.tags } + + -- `note.metadata` contains any manually added fields in the frontmatter. + -- So here we just make sure those fields are kept in the frontmatter. + if note.metadata ~= nil and not vim.tbl_isempty(note.metadata) then + for k, v in pairs(note.metadata) do + out[k] = v + end + end + + return out + end, + + -- Optional, for templates (see below). + templates = { + folder = '~/vaults/templates', + date_format = '%Y-%m-%d', + time_format = '%H:%M', + -- A map for custom variables, the key should be the variable and the value a function + substitutions = {}, + }, + + -- Optional, by default when you use `:ObsidianFollowLink` on a link to an external + -- URL it will be ignored but you can customize this behavior here. + ---@param url string + follow_url_func = function(url) + -- Open the URL in the default web browser. + vim.fn.jobstart { 'open', url } -- Mac OS + -- vim.fn.jobstart({"xdg-open", url}) -- linux + end, + + -- Optional, set to true if you use the Obsidian Advanced URI plugin. + -- https://github.com/Vinzent03/obsidian-advanced-uri + use_advanced_uri = false, + + -- Optional, set to true to force ':ObsidianOpen' to bring the app to the foreground. + open_app_foreground = false, + + picker = { + -- Set your preferred picker. Can be one of 'telescope.nvim', 'fzf-lua', or 'mini.pick'. + name = 'telescope.nvim', + -- Optional, configure key mappings for the picker. These are the defaults. + -- Not all pickers support all mappings. + mappings = { + -- Create a new note from your query. + new = '', + -- Insert a link to the selected note. + insert_link = '', + }, + }, + + -- Optional, sort search results by "path", "modified", "accessed", or "created". + -- The recommend value is "modified" and `true` for `sort_reversed`, which means, for example, + -- that `:ObsidianQuickSwitch` will show the notes sorted by latest modified time + sort_by = 'modified', + sort_reversed = true, + + -- Set the maximum number of lines to read from notes on disk when performing certain searches. + search_max_lines = 1000, + + -- Optional, determines how certain commands open notes. The valid options are: + -- 1. "current" (the default) - to always open in the current window + -- 2. "vsplit" - to open in a vertical split if there's not already a vertical split + -- 3. "hsplit" - to open in a horizontal split if there's not already a horizontal split + open_notes_in = 'current', + + -- Optional, define your own callbacks to further customize behavior. + callbacks = { + -- Runs at the end of `require("obsidian").setup()`. + ---@param client obsidian.Client + post_setup = function(client) end, + + -- Runs anytime you enter the buffer for a note. + ---@param client obsidian.Client + ---@param note obsidian.Note + enter_note = function(client, note) end, + + -- Runs anytime you leave the buffer for a note. + ---@param client obsidian.Client + ---@param note obsidian.Note + leave_note = function(client, note) end, + + -- Runs right before writing the buffer for a note. + ---@param client obsidian.Client + ---@param note obsidian.Note + pre_write_note = function(client, note) end, + + -- Runs anytime the workspace is set/changed. + ---@param client obsidian.Client + ---@param workspace obsidian.Workspace + post_set_workspace = function(client, workspace) end, + }, + + -- Optional, configure additional syntax highlighting / extmarks. + -- This requires you have `conceallevel` set to 1 or 2. See `:help conceallevel` for more details. + ui = { + enable = false, -- set to false to disable all additional syntax features + update_debounce = 200, -- update delay after a text change (in milliseconds) + max_file_length = 5000, -- disable UI features for files with more than this many lines + -- Define how various check-boxes are displayed + checkboxes = { + -- NOTE: the 'char' value has to be a single character, and the highlight groups are defined below. + [' '] = { char = '󰄱', hl_group = 'ObsidianTodo' }, + ['x'] = { char = '', hl_group = 'ObsidianDone' }, + ['>'] = { char = '', hl_group = 'ObsidianRightArrow' }, + ['~'] = { char = '󰰱', hl_group = 'ObsidianTilde' }, + ['!'] = { char = '', hl_group = 'ObsidianImportant' }, + -- Replace the above with this if you don't have a patched font: + -- [" "] = { char = "☐", hl_group = "ObsidianTodo" }, + -- ["x"] = { char = "✔", hl_group = "ObsidianDone" }, + + -- You can also add more custom ones... + }, + -- Use bullet marks for non-checkbox lists. + bullets = { char = '•', hl_group = 'ObsidianBullet' }, + external_link_icon = { char = '', hl_group = 'ObsidianExtLinkIcon' }, + -- Replace the above with this if you don't have a patched font: + -- external_link_icon = { char = "", hl_group = "ObsidianExtLinkIcon" }, + reference_text = { hl_group = 'ObsidianRefText' }, + highlight_text = { hl_group = 'ObsidianHighlightText' }, + tags = { hl_group = 'ObsidianTag' }, + block_ids = { hl_group = 'ObsidianBlockID' }, + hl_groups = { + -- The options are passed directly to `vim.api.nvim_set_hl()`. See `:help nvim_set_hl`. + ObsidianTodo = { bold = true, fg = '#f78c6c' }, + ObsidianDone = { bold = true, fg = '#89ddff' }, + ObsidianRightArrow = { bold = true, fg = '#f78c6c' }, + ObsidianTilde = { bold = true, fg = '#ff5370' }, + ObsidianImportant = { bold = true, fg = '#d73128' }, + ObsidianBullet = { bold = true, fg = '#89ddff' }, + ObsidianRefText = { underline = true, fg = '#c792ea' }, + ObsidianExtLinkIcon = { fg = '#c792ea' }, + ObsidianTag = { italic = true, fg = '#89ddff' }, + ObsidianBlockID = { italic = true, fg = '#89ddff' }, + ObsidianHighlightText = { bg = '#75662e' }, + }, + }, + + -- Specify how to handle attachments. + attachments = { + -- The default folder to place images in via `:ObsidianPasteImg`. + -- If this is a relative path it will be interpreted as relative to the vault root. + -- You can always override this per image by passing a full path to the command instead of just a filename. + img_folder = 'assets/imgs', -- This is the default + -- A function that determines the text to insert in the note when pasting an image. + -- It takes two arguments, the `obsidian.Client` and an `obsidian.Path` to the image file. + -- This is the default implementation. + ---@param client obsidian.Client + ---@param path obsidian.Path the absolute path to the image file + ---@return string + img_text_func = function(client, path) + path = client:vault_relative_path(path) or path + return string.format('![%s](%s)', path.name, path) + end, + }, + }, + }, + { + 'sainnhe/everforest', + lazy = false, + priority = 1000, + config = function() + -- Optionally configure and load the colorscheme + -- directly inside the plugin declaration. + vim.g.everforest_transparent_background = 1 + vim.g.everforest_enable_italic = true + end, + }, +}