-
Notifications
You must be signed in to change notification settings - Fork 189
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
feat: support workspaces config option #155
Conversation
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.
FYI you don't need to update doc/obsidian.txt
. That file is generated automatically from the README. So just make those same changes in the README. I recently added a CONTRIBUTING guide that goes over that and some other tips for getting CI to pass.
I added the The idea is that the require('obsidian').setup({
workspaces = {
'~/vault-1',
'~/vault-2',
},
} Then, we loop through the One problem with this implementation is that the behavior is not consistent depending on whether the user passes in
A potential solution to this inconsistency is to ignore what the user assigns to However, the last bullet point has me questioning this feature altogether. If |
Ahh, I should have read that first... |
Hey @weskoerber, I think
In this case I |
Using the following config... obsidian.setup({
workspaces = {
'~/notes',
},
}) ...and assuming the working directory is What if
My initial idea is that Is that different than your expectation? How do you expect the workspaces feature to work? |
I went back to #128 and looked at neorg workspaces. They say workspaces are "basically isolated directories that you can jump between". My initial hack I wrote up in #128 was just to support opening a directory (e.g. However, I think @sadtab's idea of workspaces were more similar to neorg's workspaces, and my little hack misses that mark. If we can jump between workspaces (e.g. |
Ok so I think there's really two different features here:
In my mind
|
I think Based on the current implementation of obsidian.nvim, I think the least intrusive approach can be the same. Let the user define a list of vaults and pick one as default, there is always one vault set as the current vault. Don't bother about the cwd or try to detect the cwd. Because it's complex, bug-prone, and also inconvenient in the very common case where you are working on your source codes and you want just to take a note quickly. The user knows its default vault, if they want to choose another vault, it changes the vault and then takes the note. Usually, a custom keymap will do it conveniently. PS: I really appreciate what you are doing, my knowledge in lua is very minimal, otherwise I would love to contribute, thanks a lot, truly appreciated |
Thanks for the feedback guys!
I agree, although I think your first point can be split into 2 parts 1a. #128 - support for multiple vaults However, I don't think I understand your second point completely (also #119), because I don't know that it's necessary with 1a and 1b. But I can see the value in changing the vault dir to cwd if the vault dir isn't set with 1a and 1b. Lemme know what you think.
This was my initial assumption as well. I thought that
IMHO, a more useful implementation would determine if the current directory exists in the
The user also knows the Let me know what y'all think! |
I misunderstood #119. The author of that issue said:
Which is different than your second point. |
21ba6c1
to
9b3e415
Compare
Thanks for the continued effort on this @weskoerber :) I'm very busy with my real job this week so I might not be able to give another review until next week. |
No worries, I'm in no rush! I got busy a couple weeks ago too, I know how it goes... |
8d119d9
to
bc6b82b
Compare
Really looking forward to this! I'm just in the process of setting up Obsidian and the ability to separate work and personal notes is a must have for me.. |
This whole |
Yep, that's exactly the intended behavior. It's actually not new functionality, just renamed from
The intention of
Admittedly,
|
Yeah, the dual-purpose was what made it a bit confusing. A boolean for tracking/detecting/following |
a4f40a8
to
f40c132
Compare
Lua hash maps are unordered so the order of This makes the definition of workspaces a little more verbose, but it makes the implementation cleaner IMO: obsidian.setup({
workspaces = {
{
name = 'personal',
path = '~/notes/personal',
},
{
name = 'work',
path = '~/notes/work',
}
},
detect_cwd = false, -- default
}) |
If we want named workspaces then this is the way to go. But is the naming really necessary? Just wondering the use case here and can't figure out anything but easier quick switch using a command. If using a picker like telescope then the name doesn't really matter much. But the logic is now much easier to follow and I agree, the implementation looks much clearer as well. Kudos! |
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.
Thank you all for the discussion! I just have a few minor requests and then I think we can get this merged ✅
self.dir = Path:new(vim.fs.normalize(tostring(opts.dir and opts.dir or "./"))) | ||
|
||
self.current_workspace = obsidian.workspace.get_from_opts(opts) | ||
self.dir = Path:new(self.current_workspace.path) |
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.
I think we should still normalize dir
to avoid breaking changes.
self.dir = Path:new(self.current_workspace.path) | |
self.dir = Path:new(vim.fs.normalize(tostring(self.current_workspace.path))) |
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.
Hi! I finally have time to swing back around on these...
The workspace paths should already be normalized.
Here, in workspace.new()
, the path is normalized:
workspace.new = function(name, path)
local self = setmetatable({}, { __index = workspace })
self.name = name
self.path = vim.fs.normalize(path)
return self
end
Paths are also normalized when reading from the config in client.ClientOpts.normalize()
:
for key, value in pairs(opts.workspaces) do
opts.workspaces[key].path = vim.fs.normalize(tostring(value.path))
end
There could be an edge-case I haven't fully considered, but I think it's safe to omit the redundant path normalization. However, if you still prefer normalizing the paths where you suggested I won't argue with you 😄
client.current_workspace = workspace | ||
|
||
echo.info("Switching to workspace '" .. workspace.name .. "' (" .. workspace.path .. ")", client.opts.log_level) | ||
client.dir = Path:new(workspace.path) |
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.
Same suggestion here about normalizing:
client.dir = Path:new(workspace.path) | |
client.dir = Path:new(vim.fs.normalize(tostring(workspace.path))) |
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.
See my comment in a previous suggestion
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.
Ok fair enough! Could you add a comment here at least:
client.dir = Path:new(workspace.path) | |
-- NOTE: workspace.path has already been normalized | |
client.dir = Path:new(workspace.path) |
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.
Fixed with 598bc0a
workspace.get_workspace_from_cwd = function(workspaces) | ||
local cwd = vim.fn.getcwd() | ||
local _, value = next(vim.tbl_filter(function(w) | ||
if w.path == cwd then |
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.
We might need to normalize these paths before comparing them, otherwise it seems a bit brittle.
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.
See my comment in a previous suggestion
Sorry for the delay. I'll have some time this weekend to address these concerns! |
I would love this feature, what's the state of this? @weskoerber I would like to thank you already for your work! |
Is there any update on this? I'm really excited for this feature! |
Looking forward! great work on this! |
- when called with no arguments, print the current workspace name and path - when called with a single argument, try to switch to the workspace
825ac0d
to
46b4a83
Compare
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.
Thanks for getting back to this @weskoerber! Just a couple more comments
doc/obsidian.txt
Outdated
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.
This file gets updated automatically from the README. So could you please update the README instead?
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.
Ugh sorry, I might have resolved conflicts in this file poorly when I rebased.
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.
Fixed with 48ae1f1
client.current_workspace = workspace | ||
|
||
echo.info("Switching to workspace '" .. workspace.name .. "' (" .. workspace.path .. ")", client.opts.log_level) | ||
client.dir = Path:new(workspace.path) |
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.
Ok fair enough! Could you add a comment here at least:
client.dir = Path:new(workspace.path) | |
-- NOTE: workspace.path has already been normalized | |
client.dir = Path:new(workspace.path) |
lua/obsidian/init.lua
Outdated
@@ -37,7 +41,7 @@ end | |||
---@return obsidian.Client | |||
obsidian.new_from_dir = function(dir) | |||
local opts = config.ClientOpts.default() | |||
opts.dir = vim.fs.normalize(dir) | |||
opts.workspaces = vim.tbl_extend("force", { obsidian.workspace.new("test_vault", dir) }, opts.workspaces) |
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.
Maybe name it by the name of the directory instead of "test_vault"?
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.
Fixed with 1e1ba52
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.
I would like to keep backwards compatibility for when people upgrade. This should be fairly easy:
Just check if dir
is set instead of workspaces
and convert dir
into a workspace
object.
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.
Fixed in f422f98
- names the workspace the name of the dir
- previously using obfuscatory "test_vault"
- if `dir` is set, convert it to a workspace object
lua/obsidian/config.lua
Outdated
|
||
local config = {} | ||
|
||
---[[ Options specs ]]--- | ||
|
||
---@class obsidian.config.ClientOpts | ||
---@field dir string | ||
---@field dir string|? | ||
---@field workspaces table |
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.
I think this has the obisidan.Workspace
type, right?
---@field workspaces table | |
---@field workspaces obsidian.Workspace |
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.
It's a table of obsidian.workspace
s:
require('obsidian').setup({
-- ...
workspaces = {
{
name = 'personal',
path = '~/Documents/notes/personal',
},
{
name = 'work',
path = '~/Documents/notes/acsd',
},
}
-- ...
)}
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.
Ah, right, then we can give it a type hint like this
---@field workspaces table | |
---@field workspaces obsidian.Workspace[]|? |
- if `dir` is set, use that as the default workspace - even if workspaces are defined, `dir` is used as the default
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.
LGTM! Thanks for getting this over the finish line @weskoerber :)
lua/obsidian/config.lua
Outdated
|
||
local config = {} | ||
|
||
---[[ Options specs ]]--- | ||
|
||
---@class obsidian.config.ClientOpts | ||
---@field dir string | ||
---@field dir string|? | ||
---@field workspaces table |
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.
Ah, right, then we can give it a type hint like this
---@field workspaces table | |
---@field workspaces obsidian.Workspace[]|? |
I didn't know you could type hint like that, thanks for the tip!
Right on! I appreciate you being patient with me and guiding me through this PR! |
This PR adds the following functionality:
"Workspaces" feature:
:ObsidianWorkspace
:ObsidianQuickSwitch
,:ObsidianToday
, etc...detect_cwd
is true, attempt to resolve cwd inworkspaces
workspaces
, open cwd as fallback vaultdetect_cwd
is false (default), use first workspace as working vault:ObsidianWorkspace
:Note:
dir
is maintained for backward compatibility. Ifdir
is specified, it's used as the default workspace (as long asdetect_cwd
isfalse
[it is by default]).To upgrade, move
dir
from the old config into theworkspaces
list. For example, if this is your current config:Use this config:
closes: #128
see also: #60, #119