climenu provides interactive command-line menus,
inspired by popular CLI tools like inquirer.js,
Python’s pick, and Go’s survey. It offers an
intuitive interface for users to make selections directly in the R
console, making your scripts and packages more interactive and
user-friendly.
You can pre-select items by value or by index:
# Pre-select by value
selected <- checkbox(
choices = c("Option A", "Option B", "Option C", "Option D"),
selected = c("Option A", "Option C"),
prompt = "Modify your selection:"
)
# Options A and C will be checked initially# Pre-select by index
selected <- checkbox(
choices = c("Option A", "Option B", "Option C", "Option D"),
selected = c(1, 3), # First and third items
prompt = "Modify your selection:"
)For single-selection menus, pre-selection sets the cursor position:
Sometimes you need the position of the selected item rather than its value:
# Single selection - returns integer
index <- select(
choices = c("First", "Second", "Third"),
return_index = TRUE
)
# Returns: 2 (if user selected "Second")
# Multiple selection - returns integer vector
indices <- checkbox(
choices = c("Alpha", "Beta", "Gamma", "Delta"),
return_index = TRUE
)
# Returns: c(1, 3, 4) (if user selected Alpha, Gamma, Delta)This is particularly useful when you need to map selections back to data structures or when the choice labels differ from the underlying values you want to work with.
When the keypress package is installed, you get instant
keyboard feedback:
| Key | Action |
|---|---|
| ↑ or k | Move cursor up |
| ↓ or j | Move cursor down |
| Space | Toggle selection (checkbox only) |
| Enter | Confirm selection |
| Esc or q | Cancel (returns NULL) |
Install it for the best experience:
If keypress is not available, climenu falls
back to readline() mode. You’ll need to type commands and
press Enter:
k or up - Move upj or down - Move downspace - Toggle selection (checkbox only)<number> - Jump directly to item number<Enter> - Confirm selectionq or quit - Cancelclimenu will show a one-time message suggesting to
install keypress for better keyboard support.
# Ask user to configure application settings
cat("\n=== Application Configuration ===\n")
# Choose environment
env <- select(
choices = c("Development", "Staging", "Production"),
prompt = "Select environment:"
)
# Enable features
features <- checkbox(
choices = c("Logging", "Caching", "Analytics", "Debug Mode"),
selected = c("Logging", "Caching"), # Sensible defaults
prompt = "Enable features:"
)
# Choose log level
log_level <- select(
choices = c("ERROR", "WARN", "INFO", "DEBUG", "TRACE"),
selected = "INFO",
prompt = "Select log level:"
)
# Build configuration
config <- list(
environment = env,
features = features,
log_level = log_level
)
cat("\nConfiguration complete!\n")
print(config)# Select datasets to process
available_datasets <- c(
"sales_2023.csv",
"sales_2024.csv",
"customers.csv",
"products.csv",
"inventory.csv"
)
datasets <- checkbox(
choices = available_datasets,
prompt = "Select datasets to process:"
)
if (is.null(datasets)) {
cat("Processing cancelled.\n")
} else {
# Choose processing method
method <- select(
choices = c("Fast (approximate)", "Standard", "Thorough (slow)"),
prompt = "Select processing method:"
)
cat("\nProcessing", length(datasets), "datasets using", method, "method...\n")
# ... processing logic here ...
}# Get list of files
files <- list.files(pattern = "\\.csv$")
if (length(files) == 0) {
cat("No CSV files found.\n")
} else {
# Let user select files, get indices
indices <- checkbox(
choices = files,
return_index = TRUE,
prompt = "Select files to delete:"
)
if (!is.null(indices) && length(indices) > 0) {
files_to_delete <- files[indices]
# Confirm deletion
confirm <- select(
choices = c("Yes, delete them", "No, cancel"),
prompt = paste("Delete", length(files_to_delete), "file(s)?")
)
if (confirm == "Yes, delete them") {
file.remove(files_to_delete)
cat("Deleted", length(files_to_delete), "file(s).\n")
}
}
}When a user cancels a selection (by pressing Esc or q), the menu
functions return NULL:
choice <- select(c("Continue", "Skip", "Abort"))
if (is.null(choice)) {
cat("User cancelled the operation.\n")
# Handle cancellation appropriately
stop("Operation cancelled by user")
}
# Safe to proceed with choice
cat("User selected:", choice, "\n")Always check for NULL returns when user input is
critical to your workflow.
When climenu detects it’s not running in an interactive
session (e.g., in Rscript, automated testing, or R CMD check), it:
select(): returns the first choice (or pre-selected
item if specified)checkbox(): returns pre-selected items (or empty vector
if none)This ensures your code can run in both interactive and automated contexts.
If you’re building an R package and want to use
climenu:
Add climenu to your Imports:
Imports:
climenu
Suggests:
keypress
#' Interactive configuration function
#' @export
configure_analysis <- function() {
# Check if interactive
if (!interactive()) {
cli::cli_inform("Using default configuration (non-interactive mode)")
return(get_default_config())
}
# Show interactive menu
method <- climenu::select(
choices = c("Linear Model", "Random Forest", "Neural Network"),
prompt = "Select analysis method:"
)
if (is.null(method)) {
cli::cli_abort("Configuration cancelled by user")
}
# ... rest of configuration logic ...
return(config)
}Keep choices concise - Long choice text may not display well in narrow terminals
Provide clear prompts - Tell users what they’re selecting and what will happen
Use pre-selection wisely - Pre-select sensible defaults to improve UX
Handle cancellation - Always check for
NULL returns
Test non-interactive behavior - Ensure your code works in automated contexts
Recommend keypress - Consider mentioning in your
package README that users should install keypress for the
best experience
Consider sort order - Present choices in a logical order (alphabetical, by frequency, by importance)
select(choices, prompt, selected, return_index)Single selection menu. Parameters same as menu() but
without type.
checkbox(choices, prompt, selected, return_index)Multiple selection menu. Parameters same as menu() but
without type.
Install the keypress package for proper arrow key
support:
interactive()
returns FALSE)climenu makes it easy to add interactive menus to your R
scripts and packages. Whether you’re building a data analysis wizard,
configuration tool, or just need better user input, climenu
provides an intuitive and robust solution.
Happy menu-making!