summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock59
-rw-r--r--Cargo.toml2
-rw-r--r--README.md11
-rw-r--r--src/config/mod.rs22
-rw-r--r--src/main.rs5
-rw-r--r--src/utils/prompt_input.rs10
6 files changed, 66 insertions, 43 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 763e232..c1aa01a 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -286,6 +286,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a2ef034f05691a48569bd920a96c81b9d91bbad1ab5ac7c4616c1f6ef36cb79f"
[[package]]
+name = "byteorder"
+version = "1.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b"
+
+[[package]]
name = "bytes"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -293,9 +299,9 @@ checksum = "a2bd12c1caf447e69cd4528f47f94d203fd2582878ecb9e9465484c4148a8223"
[[package]]
name = "cc"
-version = "1.0.86"
+version = "1.0.87"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7f9fa1897e4325be0d68d48df6aa1a71ac2ed4d27723887e7754192705350730"
+checksum = "3286b845d0fccbdd15af433f61c5970e711987036cb468f437ff6badd70f4e24"
[[package]]
name = "cfg-if"
@@ -774,6 +780,24 @@ dependencies = [
]
[[package]]
+name = "fuzzy-matcher"
+version = "0.3.7"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "54614a3312934d066701a80f20f15fa3b56d67ac7722b39eea5b4c9dd1d66c94"
+dependencies = [
+ "thread_local",
+]
+
+[[package]]
+name = "fxhash"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
+dependencies = [
+ "byteorder",
+]
+
+[[package]]
name = "generic-array"
version = "0.14.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -964,16 +988,17 @@ dependencies = [
[[package]]
name = "inquire"
-version = "0.6.2"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "c33e7c1ddeb15c9abcbfef6029d8e29f69b52b6d6c891031b88ed91b5065803b"
+checksum = "bd05e4e63529f3c9c5f5c668c398217f72756ffe48c85266b49692c55accd1f7"
dependencies = [
- "bitflags 1.3.2",
+ "bitflags 2.4.2",
"crossterm 0.25.0",
"dyn-clone",
- "lazy_static",
+ "fuzzy-matcher",
+ "fxhash",
"newline-converter",
- "thiserror",
+ "once_cell",
"unicode-segmentation",
"unicode-width",
]
@@ -1152,9 +1177,9 @@ dependencies = [
[[package]]
name = "newline-converter"
-version = "0.2.2"
+version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1f71d09d5c87634207f894c6b31b6a2b2c64ea3bdcf71bd5599fdbbe1600c00f"
+checksum = "47b6b097ecb1cbfed438542d16e84fd7ad9b0c76c8a65b7f9039212a3d14dc7f"
dependencies = [
"unicode-segmentation",
]
@@ -1837,12 +1862,12 @@ checksum = "b7c388c1b5e93756d0c740965c41e8822f866621d41acbdf6336a6a168f8840c"
[[package]]
name = "socket2"
-version = "0.5.5"
+version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7b5fac59a5cb5dd637972e5fca70daf0523c9067fcdc4842f053dae04a18f8e9"
+checksum = "05ffd9c0a93b7543e062e759284fcf5f5e3b098501104bfbdde4d404db792871"
dependencies = [
"libc",
- "windows-sys 0.48.0",
+ "windows-sys 0.52.0",
]
[[package]]
@@ -2008,6 +2033,16 @@ dependencies = [
]
[[package]]
+name = "thread_local"
+version = "1.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c"
+dependencies = [
+ "cfg-if",
+ "once_cell",
+]
+
+[[package]]
name = "time"
version = "0.3.34"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index ea43b5e..0ed7e4f 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -16,7 +16,7 @@ bytes = "1.4.0"
clap = { version = "4.4.8", features = ["derive"] }
dirs = "5.0.0"
futures-util = "0.3.29"
-inquire = "0.6.2"
+inquire = "0.7.0"
is-terminal = "0.4.9"
reedline = "0.29.0"
serde = { version = "1.0.152", features = ["derive"] }
diff --git a/README.md b/README.md
index 528525b..95476e0 100644
--- a/README.md
+++ b/README.md
@@ -11,7 +11,7 @@ AIChat in chat REPL mode:
AIChat in command mode:
-![command mode](https://github.com/sigoden/aichat/assets/4012553/26f7badc-1b1f-418b-99c1-fbc58bee0097)
+![command mode](https://github.com/sigoden/aichat/assets/4012553/db96a38a-2f14-4127-91e7-4d111aba6ca9)
## Install
@@ -58,10 +58,10 @@ Download it from [GitHub Releases](https://github.com/sigoden/aichat/releases),
- Support [Roles](#roles)
- Support context-aware conversation (session)
- Support multimodal models (vision)
-- Support executing commands using natural language
+- Execute commands using natural language
- Syntax highlighting for markdown and 200+ languages in code blocks
- Stream output
-- Support proxy
+- Use proxy
- With Dark/light theme
- Save messages/sessions
@@ -149,8 +149,9 @@ The Chat REPL supports:
- Emacs/Vi keybinding
- [Custom REPL Prompt](https://github.com/sigoden/aichat/wiki/Custom-REPL-Prompt)
-- Tab Completion
+- Tab Completions
- Edit/paste multiline text
+- Open an editor to modify the current prompt
- Undo support
### `.help` - print help message
@@ -395,7 +396,7 @@ aichat -e find all json files in current folder | pbcopy
## License
-Copyright (c) 2023 aichat-developers.
+Copyright (c) 2023-2024 aichat-developers.
Aichat is made available under the terms of either the MIT License or the Apache License 2.0, at your option.
diff --git a/src/config/mod.rs b/src/config/mod.rs
index d38cbf3..f8d97c2 100644
--- a/src/config/mod.rs
+++ b/src/config/mod.rs
@@ -11,7 +11,7 @@ use crate::client::{
Model, OpenAIClient, SendData,
};
use crate::render::{MarkdownRender, RenderOptions};
-use crate::utils::{get_env_name, light_theme_from_colorfgbg, now, prompt_op_err, render_prompt};
+use crate::utils::{get_env_name, light_theme_from_colorfgbg, now, render_prompt};
use anyhow::{anyhow, bail, Context, Result};
use inquire::{Confirm, Select, Text};
@@ -577,8 +577,7 @@ impl Config {
"Start a session that incorporates the last question and answer?",
)
.with_default(false)
- .prompt()
- .map_err(prompt_op_err)?;
+ .prompt()?;
if ans {
session.add_message(input, output)?;
}
@@ -593,19 +592,13 @@ impl Config {
self.last_message = None;
self.temperature = self.default_temperature;
if session.should_save() {
- let ans = Confirm::new("Save session?")
- .with_default(false)
- .prompt()
- .map_err(prompt_op_err)?;
+ let ans = Confirm::new("Save session?").with_default(false).prompt()?;
if !ans {
return Ok(());
}
let mut name = session.name().to_string();
if session.is_temp() {
- name = Text::new("Session name:")
- .with_default(&name)
- .prompt()
- .map_err(prompt_op_err)?;
+ name = Text::new("Session name:").with_default(&name).prompt()?;
}
let session_path = Self::session_file(&name)?;
let sessions_dir = session_path.parent().ok_or_else(|| {
@@ -917,15 +910,12 @@ pub enum State {
fn create_config_file(config_path: &Path) -> Result<()> {
let ans = Confirm::new("No config file, create a new one?")
.with_default(true)
- .prompt()
- .map_err(prompt_op_err)?;
+ .prompt()?;
if !ans {
exit(0);
}
- let client = Select::new("Platform:", list_client_types())
- .prompt()
- .map_err(prompt_op_err)?;
+ let client = Select::new("Platform:", list_client_types()).prompt()?;
let mut config = serde_json::json!({});
config["model"] = client.into();
diff --git a/src/main.rs b/src/main.rs
index 8946985..29e034f 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -11,7 +11,7 @@ mod utils;
use crate::cli::Cli;
use crate::config::{Config, GlobalConfig};
-use crate::utils::{prompt_op_err, run_command};
+use crate::utils::run_command;
use anyhow::{bail, Result};
use clap::Parser;
@@ -165,8 +165,7 @@ fn execute(config: &GlobalConfig, text: &str) -> Result<()> {
)),
}
})
- .prompt()
- .map_err(prompt_op_err)?;
+ .prompt()?;
match anwser.as_str() {
"E" | "e" => {
diff --git a/src/utils/prompt_input.rs b/src/utils/prompt_input.rs
index f63823a..e887b9f 100644
--- a/src/utils/prompt_input.rs
+++ b/src/utils/prompt_input.rs
@@ -10,7 +10,8 @@ pub fn prompt_input_string(desc: &str, required: bool) -> anyhow::Result<String>
} else {
text = text.with_help_message(MSG_OPTIONAL)
}
- text.prompt().map_err(prompt_op_err)
+ let text = text.prompt()?;
+ Ok(text)
}
pub fn prompt_input_integer(desc: &str, required: bool) -> anyhow::Result<String> {
@@ -36,11 +37,8 @@ pub fn prompt_input_integer(desc: &str, required: bool) -> anyhow::Result<String
})
.with_help_message(MSG_OPTIONAL)
}
- text.prompt().map_err(prompt_op_err)
-}
-
-pub fn prompt_op_err<T>(_: T) -> anyhow::Error {
- anyhow::anyhow!("Not finish questionnaire, try again later!")
+ let text = text.prompt()?;
+ Ok(text)
}
#[derive(Debug, Clone, Copy)]