Shared Server Unix Scripts #18
Replies: 8 comments 13 replies
-
This sounds like an interesting idea! The documentation states
For sandboxed applications (in this case, I would presume extensions), will another app populate the applicationScriptsDirectory with the correct scripts? Or how would that work? |
Beta Was this translation helpful? Give feedback.
-
Another question that came up: what language should be used for the scripts? Distributing binaries on macOS is really problematic, so I think a scripting language is a must. Apart from that, I think anything could work, as long as it is uses an agreed-upon script API. Personally, I'm going to use bash. I really hate bash. It's just terrible. But, it has almost no environmental dependencies, and all other languages I have used for scripting (Ruby, Python) do. This means you may make a script that works for some users, but eventually someone will have an unusual Python install and it won't work. |
Beta Was this translation helpful? Give feedback.
-
The script that invokes a language server cannot be shared as it needs to be in the Application Scripts directory of one specific application, but everything else can be in a shared location, where it is invoked by the executable-specific script. (The latter could simply be a shell script setting some paths and doing an exec on the actual language server launcher in a shared location.) |
Beta Was this translation helpful? Give feedback.
-
Generally, I do like your idea. Sharing that work would be great. |
Beta Was this translation helpful? Give feedback.
-
Does it need to be a separate script entirely? For example, in Zed, they define this struct: pub struct PluginLspAdapter {
name: WasiFn<(), String>,
fetch_latest_server_version: WasiFn<(), Option<String>>,
fetch_server_binary: WasiFn<(PathBuf, String), Result<LanguageServerBinary, String>>,
cached_server_binary: WasiFn<PathBuf, Option<LanguageServerBinary>>,
initialization_options: WasiFn<(), String>,
language_ids: WasiFn<(), Vec<(String, String)>>,
executor: Arc<Background>,
runtime: Arc<Mutex<Plugin>>,
} Then an extension would fill in the values with their code. A lot of the language servers are just installed through NPM, so they just call that command: async fn fetch_server_binary(
&self,
version: Box<dyn 'static + Send + Any>,
container_dir: PathBuf,
_: &dyn LspAdapterDelegate,
) -> Result<LanguageServerBinary> {
let version = version.downcast::<String>().unwrap();
let server_path = container_dir.join(SERVER_PATH);
if fs::metadata(&server_path).await.is_err() {
self.node
.npm_install_packages(
&container_dir,
&[("vscode-json-languageserver", version.as_str())],
)
.await?;
}
Ok(LanguageServerBinary {
path: self.node.binary_path().await?,
arguments: server_binary_arguments(&server_path),
})
} Cant we do something similar where an extension just has to implement a protocol in Swift? // Already using this struct in CodeEdit
struct LanguageServerBinary {
let execPath: String
let args: [String]
let env: [String: String]?
}
protocol LanguageServer {
func fetchBinary() -> LanguageServerBinary
func checkForUpdates() -> Bool
func getCurrentVersion() -> String
} We can then use |
Beta Was this translation helpful? Give feedback.
-
Seems like a cool idea! I haven't used |
Beta Was this translation helpful? Give feedback.
-
I threw together a basic repo to hold the scripts, documentation, as well as a Swift package for interaction/installation https://github.com/ChimeHQ/LanguageServerScripts. Currently non-functional. |
Beta Was this translation helpful? Give feedback.
-
I've added some more functionality and documentation to that repo, including a proof-of-concept that can start up gopls (the Go language server) via symlinks to a shared global (well, per-user...) location. It was incredibly difficult to figure out how to re-construct the user's shell environment in Bash, but I think I managed to get it. I have this working with |
Beta Was this translation helpful? Give feedback.
-
The concept of using a (Unix Task)[https://developer.apple.com/documentation/foundation/nsuserunixtask] to run language servers was introduced to me by @mchakravarty. I wasn't even aware of the system before! It is the first time I've ever seen a true sandbox-compatible solution that is explicitly available to all applications, App Store-delivered included.
The thing is, installing and running language servers is, in general, very complex. I think I would be amazing to have a shared pool of scripts which abstracts the process. The idea is a uniform interface for these actions:
Maybe others?
One big limitation of the Application Script system is the directories are scoped to the executable. So, it seems like it would be impossible to have a shared installation location. But I still think such an approach would be beneficial. Does anyone have any thoughts on this?
@Wouter01 @FastestMolasses
Beta Was this translation helpful? Give feedback.
All reactions