make align tab-aware

This commit is contained in:
Maxime Coste 2013-11-06 19:11:46 +00:00
parent f2a902f682
commit 79883f6a51
3 changed files with 38 additions and 7 deletions

View File

@ -397,6 +397,7 @@ Some options are built in kakoune, and can be used to control it's behaviour:
* +complete_prefix+ _bool_: when completing in command line, and multiple * +complete_prefix+ _bool_: when completing in command line, and multiple
candidates exist, enable completion with common prefix. candidates exist, enable completion with common prefix.
* +incsearch+ _bool_: execute search as it is typed * +incsearch+ _bool_: execute search as it is typed
* +aligntab+ _bool_: use tabs for alignement command
* +autoinfo+ _bool_: display automatic information box for certain commands. * +autoinfo+ _bool_: display automatic information box for certain commands.
* +autoshowcompl+ _bool_: automatically display possible completions when * +autoshowcompl+ _bool_: automatically display possible completions when
editing a prompt. editing a prompt.

View File

@ -806,13 +806,29 @@ void save_selections(Context& context, int)
" selections", get_color("Information") }); " selections", get_color("Information") });
} }
static CharCount get_column(const Buffer& buffer,
CharCount tabstop, BufferCoord coord)
{
auto& line = buffer[coord.line];
auto col = 0_char;
for (auto it = line.begin();
it != line.end() and ByteCount{it - line.begin()} < coord.column;
it = utf8::next(it))
{
if (*it == '\t')
col = (col / tabstop + 1) * tabstop;
else
++col;
}
return col;
}
template<bool insert_at_begin> template<bool insert_at_begin>
void align(Context& context, int) void align(Context& context, int)
{ {
auto& selections = context.editor().selections(); auto& selections = context.editor().selections();
auto& buffer = context.buffer(); auto& buffer = context.buffer();
auto get_column = [&buffer](BufferCoord coord) const CharCount tabstop = context.options()["tabstop"].get<int>();
{ return buffer[coord.line].char_count_to(coord.column); };
std::vector<std::vector<const Selection*>> columns; std::vector<std::vector<const Selection*>> columns;
LineCount last_line = -1; LineCount last_line = -1;
@ -830,16 +846,29 @@ void align(Context& context, int)
last_line = line; last_line = line;
} }
const bool use_tabs = context.options()["aligntab"].get<bool>();
for (auto& col : columns) for (auto& col : columns)
{ {
CharCount max_col = 0; CharCount maxcol = 0;
for (auto& sel : col) for (auto& sel : col)
max_col = std::max(get_column(sel->last()), max_col); maxcol = std::max(get_column(buffer, tabstop, sel->last()), maxcol);
for (auto& sel : col) for (auto& sel : col)
{ {
CharCount padding = max_col - get_column(sel->last()); auto insert_coord = insert_at_begin ? sel->min() : sel->last();
auto it = buffer.iterator_at(insert_at_begin ? sel->min() : sel->last()); auto lastcol = get_column(buffer, tabstop, sel->last());
buffer.insert(it, String{ ' ', padding }); String padstr;
if (not use_tabs)
padstr = String{ ' ', maxcol - lastcol };
else
{
auto inscol = get_column(buffer, tabstop, insert_coord);
auto targetcol = maxcol - (lastcol - inscol);
auto tabcol = inscol - (inscol % tabstop);
auto tabs = (targetcol - tabcol) / tabstop;
auto spaces = targetcol - (tabs ? (tabcol + tabs * tabstop) : inscol);
padstr = String{ '\t', tabs } + String{ ' ', spaces };
}
buffer.insert(buffer.iterator_at(insert_coord), std::move(padstr));
} }
} }
} }

View File

@ -117,6 +117,7 @@ GlobalOptions::GlobalOptions()
declare_option<bool>("incsearch", true); declare_option<bool>("incsearch", true);
declare_option<bool>("autoinfo", true); declare_option<bool>("autoinfo", true);
declare_option<bool>("autoshowcompl", true); declare_option<bool>("autoshowcompl", true);
declare_option<bool>("aligntab", false);
declare_option<Regex>("ignored_files", Regex{R"(^(\..*|.*\.(o|so|a))$)"}); declare_option<Regex>("ignored_files", Regex{R"(^(\..*|.*\.(o|so|a))$)"});
declare_option<String>("filetype", ""); declare_option<String>("filetype", "");
declare_option<std::vector<String>>("completions", {}); declare_option<std::vector<String>>("completions", {});