[indent] fix inside paretheses bug
This commit is contained in:
parent
7905322feb
commit
d8e1f2f7d4
|
@ -6,403 +6,404 @@
|
|||
|
||||
internal Batch_Edit*
|
||||
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 = lines.first;
|
||||
line_number <= lines.max;
|
||||
++line_number){
|
||||
i64 line_start_pos = get_line_start_pos(app, buffer, line_number);
|
||||
Indent_Info indent_info = get_indent_info_line_number_and_start(app, buffer, line_number, line_start_pos, tab_width);
|
||||
|
||||
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 = indent_info.indent_pos;
|
||||
}
|
||||
|
||||
if (correct_indentation != indent_info.indent_pos){
|
||||
u64 str_size = 0;
|
||||
u8 *str = 0;
|
||||
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);
|
||||
block_fill_u8(str, tab_count, '\t');
|
||||
block_fill_u8(str + tab_count, space_count, ' ');
|
||||
}
|
||||
else{
|
||||
str_size = correct_indentation;
|
||||
str = push_array(arena, u8, str_size);
|
||||
block_fill_u8(str, str_size, ' ');
|
||||
}
|
||||
|
||||
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, indent_info.first_char_pos);
|
||||
}
|
||||
}
|
||||
|
||||
return(batch_first);
|
||||
i64 *shifted_indentations = indentations - lines.first;
|
||||
|
||||
Batch_Edit *batch_first = 0;
|
||||
Batch_Edit *batch_last = 0;
|
||||
|
||||
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 indent_info = get_indent_info_line_number_and_start(app, buffer, line_number, line_start_pos, tab_width);
|
||||
|
||||
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 = indent_info.indent_pos;
|
||||
}
|
||||
|
||||
if (correct_indentation != indent_info.indent_pos){
|
||||
u64 str_size = 0;
|
||||
u8 *str = 0;
|
||||
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);
|
||||
block_fill_u8(str, tab_count, '\t');
|
||||
block_fill_u8(str + tab_count, space_count, ' ');
|
||||
}
|
||||
else{
|
||||
str_size = correct_indentation;
|
||||
str = push_array(arena, u8, str_size);
|
||||
block_fill_u8(str, str_size, ' ');
|
||||
}
|
||||
|
||||
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, indent_info.first_char_pos);
|
||||
}
|
||||
}
|
||||
|
||||
return(batch_first);
|
||||
}
|
||||
|
||||
internal void
|
||||
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);
|
||||
}
|
||||
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*
|
||||
find_anchor_token(Application_Links *app, Buffer_ID buffer, Token_Array *tokens, i64 invalid_line){
|
||||
ProfileScope(app, "find anchor token");
|
||||
Token *result = 0;
|
||||
|
||||
if (tokens != 0 && tokens->tokens != 0){
|
||||
result = tokens->tokens;
|
||||
i64 invalid_pos = get_line_start_pos(app, buffer, invalid_line);
|
||||
i32 scope_counter = 0;
|
||||
i32 paren_counter = 0;
|
||||
Token *token = tokens->tokens;
|
||||
for (;;token += 1){
|
||||
if (token->pos + token->size > invalid_pos){
|
||||
break;
|
||||
}
|
||||
if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
if (scope_counter == 0 && paren_counter == 0){
|
||||
result = token;
|
||||
}
|
||||
switch (token->kind){
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
{
|
||||
scope_counter += 1;
|
||||
}break;
|
||||
case TokenBaseKind_ScopeClose:
|
||||
{
|
||||
paren_counter = 0;
|
||||
if (scope_counter > 0){
|
||||
scope_counter -= 1;
|
||||
}
|
||||
}break;
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
{
|
||||
paren_counter += 1;
|
||||
}break;
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
if (paren_counter > 0){
|
||||
paren_counter -= 1;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
ProfileScope(app, "find anchor token");
|
||||
Token *result = 0;
|
||||
|
||||
if (tokens != 0 && tokens->tokens != 0){
|
||||
result = tokens->tokens;
|
||||
i64 invalid_pos = get_line_start_pos(app, buffer, invalid_line);
|
||||
i32 scope_counter = 0;
|
||||
i32 paren_counter = 0;
|
||||
Token *token = tokens->tokens;
|
||||
for (;;token += 1){
|
||||
if (token->pos + token->size > invalid_pos){
|
||||
break;
|
||||
}
|
||||
if (!HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
if (scope_counter == 0 && paren_counter == 0){
|
||||
result = token;
|
||||
}
|
||||
switch (token->kind){
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
{
|
||||
scope_counter += 1;
|
||||
}break;
|
||||
case TokenBaseKind_ScopeClose:
|
||||
{
|
||||
paren_counter = 0;
|
||||
if (scope_counter > 0){
|
||||
scope_counter -= 1;
|
||||
}
|
||||
}break;
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
{
|
||||
paren_counter += 1;
|
||||
}break;
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
if (paren_counter > 0){
|
||||
paren_counter -= 1;
|
||||
}
|
||||
}break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return(result);
|
||||
}
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
internal void
|
||||
indent__free_nest(Nest_Alloc *alloc, Nest *nest){
|
||||
sll_stack_push(alloc->free_nest, nest);
|
||||
sll_stack_push(alloc->free_nest, nest);
|
||||
}
|
||||
|
||||
internal b32
|
||||
indent__unfinished_statement(Token *token, Nest *current_nest){
|
||||
b32 result = false;
|
||||
if (current_nest != 0 && current_nest->kind == TokenBaseKind_ScopeOpen){
|
||||
result = true;
|
||||
switch (token->kind){
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
case TokenBaseKind_ScopeClose:
|
||||
case TokenBaseKind_StatementClose:
|
||||
{
|
||||
result = false;
|
||||
}break;
|
||||
}
|
||||
if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
b32 result = false;
|
||||
if (current_nest != 0 && current_nest->kind == TokenBaseKind_ScopeOpen){
|
||||
result = true;
|
||||
switch (token->kind){
|
||||
case TokenBaseKind_ScopeOpen:
|
||||
case TokenBaseKind_ScopeClose:
|
||||
case TokenBaseKind_StatementClose:
|
||||
{
|
||||
result = false;
|
||||
}break;
|
||||
}
|
||||
if (HasFlag(token->flags, TokenBaseFlag_PreprocessorBody)){
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return(result);
|
||||
}
|
||||
|
||||
function void
|
||||
line_indent_cache_update(Application_Links *app, Buffer_ID buffer, i32 tab_width, Indent_Line_Cache *line_cache){
|
||||
if (line_cache->line_number_for_cached_indent != line_cache->where_token_starts){
|
||||
ProfileScope(app, "get indent info");
|
||||
line_cache->line_number_for_cached_indent = line_cache->where_token_starts;
|
||||
line_cache->start_pos = get_line_start_pos(app, buffer, line_cache->where_token_starts);
|
||||
Range_i64 range = Ii64(line_cache->start_pos, line_cache->one_past_last_pos);
|
||||
line_cache->indent_info = get_indent_info_range(app, buffer, range, tab_width);
|
||||
}
|
||||
if (line_cache->line_number_for_cached_indent != line_cache->where_token_starts){
|
||||
ProfileScope(app, "get indent info");
|
||||
line_cache->line_number_for_cached_indent = line_cache->where_token_starts;
|
||||
line_cache->start_pos = get_line_start_pos(app, buffer, line_cache->where_token_starts);
|
||||
Range_i64 range = Ii64(line_cache->start_pos, line_cache->one_past_last_pos);
|
||||
line_cache->indent_info = get_indent_info_range(app, buffer, range, tab_width);
|
||||
}
|
||||
}
|
||||
|
||||
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){
|
||||
ProfileScope(app, "get indentation array");
|
||||
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));
|
||||
|
||||
ProfileScope(app, "get indentation array");
|
||||
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));
|
||||
|
||||
#if 0
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer);
|
||||
Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
Managed_Scope scope = buffer_get_managed_scope(app, buffer);
|
||||
Token_Array *tokens = scope_attachment(app, scope, attachment_tokens, Token_Array);
|
||||
#endif
|
||||
|
||||
Token_Array token_array = get_token_array_from_buffer(app, buffer);
|
||||
Token_Array *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, arena);
|
||||
Nest *nest = 0;
|
||||
Nest_Alloc nest_alloc = {};
|
||||
|
||||
i64 line_last_indented = line - 1;
|
||||
i64 last_indent = 0;
|
||||
i64 actual_indent = 0;
|
||||
b32 in_unfinished_statement = false;
|
||||
|
||||
Indent_Line_Cache line_cache = {};
|
||||
|
||||
for (;;){
|
||||
Token *token = token_it_read(&token_it);
|
||||
|
||||
if (line_cache.where_token_starts == 0 ||
|
||||
token->pos >= line_cache.one_past_last_pos){
|
||||
ProfileScope(app, "get line number");
|
||||
line_cache.where_token_starts = get_line_number_from_pos(app, buffer, token->pos);
|
||||
line_cache.one_past_last_pos = get_line_end_pos(app, buffer, line_cache.where_token_starts);
|
||||
}
|
||||
|
||||
i64 current_indent = 0;
|
||||
if (nest != 0){
|
||||
current_indent = nest->indent;
|
||||
}
|
||||
i64 this_indent = current_indent;
|
||||
i64 following_indent = current_indent;
|
||||
|
||||
b32 shift_by_actual_indent = false;
|
||||
b32 ignore_unfinished_statement = false;
|
||||
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;
|
||||
following_indent = nest->indent;
|
||||
ignore_unfinished_statement = true;
|
||||
}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;
|
||||
}
|
||||
following_indent = this_indent;
|
||||
ignore_unfinished_statement = true;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
{
|
||||
Nest *new_nest = indent__new_nest(arena, &nest_alloc);
|
||||
sll_stack_push(nest, new_nest);
|
||||
nest->kind = TokenBaseKind_ParentheticalOpen;
|
||||
line_indent_cache_update(app, buffer, tab_width, &line_cache);
|
||||
nest->indent = (token->pos - line_cache.indent_info.first_char_pos) + 1;
|
||||
following_indent = nest->indent;
|
||||
shift_by_actual_indent = true;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
if (nest != 0 && nest->kind == TokenBaseKind_ParentheticalOpen){
|
||||
Nest *n = nest;
|
||||
sll_stack_pop(nest);
|
||||
indent__free_nest(&nest_alloc, n);
|
||||
}
|
||||
following_indent = 0;
|
||||
if (nest != 0){
|
||||
following_indent = nest->indent;
|
||||
}
|
||||
//ignore_unfinished_statement = true;
|
||||
}break;
|
||||
}
|
||||
|
||||
if (token->sub_kind == TokenCppKind_BlockComment ||
|
||||
token->sub_kind == TokenCppKind_LiteralStringRaw){
|
||||
ignore_unfinished_statement = true;
|
||||
}
|
||||
|
||||
if (in_unfinished_statement && !ignore_unfinished_statement){
|
||||
this_indent += indent_width;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Token_Array token_array = get_token_array_from_buffer(app, buffer);
|
||||
Token_Array *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, arena);
|
||||
Nest *nest = 0;
|
||||
Nest_Alloc nest_alloc = {};
|
||||
|
||||
i64 line_last_indented = line - 1;
|
||||
i64 last_indent = 0;
|
||||
i64 actual_indent = 0;
|
||||
b32 in_unfinished_statement = false;
|
||||
|
||||
Indent_Line_Cache line_cache = {};
|
||||
|
||||
for (;;){
|
||||
Token *token = token_it_read(&token_it);
|
||||
|
||||
if (line_cache.where_token_starts == 0 ||
|
||||
token->pos >= line_cache.one_past_last_pos){
|
||||
ProfileScope(app, "get line number");
|
||||
line_cache.where_token_starts = get_line_number_from_pos(app, buffer, token->pos);
|
||||
line_cache.one_past_last_pos = get_line_end_pos(app, buffer, line_cache.where_token_starts);
|
||||
}
|
||||
|
||||
i64 current_indent = 0;
|
||||
if (nest != 0){
|
||||
current_indent = nest->indent;
|
||||
}
|
||||
i64 this_indent = current_indent;
|
||||
i64 following_indent = current_indent;
|
||||
|
||||
b32 shift_by_actual_indent = false;
|
||||
b32 ignore_unfinished_statement = false;
|
||||
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;
|
||||
following_indent = nest->indent;
|
||||
ignore_unfinished_statement = true;
|
||||
}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;
|
||||
}
|
||||
following_indent = this_indent;
|
||||
ignore_unfinished_statement = true;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalOpen:
|
||||
{
|
||||
Nest *new_nest = indent__new_nest(arena, &nest_alloc);
|
||||
sll_stack_push(nest, new_nest);
|
||||
nest->kind = TokenBaseKind_ParentheticalOpen;
|
||||
line_indent_cache_update(app, buffer, tab_width, &line_cache);
|
||||
nest->indent = (token->pos - line_cache.indent_info.first_char_pos) + 1;
|
||||
following_indent = nest->indent;
|
||||
shift_by_actual_indent = true;
|
||||
ignore_unfinished_statement = true;
|
||||
}break;
|
||||
|
||||
case TokenBaseKind_ParentheticalClose:
|
||||
{
|
||||
if (nest != 0 && nest->kind == TokenBaseKind_ParentheticalOpen){
|
||||
Nest *n = nest;
|
||||
sll_stack_pop(nest);
|
||||
indent__free_nest(&nest_alloc, n);
|
||||
}
|
||||
following_indent = 0;
|
||||
if (nest != 0){
|
||||
following_indent = nest->indent;
|
||||
}
|
||||
//ignore_unfinished_statement = true;
|
||||
}break;
|
||||
}
|
||||
|
||||
if (token->sub_kind == TokenCppKind_BlockComment ||
|
||||
token->sub_kind == TokenCppKind_LiteralStringRaw){
|
||||
ignore_unfinished_statement = true;
|
||||
}
|
||||
|
||||
if (in_unfinished_statement && !ignore_unfinished_statement){
|
||||
this_indent += indent_width;
|
||||
}
|
||||
}
|
||||
|
||||
#define EMIT(N) \
|
||||
Stmnt(if (lines.first <= line_it){shifted_indentations[line_it]=N;} \
|
||||
if (line_it == lines.end){goto finished;} \
|
||||
actual_indent = N; )
|
||||
|
||||
i64 line_it = line_last_indented;
|
||||
if (lines.first <= line_cache.where_token_starts){
|
||||
for (;line_it < line_cache.where_token_starts;){
|
||||
line_it += 1;
|
||||
if (line_it == line_cache.where_token_starts){
|
||||
EMIT(this_indent);
|
||||
}
|
||||
else{
|
||||
EMIT(last_indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
actual_indent = this_indent;
|
||||
line_it = line_cache.where_token_starts;
|
||||
}
|
||||
|
||||
i64 line_where_token_ends = get_line_number_from_pos(app, buffer, token->pos + token->size);
|
||||
if (lines.first <= line_where_token_ends){
|
||||
line_indent_cache_update(app, buffer, tab_width, &line_cache);
|
||||
i64 line_where_token_starts_shift = this_indent - line_cache.indent_info.indent_pos;
|
||||
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_number_and_start(app, buffer, line_it, 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);
|
||||
}
|
||||
}
|
||||
else{
|
||||
line_it = line_where_token_ends;
|
||||
}
|
||||
|
||||
i64 line_it = line_last_indented;
|
||||
if (lines.first <= line_cache.where_token_starts){
|
||||
for (;line_it < line_cache.where_token_starts;){
|
||||
line_it += 1;
|
||||
if (line_it == line_cache.where_token_starts){
|
||||
EMIT(this_indent);
|
||||
}
|
||||
else{
|
||||
EMIT(last_indent);
|
||||
}
|
||||
}
|
||||
}
|
||||
else{
|
||||
actual_indent = this_indent;
|
||||
line_it = line_cache.where_token_starts;
|
||||
}
|
||||
|
||||
i64 line_where_token_ends = get_line_number_from_pos(app, buffer, token->pos + token->size);
|
||||
if (lines.first <= line_where_token_ends){
|
||||
line_indent_cache_update(app, buffer, tab_width, &line_cache);
|
||||
i64 line_where_token_starts_shift = this_indent - line_cache.indent_info.indent_pos;
|
||||
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_number_and_start(app, buffer, line_it, 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);
|
||||
}
|
||||
}
|
||||
else{
|
||||
line_it = line_where_token_ends;
|
||||
}
|
||||
#undef EMIT
|
||||
|
||||
if (shift_by_actual_indent){
|
||||
nest->indent += actual_indent;
|
||||
following_indent += actual_indent;
|
||||
}
|
||||
|
||||
if (token->kind != TokenBaseKind_Comment){
|
||||
in_unfinished_statement = indent__unfinished_statement(token, nest);
|
||||
if (in_unfinished_statement){
|
||||
following_indent += indent_width;
|
||||
}
|
||||
}
|
||||
|
||||
last_indent = following_indent;
|
||||
line_last_indented = line_it;
|
||||
|
||||
if (!token_it_inc_non_whitespace(&token_it)){
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
finished:;
|
||||
return(indentations);
|
||||
|
||||
if (shift_by_actual_indent){
|
||||
nest->indent += actual_indent;
|
||||
following_indent += actual_indent;
|
||||
}
|
||||
|
||||
if (token->kind != TokenBaseKind_Comment){
|
||||
in_unfinished_statement = indent__unfinished_statement(token, nest);
|
||||
if (in_unfinished_statement){
|
||||
following_indent += indent_width;
|
||||
}
|
||||
}
|
||||
|
||||
last_indent = following_indent;
|
||||
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){
|
||||
ProfileScope(app, "auto indent buffer");
|
||||
Token_Array token_array = get_token_array_from_buffer(app, buffer);
|
||||
Token_Array *tokens = &token_array;
|
||||
|
||||
b32 result = false;
|
||||
if (tokens->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);
|
||||
ProfileScope(app, "auto indent buffer");
|
||||
Token_Array token_array = get_token_array_from_buffer(app, buffer);
|
||||
Token_Array *tokens = &token_array;
|
||||
|
||||
b32 result = false;
|
||||
if (tokens->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);
|
||||
}
|
||||
|
||||
function void
|
||||
auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos, Indent_Flag flags){
|
||||
i32 indent_width = (i32)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||
i32 tab_width = (i32)def_get_config_u64(app, vars_save_string_lit("default_tab_width"));
|
||||
tab_width = clamp_bot(1, tab_width);
|
||||
AddFlag(flags, Indent_FullTokens);
|
||||
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
|
||||
if (indent_with_tabs){
|
||||
AddFlag(flags, Indent_UseTab);
|
||||
}
|
||||
auto_indent_buffer(app, buffer, pos, flags, indent_width, tab_width);
|
||||
i32 indent_width = (i32)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||
i32 tab_width = (i32)def_get_config_u64(app, vars_save_string_lit("default_tab_width"));
|
||||
tab_width = clamp_bot(1, tab_width);
|
||||
AddFlag(flags, Indent_FullTokens);
|
||||
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
|
||||
if (indent_with_tabs){
|
||||
AddFlag(flags, Indent_UseTab);
|
||||
}
|
||||
auto_indent_buffer(app, buffer, pos, flags, indent_width, tab_width);
|
||||
}
|
||||
|
||||
function void
|
||||
auto_indent_buffer(Application_Links *app, Buffer_ID buffer, Range_i64 pos){
|
||||
auto_indent_buffer(app, buffer, pos, 0);
|
||||
auto_indent_buffer(app, buffer, pos, 0);
|
||||
}
|
||||
|
||||
////////////////////////////////
|
||||
|
@ -410,78 +411,78 @@ auto_indent_buffer(app, buffer, pos, 0);
|
|||
CUSTOM_COMMAND_SIG(auto_indent_whole_file)
|
||||
CUSTOM_DOC("Audo-indents the entire current buffer.")
|
||||
{
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
i64 buffer_size = buffer_get_size(app, buffer);
|
||||
auto_indent_buffer(app, buffer, Ii64(0, buffer_size));
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
i64 buffer_size = buffer_get_size(app, buffer);
|
||||
auto_indent_buffer(app, buffer, Ii64(0, buffer_size));
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_indent_line_at_cursor)
|
||||
CUSTOM_DOC("Auto-indents the line on which the cursor sits.")
|
||||
{
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
i64 pos = view_get_cursor_pos(app, view);
|
||||
auto_indent_buffer(app, buffer, Ii64(pos));
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
i64 pos = view_get_cursor_pos(app, view);
|
||||
auto_indent_buffer(app, buffer, Ii64(pos));
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(auto_indent_range)
|
||||
CUSTOM_DOC("Auto-indents the range between the cursor and the mark.")
|
||||
{
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
Range_i64 range = get_view_range(app, view);
|
||||
auto_indent_buffer(app, buffer, range);
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
Range_i64 range = get_view_range(app, view);
|
||||
auto_indent_buffer(app, buffer, range);
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
CUSTOM_COMMAND_SIG(write_text_and_auto_indent)
|
||||
CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.")
|
||||
{
|
||||
ProfileScope(app, "write and auto indent");
|
||||
User_Input in = get_current_input(app);
|
||||
String_Const_u8 insert = to_writable(&in);
|
||||
if (insert.str != 0 && insert.size > 0){
|
||||
b32 do_auto_indent = false;
|
||||
for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){
|
||||
switch (insert.str[i]){
|
||||
case ';': case ':':
|
||||
case '{': case '}':
|
||||
case '(': case ')':
|
||||
case '[': case ']':
|
||||
case '#':
|
||||
case '\n': case '\t':
|
||||
{
|
||||
do_auto_indent = true;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
if (do_auto_indent){
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
|
||||
Range_i64 pos = {};
|
||||
if (view_has_highlighted_range(app, view)){
|
||||
pos = get_view_range(app, view);
|
||||
}
|
||||
else{
|
||||
pos.min = pos.max = view_get_cursor_pos(app, view);
|
||||
}
|
||||
|
||||
write_text_input(app);
|
||||
|
||||
i64 end_pos = view_get_cursor_pos(app, view);
|
||||
pos.min = Min(pos.min, end_pos);
|
||||
pos.max = Max(pos.max, end_pos);
|
||||
|
||||
auto_indent_buffer(app, buffer, pos, 0);
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
else{
|
||||
write_text_input(app);
|
||||
}
|
||||
}
|
||||
ProfileScope(app, "write and auto indent");
|
||||
User_Input in = get_current_input(app);
|
||||
String_Const_u8 insert = to_writable(&in);
|
||||
if (insert.str != 0 && insert.size > 0){
|
||||
b32 do_auto_indent = false;
|
||||
for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){
|
||||
switch (insert.str[i]){
|
||||
case ';': case ':':
|
||||
case '{': case '}':
|
||||
case '(': case ')':
|
||||
case '[': case ']':
|
||||
case '#':
|
||||
case '\n': case '\t':
|
||||
{
|
||||
do_auto_indent = true;
|
||||
}break;
|
||||
}
|
||||
}
|
||||
if (do_auto_indent){
|
||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||
|
||||
Range_i64 pos = {};
|
||||
if (view_has_highlighted_range(app, view)){
|
||||
pos = get_view_range(app, view);
|
||||
}
|
||||
else{
|
||||
pos.min = pos.max = view_get_cursor_pos(app, view);
|
||||
}
|
||||
|
||||
write_text_input(app);
|
||||
|
||||
i64 end_pos = view_get_cursor_pos(app, view);
|
||||
pos.min = Min(pos.min, end_pos);
|
||||
pos.max = Max(pos.max, end_pos);
|
||||
|
||||
auto_indent_buffer(app, buffer, pos, 0);
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
else{
|
||||
write_text_input(app);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// BOTTOM
|
||||
|
|
|
@ -291,9 +291,9 @@ i32 line_number;
|
|||
};
|
||||
static Command_Metadata fcoder_metacmd_table[268] = {
|
||||
{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "W:\\4ed\\code\\custom\\4coder_default_framework.cpp", 47, 481 },
|
||||
{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 419 },
|
||||
{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 429 },
|
||||
{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 410 },
|
||||
{ PROC_LINKS(auto_indent_line_at_cursor, 0), false, "auto_indent_line_at_cursor", 26, "Auto-indents the line on which the cursor sits.", 47, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 420 },
|
||||
{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 430 },
|
||||
{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 411 },
|
||||
{ PROC_LINKS(backspace_alpha_numeric_boundary, 0), false, "backspace_alpha_numeric_boundary", 32, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 154 },
|
||||
{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 96 },
|
||||
{ PROC_LINKS(basic_change_active_panel, 0), false, "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 668 },
|
||||
|
@ -553,7 +553,7 @@ static Command_Metadata fcoder_metacmd_table[268] = {
|
|||
{ PROC_LINKS(write_hack, 0), false, "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 82 },
|
||||
{ PROC_LINKS(write_note, 0), false, "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 },
|
||||
{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 67 },
|
||||
{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 439 },
|
||||
{ PROC_LINKS(write_text_and_auto_indent, 0), false, "write_text_and_auto_indent", 26, "Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.", 145, "W:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 440 },
|
||||
{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 59 },
|
||||
{ PROC_LINKS(write_todo, 0), false, "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "W:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 76 },
|
||||
{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 73 },
|
||||
|
|
Loading…
Reference in New Issue