obsidian

package
v0.0.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 5, 2026 License: MIT Imports: 18 Imported by: 0

Documentation

Index

Constants

View Source
const (
	ExecuteUriError                    = "Failed to execute Obsidian URI"
	NoteDoesNotExistError              = "Cannot find note in vault"
	VaultAccessError                   = "Failed to access vault directory"
	VaultReadError                     = "Failed to read notes in vault"
	VaultWriteError                    = "Failed to write to update notes in vault"
	ObsidianCLIConfigReadError         = "Cannot find vault config, please use set-default-vault command to set default vault or use --vault flag"
	ObsidianCLIConfigParseError        = "Could not parse vault config file, please use set-default-vault command to set default vault or use --vault flag"
	ObsidianCLIConfigDirWriteEror      = "Failed to create vault config directory. Please ensure you have the correct permissions."
	ObsidianCLIConfigGenerateJSONError = "Failed to generate vault config file. Please ensure vault name does not contain any special characters."
	ObsidianCLIConfigWriteError        = "Failed to write vault config file. Please ensure you have correct permissions."
	ObsidianConfigReadError            = "Failed to read Obsidian config file. Please ensure vault has been set up in Obsidian."
	ObsidianConfigParseError           = "Failed to parse Obsidian config file. Please ensure vault has been set up in Obsidian."
	ObsidianConfigVaultNotFoundError   = "Vault not found in Obsidian config file. Please ensure vault has been set up in Obsidian."
)

项目中所有错误提示消息的常量定义,集中管理方便统一修改和国际化。

Variables

View Source
var CliConfigPath = config.CliPath

CliConfigPath 和 JsonMarshal 是包级变量,指向 config 包和 json 包的函数。 使用变量方便测试中替换为 Mock 实现。

View Source
var ErrPathTraversal = errors.New("path traversal detected: path must remain within vault directory")

ErrPathTraversal 当路径试图逃逸出基础目录时返回此错误。

View Source
var JsonMarshal = json.Marshal
View Source
var ObsidianConfigFile = config.ObsidianFile

ObsidianConfigFile 和 RunningInWSL 是包级变量,分别指向 config 包中的对应函数。 使用变量而非直接调用函数,方便在测试中替换为 Mock 实现。

View Source
var Run = open.Run

Run 是一个包级变量,指向 open.Run 函数。 在测试中可以通过替换此变量来避免真正唤起外部程序。

View Source
var RunningInWSL = config.RunningInWSL

Functions

func AddMdSuffix

func AddMdSuffix(str string) string

AddMdSuffix 为没有 .md 后缀的字符串追加 .md。 这是为了保证用户输入的笔记名最终都对应到 Markdown 文件。

func AddVault

func AddVault(vaultPath string) (string, error)

AddVault 将本地目录注册为 Obsidian vault。 如果 Obsidian 的配置文件不存在,会自动创建。 返回解析后的绝对路径。

func ApplyDefaultFolder

func ApplyDefaultFolder(noteName, vaultPath string) string

ApplyDefaultFolder 在 noteName 没有显式路径(不含 "/")时, 自动在前面加上 Obsidian 配置的新笔记默认文件夹。 如果 noteName 已包含 "/" 或未配置默认文件夹,则原样返回。

func ClearDefaultIfMatch

func ClearDefaultIfMatch(name string) error

ClearDefaultIfMatch 如果被移除的 vault 名称恰好是当前默认 vault,则清除默认设置。

func DefaultNoteFolder

func DefaultNoteFolder(vaultPath string) string

DefaultNoteFolder 读取 vault 中配置的新笔记默认存放文件夹。 如果未配置或读取失败,返回空字符串(调用方应回退到 vault 根目录)。

func ExcludedPaths

func ExcludedPaths(vaultPath string) []string

ExcludedPaths 读取 vault 中 .obsidian/app.json 的 userIgnoreFilters, 返回需要排除的路径模式列表。如果配置文件不存在或读取失败,返回 nil。

func GenerateBacklinkSearchPatterns

func GenerateBacklinkSearchPatterns(notePath string) []string

GenerateBacklinkSearchPatterns 创建用于查找反向链接的搜索模式列表。 包括基于 basename 的 wikilink、基于完整路径的 wikilink,以及多种 Markdown 链接格式。

func GenerateLinkReplacements

func GenerateLinkReplacements(oldNotePath, newNotePath string) map[string]string

GenerateLinkReplacements 创建移动笔记时需要替换的链接映射表。 它会处理各种 Obsidian 链接格式:简单 wikilink、路径 wikilink、Markdown 链接。 所有路径都会被归一化为正斜杠,以保证跨平台一致。

func GenerateNoteLinkTexts

func GenerateNoteLinkTexts(noteName string) [3]string

GenerateNoteLinkTexts 生成指向某篇笔记的 wikilink 模式数组。 它会先取笔记名的 basename 并去掉 .md 后缀。

func IsExcluded

func IsExcluded(relPath string, filters []string) bool

IsExcluded 判断 relPath(相对于 vault 根目录的正斜杠路径)是否匹配任何排除规则。 支持的规则类型:

  • 纯路径前缀:"Archive"、"Templates/"
  • 通配符:"*.pdf"
  • 双星号:**/drafts(匹配任意深度)

func ListEntries

func ListEntries(vaultPath, relativePath string) ([]string, error)

ListEntries 列出 vault 中指定路径下的所有文件和文件夹。 返回的目录名以 "/" 结尾,文件夹在前、文件在后,且各自按字母顺序排序。

func MomentToGoFormat

func MomentToGoFormat(momentFmt string) string

MomentToGoFormat 将 Moment.js 日期格式字符串转换为 Go 的 time.Layout 格式。 采用两遍替换策略:先用唯一占位符替换 Moment 标记,避免级联替换错误 (例如将 "January" 中的 "a" 错误替换为 "pm")。

注意:Moment.js 的 "dd" 标记(两位星期缩写,如 "Mo")在 Go 中没有对应物,不支持。

func OpenInEditor

func OpenInEditor(filePath string) error

OpenInEditor 使用用户偏好的编辑器打开指定文件。 支持常见 GUI 编辑器(VS Code、Sublime、Atom 等)的自动 --wait 等待标志, 也支持 EEDITOR 环境变量中包含参数的情况(如 "code -w")。

func RemoveMdSuffix

func RemoveMdSuffix(str string) string

RemoveMdSuffix 移除字符串末尾的 .md 后缀(如果存在)。

func RemoveVault

func RemoveVault(input string) (string, error)

RemoveVault 从 Obsidian 配置中注销一个 vault。 支持通过名称或完整路径指定。如果通过名称匹配到多个 vault,会报错提示用户使用完整路径。 返回被移除 vault 的名称(目录 basename),方便调用方做后续清理(如清除默认设置)。

func ReplaceContent

func ReplaceContent(content []byte, replacements map[string]string) []byte

ReplaceContent 批量替换 content 中的字符串,使用 replacements map 中的键值对。

func ResolveVaultName

func ResolveVaultName(input string) (string, error)

ResolveVaultName 将用户输入的名称或路径解析为已注册的 vault 名称。 如果输入的是名称且匹配到多个 vault,会返回歧义错误并提示用户使用完整路径。

func ShouldSkipDirectoryOrFile

func ShouldSkipDirectoryOrFile(info os.FileInfo) bool

ShouldSkipDirectoryOrFile 判断文件/目录是否应该被跳过(不处理)。 跳过条件:是目录、是隐藏文件(以 . 开头)、不是 .md 文件。

func ValidatePath

func ValidatePath(basePath, relativePath string) (string, error)

ValidatePath 确保 relativePath 与 basePath 拼接后仍位于 basePath 内部。 返回清理后的绝对路径;如果路径试图逃逸出基础目录,返回 ErrPathTraversal。

安全检查步骤:

  1. 拒绝绝对路径(防止直接传入 /etc/passwd)
  2. 清理并拼接路径
  3. 验证结果路径是否以 basePath 为前缀

Types

type CliConfig

type CliConfig struct {
	DefaultVaultName string `json:"default_vault_name"`          // 默认 vault 名称
	DefaultOpenType  string `json:"default_open_type,omitempty"` // 默认打开方式:obsidian 或 editor
}

CliConfig 是 CLI 自身配置文件的 JSON 结构。 保存在 ~/.config/obs-cli/preferences.json 中。

type DailyNotesConfig

type DailyNotesConfig struct {
	Folder   string `json:"folder"`   // 日记存放文件夹
	Format   string `json:"format"`   // 日期格式(Moment.js 风格)
	Template string `json:"template"` // 模板笔记路径
}

DailyNotesConfig 对应 vault 中 .obsidian/daily-notes.json 的结构。 保存 Daily Notes 插件的文件夹、日期格式和模板配置。

func ReadDailyNotesConfig

func ReadDailyNotesConfig(vaultPath string) DailyNotesConfig

ReadDailyNotesConfig 读取 vault 中 Daily Notes 插件的配置。 如果配置文件不存在或读取失败,返回零值结构体。

type FuzzyFinder

type FuzzyFinder struct{}

FuzzyFinder 是 FuzzyFinderManager 的具体实现,封装了 go-fuzzyfinder 库。

func (*FuzzyFinder) Find

func (f *FuzzyFinder) Find(slice interface{}, itemFunc func(i int) string, opts ...interface{}) (int, error)

Find 启动终端模糊搜索界面。 接收字符串切片和显示函数,返回用户选中项的索引。 如果用户取消选择或传入类型不正确,返回错误。

type FuzzyFinderManager

type FuzzyFinderManager interface {
	Find(slice interface{}, itemFunc func(i int) string, opts ...interface{}) (int, error)
}

FuzzyFinderManager 定义了模糊搜索交互界面的接口。

type Note

type Note struct{}

Note 是 NoteManager 的具体实现,提供笔记的增删改查和链接管理能力。 使用空结构体是因为方法不依赖内部状态,仅作为方法接收者的载体。

func (*Note) Delete

func (m *Note) Delete(path string) error

Delete 删除指定路径的笔记,会自动补充 .md 后缀。

func (m *Note) FindBacklinks(vaultPath, noteName string) ([]NoteMatch, error)

FindBacklinks 查找 vault 中所有引用指定笔记的反向链接。 结果按文件修改时间降序排列(最新的在前)。

func (*Note) GetContents

func (m *Note) GetContents(vaultPath string, noteName string) (string, error)

GetContents 读取 vault 中指定笔记的完整文本内容。 搜索策略:先尝试完整相对路径匹配,再回退到 basename 匹配(向后兼容)。

func (*Note) GetNotesList

func (m *Note) GetNotesList(vaultPath string) ([]string, error)

GetNotesList 获取 vault 中所有 .md 笔记的相对路径列表。 会自动跳过隐藏目录和用户配置的排除路径。

func (*Note) Move

func (m *Note) Move(originalPath string, newPath string) error

Move 将笔记从原路径移动到新路径,会自动补充 .md 后缀。

func (*Note) SearchNotesWithSnippets

func (m *Note) SearchNotesWithSnippets(vaultPath string, query string) ([]NoteMatch, error)

SearchNotesWithSnippets 在 vault 中搜索包含 query 的笔记。 同时搜索文件名和文件内容,返回匹配片段列表。 为避免内存问题,大于 10MB 的文件会被跳过。

func (*Note) SetContents

func (m *Note) SetContents(vaultPath string, noteName string, content string) error

SetContents 将内容写入 vault 中的指定笔记。 先通过遍历找到笔记的实际路径,然后覆盖写入。

func (m *Note) UpdateLinks(vaultPath string, oldNoteName string, newNoteName string) error

UpdateLinks 遍历 vault 中所有笔记,将指向旧笔记的链接更新为新笔记的链接。 这是 move 命令的重要后续操作,保证笔记间的引用关系不会断裂。

type NoteManager

type NoteManager interface {
	Move(string, string) error
	Delete(string) error
	UpdateLinks(string, string, string) error
	GetContents(string, string) (string, error)
	SetContents(string, string, string) error
	GetNotesList(string) ([]string, error)
	SearchNotesWithSnippets(string, string) ([]NoteMatch, error)
	FindBacklinks(string, string) ([]NoteMatch, error)
}

NoteManager 定义了与笔记交互的接口。 通过接口解耦,方便在测试中注入 Mock 对象。

type NoteMatch

type NoteMatch struct {
	FilePath   string // 匹配所在的笔记相对路径
	LineNumber int    // 匹配行号(0 表示文件名匹配)
	MatchLine  string // 匹配行的内容摘要
}

NoteMatch 保存单次搜索结果的信息。

type ObsidianAppConfig

type ObsidianAppConfig struct {
	NewFileLocation   string   `json:"newFileLocation"`   // 新笔记存放方式:root 或 folder
	NewFileFolderPath string   `json:"newFileFolderPath"` // 当方式为 folder 时的目标文件夹
	UserIgnoreFilters []string `json:"userIgnoreFilters"` // 用户配置的排除路径/通配符列表
}

ObsidianAppConfig 对应 vault 中 .obsidian/app.json 的结构。 主要读取新建笔记的默认位置和用户配置的排除规则。

type ObsidianVaultConfig

type ObsidianVaultConfig struct {
	Vaults map[string]struct {
		Path string `json:"path"` // vault 的绝对路径
	} `json:"vaults"`
}

ObsidianVaultConfig 是 Obsidian 官方配置文件中 vault 注册表的结构。 对应 ~/.config/obsidian/obsidian.json 中的 vaults 字段。

type Uri

type Uri struct{}

Uri 是 UriManager 的具体实现,负责构造和执行 Obsidian URI。

func (*Uri) Construct

func (u *Uri) Construct(baseUri string, params map[string]string) string

Construct 将基础 URI 与参数 map 拼接成完整的查询字符串。 空值和 "false" 会被忽略;空格会被编码为 %20 而非 +,以兼容 Obsidian。

func (*Uri) Execute

func (u *Uri) Execute(uri string) error

Execute 调用系统默认程序打开给定的 URI。

type UriManager

type UriManager interface {
	Construct(baseUri string, params map[string]string) string // 构造带查询参数的 URI
	Execute(uri string) error                                  // 执行 URI(唤起系统默认程序)
}

UriManager 定义了 URI 构造与执行的接口。 通过接口解耦,方便在测试中注入 Mock 对象。

type Vault

type Vault struct {
	Name string
}

Vault 是 VaultManager 的具体实现。 Name 为空时,业务层会自动从配置中解析默认名称。

func (*Vault) DefaultName

func (v *Vault) DefaultName() (string, error)

DefaultName 返回当前 Vault 的名称。 如果 Vault.Name 已设置,直接返回;否则从 CLI 配置文件中读取默认 vault 名称。

func (*Vault) DefaultOpenType

func (v *Vault) DefaultOpenType() (string, error)

DefaultOpenType 返回 CLI 配置中的默认打开方式。 如果未配置或读取失败,回退到 "obsidian"。

func (*Vault) Path

func (v *Vault) Path() (string, error)

Path 返回当前 vault 的绝对路径。 如果 Vault.Name 已经是绝对路径,直接返回(支持不依赖 Obsidian 配置文件的独立模式)。 否则从 Obsidian 的 vault 注册表中查找对应路径。

func (*Vault) SetDefaultName

func (v *Vault) SetDefaultName(name string) error

SetDefaultName 设置 CLI 配置中的默认 vault 名称。 会保留配置文件中已有的其他字段(如 DefaultOpenType)。

func (*Vault) SetDefaultOpenType

func (v *Vault) SetDefaultOpenType(openType string) error

SetDefaultOpenType 设置 CLI 配置中的默认打开方式(obsidian 或 editor)。 同样会保留配置文件中已有的其他字段。

type VaultInfo

type VaultInfo struct {
	Name string `json:"name"` // vault 名称(目录 basename)
	Path string `json:"path"` // vault 的绝对路径
}

VaultInfo 保存单个 vault 的名称和路径信息。

func ListVaults

func ListVaults() ([]VaultInfo, error)

ListVaults 返回所有已注册 Obsidian vault 的列表。

type VaultManager

type VaultManager interface {
	DefaultName() (string, error)     // 获取当前默认 vault 名称
	SetDefaultName(name string) error // 设置默认 vault 名称
	Path() (string, error)            // 获取当前 vault 的绝对路径
	DefaultOpenType() (string, error) // 获取默认打开方式
}

VaultManager 定义了与 Vault 交互的接口。 通过接口解耦,方便在测试中注入 Mock 对象。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL