Implement terminal_pager for log subcommand by ianthomas23 · Pull Request #46 · QuantStack/git2cpp · GitHub
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
5 changes: 5 additions & 0 deletions CMakeLists.txt
5 changes: 5 additions & 0 deletions src/subcommand/log_subcommand.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
#include <termcolor/termcolor.hpp>

#include "log_subcommand.hpp"
#include "../utils/terminal_pager.hpp"
#include "../wrapper/repository_wrapper.hpp"
#include "../wrapper/commit_wrapper.hpp"

Expand Down Expand Up @@ -90,6 +91,8 @@ void log_subcommand::run()
git_revwalk_new(&walker, repo);
git_revwalk_push_head(walker);

terminal_pager pager;

std::size_t i=0;
git_oid commit_oid;
while (!git_revwalk_next(&commit_oid, walker) && i<m_max_count_flag)
Expand All @@ -100,4 +103,6 @@ void log_subcommand::run()
}

git_revwalk_free(walker);

pager.show();
}
24 changes: 24 additions & 0 deletions src/utils/ansi_code.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#include "ansi_code.hpp"

namespace ansi_code
{
std::string cursor_to_row(size_t row)
{
return "\e[" + std::to_string(row) + "H";
}

bool is_down_arrow(std::string str)
{
return str == "\e[B" || str == "\e[1B]";
}

bool is_escape_char(char ch)
{
return ch == '\e';
}

bool is_up_arrow(std::string str)
{
return str == "\e[A" || str == "\e[1A]";
}
}
29 changes: 29 additions & 0 deletions src/utils/ansi_code.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#pragma once

#include <string>

/**
* ANSI escape codes.
* Use `termcolor` for colours.
*/
namespace ansi_code
{
// Constants.
const std::string bel = "\a"; // ASCII 7, used for audio/visual feedback.
const std::string cursor_to_top = "\e[H";
const std::string erase_screen = "\e[2J";

const std::string enable_alternative_buffer = "\e[?1049h";
const std::string disable_alternative_buffer = "\e[?1049l";

const std::string hide_cursor = "\e[?25l";
const std::string show_cursor = "\e[?25h";

// Functions.
std::string cursor_to_row(size_t row);

bool is_escape_char(char ch);

bool is_down_arrow(std::string str);
bool is_up_arrow(std::string str);
}
23 changes: 23 additions & 0 deletions src/utils/output.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include "output.hpp"

// OS-specific libraries.
#include <sys/ioctl.h>

alternative_buffer::alternative_buffer()
{
tcgetattr(fileno(stdin), &m_previous_termios);
auto new_termios = m_previous_termios;
// Disable canonical mode (buffered I/O) and echo from stdin to stdout.
new_termios.c_lflag &= (~ICANON & ~ECHO);
tcsetattr(fileno(stdin), TCSANOW, &new_termios);

std::cout << ansi_code::enable_alternative_buffer;
}

alternative_buffer::~alternative_buffer()
{
std::cout << ansi_code::disable_alternative_buffer;

// Restore previous termios settings.
tcsetattr(fileno(stdin), TCSANOW, &m_previous_termios);
}
21 changes: 19 additions & 2 deletions src/utils/output.hpp
Original file line number Diff line number Diff line change
@@ -1,20 +1,37 @@
#pragma once

#include <iostream>
#include "ansi_code.hpp"
#include "common.hpp"

// OS-specific libraries.
#include <termios.h>

// Scope object to hide the cursor. This avoids
// cursor twinkling when rewritting the same line
// too frequently.
struct cursor_hider : noncopyable_nonmovable
{
cursor_hider()
{
std::cout << "\e[?25l";
std::cout << ansi_code::hide_cursor;
}

~cursor_hider()
{
std::cout << "\e[?25h";
std::cout << ansi_code::show_cursor;
}
};

// Scope object to use alternative output buffer for
// fullscreen interactive terminal input/output.
class alternative_buffer : noncopyable_nonmovable
{
public:
alternative_buffer();

~alternative_buffer();

private:
struct termios m_previous_termios;
};
221 changes: 221 additions & 0 deletions src/utils/terminal_pager.cpp
Loading