properly implement until_end_of_word
parent
16fbbebb58
commit
6af75f364d
|
@ -152,19 +152,32 @@ iterate_file_buffer_until_reverse :: proc(it: ^FileBufferIter, until_proc: Until
|
|||
for until_proc(it, iterate_file_buffer_reverse) {}
|
||||
}
|
||||
|
||||
iterate_peek :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> (character: u8, peek_it: FileBufferIter, cond: bool) {
|
||||
peek_it = it^;
|
||||
character, _, cond = iter_proc(&peek_it);
|
||||
if !cond {
|
||||
return character, peek_it, cond;
|
||||
}
|
||||
|
||||
character = get_character_at_iter(peek_it);
|
||||
return character, peek_it, cond;
|
||||
}
|
||||
|
||||
until_non_whitespace :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
before_it := it^;
|
||||
|
||||
if character, _, cond := iter_proc(it); cond && strings.is_space(rune(character)) {
|
||||
return cond;
|
||||
}
|
||||
|
||||
it^ = before_it;
|
||||
return false;
|
||||
}
|
||||
|
||||
until_before_non_whitespace :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
peek_it := it^;
|
||||
if character, _, cond := iter_proc(&peek_it); cond && strings.is_space(rune(character)) {
|
||||
if character, peek_it, cond := iterate_peek(it, iter_proc); cond && strings.is_space(rune(character)) {
|
||||
it^ = peek_it;
|
||||
return cond;
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
|
@ -173,11 +186,13 @@ until_before_non_whitespace :: proc(it: ^FileBufferIter, iter_proc: IterProc) ->
|
|||
until_non_alpha_num :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
// TODO: make this global
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
before_it := it^;
|
||||
|
||||
if character, _, cond := iter_proc(it); cond && strings.ascii_set_contains(set, character) {
|
||||
return cond;
|
||||
}
|
||||
|
||||
it^ = before_it;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -185,8 +200,7 @@ until_before_non_alpha_num :: proc(it: ^FileBufferIter, iter_proc: IterProc) ->
|
|||
// TODO: make this global
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
|
||||
peek_it := it^;
|
||||
if character, _, cond := iter_proc(&peek_it); cond && strings.ascii_set_contains(set, character) {
|
||||
if character, peek_it, cond := iterate_peek(it, iter_proc); cond && strings.ascii_set_contains(set, character) {
|
||||
it^ = peek_it;
|
||||
return cond;
|
||||
}
|
||||
|
@ -196,25 +210,53 @@ until_before_non_alpha_num :: proc(it: ^FileBufferIter, iter_proc: IterProc) ->
|
|||
|
||||
until_alpha_num :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
before_it := it^;
|
||||
|
||||
if character, _, cond := iter_proc(it); cond && !strings.ascii_set_contains(set, character) {
|
||||
return cond;
|
||||
}
|
||||
|
||||
it^ = before_it;
|
||||
return false;
|
||||
}
|
||||
|
||||
until_before_alpha_num :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
|
||||
if character, peek_it, cond := iterate_peek(it, iter_proc); cond && !strings.ascii_set_contains(set, character) {
|
||||
it^ = peek_it;
|
||||
return cond;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
until_before_alpha_num_or_whitespace :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
|
||||
if character, peek_it, cond := iterate_peek(it, iter_proc); cond && (!strings.ascii_set_contains(set, character) && !strings.is_space(rune(character))) {
|
||||
it^ = peek_it;
|
||||
return cond;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
until_start_of_word :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
|
||||
// if not already on a word, iterate until non-whitespace
|
||||
if character, _, cond := iter_proc(it); cond && (!strings.ascii_set_contains(set, character) && !strings.is_space(rune(character))) {
|
||||
for until_before_non_whitespace(it, iter_proc) {}
|
||||
// if on a symbol go to next symbol or word
|
||||
current_character := get_character_at_iter(it^);
|
||||
if !strings.ascii_set_contains(set, current_character) && !strings.is_space(rune(current_character)) {
|
||||
_, _, cond := iter_proc(it);
|
||||
if !cond { return false; }
|
||||
|
||||
for until_alpha_num(it, iter_proc) {}
|
||||
return false;
|
||||
}
|
||||
|
||||
for until_before_non_alpha_num(it, iter_proc) {}
|
||||
for until_before_non_whitespace(it, iter_proc) {}
|
||||
for until_non_alpha_num(it, iter_proc) {}
|
||||
for until_non_whitespace(it, iter_proc) {}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -222,12 +264,41 @@ until_start_of_word :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
|||
until_end_of_word :: proc(it: ^FileBufferIter, iter_proc: IterProc) -> bool {
|
||||
set, _ := strings.ascii_set_make("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_");
|
||||
|
||||
if character, _, cond := iter_proc(it); cond && !strings.ascii_set_contains(set, character) && !strings.is_space(rune(character)) {
|
||||
for until_before_non_whitespace(it, iter_proc) {}
|
||||
return false;
|
||||
current_character := get_character_at_iter(it^);
|
||||
if character, peek_it, cond := iterate_peek(it, iter_proc); strings.ascii_set_contains(set, current_character) {
|
||||
// if current charater is a word
|
||||
|
||||
if strings.is_space(rune(character)) {
|
||||
it^ = peek_it;
|
||||
for until_non_whitespace(it, iter_proc) {}
|
||||
}
|
||||
|
||||
if strings.ascii_set_contains(set, character) {
|
||||
// we are within a word
|
||||
for until_before_non_alpha_num(it, iter_proc) {}
|
||||
} else {
|
||||
// we are at the start of a word
|
||||
for until_before_alpha_num_or_whitespace(it, iter_proc) {}
|
||||
}
|
||||
} else if character, peek_it, cond := iterate_peek(it, iter_proc); !strings.ascii_set_contains(set, current_character) {
|
||||
// if current charater is a symbol
|
||||
|
||||
if strings.is_space(rune(character)) {
|
||||
it^ = peek_it;
|
||||
for until_non_whitespace(it, iter_proc) {}
|
||||
|
||||
character = get_character_at_iter(it^);
|
||||
}
|
||||
|
||||
if !strings.ascii_set_contains(set, character) {
|
||||
// we are within a run of symbols
|
||||
for until_before_alpha_num_or_whitespace(it, iter_proc) {}
|
||||
} else {
|
||||
// we are at the start of a run of symbols
|
||||
for until_before_non_alpha_num(it, iter_proc) {}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -382,11 +453,9 @@ move_cursor_up :: proc(buffer: ^FileBuffer, amount: int = 1) {
|
|||
}
|
||||
|
||||
buffer.cursor = it.cursor;
|
||||
}
|
||||
|
||||
if buffer.cursor.line < buffer.top_line + 5 && buffer.cursor.line >= 4 {
|
||||
buffer.top_line = buffer.cursor.line - 4;
|
||||
}
|
||||
}
|
||||
update_file_buffer_scroll(buffer);
|
||||
}
|
||||
|
||||
move_cursor_down :: proc(buffer: ^FileBuffer, amount: int = 1) {
|
||||
|
@ -410,10 +479,7 @@ move_cursor_down :: proc(buffer: ^FileBuffer, amount: int = 1) {
|
|||
}
|
||||
|
||||
buffer.cursor = it.cursor;
|
||||
|
||||
if buffer.cursor.line > buffer.top_line + (buffer.glyph_buffer_height - 5) {
|
||||
buffer.top_line = buffer.cursor.line - (buffer.glyph_buffer_height - 5);
|
||||
}
|
||||
update_file_buffer_scroll(buffer);
|
||||
}
|
||||
|
||||
move_cursor_left :: proc(buffer: ^FileBuffer) {
|
||||
|
@ -440,7 +506,24 @@ move_cursor_forward_start_of_word :: proc(buffer: ^FileBuffer) {
|
|||
update_file_buffer_scroll(buffer);
|
||||
}
|
||||
|
||||
move_cursor_forward_end_of_word :: proc(buffer: ^FileBuffer) {
|
||||
it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor);
|
||||
iterate_file_buffer_until(&it, until_end_of_word);
|
||||
buffer.cursor = it.cursor;
|
||||
|
||||
update_file_buffer_scroll(buffer);
|
||||
}
|
||||
|
||||
move_cursor_backward_start_of_word :: proc(buffer: ^FileBuffer) {
|
||||
it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor);
|
||||
iterate_file_buffer_until_reverse(&it, until_end_of_word);
|
||||
//iterate_file_buffer_until(&it, until_non_whitespace);
|
||||
buffer.cursor = it.cursor;
|
||||
|
||||
update_file_buffer_scroll(buffer);
|
||||
}
|
||||
|
||||
move_cursor_backward_end_of_word :: proc(buffer: ^FileBuffer) {
|
||||
it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor);
|
||||
iterate_file_buffer_until_reverse(&it, until_start_of_word);
|
||||
buffer.cursor = it.cursor;
|
||||
|
@ -602,10 +685,13 @@ is_keyword :: proc(start: FileBufferIter, end: FileBufferIter) -> (matches: bool
|
|||
}
|
||||
|
||||
keyword_index += 1;
|
||||
if keyword_index >= len(keyword) && it == end {
|
||||
if keyword_index >= len(keyword)-1 && it == end {
|
||||
if get_character_at_iter(it) == keyword[keyword_index] {
|
||||
matches = true;
|
||||
}
|
||||
|
||||
break;
|
||||
} else if keyword_index >= len(keyword) {
|
||||
} else if keyword_index >= len(keyword)-1 {
|
||||
break;
|
||||
} else if it == end {
|
||||
break;
|
||||
|
@ -706,20 +792,18 @@ color_buffer :: proc(buffer: ^FileBuffer) {
|
|||
|
||||
iterate_file_buffer_until(&it, until_end_of_word);
|
||||
|
||||
end_of_word_it := it;
|
||||
_, _, succ := iterate_file_buffer_reverse(&end_of_word_it);
|
||||
if !succ { break; }
|
||||
|
||||
// TODO: color keywords
|
||||
if is_keyword(start_it, it) {
|
||||
color_character(buffer, start_it.cursor, end_of_word_it.cursor, .Blue);
|
||||
} else if character, _, cond := iterate_file_buffer(&it); cond {
|
||||
color_character(buffer, start_it.cursor, it.cursor, .Blue);
|
||||
} else if character, _, cond := iterate_peek(&it, iterate_file_buffer); cond {
|
||||
if character == '(' {
|
||||
color_character(buffer, start_it.cursor, end_of_word_it.cursor, .Green);
|
||||
color_character(buffer, start_it.cursor, it.cursor, .Green);
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
|
||||
iterate_file_buffer(&it);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -840,8 +924,8 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, fon
|
|||
update_file_buffer_scroll :: proc(buffer: ^FileBuffer) {
|
||||
if buffer.cursor.line > (buffer.top_line + buffer.glyph_buffer_height - 5) {
|
||||
buffer.top_line = math.max(buffer.cursor.line - buffer.glyph_buffer_height + 5, 0);
|
||||
} else {
|
||||
// TODO: scroll buffer up
|
||||
} else if buffer.cursor.line < (buffer.top_line + 5) {
|
||||
buffer.top_line = math.max(buffer.cursor.line - 5, 0);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -110,6 +110,10 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
|
|||
core.register_key_action(input_map, .W, proc(state: ^State) {
|
||||
core.move_cursor_forward_start_of_word(&state.buffers[state.current_buffer]);
|
||||
}, "move forward one word");
|
||||
core.register_key_action(input_map, .E, proc(state: ^State) {
|
||||
core.move_cursor_forward_end_of_word(&state.buffers[state.current_buffer]);
|
||||
}, "move forward to end of word");
|
||||
|
||||
core.register_key_action(input_map, .B, proc(state: ^State) {
|
||||
core.move_cursor_backward_start_of_word(&state.buffers[state.current_buffer]);
|
||||
}, "move backward one word");
|
||||
|
@ -155,6 +159,10 @@ register_default_input_actions :: proc(input_map: ^core.InputMap) {
|
|||
core.register_key_action(input_map, .I, proc(state: ^State) {
|
||||
state.mode = .Insert;
|
||||
}, "enter insert mode");
|
||||
core.register_key_action(input_map, .A, proc(state: ^State) {
|
||||
core.move_cursor_right(&state.buffers[state.current_buffer]);
|
||||
state.mode = .Insert;
|
||||
}, "enter insert mode after character (append)");
|
||||
|
||||
core.register_key_action(input_map, .SPACE, core.new_input_map(), "leader commands");
|
||||
register_default_leader_actions(&(&input_map.key_actions[.SPACE]).action.(core.InputMap));
|
||||
|
@ -317,7 +325,7 @@ main :: proc() {
|
|||
ui.draw_buffer_list_window(&state);
|
||||
}
|
||||
|
||||
if state.current_input_map != &state.input_map {
|
||||
if true || state.current_input_map != &state.input_map {
|
||||
longest_description := 0;
|
||||
for key, action in state.current_input_map.key_actions {
|
||||
if len(action.description) > longest_description {
|
||||
|
|
Loading…
Reference in New Issue