Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
Prev Previous commit
alternative_buffer scope object
  • Loading branch information
ianthomas23 committed Oct 10, 2025
commit b77eb871d13f0edaf86187d827151310839a2ce6
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ set(GIT2CPP_SRC
${GIT2CPP_SOURCE_DIR}/utils/common.hpp
${GIT2CPP_SOURCE_DIR}/utils/git_exception.cpp
${GIT2CPP_SOURCE_DIR}/utils/git_exception.hpp
${GIT2CPP_SOURCE_DIR}/utils/output.cpp
${GIT2CPP_SOURCE_DIR}/utils/output.hpp
${GIT2CPP_SOURCE_DIR}/utils/terminal_pager.cpp
${GIT2CPP_SOURCE_DIR}/utils/terminal_pager.hpp
Expand Down
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);
}
16 changes: 16 additions & 0 deletions src/utils/output.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,9 @@
#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.
Expand All @@ -19,3 +22,16 @@ struct cursor_hider : noncopyable_nonmovable
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;
};
16 changes: 2 additions & 14 deletions src/utils/terminal_pager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

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

#include <termcolor/termcolor.hpp>

#include "ansi_code.hpp"
#include "output.hpp"
#include "terminal_pager.hpp"

terminal_pager::terminal_pager()
Expand Down Expand Up @@ -181,14 +181,7 @@ void terminal_pager::show()
return;
}

struct termios old_termios;
tcgetattr(fileno(stdin), &old_termios);
auto new_termios = old_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 alt_buffer;

m_start_row_index = 0;
render_terminal();
Expand All @@ -199,11 +192,6 @@ void terminal_pager::show()
stop = process_input(get_input());
} while (!stop);

std::cout << ansi_code::disable_alternative_buffer;

// Restore original termios settings.
tcsetattr(fileno(stdin), TCSANOW, &old_termios);

m_lines.clear();
m_start_row_index = 0;
}
Expand Down