jonnyboyC / kos-language-server

A language server for the Kerboscript (kOS) a language for Kerbal Space Program
MIT License
27 stars 6 forks source link

[Feature] Better handling of absolute and local disk relative paths. #164

Open Lafreakshow opened 4 years ago

Lafreakshow commented 4 years ago

First of all, I hope I haven't simply overlooked something in the manual. If this feature does already exist I would like a bit of shame for missing that and a pointer to it.

Is your feature request related to a problem? Please describe. Quite simply, the server expects all paths to be relative to either the archive volume or the current file, which is not really problematic but slightly annoying behaviour.

Consider this Example:

Archive:/
    boot/system_loader.ks
    system/main.ks
    system/lib/some_lib.ks

system_loader.ks copies the entire structure of system to the local volume, essentially copying 0:/system/**/* to 1:/system/*/. It then sets the bootfile to main.ks, deletes itself and reboots the system.

This works wonderfully, main.ks is executed in 1:/ and can load some_lib via runoncepath("/system/lib/some_lib"). However, the language server doesn't understand this and complains that system/lib/some_lib.ks can't be found. This happens with or without the leading slash and 1:/system/lib/some_lib" leads to the same result. only "../system/lib/some_lib", "lib/some_lib" and "0:/system/lib/some_lib" are correctly understood by the server but none of these would actually work in game as the current volume isn't 0, the archive may not be accesible and the current working directory isn't system/. Thanks to #include I can still get completion for some_lib.ks, but it is still annoying to have this unresovable "error" in the code.

Describe the solution you'd like KOS interprets paths starting with a slash as relative to the current volume. So in case of the above example "/system/main.ks" resolves to "1:/system/main.ks" (so these paths are very comparable to how in linux a leading slash refers to the root of the filesystem). The server obviously can't have information on the local file structure but it does know the Archive file structure so my proposal would be an option to treat paths with a leading slash as being relative to the archive.

Describe alternatives you've considered Going beyond the above proposal, there could be an option to allow the server to interpret any absolute path starting with a slash or an explicit volume name as relative to the archive, essentially assuming that every local disk is a perfect copy of the archive.

Another alternative could also be a directive similar to #include to make the server ignore these errors, potentially even with the option to point the server to the correct location on the archive, thus making an additonal include uncessary to get completion working.

How this could look:

runpath("/system/lib/some_lib"). // #ignore unable_to_load_file

// OR

runpath("/system/lib/some_lib"). // #source "0:/system/lib/some_lib"

Note that the first example is written in a way that would allow the directive to ignore any error similar to the comments found in most linters. Making the directive be specific to this one error is probably a lot less work. I mostly just did it like this because it's a pattern programmers are already familiar with.

A third alternative could be a directive to essentially tell the server from where it should resolve paths. Something like this:

// #root "0:/"

Or if, for example, we copy 0:/system/**/* to 1:/*/, flattening the directory structure:

// #root "0:/system"

Instead of a directive, this could also be a workspace setting (in case of vscode, at least).


A relatively simple ignore directive may actually be the most sensible solution. Depends on how much work the alternatives would be (And how much free time one has I guess). In the end a directive would probably have to be implemented either way as interpreting all paths as relative to Archive would then result in paths relative to something else being complained about so regardless of whether one of the other solutions is implemented, there would always be a case where a valid path isn't recognized as such due to the fact that the language server can't have information on local volumes.

I would prefer a combination of my first proposal and both of the ignore directives but any alternative would be great.


Lastly, somewhat unrelated, Let me say how grateful I am for this project existing and how great it is to see it still maintained. It makes it approximately 10000 times more comfortable to write KOS scripts.

jonnyboyC commented 4 years ago

@Lafreakshow glad the project has been a big help. I know personally I learn languages much quicker with the kind of hints the server is hopefully providing.

I definitely like this proposal! I think this is a real issue and should be addressed. I think both the leading slash and the #// ignore dircetives are great ideas. I'll need to do some research into how KOS does file resolutions to makes sure there aren't any weird edge cases but I think both ideas make a lot of sense.