From e905fb0e18ff604e71cba59e1ea6adfe645c87f8 Mon Sep 17 00:00:00 2001 From: Will Lillis Date: Thu, 29 Aug 2024 22:32:30 -0400 Subject: [PATCH] feat: make config items optional (#132) Add note to README --- README.md | 3 +- asm-lsp_config_schema.json | 8 +- src/bin/main.rs | 26 +++--- src/lsp.rs | 27 +++--- src/test.rs | 186 ++++++++++++++++++------------------- src/types.rs | 40 ++++---- 6 files changed, 150 insertions(+), 140 deletions(-) diff --git a/README.md b/README.md index f52483c..a938e2b 100644 --- a/README.md +++ b/README.md @@ -43,7 +43,8 @@ Add a section like the following in your `settings.json` file: Add a `.asm-lsp.toml` file like the following to your project's root directory and/or `~/.config/asm-lsp/` (project configs will override global configs) to -selectively target specific assemblers and/or instruction sets. +selectively target specific assemblers and/or instruction sets. Omitting an item +from the configuration file is equivalent to setting it to `false`. ```toml version = "0.1" diff --git a/asm-lsp_config_schema.json b/asm-lsp_config_schema.json index 162ea73..8cdce16 100644 --- a/asm-lsp_config_schema.json +++ b/asm-lsp_config_schema.json @@ -34,7 +34,7 @@ "type": "boolean" } }, - "required": [ "gas", "go", "z80", "masm", "nasm" ] + "required": [] }, "instruction_sets": { "description": "Options to manage instruction set-dependent features.", @@ -55,9 +55,13 @@ "arm": { "description": "Flag to turn features related to the arm instruction set on/off.", "type": "boolean" + }, + "riscv": { + "description": "Flag to turn features related to the riscv instruction set on/off.", + "type": "boolean" } }, - "required": [ "x86", "x86_64", "z80", "arm" ] + "required": [] } }, "required": [ "version", "assemblers", "instruction_sets" ] diff --git a/src/bin/main.rs b/src/bin/main.rs index ebd6633..3c1562b 100644 --- a/src/bin/main.rs +++ b/src/bin/main.rs @@ -110,7 +110,7 @@ pub fn main() -> Result<()> { // create a map of &Instruction_name -> &Instruction - Use that in user queries // The Instruction(s) themselves are stored in a vector and we only keep references to the // former map - let x86_instructions = if target_config.instruction_sets.x86 { + let x86_instructions = if target_config.instruction_sets.x86.unwrap_or(false) { let start = std::time::Instant::now(); let x86_instrs = include_bytes!("../../docs_store/opcodes/serialized/x86"); let instrs = bincode::deserialize::>(x86_instrs)? @@ -130,7 +130,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let x86_64_instructions = if target_config.instruction_sets.x86_64 { + let x86_64_instructions = if target_config.instruction_sets.x86_64.unwrap_or(false) { let start = std::time::Instant::now(); let x86_64_instrs = include_bytes!("../../docs_store/opcodes/serialized/x86_64"); let instrs = bincode::deserialize::>(x86_64_instrs)? @@ -150,7 +150,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let z80_instructions = if target_config.instruction_sets.z80 { + let z80_instructions = if target_config.instruction_sets.z80.unwrap_or(false) { let start = std::time::Instant::now(); let z80_instrs = include_bytes!("../../docs_store/opcodes/serialized/z80"); let instrs = bincode::deserialize::>(z80_instrs)? @@ -170,7 +170,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let arm_instructions = if target_config.instruction_sets.arm { + let arm_instructions = if target_config.instruction_sets.arm.unwrap_or(false) { let start = std::time::Instant::now(); let arm_instrs = include_bytes!("../../docs_store/opcodes/serialized/arm"); // NOTE: No need to filter these instructions by assembler like we do for @@ -185,7 +185,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let riscv_instructions = if target_config.instruction_sets.riscv { + let riscv_instructions = if target_config.instruction_sets.riscv.unwrap_or(false) { let start = std::time::Instant::now(); let riscv_instrs = include_bytes!("../../docs_store/opcodes/serialized/riscv"); // NOTE: No need to filter these instructions by assembler like we do for @@ -229,7 +229,7 @@ pub fn main() -> Result<()> { // create a map of &Register_name -> &Register - Use that in user queries // The Register(s) themselves are stored in a vector and we only keep references to the // former map - let x86_registers = if target_config.instruction_sets.x86 { + let x86_registers = if target_config.instruction_sets.x86.unwrap_or(false) { let start = std::time::Instant::now(); let regs_x86 = include_bytes!("../../docs_store/registers/serialized/x86"); let regs = bincode::deserialize(regs_x86)?; @@ -242,7 +242,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let x86_64_registers = if target_config.instruction_sets.x86_64 { + let x86_64_registers = if target_config.instruction_sets.x86_64.unwrap_or(false) { let start = std::time::Instant::now(); let regs_x86_64 = include_bytes!("../../docs_store/registers/serialized/x86_64"); let regs = bincode::deserialize(regs_x86_64)?; @@ -255,7 +255,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let z80_registers = if target_config.instruction_sets.z80 { + let z80_registers = if target_config.instruction_sets.z80.unwrap_or(false) { let start = std::time::Instant::now(); let regs_z80 = include_bytes!("../../docs_store/registers/serialized/z80"); let regs = bincode::deserialize(regs_z80)?; @@ -268,7 +268,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let arm_registers = if target_config.instruction_sets.arm { + let arm_registers = if target_config.instruction_sets.arm.unwrap_or(false) { let start = std::time::Instant::now(); let regs_arm = include_bytes!("../../docs_store/registers/serialized/arm"); let regs = bincode::deserialize(regs_arm)?; @@ -281,7 +281,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let riscv_registers = if target_config.instruction_sets.riscv { + let riscv_registers = if target_config.instruction_sets.riscv.unwrap_or(false) { let start = std::time::Instant::now(); let regs_riscv = include_bytes!("../../docs_store/registers/serialized/riscv"); let regs = bincode::deserialize(regs_riscv)?; @@ -304,7 +304,7 @@ pub fn main() -> Result<()> { populate_name_to_register_map(Arch::ARM, &arm_registers, &mut names_to_info.registers); populate_name_to_register_map(Arch::RISCV, &riscv_registers, &mut names_to_info.registers); - let gas_directives = if target_config.assemblers.gas { + let gas_directives = if target_config.assemblers.gas.unwrap_or(false) { let start = std::time::Instant::now(); let gas_dirs = include_bytes!("../../docs_store/directives/serialized/gas"); let dirs = bincode::deserialize(gas_dirs)?; @@ -317,7 +317,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let masm_directives = if target_config.assemblers.masm { + let masm_directives = if target_config.assemblers.masm.unwrap_or(false) { let start = std::time::Instant::now(); let masm_dirs = include_bytes!("../../docs_store/directives/serialized/masm"); let dirs = bincode::deserialize(masm_dirs)?; @@ -330,7 +330,7 @@ pub fn main() -> Result<()> { Vec::new() }; - let nasm_directives = if target_config.assemblers.nasm { + let nasm_directives = if target_config.assemblers.nasm.unwrap_or(false) { let start = std::time::Instant::now(); let nasm_dirs = include_bytes!("../../docs_store/directives/serialized/nasm"); let dirs = bincode::deserialize(nasm_dirs)?; diff --git a/src/lsp.rs b/src/lsp.rs index 230d208..7ae5ecf 100644 --- a/src/lsp.rs +++ b/src/lsp.rs @@ -475,13 +475,13 @@ pub fn get_hover_resp( // directive lookup { - if config.assemblers.gas || config.assemblers.masm { + if config.assemblers.gas.unwrap_or(false) || config.assemblers.masm.unwrap_or(false) { // all gas directives have a '.' prefix, some masm directives do let directive_lookup = lookup_hover_resp_by_assembler(word, directive_map); if directive_lookup.is_some() { return directive_lookup; } - } else if config.assemblers.nasm { + } else if config.assemblers.nasm.unwrap_or(false) { // most nasm directives have no prefix, 2 have a '.' prefix let directive_lookup = lookup_hover_resp_by_assembler(word, directive_map); if directive_lookup.is_some() { @@ -853,10 +853,12 @@ pub fn get_comp_resp( // prepend GAS registers, some NASM directives with "%" Some("%") => { let mut items = Vec::new(); - if config.instruction_sets.x86 || config.instruction_sets.x86_64 { + if config.instruction_sets.x86.unwrap_or(false) + || config.instruction_sets.x86_64.unwrap_or(false) + { items.append(&mut filtered_comp_list(reg_comps)); } - if config.assemblers.nasm { + if config.assemblers.nasm.unwrap_or(false) { items.append(&mut filtered_comp_list_prefix(dir_comps, '%')); } @@ -869,7 +871,10 @@ pub fn get_comp_resp( } // prepend all GAS, some MASM, some NASM directives with "." Some(".") => { - if config.assemblers.gas || config.assemblers.masm || config.assemblers.nasm { + if config.assemblers.gas.unwrap_or(false) + || config.assemblers.masm.unwrap_or(false) + || config.assemblers.nasm.unwrap_or(false) + { return Some(CompletionList { is_incomplete: true, items: filtered_comp_list_prefix(dir_comps, '.'), @@ -1571,20 +1576,20 @@ pub fn instr_filter_targets(instr: &Instruction, config: &TargetConfig) -> Instr .forms .iter() .filter(|form| { - (form.gas_name.is_some() && config.assemblers.gas) - || (form.go_name.is_some() && config.assemblers.go) - || (form.z80_name.is_some() && config.instruction_sets.z80) + (form.gas_name.is_some() && config.assemblers.gas.unwrap_or(false)) + || (form.go_name.is_some() && config.assemblers.go.unwrap_or(false)) + || (form.z80_name.is_some() && config.instruction_sets.z80.unwrap_or(false)) }) .map(|form| { let mut filtered = form.clone(); // handle cases where gas and go both have names on the same form - if !config.assemblers.gas { + if !config.assemblers.gas.unwrap_or(false) { filtered.gas_name = None; } - if !config.assemblers.go { + if !config.assemblers.go.unwrap_or(false) { filtered.go_name = None; } - if !config.assemblers.z80 { + if !config.assemblers.z80.unwrap_or(false) { filtered.z80_name = None; } filtered diff --git a/src/test.rs b/src/test.rs index c9a2318..dd5f787 100644 --- a/src/test.rs +++ b/src/test.rs @@ -27,18 +27,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: false, - go: false, - masm: false, - nasm: false, - z80: false, + gas: Some(false), + go: Some(false), + masm: Some(false), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: false, - arm: false, - riscv: false, + x86: Some(false), + x86_64: Some(false), + z80: Some(false), + arm: Some(false), + riscv: Some(false), }, } } @@ -47,18 +47,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: false, - go: false, - masm: false, - nasm: false, - z80: false, + gas: Some(false), + go: Some(false), + masm: Some(false), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: true, - arm: false, - riscv: false, + x86: Some(false), + x86_64: Some(false), + z80: Some(true), + arm: Some(false), + riscv: Some(false), }, } } @@ -67,18 +67,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: false, - go: false, - masm: false, - nasm: false, - z80: false, + gas: Some(false), + go: Some(false), + masm: Some(false), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: false, - arm: true, - riscv: false, + x86: Some(false), + x86_64: Some(false), + z80: Some(false), + arm: Some(true), + riscv: Some(false), }, } } @@ -87,18 +87,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: false, - go: false, - masm: false, - nasm: false, - z80: false, + gas: Some(false), + go: Some(false), + masm: Some(false), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: false, - arm: false, - riscv: true, + x86: Some(false), + x86_64: Some(false), + z80: Some(false), + arm: Some(false), + riscv: Some(true), }, } } @@ -107,18 +107,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: true, - go: true, - masm: false, - nasm: false, - z80: false, + gas: Some(true), + go: Some(true), + masm: Some(false), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: true, - x86_64: true, - z80: false, - arm: false, - riscv: false, + x86: Some(true), + x86_64: Some(true), + z80: Some(false), + arm: Some(false), + riscv: Some(false), }, } } @@ -127,18 +127,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: true, - go: false, - masm: false, - nasm: false, - z80: false, + gas: Some(true), + go: Some(false), + masm: Some(false), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: false, - arm: false, - riscv: false, + x86: Some(false), + x86_64: Some(false), + z80: Some(false), + arm: Some(false), + riscv: Some(false), }, } } @@ -147,18 +147,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: false, - go: false, - masm: true, - nasm: false, - z80: false, + gas: Some(false), + go: Some(false), + masm: Some(true), + nasm: Some(false), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: false, - arm: false, - riscv: false, + x86: Some(false), + x86_64: Some(false), + z80: Some(false), + arm: Some(false), + riscv: Some(false), }, } } @@ -167,18 +167,18 @@ mod tests { TargetConfig { version: "0.1".to_string(), assemblers: Assemblers { - gas: false, - go: false, - masm: false, - nasm: true, - z80: false, + gas: Some(false), + go: Some(false), + masm: Some(false), + nasm: Some(true), + z80: Some(false), }, instruction_sets: InstructionSets { - x86: false, - x86_64: false, - z80: false, - arm: false, - riscv: false, + x86: Some(false), + x86_64: Some(false), + z80: Some(false), + arm: Some(false), + riscv: Some(false), }, } } @@ -246,7 +246,7 @@ mod tests { fn init_global_info(config: &TargetConfig) -> Result { let mut info = GlobalInfo::new(); - info.x86_instructions = if config.instruction_sets.x86 { + info.x86_instructions = if config.instruction_sets.x86.unwrap_or(false) { let x86_instrs = include_bytes!("../docs_store/opcodes/serialized/x86"); bincode::deserialize::>(x86_instrs)? .into_iter() @@ -260,7 +260,7 @@ mod tests { Vec::new() }; - info.x86_64_instructions = if config.instruction_sets.x86_64 { + info.x86_64_instructions = if config.instruction_sets.x86_64.unwrap_or(false) { let x86_64_instrs = include_bytes!("../docs_store/opcodes/serialized/x86_64"); bincode::deserialize::>(x86_64_instrs)? .into_iter() @@ -274,7 +274,7 @@ mod tests { Vec::new() }; - info.z80_instructions = if config.instruction_sets.z80 { + info.z80_instructions = if config.instruction_sets.z80.unwrap_or(false) { let z80_instrs = include_bytes!("../docs_store/opcodes/serialized/z80"); bincode::deserialize::>(z80_instrs)? .into_iter() @@ -288,70 +288,70 @@ mod tests { Vec::new() }; - info.arm_instructions = if config.instruction_sets.arm { + info.arm_instructions = if config.instruction_sets.arm.unwrap_or(false) { let arm_instrs = include_bytes!("../docs_store/opcodes/serialized/arm"); bincode::deserialize::>(arm_instrs)? } else { Vec::new() }; - info.riscv_instructions = if config.instruction_sets.riscv { + info.riscv_instructions = if config.instruction_sets.riscv.unwrap_or(false) { let riscv_instrs = include_bytes!("../docs_store/opcodes/serialized/riscv"); bincode::deserialize::>(riscv_instrs)? } else { Vec::new() }; - info.x86_registers = if config.instruction_sets.x86 { + info.x86_registers = if config.instruction_sets.x86.unwrap_or(false) { let regs_x86 = include_bytes!("../docs_store/registers/serialized/x86"); bincode::deserialize(regs_x86)? } else { Vec::new() }; - info.x86_64_registers = if config.instruction_sets.x86_64 { + info.x86_64_registers = if config.instruction_sets.x86_64.unwrap_or(false) { let regs_x86_64 = include_bytes!("../docs_store/registers/serialized/x86_64"); bincode::deserialize(regs_x86_64)? } else { Vec::new() }; - info.z80_registers = if config.instruction_sets.z80 { + info.z80_registers = if config.instruction_sets.z80.unwrap_or(false) { let regs_z80 = include_bytes!("../docs_store/registers/serialized/z80"); bincode::deserialize(regs_z80)? } else { Vec::new() }; - info.arm_registers = if config.instruction_sets.arm { + info.arm_registers = if config.instruction_sets.arm.unwrap_or(false) { let regs_arm = include_bytes!("../docs_store/registers/serialized/arm"); bincode::deserialize(regs_arm)? } else { Vec::new() }; - info.riscv_registers = if config.instruction_sets.riscv { + info.riscv_registers = if config.instruction_sets.riscv.unwrap_or(false) { let regs_riscv = include_bytes!("../docs_store/registers/serialized/riscv"); bincode::deserialize(regs_riscv)? } else { Vec::new() }; - info.gas_directives = if config.assemblers.gas { + info.gas_directives = if config.assemblers.gas.unwrap_or(false) { let gas_dirs = include_bytes!("../docs_store/directives/serialized/gas"); bincode::deserialize(gas_dirs)? } else { Vec::new() }; - info.masm_directives = if config.assemblers.masm { + info.masm_directives = if config.assemblers.masm.unwrap_or(false) { let masm_dirs = include_bytes!("../docs_store/directives/serialized/masm"); bincode::deserialize(masm_dirs)? } else { Vec::new() }; - info.nasm_directives = if config.assemblers.nasm { + info.nasm_directives = if config.assemblers.nasm.unwrap_or(false) { let nasm_dirs = include_bytes!("../docs_store/directives/serialized/nasm"); bincode::deserialize(nasm_dirs)? } else { diff --git a/src/types.rs b/src/types.rs index 9ea3f95..d07f534 100644 --- a/src/types.rs +++ b/src/types.rs @@ -810,21 +810,21 @@ impl std::fmt::Display for RegisterBitInfo { #[derive(Debug, Clone, Serialize, Deserialize)] pub struct Assemblers { - pub gas: bool, - pub go: bool, - pub masm: bool, - pub nasm: bool, - pub z80: bool, + pub gas: Option, + pub go: Option, + pub masm: Option, + pub nasm: Option, + pub z80: Option, } impl Default for Assemblers { fn default() -> Self { Assemblers { - gas: true, - go: true, - masm: false, - nasm: false, - z80: false, + gas: Some(true), + go: Some(true), + masm: Some(false), + nasm: Some(false), + z80: Some(false), } } } @@ -832,21 +832,21 @@ impl Default for Assemblers { #[allow(non_snake_case)] #[derive(Debug, Clone, Serialize, Deserialize)] pub struct InstructionSets { - pub x86: bool, - pub x86_64: bool, - pub z80: bool, - pub arm: bool, - pub riscv: bool, + pub x86: Option, + pub x86_64: Option, + pub z80: Option, + pub arm: Option, + pub riscv: Option, } impl Default for InstructionSets { fn default() -> Self { InstructionSets { - x86: true, - x86_64: true, - z80: false, - arm: false, - riscv: false, + x86: Some(true), + x86_64: Some(true), + z80: Some(false), + arm: Some(false), + riscv: Some(false), } } }