From 52a61854559dedba844d1669849eed29d67b43b1 Mon Sep 17 00:00:00 2001 From: Zachary Yedidia Date: Mon, 14 Mar 2016 21:34:44 -0400 Subject: [PATCH] Handle tabs correctly --- Makefile | 1 + src/buffer.d | 3 ++- src/cursor.d | 2 ++ src/main.d | 2 +- src/util.d | 7 +++++++ src/view.d | 28 ++++++++++++++++++++++++---- 6 files changed, 37 insertions(+), 6 deletions(-) create mode 100644 Makefile create mode 100644 src/util.d diff --git a/Makefile b/Makefile new file mode 100644 index 00000000..9cd1487b --- /dev/null +++ b/Makefile @@ -0,0 +1 @@ + test diff --git a/src/buffer.d b/src/buffer.d index b1acae52..e191992b 100644 --- a/src/buffer.d +++ b/src/buffer.d @@ -1,6 +1,7 @@ import rope; -import std.string, std.stdio; +import std.string: split; +import std.stdio; class Buffer { private Rope text; diff --git a/src/cursor.d b/src/cursor.d index 7ee7172e..fe2148c9 100644 --- a/src/cursor.d +++ b/src/cursor.d @@ -4,6 +4,8 @@ class Cursor { int x, y; int lastX; + int offset; + this() {} this(int x, int y) { diff --git a/src/main.d b/src/main.d index 95c7a201..5aa68c1a 100644 --- a/src/main.d +++ b/src/main.d @@ -5,7 +5,7 @@ import view; import clipboard; import std.stdio; -import std.file; +import std.file: readText, exists, isDir; void main(string[] args) { string filename = ""; diff --git a/src/util.d b/src/util.d new file mode 100644 index 00000000..0f82fbbc --- /dev/null +++ b/src/util.d @@ -0,0 +1,7 @@ +string emptyString(int size) { + string str; + foreach (i; 0 .. size) { + str ~= " "; + } + return str; +} diff --git a/src/view.d b/src/view.d index 072e89ff..f4493717 100644 --- a/src/view.d +++ b/src/view.d @@ -3,10 +3,14 @@ import buffer; import clipboard; import cursor; import statusline; +import util; +import std.regex: regex, replaceAll; import std.conv: to; import std.utf: count; +enum tabSize = 4; + class View { uint topline; uint xOffset; @@ -84,14 +88,24 @@ class View { void cursorRight() { if (cursor.x < buf.lines[cursor.y].length) { - cursor.x++; + if (buf.lines[cursor.y][cursor.x] == '\t') { + cursor.x++; + cursor.offset += tabSize-1; + } else { + cursor.x++; + } cursor.lastX = cursor.x; } } void cursorLeft() { if (cursor.x > 0) { - cursor.x--; + if (buf.lines[cursor.y][cursor.x-1] == '\t') { + cursor.x--; + cursor.offset -= tabSize-1; + } else { + cursor.x--; + } cursor.lastX = cursor.x; } } @@ -146,8 +160,14 @@ class View { cursorDown(); cursor.x = 0; cursor.lastX = cursor.x; + } else if (e.key == Key.tab) { + buf.insert(cloc, "\t"); + cursorRight(); } else if (e.key == Key.backspace2) { if (cloc > 0) { + if (buf.lines[cursor.y][cursor.x-1] == '\t') { + cursor.offset -= tabSize-1; + } buf.remove(cloc-1, cloc); setCursorLoc(cloc - 1); cursor.lastX = cursor.x; @@ -190,7 +210,7 @@ class View { setCell(cast(int) x++, cast(int) y, ' ', Color.basic, Color.basic); // Write the line - foreach (dchar ch; line) { + foreach (dchar ch; line.replaceAll(regex("\t"), emptyString(tabSize))) { setCell(x++, y, ch, Color.basic, Color.basic); } y++; @@ -200,7 +220,7 @@ class View { if (cursor.y - topline < 0 || cursor.y - topline > height-1) { hideCursor(); } else { - setCursor(cursor.x + xOffset, cursor.y - topline); + setCursor(cursor.x + xOffset + cursor.offset, cursor.y - topline); } sl.display();