mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-07-09 21:54:59 +00:00
swap in tower-lsp-server dependency (#100)
This commit is contained in:
parent
33fb726bdc
commit
e098272ea6
11 changed files with 72 additions and 51 deletions
|
@ -5,6 +5,6 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
pyo3 = { workspace = true }
|
||||
tower-lsp = { workspace = true }
|
||||
tower-lsp-server = { workspace = true, features = ["proposed"] }
|
||||
|
||||
which = "7.0.1"
|
||||
|
|
|
@ -5,7 +5,7 @@ pub use templatetags::TemplateTags;
|
|||
use pyo3::prelude::*;
|
||||
use std::fmt;
|
||||
use std::path::{Path, PathBuf};
|
||||
use tower_lsp::lsp_types::*;
|
||||
use tower_lsp_server::lsp_types::*;
|
||||
use which::which;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -24,21 +24,6 @@ impl DjangoProject {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn from_initialize_params(params: &InitializeParams) -> Option<Self> {
|
||||
// Try current directory first
|
||||
let path = std::env::current_dir()
|
||||
.ok()
|
||||
// Fall back to workspace root if provided
|
||||
.or_else(|| {
|
||||
params
|
||||
.root_uri
|
||||
.as_ref()
|
||||
.and_then(|uri| uri.to_file_path().ok())
|
||||
});
|
||||
|
||||
path.map(Self::new)
|
||||
}
|
||||
|
||||
pub fn initialize(&mut self) -> PyResult<()> {
|
||||
let python_env = PythonEnvironment::new().ok_or_else(|| {
|
||||
PyErr::new::<pyo3::exceptions::PyRuntimeError, _>("Could not find Python in PATH")
|
||||
|
|
|
@ -13,4 +13,6 @@ pyo3 = { workspace = true }
|
|||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tower-lsp = { workspace = true }
|
||||
tower-lsp-server = { workspace = true }
|
||||
|
||||
percent-encoding = "2.3"
|
||||
|
|
|
@ -1,11 +1,7 @@
|
|||
use anyhow::{anyhow, Result};
|
||||
use djls_project::TemplateTags;
|
||||
use std::collections::HashMap;
|
||||
use tower_lsp::lsp_types::{
|
||||
CompletionItem, CompletionItemKind, CompletionResponse, DidChangeTextDocumentParams,
|
||||
DidCloseTextDocumentParams, DidOpenTextDocumentParams, Documentation, InsertTextFormat,
|
||||
MarkupContent, MarkupKind, Position, Range,
|
||||
};
|
||||
use tower_lsp_server::lsp_types::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Store {
|
||||
|
@ -23,7 +19,7 @@ impl Store {
|
|||
|
||||
pub fn handle_did_open(&mut self, params: DidOpenTextDocumentParams) -> Result<()> {
|
||||
let document = TextDocument::new(
|
||||
String::from(params.text_document.uri),
|
||||
params.text_document.uri.to_string(),
|
||||
params.text_document.text,
|
||||
params.text_document.version,
|
||||
params.text_document.language_id,
|
||||
|
@ -58,7 +54,7 @@ impl Store {
|
|||
}
|
||||
|
||||
pub fn handle_did_close(&mut self, params: DidCloseTextDocumentParams) -> Result<()> {
|
||||
self.remove_document(&String::from(params.text_document.uri));
|
||||
self.remove_document(params.text_document.uri.as_str());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,19 +1,19 @@
|
|||
mod documents;
|
||||
mod server;
|
||||
mod tasks;
|
||||
mod workspace;
|
||||
|
||||
use crate::server::DjangoLanguageServer;
|
||||
use anyhow::Result;
|
||||
use tower_lsp_server::{LspService, Server};
|
||||
|
||||
pub async fn serve() -> Result<()> {
|
||||
let stdin = tokio::io::stdin();
|
||||
let stdout = tokio::io::stdout();
|
||||
|
||||
let (service, socket) = tower_lsp::LspService::build(DjangoLanguageServer::new).finish();
|
||||
let (service, socket) = LspService::build(DjangoLanguageServer::new).finish();
|
||||
|
||||
tower_lsp::Server::new(stdin, stdout, socket)
|
||||
.serve(service)
|
||||
.await;
|
||||
Server::new(stdin, stdout, socket).serve(service).await;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
|
@ -1,12 +1,13 @@
|
|||
use crate::documents::Store;
|
||||
use crate::workspace::get_project_path;
|
||||
use anyhow::Result;
|
||||
use djls_project::DjangoProject;
|
||||
use djls_worker::Worker;
|
||||
use std::sync::Arc;
|
||||
use tokio::sync::RwLock;
|
||||
use tower_lsp::jsonrpc::Result as LspResult;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use tower_lsp::{Client, LanguageServer};
|
||||
use tower_lsp_server::jsonrpc::Result as LspResult;
|
||||
use tower_lsp_server::lsp_types::*;
|
||||
use tower_lsp_server::{Client, LanguageServer};
|
||||
|
||||
const SERVER_NAME: &str = "Django Language Server";
|
||||
const SERVER_VERSION: &str = "0.1.0";
|
||||
|
@ -34,12 +35,12 @@ impl DjangoLanguageServer {
|
|||
}
|
||||
}
|
||||
|
||||
#[tower_lsp::async_trait]
|
||||
impl LanguageServer for DjangoLanguageServer {
|
||||
async fn initialize(&self, params: InitializeParams) -> LspResult<InitializeResult> {
|
||||
let project = DjangoProject::from_initialize_params(¶ms);
|
||||
let project_path = get_project_path(¶ms);
|
||||
|
||||
if let Some(mut project) = project {
|
||||
if let Some(path) = project_path {
|
||||
let mut project = DjangoProject::new(path);
|
||||
match project.initialize() {
|
||||
Ok(()) => {
|
||||
self.log_message(
|
||||
|
@ -109,7 +110,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
|
||||
self.log_message(
|
||||
MessageType::INFO,
|
||||
&format!("Opened document: {}", params.text_document.uri),
|
||||
&format!("Opened document: {:?}", params.text_document.uri),
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
|
@ -128,7 +129,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
|
||||
self.log_message(
|
||||
MessageType::INFO,
|
||||
&format!("Changed document: {}", params.text_document.uri),
|
||||
&format!("Changed document: {:?}", params.text_document.uri),
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
|
@ -147,7 +148,7 @@ impl LanguageServer for DjangoLanguageServer {
|
|||
|
||||
self.log_message(
|
||||
MessageType::INFO,
|
||||
&format!("Closed document: {}", params.text_document.uri),
|
||||
&format!("Closed document: {:?}", params.text_document.uri),
|
||||
)
|
||||
.await
|
||||
.ok();
|
||||
|
|
41
crates/djls-server/src/workspace.rs
Normal file
41
crates/djls-server/src/workspace.rs
Normal file
|
@ -0,0 +1,41 @@
|
|||
use percent_encoding::percent_decode_str;
|
||||
use std::path::PathBuf;
|
||||
use tower_lsp_server::lsp_types::{InitializeParams, Uri};
|
||||
|
||||
/// Determines the project root path from initialization parameters.
|
||||
///
|
||||
/// Tries the current directory first, then falls back to the first workspace folder.
|
||||
pub fn get_project_path(params: &InitializeParams) -> Option<PathBuf> {
|
||||
// Try current directory first
|
||||
std::env::current_dir().ok().or_else(|| {
|
||||
// Fall back to the first workspace folder URI
|
||||
params
|
||||
.workspace_folders
|
||||
.as_ref()
|
||||
.and_then(|folders| folders.first())
|
||||
.and_then(|folder| uri_to_pathbuf(&folder.uri))
|
||||
})
|
||||
}
|
||||
|
||||
/// Converts a `file:` URI into an absolute `PathBuf`.
|
||||
fn uri_to_pathbuf(uri: &Uri) -> Option<PathBuf> {
|
||||
// Check if the scheme is "file"
|
||||
if uri.scheme().map_or(true, |s| s.as_str() != "file") {
|
||||
return None;
|
||||
}
|
||||
|
||||
// Get the path part as a string
|
||||
let encoded_path_str = uri.path().as_str();
|
||||
|
||||
// Decode the percent-encoded path string
|
||||
let decoded_path_cow = percent_decode_str(encoded_path_str).decode_utf8_lossy();
|
||||
let path_str = decoded_path_cow.as_ref();
|
||||
|
||||
#[cfg(windows)]
|
||||
let path_str = {
|
||||
// Remove leading '/' for paths like /C:/...
|
||||
path_str.strip_prefix('/').unwrap_or(path_str)
|
||||
};
|
||||
|
||||
Some(PathBuf::from(path_str))
|
||||
}
|
|
@ -5,7 +5,7 @@ edition = "2021"
|
|||
|
||||
[dependencies]
|
||||
anyhow = { workspace = true }
|
||||
lsp-types = { workspace = true }
|
||||
tower-lsp-server = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
thiserror = { workspace = true }
|
||||
toml = "0.8"
|
||||
|
|
|
@ -1,9 +1,9 @@
|
|||
use crate::ast::{AstError, Span};
|
||||
use crate::lexer::LexerError;
|
||||
use crate::parser::ParserError;
|
||||
use lsp_types;
|
||||
use serde::Serialize;
|
||||
use thiserror::Error;
|
||||
use tower_lsp_server::lsp_types;
|
||||
|
||||
#[derive(Debug, Error, Serialize)]
|
||||
pub enum TemplateError {
|
||||
|
@ -71,14 +71,11 @@ impl TemplateError {
|
|||
}
|
||||
|
||||
pub fn to_lsp_diagnostic(error: &TemplateError, _source: &str) -> lsp_types::Diagnostic {
|
||||
let range = error.span().map_or_else(
|
||||
|| lsp_types::Range::default(),
|
||||
|span| {
|
||||
let start = lsp_types::Position::new(0, *span.start());
|
||||
let end = lsp_types::Position::new(0, span.start() + span.length());
|
||||
lsp_types::Range::new(start, end)
|
||||
},
|
||||
);
|
||||
let range = error.span().map_or_else(lsp_types::Range::default, |span| {
|
||||
let start = lsp_types::Position::new(0, *span.start());
|
||||
let end = lsp_types::Position::new(0, span.start() + span.length());
|
||||
lsp_types::Range::new(start, end)
|
||||
});
|
||||
|
||||
lsp_types::Diagnostic {
|
||||
range,
|
||||
|
|
|
@ -15,6 +15,6 @@ pyo3 = { workspace = true, features = ["extension-module"] }
|
|||
pyo3-async-runtimes = { workspace = true, features = ["tokio-runtime"] }
|
||||
serde_json = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tower-lsp-server = { workspace = true }
|
||||
|
||||
clap = { version = "4.5", features = ["derive"] }
|
||||
tower-lsp = { version = "0.20", features = ["proposed"] }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue