mirror of
https://github.com/joshuadavidthomas/django-language-server.git
synced 2025-09-12 05:16:46 +00:00
add initial autocomplete for installed templatetags (#46)
This commit is contained in:
parent
5eb8a775e4
commit
c16635b1c0
8 changed files with 359 additions and 58 deletions
|
@ -2,7 +2,10 @@ use crate::documents::Store;
|
|||
use crate::notifier::Notifier;
|
||||
use crate::tasks::DebugTask;
|
||||
use anyhow::Result;
|
||||
use djls_project::DjangoProject;
|
||||
use djls_worker::Worker;
|
||||
use pyo3::prelude::*;
|
||||
use std::collections::BTreeMap;
|
||||
use std::sync::Arc;
|
||||
use std::time::Duration;
|
||||
use tower_lsp::lsp_types::*;
|
||||
|
@ -12,6 +15,12 @@ const SERVER_VERSION: &str = "0.1.0";
|
|||
|
||||
pub enum LspRequest {
|
||||
Initialize(InitializeParams),
|
||||
Completion(CompletionParams),
|
||||
}
|
||||
|
||||
pub enum LspResponse {
|
||||
Initialize(InitializeResult),
|
||||
Completion(Option<CompletionResponse>),
|
||||
}
|
||||
|
||||
pub enum LspNotification {
|
||||
|
@ -23,6 +32,7 @@ pub enum LspNotification {
|
|||
}
|
||||
|
||||
pub struct DjangoLanguageServer {
|
||||
project: Option<DjangoProject>,
|
||||
notifier: Arc<Box<dyn Notifier>>,
|
||||
documents: Store,
|
||||
worker: Worker,
|
||||
|
@ -33,33 +43,77 @@ impl DjangoLanguageServer {
|
|||
let notifier = Arc::new(notifier);
|
||||
|
||||
Self {
|
||||
project: None,
|
||||
notifier,
|
||||
documents: Store::new(),
|
||||
worker: Worker::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn handle_request(&self, request: LspRequest) -> Result<InitializeResult> {
|
||||
pub fn handle_request(&mut self, request: LspRequest) -> Result<LspResponse> {
|
||||
match request {
|
||||
LspRequest::Initialize(_params) => Ok(InitializeResult {
|
||||
capabilities: ServerCapabilities {
|
||||
text_document_sync: Some(TextDocumentSyncCapability::Options(
|
||||
TextDocumentSyncOptions {
|
||||
open_close: Some(true),
|
||||
change: Some(TextDocumentSyncKind::INCREMENTAL),
|
||||
will_save: Some(false),
|
||||
will_save_wait_until: Some(false),
|
||||
save: Some(SaveOptions::default().into()),
|
||||
},
|
||||
)),
|
||||
..Default::default()
|
||||
},
|
||||
offset_encoding: None,
|
||||
server_info: Some(ServerInfo {
|
||||
name: SERVER_NAME.to_string(),
|
||||
version: Some(SERVER_VERSION.to_string()),
|
||||
}),
|
||||
}),
|
||||
LspRequest::Initialize(params) => {
|
||||
if let Some(mut project) = DjangoProject::from_initialize_params(¶ms) {
|
||||
if let Err(e) = project.initialize() {
|
||||
self.notifier.log_message(
|
||||
MessageType::ERROR,
|
||||
&format!("Failed to initialize Django project: {}", e),
|
||||
)?;
|
||||
} else {
|
||||
self.notifier.log_message(
|
||||
MessageType::INFO,
|
||||
&format!("Using project path: {}", project.path().display()),
|
||||
)?;
|
||||
self.project = Some(project);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(LspResponse::Initialize(InitializeResult {
|
||||
capabilities: ServerCapabilities {
|
||||
completion_provider: Some(CompletionOptions {
|
||||
resolve_provider: Some(false),
|
||||
trigger_characters: Some(vec![
|
||||
"{".to_string(),
|
||||
"%".to_string(),
|
||||
" ".to_string(),
|
||||
]),
|
||||
..Default::default()
|
||||
}),
|
||||
text_document_sync: Some(TextDocumentSyncCapability::Options(
|
||||
TextDocumentSyncOptions {
|
||||
open_close: Some(true),
|
||||
change: Some(TextDocumentSyncKind::INCREMENTAL),
|
||||
will_save: Some(false),
|
||||
will_save_wait_until: Some(false),
|
||||
save: Some(SaveOptions::default().into()),
|
||||
},
|
||||
)),
|
||||
..Default::default()
|
||||
},
|
||||
offset_encoding: None,
|
||||
server_info: Some(ServerInfo {
|
||||
name: SERVER_NAME.to_string(),
|
||||
version: Some(SERVER_VERSION.to_string()),
|
||||
}),
|
||||
}))
|
||||
}
|
||||
LspRequest::Completion(params) => {
|
||||
let completions = if let Some(project) = &self.project {
|
||||
if let Some(tags) = project.template_tags() {
|
||||
self.documents.get_completions(
|
||||
params.text_document_position.text_document.uri.as_str(),
|
||||
params.text_document_position.position,
|
||||
tags,
|
||||
)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
Ok(LspResponse::Completion(completions))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -71,36 +125,6 @@ impl DjangoLanguageServer {
|
|||
MessageType::INFO,
|
||||
&format!("Opened document: {}", params.text_document.uri),
|
||||
)?;
|
||||
|
||||
// Execute - still sync
|
||||
self.worker.execute(DebugTask::new(
|
||||
"Quick task".to_string(),
|
||||
Duration::from_millis(100),
|
||||
self.notifier.clone(),
|
||||
))?;
|
||||
|
||||
// Submit - spawn async task
|
||||
let worker = self.worker.clone();
|
||||
let task = DebugTask::new(
|
||||
"Important task".to_string(),
|
||||
Duration::from_secs(1),
|
||||
self.notifier.clone(),
|
||||
);
|
||||
tokio::spawn(async move {
|
||||
let _ = worker.submit(task).await;
|
||||
});
|
||||
|
||||
// Wait for result - spawn async task
|
||||
let worker = self.worker.clone();
|
||||
let task = DebugTask::new(
|
||||
"Task with result".to_string(),
|
||||
Duration::from_secs(2),
|
||||
self.notifier.clone(),
|
||||
);
|
||||
tokio::spawn(async move {
|
||||
let _ = worker.wait_for(task).await;
|
||||
});
|
||||
|
||||
Ok(())
|
||||
}
|
||||
LspNotification::DidChangeTextDocument(params) => {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue