logging
parent
ac9d33be92
commit
caaa8ebbd5
6
Makefile
6
Makefile
|
@ -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
|
||||||
|
|
|
@ -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,10 +102,12 @@ 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")
|
||||||
|
if ActiveCodeView ~= nil then
|
||||||
Editor.set_current_buffer_from_index(i)
|
Editor.set_current_buffer_from_index(i)
|
||||||
add_buffer_to_code_view(ActiveCodeView+1, buffer_info.file_path, 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)
|
||||||
if tab_button_interaction.clicked then
|
if tab_button_interaction.clicked then
|
||||||
|
@ -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 ()
|
||||||
|
|
|
@ -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 {
|
||||||
|
|
|
@ -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,10 +563,12 @@ 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);
|
||||||
|
|
||||||
|
for _ in 0..<amt {
|
||||||
if !stop_at_end || cursor.?.col < line_length-1 {
|
if !stop_at_end || cursor.?.col < line_length-1 {
|
||||||
iterate_file_buffer(&it);
|
iterate_file_buffer(&it);
|
||||||
cursor.?^ = it.cursor;
|
cursor.?^ = it.cursor;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
move_cursor_forward_start_of_word :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cursor) = nil) {
|
move_cursor_forward_start_of_word :: proc(buffer: ^FileBuffer, cursor: Maybe(^Cursor) = nil) {
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if !append_to_end {
|
||||||
update_file_buffer_index_from_cursor(buffer);
|
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
|
||||||
|
|
|
@ -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);
|
||||||
|
}
|
208
src/main.odin
208
src/main.odin
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
Loading…
Reference in New Issue