Fix indent code, support indentwidth=0 for using tabs

This commit is contained in:
Maxime Coste 2013-10-14 13:47:43 +01:00
parent 9f8a75a80d
commit 608196f526
2 changed files with 26 additions and 22 deletions

View File

@ -377,7 +377,8 @@ New options can be declared using the +decl+ command:
Some options are built in kakoune, and can be used to control it's behaviour: Some options are built in kakoune, and can be used to control it's behaviour:
* +tabstop+ _int_: width of a tab character. * +tabstop+ _int_: width of a tab character.
* +indentwidth+ _int_: width used for indentation. * +indentwidth+ _int_: width (in spaces) used for indentation.
0 means a tab character.
* +scrolloff+ _int_: number of lines to keep visible above/below * +scrolloff+ _int_: number of lines to keep visible above/below
the cursor when scrolling. the cursor when scrolling.
* +eolformat+ _string_ ('lf' or 'crlf'): the format of end of lines when * +eolformat+ _string_ ('lf' or 'crlf'): the format of end of lines when

View File

@ -559,48 +559,51 @@ void keep(Context& context, int)
void indent(Context& context, int) void indent(Context& context, int)
{ {
size_t width = context.options()["indentwidth"].get<int>(); CharCount indent_width = context.options()["indentwidth"].get<int>();
String indent(' ', width); String indent = indent_width == 0 ? "\t" : String{' ', indent_width};
Editor& editor = context.editor(); Editor& editor = context.editor();
DynamicSelectionList sels{editor.buffer(), editor.selections()}; DynamicSelectionList sels{editor.buffer(), editor.selections()};
auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); }); auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); });
editor.select(select_whole_lines); editor.multi_select([&indent](const Buffer& buf, const Selection& sel) {
editor.multi_select(std::bind(select_all_matches, _1, _2, Regex{"^[^\n]"})); SelectionList res;
for (auto line = sel.min().line; line < sel.max().line+1; ++line)
{
if (buf[line].length() > 1)
res.emplace_back(line, line);
}
return res;
});
editor.insert(indent, InsertMode::Insert); editor.insert(indent, InsertMode::Insert);
} }
void deindent(Context& context, int) void deindent(Context& context, int)
{ {
const auto& indent = context.options()["indent"].get<String>(); CharCount tabstop = context.options()["tabstop"].get<int>();
size_t width = 0; CharCount indent_width = context.options()["indentwidth"].get<int>();
size_t tabstop = context.options()["tabstop"].get<int>(); if (indent_width == 0)
for (auto& c : indent) indent_width = tabstop;
{
if (c == '\t')
width = (width / tabstop + 1) * tabstop;
else
++width;
}
Editor& editor = context.editor(); Editor& editor = context.editor();
DynamicSelectionList sels{editor.buffer(), editor.selections()}; DynamicSelectionList sels{editor.buffer(), editor.selections()};
auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); }); auto restore_sels = on_scope_end([&]{ editor.select((SelectionList)std::move(sels)); });
editor.multi_select([width,tabstop](const Buffer& buf, const Selection& sel) {
editor.multi_select([indent_width,tabstop](const Buffer& buf, const Selection& sel) {
SelectionList res; SelectionList res;
for (auto line = sel.min().line; line < sel.max().line+1; ++line) for (auto line = sel.min().line; line < sel.max().line+1; ++line)
{ {
size_t cur_width = 0; CharCount width = 0;
auto& content = buf[line]; auto& content = buf[line];
for (auto column = 0_byte; column < content.length(); ++column) for (auto column = 0_byte; column < content.length(); ++column)
{ {
if (content[column] == ' ') const char c = content[column];
++cur_width; if (c == '\t')
else if (content[column] == '\t') width = (width / tabstop + 1) * tabstop;
cur_width = (cur_width / tabstop + 1) * tabstop; else if (c == ' ')
++width;
else else
break; break;
if (cur_width == width) if (width == indent_width)
{ {
res.emplace_back(line, BufferCoord{line, column}); res.emplace_back(line, BufferCoord{line, column});
break; break;