New and improved auto-indentation! Fixed some token iteration and boundary seeking bugs
parent
d654adacc5
commit
5bb89e2460
|
@ -1,38 +1,36 @@
|
|||
/*
|
||||
4coder_auto_indent.cpp - Commands for auto-indentation of C++ code.
|
||||
4coder_auto_indent.cpp - Commands for automatic indentation.
|
||||
*/
|
||||
|
||||
// TOP
|
||||
|
||||
internal Batch_Edit*
|
||||
make_batch_from_indent_marks(Application_Links *app, Arena *arena, Buffer_ID buffer,
|
||||
i64 first_line, i64 one_past_last_line, i64 *indent_marks,
|
||||
Indent_Options opts){
|
||||
i64 *shifted_indent_marks = indent_marks - first_line;
|
||||
make_batch_from_indentations(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, i64 *indentations, Indent_Flag flags, i32 tab_width){
|
||||
i64 *shifted_indentations = indentations - lines.first;
|
||||
|
||||
Batch_Edit *batch_first = 0;
|
||||
Batch_Edit *batch_last = 0;
|
||||
|
||||
for (i64 line_number = first_line;
|
||||
line_number < one_past_last_line;
|
||||
for (i64 line_number = lines.first;
|
||||
line_number <= lines.max;
|
||||
++line_number){
|
||||
i64 line_start_pos = get_line_start_pos(app, buffer, line_number);
|
||||
Indent_Info hard_start = get_indent_info_line_start(app, buffer, line_start_pos, opts.tab_width);
|
||||
Indent_Info indent_info = get_indent_info_line_start(app, buffer, line_start_pos, tab_width);
|
||||
|
||||
i64 correct_indentation = shifted_indent_marks[line_number];
|
||||
if (hard_start.is_blank && opts.empty_blank_lines){
|
||||
i64 correct_indentation = shifted_indentations[line_number];
|
||||
if (indent_info.is_blank && HasFlag(flags, Indent_ClearLine)){
|
||||
correct_indentation = 0;
|
||||
}
|
||||
if (correct_indentation == -1){
|
||||
correct_indentation = hard_start.indent_pos;
|
||||
correct_indentation = indent_info.indent_pos;
|
||||
}
|
||||
|
||||
if (correct_indentation != hard_start.indent_pos){
|
||||
if (correct_indentation != indent_info.indent_pos){
|
||||
umem str_size = 0;
|
||||
u8 *str = 0;
|
||||
if (opts.use_tabs){
|
||||
i64 tab_count = correct_indentation/opts.tab_width;
|
||||
i64 indent = tab_count*opts.tab_width;
|
||||
if (HasFlag(flags, Indent_UseTab)){
|
||||
i64 tab_count = correct_indentation/tab_width;
|
||||
i64 indent = tab_count*tab_width;
|
||||
i64 space_count = correct_indentation - indent;
|
||||
str_size = tab_count + space_count;
|
||||
str = push_array(arena, u8, str_size);
|
||||
|
@ -48,7 +46,7 @@ make_batch_from_indent_marks(Application_Links *app, Arena *arena, Buffer_ID buf
|
|||
Batch_Edit *batch = push_array(arena, Batch_Edit, 1);
|
||||
sll_queue_push(batch_first, batch_last, batch);
|
||||
batch->edit.text = SCu8(str, str_size);
|
||||
batch->edit.range = Ii64(line_start_pos, hard_start.first_char_pos);
|
||||
batch->edit.range = Ii64(line_start_pos, indent_info.first_char_pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -56,454 +54,265 @@ make_batch_from_indent_marks(Application_Links *app, Arena *arena, Buffer_ID buf
|
|||
}
|
||||
|
||||
internal void
|
||||
set_line_indents(Application_Links *app, Arena *arena, Buffer_ID buffer, i64 first_line, i64 one_past_last_line, i64 *indent_marks, Indent_Options opts){
|
||||
Batch_Edit *batch = make_batch_from_indent_marks(app, arena, buffer, first_line, one_past_last_line, indent_marks, opts);
|
||||
set_line_indents(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, i64 *indentations, Indent_Flag flags, i32 tab_width){
|
||||
Batch_Edit *batch = make_batch_from_indentations(app, arena, buffer, lines, indentations, flags, tab_width);
|
||||
if (batch != 0){
|
||||
buffer_batch_edit(app, buffer, batch);
|
||||
}
|
||||
}
|
||||
|
||||
internal Token*
|
||||
seek_matching_token_backwards(Token_Array tokens, Token *token,
|
||||
Token_Base_Kind open, Token_Base_Kind close){
|
||||
if (token <= tokens.tokens){
|
||||
token = tokens.tokens;
|
||||
}
|
||||
else{
|
||||
i32 nesting_level = 0;
|
||||
for (; token > tokens.tokens; --token){
|
||||
if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
if (token->kind == close){
|
||||
++nesting_level;
|
||||
}
|
||||
else if (token->kind == open){
|
||||
if (nesting_level == 0){
|
||||
break;
|
||||
}
|
||||
else{
|
||||
--nesting_level;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(token);
|
||||
}
|
||||
|
||||
internal Indent_Anchor_Position
|
||||
find_anchor_token(Application_Links *app, Buffer_ID buffer, Token_Array tokens, i64 line_start, i32 tab_width){
|
||||
Indent_Anchor_Position anchor = {};
|
||||
if (tokens.count > 0){
|
||||
Token *first_invalid_token = get_first_token_from_line(app, buffer, tokens, line_start);
|
||||
if (first_invalid_token <= tokens.tokens){
|
||||
anchor.token = tokens.tokens;
|
||||
}
|
||||
else{
|
||||
i32 stack[256];
|
||||
i32 top = -1;
|
||||
Token *token_it = tokens.tokens;
|
||||
i64 highest_checked_line_number = -1;
|
||||
for (; token_it < first_invalid_token; ++token_it){
|
||||
i64 line_number = get_line_number_from_pos(app, buffer, token_it->pos);
|
||||
if (highest_checked_line_number < line_number){
|
||||
highest_checked_line_number = line_number;
|
||||
if (top == -1){
|
||||
anchor.token = token_it;
|
||||
}
|
||||
}
|
||||
|
||||
switch (token_it->kind){
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
{
|
||||
top += 1;
|
||||
stack[top] = token_it->kind;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
for (;top >= 0;){
|
||||
i32 index = top;
|
||||
top -= 1;
|
||||
if (stack[index] == TokenBaseKind_ParentheticalOpen){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ScopeClose:
|
||||
{
|
||||
for (;top >= 0;){
|
||||
i32 index = top;
|
||||
if (stack[index] == TokenBaseKind_ParentheticalOpen){
|
||||
break;
|
||||
}
|
||||
top -= 1;
|
||||
if (stack[index] == TokenBaseKind_ScopeClose){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return(anchor);
|
||||
}
|
||||
|
||||
internal i64*
|
||||
get_indentation_marks(Application_Links *app, Arena *arena, Buffer_ID buffer,
|
||||
Token_Array tokens, i64 first_line, i64 one_past_last_line,
|
||||
b32 exact_align, i32 tab_width){
|
||||
i64 indent_mark_count = one_past_last_line - first_line;
|
||||
i64 *indent_marks = push_array(arena, i64, indent_mark_count);
|
||||
// Shift the array so line_index works correctly.
|
||||
indent_marks -= first_line;
|
||||
find_anchor_token(Application_Links *app, Buffer_ID buffer, Token_Array *tokens, i64 invalid_line){
|
||||
Token *result = tokens->tokens;
|
||||
i64 invalid_pos = get_line_start_pos(app, buffer, invalid_line);
|
||||
|
||||
// Decide where to start indentation parsing.
|
||||
Indent_Anchor_Position anchor = find_anchor_token(app, buffer, tokens, first_line, tab_width);
|
||||
Token *token_ptr = anchor.token;
|
||||
Indent_Parse_State indent = {};
|
||||
indent.current_indent = anchor.indentation;
|
||||
|
||||
if (token_ptr == 0){
|
||||
for (i64 line_index = first_line; line_index < one_past_last_line; ++line_index){
|
||||
indent_marks[line_index] = 0;
|
||||
i32 scope_counter = 0;
|
||||
i32 paren_counter = 0;
|
||||
Token *token = tokens->tokens;
|
||||
for (;;token += 1){
|
||||
if (token->pos + token->size > invalid_pos){
|
||||
break;
|
||||
}
|
||||
}
|
||||
else{
|
||||
i64 line_number = get_line_number_from_pos(app, buffer, token_ptr->pos);
|
||||
line_number = clamp_top(line_number, first_line);
|
||||
|
||||
if (token_ptr == tokens.tokens){
|
||||
indent.current_indent = 0;
|
||||
}
|
||||
|
||||
i64 next_line_start_pos = get_line_start_pos(app, buffer, line_number);
|
||||
indent.previous_line_indent = indent.current_indent;
|
||||
Token prev_token = {};
|
||||
Token token = {};
|
||||
if (token_ptr < tokens.tokens + tokens.count){
|
||||
token = *token_ptr;
|
||||
}
|
||||
|
||||
// Back up and consume this token too IF it is a scope opener.
|
||||
if (token.kind == TokenBaseKind_ScopeOpen){
|
||||
--token_ptr;
|
||||
}
|
||||
|
||||
// LOOP OVER TOKENS
|
||||
for (;;){
|
||||
if (line_number >= one_past_last_line){
|
||||
break;
|
||||
if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
if (scope_counter == 0 && paren_counter == 0){
|
||||
result = token;
|
||||
}
|
||||
|
||||
prev_token = token;
|
||||
++token_ptr;
|
||||
if (token_ptr < tokens.tokens + tokens.count){
|
||||
token = *token_ptr;
|
||||
}
|
||||
else{
|
||||
block_zero_struct(&token);
|
||||
token.kind = TokenBaseKind_EOF;
|
||||
token.pos = buffer_get_size(app, buffer);
|
||||
}
|
||||
|
||||
for (;token.pos >= next_line_start_pos && line_number < one_past_last_line;){
|
||||
next_line_start_pos = get_line_start_pos(app, buffer, line_number + 1);
|
||||
|
||||
i64 this_indent = 0;
|
||||
i64 previous_indent = indent.previous_line_indent;
|
||||
|
||||
i64 this_line_start = get_line_start_pos(app, buffer, line_number);
|
||||
i64 next_line_start = next_line_start_pos;
|
||||
|
||||
b32 did_multi_line_behavior = false;
|
||||
|
||||
// NOTE(allen): Check for multi-line tokens
|
||||
if (prev_token.pos <= this_line_start && prev_token.pos + prev_token.size > this_line_start){
|
||||
if (prev_token.kind == TokenBaseKind_Comment || prev_token.kind == TokenBaseKind_LiteralString){
|
||||
Indent_Info hard_start = get_indent_info_line_start(app, buffer, this_line_start, tab_width);
|
||||
|
||||
if (exact_align){
|
||||
this_indent = indent.previous_comment_indent;
|
||||
}
|
||||
else{
|
||||
if (hard_start.is_blank){
|
||||
this_indent = previous_indent;
|
||||
}
|
||||
else{
|
||||
i64 line_pos = hard_start.first_char_pos - this_line_start;
|
||||
this_indent = line_pos + indent.comment_shift;
|
||||
if (this_indent < 0){
|
||||
this_indent = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!hard_start.is_blank){
|
||||
if (line_number >= first_line){
|
||||
indent.previous_comment_indent = this_indent;
|
||||
}
|
||||
else{
|
||||
indent.previous_comment_indent = hard_start.indent_pos;
|
||||
}
|
||||
}
|
||||
|
||||
did_multi_line_behavior = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!did_multi_line_behavior){
|
||||
this_indent = indent.current_indent;
|
||||
if (token.pos < next_line_start){
|
||||
switch (token.kind){
|
||||
case TokenBaseKind_Preprocessor:
|
||||
{
|
||||
this_indent = 0;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ScopeClose:
|
||||
{
|
||||
this_indent -= tab_width;
|
||||
}break;
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
{}break;
|
||||
|
||||
default:
|
||||
if (indent.current_indent > 0){
|
||||
b32 statement_complete = false;
|
||||
|
||||
Token *prev_usable_token_ptr = token_ptr - 1;
|
||||
Token prev_usable_token = {};
|
||||
if (prev_usable_token_ptr >= tokens.tokens){
|
||||
prev_usable_token = *prev_usable_token_ptr;
|
||||
}
|
||||
|
||||
// Scan backwards for the previous token that actually tells us about the statement.
|
||||
b32 has_prev_usable_token = true;
|
||||
#define NotUsable(T) \
|
||||
(((T).flags&TokenBaseFlag_PreprocessorBody) || ((T).kind == TokenBaseKind_Comment) || ((T).kind == TokenBaseKind_Whitespace))
|
||||
if (NotUsable(prev_usable_token)){
|
||||
has_prev_usable_token = false;
|
||||
|
||||
for (--prev_usable_token_ptr;
|
||||
prev_usable_token_ptr >= tokens.tokens;
|
||||
--prev_usable_token_ptr){
|
||||
|
||||
prev_usable_token = *prev_usable_token_ptr;
|
||||
if (!NotUsable(prev_usable_token)){
|
||||
has_prev_usable_token = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#undef NotUsable
|
||||
|
||||
if (!has_prev_usable_token){
|
||||
statement_complete = true;
|
||||
}
|
||||
else{
|
||||
if (prev_usable_token.kind == TokenBaseKind_ScopeOpen ||
|
||||
prev_usable_token.kind == TokenBaseKind_ScopeClose ||
|
||||
prev_usable_token.sub_kind == TokenCppKind_Semicolon ||
|
||||
prev_usable_token.sub_kind == TokenCppKind_Colon ||
|
||||
prev_usable_token.sub_kind == TokenCppKind_Comma){
|
||||
statement_complete = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!statement_complete){
|
||||
this_indent += tab_width;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
if (this_indent < 0){
|
||||
this_indent = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (indent.paren_nesting > 0){
|
||||
if (prev_token.kind != TokenBaseKind_ParentheticalOpen){
|
||||
i64 level = indent.paren_nesting - 1;
|
||||
level = clamp_top(level, ArrayCount(indent.paren_anchor_indent) - 1);
|
||||
this_indent = indent.paren_anchor_indent[level];
|
||||
}
|
||||
}
|
||||
|
||||
// Rebase the paren anchor if the first token
|
||||
// after the open paren is on the next line.
|
||||
if (indent.paren_nesting > 0 &&
|
||||
prev_token.kind == TokenBaseKind_ParentheticalOpen){
|
||||
i64 level = indent.paren_nesting - 1;
|
||||
level = clamp_top(level, ArrayCount(indent.paren_anchor_indent) - 1);
|
||||
indent.paren_anchor_indent[level] = this_indent;
|
||||
}
|
||||
|
||||
if (line_number >= first_line){
|
||||
indent_marks[line_number] = this_indent;
|
||||
}
|
||||
++line_number;
|
||||
|
||||
indent.previous_line_indent = this_indent;
|
||||
}
|
||||
|
||||
// Update indent state.
|
||||
switch (token.kind){
|
||||
case TokenBaseKind_ScopeOpen: indent.current_indent += tab_width; break;
|
||||
case TokenBaseKind_ScopeClose: indent.current_indent -= tab_width; break;
|
||||
|
||||
case TokenBaseKind_Comment:
|
||||
case TokenBaseKind_LiteralString:
|
||||
switch (token->kind){
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
{
|
||||
i64 line = get_line_number_from_pos(app, buffer, token.pos);
|
||||
i64 start = get_line_start_pos(app, buffer, line);
|
||||
Indent_Info hard_start = get_indent_info_line_start(app, buffer, start, tab_width);
|
||||
|
||||
i64 old_dist_to_token = (token.pos - start);
|
||||
i64 old_indent = hard_start.indent_pos;
|
||||
i64 token_start_inset = old_dist_to_token - old_indent;
|
||||
i64 new_dist_to_token = indent.current_indent + token_start_inset;
|
||||
|
||||
indent.comment_shift = (new_dist_to_token - old_dist_to_token);
|
||||
indent.previous_comment_indent = old_indent;
|
||||
scope_counter += 1;
|
||||
}break;
|
||||
case TokenBaseKind_ScopeClose:
|
||||
{
|
||||
paren_counter = 0;
|
||||
if (scope_counter > 0){
|
||||
scope_counter -= 1;
|
||||
}
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
{
|
||||
if (!HasFlag(token.flags, TokenBaseFlag_PreprocessorBody)){
|
||||
if (indent.paren_nesting < ArrayCount(indent.paren_anchor_indent)){
|
||||
i64 line = get_line_number_from_pos(app, buffer, token.pos);
|
||||
i64 start = get_line_start_pos(app, buffer, line);
|
||||
i64 char_pos = token.pos - start;
|
||||
|
||||
Indent_Info hard_start = get_indent_info_line_start(app, buffer, start, tab_width);
|
||||
|
||||
i64 line_pos = hard_start.first_char_pos - start;
|
||||
|
||||
indent.paren_anchor_indent[indent.paren_nesting] = char_pos - line_pos + indent.previous_line_indent + 1;
|
||||
}
|
||||
++indent.paren_nesting;
|
||||
}
|
||||
paren_counter += 1;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
if (!HasFlag(token.flags, TokenBaseFlag_PreprocessorBody)){
|
||||
if (indent.paren_nesting > 0){
|
||||
--indent.paren_nesting;
|
||||
}
|
||||
if (paren_counter > 0){
|
||||
paren_counter -= 1;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Unshift the indent_marks array.
|
||||
indent_marks += first_line;
|
||||
return(indent_marks);
|
||||
}
|
||||
|
||||
// TODO(allen): replace these with new range operators.
|
||||
internal void
|
||||
get_indent_lines_minimum(Application_Links *app, Buffer_ID buffer, i64 start_pos, i64 end_pos, i64 *line_start_out, i64 *line_end_out){
|
||||
i64 line_start = get_line_number_from_pos(app, buffer, start_pos);
|
||||
i64 line_end = get_line_number_from_pos(app, buffer, end_pos) + 1;
|
||||
*line_start_out = line_start;
|
||||
*line_end_out = line_end;
|
||||
}
|
||||
|
||||
internal void
|
||||
get_indent_lines_whole_tokens(Application_Links *app, Buffer_ID buffer, Token_Array tokens, i64 start_pos, i64 end_pos, i64 *line_start_out, i64 *line_end_out){
|
||||
i64 line_start = get_line_number_from_pos(app, buffer, start_pos);
|
||||
i64 line_end = get_line_number_from_pos(app, buffer, end_pos);
|
||||
|
||||
for (;line_start > 1;){
|
||||
i64 line_start_pos = get_line_start_pos(app, buffer, line_start);
|
||||
Token *token = token_from_pos(&tokens, line_start_pos);
|
||||
if (token != 0 && token->pos < line_start_pos){
|
||||
line_start = get_line_number_from_pos(app, buffer, token->pos);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
i64 line_count = buffer_get_line_count(app, buffer);
|
||||
|
||||
for (;line_end < line_count;){
|
||||
i64 next_line_start_pos = get_line_start_pos(app, buffer, line_end + 1);
|
||||
Token *token = token_from_pos(&tokens, next_line_start_pos);
|
||||
if (token != 0 && token->pos < next_line_start_pos){
|
||||
line_end = get_line_number_from_pos(app, buffer, token->pos + token->size);
|
||||
}
|
||||
else{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
line_end = clamp_top(line_end, line_count);
|
||||
line_end += 1;
|
||||
|
||||
*line_start_out = line_start;
|
||||
*line_end_out = line_end;
|
||||
}
|
||||
|
||||
internal b32
|
||||
buffer_auto_indent(Application_Links *app, Buffer_ID buffer, i64 start, i64 end, i32 tab_width, Auto_Indent_Flag flags){
|
||||
b32 result = false;
|
||||
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer);
|
||||
|
||||
Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
if (tokens_ptr != 0 && tokens_ptr->count != 0){
|
||||
Scratch_Block scratch(app);
|
||||
Token_Array tokens = *tokens_ptr;
|
||||
|
||||
i64 line_start = 0;
|
||||
i64 line_end = 0;
|
||||
if (HasFlag(flags, AutoIndent_FullTokens)){
|
||||
get_indent_lines_whole_tokens(app, buffer, tokens, start, end, &line_start, &line_end);
|
||||
}
|
||||
else{
|
||||
get_indent_lines_minimum(app, buffer, start, end, &line_start, &line_end);
|
||||
}
|
||||
|
||||
i64 *indent_marks = get_indentation_marks(app, scratch, buffer, tokens, line_start, line_end, (flags & AutoIndent_ExactAlignBlock), tab_width);
|
||||
|
||||
Indent_Options opts = {};
|
||||
opts.empty_blank_lines = (flags & AutoIndent_ClearLine);
|
||||
opts.use_tabs = (flags & AutoIndent_UseTab);
|
||||
opts.tab_width = tab_width;
|
||||
|
||||
set_line_indents(app, scratch, buffer, line_start, line_end, indent_marks, opts);
|
||||
|
||||
result = true;
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
//
|
||||
// Commands
|
||||
//
|
||||
internal Nest*
|
||||
indent__new_nest(Arena *arena, Nest_Alloc *alloc){
|
||||
Nest *new_nest = alloc->free_nest;
|
||||
if (new_nest == 0){
|
||||
new_nest = push_array(arena, Nest, 1);
|
||||
}
|
||||
else{
|
||||
sll_stack_pop(alloc->free_nest);
|
||||
}
|
||||
return(new_nest);
|
||||
}
|
||||
|
||||
#if !defined(DEFAULT_INDENT_FLAGS)
|
||||
# define DEFAULT_INDENT_FLAGS ((global_config.indent_with_tabs)?(AutoIndent_UseTab):(0))
|
||||
#endif
|
||||
internal void
|
||||
indent__free_nest(Nest_Alloc *alloc, Nest *nest){
|
||||
sll_stack_push(alloc->free_nest, nest);
|
||||
}
|
||||
|
||||
#if !defined(DEF_TAB_WIDTH)
|
||||
# define DEF_TAB_WIDTH global_config.indent_width
|
||||
#endif
|
||||
internal i64*
|
||||
get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, Indent_Flag flags, i32 tab_width, i32 indent_width){
|
||||
i64 count = lines.max - lines.min + 1;
|
||||
i64 *indentations = push_array(arena, i64, count);
|
||||
i64 *shifted_indentations = indentations - lines.first;
|
||||
block_fill_u64(indentations, sizeof(*indentations)*count, (u64)(-1));
|
||||
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer);
|
||||
Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
i64 anchor_line = clamp_bot(1, lines.first - 1);
|
||||
Token *anchor_token = find_anchor_token(app, buffer, tokens, anchor_line);
|
||||
if (anchor_token != 0 &&
|
||||
anchor_token >= tokens->tokens &&
|
||||
anchor_token < tokens->tokens + tokens->count){
|
||||
i64 line = get_line_number_from_pos(app, buffer, anchor_token->pos);
|
||||
line = clamp_top(line, lines.first);
|
||||
|
||||
Token_Iterator_Array token_it = token_iterator(0, tokens, anchor_token);
|
||||
|
||||
Scratch_Block scratch(app);
|
||||
Nest *nest = 0;
|
||||
Nest_Alloc nest_alloc = {};
|
||||
|
||||
i64 line_last_indented = line - 1;
|
||||
i64 last_indent = 0;
|
||||
|
||||
for (;;){
|
||||
Token *token = token_it_read(&token_it);
|
||||
i64 line_where_token_starts = get_line_number_from_pos(app, buffer, token->pos);
|
||||
i64 line_start_pos = get_line_start_pos(app, buffer, line_where_token_starts);
|
||||
Indent_Info line_indent_info = get_indent_info_line_start(app, buffer, line_start_pos, tab_width);
|
||||
|
||||
i64 current_indent = 0;
|
||||
if (nest != 0){
|
||||
current_indent = nest->indent;
|
||||
}
|
||||
i64 this_indent = current_indent;
|
||||
|
||||
if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
this_indent = 0;
|
||||
}
|
||||
else{
|
||||
switch (token->kind){
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
{
|
||||
Nest *new_nest = indent__new_nest(arena, &nest_alloc);
|
||||
sll_stack_push(nest, new_nest);
|
||||
nest->kind = TokenBaseKind_ScopeOpen;
|
||||
nest->indent = current_indent + indent_width;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ScopeClose:
|
||||
{
|
||||
for (;nest != 0 && nest->kind != TokenBaseKind_ScopeOpen;){
|
||||
Nest *n = nest;
|
||||
sll_stack_pop(nest);
|
||||
indent__free_nest(&nest_alloc, n);
|
||||
}
|
||||
if (nest != 0 && nest->kind == TokenBaseKind_ScopeOpen){
|
||||
Nest *n = nest;
|
||||
sll_stack_pop(nest);
|
||||
indent__free_nest(&nest_alloc, n);
|
||||
}
|
||||
this_indent = 0;
|
||||
if (nest != 0){
|
||||
this_indent = nest->indent;
|
||||
}
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
{
|
||||
Nest *new_nest = indent__new_nest(arena, &nest_alloc);
|
||||
sll_stack_push(nest, new_nest);
|
||||
nest->kind = TokenBaseKind_ParentheticalOpen;
|
||||
nest->indent = line_indent_info.indent_pos + (token->pos - line_indent_info.first_char_pos) + 1;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
if (nest != 0 && nest->kind == TokenBaseKind_ParentheticalOpen){
|
||||
Nest *n = nest;
|
||||
sll_stack_pop(nest);
|
||||
indent__free_nest(&nest_alloc, n);
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
||||
#define EMIT(N) \
|
||||
Stmnt(if (lines.first <= line_it){shifted_indentations[line_it]=N;} \
|
||||
if (line_it == lines.end){goto finished;} )
|
||||
|
||||
i64 line_it = line_last_indented;
|
||||
for (;line_it < line_where_token_starts;){
|
||||
line_it += 1;
|
||||
if (line_it == line_where_token_starts){
|
||||
EMIT(this_indent);
|
||||
last_indent = this_indent;
|
||||
}
|
||||
else{
|
||||
EMIT(last_indent);
|
||||
}
|
||||
}
|
||||
|
||||
i64 line_where_token_starts_shift = this_indent - line_indent_info.indent_pos;
|
||||
i64 line_where_token_ends = get_line_number_from_pos(app, buffer, token->pos + token->size);
|
||||
for (;line_it < line_where_token_ends;){
|
||||
line_it += 1;
|
||||
i64 line_it_start_pos = get_line_start_pos(app, buffer, line_it);
|
||||
Indent_Info line_it_indent_info = get_indent_info_line_start(app, buffer, line_it_start_pos, tab_width);
|
||||
i64 new_indent = line_it_indent_info.indent_pos + line_where_token_starts_shift;
|
||||
new_indent = clamp_bot(0, new_indent);
|
||||
EMIT(new_indent);
|
||||
}
|
||||
#undef EMIT
|
||||
|
||||
line_last_indented = line_it;
|
||||
|
||||
if (!token_it_inc_non_whitespace(&token_it)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finished:;
|
||||
return(indentations);
|
||||
}
|
||||
|
||||
internal b32
|
||||
auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos, Indent_Flag flags, i32 tab_width, i32 indent_width){
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer);
|
||||
Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
|
||||
b32 result = false;
|
||||
if (tokens != 0){
|
||||
result = true;
|
||||
|
||||
Scratch_Block scratch(app);
|
||||
Range_i64 line_numbers = {};
|
||||
if (HasFlag(flags, Indent_FullTokens)){
|
||||
i32 safety_counter = 0;
|
||||
for (;;){
|
||||
Range_i64 expanded = enclose_tokens(app, buffer, pos);
|
||||
expanded = enclose_whole_lines(app, buffer, expanded);
|
||||
if (expanded == pos){
|
||||
break;
|
||||
}
|
||||
pos = expanded;
|
||||
safety_counter += 1;
|
||||
if (safety_counter == 20){
|
||||
pos = buffer_range(app, buffer);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
line_numbers = get_line_range_from_pos_range(app, buffer, pos);
|
||||
|
||||
i64 *indentations = get_indentation_array(app, scratch, buffer, line_numbers, flags, tab_width, indent_width);
|
||||
set_line_indents(app, scratch, buffer, line_numbers, indentations, flags, tab_width);
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
global_const i32 auto_indent_tab_width = 4;
|
||||
|
||||
function void
|
||||
auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos, Indent_Flag flags){
|
||||
i32 indent_width = global_config.indent_width;
|
||||
AddFlag(flags, Indent_FullTokens);
|
||||
if (global_config.indent_with_tabs){
|
||||
AddFlag(flags, Indent_UseTab);
|
||||
}
|
||||
auto_indent_buffer(app, buffer, pos, flags, indent_width, auto_indent_tab_width);
|
||||
}
|
||||
|
||||
function void
|
||||
auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos){
|
||||
auto_indent_buffer(app, buffer, pos, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_tab_whole_file)
|
||||
CUSTOM_DOC("Audo-indents the entire current buffer.")
|
||||
{
|
||||
View_ID view = get_active_view(app, AccessOpen);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
|
||||
i32 buffer_size = (i32)buffer_get_size(app, buffer);
|
||||
buffer_auto_indent(app, buffer, 0, buffer_size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens);
|
||||
i64 buffer_size = buffer_get_size(app, buffer);
|
||||
auto_indent_buffer(app, buffer, Ii64(0, buffer_size));
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_tab_line_at_cursor)
|
||||
|
@ -512,7 +321,7 @@ CUSTOM_DOC("Auto-indents the line on which the cursor sits.")
|
|||
View_ID view = get_active_view(app, AccessOpen);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
|
||||
i64 pos = view_get_cursor_pos(app, view);
|
||||
buffer_auto_indent(app, buffer, pos, pos, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens);
|
||||
auto_indent_buffer(app, buffer, Ii64(pos));
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
|
@ -522,7 +331,7 @@ CUSTOM_DOC("Auto-indents the range between the cursor and the mark.")
|
|||
View_ID view = get_active_view(app, AccessOpen);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
|
||||
Range_i64 range = get_view_range(app, view);
|
||||
buffer_auto_indent(app, buffer, range.min, range.max, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens);
|
||||
auto_indent_buffer(app, buffer, range);
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
|
@ -532,13 +341,13 @@ CUSTOM_DOC("Inserts a character and auto-indents the line on which the cursor si
|
|||
write_character(app);
|
||||
View_ID view = get_active_view(app, AccessOpen);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, AccessOpen);
|
||||
u32 flags = DEFAULT_INDENT_FLAGS;
|
||||
i64 pos = view_get_cursor_pos(app, view);
|
||||
Indent_Flag flags = 0;
|
||||
User_Input in = get_command_input(app);
|
||||
if (in.key.character == '\n'){
|
||||
flags |= AutoIndent_ExactAlignBlock;
|
||||
flags |= Indent_ExactAlignBlock;
|
||||
}
|
||||
i64 pos = view_get_cursor_pos(app, view);
|
||||
buffer_auto_indent(app, buffer, pos, pos, DEF_TAB_WIDTH, flags);
|
||||
auto_indent_buffer(app, buffer, Ii64(pos), flags);
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -7,24 +7,22 @@
|
|||
#if !defined(FCODER_AUTO_INDENT_H)
|
||||
#define FCODER_AUTO_INDENT_H
|
||||
|
||||
struct Indent_Options{
|
||||
b32 empty_blank_lines;
|
||||
b32 use_tabs;
|
||||
i32 tab_width;
|
||||
typedef u32 Indent_Flag;
|
||||
enum{
|
||||
Indent_ClearLine = 0x1,
|
||||
Indent_UseTab = 0x2,
|
||||
Indent_ExactAlignBlock = 0x4,
|
||||
Indent_FullTokens = 0x8,
|
||||
};
|
||||
|
||||
struct Indent_Parse_State{
|
||||
i64 current_indent;
|
||||
i64 previous_line_indent;
|
||||
i64 paren_nesting;
|
||||
i64 paren_anchor_indent[16];
|
||||
i64 comment_shift;
|
||||
i64 previous_comment_indent;
|
||||
struct Nest{
|
||||
Nest *next;
|
||||
Token_Base_Kind kind;
|
||||
i64 indent;
|
||||
};
|
||||
|
||||
struct Indent_Anchor_Position{
|
||||
Token *token;
|
||||
i32 indentation;
|
||||
struct Nest_Alloc{
|
||||
Nest *free_nest;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1741,6 +1741,23 @@ If32(f32 a){
|
|||
return(interval);
|
||||
}
|
||||
|
||||
internal b32
|
||||
operator==(Interval_i32 a, Interval_i32 b){
|
||||
return(a.min == b.min && a.max == b.max);
|
||||
}
|
||||
internal b32
|
||||
operator==(Interval_i64 a, Interval_i64 b){
|
||||
return(a.min == b.min && a.max == b.max);
|
||||
}
|
||||
internal b32
|
||||
operator==(Interval_u64 a, Interval_u64 b){
|
||||
return(a.min == b.min && a.max == b.max);
|
||||
}
|
||||
internal b32
|
||||
operator==(Interval_f32 a, Interval_f32 b){
|
||||
return(a.min == b.min && a.max == b.max);
|
||||
}
|
||||
|
||||
#define make_range Ii32
|
||||
#define make_range_i32 Ii32
|
||||
#define make_range_i64 Ii64
|
||||
|
|
|
@ -39,7 +39,7 @@ long_braces(Application_Links *app, char *text, i32 size){
|
|||
i64 pos = view_get_cursor_pos(app, view);
|
||||
buffer_replace_range(app, buffer, Ii64(pos), SCu8(text, size));
|
||||
view_set_cursor_and_preferred_x(app, view, seek_pos(pos + 2));
|
||||
buffer_auto_indent(app, buffer, pos, pos + size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens);
|
||||
auto_indent_buffer(app, buffer, Ii64_size(pos, size));
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
|
|
|
@ -1103,8 +1103,7 @@ BUFFER_HOOK_SIG(default_file_save){
|
|||
if (global_config.automatically_indent_text_on_save &&
|
||||
buffer_get_setting(app, buffer_id, BufferSetting_VirtualWhitespace, &is_virtual)){
|
||||
if (is_virtual){
|
||||
i64 buffer_size = buffer_get_size(app, buffer_id);
|
||||
buffer_auto_indent(app, buffer_id, 0, buffer_size, DEF_TAB_WIDTH, DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens);
|
||||
auto_indent_buffer(app, buffer_id, buffer_range(app, buffer_id));
|
||||
}
|
||||
}
|
||||
// no meaning for return
|
||||
|
|
|
@ -789,14 +789,12 @@ internal i64
|
|||
boundary_token(Application_Links *app, Buffer_ID buffer, Side side, Scan_Direction direction, i64 pos){
|
||||
i64 result = boundary_non_whitespace(app, buffer, side, direction, pos);
|
||||
Token_Array tokens = get_token_array_from_buffer(app, buffer);
|
||||
if (tokens.tokens == 0){
|
||||
result = boundary_non_whitespace(app, buffer, side, direction, pos);
|
||||
}
|
||||
else{
|
||||
if (tokens.tokens != 0){
|
||||
switch (direction){
|
||||
case Scan_Forward:
|
||||
{
|
||||
i64 buffer_size = buffer_get_size(app, buffer);
|
||||
result = buffer_size;
|
||||
if (tokens.count > 0){
|
||||
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
|
||||
Token *token = token_it_read(&it);
|
||||
|
@ -809,80 +807,45 @@ boundary_token(Application_Links *app, Buffer_ID buffer, Side side, Scan_Directi
|
|||
result = token->pos + token->size;
|
||||
}
|
||||
else{
|
||||
if (token->pos > pos){
|
||||
result = token->pos;
|
||||
if (token->pos <= pos){
|
||||
token_it_inc_non_whitespace(&it);
|
||||
token = token_it_read(&it);
|
||||
}
|
||||
else{
|
||||
token += 1;
|
||||
if (token < tokens.tokens + tokens.count){
|
||||
result = token->pos;
|
||||
}
|
||||
else{
|
||||
result = buffer_size;
|
||||
}
|
||||
if (token != 0){
|
||||
result = token->pos;
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
result = buffer_size;
|
||||
}
|
||||
}
|
||||
else{
|
||||
result = buffer_size;
|
||||
}
|
||||
}break;
|
||||
|
||||
case Scan_Backward:
|
||||
{
|
||||
result = 0;
|
||||
if (tokens.count > 0){
|
||||
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos - 1);
|
||||
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
|
||||
Token *token = token_it_read(&it);
|
||||
if (token->kind == TokenBaseKind_Whitespace){
|
||||
token_it_dec_non_whitespace(&it);
|
||||
token = token_it_read(&it);
|
||||
}
|
||||
if (side == Side_Min){
|
||||
if (token == 0){
|
||||
token = tokens.tokens + tokens.count - 1;
|
||||
if (token != 0){
|
||||
if (side == Side_Min){
|
||||
if (token->pos >= pos){
|
||||
token_it_dec_non_whitespace(&it);
|
||||
token = token_it_read(&it);
|
||||
}
|
||||
result = token->pos;
|
||||
}
|
||||
else{
|
||||
if (token->pos < pos){
|
||||
result = token->pos;
|
||||
if (token->pos + token->size >= pos){
|
||||
token_it_dec_non_whitespace(&it);
|
||||
token = token_it_read(&it);
|
||||
}
|
||||
else{
|
||||
token -= 1;
|
||||
if (token >= tokens.tokens){
|
||||
result = token->pos;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (token == 0){
|
||||
token = tokens.tokens + tokens.count - 1;
|
||||
result = token->pos + token->size;
|
||||
}
|
||||
else{
|
||||
token -= 1;
|
||||
if (token >= tokens.tokens && token->pos + token->size == pos){
|
||||
token -= 1;
|
||||
}
|
||||
if (token >= tokens.tokens){
|
||||
result = token->pos + token->size;
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
result = 0;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
|
@ -1387,7 +1350,7 @@ get_indent_info_range(Application_Links *app, Buffer_ID buffer, Range_i64 range,
|
|||
if (!character_is_whitespace(c)){
|
||||
info.is_blank = false;
|
||||
info.all_space = false;
|
||||
info.first_char_pos = range.start + (i32)i;
|
||||
info.first_char_pos = range.start + (i64)i;
|
||||
break;
|
||||
}
|
||||
if (c != ' '){
|
||||
|
|
|
@ -280,7 +280,7 @@ token_iterator_index(u64 user_id, Token_List *list, i64 index){
|
|||
block = node;
|
||||
break;
|
||||
}
|
||||
base_index += block->count;
|
||||
base_index += node->count;
|
||||
}
|
||||
Assert(block != 0);
|
||||
it.user_id = user_id;
|
||||
|
@ -320,7 +320,7 @@ token_iterator_pos(u64 user_id, Token_List *list, i64 pos){
|
|||
block = node;
|
||||
break;
|
||||
}
|
||||
base_index += block->count;
|
||||
base_index += node->count;
|
||||
}
|
||||
Assert(block != 0);
|
||||
i64 sub_index = token_index_from_pos(block->tokens, block->count, pos);
|
||||
|
|
|
@ -9,23 +9,23 @@
|
|||
|
||||
typedef i16 Token_Base_Kind;
|
||||
enum{
|
||||
TokenBaseKind_EOF,
|
||||
TokenBaseKind_Whitespace,
|
||||
TokenBaseKind_LexError,
|
||||
TokenBaseKind_Comment,
|
||||
TokenBaseKind_Keyword,
|
||||
TokenBaseKind_Preprocessor,
|
||||
TokenBaseKind_Identifier,
|
||||
TokenBaseKind_Operator,
|
||||
TokenBaseKind_LiteralInteger,
|
||||
TokenBaseKind_LiteralFloat,
|
||||
TokenBaseKind_LiteralString,
|
||||
TokenBaseKind_ScopeOpen,
|
||||
TokenBaseKind_ScopeClose,
|
||||
TokenBaseKind_ParentheticalOpen,
|
||||
TokenBaseKind_ParentheticalClose,
|
||||
TokenBaseKind_EOF = 0,
|
||||
TokenBaseKind_Whitespace = 1,
|
||||
TokenBaseKind_LexError = 2,
|
||||
TokenBaseKind_Comment = 3,
|
||||
TokenBaseKind_Keyword = 4,
|
||||
TokenBaseKind_Preprocessor = 5,
|
||||
TokenBaseKind_Identifier = 6,
|
||||
TokenBaseKind_Operator = 7,
|
||||
TokenBaseKind_LiteralInteger = 8,
|
||||
TokenBaseKind_LiteralFloat = 9,
|
||||
TokenBaseKind_LiteralString = 10,
|
||||
TokenBaseKind_ScopeOpen = 11,
|
||||
TokenBaseKind_ScopeClose = 12,
|
||||
TokenBaseKind_ParentheticalOpen = 13,
|
||||
TokenBaseKind_ParentheticalClose = 14,
|
||||
|
||||
TokenBaseKind_COUNT,
|
||||
TokenBaseKind_COUNT = 15,
|
||||
};
|
||||
|
||||
char *token_base_kind_names[] ={
|
||||
|
|
|
@ -165,13 +165,6 @@ ENUM(u32, Command_Line_Interface_Flag){
|
|||
CLI_SendEndSignal = 0x8,
|
||||
};
|
||||
|
||||
ENUM(u32, Auto_Indent_Flag){
|
||||
AutoIndent_ClearLine = 0x1,
|
||||
AutoIndent_UseTab = 0x2,
|
||||
AutoIndent_ExactAlignBlock = 0x4,
|
||||
AutoIndent_FullTokens = 0x8,
|
||||
};
|
||||
|
||||
ENUM(u32, Set_Buffer_Flag){
|
||||
SetBuffer_KeepOriginalGUI = 0x1
|
||||
};
|
||||
|
|
|
@ -248,12 +248,12 @@ i32 line_number;
|
|||
};
|
||||
static Command_Metadata fcoder_metacmd_table[226] = {
|
||||
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "w:\\4ed\\code\\custom\\4coder_remapping_commands.cpp", 48, 62 },
|
||||
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2160 },
|
||||
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2166 },
|
||||
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2172 },
|
||||
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2178 },
|
||||
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2184 },
|
||||
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2192 },
|
||||
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2123 },
|
||||
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2129 },
|
||||
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2135 },
|
||||
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2141 },
|
||||
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2147 },
|
||||
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\custom\\4coder_helper.cpp", 36, 2155 },
|
||||
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 196 },
|
||||
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 206 },
|
||||
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 216 },
|
||||
|
@ -387,10 +387,10 @@ static Command_Metadata fcoder_metacmd_table[226] = {
|
|||
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 847 },
|
||||
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 880 },
|
||||
{ PROC_LINKS(command_lister, 0), "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 960 },
|
||||
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 500 },
|
||||
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 509 },
|
||||
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 519 },
|
||||
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 529 },
|
||||
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 655 },
|
||||
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 664 },
|
||||
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 674 },
|
||||
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "w:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 684 },
|
||||
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 166 },
|
||||
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 172 },
|
||||
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "w:\\4ed\\code\\custom\\4coder_search.cpp", 36, 178 },
|
||||
|
|
Loading…
Reference in New Issue