Skip to content

Commit

Permalink
feat: added wrappers around near-cli to support saving cmd to history
Browse files Browse the repository at this point in the history
  • Loading branch information
frolvanya committed Nov 17, 2024
1 parent 98960d5 commit 843f0ab
Show file tree
Hide file tree
Showing 2 changed files with 145 additions and 8 deletions.
109 changes: 109 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,115 @@ $ near

The CLI interactively guides you through some pretty complex topics, helping you make informed decisions along the way.

## Shell Configuration for Command History

To enhance your experience with the NEAR CLI, you can configure your shell to integrate better with the near command. By adding the following functions to your shell configuration file, you ensure that commands executed via near are properly stored in your shell history and easily accessible via the arrow keys.

### Bash

Add the following function to your `~/.bashrc` file:

```bash
function near() {
command near "$@"
tmp_dir="${TMPDIR:-/tmp}"
tmp_file="$tmp_dir/near-cli-rs-final-command.log"
if [[ -f "$tmp_file" ]]; then
final_command=$(<"$tmp_file")
if [[ -n "$final_command" ]]; then
history -s -- "$final_command"
fi
rm "$tmp_file"
fi
}
```

### Zsh

Add the following function to your `~/.zshrc` file:

```zsh
function near() {
command near "$@"
tmp_dir="${TMPDIR:-/tmp}"
tmp_file="$tmp_dir/near-cli-rs-final-command.log"
if [[ -f "$tmp_file" ]]; then
final_command=$(<"$tmp_file")
if [[ -n "$final_command" ]]; then
print -s -- "$final_command"
fi
rm "$tmp_file"
fi
}
```

### Fish

Add the following function to your `~/.config/fish/config.fish` file:

```fish
function near
command near $argv
set tmp_dir (set -q TMPDIR; and echo $TMPDIR; or echo /tmp)
set tmp_file "$tmp_dir/near-cli-rs-final-command.log"
if test -f "$tmp_file"
set -l final_command (cat "$tmp_file")
if test -n "$final_command"
set -l history_file (dirname (status --current-filename))/../fish_history
if set -q XDG_DATA_HOME
set history_file "$XDG_DATA_HOME/fish/fish_history"
else if test -d "$HOME/.local/share/fish"
set history_file "$HOME/.local/share/fish/fish_history"
else
set history_file "$HOME/.fish_history"
end
echo "$history_file"
echo "- cmd: $final_command" >> $history_file
echo " when: "(date +%s) >> $history_file
history --merge
end
rm "$tmp_file"
end
end
```

> [!NOTE]
> For Fish shell, the function appends the command to the Fish history file and merges it to make it immediately accessible via the arrow keys.

### Explanation

These functions wrap the original near command and perform additional steps to read a command from a temporary log file, which is created by the NEAR CLI, and add it to your shell history. This allows you to easily access previous NEAR CLI commands using your shell's history mechanisms.

Steps performed by the functions:

- Run the original near command with all provided arguments.
- Check if the temporary log file exists.
- Read the command from the log file.
- If the command is not empty:
- For Bash and Zsh: Add the command to the shell history.
- For Fish: Append the command to the Fish history file and merge the history.
- Remove the temporary log file to prevent duplicate entries.

> [!IMPORTANT]
> Ensure that your NEAR CLI is configured to write the final command to the temporary log file at the specified location.
> Replace near with `cargo run --` in the functions if you are running the NEAR CLI via cargo locally.

## [Read more in English](docs/README.en.md)
- [Usage](docs/README.en.md#usage)
- [Installation](docs/README.en.md#installation)
Expand Down
44 changes: 36 additions & 8 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@
clippy::large_enum_variant,
clippy::too_many_arguments
)]

use std::fs::OpenOptions;
use std::io::Write;

use clap::Parser;
#[cfg(feature = "self-update")]
use color_eyre::eyre::WrapErr;
Expand All @@ -28,6 +32,8 @@ pub use near_cli_rs::utils_command;

pub use near_cli_rs::GlobalContext;

const FINAL_COMMAND_FILE_NAME: &str = "near-cli-rs-final-command.log";

type ConfigContext = (crate::config::Config,);

#[derive(Debug, Clone, interactive_clap::InteractiveClap)]
Expand Down Expand Up @@ -66,6 +72,21 @@ impl From<CmdContext> for crate::GlobalContext {
}
}

fn store_cmd(cli_cmd_str: &str) {
let tmp_file_path = std::env::temp_dir().join(FINAL_COMMAND_FILE_NAME);

if let Ok(mut tmp_file) = OpenOptions::new()
.write(true)
.create(true)
.truncate(true)
.open(tmp_file_path)
{
if let Err(err) = writeln!(tmp_file, "{}", cli_cmd_str) {
eprintln!("Failed to store final command in a temporary file: {}", err);
}
};
}

fn main() -> crate::common::CliResult {
let config = crate::config::Config::get_config_toml()?;

Expand Down Expand Up @@ -168,13 +189,17 @@ fn main() -> crate::common::CliResult {
let cli_cmd = match <Cmd as interactive_clap::FromCli>::from_cli(Some(cli), (config,)) {
interactive_clap::ResultFromCli::Ok(cli_cmd)
| interactive_clap::ResultFromCli::Cancel(Some(cli_cmd)) => {
let cli_cmd_str = shell_words::join(
std::iter::once(&near_cli_exec_path).chain(&cli_cmd.to_cli_args()),
);

eprintln!(
"\n\nHere is your console command if you need to script it or re-run:\n {}\n",
shell_words::join(
std::iter::once(&near_cli_exec_path).chain(&cli_cmd.to_cli_args())
)
.yellow()
cli_cmd_str.yellow()
);

store_cmd(&cli_cmd_str);

Ok(Some(cli_cmd))
}
interactive_clap::ResultFromCli::Cancel(None) => {
Expand All @@ -186,13 +211,16 @@ fn main() -> crate::common::CliResult {
}
interactive_clap::ResultFromCli::Err(optional_cli_cmd, err) => {
if let Some(cli_cmd) = optional_cli_cmd {
let cli_cmd_str = shell_words::join(
std::iter::once(&near_cli_exec_path).chain(&cli_cmd.to_cli_args()),
);

eprintln!(
"\nHere is your console command if you need to script it or re-run:\n {}\n",
shell_words::join(
std::iter::once(&near_cli_exec_path).chain(&cli_cmd.to_cli_args())
)
.yellow()
cli_cmd_str.yellow()
);

store_cmd(&cli_cmd_str);
}
Err(err)
}
Expand Down

0 comments on commit 843f0ab

Please sign in to comment.