4coder/power/4coder_chronal.cpp

305 lines
9.2 KiB
C++

// TOP
#include "4coder_default.cpp"
//#include "chr_winutils.h"
#ifndef literal
#define literal(s) (s), (sizeof(s)-1)
#endif
#define rgb_color(r, g, b) (r << 16 + g << 8 + b << 0)
#define hex_color(hex) hex
const int color_margin_normal = 0x341313;
const int color_margin_insert = 0x5a3619;
enum Vim_Maps {
mapid_normal = mapid_global,
mapid_insert = 0,
mapid_replace,
mapid_visual,
// There are a bunch of different chord "starters" that result in keys having
// different behaviors. There's no better way to handle this right now than
// just explicitly creating maps for each one.
//TODO(chronister): Chords can be built up, so this can have potentially huge
//combinatorics... what I *want* is a way to build up an actual stack of commands
//...
mapid_chord_delete,
mapid_chord_yank,
mapid_chord_g,
};
HOOK_SIG(chronal_init){
exec_command(app, cmdid_open_panel_vsplit);
exec_command(app, cmdid_change_active_panel);
app->change_theme(app, literal("4coder"));
app->change_font(app, literal("hack"));
const int color_bg = 0x15100f;
const int color_bar = 0x1c1212;
const int color_bar_hover = 0x261414;
const int color_bar_active = 0x341313;
const int color_text = 0x916550;
const int color_comment = 0x9d5b25;
const int color_string_literal = 0x9c2d21;
const int color_num_literals = 0xc56211;
const int color_keyword = 0xf74402;
Theme_Color colors[] = {
{ Stag_Back, color_bg },
{ Stag_Margin, color_bar },
{ Stag_Margin_Hover, color_bar_hover },
{ Stag_Margin_Active, color_margin_normal },
{ Stag_Bar, color_bar },
{ Stag_Bar_Active, color_bar_active },
{ Stag_Base, color_text },
{ Stag_Default, color_text },
{ Stag_Comment, color_comment },
{ Stag_Int_Constant, color_num_literals },
{ Stag_Float_Constant, color_num_literals },
{ Stag_Str_Constant, color_string_literal },
{ Stag_Char_Constant, color_string_literal },
{ Stag_Bool_Constant, color_keyword },
{ Stag_Keyword, color_keyword },
{ Stag_Special_Character, color_keyword },
{ Stag_Preproc, color_keyword },
};
app->set_theme_colors(app, colors, ArrayCount(colors));
push_parameter(app, par_key_mapid, mapid_normal);
exec_command(app, cmdid_set_settings);
// no meaning for return
return(0);
}
HOOK_SIG(chronal_file_settings){
// NOTE(allen|a4): In hooks that want parameters, such as this file
// created hook. The file created hook is guaranteed to have only
// and exactly one buffer parameter. In normal command callbacks
// there are no parameter buffers.
Buffer_Summary buffer = app->get_parameter_buffer(app, 0);
assert(buffer.exists);
int treat_as_code = 0;
if (buffer.file_name && buffer.size < (16 << 20)){
String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len));
if (match(ext, make_lit_string("cpp"))) treat_as_code = 1;
else if (match(ext, make_lit_string("h"))) treat_as_code = 1;
else if (match(ext, make_lit_string("c"))) treat_as_code = 1;
else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1;
}
push_parameter(app, par_lex_as_cpp_file, treat_as_code);
push_parameter(app, par_wrap_lines, !treat_as_code);
push_parameter(app, par_key_mapid, mapid_normal);
exec_command(app, cmdid_set_settings);
// no meaning for return
return(0);
}
/* *
* Custom commands *
* */
CUSTOM_COMMAND_SIG(do_nothing){
}
CUSTOM_COMMAND_SIG(enter_insert_mode){
push_parameter(app, par_key_mapid, mapid_insert);
exec_command(app, cmdid_set_settings);
Theme_Color colors[] = {
{ Stag_Bar_Active, color_margin_insert },
{ Stag_Margin_Active, color_margin_insert },
};
app->set_theme_colors(app, colors, ArrayCount(colors));
}
CUSTOM_COMMAND_SIG(enter_normal_mode){
push_parameter(app, par_key_mapid, mapid_normal);
exec_command(app, cmdid_set_settings);
Theme_Color colors[] = {
{ Stag_Bar_Active, color_margin_normal },
{ Stag_Margin_Active, color_margin_normal },
};
app->set_theme_colors(app, colors, ArrayCount(colors));
}
CUSTOM_COMMAND_SIG(seek_forward_word_start){
View_Summary view;
view = app->get_active_view(app);
push_parameter(app, par_flags, BoundryToken);
exec_command(app, cmdid_seek_right);
app->refresh_view(app, &view);
}
CUSTOM_COMMAND_SIG(seek_backward_word_start){
View_Summary view;
view = app->get_active_view(app);
push_parameter(app, par_flags, BoundryToken | BoundryWhitespace);
exec_command(app, cmdid_seek_left);
app->refresh_view(app, &view);
}
CUSTOM_COMMAND_SIG(seek_forward_word_end){
View_Summary view;
view = app->get_active_view(app);
push_parameter(app, par_flags, BoundryToken | BoundryWhitespace);
exec_command(app, cmdid_seek_right);
app->refresh_view(app, &view);
}
CUSTOM_COMMAND_SIG(newline_then_insert_before){
exec_command(app, cmdid_seek_beginning_of_line);
write_string(app, make_lit_string("\n"));
exec_command(app, cmdid_move_left);
exec_command(app, enter_insert_mode);
}
CUSTOM_COMMAND_SIG(newline_then_insert_after){
exec_command(app, cmdid_seek_end_of_line);
write_string(app, make_lit_string("\n"));
exec_command(app, enter_insert_mode);
}
CUSTOM_COMMAND_SIG(begin_chord_delete){
push_parameter(app, par_key_mapid, mapid_chord_delete);
exec_command(app, cmdid_set_settings);
}
CUSTOM_COMMAND_SIG(delete_line){
View_Summary view;
Buffer_Summary buffer;
int pos1, pos2;
view = app->get_active_view(app);
exec_command(app, cmdid_seek_beginning_of_line);
app->refresh_view(app, &view);
pos1 = view.cursor.pos;
exec_command(app, cmdid_seek_end_of_line);
app->refresh_view(app, &view);
pos2 = view.cursor.pos;
Range range = make_range(pos1, pos2);
buffer = app->get_buffer(app, view.buffer_id);
app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0);
}
CUSTOM_COMMAND_SIG(delete_word){
View_Summary view;
Buffer_Summary buffer;
int pos1, pos2;
view = app->get_active_view(app);
exec_command(app, seek_backward_word_start);
app->refresh_view(app, &view);
pos1 = view.cursor.pos;
exec_command(app, seek_forward_word_end);
app->refresh_view(app, &view);
pos2 = view.cursor.pos;
Range range = make_range(pos1, pos2);
buffer = app->get_buffer(app, view.buffer_id);
app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0);
}
void
chronal_get_bindings(Bind_Helper *context){
set_hook(context, hook_start, chronal_init);
set_hook(context, hook_open_file, chronal_file_settings);
set_scroll_rule(context, smooth_scroll_rule);
/* *
* SECTION: Vim keybindings *
* */
/* Normal mode.
* aka "It's eating all my input, help!" mode.
* Shortcuts for navigation, entering various modes,
* dealing with the editor.
*/
begin_map(context, mapid_normal);
bind_vanilla_keys(context, do_nothing);
bind(context, 'w', MDFR_NONE, seek_forward_word_start);
bind(context, 'e', MDFR_NONE, seek_forward_word_end);
bind(context, 'b', MDFR_NONE, seek_backward_word_start);
bind(context, '$', MDFR_NONE, cmdid_seek_end_of_line);
bind(context, '0', MDFR_NONE, cmdid_seek_beginning_of_line);
bind(context, 'h', MDFR_NONE, cmdid_move_left);
bind(context, 'j', MDFR_NONE, cmdid_move_down);
bind(context, 'k', MDFR_NONE, cmdid_move_up);
bind(context, 'l', MDFR_NONE, cmdid_move_right);
bind(context, 'u', MDFR_CTRL, cmdid_page_up);
bind(context, 'd', MDFR_CTRL, cmdid_page_down);
bind(context, 'x', MDFR_NONE, cmdid_delete);
bind(context, 'u', MDFR_NONE, cmdid_undo);
bind(context, 'r', MDFR_CTRL, cmdid_redo);
bind(context, '/', MDFR_NONE, search);
bind(context, 'i', MDFR_NONE, enter_insert_mode);
bind(context, 'o', MDFR_NONE, newline_then_insert_after);
bind(context, 'O', MDFR_NONE, newline_then_insert_before);
bind(context, 'n', MDFR_CTRL, cmdid_word_complete);
// TEMP (will be replaced later by :statusbar commands)
bind(context, 'o', MDFR_CTRL, cmdid_interactive_open);
bind(context, 'c', MDFR_CTRL, cmdid_open_color_tweaker);
end_map(context);
/* Insert mode
* You type and it goes into the buffer. Nice and simple.
* Escape to exit.
*/
begin_map(context, mapid_insert);
inherit_map(context, mapid_nomap);
bind_vanilla_keys(context, cmdid_write_character);
bind(context, key_back, MDFR_NONE, cmdid_backspace);
bind(context, key_esc, MDFR_NONE, enter_normal_mode);
end_map(context);
#if 1
/* Chord "modes".
* They're not really an explicit mode per-say, but the meaning of key presses
* does change once a chord starts, and is context-dependent.
* TODO(chronister): I want these to properly build on each other.
*/
begin_map(context, mapid_chord_delete);
inherit_map(context, mapid_nomap);
bind(context, 'd', MDFR_NONE, delete_line);
bind(context, 'w', MDFR_NONE, delete_word);
end_map(context);
#endif
}