Skip to content

Commit

Permalink
Completion of mnemonics
Browse files Browse the repository at this point in the history
  • Loading branch information
themkat authored and sagacity committed Sep 2, 2022
1 parent 5a2ece3 commit 33fe914
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 3 deletions.
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions mos-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ petgraph = "0.6"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
smallvec = "1"
strum = { version = "0.23", features = ["derive"] }
toml = "0.5"

[dev-dependencies]
Expand Down
4 changes: 3 additions & 1 deletion mos-core/src/parser/mnemonic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,11 @@ use super::{IResult, LocatedSpan};
use nom::branch::alt;
use nom::bytes::complete::tag_no_case;
use nom::combinator::map;
use strum::{EnumIter, EnumString, EnumVariantNames};

/// The available 6502 instructions.
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, EnumVariantNames, EnumIter, EnumString)]
#[strum(serialize_all = "lowercase")]
pub enum Mnemonic {
Adc,
And,
Expand Down
41 changes: 39 additions & 2 deletions mos/src/lsp/completion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,9 @@ use crate::lsp::{LspContext, RequestHandler};
use itertools::Itertools;
use lsp_types::request::Completion;
use lsp_types::{CompletionItem, CompletionParams, CompletionResponse};
use mos_core::parser::IdentifierPath;
use mos_core::parser::{IdentifierPath, Mnemonic};
use std::collections::HashMap;
use strum::IntoEnumIterator;

pub struct CompletionHandler;

Expand All @@ -31,9 +32,10 @@ impl RequestHandler<Completion> for CompletionHandler {
let source_column = params.text_document_position.position.character as usize;

// Try to determine the previous characters to see if we're trying to auto-complete inside a scope
let mut line = "";
let mut nested_scope = None;
if let Some(source_file) = codegen.tree().files.get(path) {
let line = source_file.file.source_line(source_line);
line = source_file.file.source_line(source_line);

// Only look at the line until the source_column
if source_column <= line.len() && source_column > 0 {
Expand Down Expand Up @@ -69,6 +71,16 @@ impl RequestHandler<Completion> for CompletionHandler {
);
}

// offsets still empty? probably a global symbol (mnemonic, built-in etc.)
let global_symbols: Vec<String> = if offsets.is_empty() {
Mnemonic::iter()
.map(|mnemonic| mnemonic.to_string().to_lowercase())
.filter(|sym| sym.starts_with(line.trim()))
.collect()
} else {
Vec::new()
};

let mut symbols = HashMap::new();
offsets.into_iter().for_each(|offset| {
let scope_nx = match &nested_scope {
Expand All @@ -92,6 +104,10 @@ impl RequestHandler<Completion> for CompletionHandler {
label: id.to_string(),
..Default::default()
})
.chain(global_symbols.iter().map(|sym| CompletionItem {
label: sym.to_string(),
..Default::default()
}))
.collect_vec();
return Ok(Some(CompletionResponse::from(items)));
}
Expand Down Expand Up @@ -157,6 +173,27 @@ mod tests {
Ok(())
}

#[test]
fn mnemonics_completions_empty_in() -> MosResult<()> {
use strum::VariantNames;
let mut server = LspServer::new(LspContext::new());
server.did_open_text_document(test_root().join("main.asm"), "")?;
let response = server.completion(test_root().join("main.asm"), Position::new(0, 1))?;
assert_unordered_eq(&unwrap(&response), &Mnemonic::VARIANTS);

Ok(())
}

#[test]
fn mnemonics_completions_ld() -> MosResult<()> {
let mut server = LspServer::new(LspContext::new());
server.did_open_text_document(test_root().join("main.asm"), "ld")?;
let response = server.completion(test_root().join("main.asm"), Position::new(0, 1))?;
assert_unordered_eq(&unwrap(&response), &["ldx", "ldy", "lda"]);

Ok(())
}

fn unwrap(response: &Option<CompletionResponse>) -> Vec<&str> {
match response {
Some(r) => match r {
Expand Down

0 comments on commit 33fe914

Please sign in to comment.