-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix: cleanup all and new project layout (#9)
- Loading branch information
1 parent
6fceb45
commit 350754b
Showing
15 changed files
with
514 additions
and
333 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
|
||
pub mod notification_did_change; | ||
pub mod notification_did_open; | ||
pub mod request_completion; | ||
pub mod request_goto_definition; | ||
pub mod request_hover; | ||
|
||
use lsp_server::{Notification, Request, RequestId}; | ||
|
||
pub fn cast<R>(req: Request) -> Result<(RequestId, R::Params)> | ||
where | ||
R: lsp_types::request::Request, | ||
R::Params: serde::de::DeserializeOwned, | ||
{ | ||
req.extract(R::METHOD).map_err(Error::ExtractRequestError) | ||
} | ||
|
||
pub fn cast_notification<N>(req: Notification) -> Result<N::Params> | ||
where | ||
N: lsp_types::notification::Notification, | ||
N::Params: serde::de::DeserializeOwned, | ||
{ | ||
req.extract(N::METHOD) | ||
.map_err(Error::ExtractNotificationError) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
|
||
use std::collections::HashMap; | ||
|
||
use lsp_server::Notification; | ||
use ropey::Rope; | ||
|
||
use super::cast_notification; | ||
|
||
pub fn handle_did_change_text_document( | ||
notification: &Notification, | ||
files: &mut HashMap<String, Rope>, | ||
) -> Result<()> { | ||
match cast_notification::<lsp_types::notification::DidChangeTextDocument>(notification.clone()) | ||
{ | ||
Ok(params) => { | ||
let rope = files | ||
.get_mut(¶ms.text_document.uri.to_string()) | ||
.expect("Must be able to get rope for lang"); | ||
for change in params.content_changes { | ||
let range = change.range.unwrap_or_default(); | ||
let start = | ||
rope.line_to_char(range.start.line as usize) + range.start.character as usize; | ||
let end = rope.line_to_char(range.end.line as usize) + range.end.character as usize; | ||
rope.remove(start..end); | ||
rope.insert(start, change.text.as_str()); | ||
} | ||
Ok(()) | ||
} | ||
Err(_) => todo!(), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,28 @@ | ||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
|
||
use std::collections::HashMap; | ||
|
||
use lsp_server::Notification; | ||
use ropey::Rope; | ||
|
||
use super::cast_notification; | ||
|
||
pub fn handle_did_open_text_document( | ||
notification: &Notification, | ||
files: &mut HashMap<String, Rope>, | ||
) -> Result<()> { | ||
match cast_notification::<lsp_types::notification::DidOpenTextDocument>(notification.clone()) { | ||
Ok(params) => { | ||
if let std::collections::hash_map::Entry::Vacant(e) = | ||
files.entry(params.text_document.uri.to_string()) | ||
{ | ||
let rope = Rope::from_str(params.text_document.text.as_str()); | ||
e.insert(rope); | ||
} | ||
Ok(()) | ||
} | ||
Err(Error::ExtractNotificationError(req)) => Err(Error::ExtractNotificationError(req)), | ||
Err(err) => panic!("{err:?}"), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
use crate::{ | ||
utils::{ | ||
ropey::{get_ix::GetIx, word_at::WordAt, RopeSliceIsLower}, | ||
HashMapGetForLSPParams, | ||
}, | ||
words::Words, | ||
}; | ||
|
||
use std::collections::HashMap; | ||
|
||
use lsp_server::{Connection, Message, Request, Response}; | ||
use lsp_types::{request::Completion, CompletionItem, CompletionResponse}; | ||
use ropey::Rope; | ||
|
||
use super::cast; | ||
|
||
pub fn handle_completion( | ||
req: &Request, | ||
connection: &Connection, | ||
data: &Words, | ||
files: &mut HashMap<String, Rope>, | ||
) -> Result<()> { | ||
match cast::<Completion>(req.clone()) { | ||
Ok((id, params)) => { | ||
eprintln!("#{id}: {params:?}"); | ||
let rope = if let Some(rope) = files.for_position_param(¶ms.text_document_position) | ||
{ | ||
rope | ||
} else { | ||
return Err(Error::NoSuchFile( | ||
params.text_document_position.text_document.uri.to_string(), | ||
)); | ||
}; | ||
let mut ix = rope.get_ix(¶ms); | ||
if ix >= rope.len_chars() { | ||
return Err(Error::OutOfBounds(ix)); | ||
} | ||
if let Some(char_at_ix) = rope.get_char(ix) { | ||
if char_at_ix.is_whitespace() && ix > 0 { | ||
ix -= 1; | ||
} | ||
} | ||
let word = rope.word_at(ix); | ||
let result = if word.len_chars() > 0 { | ||
eprintln!("Found word {}", word); | ||
let use_lower = word.is_lowercase(); | ||
let mut ret = vec![]; | ||
let candidates = data.words.iter().filter(|x| { | ||
x.token | ||
.to_lowercase() | ||
.starts_with(word.to_string().to_lowercase().as_str()) | ||
}); | ||
for candidate in candidates { | ||
let label = candidate.token.to_owned(); | ||
let label = if use_lower { | ||
label.to_lowercase() | ||
} else { | ||
label | ||
}; | ||
ret.push(CompletionItem { | ||
label, | ||
detail: Some(candidate.stack.to_owned()), | ||
documentation: Some(lsp_types::Documentation::MarkupContent( | ||
lsp_types::MarkupContent { | ||
kind: lsp_types::MarkupKind::Markdown, | ||
value: candidate.documentation(), | ||
}, | ||
)), | ||
..Default::default() | ||
}); | ||
} | ||
Some(CompletionResponse::Array(ret)) | ||
} else { | ||
None | ||
}; | ||
let result = serde_json::to_value(result) | ||
.expect("Must be able to serialize the CompletionResponse"); | ||
let resp = Response { | ||
id, | ||
result: Some(result), | ||
error: None, | ||
}; | ||
connection | ||
.sender | ||
.send(Message::Response(resp)) | ||
.map_err(|err| Error::SendError(err.to_string()))?; | ||
Ok(()) | ||
} | ||
Err(Error::ExtractRequestError(req)) => Err(Error::ExtractRequestError(req)), | ||
Err(err) => panic!("{err:?}"), | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
use crate::{ | ||
utils::{ | ||
data_to_position::ToPosition, | ||
find_variant_sublists_from_to::FindVariantSublistsFromTo, | ||
ropey::{get_ix::GetIx, word_on_or_before::WordOnOrBefore}, | ||
HashMapGetForLSPParams, | ||
}, | ||
words::Words, | ||
}; | ||
|
||
use std::{collections::HashMap, mem::discriminant}; | ||
|
||
use forth_lexer::{ | ||
parser::Lexer, | ||
token::{Data, Token}, | ||
}; | ||
use lsp_server::{Connection, Message, Request, Response}; | ||
use lsp_types::{request::GotoDefinition, GotoDefinitionResponse, Location, Range, Url}; | ||
use ropey::Rope; | ||
|
||
use super::cast; | ||
|
||
pub fn handle_goto_definition( | ||
req: &Request, | ||
connection: &Connection, | ||
_data: &Words, | ||
files: &mut HashMap<String, Rope>, | ||
) -> Result<()> { | ||
match cast::<GotoDefinition>(req.clone()) { | ||
Ok((id, params)) => { | ||
eprintln!("#{id}: {params:?}"); | ||
let mut ret: Vec<Location> = vec![]; | ||
let rope = if let Some(rope) = | ||
files.for_position_param(¶ms.text_document_position_params) | ||
{ | ||
rope | ||
} else { | ||
return Err(Error::NoSuchFile( | ||
params | ||
.text_document_position_params | ||
.text_document | ||
.uri | ||
.to_string(), | ||
)); | ||
}; | ||
let ix = rope.get_ix(¶ms); | ||
if ix >= rope.len_chars() { | ||
return Err(Error::OutOfBounds(ix)); | ||
} | ||
let word = rope.word_on_or_before(ix).to_string(); | ||
for (file, rope) in files.iter() { | ||
eprintln!("Word: {}", word); | ||
let progn = rope.to_string(); | ||
let mut lexer = Lexer::new(progn.as_str()); | ||
let tokens = lexer.parse(); | ||
|
||
for result in tokens.find_variant_sublists_from_to( | ||
discriminant(&Token::Colon(Data::default())), | ||
discriminant(&Token::Semicolon(Data::default())), | ||
) { | ||
eprintln!("{:?}", result); | ||
let tok = Token::Illegal(Data::new(0, 0, "")); | ||
let begin = result.first().unwrap_or(&tok).get_data(); | ||
let end = result.last().unwrap_or(&tok).get_data(); | ||
if let Ok(uri) = Url::from_file_path(file) { | ||
ret.push(Location { | ||
uri, | ||
range: Range { | ||
start: begin.to_position_start(rope), | ||
end: end.to_position_end(rope), | ||
}, | ||
}); | ||
} else { | ||
eprintln!("Failed to parse URI for {}", file); | ||
} | ||
} | ||
} | ||
let result = Some(GotoDefinitionResponse::Array(ret)); | ||
let result = serde_json::to_value(result) | ||
.expect("Must be able to serialize the GotoDefinitionResponse"); | ||
let resp = Response { | ||
id, | ||
result: Some(result), | ||
error: None, | ||
}; | ||
connection | ||
.sender | ||
.send(Message::Response(resp)) | ||
.map_err(|err| Error::SendError(err.to_string()))?; | ||
Ok(()) | ||
} | ||
Err(Error::ExtractRequestError(req)) => Err(Error::ExtractRequestError(req)), | ||
Err(err) => panic!("{err:?}"), | ||
// Err(err @ ExtractError::JsonError { .. }) => panic!("{err:?}"), | ||
// Err(ExtractError::MethodMismatch(req)) => req, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
#[allow(unused_imports)] | ||
use crate::prelude::*; | ||
use crate::{ | ||
utils::{ | ||
ropey::{get_ix::GetIx, word_on_or_before::WordOnOrBefore}, | ||
HashMapGetForLSPParams, | ||
}, | ||
words::{Word, Words}, | ||
}; | ||
|
||
use std::collections::HashMap; | ||
|
||
use lsp_server::{Connection, Message, Request, Response}; | ||
use lsp_types::{request::HoverRequest, Hover}; | ||
use ropey::Rope; | ||
|
||
use super::cast; | ||
|
||
pub fn handle_hover( | ||
req: &Request, | ||
connection: &Connection, | ||
data: &Words, | ||
files: &mut HashMap<String, Rope>, | ||
) -> Result<()> { | ||
match cast::<HoverRequest>(req.clone()) { | ||
Ok((id, params)) => { | ||
eprintln!("#{id}: {params:?}"); | ||
let rope = if let Some(rope) = | ||
files.for_position_param(¶ms.text_document_position_params) | ||
{ | ||
rope | ||
} else { | ||
return Err(Error::NoSuchFile( | ||
params | ||
.text_document_position_params | ||
.text_document | ||
.uri | ||
.to_string(), | ||
)); | ||
}; | ||
let ix = rope.get_ix(¶ms); | ||
if ix >= rope.len_chars() { | ||
return Err(Error::OutOfBounds(ix)); | ||
} | ||
let word = rope.word_on_or_before(ix); | ||
let result = if !word.len_chars() > 0 { | ||
let default_info = &Word::default(); | ||
let info = data | ||
.words | ||
.iter() | ||
.find(|x| x.token.to_lowercase() == (word.to_string().to_lowercase().as_str())) | ||
.unwrap_or(&default_info); | ||
Some(Hover { | ||
contents: lsp_types::HoverContents::Markup(lsp_types::MarkupContent { | ||
kind: lsp_types::MarkupKind::Markdown, | ||
value: info.documentation(), | ||
}), | ||
range: None, | ||
}) | ||
} else { | ||
None | ||
}; | ||
let result = serde_json::to_value(result).expect("Must be able to serialize the Hover"); | ||
let resp = Response { | ||
id, | ||
result: Some(result), | ||
error: None, | ||
}; | ||
connection | ||
.sender | ||
.send(Message::Response(resp)) | ||
.map_err(|err| Error::SendError(err.to_string()))?; | ||
Ok(()) | ||
} | ||
Err(Error::ExtractRequestError(req)) => Err(Error::ExtractRequestError(req)), | ||
Err(err) => panic!("{err:?}"), | ||
// Err(err @ ExtractError::JsonError { .. }) => panic!("{err:?}"), | ||
// Err(ExtractError::MethodMismatch(req)) => req, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
Oops, something went wrong.