-
-
Notifications
You must be signed in to change notification settings - Fork 164
fix: respect Obsidian 'New link format' setting when appending links #958
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
- Pass active file path to generateMarkdownLink instead of empty string - Add warning when no active file and requireActiveFile is true - Fixes #363
- Add insertFileLinkToActiveView helper in utilityObsidian.ts - Eliminates code duplication across CaptureChoiceEngine and TemplateChoiceEngine - Centralizes link generation with proper source path handling
The latest updates on your projects. Learn more about Vercel for GitHub.
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 1 potential issue that should be addressed.
- Throw error instead of logging warning when no active file exists and requireActiveFile is true - Maintains existing failure semantics that callers depend on - Ensures users get explicit feedback when append-link action fails
- Override getCurrentFileLink() in CaptureChoiceFormatter to use destination file path - Ensures relative links work correctly across different folders - Reverts completeFormatter.ts to original behavior (empty string) - Example: Active file Projects/Idea.md captured to Journal/Inbox.md now generates [[Projects/Idea]] instead of [[Idea]]
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
- Change fallback from currentFile.path to empty string when this.file is null - First format pass (formatContentOnly) happens before this.file is set - Empty string produces vault-absolute path, which is correct for first pass - Second pass (formatContentWithFile) sets this.file and generates proper relative link
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 1 potential issue that should be addressed.
- Add setDestinationFile() method to CaptureChoiceFormatter - Call setDestinationFile() in CaptureChoiceEngine before formatContentOnly() - Ensures {{LINKCURRENT}} has correct context in first pass for proper relative links - Prevents double processing by having the right context from the start
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 1 potential issue that should be addressed.
- Add sourcePath property to CaptureChoiceFormatter for pre-file-creation context - Update getCurrentFileLink to prefer sourcePath over file.path - Call setDestinationSourcePath before formatContentOnly in new file flow - Fix insertFileLinkToActiveView to return false (not throw) when no active file and requireActiveFile is false - Fix newLine placement to check line.length === 0 instead of endsWith('\n') - Ensures proper relative links even when destination file doesn't exist yet
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
Comment 1: Clear this.file when setting sourcePath to prevent stale values from previous captures Comment 2: Check for MarkdownView availability before insertion to ensure accurate return value - Pass requireActiveView: false to insertLinkWithPlacement since we've already validated the view exists
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
- Add sourcePath override option to FileSuggester constructor - Update getSuggestions and getRelativePathSuggestions to use source context - Add getLinkSourcePath() protected method to formatters - CaptureChoiceFormatter overrides to return destination path - Add PromptWithContext static method to GenericInputPrompt - CompleteFormatter uses PromptWithContext when prompting for field values - Ensures links inserted via [[ suggester are relative to capture destination, not active file - Fixes issue where links were relative to wrong folder during captures
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 1 potential issue that should be addressed.
- Add PromptWithContext to GenericWideInputPrompt (matching GenericInputPrompt) - Update promptForValue to use PromptWithContext when linkSourcePath is available - Ensures file suggester during capture input uses destination path for relative links - Fixes issue where [[file]] inserted during capture was not relative to destination
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
- Add getSourceFolder() helper that extracts folder from path string - Use source folder for search context even when destination file doesn't exist yet - Handle relative path navigation (../) using string manipulation - Ensures suggester context matches link generation context during new file captures - Fixes inconsistent behavior where suggestions used active file folder but links used destination folder
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
- Add normalizeFolderPath() to handle / vs empty string and trailing slashes consistently - Use fileManager.getNewFileParent() instead of manual string parsing - Add resolveRelative() to handle multiple ../ segments correctly - Clear currentFile bias when sourcePathOverride is set to avoid unrelated heading/block suggestions - Normalize folder paths in attachment suggestions and filters - Fixes edge cases: root folder, nested relative paths, non-existent destination folders
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found 1 potential issue that should be addressed.
- Stop processing ../ when already at root folder (empty string) - Preserve ../ in query instead of silently stripping it - User gets no results, making it clear they can't navigate above root - More predictable and easier to understand behavior
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
✅ No issues found in the current changes.
# [2.6.0](2.5.0...2.6.0) (2025-10-16) ### Bug Fixes * correct broken documentation link ([#948](#948)) ([1ac3f2b](1ac3f2b)) * improve AI model parameter handling and validation ([#949](#949)) ([dbc74a7](dbc74a7)), closes [#674](#674) * initialize user script default values before execution ([#956](#956)) ([3017875](3017875)), closes [#262](#262) * keep custom suggestions last ([#965](#965)) ([3ca5eef](3ca5eef)) * nested choice reordering not persisting ([#953](#953)) ([acee380](acee380)), closes [#142](#142) * respect macro member access ([#963](#963)) ([a0b77fe](a0b77fe)) * respect Obsidian 'New link format' setting when appending links ([#958](#958)) ([9368ef0](9368ef0)), closes [#363](#363) * respect Obsidian's default location for new notes ([#951](#951)) ([c096a2d](c096a2d)), closes [#613](#613) * restore TITLE behavior when FIELD:title is used ([#967](#967)) ([d89bc7d](d89bc7d)), closes [#966](#966) * standardize multi-line input font size across themes ([#955](#955)) ([bda1dad](bda1dad)), closes [#270](#270) ### Features * add {{FILENAMECURRENT}} format syntax ([#954](#954)) ([f66ada5](f66ada5)), closes [#499](#499) * add |custom modifier for VALUE syntax to allow custom input ([207b0ba](207b0ba)), closes [#461](#461) * add conditional macro command support ([#959](#959)) ([4e0fc1e](4e0fc1e)) * add toggle for input cancellation notices ([aeb0002](aeb0002)) * improved input validation and autocomplete with full-width layouts ([0b66d43](0b66d43)), closes [#625](#625) * package export/import workflow ([#97](#97)) ([#961](#961)) ([80da44b](80da44b)) * pre-populate default values in input fields ([db76b9d](db76b9d))
🎉 This PR is included in version 2.6.0 🎉 The release is available on GitHub release Your semantic-release bot 📦🚀 |
Description
Fixes #363
QuickAdd now properly respects Obsidian's "New link format" setting (relative/shortest/markdown vs wiki) when appending links and generating links in all contexts, including during user input via file suggester.
Root Cause
The issue was caused by passing an empty string or incorrect context as the
sourcePath
parameter togenerateMarkdownLink()
:When
sourcePath
is empty or incorrect, Obsidian cannot calculate the relative path between source and target files, so it defaults to generating vault-absolute paths instead of respecting the user's configured link format.Changes
Core Link Generation Fixes
Created reusable link insertion utility (
insertFileLinkToActiveView
)requireActiveFile
option with correct error semanticsfalse
gracefully when optional and no view availableutilityObsidian.ts
Fixed append-link in Capture and Template engines
generateMarkdownLink()
Fixed
{{LINKCURRENT}}
in capturesgetCurrentFileLink()
inCaptureChoiceFormatter
sourcePath
property to track destination before file creationsetDestinationFile()
andsetDestinationSourcePath()
methodsthis.file
when settingsourcePath
to prevent stale state from previous capturesFixed file suggester link generation (comprehensive refactor)
sourcePath
parameter toFileSuggester
constructornormalizeFolderPath()
helper to handle"/"
vs""
and trailing slashes consistentlyfileManager.getNewFileParent()
instead of manual string parsing for robust path handlingresolveRelative()
helper for multi-level../
navigationgetSuggestions()
to use source folder context even when file doesn't existcurrentFile
bias when using override to avoid unrelated heading/block suggestionsgetRelativePathSuggestions()
to handle multiple../
segments correctlyPromptWithContext
static methods toGenericInputPrompt
andGenericWideInputPrompt
[[
link insertion uses correct relative paths during capturesEdge Case Handling
Prevented stale state contamination
this.file
when settingsourcePath
to avoid previous capture valuesFixed newLine placement
line.length === 0
instead ofendsWith('\n')
Improved error handling
false
instead of throwing whenrequireActiveFile
is falserequireActiveFile
is trueRobust path handling in file suggester
../../
)Implementation Details
Architecture
sourcePath
override via options objectfileManager.getNewFileParent()
for robust folder derivationsourcePath
propertygetLinkSourcePath()
for prompt contextgetLinkSourcePath()
protected method (returns null by default)PromptWithContext
when source path is availablePromptWithContext()
static methodslinkSourcePath
toFileSuggester
constructorinsertFileLinkToActiveView()
utility functionFlow for Captures
setDestinationFile(file)
before first format passsetDestinationSourcePath(filePath)
before first format pass, clearsthis.file
sourcePath
to prompts viaPromptWithContext()
sourcePath
in constructor optionsgetNewFileParent()
(works even if file doesn't exist)getSourcePath()
Path Normalization Strategy
"/"
to""
getNewFileParent
) instead of manual parsing../
handled with safe bounds checkingTesting
bun run build-with-lint
Manual Testing Scenarios
Link format settings
Capture scenarios
{{LINKCURRENT}}
in captures → links to active file from destination context{{VALUE}}
prompt → file suggester uses destination contextFile suggester relative paths
./
shows files in destination folder../
navigates up one level from destination../../
navigates up two levels (multi-level support)Edge cases
requireActiveFile: true
→ throws errorrequireActiveFile: false
→ skips link insertionCross-folder captures
Projects/ClientA/file.md
Journal/Inbox.md
Resources/Templates/Meeting.md
[[../Resources/Templates/Meeting]]
(relative to destination)Resources/
when typing../Res
New file creation flow
Projects/Ideas/Brainstorm.md
Daily/2025-01-15.md
(doesn't exist)Daily/
folder (notProjects/Ideas/
)../Resources/...
navigation works correctlyDaily/
, not active fileImpact
{{LINKCURRENT}}
in captures now generates proper relative links to active file../
) works consistently with multi-level supportFiles Changed
src/utilityObsidian.ts
- Added link insertion utility and fixed newLine behaviorsrc/engine/CaptureChoiceEngine.ts
- Set destination before formatting, use utilitysrc/engine/TemplateChoiceEngine.ts
- Use link insertion utilitysrc/formatters/captureChoiceFormatter.ts
- Track destination path, override link generation, provide context to promptssrc/formatters/completeFormatter.ts
- Add link source path support, use context in promptssrc/gui/suggesters/fileSuggester.ts
- Accept source path override, robust path handling, normalizationsrc/gui/GenericInputPrompt/GenericInputPrompt.ts
- Add PromptWithContext methodsrc/gui/GenericWideInputPrompt/GenericWideInputPrompt.ts
- Add PromptWithContext method