blob: 320fe4864302758baaa6d30fb0517e61af433bac (
plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
|
// file : butl/pager -*- C++ -*-
// copyright : Copyright (c) 2014-2017 Code Synthesis Ltd
// license : MIT; see accompanying LICENSE file
#ifndef BUTL_PAGER
#define BUTL_PAGER
#include <string>
#include <vector>
#include <iostream>
#include <butl/export>
#include <butl/process>
#include <butl/fdstream>
namespace butl
{
// Try to run the output through a pager program, such as more or less (no
// pun intended, less is used by default). If the default pager program is
// used, then the output is indented so that 80-character long lines will
// appear centered in the terminal. If the default pager program fails to
// start, then the output is sent directly to STDOUT.
//
// If the pager program is specified and is empty, then no pager is used
// and the output is sent directly to STDOUT.
//
// Throw std::system_error if there are problems with the pager program.
//
// Typical usage:
//
// try
// {
// pager p ("help for foo");
// ostream& os (p.stream ());
//
// os << "Foo is such and so ...";
//
// if (!p.wait ())
// ... // Pager program returned non-zero status.
// }
// catch (const std::system_error& e)
// {
// cerr << "pager error: " << e << endl;
// }
//
class LIBBUTL_EXPORT pager: protected std::streambuf
{
public:
~pager () {wait (true);}
// If verbose is true, then print (to STDERR) the pager command line.
//
pager (const std::string& name,
bool verbose = false,
const std::string* pager = nullptr,
const std::vector<std::string>* pager_options = nullptr);
std::ostream&
stream () {return os_.is_open () ? os_ : std::cout;}
bool
wait (bool ignore_errors = false);
// The streambuf output interface that implements indentation. You can
// override it to implement custom output pre-processing.
//
protected:
using int_type = std::streambuf::int_type;
using traits_type = std::streambuf::traits_type;
virtual int_type
overflow (int_type);
virtual int
sync ();
private:
process p_;
ofdstream os_;
std::string indent_;
int_type prev_ = '\n'; // Previous character.
std::streambuf* buf_ = nullptr;
};
}
#endif // BUTL_PAGER
|