feat: Add configuration for add_newline (#116)
- Replace TableExt with a Config trait that extends toml::value::Table Add configuration for add_newline - add_newline is a root-level configuration value. When set to false, the initial newline before the prompt is removed.
This commit is contained in:
parent
95ce43ee70
commit
0bc28c521d
|
@ -14,6 +14,9 @@ $ touch ~/.config/starship.toml
|
||||||
All configuration for starship is done in this [TOML](https://github.com/toml-lang/toml) file:
|
All configuration for starship is done in this [TOML](https://github.com/toml-lang/toml) file:
|
||||||
|
|
||||||
```toml
|
```toml
|
||||||
|
# Don't print a new line at the start of the prompt
|
||||||
|
add_newline = false
|
||||||
|
|
||||||
# Replace the "➜" symbol in the prompt with "❯"
|
# Replace the "➜" symbol in the prompt with "❯"
|
||||||
[character] # The name of the module we are confguring is "character"
|
[character] # The name of the module we are confguring is "character"
|
||||||
symbol = "❯" # The "symbol" segment is being set to "❯"
|
symbol = "❯" # The "symbol" segment is being set to "❯"
|
||||||
|
@ -37,6 +40,24 @@ are segments within it. Every module also has a prefix and suffix that are the d
|
||||||
"via " "⬢" "v10.4.1" ""
|
"via " "⬢" "v10.4.1" ""
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Prompt
|
||||||
|
|
||||||
|
This is the list of prompt-wide configuration options.
|
||||||
|
|
||||||
|
### Options
|
||||||
|
|
||||||
|
| Variable | Default | Description|
|
||||||
|
| `add_newline` | `true` | Add a new line before the start of the prompt |
|
||||||
|
|
||||||
|
### Example
|
||||||
|
|
||||||
|
```toml
|
||||||
|
# ~/.config/starship.toml
|
||||||
|
|
||||||
|
# Disable the newline at the start of the prompt
|
||||||
|
add_newline = false
|
||||||
|
```
|
||||||
|
|
||||||
## Battery
|
## Battery
|
||||||
|
|
||||||
The `battery` module shows how charged the device's battery is and its current charging status.
|
The `battery` module shows how charged the device's battery is and its current charging status.
|
||||||
|
|
|
@ -2,25 +2,33 @@ use crate::utils;
|
||||||
use std::env;
|
use std::env;
|
||||||
|
|
||||||
use dirs::home_dir;
|
use dirs::home_dir;
|
||||||
|
use toml::value::Table;
|
||||||
|
|
||||||
pub struct Config {
|
pub trait Config {
|
||||||
data: toml::value::Table,
|
fn initialize() -> Table;
|
||||||
|
fn config_from_file() -> Option<Table>;
|
||||||
|
fn get_module_config(&self, module_name: &str) -> Option<&Table>;
|
||||||
|
|
||||||
|
// Config accessor methods
|
||||||
|
fn get_as_bool(&self, key: &str) -> Option<bool>;
|
||||||
|
fn get_as_str(&self, key: &str) -> Option<&str>;
|
||||||
|
|
||||||
|
// Internal implementation for accessors
|
||||||
|
fn get_config(&self, key: &str) -> Option<&toml::value::Value>;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Config {
|
impl Config for Table {
|
||||||
/// Initialize the Config struct
|
/// Initialize the Config struct
|
||||||
pub fn initialize() -> Config {
|
fn initialize() -> Table {
|
||||||
if let Some(file_data) = Config::config_from_file() {
|
if let Some(file_data) = Table::config_from_file() {
|
||||||
return Config { data: file_data };
|
return file_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
Config {
|
Table::new()
|
||||||
data: toml::value::Table::new(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a config from a starship configuration file
|
/// Create a config from a starship configuration file
|
||||||
fn config_from_file() -> Option<toml::value::Table> {
|
fn config_from_file() -> Option<Table> {
|
||||||
let file_path = match env::var("STARSHIP_CONFIG") {
|
let file_path = match env::var("STARSHIP_CONFIG") {
|
||||||
Ok(path) => {
|
Ok(path) => {
|
||||||
// Use $STARSHIP_CONFIG as the config path if available
|
// Use $STARSHIP_CONFIG as the config path if available
|
||||||
|
@ -55,9 +63,8 @@ impl Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Get the subset of the table for a module by its name
|
/// Get the subset of the table for a module by its name
|
||||||
pub fn get_module_config(&self, module_name: &str) -> Option<&toml::value::Table> {
|
fn get_module_config(&self, module_name: &str) -> Option<&toml::value::Table> {
|
||||||
let module_config = self
|
let module_config = self
|
||||||
.data
|
|
||||||
.get(module_name)
|
.get(module_name)
|
||||||
.map(toml::Value::as_table)
|
.map(toml::Value::as_table)
|
||||||
.unwrap_or(None);
|
.unwrap_or(None);
|
||||||
|
@ -74,16 +81,7 @@ impl Config {
|
||||||
|
|
||||||
module_config
|
module_config
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/// Extends `toml::value::Table` with useful methods
|
|
||||||
pub trait TableExt {
|
|
||||||
fn get_config(&self, key: &str) -> Option<&toml::value::Value>;
|
|
||||||
fn get_as_bool(&self, key: &str) -> Option<bool>;
|
|
||||||
fn get_as_str(&self, key: &str) -> Option<&str>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl TableExt for toml::value::Table {
|
|
||||||
/// Get the config value for a given key
|
/// Get the config value for a given key
|
||||||
fn get_config(&self, key: &str) -> Option<&toml::value::Value> {
|
fn get_config(&self, key: &str) -> Option<&toml::value::Value> {
|
||||||
log::trace!("Looking for config key \"{}\"", key);
|
log::trace!("Looking for config key \"{}\"", key);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::config::{Config, TableExt};
|
use crate::config::Config;
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
|
|
||||||
use clap::ArgMatches;
|
use clap::ArgMatches;
|
||||||
|
@ -13,7 +13,7 @@ use std::path::PathBuf;
|
||||||
/// of the prompt.
|
/// of the prompt.
|
||||||
pub struct Context<'a> {
|
pub struct Context<'a> {
|
||||||
/// The deserialized configuration map from the user's `starship.toml` file.
|
/// The deserialized configuration map from the user's `starship.toml` file.
|
||||||
pub config: Config,
|
pub config: toml::value::Table,
|
||||||
|
|
||||||
/// The current working directory that starship is being called in.
|
/// The current working directory that starship is being called in.
|
||||||
pub current_dir: PathBuf,
|
pub current_dir: PathBuf,
|
||||||
|
@ -51,7 +51,7 @@ impl<'a> Context<'a> {
|
||||||
where
|
where
|
||||||
T: Into<PathBuf>,
|
T: Into<PathBuf>,
|
||||||
{
|
{
|
||||||
let config = Config::initialize();
|
let config = toml::value::Table::initialize();
|
||||||
|
|
||||||
// TODO: Currently gets the physical directory. Get the logical directory.
|
// TODO: Currently gets the physical directory. Get the logical directory.
|
||||||
let current_dir = Context::expand_tilde(dir.into());
|
let current_dir = Context::expand_tilde(dir.into());
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::config::TableExt;
|
use crate::config::Config;
|
||||||
use crate::segment::Segment;
|
use crate::segment::Segment;
|
||||||
use ansi_term::Style;
|
use ansi_term::Style;
|
||||||
use ansi_term::{ANSIString, ANSIStrings};
|
use ansi_term::{ANSIString, ANSIStrings};
|
||||||
|
|
|
@ -2,6 +2,7 @@ use clap::ArgMatches;
|
||||||
use rayon::prelude::*;
|
use rayon::prelude::*;
|
||||||
use std::io::{self, Write};
|
use std::io::{self, Write};
|
||||||
|
|
||||||
|
use crate::config::Config;
|
||||||
use crate::context::Context;
|
use crate::context::Context;
|
||||||
use crate::module::Module;
|
use crate::module::Module;
|
||||||
use crate::modules;
|
use crate::modules;
|
||||||
|
@ -23,12 +24,15 @@ const PROMPT_ORDER: &[&str] = &[
|
||||||
|
|
||||||
pub fn prompt(args: ArgMatches) {
|
pub fn prompt(args: ArgMatches) {
|
||||||
let context = Context::new(args);
|
let context = Context::new(args);
|
||||||
|
let config = &context.config;
|
||||||
|
|
||||||
let stdout = io::stdout();
|
let stdout = io::stdout();
|
||||||
let mut handle = stdout.lock();
|
let mut handle = stdout.lock();
|
||||||
|
|
||||||
// Write a new line before the prompt
|
// Write a new line before the prompt
|
||||||
|
if config.get_as_bool("add_newline") != Some(false) {
|
||||||
writeln!(handle).unwrap();
|
writeln!(handle).unwrap();
|
||||||
|
}
|
||||||
|
|
||||||
let modules = PROMPT_ORDER
|
let modules = PROMPT_ORDER
|
||||||
.par_iter()
|
.par_iter()
|
||||||
|
|
|
@ -9,8 +9,8 @@ lazy_static! {
|
||||||
static ref EMPTY_CONFIG: PathBuf = MANIFEST_DIR.join("empty_config.toml");
|
static ref EMPTY_CONFIG: PathBuf = MANIFEST_DIR.join("empty_config.toml");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Run an instance of starship
|
/// Render the full starship prompt
|
||||||
fn run_starship() -> process::Command {
|
pub fn render_prompt() -> process::Command {
|
||||||
let mut command = process::Command::new("./target/debug/starship");
|
let mut command = process::Command::new("./target/debug/starship");
|
||||||
|
|
||||||
command
|
command
|
||||||
|
@ -22,6 +22,7 @@ fn run_starship() -> process::Command {
|
||||||
command
|
command
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Render a specific starship module by name
|
||||||
pub fn render_module(module_name: &str) -> process::Command {
|
pub fn render_module(module_name: &str) -> process::Command {
|
||||||
let mut command = process::Command::new("./target/debug/starship");
|
let mut command = process::Command::new("./target/debug/starship");
|
||||||
|
|
||||||
|
|
|
@ -32,3 +32,24 @@ fn disabled_module() -> io::Result<()> {
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_newline_configuration() -> io::Result<()> {
|
||||||
|
// Start prompt with newline
|
||||||
|
let default_output = common::render_prompt().output()?;
|
||||||
|
let actual = String::from_utf8(default_output.stdout).unwrap();
|
||||||
|
let expected = actual.trim_start();
|
||||||
|
assert_ne!(actual, expected);
|
||||||
|
|
||||||
|
// Start prompt without newline
|
||||||
|
let output = common::render_prompt()
|
||||||
|
.use_config(toml::toml! {
|
||||||
|
add_newline = false
|
||||||
|
})
|
||||||
|
.output()?;
|
||||||
|
let actual = String::from_utf8(output.stdout).unwrap();
|
||||||
|
let expected = actual.trim_start();
|
||||||
|
assert_eq!(expected, actual);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue