Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,4 @@ path = "src/powershell.rs"
crate-type = ["cdylib"]

[dependencies]
zed_extension_api = "0.0.6"
zed_extension_api = "0.2.0"
2 changes: 1 addition & 1 deletion extension.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ repository = "https://github.com/wingyplus/zed-powershell"

[grammars.powershell]
repository = "https://github.com/airbus-cert/tree-sitter-powershell"
commit = "804d86fd4ad286bd0cc1c1f0f7b28bd7af6755ad"
commit = "b3fe65637fca35e426dc8c889d86c8724aaa73d5" # v0.24.4

[language_servers.powershell-es]
name = "PowerShell Editor Services"
Expand Down
2 changes: 1 addition & 1 deletion languages/powershell/config.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name = "PowerShell"
grammar = "powershell"
path_suffixes = ["ps1"]
path_suffixes = ["ps1", "psm1"]
line_comments = ["# "]
# autoclose_before = ";:.,=}])>"
brackets = [
Expand Down
147 changes: 75 additions & 72 deletions languages/powershell/highlights.scm
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
; Keywords
[
"begin"
"break"
"catch"
"class"
"clean"
; "clean"
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is fine to comment this out on this PR. Let's fix the highlights.scm to make it work again on another PR.

"continue"
"data"
"define"
; "define"
"do"
"dynamicparam"
"else"
Expand All @@ -18,7 +19,7 @@
"finally"
"for"
"foreach"
"from"
; "from"
"function"
"hidden"
"if"
Expand All @@ -32,84 +33,86 @@
"trap"
"try"
"until"
"using"
"var"
; "using"
; "var"
"while"
] @keyword

; Powershell Workflows
[
"inlinescript",
"parallel",
"sequence",
"inlinescript"
"parallel"
"sequence"
"workflow"
] @keyword

"-as" @operator
"-ccontains" @operator
"-ceq" @operator
"-cge" @operator
"-cgt" @operator
"-cle" @operator
"-clike" @operator
"-clt" @operator
"-cmatch" @operator
"-cne" @operator
"-cnotcontains" @operator
"-cnotlike" @operator
"-cnotmatch" @operator
"-contains" @operator
"-creplace" @operator
"-csplit" @operator
"-eq" @operator
"-ge" @operator
"-gt" @operator
"-icontains" @operator
"-ieq" @operator
"-ige" @operator
"-igt" @operator
"-ile" @operator
"-ilike" @operator
"-ilt" @operator
"-imatch" @operator
"-in" @operator
"-ine" @operator
"-inotcontains" @operator
"-inotlike" @operator
"-inotmatch" @operator
"-ireplace" @operator
"-is" @operator
"-isnot" @operator
"-isplit" @operator
"-join" @operator
"-le" @operator
"-like" @operator
"-lt" @operator
"-match" @operator
"-ne" @operator
"-notcontains" @operator
"-notin" @operator
"-notlike" @operator
"-notmatch" @operator
"-replace" @operator
"-shl" @operator
"-shr" @operator
"-split" @operator
"-and" @operator
"-or" @operator
"-xor" @operator
"-band" @operator
"-bor" @operator
"-bxor" @operator
"+" @operator
"-" @operator
"/" @operator
"\\" @operator
"%" @operator
"*" @operator
".." @operator
"-not" @operator

[
"-as"
"-ccontains"
"-ceq"
"-cge"
"-cgt"
"-cle"
"-clike"
"-clt"
"-cmatch"
"-cne"
"-cnotcontains"
"-cnotlike"
"-cnotmatch"
"-contains"
"-creplace"
"-csplit"
"-eq"
"-ge"
"-gt"
"-icontains"
"-ieq"
"-ige"
"-igt"
"-ile"
"-ilike"
"-ilt"
"-imatch"
"-in"
"-ine"
"-inotcontains"
"-inotlike"
"-inotmatch"
"-ireplace"
"-is"
"-isnot"
"-isplit"
"-join"
"-le"
"-like"
"-lt"
"-match"
"-ne"
"-notcontains"
"-notin"
"-notlike"
"-notmatch"
"-replace"
"-shl"
"-shr"
"-split"
"-and"
"-or"
"-xor"
"-band"
"-bor"
"-bxor"
"+"
"-"
"/"
"\\"
"%"
"*"
".."
"-not"
] @operator

[
","
Expand Down
39 changes: 0 additions & 39 deletions src/language_server.rs

This file was deleted.

99 changes: 80 additions & 19 deletions src/powershell.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
mod language_server;

use zed_extension_api::{self as zed, settings::LspSettings};

use crate::language_server::PowerShellEditorServices as EditorServices;
use std::fs;
use std::path;
use zed_extension_api::{self as zed, Result};

struct PowerShellExtension {
/// The PowerShell binary, default to `pwsh`.
Expand All @@ -16,7 +14,7 @@ impl zed::Extension for PowerShellExtension {
Self: Sized,
{
Self {
powershell_bin: Some("pwsh".to_string()),
powershell_bin: None,
}
}

Expand All @@ -25,21 +23,13 @@ impl zed::Extension for PowerShellExtension {
language_server_id: &zed_extension_api::LanguageServerId,
worktree: &zed_extension_api::Worktree,
) -> zed_extension_api::Result<zed_extension_api::Command> {
let pwsh_bin = worktree
.which(self.powershell_bin.clone().unwrap().as_str())
.ok_or_else(|| "No PowerShell command found")?;

let bundle_path = LspSettings::for_worktree("powershell-es", worktree)
.ok()
.and_then(|lsp_settings| lsp_settings.binary)
.and_then(|binary| binary.path)
.unwrap();
let pwsh_bin = PowerShellExtension::powershell_binary_path(self, worktree).unwrap();

// TODO: make remote install works.
// let bundle_path = EditorServices::install(language_server_id)
// .map_err(|err| format!("failed to get editor services: {}", err))?;
let bundle_path = self
.language_server_path(language_server_id)
.map_err(|err| format!("failed to get editor services: {}", err))?;

let command = format!("{bundle_path}/PowerShellEditorServices/Start-EditorServices.ps1 -BundledModulesPath {bundle_path} -Stdio -SessionDetailsPath {bundle_path}/powershell-es.session.json -LogPath {bundle_path}/logs -FeatureFlags @() -AdditionalModules @() -HostName zed -HostProfileId 0 -HostVersion 1.0.0 -LogLevel Diagnostic");
let command = format!("Import-Module (Join-Path '{bundle_path}' 'PowerShellEditorServices/PowerShellEditorServices.psd1'); Start-EditorServices -Stdio -SessionDetailsPath '{bundle_path}/powershell-es.session.json' -LogPath '{bundle_path}/logs' -FeatureFlags @() -AdditionalModules @() -HostName zed -HostProfileId 0 -HostVersion 1.0.0 -LogLevel Diagnostic");

Ok(zed::Command {
command: pwsh_bin,
Expand All @@ -54,4 +44,75 @@ impl zed::Extension for PowerShellExtension {
}
}

impl PowerShellExtension {
fn powershell_binary_path(&mut self, worktree: &zed::Worktree) -> Result<String> {
let pwsh_path = match &self.powershell_bin {
Some(path) if fs::metadata(path).map_or(false, |stat| stat.is_file()) => path.clone(),
Some(path) => worktree
.which(path.clone().as_str())
.ok_or_else(|| "PowerShell must be installed for PowerShell Extension")?,
None => worktree
.which("pwsh")
.ok_or_else(|| "PowerShell must be installed for PowerShell Extension")?,
};
self.powershell_bin = Some(pwsh_path.clone());
Ok(pwsh_path)
}

fn language_server_path(
&mut self,
language_server_id: &zed_extension_api::LanguageServerId,
) -> Result<String> {
zed::set_language_server_installation_status(
language_server_id,
&zed::LanguageServerInstallationStatus::CheckingForUpdate,
);

let release = zed::latest_github_release(
"PowerShell/PowerShellEditorServices",
zed::GithubReleaseOptions {
require_assets: true,
pre_release: false,
},
)?;

let asset = release
.assets
.iter()
.find(|asset| asset.name == "PowerShellEditorServices.zip")
.ok_or_else(|| format!("no PowerShellEditorServices.zip found"))?;

let version_dir = format!("powershell-es-{}", release.version);
let lsp_path = format!("{version_dir}/PowerShellEditorServices/Start-EditorServices.ps1");

if !fs::metadata(&lsp_path).map_or(false, |stat| stat.is_file()) {
// Download the asset
zed::set_language_server_installation_status(
&language_server_id,
&zed::LanguageServerInstallationStatus::Downloading,
);
zed::download_file(
&asset.download_url,
&version_dir,
zed::DownloadedFileType::Zip,
)
.map_err(|err| format!("download error {}", err))?;

// Ensure the binary exists
let entries =
fs::read_dir(".").map_err(|e| format!("failed to list working directory {e}"))?;
for entry in entries {
let entry = entry.map_err(|e| format!("failed to load directory entry {e}"))?;
if entry.file_name().to_str() != Some(&version_dir) {
fs::remove_dir_all(entry.path()).ok();
}
}
}

let abs_path =
path::absolute(&version_dir).map_err(|e| format!("failed to get absolute path {e}"))?;
Ok(abs_path.display().to_string())
}
}

zed::register_extension!(PowerShellExtension);