-
Notifications
You must be signed in to change notification settings - Fork 66
Added filewatch and cache functionality, notes can be searched by aliases #142
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
Open
kostabekre
wants to merge
64
commits into
obsidian-nvim:main
Choose a base branch
from
kostabekre:add-cache
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 11 commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
95b52bb
cache init commit
kostabekre 10dfbac
rejected using sqlite, added basic vault indexing, filewatch
kostabekre 7f7a3eb
A note can be searched by alias
kostabekre 95854da
Merge remote-tracking branch 'upstream/main'
kostabekre e334d68
Updated the filewatch
kostabekre c109e6d
working version
kostabekre 921ef52
Merge remote-tracking branch 'upstream/main'
kostabekre aa48f82
last todo
kostabekre dda1188
updated read me, fixed test
kostabekre 3037db7
fix readme
kostabekre e8052e7
Updated changelog
kostabekre 043ec03
moved changes in changelog to unreleased
kostabekre a39d9d1
removed 3.12 from changelog
kostabekre b80f913
added semicolon
kostabekre 8e3df02
Updated config option to enable cache
kostabekre a16912e
Squash merge add-cache into main
kostabekre b496be5
code update
kostabekre d19bd80
Merge branch 'add-cache'
kostabekre 7da49dd
Added log when a note is updated as a warning
kostabekre 0a7f300
Merge branch 'main' into add-cache
kostabekre 9dc7df8
Added a test warning
kostabekre f7f2aa5
checking get_cache_notes for error
kostabekre 9714bc3
more description of errors
kostabekre 64f914e
fix error
kostabekre 2a2a40d
changed log warning to debug
kostabekre 6d06a65
Merge branch 'add-cache' into develop
kostabekre bd14b1a
temp changes
kostabekre 8d80abb
file watch sends multiple files but didn't test
kostabekre 040e766
Fixed errors
kostabekre d353656
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre 2a37f1d
Updated Cache config
kostabekre b19e938
Added the file handle for root on Linux
kostabekre 9da52d3
github code review changes
kostabekre a5f58d7
Merge branch 'add-cache'
kostabekre 9dda489
Merge remote-tracking branch 'upstream/main'
kostabekre 5bef2a6
github code review
kostabekre 8084864
Merge remote-tracking branch 'upstream/main'
kostabekre ace8863
Merge branch 'main' into add-cache
kostabekre 593d6a1
added tags, fixed bug with plenary (too many files), style fix
kostabekre e29f7ad
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre 78023b5
Apply suggestions from code review
neo451 d3b5366
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre ea8bfa6
Merge branch 'add-cache' of github.com:kostabekre/obsidian.nvim into …
kostabekre 2721082
Code review changes
kostabekre 151d792
fix update errors
kostabekre 2aec269
used joinpath for cross platform, added an option to show or hide tag…
kostabekre 75c4cd9
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre e7cdbd2
fix: dropped abc in cache, cache doesn't use client
kostabekre 53d167a
fix: forgot to use Obsidian.opts in quick_switch
kostabekre 6992c30
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre 0233ee6
A lock file is created for a workspace, when enabling filewatch
kostabekre d4d1931
.gitignore or .ignore is respected in filewatch and cache
kostabekre 6dd1a7b
lock file fix: use pid to check if the neovim isntance, which created…
kostabekre 65a8cc1
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre f43d2dc
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre b52a176
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre 9ead762
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre ea5af9f
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre 5fe0083
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre 3a6ce80
moved lock file to the state folder, set the workspace based on the c…
kostabekre 89dbe34
moved lock file from state to state/obsidian
kostabekre df75256
Merge remote-tracking branch 'upstream/main' into add-cache
kostabekre a46c848
use obsidian.async
kostabekre c5e8ba8
disable warning that a string should be passed instead of a number wh…
kostabekre File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,282 @@ | ||
local abc = require "obsidian.abc" | ||
local search = require "obsidian.search" | ||
local Note = require "obsidian.note" | ||
local log = require "obsidian.log" | ||
local EventTypes = require("obsidian.filewatch").EventTypes | ||
local uv = vim.uv | ||
|
||
---This class allows you to find the notes in your vault more quickly. | ||
---It scans your vault and saves the founded metadata to the default cache file ".cache.json" | ||
---in the root of your vault or in the path you specified. | ||
---For example, this allows to search for alises of your | ||
---notes in much shorter time. | ||
---@class obsidian.Cache : obsidian.ABC | ||
--- | ||
---@field client obsidian.Client | ||
local Cache = abc.new_class() | ||
|
||
---Contains some information from the metadata of your note plus additional info. | ||
---@class obsidian.cache.CacheNote | ||
--- | ||
---@field absolute_path string The full path to the note. | ||
---@field relative_path string The relative path to the root of the vault. | ||
---@field aliases string[] The alises of the note founded in the frontmatter. | ||
---@field last_updated number The last time the note was updated in seconds since epoch. | ||
|
||
---Converts the links to json and saves to the file at the given path. | ||
---@param links obsidian.cache.CacheNote[] | ||
---@param note_path string|obsidian.Note | ||
local save_cache_notes_to_file = function(links, note_path) | ||
local save_path | ||
|
||
if type(note_path) == "obsidian.Note" then | ||
save_path = note_path.path.filename | ||
else | ||
save_path = note_path | ||
end | ||
|
||
local file, err = io.open(save_path, "w") | ||
|
||
if file then | ||
file:write(vim.fn.json_encode(links)) | ||
file:close() | ||
else | ||
error(table.concat { "Couldn't write vault index to the file: ", save_path, ". Description: ", err }) | ||
kostabekre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
end | ||
|
||
---@param self obsidian.Cache | ||
---@return fun (absolute_path: string, event_type: obsidian.filewatch.EventType, stat: uv.fs_stat.result) | ||
local create_on_file_change_callback = function(self) | ||
return function(filename, event_type, stat) | ||
vim.schedule(function() | ||
local founded = false | ||
|
||
local links = self:get_cache_notes_from_file() | ||
for i, v in ipairs(links) do | ||
if v.absolute_path == filename then | ||
if event_type == EventTypes.deleted then | ||
table.remove(links, i) | ||
else | ||
local note = Note.from_file(filename, { read_only_frontmatter = true }) | ||
|
||
local relative_path = note.path.filename:gsub(self.client.dir.filename .. "/", "") | ||
|
||
links[i] = { | ||
absolute_path = filename, | ||
aliases = note.aliases, | ||
relative_path = relative_path, | ||
last_updated = stat.mtime.sec, | ||
} | ||
end | ||
|
||
founded = true | ||
break | ||
end | ||
end | ||
|
||
if not founded then | ||
-- Unknown file that was deleted is not in the cache, so we don't need to do anything. | ||
if event_type == EventTypes.deleted then | ||
return | ||
end | ||
|
||
local new_note = Note.from_file(filename, { read_only_frontmatter = true }) | ||
|
||
local relative_path = new_note.path.filename:gsub(self.client.dir.filename .. "/", "") | ||
|
||
local new_cache = { | ||
absolute_path = filename, | ||
aliases = new_note.aliases, | ||
relative_path = relative_path, | ||
last_updated = stat.mtime.sec, | ||
} | ||
|
||
table.insert(links, new_cache) | ||
end | ||
|
||
save_cache_notes_to_file(links, self.client.opts.cache.cache_path) | ||
end) | ||
end | ||
end | ||
|
||
---Checks for note cache that were updated outside the vault | ||
---@param self obsidian.Cache | ||
local check_cache_notes_are_fresh = function(self) | ||
local note_cache_list = self:get_cache_notes_from_file() | ||
|
||
local completed = 0 | ||
local total = #note_cache_list | ||
local updated = {} | ||
local on_done = function() | ||
completed = completed + 1 | ||
|
||
if completed == total then | ||
vim.schedule(function() | ||
save_cache_notes_to_file(updated, self.client.opts.cache.cache_path) | ||
end) | ||
end | ||
end | ||
|
||
for _, note_cache in ipairs(note_cache_list) do | ||
uv.fs_stat(note_cache.absolute_path, function(err, stat) | ||
if err then | ||
err("Couldn't get stat from the file " .. note_cache.relative_path .. " when performing reindex: " .. err) | ||
neo451 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
end | ||
|
||
local aliases | ||
if note_cache.last_updated ~= stat.mtime.sec then | ||
local note = Note.from_file(note_cache.absolute_path, { read_only_frontmatter = true }) | ||
aliases = note.aliases | ||
else | ||
aliases = note_cache.aliases | ||
end | ||
|
||
---@type obsidian.cache.CacheNote | ||
table.insert(updated, { | ||
absolute_path = note_cache.absolute_path, | ||
last_updated = stat.mtime.sec, | ||
aliases = aliases, | ||
relative_path = note_cache.relative_path, | ||
}) | ||
|
||
on_done() | ||
end) | ||
end | ||
end | ||
|
||
---Checks that file exits | ||
---@param path string | ||
---@param callback fun (result: boolean) | ||
local check_file_exists = function(path, callback) | ||
uv.fs_stat(path, function(err, _) | ||
if not err then | ||
callback(true) | ||
kostabekre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
callback(false) | ||
end | ||
end) | ||
end | ||
|
||
---Watches the vault for changes. | ||
---@param self obsidian.Cache | ||
local enable_filewatch = function(self) | ||
local handlers = require("obsidian.filewatch").watch(self.client.dir.filename, create_on_file_change_callback(self)) | ||
|
||
vim.api.nvim_create_autocmd({ "QuitPre", "ExitPre" }, { | ||
callback = function() | ||
for _, handle in ipairs(handlers) do | ||
if handle then | ||
handle:stop() | ||
if not handle.is_closing then | ||
handle:close() | ||
end | ||
end | ||
end | ||
end, | ||
}) | ||
end | ||
|
||
---@param self obsidian.Cache | ||
local check_vault_cache = function(self) | ||
check_file_exists(self.client.opts.cache.cache_path, function(exists) | ||
if exists then | ||
vim.schedule(function() | ||
check_cache_notes_are_fresh(self) | ||
end) | ||
else | ||
vim.schedule(function() | ||
self:index_vault() | ||
end) | ||
end | ||
end) | ||
end | ||
|
||
---@param client obsidian.Client | ||
Cache.new = function(client) | ||
local self = Cache.init() | ||
self.client = client | ||
|
||
if client.opts.cache.use_cache then | ||
enable_filewatch(self) | ||
|
||
check_vault_cache(self) | ||
end | ||
|
||
return self | ||
end | ||
|
||
--- Reads all notes in the vaults and returns the founded data. | ||
---@param client obsidian.Client | ||
---@return obsidian.cache.CacheNote[] | ||
local get_cache_notes_from_vault = function(client) | ||
local interator = search.find(client.dir, "", nil) | ||
kostabekre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
---@type obsidian.cache.CacheNote[] | ||
local created_note_caches = {} | ||
|
||
local notepath = interator() | ||
|
||
--TODO add indexing progress | ||
while notepath do | ||
local note = Note.from_file(notepath, { read_only_frontmatter = true }) | ||
|
||
local absolute_path = note.path.filename | ||
local relative_path = absolute_path:gsub(client.dir.filename .. "/", "") | ||
|
||
local file_stat = uv.fs_stat(absolute_path) | ||
local last_updated | ||
|
||
if type(file_stat) ~= "table" then | ||
log.err(table.concat { "couldn't get file stat from file ", absolute_path }) | ||
last_updated = 0 | ||
else | ||
last_updated = file_stat.mtime.sec | ||
end | ||
|
||
---@type obsidian.cache.CacheNote | ||
local note_cache = { | ||
absolute_path = absolute_path, | ||
aliases = note.aliases, | ||
relative_path = relative_path, | ||
kostabekre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
last_updated = last_updated, | ||
} | ||
|
||
table.insert(created_note_caches, note_cache) | ||
|
||
notepath = interator() | ||
end | ||
|
||
return created_note_caches | ||
end | ||
|
||
--- Reads all notes in the vaults and saves them to the cache file. | ||
---@param self obsidian.Cache | ||
Cache.index_vault = function(self) | ||
if not self.client.opts.cache.use_cache then | ||
log.error "The cache is disabled. Cannot index vault." | ||
end | ||
|
||
local founded_links = get_cache_notes_from_vault(self.client) | ||
|
||
save_cache_notes_to_file(founded_links, self.client.opts.cache.cache_path) | ||
|
||
log.info "Vault was indexed succesfully." | ||
end | ||
|
||
---Reads the cache file from client.opts.cache.cache_path and returns founded note cache. | ||
---@param self obsidian.Cache | ||
---@return obsidian.cache.CacheNote[] | ||
Cache.get_cache_notes_from_file = function(self) | ||
local file, err = io.open(self.client.opts.cache.cache_path, "r") | ||
|
||
if file then | ||
local links_json = file:read() | ||
file:close() | ||
return vim.fn.json_decode(links_json) | ||
kostabekre marked this conversation as resolved.
Show resolved
Hide resolved
|
||
else | ||
error("couldn't read vault index from file: " .. err) | ||
end | ||
end | ||
|
||
return Cache |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
neo451 marked this conversation as resolved.
Show resolved
Hide resolved
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
---@param client obsidian.Client | ||
---@param data CommandArgs | ||
return function(client, data) | ||
client.cache:index_vault() | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.