1use std::io::{self, Write};
4use app::{Config, PagingMode};
5use assets::HighlightingAssets;
7use inputfile::{InputFile, InputFileReader};
8use line_range::{LineRanges, RangeCheckResult};
10use printer::{InteractivePrinter, Printer, SimplePrinter};
12pub struct Controller<'a> {
13 config: &'a Config<'a>,
14 assets: &'a HighlightingAssets,
17impl<'b> Controller<'b> {
18 pub fn new<'a>(config: &'a Config, assets: &'a HighlightingAssets) -> Controller<'a> {
19 Controller { config, assets }
22 pub fn run(&self) -> Result<bool> {
23 // Do not launch the pager if NONE of the input files exist
24 let mut paging_mode = self.config.paging_mode;
25 if self.config.paging_mode != PagingMode::Never {
26 let call_pager = self.config.files.iter().any(|file| {
27 if let InputFile::Ordinary(path) = file {
28 return Path::new(path).exists();
34 paging_mode = PagingMode::Never;
38 let mut output_type = OutputType::from_mode(paging_mode, self.config.pager)?;
39 let writer = output_type.handle()?;
40 let mut no_errors: bool = true;
42 let stdin = io::stdin();
44 for input_file in &self.config.files {
45 match input_file.get_reader(&stdin) {
46 Err(Error(ErrorKind::ImmediateEOF, _)) => (),
52 let result = if self.config.loop_through {
53 let mut printer = SimplePrinter::new();
54 self.print_file(reader, &mut printer, writer, *input_file)
56 let mut printer = InteractivePrinter::new(
62 self.print_file(reader, &mut printer, writer, *input_file)
65 if let Err(error) = result {
76 fn print_file<'a, P: Printer>(
78 reader: InputFileReader,
81 input_file: InputFile<'a>,
83 printer.print_header(writer, input_file)?;
84 self.print_file_ranges(printer, writer, reader, &self.config.line_ranges)?;
85 printer.print_footer(writer)?;
90 fn print_file_ranges<'a, P: Printer>(
94 mut reader: InputFileReader,
95 line_ranges: &LineRanges,
97 let mut line_buffer = Vec::new();
98 let mut line_number: usize = 1;
100 while reader.read_line(&mut line_buffer)? {
101 match line_ranges.check(line_number) {
102 RangeCheckResult::OutsideRange => {
103 // Call the printer in case we need to call the syntax highlighter
104 // for this line. However, set `out_of_range` to `true`.
105 printer.print_line(true, writer, line_number, &line_buffer)?;
107 RangeCheckResult::InRange => {
108 printer.print_line(false, writer, line_number, &line_buffer)?;
110 RangeCheckResult::AfterLastRange => {
keysesc to close
- j k
- move down, up
- enter
- open
- esc
- back, or up a level
- 1 2 3 4
- readme, files, commits, refs
- /
- filter
- y
- copy the clone command
- c
- compare the chosen commit with another (or shift-click both)
- ?
- show or hide this list