Skip to content

Commit

Permalink
feat: Add configuration for add_newline (#116)
Browse files Browse the repository at this point in the history
- 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.
  • Loading branch information
matchai committed Jul 27, 2019
1 parent 95ce43e commit 0bc28c5
Show file tree
Hide file tree
Showing 7 changed files with 73 additions and 28 deletions.
21 changes: 21 additions & 0 deletions docs/config/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@ $ touch ~/.config/starship.toml
All configuration for starship is done in this [TOML](https://github.com/toml-lang/toml) file:

```toml
# Don't print a new line at the start of the prompt
add_newline = false

# Replace the "➜" symbol in the prompt with "❯"
[character] # The name of the module we are confguring is "character"
symbol = "" # The "symbol" segment is being set to "❯"
Expand All @@ -37,6 +40,24 @@ are segments within it. Every module also has a prefix and suffix that are the d
"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

The `battery` module shows how charged the device's battery is and its current charging status.
Expand Down
40 changes: 19 additions & 21 deletions src/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,25 +2,33 @@ use crate::utils;
use std::env;

use dirs::home_dir;
use toml::value::Table;

pub struct Config {
data: toml::value::Table,
pub trait Config {
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
pub fn initialize() -> Config {
if let Some(file_data) = Config::config_from_file() {
return Config { data: file_data };
fn initialize() -> Table {
if let Some(file_data) = Table::config_from_file() {
return file_data;
}

Config {
data: toml::value::Table::new(),
}
Table::new()
}

/// 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") {
Ok(path) => {
// Use $STARSHIP_CONFIG as the config path if available
Expand Down Expand Up @@ -55,9 +63,8 @@ impl Config {
}

/// 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
.data
.get(module_name)
.map(toml::Value::as_table)
.unwrap_or(None);
Expand All @@ -74,16 +81,7 @@ impl 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
fn get_config(&self, key: &str) -> Option<&toml::value::Value> {
log::trace!("Looking for config key \"{}\"", key);
Expand Down
6 changes: 3 additions & 3 deletions src/context.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::{Config, TableExt};
use crate::config::Config;
use crate::module::Module;

use clap::ArgMatches;
Expand All @@ -13,7 +13,7 @@ use std::path::PathBuf;
/// of the prompt.
pub struct Context<'a> {
/// 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.
pub current_dir: PathBuf,
Expand Down Expand Up @@ -51,7 +51,7 @@ impl<'a> Context<'a> {
where
T: Into<PathBuf>,
{
let config = Config::initialize();
let config = toml::value::Table::initialize();

// TODO: Currently gets the physical directory. Get the logical directory.
let current_dir = Context::expand_tilde(dir.into());
Expand Down
2 changes: 1 addition & 1 deletion src/module.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::config::TableExt;
use crate::config::Config;
use crate::segment::Segment;
use ansi_term::Style;
use ansi_term::{ANSIString, ANSIStrings};
Expand Down
6 changes: 5 additions & 1 deletion src/print.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ use clap::ArgMatches;
use rayon::prelude::*;
use std::io::{self, Write};

use crate::config::Config;
use crate::context::Context;
use crate::module::Module;
use crate::modules;
Expand All @@ -23,12 +24,15 @@ const PROMPT_ORDER: &[&str] = &[

pub fn prompt(args: ArgMatches) {
let context = Context::new(args);
let config = &context.config;

let stdout = io::stdout();
let mut handle = stdout.lock();

// Write a new line before the prompt
writeln!(handle).unwrap();
if config.get_as_bool("add_newline") != Some(false) {
writeln!(handle).unwrap();
}

let modules = PROMPT_ORDER
.par_iter()
Expand Down
5 changes: 3 additions & 2 deletions tests/testsuite/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ lazy_static! {
static ref EMPTY_CONFIG: PathBuf = MANIFEST_DIR.join("empty_config.toml");
}

/// Run an instance of starship
fn run_starship() -> process::Command {
/// Render the full starship prompt
pub fn render_prompt() -> process::Command {
let mut command = process::Command::new("./target/debug/starship");

command
Expand All @@ -22,6 +22,7 @@ fn run_starship() -> process::Command {
command
}

/// Render a specific starship module by name
pub fn render_module(module_name: &str) -> process::Command {
let mut command = process::Command::new("./target/debug/starship");

Expand Down
21 changes: 21 additions & 0 deletions tests/testsuite/configuration.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,3 +32,24 @@ fn disabled_module() -> io::Result<()> {

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(())
}

0 comments on commit 0bc28c5

Please sign in to comment.