From 2044864857c06a0a708d9e554fd8b043ab5cec0d Mon Sep 17 00:00:00 2001 From: Ankur Kumar <18713058+sirjager@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:09:33 +0530 Subject: [PATCH 1/6] feat: added file patterns .mdx, .mdoc - added new utility file - obsidian/patterns.lua - added file extensions for: .mdx, .mdoc - more file extensions can be added via obsidian/patterns.lua --- lua/obsidian/client.lua | 12 +++++++++++- lua/obsidian/init.lua | 7 ++++--- lua/obsidian/patterns.lua | 12 ++++++++++++ lua/obsidian/search.lua | 13 ++++--------- lua/obsidian/ui.lua | 2 +- 5 files changed, 32 insertions(+), 14 deletions(-) create mode 100644 lua/obsidian/patterns.lua diff --git a/lua/obsidian/client.lua b/lua/obsidian/client.lua index 00c09c77f..9ca735b8e 100644 --- a/lua/obsidian/client.lua +++ b/lua/obsidian/client.lua @@ -189,8 +189,18 @@ end Client.path_is_note = function(self, path, workspace) path = Path.new(path):resolve() + local valid_extensions = require("obsidian.patterns").file_extensions + local is_valid = false + + for _, suffix in ipairs(valid_extensions) do + if path.suffix == suffix then + is_valid = true + break + end + end + -- Notes have to be markdown file. - if path.suffix ~= ".md" then + if not is_valid then return false end diff --git a/lua/obsidian/init.lua b/lua/obsidian/init.lua index b5e139103..11235cc0d 100644 --- a/lua/obsidian/init.lua +++ b/lua/obsidian/init.lua @@ -1,4 +1,5 @@ local log = require "obsidian.log" +local patterns = require("obsidian.patterns").file_patterns local module_lookups = { abc = "obsidian.abc", @@ -113,7 +114,7 @@ obsidian.setup = function(opts) -- Complete setup and update workspace (if needed) when entering a markdown buffer. vim.api.nvim_create_autocmd({ "BufEnter" }, { group = group, - pattern = "*.md", + pattern = patterns, callback = function(ev) -- Set the current directory of the buffer. local buf_dir = vim.fs.dirname(ev.match) @@ -166,7 +167,7 @@ obsidian.setup = function(opts) vim.api.nvim_create_autocmd({ "BufLeave" }, { group = group, - pattern = "*.md", + pattern = patterns, callback = function(ev) -- Check if we're in *any* workspace. local workspace = obsidian.Workspace.get_workspace_for_dir(vim.fs.dirname(ev.match), client.opts.workspaces) @@ -189,7 +190,7 @@ obsidian.setup = function(opts) -- Add/update frontmatter for notes before writing. vim.api.nvim_create_autocmd({ "BufWritePre" }, { group = group, - pattern = "*.md", + pattern = patterns, callback = function(ev) local buf_dir = vim.fs.dirname(ev.match) diff --git a/lua/obsidian/patterns.lua b/lua/obsidian/patterns.lua new file mode 100644 index 000000000..b2c429a08 --- /dev/null +++ b/lua/obsidian/patterns.lua @@ -0,0 +1,12 @@ +local M = {} + +-- used in obsidian/init.lua -> vim.api.nvim_create_autocmd +M.file_patterns = { "*.md", "*.mdx", "*.mdoc" } + +-- used in search.lua -> M.build_find_cmd +M.search_pattern = "*.md,*.mdx,*.mdoc" + +-- used in client.lua -> Client.path_is_note +M.file_extensions = { ".md", ".mdx", ".mdoc" } + +return M diff --git a/lua/obsidian/search.lua b/lua/obsidian/search.lua index 6b981c921..2fca209c9 100644 --- a/lua/obsidian/search.lua +++ b/lua/obsidian/search.lua @@ -392,19 +392,14 @@ end ---@return string[] M.build_find_cmd = function(path, term, opts) opts = SearchOpts.from_tbl(opts and opts or {}) - local additional_opts = {} + local pattern = require("obsidian.patterns").search_pattern + if term ~= nil then - if opts.include_non_markdown then - term = "*" .. term .. "*" - elseif not vim.endswith(term, ".md") then - term = "*" .. term .. "*.md" - else - term = "*" .. term - end + term = "*" .. term .. "*" additional_opts[#additional_opts + 1] = "-g" - additional_opts[#additional_opts + 1] = term + additional_opts[#additional_opts + 1] = pattern end if opts.ignore_case then diff --git a/lua/obsidian/ui.lua b/lua/obsidian/ui.lua index 04364dbf6..c30f15f44 100644 --- a/lua/obsidian/ui.lua +++ b/lua/obsidian/ui.lua @@ -617,7 +617,7 @@ M.setup = function(workspace, ui_opts) install_hl_groups(ui_opts) - local pattern = tostring(workspace.root) .. "/**.md" + local pattern = require("obsidian.patterns").file_patterns vim.api.nvim_create_autocmd({ "BufEnter" }, { group = group, From f7346609e550915982439a4f437d587793ef4d2f Mon Sep 17 00:00:00 2001 From: Ankur Kumar <18713058+sirjager@users.noreply.github.com> Date: Fri, 3 Jan 2025 16:40:09 +0530 Subject: [PATCH 2/6] fix: ensure term is used in search options to resolve unused variable warning (W311) --- lua/obsidian/search.lua | 1 + 1 file changed, 1 insertion(+) diff --git a/lua/obsidian/search.lua b/lua/obsidian/search.lua index 2fca209c9..dfa20333e 100644 --- a/lua/obsidian/search.lua +++ b/lua/obsidian/search.lua @@ -399,6 +399,7 @@ M.build_find_cmd = function(path, term, opts) if term ~= nil then term = "*" .. term .. "*" additional_opts[#additional_opts + 1] = "-g" + additional_opts[#additional_opts + 1] = term additional_opts[#additional_opts + 1] = pattern end From a6a74d2e911ec5269287c976545283556b3adcf0 Mon Sep 17 00:00:00 2001 From: Ankur Kumar <18713058+sirjager@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:19:35 +0530 Subject: [PATCH 3/6] chore: updated CHANGELOG.md for feat/extending-file-support --- CHANGELOG.md | 128 ++++++++++++++++++++++++++++----------------------- 1 file changed, 70 insertions(+), 58 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b585ed0e2..d7cb9085c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,10 +3,20 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) with respect to the public API, which currently includes the installation steps, dependencies, configuration, keymappings, commands, and other plugin functionality. At the moment this does *not* include the Lua `Client` API, although in the future it will once that API stabilizes. +and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html) with respect to the public API, which currently includes the installation steps, dependencies, configuration, keymappings, commands, and other plugin functionality. At the moment this does _not_ include the Lua `Client` API, although in the future it will once that API stabilizes. ## Unreleased +## Added + +- Added utility file `obsidian/pattern.lua` to extend markdown file support. + - Defined `M.file_patterns` for file pattern matching (`*.md`, `*.mdx`, `*.mdoc`). + - Defined `M.search_pattern` for search pattern support (`*.md,*.mdx,*.mdoc`). + - Defined `M.file_extensions` for file extension checking (`.md`, `.mdx`, `.mdoc`). +- Updated `lua/obsidian/client.lua` func `Client.path_is_note` to allow `file_extensions` `.md, .mdx, .mdoc` as note +- Updated `lua/obsidian/init.lua` `vim.api.nvim_create_autocmd` from `patter = "*.md"` to `file_patterns` from `obsidian/pattern.lua` +- Updated `lua/obsidian/search.lua` func `M.build_find_cmd` to properly include the term in search options. Fix for: ensure term is used in search options to resolve unused variable warning (W311) + ### Added - Added `opts.follow_img_func` option for customizing how to handle image paths. @@ -189,12 +199,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [v3.7.0](https://github.com/epwalsh/obsidian.nvim/releases/tag/v3.7.0) - 2024-03-08 There's a lot of new features and improvements here that I'm really excited about 🥳 They've improved my workflow a ton and I hope they do for you too. To highlight the 3 biggest additions: + 1. 🔗 Full support for header anchor links and block links! That means both for following links and completion of links. Various forms of anchor/block links are support. Here are a few examples: - - Typical Obsidian-style wiki links, e.g. `[[My note#Heading 1]]`, `[[My note#Heading 1#Sub heading]]`, `[[My note#^block-123]]`. - - Wiki links with a label, e.g. `[[my-note#heading-1|Heading 1 in My Note]]`. - - Markdown links, e.g. `[Heading 1 in My Note](my-note.md#heading-1)`. - We also support links to headers within the same note, like for a table of contents, e.g. `[[#Heading 1]]`, `[[#heading-1|Heading]]`, `[[#^block-1]]`. + - Typical Obsidian-style wiki links, e.g. `[[My note#Heading 1]]`, `[[My note#Heading 1#Sub heading]]`, `[[My note#^block-123]]`. + - Wiki links with a label, e.g. `[[my-note#heading-1|Heading 1 in My Note]]`. + - Markdown links, e.g. `[Heading 1 in My Note](my-note.md#heading-1)`. + + We also support links to headers within the same note, like for a table of contents, e.g. `[[#Heading 1]]`, `[[#heading-1|Heading]]`, `[[#^block-1]]`. 2. 📲 A basic callback system to let you easily customize obisidian.nvim's behavior even more. There are currently 4 events: `post_setup`, `enter_note`, `pre_write_note`, and `post_set_workspace`. You can define a function for each of these in your config. 3. 🔭 Improved picker integrations (especially for telescope), particular for the `:ObsidianTags` command. See https://github.com/epwalsh/obsidian.nvim/discussions/450 for a demo. @@ -205,44 +217,44 @@ Full changelog below 👇 - Added a configurable callback system to further customize obsidian.nvim's behavior. Callbacks are defined through the `callbacks` field in the config: - ```lua - 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, - } - ``` + ```lua + 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, + } + ``` - Added configuration option `note_path_func(spec): obsidian.Path` for customizing how file names for new notes are generated. This takes a single argument, a table that looks like `{ id: string, dir: obsidian.Path, title: string|? }`, and returns an `obsidian.Path` object. The default behavior is equivalent to this: - ```lua - ---@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) - local path = spec.dir / tostring(spec.id) - return path:with_suffix(".md") - end - ``` + ```lua + ---@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) + local path = spec.dir / tostring(spec.id) + return path:with_suffix(".md") + end + ``` - Added config option `picker.tag_mappings`, analogous to `picker.note_mappings`. - Added `log` field to `obsidian.Client` for easier access to the logger. @@ -492,7 +504,7 @@ Minor internal improvements. ### Added -- Added extmarks that conceal "-", "*", or "+" with "•" by default. This can turned off by setting `.ui.bullets` to `nil` in your config. +- Added extmarks that conceal "-", "\*", or "+" with "•" by default. This can turned off by setting `.ui.bullets` to `nil` in your config. ### Fixed @@ -548,26 +560,26 @@ Minor internal improvements. - Added Lua API methods `Client:set_workspace(workspace: obsidian.Workspace)` and `Client:switch_workspace(workspace: string|obsidian.Workspace)`. - Added the ability to override settings per workspace by providing the `overrides` field in a workspace definition. For example: - ```lua - require("obsidian").setup({ - workspaces = { - { - name = "personal", - path = "~/vaults/personal", - }, - { - name = "work", - path = "~/vaults/work", - -- Optional, override certain settings. - overrides = { - notes_subdir = "notes", - }, + ```lua + require("obsidian").setup({ + workspaces = { + { + name = "personal", + path = "~/vaults/personal", + }, + { + name = "work", + path = "~/vaults/work", + -- Optional, override certain settings. + overrides = { + notes_subdir = "notes", }, }, + }, - -- ... other options ... - }) - ``` + -- ... other options ... + }) + ``` ### Fixed From 43de44a0fb37456337913788213b213ca5a08b82 Mon Sep 17 00:00:00 2001 From: Ankur Kumar <18713058+sirjager@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:42:48 +0530 Subject: [PATCH 4/6] chore: removed unnecessary use of term --- lua/obsidian/search.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/lua/obsidian/search.lua b/lua/obsidian/search.lua index dfa20333e..2fca209c9 100644 --- a/lua/obsidian/search.lua +++ b/lua/obsidian/search.lua @@ -399,7 +399,6 @@ M.build_find_cmd = function(path, term, opts) if term ~= nil then term = "*" .. term .. "*" additional_opts[#additional_opts + 1] = "-g" - additional_opts[#additional_opts + 1] = term additional_opts[#additional_opts + 1] = pattern end From 4dd4caaa114023e0345ffa28ca8d94d12ba3d095 Mon Sep 17 00:00:00 2001 From: Ankur Kumar <18713058+sirjager@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:43:58 +0530 Subject: [PATCH 5/6] chore: updated CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d7cb9085c..c31d69ce1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,7 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Defined `M.file_extensions` for file extension checking (`.md`, `.mdx`, `.mdoc`). - Updated `lua/obsidian/client.lua` func `Client.path_is_note` to allow `file_extensions` `.md, .mdx, .mdoc` as note - Updated `lua/obsidian/init.lua` `vim.api.nvim_create_autocmd` from `patter = "*.md"` to `file_patterns` from `obsidian/pattern.lua` -- Updated `lua/obsidian/search.lua` func `M.build_find_cmd` to properly include the term in search options. Fix for: ensure term is used in search options to resolve unused variable warning (W311) +- Updated `lua/obsidian/search.lua` func `M.build_find_cmd` to properly include the search pattern ### Added From 163ce4613967737c33af60b1f16b324ebc85649b Mon Sep 17 00:00:00 2001 From: Ankur Kumar <18713058+sirjager@users.noreply.github.com> Date: Fri, 3 Jan 2025 17:55:38 +0530 Subject: [PATCH 6/6] fix: updated search.lua/build_find_cmd to extend support for md,mdx,mdoc --- lua/obsidian/search.lua | 26 ++++++++++++++++++++++---- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/lua/obsidian/search.lua b/lua/obsidian/search.lua index 2fca209c9..7b294c2df 100644 --- a/lua/obsidian/search.lua +++ b/lua/obsidian/search.lua @@ -392,14 +392,32 @@ end ---@return string[] M.build_find_cmd = function(path, term, opts) opts = SearchOpts.from_tbl(opts and opts or {}) - local additional_opts = {} - local pattern = require("obsidian.patterns").search_pattern + local additional_opts = {} if term ~= nil then - term = "*" .. term .. "*" + local valid_extensions = require("obsidian.patterns").file_extensions + if opts.include_non_markdown then + term = "*" .. term .. "*" + else + -- Check if term does not already have a valid extension + local has_valid_extension = false + for _, ext in ipairs(valid_extensions) do + if vim.endswith(term, ext) then + has_valid_extension = true + break + end + end + + if not has_valid_extension then + term = "*" .. term .. table.concat(valid_extensions, ",*") -- Match all valid extensions + else + term = "*" .. term + end + end + additional_opts[#additional_opts + 1] = "-g" - additional_opts[#additional_opts + 1] = pattern + additional_opts[#additional_opts + 1] = term end if opts.ignore_case then