import curses
def main(stdscr):
curses.curs_set(1)
stdscr.clear()
stdscr.refresh()
text = []
row = 0
while True:
stdscr.move(row, 0)
stdscr.clrtoeol()
stdscr.addstr(row, 0, ''.join(text))
stdscr.refresh()
ch = stdscr.getch()
if ch == 27: # ESCキーで終了
break
elif ch == 10: # Enter
text.append('\n')
row += 1
elif ch == 127 or ch == curses.KEY_BACKSPACE:
if text:
text.pop()
if text[-1] == '\n':
row -= 1
else:
text.append(chr(ch))
with open("output.txt", "w") as f:
f.write(''.join(text))
curses.wrapper(main)
Rustで書くと
use crossterm::{
cursor,
event::{read, Event, KeyCode},
terminal::{enable_raw_mode, disable_raw_mode, ClearType},
ExecutableCommand,
};
use std::io::{stdout, Write};
use std::fs::File;
fn main() -> std::io::Result<()> {
let mut stdout = stdout();
let mut buffer = String::new();
enable_raw_mode()?;
stdout.execute(crossterm::terminal::Clear(ClearType::All))?;
stdout.execute(cursor::MoveTo(0, 0))?;
loop {
match read()? {
Event::Key(event) => match event.code {
KeyCode::Char(c) => {
buffer.push(c);
print!("{}", c);
stdout.flush()?;
}
KeyCode::Enter => {
buffer.push('\n');
print!("\r\n");
stdout.flush()?;
}
KeyCode::Backspace => {
buffer.pop();
stdout.execute(cursor::MoveLeft(1))?;
print!(" ");
stdout.execute(cursor::MoveLeft(1))?;
stdout.flush()?;
}
KeyCode::Esc => {
break;
}
_ => {}
},
_ => {}
}
}
disable_raw_mode()?;
let mut file = File::create("output.txt")?;
write!(file, "{}", buffer)?;
Ok(())
}
inputファイルを読み込んで、出力
use crossterm::{
cursor,
event::{read, Event, KeyCode},
terminal::{enable_raw_mode, disable_raw_mode, ClearType},
ExecutableCommand,
};
use std::io::{stdout, Write};
use std::fs::{File, read_to_string};
fn main() -> std::io::Result<()> {
let mut stdout = stdout();
let mut buffer = String::new();
let initial_text = match read_to_string("input.txt") {
Ok(content) => content,
Err(_) => String::new(),
};
buffer.push_str(&initial_text);
enable_raw_mode().expect("Failed to enable raw mode");
stdout.execute(crossterm::terminal::Clear(ClearType::All))?;
stdout.execute(cursor::MoveTo(0, 0))?;
let mut row: u16 = 0;
let mut col: u16 = 0;
for ch in buffer.chars() {
match ch {
'\n' => {
print!("\r\n");
row += 1;
col = 0;
}
_ => {
print!("{}", ch);
col += 1;
}
}
}
stdout.flush()?;
stdout.execute(cursor::MoveTo(col, row))?;
loop {
match read()? {
Event::Key(event) => match event.code {
KeyCode::Char(c) => {
buffer.push(c);
print!("{}", c);
stdout.flush()?;
}
KeyCode::Enter => {
buffer.push('\n');
row += 1;
print!("\r\n");
stdout.flush()?;
}
KeyCode::Backspace => {
buffer.pop();
stdout.execute(cursor::MoveLeft(1))?;
print!(" ");
stdout.execute(cursor::MoveLeft(1))?;
stdout.flush()?;
}
KeyCode::Esc => {
break;
}
_ => {}
},
_ => {}
}
}
disable_raw_mode()?;
let mut file = File::create("output.txt")?;
write!(file, "{}", buffer)?;
Ok(())
}
input.txtを行単位で読み込んで出力するなどの工夫が必要