Skip to content

Commit

Permalink
Add commands.query_default config field
Browse files Browse the repository at this point in the history
  • Loading branch information
LucasPickering committed Dec 31, 2024
1 parent c9e021d commit c8d247b
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 8 deletions.
3 changes: 3 additions & 0 deletions crates/config/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,8 @@ pub struct CommandsConfig {
/// Wrapping shell to parse and execute commands
/// If empty, commands will be parsed with shell-words and run natievly
pub shell: Vec<String>,
/// Default query command for responses
pub query_default: Option<String>,
}

impl Default for CommandsConfig {
Expand All @@ -150,6 +152,7 @@ impl Default for CommandsConfig {

Self {
shell: default_shell.iter().map(|s| s.to_string()).collect(),
query_default: None,
}
}
}
Expand Down
11 changes: 7 additions & 4 deletions crates/tui/src/view/common/text_box.rs
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ type Validator = Box<dyn Fn(&str) -> bool>;
impl TextBox {
/// Set initialize value for the text box
pub fn default_value(mut self, default: String) -> Self {
self.state.text = default;
self.state.end();
self.set_text(default);
self
}

Expand Down Expand Up @@ -101,10 +100,15 @@ impl TextBox {
self.state.text
}

/// Set text, and move the cursor to the end. This will **not** emit events
/// Set text, and move the cursor to the end. If the text changed, emit a
/// change event.
pub fn set_text(&mut self, text: String) {
let changed = text != self.state.text;
self.state.text = text;
self.state.end();
if changed {
self.change();
}
}

/// Check if the current input text is valid. Always returns true if there
Expand Down Expand Up @@ -402,7 +406,6 @@ impl PersistedContainer for TextBox {

fn restore_persisted(&mut self, value: Self::Value) {
self.set_text(value);
self.submit();
}
}

Expand Down
35 changes: 31 additions & 4 deletions crates/tui/src/view/component/queryable_body.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,10 @@ impl QueryableBody {
let input_engine = &TuiContext::get().input_engine;
let binding = input_engine.binding_display(Action::Search);

let text_box = TextBox::default()
let query_text_box = TextBox::default()
.placeholder(format!("{binding} to filter"))
.placeholder_focused("Enter command (ex: `jq .results`)")
.default_value(Self::default_query())
.debounce();
let text_state =
TextState::new(response.content_type(), &response.body, true);
Expand All @@ -75,7 +76,7 @@ impl QueryableBody {
query_focused: false,
query_command: None,
query_state: QueryState::None,
query_text_box: text_box.into(),
query_text_box: query_text_box.into(),
text_window: Default::default(),
text_state,
}
Expand All @@ -99,10 +100,26 @@ impl QueryableBody {
&self.text_state.text
}

/// Get the query command to use by default on initial load
fn default_query() -> String {
TuiContext::get()
.config
.commands
.query_default
.clone()
.map(|mut s| {
// Assume the user wants to start by typing a new token, so add
// a space
s.push(' ');
s
})
.unwrap_or_default()
}

/// Update query command based on the current text in the box, and start
/// a task to run the command
fn update_query(&mut self) {
let command = self.query_text_box.data().text();
let command = self.query_text_box.data().text().trim();
let response = &self.response;

// If a command is already running, abort it
Expand Down Expand Up @@ -248,7 +265,17 @@ impl PersistedContainer for QueryableBody {
}

fn restore_persisted(&mut self, value: Self::Value) {
self.query_text_box.data_mut().restore_persisted(value)
let text_box = self.query_text_box.data_mut();
text_box.restore_persisted(value);

// It's pretty common to clear the whole text box without thinking about
// it. In that case, we want to restore the default the next time we
// reload from persistence (probably either app restart or next response
// for this recipe). It's possible the user really wants an empty box
// and this is annoying, but I think it'll be more good than bad.
if text_box.text().is_empty() {
text_box.set_text(Self::default_query());
}
}
}

Expand Down
1 change: 1 addition & 0 deletions docs/src/api/configuration/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ SLUMBER_CONFIG_PATH=~/dotfiles/slumber.yml slumber
| Field | Type | Description | Default |
| -------------------------- | ----------------------------------- | ------------------------------------------------------------------------------------------------- | -------------------------------------------- |
| `commands.shell` | `string[]` | Shell used to execute commands within the TUI. [More info](#commands) | `[sh, -c]` (Unix), `[cmd, /S, /C]` (Windows) |
| `commands.query_default` | `string` | Default query command for all responses | `""` |
| `debug` | `boolean` | Enable developer information | `false` |
| `editor` | `string` | Command to use when opening files for in-app editing. [More info](./editor.md) | `VISUAL`/`EDITOR` env vars, or `vim` |
| `ignore_certificate_hosts` | `string[]` | Hostnames whose TLS certificate errors will be ignored. [More info](../../troubleshooting/tls.md) | `[]` |
Expand Down

0 comments on commit c8d247b

Please sign in to comment.