Skip to content
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

Error creating file in .dev version: No file system handle registered #1404

Open
markschaver opened this issue Oct 9, 2024 · 15 comments
Open

Comments

@markschaver
Copy link

Describe the bug

On a Mac, when I attempt to create a new file or open a daily note in the .dev version of Foam, I get an error message: No file system handle registered. I am using v0.26.1 of the extension.

Errors:

Command 'Foam: Create New Note' resulted in an error
Unable to write file '/markschaver/foamtest/Test.md' (Unavailable (FileSystemError): Error: No file system handle registered (/markschaver))

Command 'Foam: Open Daily Note' resulted in an error
Unable to write file '/markschaver/foamtest/2024-10-09.md' (Unavailable (FileSystemError): Error: No file system handle registered (/markschaver))

Small Reproducible Example

https://github.dev/markschaver/foamtest/blob/master/readme.md

Steps to Reproduce the Bug or Issue

  1. Open repository in github.dev by clicking .
  2. Use Cmd-shift-p to create a new file or open a daily note.

Expected behavior

I expect the files to be created. They are not. I am also unable to create new files by clicking on a wiki link.

Screenshots or Videos

No response

Operating System Version

macOS (though experienced same problem on Windows 11 with v26.)

Visual Studio Code Version

Latest .dev version.

Additional context

No response

@pderaaij
Copy link
Collaborator

Which browser are you using? And could you see if vscode.dev works?

@markschaver
Copy link
Author

Chrome. And yes, vscode.dev works otherwise, including other extensions. I have used vscode.dev for a long time. It does not work either in Safari, where I get this error message:

Command 'Foam: Create New Note' resulted in an error
command 'foam-vscode.create-note' not found

@markschaver
Copy link
Author

Tested at work on a Windows 11 machine, same result:

Command 'Foam: Create New Note' resulted in an error
Unable to write file '\markschaver\Notes\AnotherTest.md' (Unavailable (FileSystemError): Error: No file system handle registered (\markschaver))

Full URL: https://vscode.dev/github/markschaver/Notes. Same at https://github.dev/markschaver/Notes/.

Command 'Foam: Create New Note' resulted in an error
Unable to write file '\markschaver\Notes\StillAnotherTest.md' (Unavailable (FileSystemError): Error: No file system handle registered (\markschaver))

@pderaaij
Copy link
Collaborator

During my development work on this I only tested this on local folders. Doing some research it seems we need to add some capabilities to support remote repositories. See: https://code.visualstudio.com/blogs/2021/06/10/remote-repositories#_ensuring-your-extension-works-in-a-virtual-workspace

I will have a look at this in the upcoming weeks.

@pderaaij
Copy link
Collaborator

I've made some progress in this area. Will document my findings here. (@riccardoferretti FYI).

Ultimately, a re mote repository works as a virtual file system. This differs to the normal behaviour of Foam which in some areas looks at absolute paths or simply core functions that work differently. This requires us to handle some paths differently.

For example, the behaviour of workspace.findFiles() is different for local systems or virtual systems. For my test, I need to change the implementation as following:

const uris = await workspace.findFiles(
        folder.uri.scheme === 'vscode-vfs'
          ? '**/*'
          : new RelativePattern(folder.uri.path, '**/*'),
        new RelativePattern(
          folder.uri.path,
          `{${excludePatterns.get(folder.name).join(',')}}`
        )
      );

Note: Here I detect that the workspace folder is of the scheme vscode-vfs (virtual), if so, the include pattern should not consider the folder path (for my case here: /pderaaij/secondbrain). Locally this path is: /Users/paulderaaij/projects/secondbrain.

With this little change, Foam can load the graph and get most things working. However, Foam can't create files right now. I need to look into that behaviour, but will do with a fresh mind.

So, making some steps. However, I need some time to check some things before fully publishing a solution.

@riccardoferretti
Copy link
Collaborator

Mmmm... I am not sure, the folder there is coming from VS Code and it's one of the workspace folders, I don't understand how that would cause an issue. It is needed to support multi-folder workspaces (as opposed to opening a simple folder).
Am I missing something?

@pderaaij
Copy link
Collaborator

I am thinking RelativePattern causes the issue, but need to verify that.

@pderaaij
Copy link
Collaborator

pderaaij commented Oct 19, 2024

So, did some digging into the way we use RelativePattern in workspace.findFiles. I started to look at the value of RelativePattern.baseUri when opening a local folder and a remote repository.

Locally: the baseUri is file:///Users/paulderaaij/projects/secondbrain. Which is correct with my local path and the right scheme: file.

Remote Repository: the baseUri is file:///pderaaij/secondbrain. Which is the correct path, but not the correct scheme. This should not be file, but vscode-vfs.

That is odd. So I've done some research and found out that RelativePattern accepts a WorkspaceFolder as argument in the constructor. Passing the folder allows RelativePattern to correctly construct the pattern. Changing the code of workspace.findFiles to the code below fixed this part of the issue, without if-else constructs.

const uris = await workspace.findFiles(
        new RelativePattern(folder, '**/*'),
        new RelativePattern(
          folder,
          `{${excludePatterns.get(folder.name).join(',')}}`
        )
      );

Resulting into the following baseUri for the remote repository: vscode-vfs://github/pderaaij/secondbrain

@pderaaij
Copy link
Collaborator

I've done some research on writing files, for example the daily note. The main issue here is that NoteFactory determines the new file path for the note. In doing so, we use the helper URI.file of Foams URI model. In doing so, we disregard the notion that schemes apart from file or placeholder exist. On the other hand, we would rather not check for the proper scheme everywhere.

So, I need some reflection on how to solve this. Especially as the only way to know if you are active on a virtual workspace is determined via the workspaceFolder. The initial thought I have is to set a flag on bootstrap of the project, which can be used in the URI model to return the proper scheme. But, open to suggestions here!

@riccardoferretti
Copy link
Collaborator

Thanks for the research @pderaaij - I will do a deep dive this weekend, I feel there are a few things I don't understand enough to give informed support. I am keen to keep to a bare minimum the difference between the code for the native and the web extension, and am willing to make some tweaks to the assumptions in Foam to make that happen (e.g. remove any support we might have for files that live outside the workspace). Let me have a think, and let me know if you have any update on your side as well, thanks!

@pderaaij
Copy link
Collaborator

The RelativePattern one is a safe one and won't impact that much. The NoteFactory change will be more impactful, but not sure if this is the proper way to go.

Regarding research. The most important thing is the structure of WorkspaceFolder the scheme attribute is essential in the process.

@pderaaij
Copy link
Collaborator

@riccardoferretti Would be great if you can have a look at it this weekend. Currently, I feel the best approach is to add an optional inContext argument to the URI.file. This allows us to not break all implementation, but also to separate the vscode-vfs concern away from the models in core. Example implementation could be:

/**
   *
   * @param value Creates an URI pointing to the given path of the file.
   *
   * @param inContext Can be used to point to the path in a given context. For example,
   *                  to be used for schemes other then 'file' e.g. 'vscode-vfs'
   * @returns URI object with path pointing to the given value.
   */
  static file(value: string, inContext: URI = undefined): URI {
    const [path, authority] = pathUtils.fromFsPath(value);

    if (inContext !== undefined) {
      return new URI({ ...inContext, path: path });
    }

    return new URI({ scheme: 'file', authority, path });
  }

Note: need to think about authority here. Requires some additional research.

We can then use it at the appropriate place. For example in createFromTemplate in NoteFactory

let newFilePath = template.metadata.has('filepath')
        ? URI.file(
            template.metadata.get('filepath'),
            URI.parse(workspace.workspaceFolders[0].uri.toString())
          )
        : filepathFallbackURI;

That ensures we give the vscode context to file in URI.

Please let me know what you think. I haven't put this into code for now. Just some prototyping.

@riccardoferretti
Copy link
Collaborator

Thanks for the write up @pderaaij - I have gone through your comments and the code, I think I roughly understand the problem. Before digging too deeply I wanted to reproduce the issue, and although I can see the problem in github.dev, I have been unable to reproduce the issue in other environments.
Specifically, even setting up vscode.dev and loading the extension there (basically following the instructions here: https://code.visualstudio.com/api/extension-guides/web-extensions#test-your-web-extension-in-vscode.dev) I still can't reproduce the issue - which makes it hard to assess ideas.
Where are you reproducing the issue? Am I missing anything?

@pderaaij
Copy link
Collaborator

You need the Github.remotehub extension. This allows you to open remote repositories. It is the same mechanism as vscofe.dev uses. See https://marketplace.visualstudio.com/items?itemName=github.remotehub&origin=serp_auto

So. I install this extension and then open a GitHub repo that I used for Foam.

@riccardoferretti
Copy link
Collaborator

@pderaaij I have looked a bit more at the issue.
The approach I would explore is staying within the URI realm in the context of the VS Code workspace.
Specifically, the function asAbsoluteWorkspaceUri turns a URI into a absolute file:// URI.
I don't remember if there was a good reason for this, but basically this is not necessary, as we could always live within the workspace.workspaceFolders context and therefore anything absolute is really just absolute in relationship to the workspace.
In other words, if making something absolute in the end boils down to a workspace.workspaceFolder[...].joinPath(...) you will alway get Uris that should be compatible with vscode-vfs.
What do you think?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants