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
14 changes: 7 additions & 7 deletions src/controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,16 +62,16 @@ void Controller::create_view(const Flags& flags) {
auto logger = spdlog::get("basic_logger");
if (logger != nullptr) { logger->info("Creating view from file: " + flags.file); }

opt_lines_t file_chars = open_file(flags.file);
ReadFile file_chars = open_file(flags.file);

if (file_chars.has_value()) {
models.emplace_back(file_chars.value(), flags.file);
if (file_chars.success) {
models.emplace_back(file_chars.lines, flags.file, file_chars.has_tabs);
view.add_model(&models.at(models.size() - 1));

if (flags.lineno) {
std::size_t line_num =
std::min(flags.lineno, models.at(models.size() - 1).buf.size());
view.cursor_down(uint32_t(std::min(line_num - 1, file_chars.value().size())));
view.cursor_down(uint32_t(std::min(line_num - 1, file_chars.lines.size())));
view.center_current_line();
}
} else {
Expand Down Expand Up @@ -756,9 +756,9 @@ bool Controller::parse_command() {
}

void Controller::add_model(const std::string& filename) {
opt_lines_t contents = open_file(filename);
if (contents.has_value()) {
models.emplace_back(contents.value(), filename);
ReadFile contents = open_file(filename);
if (contents.success) {
models.emplace_back(contents.lines, filename, contents.has_tabs);
} else {
models.emplace_back(term_size.vertical - 2, filename);
}
Expand Down
6 changes: 0 additions & 6 deletions src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,6 @@ int main(int argc, char* argv[]) {
return 0;
}

auto filename_error = check_filename(flags.file);
if (!(filename_error.empty())) {
std::println("{}", filename_error);
return 0;
}

try {
auto logger = spdlog::basic_logger_mt("basic_logger", "iris.log");
} catch (const spdlog::spdlog_ex& ex) { std::println("Log init failed: {}", ex.what()); }
Expand Down
6 changes: 3 additions & 3 deletions src/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@
#include "text_io.h"

Model::Model(const std::size_t view_height, std::string_view file_name)
: buf({""}), filename(file_name) {
: buf({""}), filename(file_name), tabbed_file(false) {
buf.reserve(view_height);
set_read_only(file_name);
}

// NOTE: Intentional copy of file_chars
Model::Model(std::vector<std::string> file_chars, std::string_view file_name)
: buf(file_chars), filename(file_name) {
Model::Model(std::vector<std::string> file_chars, std::string_view file_name, bool tabbed_file)
: buf(file_chars), filename(file_name), tabbed_file(tabbed_file) {
set_read_only(file_name);
}

Expand Down
3 changes: 2 additions & 1 deletion src/model.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ struct Model {
std::string filename;
unsigned int current_line = 0; // 0-indexed
unsigned int current_char = 0; // 0-indexed
bool tabbed_file = false;
std::string search_str = "";
std::size_t vertical_offset = 0;
std::unordered_map<char, Mark> marks = {};
Expand All @@ -58,7 +59,7 @@ struct Model {
std::stack<Change> redo_stack = {};

Model(std::size_t, std::string_view);
Model(std::vector<std::string>, std::string_view);
Model(std::vector<std::string>, std::string_view, bool);
[[nodiscard]] Redraw backspace();
[[nodiscard]] std::size_t newline();
void insert(const char);
Expand Down
39 changes: 22 additions & 17 deletions src/text_io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,21 +14,23 @@
#include "spdlog/spdlog.h"
#include "view.h"

[[nodiscard]] opt_lines_t open_file(const std::string& file) {
if (!get_file_size(file)) { return {}; }
[[nodiscard]] ReadFile open_file(const std::string& file) {
if (!get_file_size(file)) { return ReadFile(); }

auto ret = std::vector<std::string>();
std::string line = "";
char ch;

std::ifstream ifs(file);
if (ifs.fail()) { return {}; }
if (ifs.fail()) { return ReadFile(); }
bool has_tabs = false;

while (ifs.get(ch)) {
switch (ch) {
case '\r':
break;
case '\t':
has_tabs = true;
line += std::string(TAB_SIZE, ' ');
break;
case '\n':
Expand All @@ -44,7 +46,7 @@
// the vector
if (line.size()) { ret.push_back(line); }

return ret;
return ReadFile(ret, has_tabs);
}

[[nodiscard]] unsigned int get_file_size(const std::string& file) {
Expand All @@ -63,7 +65,8 @@
if (filename_input.has_value()) { model->filename = filename_input.value(); }

std::ofstream out(model->filename);
for (auto&& line : model->buf) {
lines_t lines_to_write = convert_tabs(model->buf, model->tabbed_file);
for (auto&& line : lines_to_write) {
rtrim(line);
out << line << "\n";
}
Expand Down Expand Up @@ -101,18 +104,6 @@ void rtrim(std::string& str) {
return std::find(alphabet.begin(), alphabet.end(), c) != alphabet.end();
}

[[nodiscard]] std::string check_filename(const std::string& filename) {
std::string err_text = "Iris currently does not support tab-delineated files";

if (filename == "Makefile" || filename == "makefile") {
return err_text;
} else if (filename.ends_with(".go")) {
return err_text;
}

return "";
}

// https://stackoverflow.com/a/12774387
[[nodiscard]] bool file_exists(std::string_view name) {
struct stat buffer;
Expand Down Expand Up @@ -208,3 +199,17 @@ void rtrim(std::string& str) {
if (ret == std::string::npos) { return -1; }
return int32_t(ret);
}

[[nodiscard]] lines_t convert_tabs(lines_t buf, const bool has_tabs) {
if (!has_tabs) { return buf; }
const std::string tab_chars = std::string(TAB_SIZE, ' ');

for (auto&& line : buf) {
while (line.contains(tab_chars)) {
std::size_t replace_pos = line.find(tab_chars);
line = line.replace(replace_pos, TAB_SIZE, "\t");
}
}

return buf;
}
15 changes: 12 additions & 3 deletions src/text_io.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,16 @@
#include "model.h"

using lines_t = std::vector<std::string>;
using opt_lines_t = std::optional<std::vector<std::string>>;
// using opt_lines_t = std::optional<std::vector<std::string>>;

struct ReadFile {
std::vector<std::string> lines;
bool has_tabs;
bool success;

ReadFile() : lines({}), has_tabs(false), success(false) {}
ReadFile(lines_t lines, bool has_tabs) : lines(lines), has_tabs(has_tabs), success(true) {}
};

struct WriteData {
int bytes = 0;
Expand All @@ -35,16 +44,16 @@ struct Response {
std::string err = "";
};

[[nodiscard]] opt_lines_t open_file(const std::string&);
[[nodiscard]] ReadFile open_file(const std::string&);
[[nodiscard]] unsigned int get_file_size(const std::string&);
[[nodiscard]] WriteData write_to_file(Model*, std::optional<std::string>);
void rtrim(std::string& str);
[[nodiscard]] lines_t lines(const std::string&);
[[nodiscard]] bool is_letter(const char&);
[[nodiscard]] std::string check_filename(const std::string&);
[[nodiscard]] bool file_exists(std::string_view);
[[nodiscard]] std::optional<Response> shell_exec(std::string);
[[nodiscard]] std::vector<std::string> split_by(const std::string&, const char);
[[nodiscard]] int first_non_whitespace(const std::string&);
[[nodiscard]] lines_t convert_tabs(lines_t, const bool);

#endif // TEXT_IO_H
2 changes: 2 additions & 0 deletions tests/fixture/tabbed_file.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
foo
barb
9 changes: 9 additions & 0 deletions tests/integration/ui_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -401,3 +401,12 @@ def test_readonly_cli_flag():
with TmuxRunner("bash", "--norc") as r:
r.press_and_enter("./build/src/iris -r tests/fixture/test_file_1.txt")
assert "[RO]" in r.await_statusbar_parts()


def test_tabbed_file():
with TmuxRunner("bash", "--norc") as r:
r.press_and_enter("./build/src/iris -r tests/fixture/tabbed_file.txt")
assert r.await_statusbar_parts()
lines: list[str] = r.lines()
assert "foo" in lines[0]
assert " bar" in lines[1]
Loading
Loading