giga

Terminal text editor
git clone git://git.dimitrijedobrota.com/giga.git
Log | Files | Refs | README | HACKING | CONTRIBUTING | CODE_OF_CONDUCT | BUILDING

commit ac8e3cc68f65d47139eccd484340aa5d2e4096fe
parent b033d033674ecfc4df4c8e37a8cfa19231eb5250
author Dimitrije Dobrota < mail@dimitrijedobrota.com >
date Sat, 1 Mar 2025 21:08:11 +0100

Vertical scrolling, work in progress...

Diffstat:
M CMakeLists.txt | + -
M source/main.cpp | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ -----------

2 files changed, 83 insertions(+), 13 deletions(-)


diff --git a/ CMakeLists.txt b/ CMakeLists.txt

@@ -4,7 +4,7 @@ include(cmake/prelude.cmake)


project(
giga
VERSION 0.1.3
VERSION 0.1.4
DESCRIPTION "Terminal text editor"
HOMEPAGE_URL "https://git.dimitrijedobrota.com/giga.git"
LANGUAGES CXX

diff --git a/ source/main.cpp b/ source/main.cpp

@@ -5,6 +5,7 @@

#include <vector>

#include <display/display.hpp>
#include <display/utility.hpp>
#include <display/window.hpp>

class File

@@ -31,6 +32,11 @@ public:

const auto& operator[](std::size_t idx) const { return m_lines[idx]; }
auto& operator[](std::size_t idx) { return m_lines[idx]; }

auto substr(std::size_t idx, std::size_t pos, std::size_t len) const
{
return pos < m_lines[idx].size() ? m_lines[idx].substr(pos, len) : "";
}

auto size() const { return m_lines.size(); }

private:

@@ -50,27 +56,35 @@ public:

{
line_reset();

const auto linenum_width = get_linenum_width();
for (std::size_t i = 0; i < hgt().value(); i++) {
const auto line = i + m_line_start;
const auto cursor = cursor_clamp();
auto line = m_line;

if (line >= m_file.size()) {
const auto linenum_width = get_linenum_width();
const std::size_t available_width = wth().value() - linenum_width;
for (std::size_t i = 0; i < hgt().value(); i++, line.y++) {
if (line.y.value() >= m_file.size()) {
break;
}

if (i == m_cursor.y.value()) {
if (i == cursor.y.value()) {
std::cout << alec::background_v<alec::Color::BLACK>;
}

line_left(get_linenum(line, linenum_width) + " " + m_file[line]);
line_left(
get_linenum(line.y.value(), linenum_width) + " "
+ m_file.substr(line.y.value(), line.x.value(), available_width));

if (i == m_cursor.y.value()) {
if (i == cursor.y.value()) {
std::cout << alec::background_v<alec::Color::DEFAULT>;
}
}

Window::render();
Window::render_border();

std::cout << alec::cursor_show_v;
set_cursor(cursor + display::pos_t(linenum_width + 2, 1));
std::cout << std::flush;
}

void input(display::event& evnt) override

@@ -84,8 +98,8 @@ public:

if (evnt.key() == 'j') {
if (m_cursor.y.value() + 1 < hgt().value()) {
m_cursor.y++;
} else if (m_line_start + hgt().value() < m_file.size()) {
m_line_start++;
} else if (m_line.y.value() + hgt().value() < m_file.size()) {
m_line.y++;
}

evnt.type() = event::Type::NONE;

@@ -96,8 +110,46 @@ public:

if (evnt.key() == 'k') {
if (m_cursor.y.value() > 0) {
m_cursor.y--;
} else if (m_line_start > 0) {
m_line_start--;
} else if (m_line.y.value() > 0) {
m_line.y--;
}

evnt.type() = event::Type::NONE;
render();
return;
}

if (evnt.key() == 'l') {
using display::xpos_t;

m_cursor = cursor_clamp();

const auto& line = m_file[(m_line.y + m_cursor.y).value()];
const auto size = sub_lim(xpos_t(line.size()), m_line.x, xpos_t(0));

const std::size_t width = wth().value() - 4;
const auto limit = std::min(size.value(), xpos_t(width).value());
if (m_cursor.x.value() + 1 < limit) {
m_cursor.x++;
} else if (m_cursor.x.value() + 1 >= width) {
m_line.x.value() += width / 2U;
}

evnt.type() = event::Type::NONE;
render();
return;
}

if (evnt.key() == 'h') {
using display::xpos_t;

m_cursor = cursor_clamp();

const std::size_t width = wth().value() - 4;
if (m_cursor.x.value() > 0) {
m_cursor.x--;
} else if (m_line.x.value() > 0) {
m_line.x = sub_lim(m_line.x, xpos_t(width / 2), xpos_t(0));
}

evnt.type() = event::Type::NONE;

@@ -125,9 +177,27 @@ private:

return digits;
}

display::pos_t cursor_clamp() const
{
using display::clamp_high, display::xpos_t;

auto cursor = m_cursor;

const auto& line = m_file[(m_line.y + m_cursor.y).value()];
const auto size = sub_lim(xpos_t(line.size()), m_line.x, xpos_t(0));

if (size.value() > 0) {
cursor.x = clamp_high(m_cursor.x, size - 1);
} else {
cursor.x.value() = 0;
}

return cursor;
}

File m_file;

std::size_t m_line_start = 0;
display::pos_t m_line = {0, 0};
display::pos_t m_cursor = {0, 0};
};