added README and gitignore

This commit is contained in:
2026-08-12 18:19:55 +02:00
parent 71afe6df1d
commit bf28aaa435
5 changed files with 58 additions and 210 deletions
-122
View File
@@ -1,122 +0,0 @@
mod keymaps;
mod cml_functions;
use colored::*;
use std::io::Write;
use rust_translate::translate;
use random_word::gen_len;
use keymaps::get_keymap_rus;
use cml_functions::*;
// TODO:
// [ ] Line wrapping / character cap
// [x] Working cursor navigation
// [ ] Proper has_max_len (see below)
// [x] Allow full caps translation (_YU / _Yu)
// [x] Allow typing within text
// [ ] Clean up result (whitespaces)
//
// BUG:
// [x] Space -> Arrow left -> backspace -> panic
// [x] 4x space -> backspace -> -> sp -> bs -> panic
// [x] 2x space -> 2x backspace -> panic
// [x] Cursor inserts, doesnt overwrite
// [x] special letter -> left -> space -> cursor pos wrong
fn main() {
let result = diff_string_copy("hellollo".to_string(), "hello".to_string());
println!("\n{:?}", result);
loop {
let learned_word = learn_new_word();
if learned_word.is_none() {
break;
};
}
//println!("Congrats!! You learned a new Word: {}", learned_word);
}
#[tokio::main]
async fn learn_new_word() -> Option<String> {
//print!("Welcome! Which word do you want to learn?\n> ");
std::io::stdout().flush().unwrap();
//let mut vocab = String::new();
//io::stdin().read_line(&mut vocab).expect("Failed to read line");
//vocab = vocab.trim().to_string();
let vocab = gen_len(4, random_word::Lang::En).expect("no word found").to_string();
let vocab_tr = translate(&vocab, "en", "ru").await.unwrap();
println!("\n{}: {}", vocab.red(), vocab_tr.green());
println!("Please repeat in russian 🇷🇺 (2x ESC to quit)");
let input_opt = cml_input_line(get_keymap_rus());
input_opt.as_ref()?;
let input = input_opt.unwrap().to_string();
//println!("] '{}'", input);
if input == vocab_tr {
println!("Well done!");
}
else {
println!("sorry, thats wrong!");
if input.to_lowercase() == vocab_tr.to_lowercase() {
println!("upper/lowecase counts!!");
};
}
Some(vocab.to_string())
}
fn diff_string_copy(original: String, copy: String) -> Vec<u16> {
let mut diff_indicies: Vec<u16> = Vec::new();
let mut cp = copy.chars();
for letter in original.chars() {
//print!("{}", letter);
#[allow(unused_assignments)]
let mut cp_letter: Option<char> = None;
let mut found = false;
loop {
cp_letter = cp.next();
if let Some(cp_lt_unpacked) = cp_letter {
// print!("{}", letter);
if cp_lt_unpacked == letter {
print!("{}", letter);
found = true;
break;
}
else {
// different letter
print!("#");
}
}
else {
// cp iter has run out
diff_indicies.push(1);
println!("");
return diff_indicies;
}
}
if !found {
diff_indicies.push(1);
}
}
println!("\nended");
diff_indicies
}
+1
View File
@@ -0,0 +1 @@
target
+57
View File
@@ -0,0 +1,57 @@
# Russian Typing Trainer
An interactive typing program i built to learn the Cyrillic alphabet and terminal modes (two birds, one stone).
You're given a word in Russian and have to type it out using English keys.
Your keystrokes are automatically translated into Russian (Cyrillic) characters.
## Usage
- Type using standard English keys. Input is translated to Cyrillic automatically
- To type a double letter (look below), prefix with `_` (example: `_yu -> ю`)
- Press ESC twice to exit
## Example output
```bash
pour: налить
Please repeat in russian 🇷🇺 (2x ESC to quit)
] налить
Well done!
```
## Keymap
| Input | Cyrillic |
|-------|----------|
| `zh` | ж / Ж |
| `ch` | ч / Ч |
| `yu` | ю / Ю |
| `ye` | е / Е |
| `yo` | ё / Ё |
| `ya` | я / Я |
| `iy` | ы / Ы |
| `sh` | ш / Ш |
| `kh` | х / Х |
| `ts` | ц / Ц |
| `_i` | й / Й |
| `k` | к / К |
| `o` | о / О |
| `m` | м / М |
| `v` | в / В |
| `g` | г / Г |
| `l` | л / Л |
| `d` | д / Д |
| `f` | ф / Ф |
| `i` | и / И |
| `x` | х / Х |
| `z` | з / З |
| `r` | р / Р |
| `t` | т / Т |
| `a` | а / А |
| `p` | п / П |
| `n` | н / Н |
| `s` | с / С |
| `e` | э / Э |
| `u` | у / Y |
| `b` | б / Б |
| `y` | ы / Ы |
| `'` | ь |
-55
View File
@@ -1,55 +0,0 @@
use std::io::{self, Read, Write};
use std::process;
use raw::IntoRawMode;
use termion::*;
fn main() {
let stdin = io::stdin().lock();
let mut stdout = io::stdout().into_raw_mode().unwrap();
let mut input_buffer = String::new();
let _translation_map = vec![
("-f-", "Ф"),
("-I-", "И")
];
for byte in stdin.bytes() {
match byte.unwrap() {
// Handle special key (like backspace or enter)
27 => {
// Handle escape sequences for arrow keys, etc.
continue;
}
10 => { // Enter key
// Process the current input buffer and reset
writeln!(stdout, "\nYou typed: {}", input_buffer).unwrap();
input_buffer.clear();
process::exit(0);
}
127 => { // Backspace key
input_buffer.pop();
write!(stdout, "\x1b[2K\r{}", input_buffer).unwrap();
}
c => {
// Append the character to the input buffer
let ch = c as char;
input_buffer.push(ch);
// Check if the input matches any translation pattern
//for (pattern, replacement) in &translation_map {
// let re = Regex::new(pattern).unwrap();
// if re.is_match(&input_buffer) {
// input_buffer = re.replace_all(&input_buffer, *replacement).to_string();
// break; // Once we replace it, exit the loop
// }
//}
// Clear the screen and redraw input (to simulate live updating)
write!(stdout, "\x1b[2K\r{}", input_buffer).unwrap();
stdout.flush().unwrap();
}
}
}
}
-33
View File
@@ -1,33 +0,0 @@
use std::io::{self, Read, Write};
use termion::raw::IntoRawMode;
fn main() {
let _stdout = io::stdout().into_raw_mode();
let stdin = io::stdin().lock();
let mut input = String::new();
for byte in stdin.bytes() {
let inp = byte.unwrap();
let inp_char = inp as char;
match inp {
127 => {
if !input.is_empty() {
input.pop();
print!("\x08 \x08");
}
},
b'\r' => {
print!("\r");
println!();
},
_ => {
input.push(inp_char);
print!("{}", inp_char);
}
}
io::stdout().flush().unwrap();
}
}