浏览代码

Unicode input feature

David Peter 1 年之前
父节点
当前提交
5c97cc25f9
共有 6 个文件被更改,包括 183 次插入30 次删除
  1. 80 27
      Cargo.lock
  2. 1 1
      numbat-cli/Cargo.toml
  3. 16 1
      numbat-cli/src/completer.rs
  4. 1 1
      numbat/modules/units/misc.nbt
  5. 8 0
      numbat/src/lib.rs
  6. 77 0
      numbat/src/unicode_input.rs

+ 80 - 27
Cargo.lock

@@ -255,13 +255,11 @@ checksum = "702fc72eb24e5a1e48ce58027a675bc24edd52096d5397d4aea7c6dd9eca0bd1"
 
 [[package]]
 name = "clipboard-win"
-version = "4.5.0"
+version = "5.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7191c27c2357d9b7ef96baac1773290d4ca63b24205b82a3fd8a0637afcf0362"
+checksum = "c57002a5d9be777c1ef967e33674dac9ebd310d8893e4e3437b14d5f0f6372cc"
 dependencies = [
  "error-code",
- "str-buf",
- "winapi",
 ]
 
 [[package]]
@@ -490,23 +488,19 @@ dependencies = [
 
 [[package]]
 name = "error-code"
-version = "2.3.1"
+version = "3.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "64f18991e7bf11e7ffee451b5318b5c1a73c52d0d0ada6e5a3017c8c1ced6a21"
-dependencies = [
- "libc",
- "str-buf",
-]
+checksum = "281e452d3bad4005426416cdba5ccfd4f5c1280e10099e21db27f7c1c28347fc"
 
 [[package]]
 name = "fd-lock"
-version = "3.0.13"
+version = "4.0.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "ef033ed5e9bad94e55838ca0ca906db0e043f517adda0c8b79c7a8c66c93c1b5"
+checksum = "b93f7a0db71c99f68398f80653ed05afb0b00e062e1a20c7ff849c4edfabbbcc"
 dependencies = [
  "cfg-if",
  "rustix",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
 ]
 
 [[package]]
@@ -740,11 +734,11 @@ dependencies = [
 
 [[package]]
 name = "nix"
-version = "0.26.4"
+version = "0.27.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "598beaf3cc6fdd9a5dfb1630c2800c7acd31df7aaf0f565796fba2b53ca1af1b"
+checksum = "2eb04e9c688eff1c89d72b407f168cf79bb9e867a9d3323ed6c01519eb9cc053"
 dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.1",
  "cfg-if",
  "libc",
 ]
@@ -1144,9 +1138,9 @@ dependencies = [
 
 [[package]]
 name = "rustyline"
-version = "12.0.0"
+version = "13.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "994eca4bca05c87e86e15d90fc7a91d1be64b4482b38cb2d27474568fe7c9db9"
+checksum = "02a2d683a4ac90aeef5b1013933f6d977bd37d51ff3f4dad829d4931a7e6be86"
 dependencies = [
  "bitflags 2.4.1",
  "cfg-if",
@@ -1159,7 +1153,6 @@ dependencies = [
  "nix",
  "radix_trie",
  "rustyline-derive",
- "scopeguard",
  "unicode-segmentation",
  "unicode-width",
  "utf8parse",
@@ -1168,9 +1161,9 @@ dependencies = [
 
 [[package]]
 name = "rustyline-derive"
-version = "0.9.0"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "5a32af5427251d2e4be14fc151eabe18abb4a7aad5efee7044da9f096c906a43"
+checksum = "e5af959c8bf6af1aff6d2b463a57f71aae53d1332da58419e30ad8dc7011d951"
 dependencies = [
  "proc-macro2",
  "quote",
@@ -1292,12 +1285,6 @@ version = "0.9.8"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67"
 
-[[package]]
-name = "str-buf"
-version = "1.0.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "9e08d8363704e6c71fc928674353e6b7c23dcea9d82d7012c8faf2a3a025f8d0"
-
 [[package]]
 name = "strsim"
 version = "0.10.0"
@@ -1631,6 +1618,15 @@ dependencies = [
  "windows-targets 0.48.5",
 ]
 
+[[package]]
+name = "windows-sys"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d"
+dependencies = [
+ "windows-targets 0.52.0",
+]
+
 [[package]]
 name = "windows-targets"
 version = "0.42.2"
@@ -1661,6 +1657,21 @@ dependencies = [
  "windows_x86_64_msvc 0.48.5",
 ]
 
+[[package]]
+name = "windows-targets"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8a18201040b24831fbb9e4eb208f8892e1f50a37feb53cc7ff887feb8f50e7cd"
+dependencies = [
+ "windows_aarch64_gnullvm 0.52.0",
+ "windows_aarch64_msvc 0.52.0",
+ "windows_i686_gnu 0.52.0",
+ "windows_i686_msvc 0.52.0",
+ "windows_x86_64_gnu 0.52.0",
+ "windows_x86_64_gnullvm 0.52.0",
+ "windows_x86_64_msvc 0.52.0",
+]
+
 [[package]]
 name = "windows_aarch64_gnullvm"
 version = "0.42.2"
@@ -1673,6 +1684,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8"
 
+[[package]]
+name = "windows_aarch64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "cb7764e35d4db8a7921e09562a0304bf2f93e0a51bfccee0bd0bb0b666b015ea"
+
 [[package]]
 name = "windows_aarch64_msvc"
 version = "0.42.2"
@@ -1685,6 +1702,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc"
 
+[[package]]
+name = "windows_aarch64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "bbaa0368d4f1d2aaefc55b6fcfee13f41544ddf36801e793edbbfd7d7df075ef"
+
 [[package]]
 name = "windows_i686_gnu"
 version = "0.42.2"
@@ -1697,6 +1720,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e"
 
+[[package]]
+name = "windows_i686_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a28637cb1fa3560a16915793afb20081aba2c92ee8af57b4d5f28e4b3e7df313"
+
 [[package]]
 name = "windows_i686_msvc"
 version = "0.42.2"
@@ -1709,6 +1738,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406"
 
+[[package]]
+name = "windows_i686_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ffe5e8e31046ce6230cc7215707b816e339ff4d4d67c65dffa206fd0f7aa7b9a"
+
 [[package]]
 name = "windows_x86_64_gnu"
 version = "0.42.2"
@@ -1721,6 +1756,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e"
 
+[[package]]
+name = "windows_x86_64_gnu"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3d6fa32db2bc4a2f5abeacf2b69f7992cd09dca97498da74a151a3132c26befd"
+
 [[package]]
 name = "windows_x86_64_gnullvm"
 version = "0.42.2"
@@ -1733,6 +1774,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc"
 
+[[package]]
+name = "windows_x86_64_gnullvm"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1a657e1e9d3f514745a572a6846d3c7aa7dbe1658c056ed9c3344c4109a6949e"
+
 [[package]]
 name = "windows_x86_64_msvc"
 version = "0.42.2"
@@ -1745,6 +1792,12 @@ version = "0.48.5"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538"
 
+[[package]]
+name = "windows_x86_64_msvc"
+version = "0.52.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04"
+
 [[package]]
 name = "winnow"
 version = "0.5.19"

+ 1 - 1
numbat-cli/Cargo.toml

@@ -14,7 +14,7 @@ rust-version = "1.70"
 
 [dependencies]
 anyhow = "1"
-rustyline = { version = "12", features = ["derive"] }
+rustyline = { version = "13", features = ["derive"] }
 dirs = "5"
 numbat = { version = "1.8.0", path = "../numbat" }
 colored = "2"

+ 16 - 1
numbat-cli/src/completer.rs

@@ -1,6 +1,6 @@
 use std::sync::{Arc, Mutex};
 
-use numbat::Context;
+use numbat::{unicode_input::UNICODE_INPUT, Context};
 use rustyline::{
     self,
     completion::{extract_word, Completer, Pair},
@@ -20,6 +20,21 @@ impl Completer for NumbatCompleter {
         pos: usize,
         _: &rustyline::Context<'_>,
     ) -> rustyline::Result<(usize, Vec<Self::Candidate>)> {
+        for (patterns, replacement) in UNICODE_INPUT {
+            for pattern in *patterns {
+                let backslash_pattern = format!("\\{}", pattern);
+                if line[..pos].ends_with(&backslash_pattern) {
+                    return Ok((
+                        pos - (1 + pattern.len()),
+                        vec![Pair {
+                            display: backslash_pattern.to_string(),
+                            replacement: replacement.to_string(),
+                        }],
+                    ));
+                }
+            }
+        }
+
         if line.starts_with("use ") {
             return Ok((
                 0,

+ 1 - 1
numbat/modules/units/misc.nbt

@@ -10,7 +10,7 @@ unit bar: Pressure = 100 kPa
 
 @name("Ångström")
 @url("https://en.wikipedia.org/wiki/Angstrom")
-@aliases(angstroms, Å: short)
+@aliases(angstroms, Å: short, Å: short)
 unit angstrom: Length = 1e-10 meter
 
 @name("Barn")

+ 8 - 0
numbat/src/lib.rs

@@ -30,6 +30,7 @@ mod suggestion;
 mod tokenizer;
 mod typechecker;
 mod typed_ast;
+pub mod unicode_input;
 mod unit;
 mod unit_registry;
 pub mod value;
@@ -68,6 +69,7 @@ use unit::BaseUnitAndFactor;
 use unit_registry::UnitMetadata;
 
 use crate::prefix_parser::PrefixParserResult;
+use crate::unicode_input::UNICODE_INPUT;
 
 #[derive(Debug, Error)]
 pub enum NumbatError {
@@ -215,6 +217,12 @@ impl Context {
 
         let mut words: Vec<_> = KEYWORDS.iter().map(|k| k.to_string()).collect();
 
+        for (patterns, _) in UNICODE_INPUT {
+            for pattern in *patterns {
+                words.push(pattern.to_string());
+            }
+        }
+
         {
             for variable in self.variable_names() {
                 words.push(variable.clone());

+ 77 - 0
numbat/src/unicode_input.rs

@@ -0,0 +1,77 @@
+// We are following Julia here [1], but we only support
+// a small (useful) subset of sequences for now.
+// [1] https://docs.julialang.org/en/v1/manual/unicode-input/
+pub const UNICODE_INPUT: &[(&[&str], &str)] = &[
+    // Superscript symbols
+    (&["^-"], "⁻"),
+    (&["pm"], "±"),
+    (&["^1"], "¹"),
+    (&["^2"], "²"),
+    (&["^3"], "³"),
+    (&["^4"], "⁴"),
+    (&["^5"], "⁵"),
+    (&["^6"], "⁶"),
+    (&["^7"], "⁷"),
+    (&["^8"], "⁸"),
+    (&["^9"], "⁹"),
+    // Numbers
+    (&["1/2"], "½"),
+    // Operators
+    (&["cdot"], "⋅"),
+    (&["cdotp"], "·"),
+    (&["times"], "×"),
+    (&["div"], "÷"),
+    (&["to", "rightarrow"], "→"),
+    (&["ge"], "≥"),
+    (&["le"], "≤"),
+    (&["dots", "ldots"], "…"),
+    // Greek alphabet
+    (&["Gamma"], "Γ"),
+    (&["Delta"], "Δ"),
+    (&["Theta"], "Θ"),
+    (&["Lambda"], "Λ"),
+    (&["Pi"], "Π"),
+    (&["Sigma"], "Σ"),
+    (&["Phi"], "Φ"),
+    (&["Psi"], "Ψ"),
+    (&["Omega"], "Ω"),
+    (&["alpha"], "α"),
+    (&["beta"], "β"),
+    (&["gamma"], "γ"),
+    (&["delta"], "δ"),
+    (&["epsilon"], "ε"),
+    (&["varepsilon"], "ϵ"),
+    (&["zeta"], "ζ"),
+    (&["eta"], "η"),
+    (&["theta"], "θ"),
+    (&["vartheta"], "ϑ"),
+    (&["iota"], "ι"),
+    (&["kappa"], "κ"),
+    (&["lambda"], "λ"),
+    (&["mu"], "μ"),
+    (&["nu"], "ν"),
+    (&["xi"], "ξ"),
+    (&["pi"], "π"),
+    (&["rho"], "ρ"),
+    (&["sigma"], "σ"),
+    (&["tau"], "τ"),
+    (&["upsilon"], "υ"),
+    (&["phi"], "ϕ"),
+    (&["varphi"], "φ"),
+    (&["chi"], "χ"),
+    (&["psi"], "ψ"),
+    (&["omega"], "ω"),
+    // Units
+    (&["sterling"], "£"),
+    (&["yen"], "¥"),
+    (&["euro"], "€"),
+    (&["degree"], "°"),
+    (&["ohm"], "Ω"),
+    (&["Angstrom"], "Å"),
+    (&["percent"], "%"),
+    (&["perthousand"], "‰"),
+    (&["pertenthousand"], "‱"),
+    // Constants
+    (&["hbar"], "ℏ"),
+    (&["planck"], "ℎ"),
+];