mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-11 12:56:46 +00:00
add djls-django crate (#6)
* add djls-django crate * rework * oops * add check for GDAL and GeoDjango * lots of things * remove unused scripts * move scripts to dedicated mod and make static consts * inline gdal check * rename mod * rename mod * move server info to consts * adjust pyproject * hide rustfmt config * simplify django setup * adjust printing
This commit is contained in:
parent
b7a1de98dd
commit
fce343f44d
32 changed files with 1139 additions and 291 deletions
|
@ -1,57 +1,56 @@
|
|||
mod notifier;
|
||||
mod server;
|
||||
|
||||
use crate::notifier::TowerLspNotifier;
|
||||
use crate::server::{DjangoLanguageServer, LspNotification, LspRequest};
|
||||
use anyhow::Result;
|
||||
use djls_django::DjangoProject;
|
||||
use tower_lsp::jsonrpc::Result as LspResult;
|
||||
use tower_lsp::lsp_types::*;
|
||||
use tower_lsp::{Client, LanguageServer, LspService, Server};
|
||||
use tower_lsp::{LanguageServer, LspService, Server};
|
||||
|
||||
use djls_python::Python;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct Backend {
|
||||
client: Client,
|
||||
python: Python,
|
||||
struct TowerLspBackend {
|
||||
server: DjangoLanguageServer,
|
||||
}
|
||||
|
||||
#[tower_lsp::async_trait]
|
||||
impl LanguageServer for Backend {
|
||||
async fn initialize(&self, _params: InitializeParams) -> LspResult<InitializeResult> {
|
||||
Ok(InitializeResult {
|
||||
capabilities: ServerCapabilities {
|
||||
text_document_sync: Some(TextDocumentSyncCapability::Kind(
|
||||
TextDocumentSyncKind::INCREMENTAL,
|
||||
)),
|
||||
..Default::default()
|
||||
},
|
||||
offset_encoding: None,
|
||||
server_info: Some(ServerInfo {
|
||||
name: String::from("Django Language Server"),
|
||||
version: Some(String::from("0.1.0")),
|
||||
}),
|
||||
})
|
||||
impl LanguageServer for TowerLspBackend {
|
||||
async fn initialize(&self, params: InitializeParams) -> LspResult<InitializeResult> {
|
||||
self.server
|
||||
.handle_request(LspRequest::Initialize(params))
|
||||
.map_err(|_| tower_lsp::jsonrpc::Error::internal_error())
|
||||
}
|
||||
|
||||
async fn initialized(&self, _: InitializedParams) {
|
||||
self.client
|
||||
.log_message(MessageType::INFO, "server initialized!")
|
||||
.await;
|
||||
|
||||
self.client
|
||||
.log_message(MessageType::INFO, format!("\n{}", self.python))
|
||||
.await;
|
||||
async fn initialized(&self, params: InitializedParams) {
|
||||
if self
|
||||
.server
|
||||
.handle_notification(LspNotification::Initialized(params))
|
||||
.is_err()
|
||||
{
|
||||
// Handle error
|
||||
}
|
||||
}
|
||||
|
||||
async fn shutdown(&self) -> LspResult<()> {
|
||||
Ok(())
|
||||
self.server
|
||||
.handle_notification(LspNotification::Shutdown)
|
||||
.map_err(|_| tower_lsp::jsonrpc::Error::internal_error())
|
||||
}
|
||||
}
|
||||
|
||||
#[tokio::main]
|
||||
async fn main() -> Result<()> {
|
||||
let python = Python::initialize()?;
|
||||
let django = DjangoProject::setup()?;
|
||||
|
||||
let stdin = tokio::io::stdin();
|
||||
let stdout = tokio::io::stdout();
|
||||
|
||||
let (service, socket) = LspService::build(|client| Backend { client, python }).finish();
|
||||
let (service, socket) = LspService::build(|client| {
|
||||
let notifier = Box::new(TowerLspNotifier::new(client.clone()));
|
||||
let server = DjangoLanguageServer::new(django, notifier);
|
||||
TowerLspBackend { server }
|
||||
})
|
||||
.finish();
|
||||
|
||||
Server::new(stdin, stdout, socket).serve(service).await;
|
||||
|
||||
|
|
59
crates/djls/src/notifier.rs
Normal file
59
crates/djls/src/notifier.rs
Normal file
|
@ -0,0 +1,59 @@
|
|||
use anyhow::Result;
|
||||
use tower_lsp::async_trait;
|
||||
use tower_lsp::lsp_types::MessageActionItem;
|
||||
use tower_lsp::lsp_types::MessageType;
|
||||
use tower_lsp::Client;
|
||||
|
||||
#[async_trait]
|
||||
pub trait Notifier: Send + Sync {
|
||||
fn log_message(&self, typ: MessageType, msg: &str) -> Result<()>;
|
||||
fn show_message(&self, typ: MessageType, msg: &str) -> Result<()>;
|
||||
async fn show_message_request(
|
||||
&self,
|
||||
typ: MessageType,
|
||||
msg: &str,
|
||||
actions: Option<Vec<MessageActionItem>>,
|
||||
) -> Result<Option<MessageActionItem>>;
|
||||
}
|
||||
|
||||
pub struct TowerLspNotifier {
|
||||
client: Client,
|
||||
}
|
||||
|
||||
impl TowerLspNotifier {
|
||||
pub fn new(client: Client) -> Self {
|
||||
Self { client }
|
||||
}
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl Notifier for TowerLspNotifier {
|
||||
fn log_message(&self, typ: MessageType, msg: &str) -> Result<()> {
|
||||
let client = self.client.clone();
|
||||
let msg = msg.to_string();
|
||||
tokio::spawn(async move {
|
||||
client.log_message(typ, msg).await;
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn show_message(&self, typ: MessageType, msg: &str) -> Result<()> {
|
||||
let client = self.client.clone();
|
||||
let msg = msg.to_string();
|
||||
tokio::spawn(async move {
|
||||
client.show_message(typ, msg).await;
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn show_message_request(
|
||||
&self,
|
||||
typ: MessageType,
|
||||
msg: &str,
|
||||
actions: Option<Vec<MessageActionItem>>,
|
||||
) -> Result<Option<MessageActionItem>> {
|
||||
let client = self.client.clone();
|
||||
let msg = msg.to_string();
|
||||
Ok(client.show_message_request(typ, msg, actions).await?)
|
||||
}
|
||||
}
|
60
crates/djls/src/server.rs
Normal file
60
crates/djls/src/server.rs
Normal file
|
@ -0,0 +1,60 @@
|
|||
use crate::notifier::Notifier;
|
||||
use anyhow::Result;
|
||||
use djls_django::DjangoProject;
|
||||
use tower_lsp::lsp_types::*;
|
||||
|
||||
const SERVER_NAME: &str = "Django Language Server";
|
||||
const SERVER_VERSION: &str = "0.1.0";
|
||||
|
||||
pub enum LspRequest {
|
||||
Initialize(InitializeParams),
|
||||
}
|
||||
|
||||
pub enum LspNotification {
|
||||
Initialized(InitializedParams),
|
||||
Shutdown,
|
||||
}
|
||||
|
||||
pub struct DjangoLanguageServer {
|
||||
django: DjangoProject,
|
||||
notifier: Box<dyn Notifier>,
|
||||
}
|
||||
|
||||
impl DjangoLanguageServer {
|
||||
pub fn new(django: DjangoProject, notifier: Box<dyn Notifier>) -> Self {
|
||||
Self { django, notifier }
|
||||
}
|
||||
|
||||
pub fn handle_request(&self, request: LspRequest) -> Result<InitializeResult> {
|
||||
match request {
|
||||
LspRequest::Initialize(_params) => Ok(InitializeResult {
|
||||
capabilities: ServerCapabilities {
|
||||
text_document_sync: Some(TextDocumentSyncCapability::Kind(
|
||||
TextDocumentSyncKind::INCREMENTAL,
|
||||
)),
|
||||
..Default::default()
|
||||
},
|
||||
offset_encoding: None,
|
||||
server_info: Some(ServerInfo {
|
||||
name: SERVER_NAME.to_string(),
|
||||
version: Some(SERVER_VERSION.to_string()),
|
||||
}),
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_notification(&self, notification: LspNotification) -> Result<()> {
|
||||
match notification {
|
||||
LspNotification::Initialized(_) => {
|
||||
self.notifier
|
||||
.log_message(MessageType::INFO, "server initialized!")?;
|
||||
self.notifier
|
||||
.log_message(MessageType::INFO, &format!("\n{}", self.django.py()))?;
|
||||
self.notifier
|
||||
.log_message(MessageType::INFO, &format!("\n{}", self.django))?;
|
||||
Ok(())
|
||||
}
|
||||
LspNotification::Shutdown => Ok(()),
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue