some clean up on the indent rule code
							parent
							
								
									55eb007f68
								
							
						
					
					
						commit
						5b2077c6d7
					
				
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							| 
						 | 
					@ -2,6 +2,10 @@
 | 
				
			||||||
#ifndef FCODER_AUTO_INDENT_INC
 | 
					#ifndef FCODER_AUTO_INDENT_INC
 | 
				
			||||||
#define FCODER_AUTO_INDENT_INC
 | 
					#define FCODER_AUTO_INDENT_INC
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Generic Line Indenter
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Hard_Start_Result{
 | 
					struct Hard_Start_Result{
 | 
				
			||||||
    int32_t char_pos;
 | 
					    int32_t char_pos;
 | 
				
			||||||
    int32_t indent_pos;
 | 
					    int32_t indent_pos;
 | 
				
			||||||
| 
						 | 
					@ -62,36 +66,80 @@ struct Indent_Options{
 | 
				
			||||||
    int32_t tab_width;
 | 
					    int32_t tab_width;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#include "4cpp_lexer.h"
 | 
					static Buffer_Batch_Edit
 | 
				
			||||||
 | 
					make_batch_from_indent_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer,
 | 
				
			||||||
static int32_t
 | 
					                             int32_t line_start, int32_t line_end, int32_t *indent_marks,
 | 
				
			||||||
buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){
 | 
					                             Indent_Options opts){
 | 
				
			||||||
    Partial_Cursor partial_cursor;
 | 
					 | 
				
			||||||
    app->buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &partial_cursor);
 | 
					 | 
				
			||||||
    return(partial_cursor.pos);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static int32_t
 | 
					 | 
				
			||||||
buffer_get_line_index(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
 | 
					 | 
				
			||||||
    Partial_Cursor partial_cursor;
 | 
					 | 
				
			||||||
    app->buffer_compute_cursor(app, buffer, seek_pos(pos), &partial_cursor);
 | 
					 | 
				
			||||||
    return(partial_cursor.line);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static Cpp_Token*
 | 
					 | 
				
			||||||
get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line){
 | 
					 | 
				
			||||||
    int32_t line_start = buffer_get_line_start(app, buffer, line);
 | 
					 | 
				
			||||||
    Cpp_Get_Token_Result get_token = cpp_get_token(&tokens, line_start);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (get_token.in_whitespace){
 | 
					    Buffer_Batch_Edit result = {0};
 | 
				
			||||||
        get_token.token_index += 1;
 | 
					    
 | 
				
			||||||
 | 
					    int32_t edit_max = line_end - line_start;
 | 
				
			||||||
 | 
					    int32_t edit_count = 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    char *str_base = (char*)part->base + part->pos;
 | 
				
			||||||
 | 
					    int32_t str_size = 0;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    // NOTE(allen): Shift the array so that line_i can just operate in
 | 
				
			||||||
 | 
					    // it's natural value range.
 | 
				
			||||||
 | 
					    indent_marks -= line_start;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    for (int32_t line_i = line_start; line_i < line_end; ++line_i){
 | 
				
			||||||
 | 
					        int32_t line_start = buffer_get_line_start(app, buffer, line_i);
 | 
				
			||||||
 | 
					        Hard_Start_Result hard_start = 
 | 
				
			||||||
 | 
					            buffer_find_hard_start(app, buffer, line_start, opts.tab_width);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        int32_t correct_indentation = indent_marks[line_i];
 | 
				
			||||||
 | 
					        if (hard_start.all_whitespace && opts.empty_blank_lines) correct_indentation = 0;
 | 
				
			||||||
 | 
					        if (correct_indentation == -1) correct_indentation = hard_start.indent_pos;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        // TODO(allen): Only replace spaces if we are using space based indentation.
 | 
				
			||||||
 | 
					        // TODO(allen): See if the first clause can just be removed because it's dumb.
 | 
				
			||||||
 | 
					        if (!hard_start.all_space || correct_indentation != hard_start.indent_pos){
 | 
				
			||||||
 | 
					            Buffer_Edit new_edit;
 | 
				
			||||||
 | 
					            new_edit.str_start = str_size;
 | 
				
			||||||
 | 
					            str_size += correct_indentation;
 | 
				
			||||||
 | 
					            char *str = push_array(part, char, correct_indentation);
 | 
				
			||||||
 | 
					            int32_t j = 0;
 | 
				
			||||||
 | 
					            if (opts.use_tabs){
 | 
				
			||||||
 | 
					                int32_t i = 0;
 | 
				
			||||||
 | 
					                for (; i + opts.tab_width <= correct_indentation; i += opts.tab_width) str[j++] = '\t';
 | 
				
			||||||
 | 
					                for (; i < correct_indentation; ++i) str[j++] = ' ';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else{
 | 
				
			||||||
 | 
					                for (; j < correct_indentation; ++j) str[j] = ' ';
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            new_edit.len = j;
 | 
				
			||||||
 | 
					            new_edit.start = line_start;
 | 
				
			||||||
 | 
					            new_edit.end = hard_start.char_pos;
 | 
				
			||||||
 | 
					            edits[edit_count++] = new_edit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Assert(edit_count <= edit_max);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    Cpp_Token *result = tokens.tokens + get_token.token_index;
 | 
					    result.str = str_base;
 | 
				
			||||||
 | 
					    result.str_len = str_size;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    result.edits = edits;
 | 
				
			||||||
 | 
					    result.edit_count = edit_count;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    return(result);
 | 
					    return(result);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static void
 | 
				
			||||||
 | 
					set_line_indents(Application_Links *app, Partition *part, Buffer_Summary *buffer,
 | 
				
			||||||
 | 
					                 int32_t line_start, int32_t line_end, int32_t *indent_marks, Indent_Options opts){
 | 
				
			||||||
 | 
					    Buffer_Batch_Edit batch =
 | 
				
			||||||
 | 
					        make_batch_from_indent_marks(app, part, buffer, line_start, line_end, indent_marks, opts);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (batch.edit_count > 0){
 | 
				
			||||||
 | 
					        app->buffer_batch_edit(app, buffer, batch.str, batch.str_len,
 | 
				
			||||||
 | 
					                               batch.edits, batch.edit_count, BatchEdit_PreserveTokens);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static Cpp_Token*
 | 
					static Cpp_Token*
 | 
				
			||||||
seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token,
 | 
					seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token,
 | 
				
			||||||
                              Cpp_Token_Type open_type, Cpp_Token_Type close_type){
 | 
					                              Cpp_Token_Type open_type, Cpp_Token_Type close_type){
 | 
				
			||||||
| 
						 | 
					@ -119,6 +167,91 @@ seek_matching_token_backwards(Cpp_Token_Array tokens, Cpp_Token *token,
 | 
				
			||||||
    return(token);
 | 
					    return(token);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Cpp_Token*
 | 
				
			||||||
 | 
					find_anchor_token(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens,
 | 
				
			||||||
 | 
					                  int32_t line_start, int32_t tab_width, int32_t *current_indent_out){
 | 
				
			||||||
 | 
					    Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_start);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (token != tokens.tokens){
 | 
				
			||||||
 | 
					        --token;
 | 
				
			||||||
 | 
					        for (; token > tokens.tokens; --token){
 | 
				
			||||||
 | 
					            if (!(token->flags & CPP_TFLAG_PP_BODY)){
 | 
				
			||||||
 | 
					                switch(token->type){
 | 
				
			||||||
 | 
					                    case CPP_TOKEN_BRACE_OPEN:
 | 
				
			||||||
 | 
					                    case CPP_TOKEN_BRACE_CLOSE:
 | 
				
			||||||
 | 
					                    goto out_of_loop;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        out_of_loop:;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    int32_t current_indent = 0;
 | 
				
			||||||
 | 
					    int32_t found_safe_start_position = 0;
 | 
				
			||||||
 | 
					    do{
 | 
				
			||||||
 | 
					        int32_t line = buffer_get_line_index(app, buffer, token->start);
 | 
				
			||||||
 | 
					        int32_t start = buffer_get_line_start(app, buffer, line);
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Hard_Start_Result hard_start = buffer_find_hard_start(app, buffer, start, tab_width);
 | 
				
			||||||
 | 
					        current_indent = hard_start.indent_pos;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        Cpp_Token *start_token = get_first_token_at_line(app, buffer, tokens, line);
 | 
				
			||||||
 | 
					        Cpp_Token *brace_token = token;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        if (start_token->type == CPP_TOKEN_PARENTHESE_OPEN){
 | 
				
			||||||
 | 
					            if (start_token == tokens.tokens){
 | 
				
			||||||
 | 
					                found_safe_start_position = 1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            else{
 | 
				
			||||||
 | 
					                token = start_token-1;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        else{
 | 
				
			||||||
 | 
					            int32_t close = 0;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            for (token = brace_token; token > start_token; --token){
 | 
				
			||||||
 | 
					                switch(token->type){
 | 
				
			||||||
 | 
					                    case CPP_TOKEN_PARENTHESE_CLOSE:
 | 
				
			||||||
 | 
					                    case CPP_TOKEN_BRACKET_CLOSE:
 | 
				
			||||||
 | 
					                    case CPP_TOKEN_BRACE_CLOSE:
 | 
				
			||||||
 | 
					                    close = token->type;
 | 
				
			||||||
 | 
					                    goto out_of_loop2;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					            out_of_loop2:;
 | 
				
			||||||
 | 
					            
 | 
				
			||||||
 | 
					            switch (close){
 | 
				
			||||||
 | 
					                case 0: token = start_token; found_safe_start_position = 1; break;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case CPP_TOKEN_PARENTHESE_CLOSE:
 | 
				
			||||||
 | 
					                token = seek_matching_token_backwards(tokens, token-1,
 | 
				
			||||||
 | 
					                                                      CPP_TOKEN_PARENTHESE_OPEN,
 | 
				
			||||||
 | 
					                                                      CPP_TOKEN_PARENTHESE_CLOSE);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case CPP_TOKEN_BRACKET_CLOSE:
 | 
				
			||||||
 | 
					                token = seek_matching_token_backwards(tokens, token-1,
 | 
				
			||||||
 | 
					                                                      CPP_TOKEN_BRACKET_OPEN,
 | 
				
			||||||
 | 
					                                                      CPP_TOKEN_BRACKET_CLOSE);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					                
 | 
				
			||||||
 | 
					                case CPP_TOKEN_BRACE_CLOSE:
 | 
				
			||||||
 | 
					                token = seek_matching_token_backwards(tokens, token-1,
 | 
				
			||||||
 | 
					                                                      CPP_TOKEN_BRACE_OPEN,
 | 
				
			||||||
 | 
					                                                      CPP_TOKEN_BRACE_CLOSE);
 | 
				
			||||||
 | 
					                break;
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    } while(found_safe_start_position == 0);
 | 
				
			||||||
 | 
					    *current_indent_out = current_indent;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return(token);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Indent Rules
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Indent_Parse_State{
 | 
					struct Indent_Parse_State{
 | 
				
			||||||
    int32_t current_indent;
 | 
					    int32_t current_indent;
 | 
				
			||||||
    int32_t previous_line_indent;
 | 
					    int32_t previous_line_indent;
 | 
				
			||||||
| 
						 | 
					@ -135,14 +268,7 @@ compute_this_indent(Application_Links *app, Buffer_Summary *buffer, Indent_Parse
 | 
				
			||||||
    int32_t this_indent = 0;
 | 
					    int32_t this_indent = 0;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int32_t this_line_start = buffer_get_line_start(app, buffer, line_i);
 | 
					    int32_t this_line_start = buffer_get_line_start(app, buffer, line_i);
 | 
				
			||||||
    int32_t next_line_start = 0;
 | 
					    int32_t next_line_start = buffer_get_line_start(app, buffer, line_i+1);
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (line_i+1 < buffer->line_count){
 | 
					 | 
				
			||||||
        next_line_start = buffer_get_line_start(app, buffer, line_i+1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    else{
 | 
					 | 
				
			||||||
        next_line_start = buffer->size;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    bool32 did_special_behavior = false;
 | 
					    bool32 did_special_behavior = false;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -215,134 +341,55 @@ compute_this_indent(Application_Links *app, Buffer_Summary *buffer, Indent_Parse
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int32_t*
 | 
					static int32_t*
 | 
				
			||||||
get_line_indentation_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer, Cpp_Token_Array tokens,
 | 
					get_indentation_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer,
 | 
				
			||||||
                           int32_t line_start, int32_t line_end, int32_t tab_width){
 | 
					                      Cpp_Token_Array tokens, int32_t line_start, int32_t line_end, int32_t tab_width){
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int32_t indent_mark_count = line_end - line_start;
 | 
					    int32_t indent_mark_count = line_end - line_start;
 | 
				
			||||||
    int32_t *indent_marks = push_array(part, int32_t, indent_mark_count);
 | 
					    int32_t *indent_marks = push_array(part, int32_t, indent_mark_count);
 | 
				
			||||||
    
 | 
					    // Shift the array so line_i works correctly.
 | 
				
			||||||
    Indent_Parse_State indent = {0};
 | 
					 | 
				
			||||||
    Cpp_Token *token = get_first_token_at_line(app, buffer, tokens, line_start);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    if (token != tokens.tokens){
 | 
					 | 
				
			||||||
        --token;
 | 
					 | 
				
			||||||
        for (; token > tokens.tokens; --token){
 | 
					 | 
				
			||||||
            if (!(token->flags & CPP_TFLAG_PP_BODY)){
 | 
					 | 
				
			||||||
                switch(token->type){
 | 
					 | 
				
			||||||
                    case CPP_TOKEN_BRACE_OPEN:
 | 
					 | 
				
			||||||
                    case CPP_TOKEN_BRACE_CLOSE:
 | 
					 | 
				
			||||||
                    goto out_of_loop;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        out_of_loop:;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // TODO(allen): This can maybe be it's own function now, so that we
 | 
					 | 
				
			||||||
    // can do the decls in the order we want and avoid the extra binary search.
 | 
					 | 
				
			||||||
    int32_t found_safe_start_position = 0;
 | 
					 | 
				
			||||||
    do{
 | 
					 | 
				
			||||||
        int32_t line = buffer_get_line_index(app, buffer, token->start);
 | 
					 | 
				
			||||||
        int32_t start = buffer_get_line_start(app, buffer, line);
 | 
					 | 
				
			||||||
        Hard_Start_Result hard_start = buffer_find_hard_start(app, buffer, start, tab_width);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        indent.current_indent = hard_start.indent_pos;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Cpp_Token *start_token = get_first_token_at_line(app, buffer, tokens, line);
 | 
					 | 
				
			||||||
        Cpp_Token *brace_token = token;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        if (start_token->type == CPP_TOKEN_PARENTHESE_OPEN){
 | 
					 | 
				
			||||||
            if (start_token == tokens.tokens){
 | 
					 | 
				
			||||||
                found_safe_start_position = 1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else{
 | 
					 | 
				
			||||||
                token = start_token-1;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        else{
 | 
					 | 
				
			||||||
            int32_t close = 0;
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            for (token = brace_token; token > start_token; --token){
 | 
					 | 
				
			||||||
                switch(token->type){
 | 
					 | 
				
			||||||
                    case CPP_TOKEN_PARENTHESE_CLOSE:
 | 
					 | 
				
			||||||
                    case CPP_TOKEN_BRACKET_CLOSE:
 | 
					 | 
				
			||||||
                    case CPP_TOKEN_BRACE_CLOSE:
 | 
					 | 
				
			||||||
                    close = token->type;
 | 
					 | 
				
			||||||
                    goto out_of_loop2;
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            out_of_loop2:;
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            switch (close){
 | 
					 | 
				
			||||||
                case 0: token = start_token; found_safe_start_position = 1; break;
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                case CPP_TOKEN_PARENTHESE_CLOSE:
 | 
					 | 
				
			||||||
                token = seek_matching_token_backwards(tokens, token-1,
 | 
					 | 
				
			||||||
                                                      CPP_TOKEN_PARENTHESE_OPEN,
 | 
					 | 
				
			||||||
                                                      CPP_TOKEN_PARENTHESE_CLOSE);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                case CPP_TOKEN_BRACKET_CLOSE:
 | 
					 | 
				
			||||||
                token = seek_matching_token_backwards(tokens, token-1,
 | 
					 | 
				
			||||||
                                                      CPP_TOKEN_BRACKET_OPEN,
 | 
					 | 
				
			||||||
                                                      CPP_TOKEN_BRACKET_CLOSE);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                case CPP_TOKEN_BRACE_CLOSE:
 | 
					 | 
				
			||||||
                token = seek_matching_token_backwards(tokens, token-1,
 | 
					 | 
				
			||||||
                                                      CPP_TOKEN_BRACE_OPEN,
 | 
					 | 
				
			||||||
                                                      CPP_TOKEN_BRACE_CLOSE);
 | 
					 | 
				
			||||||
                break;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
    } while(found_safe_start_position == 0);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // NOTE(allen): Shift the array so that line_i can just operate in
 | 
					 | 
				
			||||||
    // it's natural value range.
 | 
					 | 
				
			||||||
    indent_marks -= line_start;
 | 
					    indent_marks -= line_start;
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int32_t line_i = buffer_get_line_index(app, buffer, token->start);
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    if (line_i > line_start){
 | 
					    // Decide where to start indentation parsing.
 | 
				
			||||||
        line_i = line_start;
 | 
					    Indent_Parse_State indent = {0};
 | 
				
			||||||
 | 
					    Cpp_Token *token_ptr = find_anchor_token(app, buffer, tokens, line_start,
 | 
				
			||||||
 | 
					                                             tab_width, &indent.current_indent);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    int32_t line_index = buffer_get_line_index(app, buffer, token_ptr->start);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (line_index > line_start){
 | 
				
			||||||
 | 
					        line_index = line_start;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    int32_t next_line_start = buffer->size;
 | 
					    int32_t next_line_start_pos = buffer_get_line_start(app, buffer, line_index+1);
 | 
				
			||||||
    if (line_i+1 < buffer->line_count){
 | 
					 | 
				
			||||||
        next_line_start = buffer_get_line_start(app, buffer, line_i+1);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    switch (token->type){
 | 
					    switch (token_ptr->type){
 | 
				
			||||||
        case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += tab_width; break;
 | 
					        case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += tab_width; break;
 | 
				
			||||||
        case CPP_TOKEN_BRACE_OPEN: indent.current_indent += tab_width; break;
 | 
					        case CPP_TOKEN_BRACE_OPEN: indent.current_indent += tab_width; break;
 | 
				
			||||||
        case CPP_TOKEN_PARENTHESE_OPEN: indent.current_indent += tab_width; break;
 | 
					        case CPP_TOKEN_PARENTHESE_OPEN: indent.current_indent += tab_width; break;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    indent.previous_line_indent = indent.current_indent;
 | 
					    indent.previous_line_indent = indent.current_indent;
 | 
				
			||||||
    Cpp_Token T;
 | 
					 | 
				
			||||||
    Cpp_Token prev_token = *token;
 | 
					 | 
				
			||||||
    ++token;
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    for (; line_i < line_end; ++token){
 | 
					    for (;line_index < line_end;){
 | 
				
			||||||
        if (token < tokens.tokens + tokens.count){
 | 
					        Cpp_Token prev_token = *token_ptr;
 | 
				
			||||||
            T = *token;
 | 
					        Cpp_Token token;
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
 | 
					        ++token_ptr;
 | 
				
			||||||
 | 
					        if (token_ptr < tokens.tokens + tokens.count){
 | 
				
			||||||
 | 
					            token = *token_ptr;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        else{
 | 
					        else{
 | 
				
			||||||
            T.type = CPP_TOKEN_EOF;
 | 
					            token.type = CPP_TOKEN_EOF;
 | 
				
			||||||
            T.start = buffer->size;
 | 
					            token.start = buffer->size;
 | 
				
			||||||
            T.flags = 0;
 | 
					            token.flags = 0;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        for (; T.start >= next_line_start && line_i < line_end;){
 | 
					        for (;token.start >= next_line_start_pos && line_index < line_end;){
 | 
				
			||||||
            if (line_i+1 < buffer->line_count){
 | 
					            next_line_start_pos = buffer_get_line_start(app, buffer, line_index+1);
 | 
				
			||||||
                next_line_start = buffer_get_line_start(app, buffer, line_i+1);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else{
 | 
					 | 
				
			||||||
                next_line_start = buffer->size;
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            int32_t this_indent =
 | 
					            int32_t this_indent =
 | 
				
			||||||
                compute_this_indent(app, buffer, indent, T, prev_token, line_i, tab_width);
 | 
					                compute_this_indent(app, buffer, indent, token, prev_token, line_index, tab_width);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            // NOTE(allen): Rebase the paren anchor if the first token
 | 
					            // NOTE(allen): Rebase the paren anchor if the first token
 | 
				
			||||||
            // after an open paren is on the next line.
 | 
					            // after an open paren is on the next line.
 | 
				
			||||||
| 
						 | 
					@ -356,15 +403,16 @@ get_line_indentation_marks(Application_Links *app, Partition *part, Buffer_Summa
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            if (line_i >= line_start){
 | 
					            if (line_index >= line_start){
 | 
				
			||||||
                indent_marks[line_i] = this_indent;
 | 
					                indent_marks[line_index] = this_indent;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            ++line_i;
 | 
					            ++line_index;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            indent.previous_line_indent = this_indent;
 | 
					            indent.previous_line_indent = this_indent;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        switch (T.type){
 | 
					        // Update indent state.
 | 
				
			||||||
 | 
					        switch (token.type){
 | 
				
			||||||
            case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += 4; break;
 | 
					            case CPP_TOKEN_BRACKET_OPEN: indent.current_indent += 4; break;
 | 
				
			||||||
            case CPP_TOKEN_BRACKET_CLOSE: indent.current_indent -= 4; break;
 | 
					            case CPP_TOKEN_BRACKET_CLOSE: indent.current_indent -= 4; break;
 | 
				
			||||||
            case CPP_TOKEN_BRACE_OPEN: indent.current_indent += 4; break;
 | 
					            case CPP_TOKEN_BRACE_OPEN: indent.current_indent += 4; break;
 | 
				
			||||||
| 
						 | 
					@ -372,18 +420,18 @@ get_line_indentation_marks(Application_Links *app, Partition *part, Buffer_Summa
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            case CPP_TOKEN_COMMENT:
 | 
					            case CPP_TOKEN_COMMENT:
 | 
				
			||||||
            {
 | 
					            {
 | 
				
			||||||
                int32_t line = buffer_get_line_index(app, buffer, T.start);
 | 
					                int32_t line = buffer_get_line_index(app, buffer, token.start);
 | 
				
			||||||
                int32_t start = buffer_get_line_start(app, buffer, line);
 | 
					                int32_t start = buffer_get_line_start(app, buffer, line);
 | 
				
			||||||
                
 | 
					                
 | 
				
			||||||
                indent.comment_shift = (indent.current_indent - (T.start - start));
 | 
					                indent.comment_shift = (indent.current_indent - (token.start - start));
 | 
				
			||||||
            }break;
 | 
					            }break;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            case CPP_TOKEN_PARENTHESE_OPEN:
 | 
					            case CPP_TOKEN_PARENTHESE_OPEN:
 | 
				
			||||||
            if (!(T.flags & CPP_TFLAG_PP_BODY)){
 | 
					            if (!(token.flags & CPP_TFLAG_PP_BODY)){
 | 
				
			||||||
                if (indent.paren_nesting < ArrayCount(indent.paren_anchor_indent)){
 | 
					                if (indent.paren_nesting < ArrayCount(indent.paren_anchor_indent)){
 | 
				
			||||||
                    int32_t line = buffer_get_line_index(app, buffer, T.start);
 | 
					                    int32_t line = buffer_get_line_index(app, buffer, token.start);
 | 
				
			||||||
                    int32_t start = buffer_get_line_start(app, buffer, line);
 | 
					                    int32_t start = buffer_get_line_start(app, buffer, line);
 | 
				
			||||||
                    int32_t char_pos = T.start - start;
 | 
					                    int32_t char_pos = token.start - start;
 | 
				
			||||||
                    
 | 
					                    
 | 
				
			||||||
                    Hard_Start_Result hard_start =
 | 
					                    Hard_Start_Result hard_start =
 | 
				
			||||||
                        buffer_find_hard_start(app, buffer, start, tab_width);
 | 
					                        buffer_find_hard_start(app, buffer, start, tab_width);
 | 
				
			||||||
| 
						 | 
					@ -398,126 +446,31 @@ get_line_indentation_marks(Application_Links *app, Partition *part, Buffer_Summa
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            case CPP_TOKEN_PARENTHESE_CLOSE:
 | 
					            case CPP_TOKEN_PARENTHESE_CLOSE:
 | 
				
			||||||
            if (!(T.flags & CPP_TFLAG_PP_BODY)){
 | 
					            if (!(token.flags & CPP_TFLAG_PP_BODY)){
 | 
				
			||||||
                --indent.paren_nesting;
 | 
					                --indent.paren_nesting;
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        prev_token = T;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    // NOTE(allen): Unshift the indent_marks array so that the return value
 | 
					    // Unshift the indent_marks array.
 | 
				
			||||||
    // is the exact starting point of the array that was actually allocated.
 | 
					 | 
				
			||||||
    indent_marks += line_start;
 | 
					    indent_marks += line_start;
 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    return(indent_marks);
 | 
					    return(indent_marks);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
struct Make_Batch_Result{
 | 
					 | 
				
			||||||
    char *str_base;
 | 
					 | 
				
			||||||
    int32_t str_size;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Buffer_Edit *edits;
 | 
					 | 
				
			||||||
    int32_t edit_max;
 | 
					 | 
				
			||||||
    int32_t edit_count;
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static Make_Batch_Result
 | 
					 | 
				
			||||||
make_batch_from_indent_marks(Application_Links *app, Partition *part, Buffer_Summary *buffer,
 | 
					 | 
				
			||||||
                             int32_t line_start, int32_t line_end, int32_t *indent_marks, Indent_Options opts){
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Make_Batch_Result result = {0};
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    int32_t edit_max = line_end - line_start;
 | 
					 | 
				
			||||||
    int32_t edit_count = 0;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Buffer_Edit *edits = push_array(part, Buffer_Edit, edit_max);
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    char *str_base = (char*)part->base + part->pos;
 | 
					 | 
				
			||||||
    int32_t str_size = 0;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    // NOTE(allen): Shift the array so that line_i can just operate in
 | 
					 | 
				
			||||||
    // it's natural value range.
 | 
					 | 
				
			||||||
    indent_marks -= line_start;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    for (int32_t line_i = line_start; line_i < line_end; ++line_i){
 | 
					 | 
				
			||||||
        int32_t line_start = buffer_get_line_start(app, buffer, line_i);
 | 
					 | 
				
			||||||
        Hard_Start_Result hard_start = 
 | 
					 | 
				
			||||||
            buffer_find_hard_start(app, buffer, line_start, opts.tab_width);
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        int32_t correct_indentation = indent_marks[line_i];
 | 
					 | 
				
			||||||
        if (hard_start.all_whitespace && opts.empty_blank_lines) correct_indentation = 0;
 | 
					 | 
				
			||||||
        if (correct_indentation == -1) correct_indentation = hard_start.indent_pos;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        // TODO(allen): Only replace spaces if we are using space based indentation.
 | 
					 | 
				
			||||||
        // TODO(allen): See if the first clause can just be removed because it's dumb.
 | 
					 | 
				
			||||||
        if ((hard_start.all_whitespace && hard_start.char_pos > line_start) ||
 | 
					 | 
				
			||||||
            !hard_start.all_space || correct_indentation != hard_start.indent_pos){
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            Buffer_Edit new_edit;
 | 
					 | 
				
			||||||
            new_edit.str_start = str_size;
 | 
					 | 
				
			||||||
            str_size += correct_indentation;
 | 
					 | 
				
			||||||
            char *str = push_array(part, char, correct_indentation);
 | 
					 | 
				
			||||||
            int32_t j = 0;
 | 
					 | 
				
			||||||
            if (opts.use_tabs){
 | 
					 | 
				
			||||||
                int32_t i = 0;
 | 
					 | 
				
			||||||
                for (; i + opts.tab_width <= correct_indentation; i += opts.tab_width) str[j++] = '\t';
 | 
					 | 
				
			||||||
                for (; i < correct_indentation; ++i) str[j++] = ' ';
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else{
 | 
					 | 
				
			||||||
                for (; j < correct_indentation; ++j) str[j] = ' ';
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            new_edit.len = j;
 | 
					 | 
				
			||||||
            new_edit.start = line_start;
 | 
					 | 
				
			||||||
            new_edit.end = hard_start.char_pos;
 | 
					 | 
				
			||||||
            edits[edit_count++] = new_edit;
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Assert(edit_count <= edit_max);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    result.str_base = str_base;
 | 
					 | 
				
			||||||
    result.str_size = str_size;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    result.edits = edits;
 | 
					 | 
				
			||||||
    result.edit_max = edit_max;
 | 
					 | 
				
			||||||
    result.edit_count = edit_count;
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    return(result);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
static bool32
 | 
					static bool32
 | 
				
			||||||
buffer_auto_indent(Application_Links *app, Partition *part, Buffer_Summary *buffer,
 | 
					buffer_auto_indent(Application_Links *app, Partition *part, Buffer_Summary *buffer,
 | 
				
			||||||
                   int32_t start, int32_t end, int32_t tab_width, Auto_Indent_Flag flags)/*
 | 
					                   int32_t start, int32_t end, int32_t tab_width, Auto_Indent_Flag flags){
 | 
				
			||||||
DOC_PARAM(buffer, The buffer specifies the buffer in which to apply auto indentation.)
 | 
					 | 
				
			||||||
DOC_PARAM(start, This parameter specifies the absolute position of the start of the indentation range.)
 | 
					 | 
				
			||||||
DOC_PARAM(end, This parameter specifies the absolute position of the end of the indentation range.)
 | 
					 | 
				
			||||||
DOC_PARAM(tab_width, The tab_width parameter specifies how many spaces should be used for one indentation in space mode.)
 | 
					 | 
				
			||||||
DOC_PARAM(flags, This parameter specifies behaviors for the indentation.)
 | 
					 | 
				
			||||||
DOC_RETURN(This call returns non-zero when the call succeeds.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DOC(Applies the built in auto-indentation rule to the code in the range 
 | 
					 | 
				
			||||||
from start to end by inserting spaces or tabs at the beginning of the
 | 
					 | 
				
			||||||
lines. If the buffer does not have lexing enabled or the lexing job has
 | 
					 | 
				
			||||||
not completed this function will fail.)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
DOC_SEE(Auto_Indent_Flag)
 | 
					 | 
				
			||||||
DOC_SEE(4coder_Buffer_Positioning_System)
 | 
					 | 
				
			||||||
*/{
 | 
					 | 
				
			||||||
    
 | 
					 | 
				
			||||||
    Indent_Options opts = {0};
 | 
					 | 
				
			||||||
    
 | 
					    
 | 
				
			||||||
    bool32 result = 0;
 | 
					    bool32 result = 0;
 | 
				
			||||||
    if (buffer->exists && buffer->tokens_are_ready){
 | 
					    if (buffer->exists && buffer->tokens_are_ready){
 | 
				
			||||||
        result = 1;
 | 
					        result = 1;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        opts.empty_blank_lines = (flags & AutoIndent_ClearLine);
 | 
					 | 
				
			||||||
        opts.use_tabs = (flags & AutoIndent_UseTab);
 | 
					 | 
				
			||||||
        opts.tab_width = tab_width;
 | 
					 | 
				
			||||||
        
 | 
					 | 
				
			||||||
        Temp_Memory temp = begin_temp_memory(part);
 | 
					        Temp_Memory temp = begin_temp_memory(part);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // TODO(allen): Only read in the tokens in the range we need.
 | 
					        // Stage 1: Setup
 | 
				
			||||||
 | 
					        //  Read the tokens to be used for indentation.
 | 
				
			||||||
 | 
					        //  Get the first and last lines to indent.
 | 
				
			||||||
        Cpp_Token_Array tokens;
 | 
					        Cpp_Token_Array tokens;
 | 
				
			||||||
        tokens.count = app->buffer_token_count(app, buffer);
 | 
					        tokens.count = app->buffer_token_count(app, buffer);
 | 
				
			||||||
        tokens.max_count = tokens.count;
 | 
					        tokens.max_count = tokens.count;
 | 
				
			||||||
| 
						 | 
					@ -525,19 +478,21 @@ DOC_SEE(4coder_Buffer_Positioning_System)
 | 
				
			||||||
        app->buffer_read_tokens(app, buffer, 0, tokens.count, tokens.tokens);
 | 
					        app->buffer_read_tokens(app, buffer, 0, tokens.count, tokens.tokens);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        int32_t line_start = buffer_get_line_index(app, buffer, start);
 | 
					        int32_t line_start = buffer_get_line_index(app, buffer, start);
 | 
				
			||||||
        int32_t line_end = buffer_get_line_index(app, buffer, end);
 | 
					        int32_t line_end = buffer_get_line_index(app, buffer, end) + 1;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
 | 
					        // Stage 2: Decide Indent Amounts
 | 
				
			||||||
 | 
					        //  Get an array representing how much each line in [line_start,line_end]
 | 
				
			||||||
 | 
					        //   should be indented.
 | 
				
			||||||
        int32_t *indent_marks =
 | 
					        int32_t *indent_marks =
 | 
				
			||||||
            get_line_indentation_marks(app, part, buffer, tokens,
 | 
					            get_indentation_marks(app, part, buffer, tokens, line_start, line_end, tab_width);
 | 
				
			||||||
                                       line_start, line_end, opts.tab_width);
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        Make_Batch_Result batch =
 | 
					        // Stage 3: Set the Line Indents
 | 
				
			||||||
            make_batch_from_indent_marks(app, part, buffer, line_start, line_end, indent_marks, opts);
 | 
					        Indent_Options opts = {0};
 | 
				
			||||||
 | 
					        opts.empty_blank_lines = (flags & AutoIndent_ClearLine);
 | 
				
			||||||
 | 
					        opts.use_tabs = (flags & AutoIndent_UseTab);
 | 
				
			||||||
 | 
					        opts.tab_width = tab_width;
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        if (batch.edit_count > 0){
 | 
					        set_line_indents(app, part, buffer, line_start, line_end, indent_marks, opts);
 | 
				
			||||||
            app->buffer_batch_edit(app, buffer, batch.str_base, batch.str_size,
 | 
					 | 
				
			||||||
                                   batch.edits, batch.edit_count, BatchEdit_PreserveTokens);
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        end_temp_memory(temp);
 | 
					        end_temp_memory(temp);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -547,6 +547,46 @@ buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_Summary *
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// Some Basic Buffer Positioning
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#include "4cpp_lexer.h"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int32_t
 | 
				
			||||||
 | 
					buffer_get_line_start(Application_Links *app, Buffer_Summary *buffer, int32_t line){
 | 
				
			||||||
 | 
					    Partial_Cursor partial_cursor;
 | 
				
			||||||
 | 
					    int32_t result = buffer->size;
 | 
				
			||||||
 | 
					    if (line < buffer->line_count){
 | 
				
			||||||
 | 
					        app->buffer_compute_cursor(app, buffer, seek_line_char(line, 1), &partial_cursor);
 | 
				
			||||||
 | 
					        result = partial_cursor.pos;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static int32_t
 | 
				
			||||||
 | 
					buffer_get_line_index(Application_Links *app, Buffer_Summary *buffer, int32_t pos){
 | 
				
			||||||
 | 
					    Partial_Cursor partial_cursor;
 | 
				
			||||||
 | 
					    app->buffer_compute_cursor(app, buffer, seek_pos(pos), &partial_cursor);
 | 
				
			||||||
 | 
					    return(partial_cursor.line);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					static Cpp_Token*
 | 
				
			||||||
 | 
					get_first_token_at_line(Application_Links *app, Buffer_Summary *buffer, Cpp_Token_Array tokens, int32_t line){
 | 
				
			||||||
 | 
					    int32_t line_start = buffer_get_line_start(app, buffer, line);
 | 
				
			||||||
 | 
					    Cpp_Get_Token_Result get_token = cpp_get_token(&tokens, line_start);
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    if (get_token.in_whitespace){
 | 
				
			||||||
 | 
					        get_token.token_index += 1;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    Cpp_Token *result = tokens.tokens + get_token.token_index;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    return(result);
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Fundamental Editing
 | 
					// Fundamental Editing
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -123,15 +123,6 @@ ENUM(int32_t, Event_Message_Type_ID){
 | 
				
			||||||
    EventMessage_CloseView
 | 
					    EventMessage_CloseView
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* DOC(A Buffer_Batch_Edit_Type is a type of batch operation.) */
 | 
					 | 
				
			||||||
ENUM(int32_t, Buffer_Batch_Edit_Type){
 | 
					 | 
				
			||||||
    /* DOC(The BatchEdit_Normal operation is always correct but does the most work.) */
 | 
					 | 
				
			||||||
    BatchEdit_Normal,
 | 
					 | 
				
			||||||
    /* DOC(The BatchEdit_PreserveTokens operation is one in which none of the edits add, delete, or change any tokens.
 | 
					 | 
				
			||||||
    This usually applies when whitespace is being replaced with whitespace.) */
 | 
					 | 
				
			||||||
    BatchEdit_PreserveTokens
 | 
					 | 
				
			||||||
};
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* DOC(A Buffer_Setting_ID names a setting in a buffer.) */
 | 
					/* DOC(A Buffer_Setting_ID names a setting in a buffer.) */
 | 
				
			||||||
ENUM(int32_t, Buffer_Setting_ID){
 | 
					ENUM(int32_t, Buffer_Setting_ID){
 | 
				
			||||||
    /* DOC(BufferSetting_Null is not a valid setting, it is reserved to detect errors.) */
 | 
					    /* DOC(BufferSetting_Null is not a valid setting, it is reserved to detect errors.) */
 | 
				
			||||||
| 
						 | 
					@ -702,14 +693,41 @@ struct Event_Message{
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* 
 | 
					/* 
 | 
				
			||||||
DOC(Theme_Color stores a style tag/color pair, for the purpose of setting and getting colors in the theme .)
 | 
					DOC(Theme_Color stores a style tag/color pair, for the purpose of setting and getting colors in the theme.)
 | 
				
			||||||
DOC_SEE(Style_Tag)
 | 
					DOC_SEE(Style_Tag)
 | 
				
			||||||
DOC_SEE(int_color)
 | 
					DOC_SEE(int_color)
 | 
				
			||||||
*/
 | 
					*/
 | 
				
			||||||
struct Theme_Color{
 | 
					struct Theme_Color{
 | 
				
			||||||
 | 
					    /* DOC(The style slot in the style palette.) */
 | 
				
			||||||
    Style_Tag tag;
 | 
					    Style_Tag tag;
 | 
				
			||||||
 | 
					    /* DOC(The color in the slot.) */
 | 
				
			||||||
    int_color color;
 | 
					    int_color color;
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* DOC(A Buffer_Batch_Edit_Type is a type of batch operation.) */
 | 
				
			||||||
 | 
					ENUM(int32_t, Buffer_Batch_Edit_Type){
 | 
				
			||||||
 | 
					    /* DOC(The BatchEdit_Normal operation is always correct but does the most work if there are tokens to correct.) */
 | 
				
			||||||
 | 
					    BatchEdit_Normal,
 | 
				
			||||||
 | 
					    /* DOC(The BatchEdit_PreserveTokens operation is one in which none of the edits add, delete, or change any tokens.
 | 
				
			||||||
 | 
					    This usually applies when whitespace is being replaced with whitespace.) */
 | 
				
			||||||
 | 
					    BatchEdit_PreserveTokens
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/*
 | 
				
			||||||
 | 
					DOC(This struct is used to bundle the parameters of the buffer_batch_edit function.  It is convenient
 | 
				
			||||||
 | 
					for a few functions that return a batch edit to the user.)
 | 
				
			||||||
 | 
					DOC_SEE(buffer_batch_edit)
 | 
				
			||||||
 | 
					*/
 | 
				
			||||||
 | 
					struct Buffer_Batch_Edit{
 | 
				
			||||||
 | 
					    /* DOC(The pointer to the edit string buffer.) */
 | 
				
			||||||
 | 
					    char *str;
 | 
				
			||||||
 | 
					    /* DOC(The length of the edit string buffer.) */
 | 
				
			||||||
 | 
					    int32_t str_len;
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    /* DOC(The array of edits to be applied.) */
 | 
				
			||||||
 | 
					    Buffer_Edit *edits;
 | 
				
			||||||
 | 
					    /* DOC(The number of edits in the array.) */
 | 
				
			||||||
 | 
					    int32_t edit_count;
 | 
				
			||||||
 | 
					};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -1295,10 +1295,10 @@ in the system, the call will fail.)
 | 
				
			||||||
            Assert(panel_ptr != panel);
 | 
					            Assert(panel_ptr != panel);
 | 
				
			||||||
            active = (i32)(panel_ptr - models->layout.panels);
 | 
					            active = (i32)(panel_ptr - models->layout.panels);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					        Assert(active != -1 && panel != models->layout.panels + active);
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
        // If the panel we're closing was previously active, we have to switch to it's sibling.
 | 
					        // If the panel we're closing was previously active, we have to switch to it's sibling.
 | 
				
			||||||
        if (models->layout.active_panel == (i32)(panel - models->layout.panels)){
 | 
					        if (models->layout.active_panel == (i32)(panel - models->layout.panels)){
 | 
				
			||||||
            Assert(active != -1 && panel != models->layout.panels + active);
 | 
					 | 
				
			||||||
            models->layout.active_panel = active;
 | 
					            models->layout.active_panel = active;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        
 | 
					        
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
| 
						 | 
					@ -5123,26 +5123,6 @@ draw_file_bar(Render_Target *target, View *view, Editing_File *file, i32_Rect re
 | 
				
			||||||
                append_ss(&bar_text, make_lit_string(" nix"));
 | 
					                append_ss(&bar_text, make_lit_string(" nix"));
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            append_ss(&bar_text, make_lit_string(" -"));
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            Command_Map *map = view->map;
 | 
					 | 
				
			||||||
            if (map == &models->map_top){
 | 
					 | 
				
			||||||
                append_ss(&bar_text, make_lit_string(" global"));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if (map == &models->map_file){
 | 
					 | 
				
			||||||
                append_ss(&bar_text, make_lit_string(" file"));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else if (map == &models->map_ui){
 | 
					 | 
				
			||||||
                append_ss(&bar_text, make_lit_string(" gui"));
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            else{
 | 
					 | 
				
			||||||
                i32 map_index = (i32)(view->map - models->user_maps);
 | 
					 | 
				
			||||||
                i32 map_id = models->map_id_table[map_index];
 | 
					 | 
				
			||||||
                
 | 
					 | 
				
			||||||
                append_ss        (&bar_text, make_lit_string(" user:"));
 | 
					 | 
				
			||||||
                append_int_to_str(&bar_text, map_id);
 | 
					 | 
				
			||||||
            }
 | 
					 | 
				
			||||||
            
 | 
					 | 
				
			||||||
            intbar_draw_string(target, &bar, bar_text, base_color);
 | 
					            intbar_draw_string(target, &bar, bar_text, base_color);
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
            
 | 
					            
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										24
									
								
								TODO.txt
								
								
								
								
							
							
						
						
									
										24
									
								
								TODO.txt
								
								
								
								
							| 
						 | 
					@ -82,30 +82,32 @@
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; BEFORE I SHIP
 | 
					; BEFORE I SHIP
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					; [X] killing compilation panel changes active panel
 | 
				
			||||||
; [X] tokens in the custom API
 | 
					; [X] tokens in the custom API
 | 
				
			||||||
;     [X] token seeking on custom side
 | 
					;     [X] token seeking on custom side
 | 
				
			||||||
;     [X] auto indent on the custom side
 | 
					;     [X] auto indent on the custom side
 | 
				
			||||||
;         [] clean up and comment the auto indent code to allow for customizations
 | 
					;         [] clean up and comment the auto indent code to allow for customizations
 | 
				
			||||||
;         [] more built in options for auto indenting
 | 
					;         [] more built in options for auto indenting
 | 
				
			||||||
; [] expose dirty flags
 | 
					; [] expose dirty flags
 | 
				
			||||||
; [] option to not open *messages* every startup
 | 
					 | 
				
			||||||
; [] commands for resizing panels
 | 
					 | 
				
			||||||
; [] make panel resizing not whacky with child panels
 | 
					; [] make panel resizing not whacky with child panels
 | 
				
			||||||
; [] killing compilation panel changes active panel
 | 
					 | 
				
			||||||
; [] control over how mouse effects panel focus
 | 
					 | 
				
			||||||
; [] API docs as text file
 | 
					 | 
				
			||||||
; [] user file bar string
 | 
					 | 
				
			||||||
; [] mouse down/up distinction
 | 
					; [] mouse down/up distinction
 | 
				
			||||||
; [] hook on exit
 | 
					; [] hook on exit
 | 
				
			||||||
; [] read only files
 | 
					 | 
				
			||||||
; [] occasionally missing the (!) mark on files on windows
 | 
					; [] occasionally missing the (!) mark on files on windows
 | 
				
			||||||
; [] case insensitive interactive switch buffer
 | 
					; [] case insensitive interactive switch buffer
 | 
				
			||||||
; [] option to hide hidden files
 | 
					 | 
				
			||||||
; [] tab to complete folder names in the new file dialogue
 | 
					 | 
				
			||||||
; [] view fails to follow cursor when the view is shrunk
 | 
					 | 
				
			||||||
; [] view fails to follow cursor after deleting long line
 | 
					 | 
				
			||||||
; [] scroll down on compilation buffer durring compilation
 | 
					; [] scroll down on compilation buffer durring compilation
 | 
				
			||||||
;
 | 
					;
 | 
				
			||||||
 | 
					;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					; [] commands for resizing panels
 | 
				
			||||||
 | 
					; [] user file bar string
 | 
				
			||||||
 | 
					; [] option to not open *messages* every startup
 | 
				
			||||||
 | 
					; [] API docs as text file
 | 
				
			||||||
 | 
					; [] read only files
 | 
				
			||||||
 | 
					; [] tab to complete folder names in the new file dialogue
 | 
				
			||||||
 | 
					; [] option to hide hidden files
 | 
				
			||||||
 | 
					; [] view fails to follow cursor when the view is shrunk
 | 
				
			||||||
 | 
					; [] view fails to follow cursor after deleting long line
 | 
				
			||||||
 | 
					; [] control over how mouse effects panel focus
 | 
				
			||||||
 | 
					
 | 
				
			||||||
; TODOS
 | 
					; TODOS
 | 
				
			||||||
; [X] success message when compiler works
 | 
					; [X] success message when compiler works
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue