Taitava / obsidian-shellcommands

Execute system commands via hotkeys or command palette in Obsidian (https://obsidian.md). Some automated events are also supported, and execution via URI links.
GNU General Public License v3.0
351 stars 11 forks source link

A new variable {{note_content}} #77

Closed Taitava closed 1 year ago

Taitava commented 2 years ago

Discussed in https://github.com/Taitava/obsidian-shellcommands/discussions/57

Gets the current note's content without YAML frontmatter.

Taitava commented 2 years ago

I tried to implement this now, but faced difficulties:

  1. Getting file content in Obsidian's API seems to require asynchronous method processing. This is something that is new to me in JavaScript, and the variable system in SC is not built to work asynchronously. I quess I can do the kind of refactoring needed for this, but cannot promise anything yet.
  2. I was not able to find a way to reliably filter out YAML fronmatter from the file content. For this, I have asked a question in Obsidian's forum.

So, unfortunately I need to postpone this until those two problems get solved. If I get number 1 solved myself in the future, I think I could then create another variable file_content (needs a new feature issue) that would contain the whole content of the current file. It would not be a replacement for this variable, it would be a different thing, but at least something.

FelipeRearden commented 2 years ago

I tried to implement this now, but faced difficulties:

Sorry if this FR is bring some hurdles @Taitava !

So, unfortunately I need to postpone this until those two problems get solved. If I get number 1 solved myself in the future, I think I could then create another variable file_content (needs a new feature issue) that would contain the whole content of the current file. It would not be a replacement for this variable, it would be a different thing, but at least something.

Okay, I think you are right!

Let's wait a feedback from our community friends. Maybe some other developer can help us with this issue :)

Have a great day!

Taitava commented 2 years ago

Sorry if this FR is bring some hurdles @Taitava !

Problems are nothing new under the sun of code 🙂 . I've been developing this plugin since mid August, so only a couple of months, and before that I had no experience of Obsidian's API and plugin development. Things tend to be harder in the beginning 🙂 .

Let's wait a feedback from our community friends. Maybe some other developer can help us with this issue :)

I hope so too.

Have a nice day, too! 🙂

FelipeRearden commented 2 years ago

Problems are nothing new under the sun of code 🙂 . I've been developing this plugin since mid August, so only a couple of months, and before that I had no experience of Obsidian's API and plugin development. Things tend to be harder in the beginning 🙂 .

It's amazing to see how you accomplished so much in just only 2/3 months :)

I can imagine @Taitava . Code development is something so special and complex when compared to other subjects :)

You are doing an spectacular job :)

Have a great day :)

FelipeRearden commented 2 years ago

@Taitava

I found this link that has a code about reading the file current content:

https://liamca.in/Obsidian/API+FAQ/filesystem/read+the+current+file

Reading the current file contents is a two-step process:

Retrieve the current view from the Workspace. Read the view's file from the Vault.

Sample Code

import type { MarkdownView } from 'obsidian';

/* ... */

const { workspace } = this.app;
const activeView = workspace.getActiveViewOfType(MarkdownView);

if (activeView) {  // The active view might not be a markdown view
  // Read the file (from either the cache or from disk)
  // Note: `cachedRead` returns stale data which should be good for most cases. 
  // However, if you plan on writing back to disk, use `vault.read` here 
  // instead to avoid data loss.
  const fileContents = vault.cachedRead(activeView.file);
}

Maybe it helps :)

Taitava commented 2 years ago

Thanks @FelipeRearden ! The Liam Cain's solution seems to be quite similar to another solution that I found over here. Both of these use vault.read() / vault.cachedRead() methods, which return Promise objects (sorry I'm not explaining this with non-programmin terms), and Promise objects are something that will require me to do some bigger changes in the variable system due to their asynchronous nature.

Taitava commented 2 years ago

A short explanation for Promise objects: In theory vault.read() / vault.cachedRead() could return the file's content to my program directly. That would be easy. But they do not do that. Instead they return me something that tells: "Hey, I'll promise to give you the file's content in the future." So I need to wait - probably less than a millisecond, but still. And I need to make the whole SC wait: the variable waits to get the file content that it can then give to earlier code that replaces variables with their values, and when that code finally gets the variable value, it can continue processing other variables and finally let even earlier code to continue with actually executing the shell command. This whole chain needs to be organised a bit differently to take into account that we need to wait a bit before we can execute the shell command. 👍

(I guess this explanation didn't exlain anything 😆 )

FelipeRearden commented 2 years ago

Looks like this is the kind of thing that we have to wait for Obsidian API gives us a "map" to simple extract the content without the YAML :(

I face the same situation trying to ask for a command palette command to the right mouse click:

Thanks for the explanation @Taitava !

We have to wait for some external help :)

Taitava commented 2 years ago

My question in the forum has been answered: https://forum.obsidian.md/t/how-to-get-current-file-content-without-yaml-frontmatter/26197/2

I haven't tried the solution yet.

FelipeRearden commented 2 years ago

My question in the forum has been answered: https://forum.obsidian.md/t/how-to-get-current-file-content-without-yaml-frontmatter/26197/2

I haven't tried the solution yet.

Great to know @Taitava ! Let's hope that we have a good solution 🙏

marvinwu commented 2 years ago

Thanks for this great plugin and it is very useful, just a very hacky thought , instead of using obsidian api, since we know the current file path already, can we just cat the file in bash to get the content ?

Taitava commented 2 years ago

Thank you @marvinwu for your positive feedback! ❤️ cat works very well as a workaround solution, if users use it in their own shell commands. It just doesn't make it easy to get the content without YAML frontmatter, in case a user doesn't want the frontmatter.

What comes to this actual {{note_content}} variable, in theory it could be implemented so that it would execute a cat command under the hood (I don't know if you meant to suggest that or not), but there's two reasons why I wouldn't do it:

But anyway, cat is a good workaround for users until this variable finally gets implemented.

Taitava commented 2 years ago

Success

I was able to make this variable work! I did the needed variable system refactoring (issue #265). I still need to do extensive testing, because the changes were quite big, so need to ensure I didn't break anything in the variable parsing process.

I'll update this issue when the variable is ready to be released.

TODO:

Taitava commented 1 year ago

Released now.