diff --git a/README.md b/README.md index d94891b8..fd7bce97 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,7 @@ Download latest [release](https://github.com/Nimaoth/Nev/releases) or [build fro - [Configuration](docs/configuration.md) - [Finders](docs/finders.md) - [Plugin API](https://nimaoth.github.io/AbsytreeDocs/scripting_nim/htmldocs/theindex.html). +- [Virtual file system](docs/virtual_file_system.md) ## Screenshots diff --git a/docs/getting_started.md b/docs/getting_started.md index d220ee4f..385e4312 100644 --- a/docs/getting_started.md +++ b/docs/getting_started.md @@ -17,5 +17,8 @@ To open this document at any time run the command `help` or `explore-help`. ## Sessions [Go here](sessions.md) to learn how to create sessions to persist editor state when closing (e.g. open files, workspace folders, breakpoints) +## Virtual file system +[Go here](virtual_file_system.md) to learn about the virtual file systems used by Nev. + ## Workspaces [Go here](workspaces.md) to learn about workspaces. diff --git a/docs/virtual_file_system.md b/docs/virtual_file_system.md new file mode 100644 index 00000000..f2b4ed9e --- /dev/null +++ b/docs/virtual_file_system.md @@ -0,0 +1,377 @@ +# Virtual file system (VFS) + +Nev uses a virtual file system internally. The VFS is a tree of different types of file systems (local, in-memory, remote, etc.). + +Here are the types of file systems that are supported: +- `VFS` - The base type for all other file systems, which can be used as a container/folder for other VFSs. +- `VFSInMemory` - This file system stores files in RAM. +- `VFSLocal` - This represents your local filesystem. +- `VFSLink` - This file system can link into a subfolder of another file systems. Cycles are not allowed. + +By default Nev creates a VFS hierarchy which contains the local file system under `local://`, and some links into that for convenience: +- `app://` links to the directory when Nev is installed under `local://` +- `home://` links to the user home directory under `local://` +- `ws0://`, `ws1://` etc. link to the workspace folders. +- `ws://0`, `ws://1` etc. link to the workspace folders. +- `plugs://`, contains plugin sources (if available) + +To explore the entire VFS in the builtin file explorer you can run the command `explore-file "" true` (to see some more info about the VFSs) or just `explore-files` + +![alt](https://raw.githubusercontent.com/Nimaoth/AbsytreeScreenshots/main/vfs.png) + +You can see the also VFS hierarchy by running the command `dump-vfs-hierarchy`, which will output something like this: +``` +VFS() + '' -> VFSLink(, VFSLocal(local://)/) + 'local://' -> VFSLocal(local://) + 'app://' -> VFSLink(app://, VFSLocal(local://)//home/xyz/Nev) + 'plugs://' -> VFS(plugs://) + 'keybindings_plugin' -> VFSInMemory(keybindings_plugin) + 'my_plugin' -> VFSInMemory(my_plugin) + 'ws://' -> VFS(ws://) + '0' -> VFSLink(0, VFSLocal(local://)//home/xyz/my project) + 'home://' -> VFSLink(home://, VFSLocal(local://)//home/xyz) + 'ws0://' -> VFSLink(ws0://, VFSLocal(local://)//home/xyz/my project) +``` +Here is a visual representation. + + + +DFA + + + +VFS\nroot + +VFS +root + + + +VFS\nPlugin sources + +VFS +Plugin sources + + + +VFS\nroot->VFS\nPlugin sources + + +'plugs://' + + + +VFSLink\nForward to local\n + +VFSLink +Forward to local + + + +VFS\nroot->VFSLink\nForward to local\n + + +'' + + + +VFSLink\nApp directory\n/home/xyz/Nev + +VFSLink +App directory +/home/xyz/Nev + + + +VFS\nroot->VFSLink\nApp directory\n/home/xyz/Nev + + +'app://' + + + +VFSLink\nHome directory\n/home/xyz + +VFSLink +Home directory +/home/xyz + + + +VFS\nroot->VFSLink\nHome directory\n/home/xyz + + +'home://' + + + +VFSLink\nFirst workspace folder\n/home/xyz/my project + +VFSLink +First workspace folder +/home/xyz/my project + + + +VFS\nroot->VFSLink\nFirst workspace folder\n/home/xyz/my project + + +'ws0://' + + + +VFSLocal\n + +VFSLocal + + + +VFS\nroot->VFSLocal\n + + +'local://' + + + +VFS\nWorkspace folders + +VFS +Workspace folders + + + +VFS\nroot->VFS\nWorkspace folders + + +'ws://' + + + +VFSInMemory\n + +VFSInMemory + + + +VFS\nPlugin sources->VFSInMemory\n + + +'keybindings_plugin' + + + +VFSLink\nForward to local\n->VFSLocal\n + + + + + +VFSLink\nForward to local\n->VFSLocal\n + + + + + +VFSLink\nApp directory\n/home/xyz/Nev->VFSLocal\n + + + + + +Nev + +Nev + + + +VFSLink\nApp directory\n/home/xyz/Nev->Nev + + + + + +VFSLink\nHome directory\n/home/xyz->VFSLocal\n + + + + + +xyz + +xyz + + + +VFSLink\nHome directory\n/home/xyz->xyz + + + + + +VFSLink\nFirst workspace folder\n/home/xyz/my project->VFSLocal\n + + + + + +my project + +my project + + + +VFSLink\nFirst workspace folder\n/home/xyz/my project->my project + + + + + +home + +home + + + +VFSLocal\n->home + + + + + +root + +root + + + +VFSLocal\n->root + + + + + +... + +... + + + +VFSLocal\n->... + + + + + +home->xyz + + + + + +xyz->Nev + + + + + +xyz->my project + + + + + +VFSLink\nWorkspace 0\n/home/xyz/my project + +VFSLink +Workspace 0 +/home/xyz/my project + + + +VFS\nWorkspace folders->VFSLink\nWorkspace 0\n/home/xyz/my project + + +'0' + + + +VFSLink\nWorkspace 0\n/home/xyz/my project->VFSLocal\n + + + + + +VFSLink\nWorkspace 0\n/home/xyz/my project->my project + + + + + + +With the given VFS, the following paths would refer to these files: + +| VFS Path | Normalized path | Explanation | +| ------------------------- | -------------- | - | +| `local:///home/xyz/Nev/nev.exe` | `local:///home/xyz/Nev/nev.exe` | The `local://` prefix refers to a VFSLocal, which itself doesn't link to other VFSs. | +| `/home/xyz/Nev/nev.exe` | `local:///home/xyz/Nev/nev.exe` | This path doesn't match any of the prefixes of the form `xyz://`, but it does match the VFSLink with an empty prefix, which in turn links to the VFSLocal | +| `home://Nev/nev.exe` | `local:///home/xyz/Nev/nev.exe` | The `home://` prefix refers to `local:///home/xyz`, add to that `Nev/nev.exe` | +| `app://nev.exe` | `local:///home/xyz/Nev/nev.exe` | The `app://` prefix refers to `local:///home/xyz/Nev`, add to that `nev.exe` | +| `ws0://foo.txt` | `local:///home/xyz/my project/foo.txt` | The `ws0://` prefix refers to `local:///home/xyz/my project`, add to that `foo.txt` | +| `ws://0/foo.txt` | `local:///home/xyz/my project/foo.txt` | The `ws://` prefix refers to a sub VFS, and in there the `0` prefix refers to `local:///home/xyz/my project`, add to that `foo.txt` | +| `plugs://keybindings_plugin/src.nim` | `plugs://keybindings_plugin/src.nim` | The `plugs://` prefix refers to a sub VFS, and in there the `keybindings_plugin` prefix refers to an in memory VFS | + +## Mounting VFSs + +The `mount-vfs` command can be used to mount new VFSs in the VFS hierarchy: + +``` +mount-vfs +``` + +## Examples + +### Mount the nimble packages directory under `nimble://` to have quick access to nim library source code: +```json +// ~/.nev/settings.json +{ + "+wasm-plugin-post-load-commands": [ // Run these commands after loading wasm plugins + [ + "mount-vfs", + null, // Null means mount under the root. If a path is provided then it will be mounted under the VFS the given path resolves to. + "nimble://", // The prefix under which to mount the new VFS + { // VFS description + "type": "link", // create a VFSLink + "target": "home://", // path of the target VFS to link to + "targetPrefix": ".nimble/pkgs2" // Subdirectory within the target VFS + } + ] + ] +} +``` +After running this command the path `nimble://package_name/package.nim` would refer to `home://.nimble/pkgs2/package_name/package.nim`, which in turn refers to `local:///home/xyz/.nimble/pkgs2/package_name/package.nim` + +### Mount a local folder as plugin source. +The `browse-keybinds` finder shows you the source code which defined keybindings (if available). It reads this source code from `plugs:///.nim`, which by default is mounted as an in memory VFS, containing embedded source code from the wasm binary. + +If you develop you're own plugin you might want that to link to you're source code on your local file system instead. + +To do this you can remount the filesystem for your plugin like this: +```json +// ~/.nev/settings.json +{ + "+wasm-plugin-post-load-commands": [ // Run these commands after loading wasm plugins + [ + "mount-vfs", + "plugs://", // Mount the new VFS under the VFS with the prefix 'plugs://' + "my_plugin", // The prefix under which to mount the new VFS + { // VFS description + "type": "link", // create a VFSLink + "target": "local://", // path of the target VFS to link to, you could also use app:// or home:// or whatever. + "targetPrefix": "/path/to/plugin/source" // Subdirectory within the target VFS + } + ] + ] +} +``` +After running this command the path `plugs://my_plugin/source.nim` would not refer to the in-memory VFS anymore but to `local:///path/to/plugin/source/source.nim` instead. diff --git a/src/vfs.nim b/src/vfs.nim index e81735fb..baa6b793 100644 --- a/src/vfs.nim +++ b/src/vfs.nim @@ -158,7 +158,7 @@ proc prettyHierarchy*(self: VFS): string = result.add self.name for m in self.mounts: result.add "\n" - result.add (m.prefix & " -> " & m.vfs.prettyHierarchy()).indent(2) + result.add ("'" & m.prefix & "' -> " & m.vfs.prettyHierarchy()).indent(2) ########################################################