Skip to content

Commit

Permalink
Ahnlich CLI rewrite with Raw mode enabled (#125)
Browse files Browse the repository at this point in the history
* unfucking the cli: used raw mode to extrapolate events properly

* add logic for deleting entries

* clippy fixes

* Implemented ctrl-C exit, clearsreen (ctrl-l) and fix spaces not printing

* Adding history navigation control and typing after cursor move

---------

Co-authored-by: Diretnan Domnan <[email protected]>
  • Loading branch information
Iamdavidonuh and deven96 authored Oct 4, 2024
1 parent 82950a1 commit 1f0bc6a
Show file tree
Hide file tree
Showing 10 changed files with 469 additions and 88 deletions.
49 changes: 49 additions & 0 deletions ahnlich/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 ahnlich/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,4 @@ opentelemetry = { version = "0.23.0", features = ["trace"] }
tracing-opentelemetry = "0.24.0"
log = "0.4"
fallible_collections = "0.4.9"
dirs = "5.0.1"
3 changes: 2 additions & 1 deletion ahnlich/cli/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,9 @@ path = "src/lib.rs"


[dependencies]
crossterm = "0.28.1"
crossterm = { version = "0.28.1", feature = ["bracketed-paste"]}
clap.workspace = true
dirs.workspace = true
dsl = { path = "../dsl", version = "*" }
thiserror.workspace = true
tokio.workspace = true
Expand Down
8 changes: 8 additions & 0 deletions ahnlich/cli/src/connect.rs
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,14 @@ impl AgentPool {
}
}

/// Returns the commands for the agent pool in question
pub fn commands(&self) -> &[&str] {
match self {
AgentPool::AI(_) => dsl::ai::COMMANDS,
AgentPool::DB(_) => dsl::db::COMMANDS,
}
}

/// Checks if the connection to to a host and post is alive, also checks the cli is connected
/// to the right server( ahnlich ai or db)
pub async fn is_valid_connection(&self) -> Result<bool, String> {
Expand Down
103 changes: 103 additions & 0 deletions ahnlich/cli/src/history.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
use std::{
fs::OpenOptions,
io::{self, BufRead, Write},
path::PathBuf,
};

fn get_history_file_path() -> PathBuf {
let mut path = dirs::home_dir().expect("Could not find home directory");
path.push(".ahnlich_cli_history");
path
}

fn load_command_history() -> Vec<String> {
let path = get_history_file_path();
if path.exists() {
let file = OpenOptions::new()
.read(true)
.open(path)
.expect("Unable to open history file");
let reader = io::BufReader::new(file);
reader.lines().map_while(Result::ok).collect()
} else {
Vec::new()
}
}

fn save_command_history(commands: &[String]) {
let path = get_history_file_path();
let mut file = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(path)
.expect("Unable to open history file");
for command in commands {
writeln!(file, "{}", command).expect("Unable to write to history file");
}
}

pub(crate) struct HistoryManager {
command_history: Vec<String>,
current_command_index: usize,
}

impl HistoryManager {
pub(crate) fn new() -> Self {
let command_history = load_command_history();
let current_command_index = command_history.len();
Self {
command_history,
current_command_index,
}
}

pub(crate) fn down(&mut self) -> String {
if self.current_command_index < self.command_history.len() {
self.current_command_index += 1;
}
if self.is_index_end() {
String::new()
} else {
self.get_at_index()
}
}

pub(crate) fn up(&mut self) -> String {
if self.current_command_index > 0 {
self.current_command_index -= 1;
}
if self.command_history.is_empty() && self.current_command_index == 0 {
String::new()
} else {
self.get_at_index()
}
}

fn get_at_index(&self) -> String {
self.command_history[self.current_command_index].clone()
}

pub(crate) fn reset_index(&mut self) {
self.current_command_index = self.command_history.len();
}

pub(crate) fn is_index_end(&self) -> bool {
self.current_command_index == self.command_history.len()
}

pub(crate) fn save_to_disk(&self) {
save_command_history(&self.command_history);
}

pub(crate) fn add_command(&mut self, command: &str) {
if let Some(last_command) = self.command_history.last() {
if last_command != command {
self.command_history.push(command.to_string());
}
} else {
self.command_history.push(command.to_string());
}
self.reset_index();
}
}
1 change: 1 addition & 0 deletions ahnlich/cli/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod config;
pub mod connect;
mod history;
pub mod term;
Loading

0 comments on commit 1f0bc6a

Please sign in to comment.