summaryrefslogtreecommitdiff
path: root/cli/tools/repl/mod.rs
diff options
context:
space:
mode:
Diffstat (limited to 'cli/tools/repl/mod.rs')
-rw-r--r--cli/tools/repl/mod.rs66
1 files changed, 55 insertions, 11 deletions
diff --git a/cli/tools/repl/mod.rs b/cli/tools/repl/mod.rs
index 687e8a300..e971d0a7a 100644
--- a/cli/tools/repl/mod.rs
+++ b/cli/tools/repl/mod.rs
@@ -4,7 +4,10 @@ use crate::ast::transpile;
use crate::ast::Diagnostics;
use crate::ast::ImportsNotUsedAsValues;
use crate::colors;
+use crate::lsp::ReplLanguageServer;
use crate::proc_state::ProcState;
+use crate::tools::repl::channel::RustylineSyncMessage;
+use crate::tools::repl::channel::RustylineSyncResponse;
use deno_ast::swc::parser::error::SyntaxError;
use deno_ast::swc::parser::token::Token;
use deno_ast::swc::parser::token::Word;
@@ -181,6 +184,15 @@ impl Completer for EditorHelper {
pos: usize,
_ctx: &Context<'_>,
) -> Result<(usize, Vec<String>), ReadlineError> {
+ let lsp_completions = self.sync_sender.lsp_completions(line, pos);
+ if !lsp_completions.is_empty() {
+ // assumes all lsp completions have the same start position
+ return Ok((
+ lsp_completions[0].span.lo.0 as usize,
+ lsp_completions.into_iter().map(|c| c.new_text).collect(),
+ ));
+ }
+
let expr = get_expr_from_line_at_pos(line, pos);
// check if the expression is in the form `obj.prop`
@@ -428,14 +440,21 @@ impl std::fmt::Display for EvaluationOutput {
}
}
+struct TsEvaluateResponse {
+ ts_code: String,
+ value: Value,
+}
+
struct ReplSession {
worker: MainWorker,
session: LocalInspectorSession,
pub context_id: u64,
+ language_server: ReplLanguageServer,
}
impl ReplSession {
pub async fn initialize(mut worker: MainWorker) -> Result<Self, AnyError> {
+ let language_server = ReplLanguageServer::new_initialized().await?;
let mut session = worker.create_inspector_session().await;
worker
@@ -467,6 +486,7 @@ impl ReplSession {
worker,
session,
context_id,
+ language_server,
};
// inject prelude
@@ -520,13 +540,18 @@ impl ReplSession {
match self.evaluate_line_with_object_wrapping(line).await {
Ok(evaluate_response) => {
- let evaluate_result = evaluate_response.get("result").unwrap();
+ let evaluate_result = evaluate_response.value.get("result").unwrap();
let evaluate_exception_details =
- evaluate_response.get("exceptionDetails");
+ evaluate_response.value.get("exceptionDetails");
if evaluate_exception_details.is_some() {
self.set_last_thrown_error(evaluate_result).await?;
} else {
+ self
+ .language_server
+ .commit_text(&evaluate_response.ts_code)
+ .await;
+
self.set_last_eval_result(evaluate_result).await?;
}
@@ -561,7 +586,7 @@ impl ReplSession {
async fn evaluate_line_with_object_wrapping(
&mut self,
line: &str,
- ) -> Result<Value, AnyError> {
+ ) -> Result<TsEvaluateResponse, AnyError> {
// Expressions like { "foo": "bar" } are interpreted as block expressions at the
// statement level rather than an object literal so we interpret it as an expression statement
// to match the behavior found in a typical prompt including browser developer tools.
@@ -582,6 +607,7 @@ impl ReplSession {
|| evaluate_response
.as_ref()
.unwrap()
+ .value
.get("exceptionDetails")
.is_some())
{
@@ -658,7 +684,7 @@ impl ReplSession {
async fn evaluate_ts_expression(
&mut self,
expression: &str,
- ) -> Result<Value, AnyError> {
+ ) -> Result<TsEvaluateResponse, AnyError> {
let parsed_module = deno_ast::parse_module(deno_ast::ParseParams {
specifier: "repl.ts".to_string(),
source: deno_ast::SourceTextInfo::from_string(expression.to_string()),
@@ -688,12 +714,17 @@ impl ReplSession {
)?
.0;
- self
+ let value = self
.evaluate_expression(&format!(
"'use strict'; void 0;\n{}",
transpiled_src
))
- .await
+ .await?;
+
+ Ok(TsEvaluateResponse {
+ ts_code: expression.to_string(),
+ value,
+ })
}
async fn evaluate_expression(
@@ -727,11 +758,24 @@ async fn read_line_and_poll(
return result.unwrap();
}
result = message_handler.recv() => {
- if let Some((method, params)) = result {
- let result = repl_session
- .post_message_with_event_loop(&method, params)
- .await;
- message_handler.send(result).unwrap();
+ match result {
+ Some(RustylineSyncMessage::PostMessage {
+ method,
+ params
+ }) => {
+ let result = repl_session
+ .post_message_with_event_loop(&method, params)
+ .await;
+ message_handler.send(RustylineSyncResponse::PostMessage(result)).unwrap();
+ },
+ Some(RustylineSyncMessage::LspCompletions {
+ line_text,
+ position,
+ }) => {
+ let result = repl_session.language_server.completions(&line_text, position).await;
+ message_handler.send(RustylineSyncResponse::LspCompletions(result)).unwrap();
+ }
+ None => {}, // channel closed
}
poll_worker = true;