-
Notifications
You must be signed in to change notification settings - Fork 10
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
Navigation of daily notes #62
Comments
Thank you so much for commenting! I've with you on this being important. The workspace symbols idea would be perfect. However, I don't believe it would be possible to open daily notes that have not been created yet; you want tomorrow but 2024-04-26 doesn't exist for example. What do you think about a CLI for this? I have been using this little nu-shell script for opening daily notes .. it could be ported #!/usr/bin/env nu
def main [change: int = 0, --gui] {
let day = (date now) + ($"($change)day" | into duration)
let day = ($day | date to-record)
cd ~/Notes
let month = if $day.month < 10 {
"0" + ($day.month | into string)
} else {
$day.month | into string
}
let day_num = if $day.day < 10 {
"0" + ($day.day | into string)
} else {
$day.day | into string
}
if $gui {
neovide $"($day.year)-($month)-($day_num).md"
} else {
nvim $"($day.year)-($month)-($day_num).md"
}
} this allows you to prompt What do you think about this? There is also the option of making an LSP command and implementing it for every text editor |
Of course! This is a cool idea for a project and right up my alley. Not an expert in LSP at all, but learning more about how useful it can be.
This might be editor dependent; a proof of concept seems like the non-existent file may be created for proof of concept diff: diff --git a/src/main.rs b/src/main.rs
index d73567c..8b3fa6c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -291,9 +291,10 @@ impl Backend {
#[tower_lsp::async_trait]
impl LanguageServer for Backend {
async fn initialize(&self, i: InitializeParams) -> Result<InitializeResult> {
-
let root_dir = match i.root_uri {
- Some(uri) => uri.to_file_path().or(Err(Error::new(ErrorCode::InvalidParams)))?,
+ Some(uri) => uri
+ .to_file_path()
+ .or(Err(Error::new(ErrorCode::InvalidParams)))?,
None => std::env::current_dir().or(Err(Error::new(ErrorCode::InvalidParams)))?,
};
@@ -612,7 +613,8 @@ impl LanguageServer for Backend {
&self,
params: WorkspaceSymbolParams,
) -> Result<Option<Vec<SymbolInformation>>> {
- self.bind_vault(|vault| Ok(workspace_symbol(vault, ¶ms)))
+ let settings = self.bind_settings(|settings| Ok(settings.clone())).await?;
+ self.bind_vault(|vault| Ok(workspace_symbol(&settings, vault, ¶ms)))
.await
}
diff --git a/src/symbol.rs b/src/symbol.rs
index ce3fbd5..09c8b2a 100644
--- a/src/symbol.rs
+++ b/src/symbol.rs
@@ -1,3 +1,4 @@
+use chrono::{Duration, NaiveDate};
use std::{iter, path::Path};
use itertools::Itertools;
@@ -6,14 +7,18 @@ use tower_lsp::lsp_types::{
SymbolKind, Url, WorkspaceSymbolParams,
};
-use crate::vault::{MDHeading, Referenceable, Vault};
+use crate::{
+ config::Settings,
+ vault::{MDHeading, Referenceable, Vault},
+};
pub fn workspace_symbol(
+ settings: &Settings,
vault: &Vault,
_params: &WorkspaceSymbolParams,
) -> Option<Vec<SymbolInformation>> {
let referenceables = vault.select_referenceable_nodes(None);
- let symbol_informations = referenceables
+ let mut symbol_informations = referenceables
.into_iter()
.flat_map(|referenceable| {
let range = match referenceable {
@@ -48,6 +53,62 @@ pub fn workspace_symbol(
})
.collect_vec();
+ fn date_to_filename(settings: &Settings, date: NaiveDate) -> String {
+ date.format(settings.dailynote.as_str()).to_string()
+ }
+
+ fn relative_date_string(date: NaiveDate) -> Option<String> {
+ let today = chrono::Local::now().date_naive();
+
+ if today == date {
+ Some("today".to_string())
+ } else {
+ match (date - today).num_days() {
+ 1 => Some("tomorrow".to_string()),
+ 2..=7 => Some(format!("next {}", date.format("%A"))),
+ -1 => Some("yesterday".to_string()),
+ -7..=-1 => Some(format!("last {}", date.format("%A"))),
+ _ => None,
+ }
+ }
+ }
+
+ fn date_to_match_string(settings: &Settings, date: NaiveDate) -> Option<String> {
+ let refname = date_to_filename(settings, date);
+ format!("{}: {}", relative_date_string(date)?, refname).into()
+ }
+
+ let today = chrono::Local::now().date_naive();
+ let days = (-7..=7)
+ .flat_map(|i| Some(today + Duration::try_days(i)?))
+ // .flat_map(|date| relative_date_string(date))
+ // TODO: this filters out duplicates, which may not actually be desirable here?
+ // .filter(|date| !refnames.contains(&date.ref_name))
+ // TODO: collect Symbol information here
+ .filter_map(|date| {
+ Some(SymbolInformation {
+ name: date_to_match_string(settings, date)?,
+ kind: SymbolKind::FILE,
+ location: Location {
+ uri: Url::from_file_path(date_to_filename(settings, date)).ok()?,
+ range: tower_lsp::lsp_types::Range {
+ start: tower_lsp::lsp_types::Position {
+ line: 0,
+ character: 0,
+ },
+ end: tower_lsp::lsp_types::Position {
+ line: 0,
+ character: 1,
+ },
+ },
+ },
+ container_name: None,
+ tags: None,
+ deprecated: None,
+ })
+ });
+
+ symbol_informations.extend(days);
Some(symbol_informations)
}
It's not something I'd expect to be in scope for this project, and so not something I'd ask to be included here. The existing CLI tools and editor plugins for managing wikis of various flavors are pretty reasonable. I'd likely stick with one of those if there isn't a good way to accomplish some of the wiki management through an LSP. Sadly, it seems like |
Hey That snippet looks good. I just dont know how the symbols will work for locations of files that to not yet exist. It would be perfect if the file is created, but I expect the editor would throw an error |
At least helix and neovim open non-existent files as empty buffers, though they may be swallowing an error internally. I've started to prototype out daily note functionality as lsp commands which I'd be happy to contribute back once I have something decent. The commands should be able to be a lot better anyways (to have next note/prev note, for example, not just specific days). |
Cool looks good. Could you open a PR? Its okay even if you don't have much code yet |
Happy to, I'll get one up this weekend |
awesome! |
|
re: #85 (comment) A plugin isn't super valuable for me, I've just wrapped |
Yea that makes total sense. I am on the same page as you. I think it would be valuable for beginners to have a default setup for lsp capabilities (file watcher), code lens, and commands - things that nvim-lspconfig cannot do. It would also enable some advanced features. The issue is here #95; It would be awesome to collaborate more. |
One of my most used operations (as a longtime vimwiki user moving over to Obsidian) is to open a daily note. I really like the ability to use
today
,tomorrow
, etc. to link to the daily note for the corresponding day and would like a corresponding way to open daily notes.Would it be possible to also add
today
,tomorrow
, etc. as workspace symbols, or otherwise add a command to open these notes?The text was updated successfully, but these errors were encountered: