Skip to content
Open
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
78 changes: 78 additions & 0 deletions .github/workflows/release-proxy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
name: Release Proxy Binary

on:
push:
tags:
- "v*"

permissions:
contents: write

jobs:
build:
name: Build ${{ matrix.asset_name }}
runs-on: ${{ matrix.runner }}
strategy:
fail-fast: false
matrix:
include:
- target: aarch64-apple-darwin
runner: macos-14
asset_name: java-lsp-proxy-darwin-aarch64.tar.gz
- target: x86_64-apple-darwin
runner: macos-14
asset_name: java-lsp-proxy-darwin-x86_64.tar.gz
- target: x86_64-unknown-linux-gnu
runner: ubuntu-latest
asset_name: java-lsp-proxy-linux-x86_64.tar.gz
- target: aarch64-unknown-linux-gnu
runner: ubuntu-latest
asset_name: java-lsp-proxy-linux-aarch64.tar.gz
cross: true
- target: x86_64-pc-windows-msvc
runner: windows-latest
asset_name: java-lsp-proxy-windows-x86_64.zip
- target: aarch64-pc-windows-msvc
runner: windows-latest
asset_name: java-lsp-proxy-windows-aarch64.zip

steps:
- name: Checkout
uses: actions/checkout@v4

- name: Install Rust toolchain
uses: dtolnay/rust-toolchain@stable
with:
targets: ${{ matrix.target }}

- name: Install cross (Linux aarch64)
if: matrix.cross
run: cargo install cross --git https://github.com/cross-rs/cross

- name: Build proxy binary
working-directory: proxy
run: |
if [ "${{ matrix.cross }}" = "true" ]; then
cross build --release --target ${{ matrix.target }}
else
cargo build --release --target ${{ matrix.target }}
fi
Comment on lines +55 to +59
Copy link
Contributor

Choose a reason for hiding this comment

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

Think there might be something missing here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Something might indeed be off

shell: bash

- name: Package binary (Unix)
if: runner.os != 'Windows'
run: |
tar -czf ${{ matrix.asset_name }} \
-C proxy/target/${{ matrix.target }}/release \
java-lsp-proxy

- name: Package binary (Windows)
if: runner.os == 'Windows'
shell: pwsh
run: |
Compress-Archive -Path proxy/target/${{ matrix.target }}/release/java-lsp-proxy.exe -DestinationPath ${{ matrix.asset_name }}

- name: Upload release asset
uses: softprops/action-gh-release@v2
with:
files: ${{ matrix.asset_name }}
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
grammars/
target/
proxy/target/
extension.wasm
.DS_Store
34 changes: 34 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
native_target := `rustc -vV | grep host | awk '{print $2}'`
ext_dir := if os() == "macos" { env("HOME") / "Library/Application Support/Zed/extensions/work/java" } else if os() == "linux" { env("HOME") / ".local/share/zed/extensions/work/java" } else { env("LOCALAPPDATA") / "Zed/extensions/work/java" }
proxy_bin := ext_dir / "proxy-bin" / "java-lsp-proxy"

# Build proxy in debug mode
proxy-build:
cd proxy && cargo build --target {{ native_target }}

# Build proxy in release mode
proxy-release:
cd proxy && cargo build --release --target {{ native_target }}

# Build proxy release and install to extension workdir for testing
proxy-install: proxy-release
mkdir -p "{{ ext_dir }}/proxy-bin"
cp "proxy/target/{{ native_target }}/release/java-lsp-proxy" "{{ proxy_bin }}"
@echo "Installed to {{ proxy_bin }}"

# Build WASM extension in release mode
ext-build:
cargo build --release

# Format all code
fmt:
cargo fmt --all
cd proxy && cargo fmt --all

# Run clippy on both crates
clippy:
cargo clippy --all-targets --fix --allow-dirty
cd proxy && cargo clippy --all-targets --fix --allow-dirty --target {{ native_target }}

# Build everything: fmt, clippy, extension, proxy install
all: fmt clippy ext-build proxy-install
2 changes: 2 additions & 0 deletions proxy/.cargo/config.toml
Copy link
Contributor

Choose a reason for hiding this comment

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

Do we need this?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Rust-analyzer without it wasn't able to recognize the active code behind cfg. I'm open to better options. The idea otherwise was to provide all possible values as comment and ask the maintainer to select the proper system.

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[build]
target = "aarch64-apple-darwin"
188 changes: 188 additions & 0 deletions proxy/Cargo.lock

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

21 changes: 21 additions & 0 deletions proxy/Cargo.toml
Copy link
Contributor

Choose a reason for hiding this comment

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

We could perhaps consider to just make the extension a "proper" Rust workspace? Not sure it is worth it though (or causes some other issues), but might be a bit nicer to work with.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I agree, it is annoying to have two windows open, one with the extension as root and one with the proxy.

Let me see whether the extension will work correctly even with that enabled.

Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
[package]
name = "java-lsp-proxy"
version = "6.8.12"
edition = "2021"
publish = false
license = "Apache-2.0"
description = "Native LSP proxy for the Zed Java extension"

[[bin]]
name = "java-lsp-proxy"
path = "src/main.rs"

[dependencies]
serde = { version = "1.0", features = ["derive"] }
serde_json = "1.0"

[target.'cfg(unix)'.dependencies]
libc = "0.2"

[target.'cfg(windows)'.dependencies]
windows-sys = { version = "0.59", features = ["Win32_System_Threading", "Win32_Foundation", "Win32_System_Diagnostics_ToolHelp"] }
59 changes: 59 additions & 0 deletions proxy/src/completions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
use serde_json::Value;

pub fn should_sort_completions(msg: &Value) -> bool {
msg.get("result").is_some_and(|result| {
result.get("items").is_some_and(|v| v.is_array()) || result.is_array()
})
}

pub fn sort_completions_by_param_count(msg: &mut Value) {
let items = if let Some(result) = msg.get_mut("result") {
if result.is_array() {
result.as_array_mut()
} else {
result.get_mut("items").and_then(|v| v.as_array_mut())
}
} else {
None
};

if let Some(items) = items {
for item in items.iter_mut() {
let kind = item.get("kind").and_then(|v| v.as_u64()).unwrap_or(0);
if kind == 2 || kind == 3 {
let detail = item
.pointer("/labelDetails/detail")
.and_then(|v| v.as_str())
.unwrap_or("");
let count = count_params(detail);
let existing = item.get("sortText").and_then(|v| v.as_str()).unwrap_or("");
item["sortText"] = Value::String(format!("{count:02}{existing}"));
}
}
}
}

fn count_params(detail: &str) -> usize {
if detail.is_empty() || detail == "()" {
return 0;
}
let inner = detail
.strip_prefix('(')
.and_then(|s| s.strip_suffix(')'))
.unwrap_or(detail)
.trim();
if inner.is_empty() {
return 0;
}
let mut count = 1usize;
let mut depth = 0i32;
for ch in inner.chars() {
match ch {
'<' => depth += 1,
'>' => depth -= 1,
',' if depth == 0 => count += 1,
_ => {}
}
}
count
}
Loading