add --long flag to history command for sqlite history (#7480)

This commit is contained in:
Darren Schroeder 2022-12-15 08:46:32 -06:00 committed by GitHub
parent 578ef04988
commit b6683a3010
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -2,10 +2,10 @@ use nu_protocol::ast::Call;
use nu_protocol::engine::{Command, EngineState, Stack}; use nu_protocol::engine::{Command, EngineState, Stack};
use nu_protocol::{ use nu_protocol::{
Category, Example, HistoryFileFormat, IntoInterruptiblePipelineData, PipelineData, ShellError, Category, Example, HistoryFileFormat, IntoInterruptiblePipelineData, PipelineData, ShellError,
Signature, Value, Signature, Span, Value,
}; };
use reedline::{ use reedline::{
FileBackedHistory, History as ReedlineHistory, SearchDirection, SearchQuery, FileBackedHistory, History as ReedlineHistory, HistoryItem, SearchDirection, SearchQuery,
SqliteBackedHistory, SqliteBackedHistory,
}; };
@ -24,6 +24,11 @@ impl Command for History {
fn signature(&self) -> nu_protocol::Signature { fn signature(&self) -> nu_protocol::Signature {
Signature::build("history") Signature::build("history")
.switch("clear", "Clears out the history entries", Some('c')) .switch("clear", "Clears out the history entries", Some('c'))
.switch(
"long",
"Show long listing of entries for sqlite history",
Some('l'),
)
.category(Category::Misc) .category(Category::Misc)
} }
@ -35,9 +40,11 @@ impl Command for History {
_input: PipelineData, _input: PipelineData,
) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> { ) -> Result<nu_protocol::PipelineData, nu_protocol::ShellError> {
let head = call.head; let head = call.head;
// todo for sqlite history this command should be an alias to `open ~/.config/nushell/history.sqlite3 | get history` // todo for sqlite history this command should be an alias to `open ~/.config/nushell/history.sqlite3 | get history`
if let Some(config_path) = nu_path::config_dir() { if let Some(config_path) = nu_path::config_dir() {
let clear = call.has_flag("clear"); let clear = call.has_flag("clear");
let long = call.has_flag("long");
let ctrlc = engine_state.ctrlc.clone(); let ctrlc = engine_state.ctrlc.clone();
let mut history_path = config_path; let mut history_path = config_path;
@ -106,85 +113,9 @@ impl Command for History {
.ok() .ok()
}) })
.map(move |entries| { .map(move |entries| {
entries entries.into_iter().enumerate().map(move |(idx, entry)| {
.into_iter() create_history_record(idx, entry, long, head)
.enumerate() })
.map(move |(idx, entry)| Value::Record {
cols: vec![
"item_id".into(),
"start_timestamp".into(),
"command".to_string(),
"session_id".into(),
"hostname".into(),
"cwd".into(),
"duration".into(),
"exit_status".into(),
"index".to_string(),
],
vals: vec![
Value::Int {
val: match entry.id {
Some(id) => {
let ids = id.to_string();
match ids.parse::<i64>() {
Ok(i) => i,
_ => 0i64,
}
}
None => 0i64,
},
span: head,
},
Value::String {
val: match entry.start_timestamp {
Some(time) => time.to_string(),
None => "".into(),
},
span: head,
},
Value::String {
val: entry.command_line,
span: head,
},
Value::Int {
val: match entry.session_id {
Some(sid) => {
let sids = sid.to_string();
match sids.parse::<i64>() {
Ok(i) => i,
_ => 0i64,
}
}
None => 0i64,
},
span: head,
},
Value::String {
val: match entry.hostname {
Some(host) => host,
None => "".into(),
},
span: head,
},
Value::String {
val: match entry.cwd {
Some(cwd) => cwd,
None => "".into(),
},
span: head,
},
Value::Duration {
val: match entry.duration {
Some(d) => d.as_nanos().try_into().unwrap_or(0),
None => 0,
},
span: head,
},
Value::int(entry.exit_status.unwrap_or(0), head),
Value::int(idx as i64, head),
],
span: head,
})
}) })
.ok_or(ShellError::FileNotFound(head))? .ok_or(ShellError::FileNotFound(head))?
.into_pipeline_data(ctrlc)), .into_pipeline_data(ctrlc)),
@ -215,3 +146,114 @@ impl Command for History {
] ]
} }
} }
fn create_history_record(idx: usize, entry: HistoryItem, long: bool, head: Span) -> Value {
//1. Format all the values
//2. Create a record of either short or long columns and values
let item_id_value = Value::Int {
val: match entry.id {
Some(id) => {
let ids = id.to_string();
match ids.parse::<i64>() {
Ok(i) => i,
_ => 0i64,
}
}
None => 0i64,
},
span: head,
};
let start_timestamp_value = Value::String {
val: match entry.start_timestamp {
Some(time) => time.to_string(),
None => "".into(),
},
span: head,
};
let command_value = Value::String {
val: entry.command_line,
span: head,
};
let session_id_value = Value::Int {
val: match entry.session_id {
Some(sid) => {
let sids = sid.to_string();
match sids.parse::<i64>() {
Ok(i) => i,
_ => 0i64,
}
}
None => 0i64,
},
span: head,
};
let hostname_value = Value::String {
val: match entry.hostname {
Some(host) => host,
None => "".into(),
},
span: head,
};
let cwd_value = Value::String {
val: match entry.cwd {
Some(cwd) => cwd,
None => "".into(),
},
span: head,
};
let duration_value = Value::Duration {
val: match entry.duration {
Some(d) => d.as_nanos().try_into().unwrap_or(0),
None => 0,
},
span: head,
};
let exit_status_value = Value::int(entry.exit_status.unwrap_or(0), head);
let index_value = Value::int(idx as i64, head);
if long {
Value::Record {
cols: vec![
"item_id".into(),
"start_timestamp".into(),
"command".to_string(),
"session_id".into(),
"hostname".into(),
"cwd".into(),
"duration".into(),
"exit_status".into(),
"idx".to_string(),
],
vals: vec![
item_id_value,
start_timestamp_value,
command_value,
session_id_value,
hostname_value,
cwd_value,
duration_value,
exit_status_value,
index_value,
],
span: head,
}
} else {
Value::Record {
cols: vec![
"start_timestamp".into(),
"command".to_string(),
"cwd".into(),
"duration".into(),
"exit_status".into(),
],
vals: vec![
start_timestamp_value,
command_value,
cwd_value,
duration_value,
exit_status_value,
],
span: head,
}
}
}