2
2
// Copyright (c) 2023-2024 Rust Nostr Developers
3
3
// Distributed under the MIT software license
4
4
5
- use std:: fs:: File ;
5
+ use std:: fs:: { self , File } ;
6
6
use std:: io:: { BufRead , BufReader } ;
7
+ use std:: path:: PathBuf ;
7
8
use std:: time:: Duration ;
8
9
9
10
use clap:: Parser ;
10
11
use nostr_relay_builder:: prelude:: * ;
11
12
use nostr_sdk:: prelude:: * ;
12
13
use rustyline:: error:: ReadlineError ;
13
- use rustyline:: DefaultEditor ;
14
+ use rustyline:: history:: FileHistory ;
15
+ use rustyline:: { Config , Editor } ;
14
16
use tokio:: time:: Instant ;
15
17
16
18
mod cli;
@@ -30,7 +32,18 @@ async fn run() -> Result<()> {
30
32
31
33
match args. command {
32
34
Command :: Shell { relays } => {
33
- let db = NostrLMDB :: open ( "./db/nostr-lmdb" ) ?;
35
+ // Get data dir
36
+ let data_dir: PathBuf = dirs:: data_dir ( ) . expect ( "Can't find data directory" ) ;
37
+
38
+ // Compose paths
39
+ let nostr_cli_dir: PathBuf = data_dir. join ( "rust-nostr/cli" ) ;
40
+ let db_path = nostr_cli_dir. join ( "data/lmdb" ) ;
41
+ let history_path = nostr_cli_dir. join ( ".shell_history" ) ;
42
+
43
+ // Create main dir if not exists
44
+ fs:: create_dir_all ( nostr_cli_dir) ?;
45
+
46
+ let db = NostrLMDB :: open ( db_path) ?;
34
47
let client = Client :: builder ( ) . database ( db) . build ( ) ;
35
48
36
49
// Add relays
@@ -40,15 +53,25 @@ async fn run() -> Result<()> {
40
53
41
54
client. connect ( ) . await ;
42
55
43
- let rl = & mut DefaultEditor :: new ( ) ?;
56
+ let config = Config :: builder ( ) . max_history_size ( 2000 ) ?. build ( ) ;
57
+ let history = FileHistory :: with_config ( config) ;
58
+ let rl: & mut Editor < ( ) , FileHistory > = & mut Editor :: with_history ( config, history) ?;
59
+
60
+ // Load history
61
+ let _ = rl. load_history ( & history_path) ;
44
62
45
63
loop {
46
64
let readline = rl. readline ( "nostr> " ) ;
47
65
match readline {
48
66
Ok ( line) => {
67
+ // Add to history
49
68
rl. add_history_entry ( line. as_str ( ) ) ?;
69
+
70
+ // Split command line
50
71
let mut vec: Vec < String > = parser:: split ( & line) ?;
51
72
vec. insert ( 0 , String :: new ( ) ) ;
73
+
74
+ // Parse command
52
75
match ShellCommand :: try_parse_from ( vec) {
53
76
Ok ( command) => {
54
77
if let Err ( e) = handle_command ( command, & client) . await {
@@ -73,6 +96,9 @@ async fn run() -> Result<()> {
73
96
}
74
97
}
75
98
99
+ // Save history to file
100
+ rl. save_history ( & history_path) ?;
101
+
76
102
Ok ( ( ) )
77
103
}
78
104
Command :: Serve => {
0 commit comments