Indent next line only on hitting enter
This commit is contained in:
parent
5aebe18778
commit
24c8370f75
|
@ -437,14 +437,84 @@ CUSTOM_DOC("Auto-indents the range between the cursor and the mark.")
|
|||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
|
||||
function i64
|
||||
get_line_indent_level(Application_Links *app, View_ID view, Buffer_ID buffer, i64 line)
|
||||
{
|
||||
Scratch_Block scratch(app);
|
||||
|
||||
String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line);
|
||||
i64 line_start_pos = get_line_start_pos(app, buffer, line);
|
||||
|
||||
Range_i64 line_indent_range = Ii64(0, 0);
|
||||
i64 tabs_at_beginning = 0;
|
||||
i64 spaces_at_beginning = 0;
|
||||
for(u64 i = 0; i < line_string.size; i += 1)
|
||||
{
|
||||
if(line_string.str[i] == '\t')
|
||||
{
|
||||
tabs_at_beginning += 1;
|
||||
}
|
||||
else if(character_is_whitespace(line_string.str[i]))
|
||||
{
|
||||
spaces_at_beginning += 1;
|
||||
}
|
||||
else if(!character_is_whitespace(line_string.str[i]))
|
||||
{
|
||||
line_indent_range.max = (i64)i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// NOTE(PS): This is in the event that we are unindenting a line that
|
||||
// is JUST tabs or spaces - rather than unindenting nothing
|
||||
// and then reindenting the proper amount, this should cause
|
||||
// the removal of all leading tabs and spaces on an otherwise
|
||||
// empty line
|
||||
bool place_cursor_at_end = false;
|
||||
if (line_indent_range.max == 0 && line_string.size > 0)
|
||||
{
|
||||
line_indent_range.max = line_string.size;
|
||||
place_cursor_at_end = true;
|
||||
}
|
||||
|
||||
Range_i64 indent_range =
|
||||
{
|
||||
line_indent_range.min + line_start_pos,
|
||||
line_indent_range.max + line_start_pos,
|
||||
};
|
||||
|
||||
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||
i64 spaces_per_indent_level = indent_width;
|
||||
i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning;
|
||||
|
||||
return indent_level;
|
||||
}
|
||||
|
||||
function String_Const_u8
|
||||
get_indent_string(Application_Links* app, Arena* scratch)
|
||||
{
|
||||
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
|
||||
String_Const_u8 result;
|
||||
if (indent_with_tabs) {
|
||||
result = string_u8_litexpr("\t");
|
||||
} else {
|
||||
result = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
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");
|
||||
Scratch_Block scratch(app);
|
||||
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;
|
||||
b32 only_indent_next_line = true;
|
||||
b32 is_newline = false;
|
||||
for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){
|
||||
switch (insert.str[i]){
|
||||
case ';': case ':':
|
||||
|
@ -452,16 +522,30 @@ CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if a
|
|||
case '(': case ')':
|
||||
case '[': case ']':
|
||||
case '#':
|
||||
case '\n': case '\t':
|
||||
{
|
||||
do_auto_indent = true;
|
||||
}break;
|
||||
case '\n': case '\t':
|
||||
{
|
||||
do_auto_indent = true;
|
||||
is_newline = 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);
|
||||
|
||||
String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer);
|
||||
String_Const_u8 ext = string_file_extension(file_name);
|
||||
if (string_match(ext, string_u8_litexpr("js")) ||
|
||||
string_match(ext, string_u8_litexpr("css")))
|
||||
{
|
||||
only_indent_next_line = do_auto_indent;
|
||||
}
|
||||
|
||||
if (do_auto_indent){
|
||||
History_Group group = history_group_begin(app, buffer);
|
||||
Range_i64 pos = {};
|
||||
if (view_has_highlighted_range(app, view)){
|
||||
pos = get_view_range(app, view);
|
||||
|
@ -473,11 +557,29 @@ CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if a
|
|||
write_text_input(app);
|
||||
|
||||
i64 end_pos = view_get_cursor_pos(app, view);
|
||||
if (!only_indent_next_line) {
|
||||
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 if (only_indent_next_line && is_newline) {
|
||||
String_Const_u8 indent_string = get_indent_string(app, scratch);
|
||||
|
||||
// getting the indent from the PREVIOUS line, not the line
|
||||
// the cursor is about to be on - since that line is new,
|
||||
// and therefore, empty
|
||||
i64 line = get_line_number_from_pos(app, buffer, pos.min);
|
||||
i64 indent_level = get_line_indent_level(app, view, buffer, line);
|
||||
|
||||
pos.min = pos.max = end_pos;
|
||||
|
||||
for(i64 i = 0; i < indent_level; i += 1)
|
||||
{
|
||||
buffer_replace_range(app, buffer, Ii64(pos.max), indent_string);
|
||||
}
|
||||
move_past_lead_whitespace(app, view, buffer);
|
||||
}
|
||||
history_group_end(group);
|
||||
}
|
||||
else{
|
||||
write_text_input(app);
|
||||
|
|
|
@ -555,7 +555,7 @@ static Command_Metadata fcoder_metacmd_table[269] = {
|
|||
{ 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, "C:\\projects\\4coder_gs\\code\\custom\\4coder_combined_write_commands.cpp", 68, 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, "C:\\projects\\4coder_gs\\code\\custom\\4coder_combined_write_commands.cpp", 68, 88 },
|
||||
{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "C:\\projects\\4coder_gs\\code\\custom\\4coder_base_commands.cpp", 58, 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, "C:\\projects\\4coder_gs\\code\\custom\\4coder_auto_indent.cpp", 56, 440 },
|
||||
{ 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, "C:\\projects\\4coder_gs\\code\\custom\\4coder_auto_indent.cpp", 56, 507 },
|
||||
{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "C:\\projects\\4coder_gs\\code\\custom\\4coder_base_commands.cpp", 58, 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, "C:\\projects\\4coder_gs\\code\\custom\\4coder_combined_write_commands.cpp", 68, 76 },
|
||||
{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "C:\\projects\\4coder_gs\\code\\custom\\4coder_base_commands.cpp", 58, 73 },
|
||||
|
|
Loading…
Reference in New Issue