Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,14 @@ In case you have [Rust](https://www.rust-lang.org/) installed, you can install w
cargo install git-graph
```

**From `homebrew`**

If you use the [homebrew](https://brew.sh/) package manager:

```
brew install git-graph
```

## Usage

**For detailed information, see the [manual](docs/manual.md)**.
Expand Down
114 changes: 2 additions & 112 deletions src/main.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
//! Command line tool to show clear git graphs arranged for your branching model.

use clap::{crate_version, Arg, Command};
use crossterm::cursor::MoveToRow;
use crossterm::event::{Event, KeyCode, KeyModifiers};
use crossterm::style::Print;
use crossterm::terminal::{disable_raw_mode, enable_raw_mode, Clear, ClearType};
use crossterm::ExecutableCommand;
use git2::Repository;
use git_graph::config::{
create_config, get_available_models, get_model, get_model_name, set_model,
Expand All @@ -17,7 +12,6 @@ use git_graph::print::svg::print_svg;
use git_graph::print::unicode::print_unicode;
use git_graph::settings::{BranchOrder, BranchSettings, Characters, MergePatterns, Settings};
use platform_dirs::AppDirs;
use std::io::{stdout, Error};
use std::str::FromStr;
use std::time::Instant;

Expand Down Expand Up @@ -139,13 +133,6 @@ fn from_args() -> Result<(), String> {
.required(false)
.num_args(0),
)
.arg(
Arg::new("no-pager")
.long("no-pager")
.help("Use no pager (print everything at once without prompt).")
.required(false)
.num_args(0),
)
.arg(
Arg::new("style")
.long("style")
Expand Down Expand Up @@ -301,7 +288,6 @@ fn from_args() -> Result<(), String> {
let reverse_commit_order = matches.get_flag("reverse");

let svg = matches.get_flag("svg");
let pager = !matches.get_flag("no-pager");
let compact = !matches.get_flag("sparse");
let debug = matches.get_flag("debug");
let style = matches
Expand Down Expand Up @@ -418,15 +404,14 @@ fn from_args() -> Result<(), String> {
merge_patterns: MergePatterns::default(),
};

run(repository, &settings, svg, commit_limit, pager)
run(repository, &settings, svg, commit_limit)
}

fn run(
repository: Repository,
settings: &Settings,
svg: bool,
max_commits: Option<usize>,
pager: bool,
) -> Result<(), String> {
let now = Instant::now();
let graph = GitGraph::new(repository, settings, None, max_commits)?;
Expand All @@ -453,18 +438,7 @@ fn run(
println!("{}", print_svg(&graph, settings)?);
} else {
let (g_lines, t_lines, _indices) = print_unicode(&graph, settings)?;
let use_pager =
// Pager is enabled
pager
// and in a terminal, not a pipe
&& atty::is(atty::Stream::Stdout)
// and terminal height is not enough for all lines + the help text
&& (crossterm::terminal::size().unwrap().1 as usize) < g_lines.len() + 1;
if use_pager {
print_paged(&g_lines, &t_lines).map_err(|err| err.to_string())?;
} else {
print_unpaged(&g_lines, &t_lines);
}
print_unpaged(&g_lines, &t_lines);
};

let duration_print = now.elapsed().as_micros();
Expand All @@ -480,90 +454,6 @@ fn run(
Ok(())
}

/// Print the graph, paged (i.e. wait for user input once the terminal is filled).
fn print_paged(graph_lines: &[String], text_lines: &[String]) -> Result<(), Error> {
let (width, height) = crossterm::terminal::size()?;
let mut start_idx: usize = 0;
let mut should_update: bool = true;
let visible_lines: usize = height as usize - 1;
let help = "\r >>> Down/Up: line, PgDown/Enter: page, End: all, Esc/Q/^C: quit\r";
let help = if help.len() > width as usize {
&help[0..width as usize]
} else {
help
};

enable_raw_mode()?;
loop {
// Print commits
if should_update {
should_update = false;
// Make sure that start_idx + visible_lines <= graph_lines.len()
start_idx = start_idx.min(graph_lines.len().saturating_sub(visible_lines));
stdout()
.execute(MoveToRow(0))?
.execute(Clear(ClearType::CurrentLine))?;
let content_len = visible_lines.min(graph_lines.len());
for curr_idx in 0..content_len {
stdout()
.execute(Clear(ClearType::CurrentLine))?
.execute(Print(format!(
" {} {}\r\n",
graph_lines[start_idx + curr_idx],
text_lines[start_idx + curr_idx]
)))?;
}
if content_len < visible_lines {
// Exit if screen is larger than full list
break;
}
// Print help at the end
stdout().execute(Print(help))?;
} else {
let input = crossterm::event::read()?;
if let Event::Key(evt) = input {
match evt.code {
KeyCode::Down => {
start_idx += 1;
should_update = true;
}
KeyCode::Up => {
if start_idx > 0 {
start_idx -= 1;
should_update = true;
}
}
KeyCode::Enter | KeyCode::PageDown => {
start_idx += height as usize - 2;
should_update = true;
}
KeyCode::End => {
start_idx = graph_lines.len() - height as usize - 2;
should_update = true;
// TODO: maybe make this better
}
KeyCode::Char(c) => match c {
'q' => {
break;
}
'c' if evt.modifiers == KeyModifiers::CONTROL => {
break;
}
_ => {}
},
KeyCode::Esc => {
break;
}
_ => {}
}
}
}
}

disable_raw_mode()?;
Ok(())
}

/// Print the graph, un-paged.
fn print_unpaged(graph_lines: &[String], text_lines: &[String]) {
for (g_line, t_line) in graph_lines.iter().zip(text_lines.iter()) {
Expand Down
Loading