memory-refactor
Patrick Cleavelin 2025-01-27 22:33:10 -06:00
parent ac9d33be92
commit caaa8ebbd5
9 changed files with 290 additions and 116 deletions

View File

@ -1,8 +1,8 @@
all: editor all: editor
editor: src/*.odin grep odin_highlighter editor: src/*.odin # grep odin_highlighter
odin build src/ -out:bin/editor.o -build-mode:obj -debug -lld # odin build src/ -out:bin/editor.o -build-mode:obj -debug -lld
dsymutil bin/editor.o -o bin/editor.dSYM # dsymutil bin/editor.o -o bin/editor.dSYM
odin build src/ -out:bin/editor -lld odin build src/ -out:bin/editor -lld
odin_highlighter: plugins/highlighter/src/*.odin odin_highlighter: plugins/highlighter/src/*.odin

View File

@ -1,6 +1,9 @@
local BufferSearchOpen = false local BufferSearchOpen = false
local BufferSearchOpenElapsed = 0 local BufferSearchOpenElapsed = 0
local LogWindowOpen = false
local LogWindowOpenElapsed = 0
local CurrentPreviewBufferIndex = Editor.get_current_buffer_index() local CurrentPreviewBufferIndex = Editor.get_current_buffer_index()
local BufferSearchIndex = 0 local BufferSearchIndex = 0
@ -99,9 +102,11 @@ function ui_sidemenu(ctx)
end end
if UI.advanced_button(ctx, " x ", flags, UI.FitText, UI.FitText).clicked then if UI.advanced_button(ctx, " x ", flags, UI.FitText, UI.FitText).clicked then
print("hahah, you can't close buffers yet silly") Editor.log("hahah, you can't close buffers yet silly")
Editor.set_current_buffer_from_index(i) if ActiveCodeView ~= nil then
add_buffer_to_code_view(ActiveCodeView+1, buffer_info.file_path, i) Editor.set_current_buffer_from_index(i)
add_buffer_to_code_view(ActiveCodeView+1, buffer_info.file_path, i)
end
end end
tab_button_interaction = UI.advanced_button(ctx, " "..buffer_info.file_path.." ", flags, UI.Fill, UI.FitText) tab_button_interaction = UI.advanced_button(ctx, " "..buffer_info.file_path.." ", flags, UI.Fill, UI.FitText)
@ -275,6 +280,7 @@ function render_ui_window(ctx)
end end
render_buffer_search(ctx) render_buffer_search(ctx)
render_log_window(ctx)
LastMouseX = x LastMouseX = x
LastMouseY = y LastMouseY = y
@ -317,13 +323,54 @@ function render_buffer_search(ctx)
end end
end end
function render_log_window(ctx)
if Editor.get_current_buffer_index() ~= -2 then
LogWindowOpen = false
end
if LogWindowOpen or LogWindowOpenElapsed > 0 then
if LogWindowOpen and LogWindowOpenElapsed < numFrames then
LogWindowOpenElapsed = LogWindowOpenElapsed + 1
elseif not LogWindowOpen and LogWindowOpenElapsed > 0 then
LogWindowOpenElapsed = LogWindowOpenElapsed - 1
end
end
if LogWindowOpen or LogWindowOpenElapsed > 0 then
window_percent = 75
if LogWindowOpenElapsed > 0 then
window_percent = ((LogWindowOpenElapsed/numFrames) * 75)
end
UI.push_parent(ctx, UI.push_floating(ctx, "log window canvas", 0, 0))
centered(ctx, "log window", UI.Horizontal, UI.PercentOfParent(window_percent), UI.PercentOfParent(window_percent), (
function ()
UI.push_parent(ctx, UI.push_rect(ctx, "window", true, true, UI.Horizontal, UI.Fill, UI.Fill))
-- -2 is the log buffer
UI.buffer(ctx, -2)
UI.pop_parent(ctx)
end
))
UI.pop_parent(ctx)
end
end
function handle_buffer_input() function handle_buffer_input()
-- print("you inputted into a buffer")
end end
function OnInit() function OnInit()
print("Main View plugin initialized") Editor.log("Main View plugin initialized")
Editor.register_key_group({ Editor.register_key_group({
{Editor.Key.Backtick, "Open Editor Logs", (function ()
if not LogWindowOpen then
LogWindowOpen = true
Editor.set_current_buffer_from_index(-2)
else
LogWindowOpen = false
local code_view = CodeViews[ActiveCodeView]
Editor.set_current_buffer_from_index(code_view.tabs[code_view.current_tab]["buffer_index"])
end
end)},
{Editor.Key.Space, "", { {Editor.Key.Space, "", {
{Editor.Key.B, "Buffer Search", ( {Editor.Key.B, "Buffer Search", (
function () function ()

View File

@ -3,6 +3,7 @@ package core
import "core:runtime" import "core:runtime"
import "core:reflect" import "core:reflect"
import "core:fmt" import "core:fmt"
import "core:log"
import "vendor:sdl2" import "vendor:sdl2"
import lua "vendor:lua/5.4" import lua "vendor:lua/5.4"
@ -67,6 +68,8 @@ State :: struct {
current_buffer: int, current_buffer: int,
buffers: [dynamic]FileBuffer, buffers: [dynamic]FileBuffer,
log_buffer: FileBuffer,
window: ^Window, window: ^Window,
should_close_window: bool, should_close_window: bool,
@ -80,6 +83,22 @@ State :: struct {
lua_hooks: map[plugin.Hook][dynamic]LuaHookRef, lua_hooks: map[plugin.Hook][dynamic]LuaHookRef,
} }
current_buffer :: proc(state: ^State) -> ^FileBuffer {
if state.current_buffer == -2 {
return &state.log_buffer;
}
return &state.buffers[state.current_buffer];
}
buffer_from_index :: proc(state: ^State, buffer_index: int) -> ^FileBuffer {
if buffer_index == -2 {
return &state.log_buffer;
}
return &state.buffers[buffer_index];
}
add_hook :: proc(state: ^State, hook: plugin.Hook, hook_proc: plugin.OnHookProc) { add_hook :: proc(state: ^State, hook: plugin.Hook, hook_proc: plugin.OnHookProc) {
if _, exists := state.hooks[hook]; !exists { if _, exists := state.hooks[hook]; !exists {
state.hooks[hook] = make([dynamic]plugin.OnHookProc); state.hooks[hook] = make([dynamic]plugin.OnHookProc);
@ -155,7 +174,7 @@ delete_input_actions :: proc(input_map: ^InputActions) {
register_plugin_key_action_single :: proc(input_map: ^InputActions, key: plugin.Key, action: PluginEditorAction, description: string = "") { register_plugin_key_action_single :: proc(input_map: ^InputActions, key: plugin.Key, action: PluginEditorAction, description: string = "") {
if ok := key in input_map.key_actions; ok { if ok := key in input_map.key_actions; ok {
// TODO: log that key is already registered // TODO: log that key is already registered
fmt.eprintln("plugin key already registered with single action", key); log.error("plugin key already registered with single action", key);
} }
input_map.key_actions[key] = Action { input_map.key_actions[key] = Action {
@ -167,7 +186,7 @@ register_plugin_key_action_single :: proc(input_map: ^InputActions, key: plugin.
register_key_action_single :: proc(input_map: ^InputActions, key: plugin.Key, action: EditorAction, description: string = "") { register_key_action_single :: proc(input_map: ^InputActions, key: plugin.Key, action: EditorAction, description: string = "") {
if ok := key in input_map.key_actions; ok { if ok := key in input_map.key_actions; ok {
// TODO: log that key is already registered // TODO: log that key is already registered
fmt.eprintln("key already registered with single action", key); log.error("key already registered with single action", key);
} }
input_map.key_actions[key] = Action { input_map.key_actions[key] = Action {
@ -191,7 +210,7 @@ register_key_action_group :: proc(input_map: ^InputActions, key: plugin.Key, inp
register_ctrl_key_action_single :: proc(input_map: ^InputActions, key: plugin.Key, action: EditorAction, description: string = "") { register_ctrl_key_action_single :: proc(input_map: ^InputActions, key: plugin.Key, action: EditorAction, description: string = "") {
if ok := key in input_map.key_actions; ok { if ok := key in input_map.key_actions; ok {
// TODO: log that key is already registered // TODO: log that key is already registered
fmt.eprintln("key already registered with single action", key); log.error("key already registered with single action", key);
} }
input_map.ctrl_key_actions[key] = Action { input_map.ctrl_key_actions[key] = Action {
@ -203,7 +222,7 @@ register_ctrl_key_action_single :: proc(input_map: ^InputActions, key: plugin.Ke
register_ctrl_key_action_group :: proc(input_map: ^InputActions, key: plugin.Key, input_group: InputGroup, description: string = "") { register_ctrl_key_action_group :: proc(input_map: ^InputActions, key: plugin.Key, input_group: InputGroup, description: string = "") {
if ok := key in input_map.key_actions; ok { if ok := key in input_map.key_actions; ok {
// TODO: log that key is already registered // TODO: log that key is already registered
fmt.eprintln("key already registered with single action", key); log.error("key already registered with single action", key);
} }
input_map.ctrl_key_actions[key] = Action { input_map.ctrl_key_actions[key] = Action {

View File

@ -43,7 +43,7 @@ Selection :: struct {
end: Cursor, end: Cursor,
} }
Glyph :: struct #packed { Glyph :: struct {
codepoint: u8, codepoint: u8,
color: theme.PaletteColor, color: theme.PaletteColor,
} }
@ -84,6 +84,17 @@ new_file_buffer_iter_with_cursor :: proc(file_buffer: ^FileBuffer, cursor: Curso
} }
new_file_buffer_iter :: proc{new_file_buffer_iter_from_beginning, new_file_buffer_iter_with_cursor}; new_file_buffer_iter :: proc{new_file_buffer_iter_from_beginning, new_file_buffer_iter_with_cursor};
file_buffer_end :: proc(buffer: ^FileBuffer) -> Cursor {
return Cursor {
col = 0,
line = 0,
index = FileBufferIndex {
slice_index = len(buffer.content_slices)-1,
content_index = len(buffer.content_slices[len(buffer.content_slices)-1])-1,
}
};
}
iterate_file_buffer :: proc(it: ^FileBufferIter) -> (character: u8, idx: FileBufferIndex, cond: bool) { iterate_file_buffer :: proc(it: ^FileBufferIter) -> (character: u8, idx: FileBufferIndex, cond: bool) {
if it.cursor.index.slice_index >= len(it.buffer.content_slices) || it.cursor.index.content_index >= len(it.buffer.content_slices[it.cursor.index.slice_index]) { if it.cursor.index.slice_index >= len(it.buffer.content_slices) || it.cursor.index.content_index >= len(it.buffer.content_slices[it.cursor.index.slice_index]) {
return; return;
@ -542,7 +553,7 @@ move_cursor_left :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cursor) = nil) {
} }
} }
move_cursor_right :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, cursor: Maybe(^Cursor) = nil) { move_cursor_right :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, amt: int = 1, cursor: Maybe(^Cursor) = nil) {
cursor := cursor; cursor := cursor;
if cursor == nil { if cursor == nil {
@ -552,9 +563,11 @@ move_cursor_right :: proc(buffer: ^FileBuffer, stop_at_end: bool = true, cursor:
it := new_file_buffer_iter_with_cursor(buffer, cursor.?^); it := new_file_buffer_iter_with_cursor(buffer, cursor.?^);
line_length := file_buffer_line_length(buffer, it.cursor.index); line_length := file_buffer_line_length(buffer, it.cursor.index);
if !stop_at_end || cursor.?.col < line_length-1 { for _ in 0..<amt {
iterate_file_buffer(&it); if !stop_at_end || cursor.?.col < line_length-1 {
cursor.?^ = it.cursor; iterate_file_buffer(&it);
cursor.?^ = it.cursor;
}
} }
} }
@ -742,7 +755,7 @@ into_buffer_info :: proc(state: ^State, buffer: ^FileBuffer) -> plugin.BufferInf
}; };
} }
into_buffer_info_from_index :: proc(state: ^State, buffer_index: int) -> plugin.BufferInfo { into_buffer_info_from_index :: proc(state: ^State, buffer_index: int) -> plugin.BufferInfo {
buffer := &state.buffers[buffer_index]; buffer := buffer_from_index(state, buffer_index);
return into_buffer_info(state, buffer); return into_buffer_info(state, buffer);
} }
@ -860,7 +873,7 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, sho
cursor_y -= begin * state.source_font_height; cursor_y -= begin * state.source_font_height;
// draw cursor // draw cursor
if state.mode == .Normal { if state.mode == .Normal || current_buffer(state) != buffer {
draw_rect(state, cursor_x, cursor_y, state.source_font_width, state.source_font_height, .Background4); draw_rect(state, cursor_x, cursor_y, state.source_font_width, state.source_font_height, .Background4);
} else if state.mode == .Visual { } else if state.mode == .Visual {
start_sel_x := x + padding + buffer.selection.?.start.col * state.source_font_width; start_sel_x := x + padding + buffer.selection.?.start.col * state.source_font_width;
@ -919,7 +932,7 @@ draw_file_buffer :: proc(state: ^State, buffer: ^FileBuffer, x: int, y: int, sho
// NOTE: this requires transparent background color because it renders after the text // NOTE: this requires transparent background color because it renders after the text
// and its after the text because the line length needs to be calculated // and its after the text because the line length needs to be calculated
if state.mode == .Visual { if state.mode == .Visual && current_buffer(state) == buffer {
sel_x := x + padding; sel_x := x + padding;
width: int width: int
@ -976,14 +989,14 @@ scroll_file_buffer :: proc(buffer: ^FileBuffer, dir: ScrollDir, cursor: Maybe(^C
} }
} }
insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8) { insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8, append_to_end: bool = false) {
if len(to_be_inserted) == 0 { if len(to_be_inserted) == 0 {
return; return;
} }
// TODO: is this even needed? would mean that the cursor isn't always in a valid state. // TODO: is this even needed? would mean that the cursor isn't always in a valid state.
update_file_buffer_index_from_cursor(buffer); // update_file_buffer_index_from_cursor(buffer);
it := new_file_buffer_iter(buffer, buffer.cursor); it := new_file_buffer_iter_with_cursor(buffer, buffer.cursor) if !append_to_end else new_file_buffer_iter_with_cursor(buffer, file_buffer_end(buffer));
length := append(&buffer.added_content, ..to_be_inserted); length := append(&buffer.added_content, ..to_be_inserted);
inserted_slice: []u8 = buffer.added_content[len(buffer.added_content)-length:]; inserted_slice: []u8 = buffer.added_content[len(buffer.added_content)-length:];
@ -991,7 +1004,7 @@ insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8) {
if it.cursor.index.content_index == 0 { if it.cursor.index.content_index == 0 {
// insertion happening in beginning of content slice // insertion happening in beginning of content slice
inject_at(&buffer.content_slices, buffer.cursor.index.slice_index, inserted_slice); inject_at(&buffer.content_slices, it.cursor.index.slice_index, inserted_slice);
} }
else { else {
// insertion is happening in middle of content slice // insertion is happening in middle of content slice
@ -1004,7 +1017,10 @@ insert_content :: proc(buffer: ^FileBuffer, to_be_inserted: []u8) {
inject_at(&buffer.content_slices, it.cursor.index.slice_index+2, end_slice); inject_at(&buffer.content_slices, it.cursor.index.slice_index+2, end_slice);
} }
update_file_buffer_index_from_cursor(buffer); if !append_to_end {
update_file_buffer_index_from_cursor(buffer);
move_cursor_right(buffer, false, amt = len(to_be_inserted));
}
} }
// TODO: potentially add FileBufferIndex as parameter // TODO: potentially add FileBufferIndex as parameter

40
src/core/logger.odin Normal file
View File

@ -0,0 +1,40 @@
package core
import "core:runtime"
import "core:reflect"
import "core:fmt"
import "core:log"
Level_Header := [?]string {
0..<10 = "[DEBUG]: ",
10..<20 = "[INFO ]: ",
20..<30 = "[WARN ]: ",
30..<40 = "[ERROR]: ",
40..<50 = "[FATAL]: ",
};
new_logger :: proc(buffer: ^FileBuffer) -> runtime.Logger {
return runtime.Logger {
procedure = logger_proc,
data = buffer,
lowest_level = .Debug,
options = {
.Level,
.Date,
.Time,
.Short_File_Path,
.Thread_Id
},
};
}
logger_proc :: proc(data: rawptr, level: runtime.Logger_Level, text: string, options: runtime.Logger_Options, location := #caller_location) {
buffer := cast(^FileBuffer)data;
if .Level in options {
insert_content(buffer, transmute([]u8)(Level_Header[level]), true);
}
insert_content(buffer, transmute([]u8)(text), true);
insert_content(buffer, {'\n'}, true);
}

View File

@ -6,6 +6,7 @@ import "core:math"
import "core:strings" import "core:strings"
import "core:runtime" import "core:runtime"
import "core:fmt" import "core:fmt"
import "core:log"
import "core:mem" import "core:mem"
import "core:slice" import "core:slice"
import "vendor:sdl2" import "vendor:sdl2"
@ -27,6 +28,7 @@ StateWithUi :: struct {
ui_context: ^ui.Context, ui_context: ^ui.Context,
} }
// TODO: why do I have this here again?
// TODO: use buffer list in state // TODO: use buffer list in state
do_normal_mode :: proc(state: ^State, buffer: ^FileBuffer) { do_normal_mode :: proc(state: ^State, buffer: ^FileBuffer) {
if state.current_input_map != nil { if state.current_input_map != nil {
@ -90,11 +92,11 @@ register_default_leader_actions :: proc(input_map: ^core.InputActions) {
register_default_go_actions :: proc(input_map: ^core.InputActions) { register_default_go_actions :: proc(input_map: ^core.InputActions) {
core.register_key_action(input_map, .H, proc(state: ^State) { core.register_key_action(input_map, .H, proc(state: ^State) {
core.move_cursor_start_of_line(&state.buffers[state.current_buffer]); core.move_cursor_start_of_line(core.current_buffer(state));
state.current_input_map = &state.input_map.mode[state.mode]; state.current_input_map = &state.input_map.mode[state.mode];
}, "move to beginning of line"); }, "move to beginning of line");
core.register_key_action(input_map, .L, proc(state: ^State) { core.register_key_action(input_map, .L, proc(state: ^State) {
core.move_cursor_end_of_line(&state.buffers[state.current_buffer]); core.move_cursor_end_of_line(core.current_buffer(state));
state.current_input_map = &state.input_map.mode[state.mode]; state.current_input_map = &state.input_map.mode[state.mode];
}, "move to end of line"); }, "move to end of line");
} }
@ -103,34 +105,34 @@ register_default_input_actions :: proc(input_map: ^core.InputActions) {
// Cursor Movement // Cursor Movement
{ {
core.register_key_action(input_map, .W, proc(state: ^State) { core.register_key_action(input_map, .W, proc(state: ^State) {
core.move_cursor_forward_start_of_word(&state.buffers[state.current_buffer]); core.move_cursor_forward_start_of_word(core.current_buffer(state));
}, "move forward one word"); }, "move forward one word");
core.register_key_action(input_map, .E, proc(state: ^State) { core.register_key_action(input_map, .E, proc(state: ^State) {
core.move_cursor_forward_end_of_word(&state.buffers[state.current_buffer]); core.move_cursor_forward_end_of_word(core.current_buffer(state));
}, "move forward to end of word"); }, "move forward to end of word");
core.register_key_action(input_map, .B, proc(state: ^State) { core.register_key_action(input_map, .B, proc(state: ^State) {
core.move_cursor_backward_start_of_word(&state.buffers[state.current_buffer]); core.move_cursor_backward_start_of_word(core.current_buffer(state));
}, "move backward one word"); }, "move backward one word");
core.register_key_action(input_map, .K, proc(state: ^State) { core.register_key_action(input_map, .K, proc(state: ^State) {
core.move_cursor_up(&state.buffers[state.current_buffer]); core.move_cursor_up(core.current_buffer(state));
}, "move up one line"); }, "move up one line");
core.register_key_action(input_map, .J, proc(state: ^State) { core.register_key_action(input_map, .J, proc(state: ^State) {
core.move_cursor_down(&state.buffers[state.current_buffer]); core.move_cursor_down(core.current_buffer(state));
}, "move down one line"); }, "move down one line");
core.register_key_action(input_map, .H, proc(state: ^State) { core.register_key_action(input_map, .H, proc(state: ^State) {
core.move_cursor_left(&state.buffers[state.current_buffer]); core.move_cursor_left(core.current_buffer(state));
}, "move left one char"); }, "move left one char");
core.register_key_action(input_map, .L, proc(state: ^State) { core.register_key_action(input_map, .L, proc(state: ^State) {
core.move_cursor_right(&state.buffers[state.current_buffer]); core.move_cursor_right(core.current_buffer(state));
}, "move right one char"); }, "move right one char");
core.register_ctrl_key_action(input_map, .U, proc(state: ^State) { core.register_ctrl_key_action(input_map, .U, proc(state: ^State) {
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Up); core.scroll_file_buffer(core.current_buffer(state), .Up);
}, "scroll buffer up"); }, "scroll buffer up");
core.register_ctrl_key_action(input_map, .D, proc(state: ^State) { core.register_ctrl_key_action(input_map, .D, proc(state: ^State) {
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Down); core.scroll_file_buffer(core.current_buffer(state), .Down);
}, "scroll buffer up"); }, "scroll buffer up");
} }
@ -143,7 +145,7 @@ register_default_input_actions :: proc(input_map: ^core.InputActions) {
state.font_atlas = core.gen_font_atlas(state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf"); state.font_atlas = core.gen_font_atlas(state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
} }
fmt.println(state.source_font_height); log.debug(state.source_font_height);
}, "increase font size"); }, "increase font size");
core.register_ctrl_key_action(input_map, .EQUAL, proc(state: ^State) { core.register_ctrl_key_action(input_map, .EQUAL, proc(state: ^State) {
state.source_font_height += 2; state.source_font_height += 2;
@ -163,7 +165,7 @@ register_default_input_actions :: proc(input_map: ^core.InputActions) {
state.mode = .Visual; state.mode = .Visual;
state.current_input_map = &state.input_map.mode[.Visual]; state.current_input_map = &state.input_map.mode[.Visual];
state.buffers[state.current_buffer].selection = core.new_selection(state.buffers[state.current_buffer].cursor); core.current_buffer(state).selection = core.new_selection(core.current_buffer(state).cursor);
}, "enter visual mode"); }, "enter visual mode");
} }
@ -173,58 +175,58 @@ register_default_visual_actions :: proc(input_map: ^core.InputActions) {
state.mode = .Normal; state.mode = .Normal;
state.current_input_map = &state.input_map.mode[.Normal]; state.current_input_map = &state.input_map.mode[.Normal];
state.buffers[state.current_buffer].selection = nil; core.current_buffer(state).selection = nil;
}, "exit visual mode"); }, "exit visual mode");
// Cursor Movement // Cursor Movement
{ {
core.register_key_action(input_map, .W, proc(state: ^State) { core.register_key_action(input_map, .W, proc(state: ^State) {
sel_cur := &state.buffers[state.current_buffer].selection.?; sel_cur := core.current_buffer(state).selection.?;
core.move_cursor_forward_start_of_word(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_forward_start_of_word(core.current_buffer(state), cursor = &sel_cur.end);
}, "move forward one word"); }, "move forward one word");
core.register_key_action(input_map, .E, proc(state: ^State) { core.register_key_action(input_map, .E, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.move_cursor_forward_end_of_word(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_forward_end_of_word(core.current_buffer(state), cursor = &sel_cur.end);
}, "move forward to end of word"); }, "move forward to end of word");
core.register_key_action(input_map, .B, proc(state: ^State) { core.register_key_action(input_map, .B, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.move_cursor_backward_start_of_word(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_backward_start_of_word(core.current_buffer(state), cursor = &sel_cur.end);
}, "move backward one word"); }, "move backward one word");
core.register_key_action(input_map, .K, proc(state: ^State) { core.register_key_action(input_map, .K, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.move_cursor_up(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_up(core.current_buffer(state), cursor = &sel_cur.end);
}, "move up one line"); }, "move up one line");
core.register_key_action(input_map, .J, proc(state: ^State) { core.register_key_action(input_map, .J, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.move_cursor_down(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_down(core.current_buffer(state), cursor = &sel_cur.end);
}, "move down one line"); }, "move down one line");
core.register_key_action(input_map, .H, proc(state: ^State) { core.register_key_action(input_map, .H, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.move_cursor_left(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_left(core.current_buffer(state), cursor = &sel_cur.end);
}, "move left one char"); }, "move left one char");
core.register_key_action(input_map, .L, proc(state: ^State) { core.register_key_action(input_map, .L, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.move_cursor_right(&state.buffers[state.current_buffer], cursor = &sel_cur.end); core.move_cursor_right(core.current_buffer(state), cursor = &sel_cur.end);
}, "move right one char"); }, "move right one char");
core.register_ctrl_key_action(input_map, .U, proc(state: ^State) { core.register_ctrl_key_action(input_map, .U, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Up, cursor = &sel_cur.end); core.scroll_file_buffer(core.current_buffer(state), .Up, cursor = &sel_cur.end);
}, "scroll buffer up"); }, "scroll buffer up");
core.register_ctrl_key_action(input_map, .D, proc(state: ^State) { core.register_ctrl_key_action(input_map, .D, proc(state: ^State) {
sel_cur := &(state.buffers[state.current_buffer].selection.?); sel_cur := &(core.current_buffer(state).selection.?);
core.scroll_file_buffer(&state.buffers[state.current_buffer], .Down, cursor = &sel_cur.end); core.scroll_file_buffer(core.current_buffer(state), .Down, cursor = &sel_cur.end);
}, "scroll buffer up"); }, "scroll buffer up");
} }
} }
@ -235,7 +237,7 @@ register_default_text_input_actions :: proc(input_map: ^core.InputActions) {
sdl2.StartTextInput(); sdl2.StartTextInput();
}, "enter insert mode"); }, "enter insert mode");
core.register_key_action(input_map, .A, proc(state: ^State) { core.register_key_action(input_map, .A, proc(state: ^State) {
core.move_cursor_right(&state.buffers[state.current_buffer], false); core.move_cursor_right(core.current_buffer(state), false);
state.mode = .Insert; state.mode = .Insert;
sdl2.StartTextInput(); sdl2.StartTextInput();
}, "enter insert mode after character (append)"); }, "enter insert mode after character (append)");
@ -243,9 +245,9 @@ register_default_text_input_actions :: proc(input_map: ^core.InputActions) {
// TODO: add shift+o to insert newline above current one // TODO: add shift+o to insert newline above current one
core.register_key_action(input_map, .O, proc(state: ^State) { core.register_key_action(input_map, .O, proc(state: ^State) {
core.move_cursor_end_of_line(&state.buffers[state.current_buffer], false); core.move_cursor_end_of_line(core.current_buffer(state), false);
core.insert_content(&state.buffers[state.current_buffer], []u8{'\n'}); core.insert_content(core.current_buffer(state), []u8{'\n'});
core.move_cursor_down(&state.buffers[state.current_buffer]); core.move_cursor_down(core.current_buffer(state));
state.mode = .Insert; state.mode = .Insert;
sdl2.StartTextInput(); sdl2.StartTextInput();
@ -263,9 +265,9 @@ load_plugin :: proc(info: os.File_Info, in_err: os.Errno, state: rawptr) -> (err
append(&state.plugins, loaded_plugin); append(&state.plugins, loaded_plugin);
if rel_error == .None { if rel_error == .None {
fmt.println("Loaded", relative_file_path); log.info("Loaded", relative_file_path);
} else { } else {
fmt.println("Loaded", info.fullpath); log.info("Loaded", info.fullpath);
} }
} }
} }
@ -281,7 +283,7 @@ ui_font_height :: proc() -> i32 {
} }
draw :: proc(state_with_ui: ^StateWithUi) { draw :: proc(state_with_ui: ^StateWithUi) {
buffer := &state_with_ui.state.buffers[state_with_ui.state.current_buffer]; buffer := core.current_buffer(state_with_ui.state);
buffer.glyph_buffer_height = math.min(256, int((state_with_ui.state.screen_height - state_with_ui.state.source_font_height*2) / state_with_ui.state.source_font_height)) + 1; buffer.glyph_buffer_height = math.min(256, int((state_with_ui.state.screen_height - state_with_ui.state.source_font_height*2) / state_with_ui.state.source_font_height)) + 1;
buffer.glyph_buffer_width = math.min(256, int((state_with_ui.state.screen_width - state_with_ui.state.source_font_width) / state_with_ui.state.source_font_width)); buffer.glyph_buffer_width = math.min(256, int((state_with_ui.state.screen_width - state_with_ui.state.source_font_width) / state_with_ui.state.source_font_width));
@ -420,7 +422,7 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
extension := strings.clone(string(extension)); extension := strings.clone(string(extension));
if _, exists := state.highlighters[extension]; exists { if _, exists := state.highlighters[extension]; exists {
fmt.eprintln("Highlighter already registered for", extension, "files"); log.error("Highlighter already registered for", extension, "files");
} else { } else {
state.highlighters[extension] = on_color_buffer; state.highlighters[extension] = on_color_buffer;
} }
@ -440,11 +442,11 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
if action, exists := to_be_edited_map.key_actions[key]; exists { if action, exists := to_be_edited_map.key_actions[key]; exists {
switch value in action.action { switch value in action.action {
case core.LuaEditorAction: case core.LuaEditorAction:
fmt.eprintln("Plugin attempted to register input group on existing key action (added from Lua)"); log.warn("Plugin attempted to register input group on existing key action (added from Lua)");
case core.PluginEditorAction: case core.PluginEditorAction:
fmt.eprintln("Plugin attempted to register input group on existing key action (added from Plugin)"); log.warn("Plugin attempted to register input group on existing key action (added from Plugin)");
case core.EditorAction: case core.EditorAction:
fmt.eprintln("Plugin attempted to register input group on existing key action"); log.warn("Plugin attempted to register input group on existing key action");
case core.InputActions: case core.InputActions:
input_map := &(&to_be_edited_map.key_actions[key]).action.(core.InputActions); input_map := &(&to_be_edited_map.key_actions[key]).action.(core.InputActions);
register_group(state.plugin_vtable, transmute(rawptr)input_map); register_group(state.plugin_vtable, transmute(rawptr)input_map);
@ -469,13 +471,13 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
if action, exists := to_be_edited_map.key_actions[key]; exists { if action, exists := to_be_edited_map.key_actions[key]; exists {
switch value in action.action { switch value in action.action {
case core.LuaEditorAction: case core.LuaEditorAction:
fmt.eprintln("Plugin attempted to register key action on existing key action (added from Lua)"); log.warn("Plugin attempted to register key action on existing key action (added from Lua)");
case core.PluginEditorAction: case core.PluginEditorAction:
fmt.eprintln("Plugin attempted to register key action on existing key action (added from Plugin)"); log.warn("Plugin attempted to register key action on existing key action (added from Plugin)");
case core.EditorAction: case core.EditorAction:
fmt.eprintln("Plugin attempted to register input key action on existing key action"); log.warn("Plugin attempted to register input key action on existing key action");
case core.InputActions: case core.InputActions:
fmt.eprintln("Plugin attempted to register input key action on existing input group"); log.warn("Plugin attempted to register input key action on existing input group");
} }
} else { } else {
core.register_key_action(to_be_edited_map, key, input_action, description); core.register_key_action(to_be_edited_map, key, input_action, description);
@ -545,12 +547,12 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
}, },
draw_buffer_from_index = proc "c" (buffer_index: int, x: int, y: int, glyph_buffer_width: int, glyph_buffer_height: int, show_line_numbers: bool) { draw_buffer_from_index = proc "c" (buffer_index: int, x: int, y: int, glyph_buffer_width: int, glyph_buffer_height: int, show_line_numbers: bool) {
context = state.ctx; context = state.ctx;
state.buffers[buffer_index].glyph_buffer_width = glyph_buffer_width; core.buffer_from_index(&state, buffer_index).glyph_buffer_width = glyph_buffer_width;
state.buffers[buffer_index].glyph_buffer_height = glyph_buffer_height; core.buffer_from_index(&state, buffer_index).glyph_buffer_height = glyph_buffer_height;
core.draw_file_buffer( core.draw_file_buffer(
&state, &state,
&state.buffers[buffer_index], core.buffer_from_index(&state, buffer_index),
x, x,
y, y,
show_line_numbers); show_line_numbers);
@ -573,7 +575,7 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
get_current_buffer_iterator = proc "c" () -> plugin.BufferIter { get_current_buffer_iterator = proc "c" () -> plugin.BufferIter {
context = state.ctx; context = state.ctx;
it := core.new_file_buffer_iter(&state.buffers[state.current_buffer]); it := core.new_file_buffer_iter(core.current_buffer(&state));
// TODO: make this into a function // TODO: make this into a function
return plugin.BufferIter { return plugin.BufferIter {
@ -794,7 +796,7 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
}, },
get_buffer_info_from_index = proc "c" (buffer_index: int) -> plugin.BufferInfo { get_buffer_info_from_index = proc "c" (buffer_index: int) -> plugin.BufferInfo {
context = state.ctx; context = state.ctx;
buffer := &state.buffers[buffer_index]; buffer := core.buffer_from_index(&state, buffer_index);
return core.into_buffer_info(&state, buffer); return core.into_buffer_info(&state, buffer);
}, },
@ -843,14 +845,14 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
if should_create_buffer { if should_create_buffer {
new_buffer, err := core.new_file_buffer(context.allocator, strings.clone(path)); new_buffer, err := core.new_file_buffer(context.allocator, strings.clone(path));
if err.type != .None { if err.type != .None {
fmt.println("Failed to open/create file buffer:", err); log.error("Failed to open/create file buffer:", err);
} else { } else {
runtime.append(&state.buffers, new_buffer); runtime.append(&state.buffers, new_buffer);
state.current_buffer = len(state.buffers)-1; state.current_buffer = len(state.buffers)-1;
buffer = &state.buffers[state.current_buffer]; buffer = core.current_buffer(&state);
} }
} else { } else {
buffer = &state.buffers[state.current_buffer]; buffer = core.current_buffer(&state);
} }
if buffer != nil { if buffer != nil {
@ -971,11 +973,11 @@ init_plugin_vtable :: proc(ui_context: ^ui.Context) -> plugin.Plugin {
ui_file_buffer(ui_context, buffer); ui_file_buffer(ui_context, buffer);
}, },
buffer_from_index = proc "c" (ui_context: rawptr, buffer: int, show_line_numbers: bool) { buffer_from_index = proc "c" (ui_context: rawptr, buffer_index: int, show_line_numbers: bool) {
context = state.ctx; context = state.ctx;
ui_context := transmute(^ui.Context)ui_context; ui_context := transmute(^ui.Context)ui_context;
buffer := &state.buffers[buffer]; buffer := core.buffer_from_index(&state, buffer_index);
ui_file_buffer(ui_context, buffer); ui_file_buffer(ui_context, buffer);
}, },
@ -1026,8 +1028,13 @@ main :: proc() {
highlighters = make(map[string]plugin.OnColorBufferProc), highlighters = make(map[string]plugin.OnColorBufferProc),
hooks = make(map[plugin.Hook][dynamic]plugin.OnHookProc), hooks = make(map[plugin.Hook][dynamic]plugin.OnHookProc),
lua_hooks = make(map[plugin.Hook][dynamic]core.LuaHookRef), lua_hooks = make(map[plugin.Hook][dynamic]core.LuaHookRef),
log_buffer = core.new_virtual_file_buffer(context.allocator),
}; };
context.logger = core.new_logger(&state.log_buffer);
state.ctx = context;
state.current_input_map = &state.input_map.mode[.Normal]; state.current_input_map = &state.input_map.mode[.Normal];
register_default_input_actions(&state.input_map.mode[.Normal]); register_default_input_actions(&state.input_map.mode[.Normal]);
register_default_visual_actions(&state.input_map.mode[.Visual]); register_default_visual_actions(&state.input_map.mode[.Visual]);
@ -1037,7 +1044,7 @@ main :: proc() {
for arg in os.args[1:] { for arg in os.args[1:] {
buffer, err := core.new_file_buffer(context.allocator, arg, state.directory); buffer, err := core.new_file_buffer(context.allocator, arg, state.directory);
if err.type != .None { if err.type != .None {
fmt.println("Failed to create file buffer:", err); log.error("Failed to create file buffer:", err);
continue; continue;
} }
@ -1045,12 +1052,12 @@ main :: proc() {
} }
if sdl2.Init({.VIDEO}) < 0 { if sdl2.Init({.VIDEO}) < 0 {
fmt.eprintln("SDL failed to initialize:", sdl2.GetError()); log.error("SDL failed to initialize:", sdl2.GetError());
return; return;
} }
if ttf.Init() < 0 { if ttf.Init() < 0 {
fmt.eprintln("SDL_TTF failed to initialize:", ttf.GetError()); log.error("SDL_TTF failed to initialize:", ttf.GetError());
return; return;
} }
defer ttf.Quit(); defer ttf.Quit();
@ -1068,7 +1075,7 @@ main :: proc() {
} }
if sdl_window == nil { if sdl_window == nil {
fmt.eprintln("Failed to create window:", sdl2.GetError()); log.error("Failed to create window:", sdl2.GetError());
return; return;
} }
@ -1078,7 +1085,7 @@ main :: proc() {
} }
if state.sdl_renderer == nil { if state.sdl_renderer == nil {
fmt.eprintln("Failed to create renderer:", sdl2.GetError()); log.error("Failed to create renderer:", sdl2.GetError());
return; return;
} }
state.font_atlas = core.gen_font_atlas(&state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf"); state.font_atlas = core.gen_font_atlas(&state, "/System/Library/Fonts/Supplemental/Andale Mono.ttf");
@ -1139,13 +1146,13 @@ main :: proc() {
} }
}, },
lua.L_Reg { lua.L_Reg {
"print", "log",
proc "c" (L: ^lua.State) -> i32 { proc "c" (L: ^lua.State) -> i32 {
context = state.ctx; context = state.ctx;
a := lua.L_checkinteger(L, 1); text := string(lua.L_checkstring(L, 1));
log.info("[LUA]:", text);
fmt.printf("LUA: print(%d)\n", a);
return i32(lua.OK); return i32(lua.OK);
} }
}, },
@ -1194,11 +1201,11 @@ main :: proc() {
if action, exists := input_map.key_actions[key]; exists { if action, exists := input_map.key_actions[key]; exists {
switch value in action.action { switch value in action.action {
case core.LuaEditorAction: case core.LuaEditorAction:
fmt.eprintln("Plugin attempted to register input group on existing key action (added from Lua)"); log.warn("Plugin attempted to register input group on existing key action (added from Lua)");
case core.PluginEditorAction: case core.PluginEditorAction:
fmt.eprintln("Plugin attempted to register input group on existing key action (added from Plugin)"); log.warn("Plugin attempted to register input group on existing key action (added from Plugin)");
case core.EditorAction: case core.EditorAction:
fmt.eprintln("Plugin attempted to register input group on existing key action"); log.warn("Plugin attempted to register input group on existing key action");
case core.InputActions: case core.InputActions:
input_map := &(&input_map.key_actions[key]).action.(core.InputActions); input_map := &(&input_map.key_actions[key]).action.(core.InputActions);
table_to_action(L, lua.gettop(L), input_map); table_to_action(L, lua.gettop(L), input_map);
@ -1258,7 +1265,7 @@ main :: proc() {
context = state.ctx; context = state.ctx;
buffer_index := int(lua.L_checkinteger(L, 1)); buffer_index := int(lua.L_checkinteger(L, 1));
if buffer_index < 0 || buffer_index >= len(state.buffers) { if buffer_index != -2 && (buffer_index < 0 || buffer_index >= len(state.buffers)) {
return i32(lua.ERRRUN); return i32(lua.ERRRUN);
} else { } else {
state.current_buffer = buffer_index; state.current_buffer = buffer_index;
@ -1301,7 +1308,7 @@ main :: proc() {
} }
} }
push_lua_buffer_info(L, &state.buffers[buffer_index]); push_lua_buffer_info(L, core.buffer_from_index(&state, buffer_index));
} }
return 1; return 1;
@ -1661,11 +1668,29 @@ main :: proc() {
if ui_ctx != nil { if ui_ctx != nil {
buffer_index := int(lua.L_checkinteger(L, 2)); buffer_index := int(lua.L_checkinteger(L, 2));
if buffer_index < 0 || buffer_index >= len(state.buffers) { if buffer_index != -2 && (buffer_index < 0 || buffer_index >= len(state.buffers)) {
return i32(lua.ERRRUN); return i32(lua.ERRRUN);
} }
ui_file_buffer(ui_ctx, &state.buffers[buffer_index]); ui_file_buffer(ui_ctx, core.buffer_from_index(&state, buffer_index));
return i32(lua.OK);
}
return i32(lua.ERRRUN);
}
},
lua.L_Reg {
"log_buffer",
proc "c" (L: ^lua.State) -> i32 {
context = state.ctx;
lua.L_checktype(L, 1, i32(lua.TLIGHTUSERDATA));
lua.pushvalue(L, 1);
ui_ctx := transmute(^ui.Context)lua.touserdata(L, -1);
if ui_ctx != nil {
ui_file_buffer(ui_ctx, &state.log_buffer);
return i32(lua.OK); return i32(lua.OK);
} }
@ -1675,6 +1700,7 @@ main :: proc() {
} }
}; };
// TODO: generate this from the plugin.Key enum
lua.newtable(L); lua.newtable(L);
{ {
lua.newtable(L); lua.newtable(L);
@ -1702,6 +1728,9 @@ main :: proc() {
lua.pushinteger(L, lua.Integer(plugin.Key.Q)); lua.pushinteger(L, lua.Integer(plugin.Key.Q));
lua.setfield(L, -2, "Q"); lua.setfield(L, -2, "Q");
lua.pushinteger(L, lua.Integer(plugin.Key.BACKQUOTE));
lua.setfield(L, -2, "Backtick");
lua.pushinteger(L, lua.Integer(plugin.Key.ESCAPE)); lua.pushinteger(L, lua.Integer(plugin.Key.ESCAPE));
lua.setfield(L, -2, "Escape"); lua.setfield(L, -2, "Escape");
@ -1748,7 +1777,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln(err); log.error(err);
} }
// Initialize Lua Plugins // Initialize Lua Plugins
@ -1760,7 +1789,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln("failed to initialize plugin (OnInit):", err); log.error("failed to initialize plugin (OnInit):", err);
} }
} }
// ********************************************************************** // **********************************************************************
@ -1768,7 +1797,7 @@ main :: proc() {
control_key_pressed: bool; control_key_pressed: bool;
for !state.should_close { for !state.should_close {
// if false { // if false {
// buffer := &state.buffers[state.current_buffer]; // buffer := core.current_buffer(&state);
// ui.push_parent(&ui_context, ui.push_box(&ui_context, "main", {}, .Vertical, semantic_size = {ui.make_semantic_size(.Fill, 100), ui.make_semantic_size(.Fill, 100)})); // ui.push_parent(&ui_context, ui.push_box(&ui_context, "main", {}, .Vertical, semantic_size = {ui.make_semantic_size(.Fill, 100), ui.make_semantic_size(.Fill, 100)}));
// defer ui.pop_parent(&ui_context); // defer ui.pop_parent(&ui_context);
@ -1824,7 +1853,7 @@ main :: proc() {
// defer ui.pop_parent(&ui_context); // defer ui.pop_parent(&ui_context);
// { // {
// if ui_file_buffer(&ui_context, &state.buffers[state.current_buffer]).clicked { // if ui_file_buffer(&ui_context, core.current_buffer(&state)).clicked {
// state.current_buffer = 3; // state.current_buffer = 3;
// } // }
// } // }
@ -1872,6 +1901,15 @@ main :: proc() {
// } // }
// } // }
// TODO: move this to view.lua
// log_window, _ := ui.push_floating(&ui_context, "log", {0,0}, flags = {.Floating, .DrawBackground}, semantic_size = {ui.make_semantic_size(.PercentOfParent, 75), ui.make_semantic_size(.PercentOfParent, 75)});
// ui.push_parent(&ui_context, log_window);
// {
// defer ui.pop_parent(&ui_context);
// ui_file_buffer(&ui_context, &state.log_buffer);
// }
for hook_ref in state.lua_hooks[plugin.Hook.Draw] { for hook_ref in state.lua_hooks[plugin.Hook.Draw] {
lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(hook_ref)); lua.rawgeti(state.L, lua.REGISTRYINDEX, lua.Integer(hook_ref));
lua.pushlightuserdata(state.L, &ui_context); lua.pushlightuserdata(state.L, &ui_context);
@ -1879,7 +1917,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln(err); log.error(err);
} else { } else {
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
} }
@ -1939,7 +1977,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln(err); log.error(err);
} else { } else {
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
} }
@ -1964,7 +2002,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln(err); log.error(err);
} else { } else {
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
} }
@ -1997,7 +2035,7 @@ main :: proc() {
if state.window != nil && state.window.get_buffer != nil { if state.window != nil && state.window.get_buffer != nil {
buffer = transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data)); buffer = transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data));
} else { } else {
buffer = &state.buffers[state.current_buffer]; buffer = core.current_buffer(&state);
} }
if sdl_event.type == .KEYDOWN { if sdl_event.type == .KEYDOWN {
@ -2024,7 +2062,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln(err); log.error(err);
} else { } else {
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
} }
@ -2054,7 +2092,7 @@ main :: proc() {
err := lua.tostring(L, lua.gettop(L)); err := lua.tostring(L, lua.gettop(L));
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
fmt.eprintln(err); log.error(err);
} else { } else {
lua.pop(L, lua.gettop(L)); lua.pop(L, lua.gettop(L));
} }
@ -2077,7 +2115,7 @@ main :: proc() {
buffer := transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data)); buffer := transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data));
do_normal_mode(&state, buffer); do_normal_mode(&state, buffer);
} else { } else {
buffer := &state.buffers[state.current_buffer]; buffer := core.current_buffer(&state);
do_normal_mode(&state, buffer); do_normal_mode(&state, buffer);
} }
case .Insert: case .Insert:
@ -2085,14 +2123,14 @@ main :: proc() {
buffer := transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data)); buffer := transmute(^core.FileBuffer)(state.window.get_buffer(state.plugin_vtable, state.window.user_data));
do_insert_mode(&state, buffer); do_insert_mode(&state, buffer);
} else { } else {
buffer := &state.buffers[state.current_buffer]; buffer := core.current_buffer(&state);
do_insert_mode(&state, buffer); do_insert_mode(&state, buffer);
} }
case .Visual: case .Visual:
if state.window != nil && state.window.get_buffer != nil { if state.window != nil && state.window.get_buffer != nil {
// TODO // TODO
} else { } else {
buffer := &state.buffers[state.current_buffer]; buffer := core.current_buffer(&state);
do_visual_mode(&state, buffer); do_visual_mode(&state, buffer);
} }
} }

View File

@ -3,6 +3,7 @@ package plugin;
import "core:intrinsics" import "core:intrinsics"
import "core:dynlib" import "core:dynlib"
import "core:fmt" import "core:fmt"
import "core:log"
import "../theme" import "../theme"
@ -419,7 +420,7 @@ load_proc_address :: proc(lib_path: string, library: dynlib.Library, symbol: str
if address, found := dynlib.symbol_address(library, symbol); found { if address, found := dynlib.symbol_address(library, symbol); found {
return transmute(ProcType)address; return transmute(ProcType)address;
} else { } else {
fmt.println("Could not find symbol", symbol, "in library", lib_path); log.warn("Could not find symbol", symbol, "in library", lib_path);
} }
return nil; return nil;

View File

@ -3,6 +3,7 @@ package ui
import "core:fmt" import "core:fmt"
import "core:strings" import "core:strings"
import "core:math" import "core:math"
import "core:log"
import "vendor:sdl2" import "vendor:sdl2"
import "../core" import "../core"
@ -652,19 +653,19 @@ debug_print :: proc(ctx: ^Context, box: ^Box, depth: int = 0) {
for box, idx in iterate_box(&iter, true) { for box, idx in iterate_box(&iter, true) {
for _ in 0..<(depth*6) { for _ in 0..<(depth*6) {
fmt.print("-"); log.debug("-");
} }
if depth > 0 { if depth > 0 {
fmt.print(">"); log.debug(">");
} }
fmt.println(idx, "Box _", box.label, "#", box.key.label, "ptr", transmute(rawptr)box); //, "_ first", transmute(rawptr)box.first, "parent", transmute(rawptr)box.parent, box.computed_size); log.debug(idx, "Box _", box.label, "#", box.key.label, "ptr", transmute(rawptr)box); //, "_ first", transmute(rawptr)box.first, "parent", transmute(rawptr)box.parent, box.computed_size);
debug_print(ctx, box, depth+1); debug_print(ctx, box, depth+1);
} }
if depth == 0 { if depth == 0 {
fmt.println("persistent"); log.debug("persistent");
for p in ctx.persistent { for p in ctx.persistent {
fmt.println(p); log.debug(p);
} }
} }
} }

12
todo.md Normal file
View File

@ -0,0 +1,12 @@
- Finish selections
- Guarantee that start and end are always ordered
- Add in text actions
- Yank
- Delete
- Change
- Re-write the UI (again)
- Re-do dylib plugin system
- Re-do Lua plugin system
- Persist end of line cursor position
- Generate key mappings from the plugin.Key enum
- Fix jumping forward a word jumping past consecutive brackets