simple highlighting for prompt

This commit is contained in:
pedrocarlo
2025-03-04 18:41:22 -03:00
parent 051d879db2
commit f631706ea4
5 changed files with 1910 additions and 10 deletions

176
Cargo.lock generated
View File

@@ -208,6 +208,21 @@ dependencies = [
"backtrace",
]
[[package]]
name = "base64"
version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "bincode"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad"
dependencies = [
"serde",
]
[[package]]
name = "bitflags"
version = "1.3.2"
@@ -519,6 +534,15 @@ dependencies = [
"libc",
]
[[package]]
name = "crc32fast"
version = "1.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
dependencies = [
"cfg-if",
]
[[package]]
name = "criterion"
version = "0.5.1"
@@ -675,6 +699,15 @@ dependencies = [
"uuid",
]
[[package]]
name = "deranged"
version = "0.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4"
dependencies = [
"powerfmt",
]
[[package]]
name = "difflib"
version = "0.4.0"
@@ -888,6 +921,22 @@ dependencies = [
"winapi",
]
[[package]]
name = "flate2"
version = "1.0.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c936bfdafb507ebbf50b8074c54fa31c5be9a1e7e5f467dd659697041407d07c"
dependencies = [
"crc32fast",
"miniz_oxide",
]
[[package]]
name = "fnv"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1"
[[package]]
name = "foldhash"
version = "0.1.4"
@@ -1320,7 +1369,7 @@ dependencies = [
"log",
"num-format",
"once_cell",
"quick-xml",
"quick-xml 0.26.0",
"rgb",
"str_stack",
]
@@ -1616,6 +1665,7 @@ dependencies = [
"limbo_core",
"miette",
"rustyline",
"syntect",
"tracing",
"tracing-subscriber",
]
@@ -1839,6 +1889,12 @@ dependencies = [
"uuid",
]
[[package]]
name = "linked-hash-map"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0717cef1bc8b636c6e1c1bbdefc09e6322da8a9321966e8928ef80d20f7f770f"
[[package]]
name = "linkme"
version = "0.3.31"
@@ -2081,6 +2137,12 @@ dependencies = [
"winapi",
]
[[package]]
name = "num-conv"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9"
[[package]]
name = "num-format"
version = "0.4.4"
@@ -2115,6 +2177,28 @@ version = "1.20.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775"
[[package]]
name = "onig"
version = "6.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c4b31c8722ad9171c6d77d3557db078cab2bd50afcc9d09c8b315c59df8ca4f"
dependencies = [
"bitflags 1.3.2",
"libc",
"once_cell",
"onig_sys",
]
[[package]]
name = "onig_sys"
version = "69.8.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7b829e3d7e9cc74c7e315ee8edb185bf4190da5acde74afd7fc59c35b1f086e7"
dependencies = [
"cc",
"pkg-config",
]
[[package]]
name = "oorandom"
version = "11.1.4"
@@ -2279,6 +2363,19 @@ version = "0.3.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "953ec861398dccce10c670dfeaf3ec4911ca479e9c02154b3a215178c5f566f2"
[[package]]
name = "plist"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "42cf17e9a1800f5f396bc67d193dc9411b59012a5876445ef450d449881e1016"
dependencies = [
"base64",
"indexmap",
"quick-xml 0.32.0",
"serde",
"time",
]
[[package]]
name = "plotters"
version = "0.3.7"
@@ -2328,6 +2425,12 @@ version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6"
[[package]]
name = "powerfmt"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "pprof"
version = "0.14.0"
@@ -2480,6 +2583,15 @@ dependencies = [
"memchr",
]
[[package]]
name = "quick-xml"
version = "0.32.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d3a6e5838b60e0e8fa7a43f22ade549a37d61f8bdbe636d0d7816191de969c2"
dependencies = [
"memchr",
]
[[package]]
name = "quickcheck"
version = "1.0.3"
@@ -3079,6 +3191,28 @@ dependencies = [
"syn 2.0.96",
]
[[package]]
name = "syntect"
version = "5.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "874dcfa363995604333cf947ae9f751ca3af4522c60886774c4963943b4746b1"
dependencies = [
"bincode",
"bitflags 1.3.2",
"flate2",
"fnv",
"once_cell",
"onig",
"plist",
"regex-syntax",
"serde",
"serde_derive",
"serde_json",
"thiserror 1.0.69",
"walkdir",
"yaml-rust",
]
[[package]]
name = "target-lexicon"
version = "0.12.16"
@@ -3206,6 +3340,37 @@ dependencies = [
"once_cell",
]
[[package]]
name = "time"
version = "0.3.37"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21"
dependencies = [
"deranged",
"itoa",
"num-conv",
"powerfmt",
"serde",
"time-core",
"time-macros",
]
[[package]]
name = "time-core"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3"
[[package]]
name = "time-macros"
version = "0.2.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de"
dependencies = [
"num-conv",
"time-core",
]
[[package]]
name = "tinystr"
version = "0.7.6"
@@ -3831,6 +3996,15 @@ version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1e9df38ee2d2c3c5948ea468a8406ff0db0b29ae1ffde1bcf20ef305bcc95c51"
[[package]]
name = "yaml-rust"
version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "56c1936c4cc7a1c9ab21a1ebb602eb942ba868cbd44a99cb7cdc5892335e1c85"
dependencies = [
"linked-hash-map",
]
[[package]]
name = "yoke"
version = "0.7.5"

View File

@@ -1,14 +1,14 @@
# Copyright 2023 the Limbo authors. All rights reserved. MIT license.
[package]
name = "limbo_cli"
version.workspace = true
authors.workspace = true
default-run = "limbo"
description = "The Limbo interactive SQL shell"
edition.workspace = true
license.workspace = true
name = "limbo_cli"
repository.workspace = true
description = "The Limbo interactive SQL shell"
version.workspace = true
[package.metadata.dist]
dist = true
@@ -20,22 +20,23 @@ path = "main.rs"
[dependencies]
anyhow = "1.0.75"
cfg-if = "1.0.0"
clap = { version = "4.5", features = ["derive"] }
comfy-table = "7.1.4"
csv = "1.3.1"
ctrlc = "3.4.4"
dirs = "5.0.1"
env_logger = "0.10.1"
limbo_core = { path = "../core", default-features = true, features = [
"completion",
] }
miette = { version = "7.4.0", features = ["fancy"] }
rustyline = { version = "15.0.0", default-features = true, features = [
"derive",
] }
ctrlc = "3.4.4"
csv = "1.3.1"
miette = { version = "7.4.0", features = ["fancy"] }
cfg-if = "1.0.0"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
syntect = "5.2.0"
tracing = "0.1.41"
tracing-subscriber = { version = "0.3.19", features = ["env-filter"] }
[features]
default = ["io_uring"]

1670
cli/SQL.sublime-syntax Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -235,6 +235,7 @@ impl<'a> Limbo<'a> {
opts: Settings::from(&opts),
rl,
};
if opts.sql.is_some() {
app.handle_first_input(opts.sql.as_ref().unwrap());
}

View File

@@ -5,6 +5,10 @@ use limbo_core::{Connection, StepResult};
use rustyline::completion::{extract_word, Completer, Pair};
use rustyline::highlight::Highlighter;
use rustyline::{Completer, Helper, Hinter, Validator};
use syntect::easy::HighlightLines;
use syntect::highlighting::{Style, ThemeSet};
use syntect::parsing::SyntaxSet;
use syntect::util::{as_24_bit_terminal_escaped, LinesWithEndings};
macro_rules! try_result {
($expr:expr, $err:expr) => {
@@ -19,17 +23,67 @@ macro_rules! try_result {
pub struct LimboHelper {
#[rustyline(Completer)]
completer: SqlCompleter,
syntax_set: SyntaxSet,
theme_set: ThemeSet,
}
impl LimboHelper {
pub fn new(conn: Rc<Connection>, io: Arc<dyn limbo_core::IO>) -> Self {
// Load only predefined syntax
let ps = SyntaxSet::load_defaults_newlines();
let ts = ThemeSet::load_defaults();
LimboHelper {
completer: SqlCompleter::new(conn, io),
syntax_set: ps,
theme_set: ts,
}
}
}
impl Highlighter for LimboHelper {}
impl Highlighter for LimboHelper {
fn highlight<'l>(&self, line: &'l str, pos: usize) -> std::borrow::Cow<'l, str> {
let _ = pos;
// TODO use lifetimes to store highlight lines
let syntax = self.syntax_set.find_syntax_by_extension("sql").unwrap();
let mut h = HighlightLines::new(syntax, &self.theme_set.themes["base16-ocean.dark"]);
let mut ret_line = String::new();
for new_line in LinesWithEndings::from(line) {
let ranges: Vec<(Style, &str)> = h.highlight_line(new_line, &self.syntax_set).unwrap();
let escaped = as_24_bit_terminal_escaped(&ranges[..], false);
ret_line.push_str(&escaped);
}
// Push this escape sequence to reset
// ret_line.push_str("\x1b[0m");
std::borrow::Cow::Owned(ret_line)
}
fn highlight_prompt<'b, 's: 'b, 'p: 'b>(
&'s self,
prompt: &'p str,
default: bool,
) -> std::borrow::Cow<'b, str> {
let _ = default;
std::borrow::Cow::Owned(format!("\x1b[1;32m{}\x1b[0m", prompt))
}
fn highlight_hint<'h>(&self, hint: &'h str) -> std::borrow::Cow<'h, str> {
std::borrow::Cow::Borrowed(hint)
}
fn highlight_candidate<'c>(
&self,
candidate: &'c str,
completion: rustyline::CompletionType,
) -> std::borrow::Cow<'c, str> {
let _ = completion;
std::borrow::Cow::Borrowed(candidate)
}
fn highlight_char(&self, line: &str, pos: usize, kind: rustyline::highlight::CmdKind) -> bool {
let _ = (line, pos, kind);
true
}
}
pub struct SqlCompleter {
conn: Rc<Connection>,