From af607b992ec23c097b9fb51c73fbd3e0d313c8a9 Mon Sep 17 00:00:00 2001 From: Archie Fox Date: Fri, 15 Aug 2025 02:02:47 +0300 Subject: [PATCH] Add settings for Neorg and keybinds --- init.lua | 1 + lua/config/keymaps.lua | 4 + lua/config/obsidian.lua | 317 +++++++++++++++++++++++++++++++++++++++ lua/plugins/disabled.lua | 2 +- lua/plugins/init.lua | 1 + lua/plugins/neorg.lua | 10 +- lua/plugins/nvim-cmp.lua | 141 ++++++++--------- lua/plugins/obsidian.lua | 35 ----- 8 files changed, 403 insertions(+), 108 deletions(-) create mode 100644 lua/config/obsidian.lua diff --git a/init.lua b/init.lua index fb47285..b05cd81 100644 --- a/init.lua +++ b/init.lua @@ -3,5 +3,6 @@ require("config.lazy") require("config.luasnip") require("config.hyprls") require("config.bufferline") +require("config.obsidian") require("colorizer").setup() diff --git a/lua/config/keymaps.lua b/lua/config/keymaps.lua index 793229f..26fc8e3 100644 --- a/lua/config/keymaps.lua +++ b/lua/config/keymaps.lua @@ -63,3 +63,7 @@ vim.keymap.set("n", "G", function() local line_count = vim.api.nvim_buf_line_count(0) vim.api.nvim_win_set_cursor(0, { line_count, 0 }) end, { desc = "Go to last line" }) + +k.set("n", "\\", "(neorg.qol.todo-items.todo.task-cycle)", { desc = "Cycle done-undone task in Neorg" }) +k.set("n", "\\jt", ":Neorg journal today", { desc = "Create Neorg Journal note today" }) +k.set("n", "\\jc", ":Neorg journal custom", { desc = "Create Neorg Journal note custom" }) diff --git a/lua/config/obsidian.lua b/lua/config/obsidian.lua new file mode 100644 index 0000000..4f20636 --- /dev/null +++ b/lua/config/obsidian.lua @@ -0,0 +1,317 @@ +require("obsidian").setup({ + -- A list of workspace names, paths, and configuration overrides. + -- If you use the Obsidian app, the 'path' of a workspace should generally be + -- your vault root (where the `.obsidian` folder is located). + -- When obsidian.nvim is loaded by your plugin manager, it will automatically set + -- the workspace to the first workspace in the list whose `path` is a parent of the + -- current markdown file being edited. + workspaces = { + { + name = "default", + path = "~/Share/Obsidian/default", + }, + }, + + -- Alternatively - and for backwards compatibility - you can set 'dir' to a single path instead of + -- 'workspaces'. For example: + -- dir = "~/vaults/work", + + -- Optional, if you keep notes in a specific subdirectory of your vault. + notes_subdir = "Daily", + + -- Optional, set the log level for obsidian.nvim. This is an integer corresponding to one of the log + -- levels defined by "vim.log.levels.*". + log_level = vim.log.levels.INFO, + + daily_notes = { + -- Optional, if you keep daily notes in a separate directory. + folder = "Inbox", + -- Optional, if you want to change the date format for the ID of daily notes. + date_format = "%Y-%m-%d", + -- Optional, if you want to change the date format of the default alias of daily notes. + alias_format = "%B %-d, %Y", + -- Optional, default tags to add to each new daily note created. + default_tags = { "daily-notes" }, + -- Optional, if you want to automatically insert a template from your template directory like 'daily.md' + template = nil, + }, + + -- Optional, completion of wiki links, local markdown links, and tags using nvim-cmp. + completion = { + -- Set to false to disable completion. + nvim_cmp = true, + -- Trigger completion at 2 chars. + min_chars = 2, + }, + + -- Optional, configure key mappings. These are the defaults. If you don't want to set any keymappings this + -- way then set 'mappings = {}'. + 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 }, + }, + }, + + -- Where to put new notes. Valid options are + -- * "current_dir" - put new notes in same directory as the current buffer. + -- * "notes_subdir" - put new notes in the default notes subdirectory. + new_notes_location = "Inbox", + + -- 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, 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 = "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 + -- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows + -- vim.ui.open(url) -- need Neovim 0.10.0+ + end, + + -- Optional, by default when you use `:ObsidianFollowLink` on a link to an image + -- file it will be ignored but you can customize this behavior here. + ---@param img string + follow_img_func = function(img) + vim.fn.jobstart({ "qlmanage", "-p", img }) -- Mac OS quick look preview + -- vim.fn.jobstart({"xdg-open", url}) -- linux + -- vim.cmd(':silent exec "!start ' .. url .. '"') -- Windows + 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. + note_mappings = { + -- Create a new note from your query. + new = "", + -- Insert a link to the selected note. + insert_link = "", + }, + tag_mappings = { + -- Add tag(s) to current note. + tag_note = "", + -- Insert a tag at the current location. + insert_tag = "", + }, + }, + + -- 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 = true, -- 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 + + -- Optional, customize the default name or prefix when pasting images via `:ObsidianPasteImg`. + ---@return string + img_name_func = function() + -- Prefix image names with timestamp. + return string.format("%s-", os.time()) + end, + + -- 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, + }, +}) diff --git a/lua/plugins/disabled.lua b/lua/plugins/disabled.lua index ad86440..908565b 100644 --- a/lua/plugins/disabled.lua +++ b/lua/plugins/disabled.lua @@ -1,6 +1,6 @@ return { -- disable trouble { "akinsho/bufferline.nvim", enabled = true }, - { "hrsh7th/nvim-cmp", enabled = false }, + { "hrsh7th/nvim-cmp", enabled = true }, { "folke/snacks.nvim", enabled = true }, } diff --git a/lua/plugins/init.lua b/lua/plugins/init.lua index 90d3378..296f361 100644 --- a/lua/plugins/init.lua +++ b/lua/plugins/init.lua @@ -1,3 +1,4 @@ return { { "norcalli/nvim-colorizer.lua" }, + { "onsails/lspkind.nvim" }, } diff --git a/lua/plugins/neorg.lua b/lua/plugins/neorg.lua index 7c0800d..5282de8 100644 --- a/lua/plugins/neorg.lua +++ b/lua/plugins/neorg.lua @@ -17,12 +17,18 @@ return { ["core.dirman"] = { config = { workspaces = { - default = "~/Share/notes/default", - journal = "~/Share/notes/journal", + default = "~/Share/Notes", + journal = "~/Share/Notes/journal", }, default_workspace = "default", }, }, + ["core.qol.todo_items"] = { + config = { + create_todo_items = true, + create_todo_parents = true, + }, + }, }, }) end, diff --git a/lua/plugins/nvim-cmp.lua b/lua/plugins/nvim-cmp.lua index 740c7b6..d7a66cd 100644 --- a/lua/plugins/nvim-cmp.lua +++ b/lua/plugins/nvim-cmp.lua @@ -1,3 +1,4 @@ +local lspkind = require("lspkind") return { "hrsh7th/nvim-cmp", version = false, -- last release is way too old @@ -18,7 +19,7 @@ return { vim.api.nvim_set_hl(0, "CmpGhostText", { link = "Comment", default = true }) local cmp = require("cmp") local defaults = require("cmp.config.default")() - local lspkind = require("lspkind") + -- local lspkind = require("lspkind") -- Проверяем наличие luasnip local has_luasnip = pcall(require, "luasnip") @@ -196,79 +197,79 @@ return { } -- Добавляем luasnip только если он доступен - if has_luasnip then - table.insert(go_sources, 2, { name = "luasnip", priority = 750 }) - end - - cmp.setup.filetype("go", { - sources = cmp.config.sources(go_sources, { - { name = "buffer", priority = 500, keyword_length = 2 }, -- Меньше символов для Go - { name = "path", priority = 400 }, - }), - formatting = { - format = lspkind.cmp_format({ - mode = "symbol_text", - maxwidth = 60, -- Больше места для Go типов - ellipsis_char = "...", - before = function(entry, vim_item) - if entry.source.name == "nvim_lsp" then - local completion_item = entry.completion_item - if completion_item.detail then - local detail = completion_item.detail - -- Специальная обработка Go типов - if string.match(detail, "^func") then - vim_item.menu = "[func] " .. detail:sub(1, 40) - elseif string.match(detail, "^type") then - vim_item.menu = "[type] " .. detail:sub(1, 40) - elseif string.match(detail, "^var") then - vim_item.menu = "[var] " .. detail:sub(1, 40) - elseif string.match(detail, "^const") then - vim_item.menu = "[const] " .. detail:sub(1, 40) - else - vim_item.menu = detail:sub(1, 50) - end - else - vim_item.menu = "[LSP]" - end - else - vim_item.menu = ({ - luasnip = "[Snippet]", - buffer = "[Buffer]", - path = "[Path]", - nvim_lsp_signature_help = "[Signature]", - })[entry.source.name] or "[Unknown]" - end - return vim_item - end, - }), - }, - matching = { - disallow_fuzzy_matching = false, - disallow_fullfuzzy_matching = false, - disallow_partial_fuzzy_matching = false, -- Разрешаем для Go - disallow_partial_matching = false, - disallow_prefix_unmatching = false, - }, - }) + -- if has_luasnip then + -- table.insert(go_sources, 2, { name = "luasnip", priority = 750 }) + -- end + -- + -- cmp.setup.filetype("go", { + -- sources = cmp.config.sources(go_sources, { + -- { name = "buffer", priority = 500, keyword_length = 2 }, -- Меньше символов для Go + -- { name = "path", priority = 400 }, + -- }), + -- formatting = { + -- format = lspkind.cmp_format({ + -- mode = "symbol_text", + -- maxwidth = 60, -- Больше места для Go типов + -- ellipsis_char = "...", + -- before = function(entry, vim_item) + -- if entry.source.name == "nvim_lsp" then + -- local completion_item = entry.completion_item + -- if completion_item.detail then + -- local detail = completion_item.detail + -- -- Специальная обработка Go типов + -- if string.match(detail, "^func") then + -- vim_item.menu = "[func] " .. detail:sub(1, 40) + -- elseif string.match(detail, "^type") then + -- vim_item.menu = "[type] " .. detail:sub(1, 40) + -- elseif string.match(detail, "^var") then + -- vim_item.menu = "[var] " .. detail:sub(1, 40) + -- elseif string.match(detail, "^const") then + -- vim_item.menu = "[const] " .. detail:sub(1, 40) + -- else + -- vim_item.menu = detail:sub(1, 50) + -- end + -- else + -- vim_item.menu = "[LSP]" + -- end + -- else + -- vim_item.menu = ({ + -- luasnip = "[Snippet]", + -- buffer = "[Buffer]", + -- path = "[Path]", + -- nvim_lsp_signature_help = "[Signature]", + -- })[entry.source.name] or "[Unknown]" + -- end + -- return vim_item + -- end, + -- }), + -- }, + -- matching = { + -- disallow_fuzzy_matching = false, + -- disallow_fullfuzzy_matching = false, + -- disallow_partial_fuzzy_matching = true, -- Разрешаем для Go + -- disallow_partial_matching = false, + -- disallow_prefix_unmatching = false, + -- }, + -- }) -- Use buffer source for `/` and `?` (if you enabled `native_menu`, this won't work anymore). - cmp.setup.cmdline({ "/", "?" }, { - mapping = cmp.mapping.preset.cmdline(), - sources = { - { name = "buffer" }, - }, - }) + -- cmp.setup.cmdline({ "/", "?" }, { + -- mapping = cmp.mapping.preset.cmdline(), + -- sources = { + -- { name = "buffer" }, + -- }, + -- }) -- Use cmdline & path source for ':' (if you enabled `native_menu`, this won't work anymore). - cmp.setup.cmdline(":", { - mapping = cmp.mapping.preset.cmdline(), - sources = cmp.config.sources({ - { name = "path" }, - }, { - { name = "cmdline" }, - }), - matching = { disallow_symbol_nonprefix_matching = false }, - }) + -- cmp.setup.cmdline(":", { + -- mapping = cmp.mapping.preset.cmdline(), + -- sources = cmp.config.sources({ + -- { name = "path" }, + -- }, { + -- { name = "cmdline" }, + -- }), + -- matching = { disallow_symbol_nonprefix_matching = false }, + -- }) -- Auto-pairs integration (проверяем наличие плагина) local has_autopairs, cmp_autopairs = pcall(require, "nvim-autopairs.completion.cmp") diff --git a/lua/plugins/obsidian.lua b/lua/plugins/obsidian.lua index d762762..e93c03c 100644 --- a/lua/plugins/obsidian.lua +++ b/lua/plugins/obsidian.lua @@ -7,39 +7,4 @@ return { "L3MON4D3/LuaSnip", "nvim-lua/plenary.nvim", }, - config = function() - -- ваша конфигурация - vim.opt_local.spell = false - end, - opts = { - workspaces = { - { - name = "personal", - path = "~/Share/Obsidian/default", - }, - }, - - -- Настройка создания новых заметок - note_id_func = function(title) - return title - end, - - -- Настройка ссылок - wiki_link_func = function(opts) - return require("obsidian.util").wiki_link_id_prefix(opts) - end, - - -- Настройка шаблонов - templates = { - subdir = "Templates", - date_format = "%Y-%m-%d", - time_format = "%H:%M", - }, - - -- Автодополнение - completion = { - nvim_cmp = false, - min_chars = 2, - }, - }, }