Skip to content

Commit

Permalink
Add behaviour to fix indentation when closing braces
Browse files Browse the repository at this point in the history
  • Loading branch information
mls-m5 committed Nov 15, 2023
1 parent f2a7c42 commit 0bd050e
Show file tree
Hide file tree
Showing 10 changed files with 79 additions and 12 deletions.
1 change: 1 addition & 0 deletions src/modes/insertmode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ std::shared_ptr<IMode> createInsertMode() {
{KeyEvent{Key::KeyCombination, '\b', Modifiers::Ctrl},
{sc.erase_before_word}},
{{"\n"}, {sc.combine(sc.split, sc.copy_indentation)}},
{{"}"}, sc.close_brace},
}};
map.defaultAction({sc.insert});

Expand Down
30 changes: 30 additions & 0 deletions src/script/standardcommands.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,10 @@
#include "script/indent.h"
#include "script/renamefileinteraction.h"
#include "text/cursorops.h"
#include "text/cursorrange.h"
#include "text/cursorrangeops.h"
#include "text/fstring.h"
#include "text/utf8charops.h"
#include "togglecomments.h"
#include "views/editor.h"
#include "views/mainwindow.h"
Expand Down Expand Up @@ -365,6 +367,34 @@ StandardCommands create() {
auto &e = env->editor();
e.cursor(copyIndentation(e.cursor()));
};
DEF(close_brace) {
auto &e = env->editor();
auto cursor = e.cursor();
if (cursor.x() == 0 || cursor.y() == 0) {
e.cursor(insert('}', cursor));
return;
}

if (!isSpace(content(left(cursor)))) {
e.cursor(insert('}', cursor));
return;
}
auto left = matchingLeft(cursor, '{', '}', true);
if (!left) {
e.cursor(insert('}', cursor));
return;
}
auto indentationLeft = ::indentation(*left);
auto currentIndentation = ::indentation(cursor);
auto lineStart = ::home(cursor);
auto indentationStop = lineStart;
for (auto c : currentIndentation) {
indentationStop = right(indentationStop);
}
erase(CursorRange{lineStart, indentationStop});
cursor = insert(lineStart, indentationLeft);
e.cursor(insert('}', cursor));
};
DEF(undo) {
env->editor().undo();
};
Expand Down
1 change: 1 addition & 0 deletions src/script/standardcommands.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
STD_DEF(copy) \
STD_DEF(cut) \
STD_DEF(copy_indentation) \
STD_DEF(close_brace) \
STD_DEF(undo) \
STD_DEF(undo_major) \
STD_DEF(redo) \
Expand Down
1 change: 1 addition & 0 deletions src/text/cursor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ Cursor &Cursor::operator++() {
return *this = right(*this);
}


FChar Cursor::operator*() {
return content(*this);
}
1 change: 1 addition & 0 deletions src/text/cursor.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ class Cursor : public Position {

Cursor &operator++();


//! Returns a pointer because somtimes there is no character (like when
//! there is a line-break
FChar operator*();
Expand Down
32 changes: 22 additions & 10 deletions src/text/cursorops.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "cursorops.h"
#include "buffer.h"
#include "cursorrangeops.h"
#include "text/fstring.h"
#include "text/utf8char.h"
#include "views/bufferview.h"
#include <optional>
Expand Down Expand Up @@ -175,6 +176,22 @@ Cursor split(Cursor cursor) {
}
}

FString indentation(Cursor cursor) {
auto &line = lineAt(cursor);

FString indentationStr;
for (auto c : line) {
if (c.c == ' ' || c.c == '\t') {
indentationStr += std::string{c};
}
else {
break;
}
}

return indentationStr;
}

Cursor copyIndentation(Cursor cursor, std::string autoIndentString) {
cursor = fix(cursor);

Expand All @@ -186,16 +203,7 @@ Cursor copyIndentation(Cursor cursor, std::string autoIndentString) {

auto &line = cursor.buffer().lineAt(cursor.y());
auto &lineAbove = lines.at(cursor.y() - 1);

std::string indentationStr;
for (auto c : lineAbove) {
if (c.c == ' ' || c.c == '\t') {
indentationStr += std::string{c};
}
else {
break;
}
}
auto indentationStr = indentation({cursor.buffer(), 0, cursor.y() - 1});

cursor.x(indentationStr.size());

Expand Down Expand Up @@ -483,3 +491,7 @@ Cursor findMatching(Cursor cursor) {

return cursor;
}

const FString &lineAt(Cursor cursor) {
return cursor.buffer().lineAt(cursor.y());
}
5 changes: 5 additions & 0 deletions src/text/cursorops.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,9 @@ Cursor join(Cursor);

Cursor split(Cursor);

/// Get the indentation from a line
[[nodiscard]] FString indentation(Cursor cursor);

//! Used for auto indentation
Cursor copyIndentation(Cursor, std::string autoIndentString = " ");

Expand Down Expand Up @@ -78,3 +81,5 @@ Cursor apply(BufferEdit edit);

/// Implementations for things like vims % command
Cursor findMatching(Cursor);

[[nodiscard]] const FString &lineAt(Cursor);
1 change: 1 addition & 0 deletions src/text/rawbuffer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
#include "cursorrange.h"
#include "cursorrangeops.h"
#include "text/cursor.h"
#include "text/fstringview.h"
#include <sstream>

const std::vector<FString> &RawBuffer::lines() const {
Expand Down
11 changes: 11 additions & 0 deletions test/res/vim_i.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# insert mode

## close {}

```
hello {
[I-}]
-----------
hello {
}[I]
```
8 changes: 6 additions & 2 deletions test/vim_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ struct VimCodePart : public std::string {
auto c = at(i);
if (c == '\n') {
++line;
col = 0;
}
else {
++col;
Expand Down Expand Up @@ -272,8 +273,11 @@ struct TestSuitVim : public unittest::StaticTestSuit {
EXPECT_EQ(translateVimMode(part.mode.front()),
editor.mode().name());
}
EXPECT_EQ(registers.load(standardRegister).value,
diff.first);
if (part.mode != "I") {
EXPECT_EQ(
registers.load(standardRegister).value,
diff.first);
}

if (part.anchor) {
EXPECT_TRUE(editor.selectionAnchor());
Expand Down

0 comments on commit 0bd050e

Please sign in to comment.