4.0.9 release ready
parent
5e0030825b
commit
3683069f24
|
@ -933,12 +933,14 @@ CUSTOM_COMMAND_SIG(close_panel){
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(open_panel_vsplit){
|
CUSTOM_COMMAND_SIG(open_panel_vsplit){
|
||||||
View_Summary view = app->get_active_view(app, AccessAll);
|
View_Summary view = app->get_active_view(app, AccessAll);
|
||||||
app->open_view(app, &view, ViewSplit_Right);
|
View_Summary new_view = app->open_view(app, &view, ViewSplit_Right);
|
||||||
|
app->view_set_setting(app, &new_view, ViewSetting_ShowScrollbar, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(open_panel_hsplit){
|
CUSTOM_COMMAND_SIG(open_panel_hsplit){
|
||||||
View_Summary view = app->get_active_view(app, AccessAll);
|
View_Summary view = app->get_active_view(app, AccessAll);
|
||||||
app->open_view(app, &view, ViewSplit_Bottom);
|
View_Summary new_view = app->open_view(app, &view, ViewSplit_Bottom);
|
||||||
|
app->view_set_setting(app, &new_view, ViewSetting_ShowScrollbar, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
6
4ed.cpp
6
4ed.cpp
|
@ -275,7 +275,7 @@ panel_make_empty(System_Functions *system, App_Vars *vars, Panel *panel){
|
||||||
|
|
||||||
Assert(panel->view == 0);
|
Assert(panel->view == 0);
|
||||||
new_view = live_set_alloc_view(&vars->live_set, panel, models);
|
new_view = live_set_alloc_view(&vars->live_set, panel, models);
|
||||||
view_set_file(new_view.view, 0, models);
|
view_set_file(new_view.view, models->scratch_buffer, models);
|
||||||
new_view.view->map = get_map(models, mapid_global);
|
new_view.view->map = get_map(models, mapid_global);
|
||||||
|
|
||||||
return(new_view.view);
|
return(new_view.view);
|
||||||
|
@ -2673,9 +2673,9 @@ App_Step_Sig(app_step){
|
||||||
"-A scratch buffer is now opened with 4coder automatically\n"
|
"-A scratch buffer is now opened with 4coder automatically\n"
|
||||||
"-A new mouse suppression mode toggled by <F2>\n"
|
"-A new mouse suppression mode toggled by <F2>\n"
|
||||||
"-Hinting is disabled by default, a -h flag on the command line enables it\n"
|
"-Hinting is disabled by default, a -h flag on the command line enables it\n"
|
||||||
"-New 4coder_API.html documentation file included for the custom layer API\n"
|
"-New 4coder_API.html documentation file provided for the custom layer API\n"
|
||||||
"-Experimental new work-flow for building and jumping to errors\n"
|
"-Experimental new work-flow for building and jumping to errors\n"
|
||||||
" (only available in power for this build)\n"
|
" This system is only for MSVC in the 'power' version as of 4.0.9\n"
|
||||||
"\n"
|
"\n"
|
||||||
"New in alpha 4.0.8:\n"
|
"New in alpha 4.0.8:\n"
|
||||||
"-Eliminated the parameter stack\n"
|
"-Eliminated the parameter stack\n"
|
||||||
|
|
|
@ -1158,6 +1158,8 @@ DOC_SEE(View_Split_Position)
|
||||||
|
|
||||||
models->layout.active_panel = (i32)(split.panel - models->layout.panels);
|
models->layout.active_panel = (i32)(split.panel - models->layout.panels);
|
||||||
panel_make_empty(system, cmd->vars, split.panel);
|
panel_make_empty(system, cmd->vars, split.panel);
|
||||||
|
|
||||||
|
fill_view_summary(&result, split.panel->view, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
update_command_data(cmd->vars, cmd);
|
update_command_data(cmd->vars, cmd);
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
Distribution Date: 4.7.2016 (dd.mm.yyyy)
|
Distribution Date: 5.7.2016 (dd.mm.yyyy)
|
||||||
|
|
||||||
Thank you for contributing to the 4coder project!
|
Thank you for contributing to the 4coder project!
|
||||||
|
|
||||||
|
|
423
SUPERREADME.txt
423
SUPERREADME.txt
|
@ -1,4 +1,4 @@
|
||||||
Distribution Date: 4.7.2016 (dd.mm.yyyy)
|
Distribution Date: 5.7.2016 (dd.mm.yyyy)
|
||||||
|
|
||||||
Thank you for contributing to the 4coder project!
|
Thank you for contributing to the 4coder project!
|
||||||
|
|
||||||
|
@ -22,423 +22,10 @@ updates may deeply break your code.
|
||||||
SOME DOCUMENTATION
|
SOME DOCUMENTATION
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
See comments in 4coder_default_bindings.cpp for more detailed information.
|
NEW IN 4.0.9
|
||||||
|
|
||||||
Functions to implement (optional in the dll, but required if you are using buildsuper.bat):
|
|
||||||
get_bindings
|
|
||||||
|
|
||||||
NEW IN 4.0.7
|
|
||||||
================
|
================
|
||||||
Moved a lot of commands to the custom side. Almost all of them have the same name
|
|
||||||
they use to have just without cmdid_ on the front. Other than that cmdid_backspace
|
|
||||||
became backspace_char, and cmdid_delete became delete_char.
|
|
||||||
|
|
||||||
Left and right clicks are now associated to key codes for bindings
|
|
||||||
|
|
||||||
app->get_mouse_state returns the current mouse
|
|
||||||
|
|
||||||
NEW IN 4.0.5:
|
|
||||||
================
|
|
||||||
app->buffer_compute_cursor to get cursor position info without moving the cursor
|
|
||||||
|
|
||||||
can now use f keys for bindings
|
|
||||||
|
|
||||||
NEW IN 4.0.3:
|
|
||||||
================
|
|
||||||
The build system for customizations has been changed. There is no longer a 4coder_custom.cpp.
|
|
||||||
Instead the default customizations are in 4coder_default_bindings.cpp. The batch file takes a parameter
|
|
||||||
that tells it what file to treat as the target for building, if the parameter is not defined it defaults to
|
|
||||||
4coder_default_bindings.cpp.
|
|
||||||
|
|
||||||
NEW IN 4.0.2:
|
|
||||||
================
|
|
||||||
#include "4coder_default.cpp" at the top of your own file to get a lot of the default functions
|
|
||||||
such as incremental search, various word boundry seeks, and so on.
|
|
||||||
|
|
||||||
app->buffer_seek_string_insensitive(app, &buffer, start, str, len, seek_forward, &out);
|
|
||||||
Exactly the same as app->buffer_seek_string, but the matching rule is case insensitive
|
|
||||||
|
|
||||||
app->get_command_input(app);
|
|
||||||
Returns a User_Input that represents the input event that triggered the current command.
|
|
||||||
|
|
||||||
app->print_message(app, str, len);
|
|
||||||
Put a string into the *message* buffer.
|
|
||||||
|
|
||||||
OLD API DOC:
|
|
||||||
================================================================
|
|
||||||
There is an API available to custom commands and hooks, described at length here.
|
|
||||||
The system has two main data types, buffers and views. A buffer contains text,
|
|
||||||
undo history, and tokens. Views looks at a file and has a cursor a mark a highlight
|
|
||||||
and so on. The view and buffer are not the same because not all buffers are viewed,
|
|
||||||
and there may be two views viewing the same buffer.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->memory;
|
|
||||||
app->memory_size;
|
|
||||||
Here you get 2mb of memory that are completely yours to do whatever you need to do. This is for
|
|
||||||
those who found that malloc was not working for their allocation needs. There are currently no
|
|
||||||
allocation helpers so you'll have to figure out how to manage it.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->directory_get_hot(app, out, capacity);
|
|
||||||
Fills the out buffer with the "hot directory", which is the last directory 4coder has visited.
|
|
||||||
If it cannot write out the whole name it writes only what it can.
|
|
||||||
|
|
||||||
Always returns the length of the current hot directory in bytes.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->file_exists(app, filename, len);
|
|
||||||
Filename can be either a full path or a relative path.
|
|
||||||
|
|
||||||
Returns whether the file exists.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->directory_cd(app, dir, &len, capacity, rel_path, rel_len);
|
|
||||||
Looks at dir and updates it's contents as if a "cd" command had been cone from that directory.
|
|
||||||
if rel_path is ".." then the .. is not appended as a string, the directory is shortened if possible.
|
|
||||||
|
|
||||||
Returns false if the directory does not exist or if ".." was specified but it is impossible to back up,
|
|
||||||
returns true otherwise.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_file_list(app, dir, len);
|
|
||||||
If the directory exists, generates a list of all files and folders in that directory. All File_List structs
|
|
||||||
generated by get_file_list should be freed with free_file_list.
|
|
||||||
|
|
||||||
Returns a File_List struct listing all files and folders in dir, or an empty list if dir does not exist or is empty.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->free_file_list(app, list);
|
|
||||||
Frees a File_List created by get_file_list.
|
|
||||||
|
|
||||||
================
|
|
||||||
struct File_List;
|
|
||||||
The important fields are:
|
|
||||||
File_Info *infos;
|
|
||||||
int count;
|
|
||||||
count is the number of File_Info structs in the File_Info array.
|
|
||||||
|
|
||||||
struct File_Info;
|
|
||||||
String filename;
|
|
||||||
int folder;
|
|
||||||
folder is 1 or 0 to indicate whether the entry is a file or folder.
|
|
||||||
filrname is a string which may be editted, but not resized, that is filled with the name of a file or folder.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_buffer_first(app);
|
|
||||||
app->get_buffer_next(app, &buffer);
|
|
||||||
The new method for looping over buffers is:
|
|
||||||
|
|
||||||
for (Buffer_Summary b = app->get_buffer_first(app);
|
|
||||||
b.exists;
|
|
||||||
app->get_buffer_next(app, &b)) { }
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_buffer(app, index);
|
|
||||||
Returns a Buffer_Summary which contains information about a buffer and acts as the
|
|
||||||
handle to the buffer for other functions. The parameter index can be anything in the
|
|
||||||
range [0,max) where max comes from app->get_buffer_max_index
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_active_buffer(app, index);
|
|
||||||
Returns a Buffer_Summary obtained from the active panel.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_buffer_by_name(app, str, len);
|
|
||||||
Returns a Buffer_Summary who's "full source path" exactly matches str. There is
|
|
||||||
currently no way to look a buffer up by "live name" the short name shown on the top bar.
|
|
||||||
|
|
||||||
Buffers that are not associated with real files such as *compilation* have their "full source path"
|
|
||||||
name set to the same value as their live name, therefore you can get a *compilation* buffer with
|
|
||||||
this API by the name "*compilation*".
|
|
||||||
|
|
||||||
================
|
|
||||||
app->refresh_buffer(app, &buffer);
|
|
||||||
If a changes are made to a buffer the changes are not necessarily reflected in your Buffer_Summary,
|
|
||||||
use this to get updated information on the buffer. All commands in the low level API will udpate
|
|
||||||
your Buffer_Summary if a change is made, so refreshing afterwards is not necessary in that case.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_seek_delimiter(app, &buffer, start, delim, seek_forward, &out);
|
|
||||||
Starting from start, seeks forward or backward until the first occurance of delim,
|
|
||||||
the pointer out is filled with the position of the delimiter.
|
|
||||||
|
|
||||||
If no delimiter is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_seek_string(app, &buffer, start, str, len, seek_forward, &out);
|
|
||||||
Starting from start, seeks forward or backward until the first occurance of str,
|
|
||||||
the pointer out is filled with the position of the delimiter.
|
|
||||||
|
|
||||||
If no str is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_read_range(app, &buffer, start, end, buffer_out);
|
|
||||||
Fills buffer_out with the text that the buffer contains in the range [start,end) it is your responsibility
|
|
||||||
to ensure that the memory pointed to by buffer_out is at least (end - start) bytes.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_replace_range(app, &buffer, start, end, str, len);
|
|
||||||
Replaces the text in the range between start and end with the the text in str. It is allowed that
|
|
||||||
start == end so that you may insert str without replacing anything, and it is allowed that len == 0
|
|
||||||
so that you may delete text without replacing it with anything. These edits are tracked by history
|
|
||||||
and cause an update in the tokens if there are tokens. Your buffer will be updated to reflect
|
|
||||||
the change in the buffer caused by this edit.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
View_Summary:
|
|
||||||
There use to be a lot of different view types and only "file views" were exposed in the API.
|
|
||||||
As of alpha 4 there are only views and you can always get a view.
|
|
||||||
|
|
||||||
Besides renaming the struct, there is also a change in the meaning of the "buffer_id" field.
|
|
||||||
A view can have a buffer attached, but not currently be looking at that file.
|
|
||||||
|
|
||||||
All of the following indicate the buffer associated with the view:
|
|
||||||
buffer_id
|
|
||||||
locked_buffer_id
|
|
||||||
hidden_buffer_id
|
|
||||||
|
|
||||||
These ids are nulled out to indicate that access at a particular level is not available.
|
|
||||||
buffer_id -
|
|
||||||
This is null if the file is not visible in the view OR if the view is locked.
|
|
||||||
A view is only locked right now for read only buffers (compilation output).
|
|
||||||
|
|
||||||
locked_buffer_id -
|
|
||||||
This is null only if the file is not visible.
|
|
||||||
|
|
||||||
hidden_buffer_id -
|
|
||||||
This is never null.
|
|
||||||
|
|
||||||
In normal circumstances you can just use buffer_id and your code will automatically do
|
|
||||||
nothing when you try to edit a buffer you should not.
|
|
||||||
|
|
||||||
If what you are writing is unusual and it SHOULD edit a buffer even if it is locked or
|
|
||||||
hidden, then you can use the other ids to get deeper access.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_view_first(app);
|
|
||||||
app->get_view_next(app, &view);
|
|
||||||
The new method for looping over views is:
|
|
||||||
|
|
||||||
for (View_Summary v = app->get_view_first(app);
|
|
||||||
v.exists;
|
|
||||||
app->get_view_next(app, &v)) { }
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_file_view(app, index);
|
|
||||||
Returns a View_Summary which contains information about a file view and acts as
|
|
||||||
the handle to the file view for other functions. The parameter index can be anything in the
|
|
||||||
range [0,max) where max comes from app->get_view_max_index
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_active_file_view(app, index);
|
|
||||||
Returns a View_Summary obtained from the active panel.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->refresh_file_view(app, &view);
|
|
||||||
If a changes are made to a view the changes are not necessarily reflected in your View_Summary,
|
|
||||||
use this to get updated information on the view. All commands in the low level API will udpate
|
|
||||||
your View_Summary if a change is made, so refreshing afterwards is not necessary in that case.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
struct Buffer_Seek;
|
|
||||||
This struct specifies how to set a position in a file, it is in 4coder_buffer_types.h look there to see
|
|
||||||
all the options.
|
|
||||||
|
|
||||||
The following helpers will return Buffer_Seek structs for you:
|
|
||||||
+ To seek to a particular position (0-based-indexing) use seek_pos(pos)
|
|
||||||
+ To seek to a particular xy you either want seek_wrapped_xy(x, y, round_down)
|
|
||||||
or seek_unwrapped_xy(x, y, round_down). Wrapped vs unwrapped refers to whether
|
|
||||||
line wrapping is on. Both seek types are valid whether or not lines are wrapped, but
|
|
||||||
the results may be surprising if you do not match the correct type. round_down is usually 0,
|
|
||||||
and the effect is subtle, it has to do with whether the y position should be rounded down or rounded
|
|
||||||
to the nearest line. x and y are specified in pixels to move the y up or down a while line use view.line_height.
|
|
||||||
+ To seek to a particular line and character index on that line use seek_line_char(line, char_index)
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_cursor(app, &view, seek, set_preferred_x)
|
|
||||||
Updates the cursor location in this view. See information on the Buffer_Seek struct above for more
|
|
||||||
information. set_preferred_x if true set's the "preferred_x" of view to match the x of the cursor. The
|
|
||||||
preferred_x is the x the cursor tries to stay at as it moves up and down. Most cursor motion does set
|
|
||||||
the preferred_x.
|
|
||||||
|
|
||||||
The function updates the data in the View_Summary.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_mark(app, &view, seek)
|
|
||||||
Updates the mark location in this view. See information on the Buffer_Seek struct above for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
The function updates the data in the View_Summary.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_highlight(app, &view, start, end, on)
|
|
||||||
If on is 0 this call turns the highlight off.
|
|
||||||
If on is 1 this call turns the highlight on and sets the highlight to range from start to end.
|
|
||||||
|
|
||||||
While the highlight is on the view will follow the end of the highlight and the cursor will be hidden.
|
|
||||||
Be sure to turn the highlight off when you're done with it!
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_file(app, &view, file_id)
|
|
||||||
Set this view to look at a different buffer (the buffer must already be opened and have a file_id).
|
|
||||||
|
|
||||||
The function updates the data in the View_Summary.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_user_input(app, get_type, abort_type);
|
|
||||||
This is a blocking operation that will allow 4coder to continue operating. The next input event
|
|
||||||
will be intercepted by this command, and will not be interpreted as normal. Input events include:
|
|
||||||
pressing a key
|
|
||||||
clicking left or right
|
|
||||||
rolling the mouse wheel
|
|
||||||
moving the mouse
|
|
||||||
|
|
||||||
The get_type flags specify a filter of what types of input you'd like to be notified about. Even if you
|
|
||||||
are not notified about keyboard input events, they are still not passed to any other systems to be
|
|
||||||
interpreted as commands or text input. The same is true for mouse input with the exception of
|
|
||||||
panel resizing, which can be done durring a command.
|
|
||||||
|
|
||||||
The abort_type flags specify the set of inputs you'd like to get an abort message on. It is good to
|
|
||||||
specify abort flags so that the system will know when your command is about to finish up. After
|
|
||||||
getting an abort message you can continue to do other work and call commands with exec_command
|
|
||||||
but you should not call app->get_user_input again. It will not cause an error if you do, but it could lead
|
|
||||||
to unexpected behavior. And in the future it might be that it IS an error to call get_user_input after an abort.
|
|
||||||
|
|
||||||
================
|
|
||||||
struct User_Input;
|
|
||||||
type: either UserInputKey or UserInputMouse
|
|
||||||
abort: true if this is an abort message, false otherwise
|
|
||||||
key: information about a key event
|
|
||||||
mouse: information about a mouse event
|
|
||||||
command: if this event would be translated into a command normally, this is the command.
|
|
||||||
|
|
||||||
Use CommandEqual to compare two commands in a typeless way since
|
|
||||||
cmdid_* and custom commands have different types.
|
|
||||||
|
|
||||||
================
|
|
||||||
key is of type:
|
|
||||||
struct Key_Event_Data;
|
|
||||||
keycode: always set to exactly the key that was pressed
|
|
||||||
character: a translation of the key press that takes into account Shift/Control/Alt/AltrGr/Caps-Lock
|
|
||||||
character_no_caps_lock: same as "character" but doesn't take Caps-Lock into account
|
|
||||||
|
|
||||||
modifiers[i]: flags for modifiers were held when this key was pressed
|
|
||||||
i: MDFR_SHIFT_INDEX, MDFR_CONTROL_INDEX, MDFR_ALT_INDEX, MDFR_CAPS_INDEX
|
|
||||||
|
|
||||||
TIP! Don't use MDFR_SHIFT, MDFR_CTRL, MDFR_ALT in the array! Those are bit masks, not indices!
|
|
||||||
|
|
||||||
================
|
|
||||||
mouse is of type:
|
|
||||||
struct Mouse_State;
|
|
||||||
l - whether the left button is down
|
|
||||||
r - whether the right button is down
|
|
||||||
press_l - whether the left button was just put down
|
|
||||||
press_r - whether the right button was just put down
|
|
||||||
release_l - whether the left button was just released
|
|
||||||
release_r - whether the right button was just released
|
|
||||||
wheel - values of 1, 0, -1. Does not report wheel amount, only direction.
|
|
||||||
out_of_window - 1 if the mouse is outside of the 4coder window, 0 otherwise
|
|
||||||
x, y - position of the mouse relative to the 4coder window
|
|
||||||
|
|
||||||
================
|
|
||||||
app->start_query_bar(app, &bar, 0);
|
|
||||||
Notify 4coder that you are using a Query_Bar and you want it rendered onto the screen.
|
|
||||||
While the query bar is still running any changes you make to prompt or string will be
|
|
||||||
shown right away, you don't have to ask 4coder to update it's bar because it reads straight
|
|
||||||
out of your Query_Bar.
|
|
||||||
|
|
||||||
If the pointer you pass goes bad, because a stack frame ends or you otherwise no longer
|
|
||||||
need the bar, you should call app->end_query_bar(app, &bar); so that 4coder doesn't try
|
|
||||||
to render a query bar from garbage memory. If the command finishes and there are query
|
|
||||||
bars that haven't been ended, 4coder automatically ends them.
|
|
||||||
|
|
||||||
There is a limit of 8 simultaneous queries bars and right now only file views support them.
|
|
||||||
The abillity to make a Query_Bar in other views including the empty view will come in the future though.
|
|
||||||
|
|
||||||
The 0 is there because Iintend to add flags for query bars in the future,
|
|
||||||
for modifying their appearance and behavior.
|
|
||||||
|
|
||||||
Returns 1 if it successfully started a query bar.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->end_query_bar(app, &bar);
|
|
||||||
See start_query_bar for details.
|
|
||||||
|
|
||||||
================
|
|
||||||
Theme changing API
|
|
||||||
|
|
||||||
app->change_theme(app, name, len)
|
|
||||||
Set the theme to one of the prebuilt themes by name.
|
|
||||||
|
|
||||||
app->change_font(app, name, len)
|
|
||||||
Set the font to one of the fonts by name (not by ttf file name, by the name in the list).
|
|
||||||
|
|
||||||
app->set_theme_colors(app, colors, count)
|
|
||||||
Set colors of the current theme by tag color pairs.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes from 3.3 to 3.4:
|
|
||||||
-exposed command word complete
|
|
||||||
|
|
||||||
Changes from 3.2 to 3.3:
|
|
||||||
-exposed command build and added several example uses to the example file
|
|
||||||
-introduced directory navigation API
|
|
||||||
-slight tweaks to the API, moving away from macro translation
|
|
||||||
|
|
||||||
Changes from 3.1 to 3.2:
|
|
||||||
-exposed new commands relating to auto-tab
|
|
||||||
-removed old commands for whitespace cleaning
|
|
||||||
|
|
||||||
Changes from 3.0 to 3.1:
|
|
||||||
-start_hook eliminated, now bound through set_hook durring the get_bindings function
|
|
||||||
-vanilla_keys changed so that specific keys can be overriden
|
|
||||||
-you can now specify your own maps
|
|
||||||
-new parameter stack for communicating to some commands
|
|
||||||
-fulfill_interaction has been removed (push_parameter will be used to achieve it's effect)
|
|
||||||
-new hook for opening files, intended for file setting configuration
|
|
||||||
-exposed the new commands relating to history and the timeline scrub bar
|
|
||||||
|
|
||||||
Changes from 2.2.3 to 3.0:
|
|
||||||
-exposed the new undo / redo commands
|
|
||||||
|
|
||||||
Changes from 2.2.2 to 2.2.3:
|
|
||||||
-The binding API is remarkably different, but I included a
|
|
||||||
small set of helpers with this API that make the API look
|
|
||||||
almost exactly the same.
|
|
||||||
-you can now specify size for custom fonts
|
|
||||||
-you can now fulfill interacive commands
|
|
||||||
-fixed a bug that existed when some commands were used in exec_command
|
|
||||||
|
|
||||||
Changes from 2.2.1 to 2.2.2:
|
|
||||||
-added MDFR_SHIFT
|
|
||||||
-removed redundant keys from Key_Codes struct
|
|
||||||
-added bind_me
|
|
||||||
-added exec_command
|
|
||||||
-put bind, bind_me and exec_command into a struct
|
|
||||||
-added Custom_Command_Function
|
|
||||||
-added Start_Hook_Function
|
|
||||||
|
|
||||||
|
|
||||||
|
I am deprecating this readme file now. A much better documentation than what I used to
|
||||||
|
provide here is now provided in 4coder_API.html. This is the last version that will
|
||||||
|
feature SUPERREADME.
|
||||||
|
|
||||||
|
|
|
@ -14,423 +14,10 @@ updates may deeply break your code.
|
||||||
SOME DOCUMENTATION
|
SOME DOCUMENTATION
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
|
|
||||||
See comments in 4coder_default_bindings.cpp for more detailed information.
|
NEW IN 4.0.9
|
||||||
|
|
||||||
Functions to implement (optional in the dll, but required if you are using buildsuper.bat):
|
|
||||||
get_bindings
|
|
||||||
|
|
||||||
NEW IN 4.0.7
|
|
||||||
================
|
================
|
||||||
Moved a lot of commands to the custom side. Almost all of them have the same name
|
|
||||||
they use to have just without cmdid_ on the front. Other than that cmdid_backspace
|
|
||||||
became backspace_char, and cmdid_delete became delete_char.
|
|
||||||
|
|
||||||
Left and right clicks are now associated to key codes for bindings
|
|
||||||
|
|
||||||
app->get_mouse_state returns the current mouse
|
|
||||||
|
|
||||||
NEW IN 4.0.5:
|
|
||||||
================
|
|
||||||
app->buffer_compute_cursor to get cursor position info without moving the cursor
|
|
||||||
|
|
||||||
can now use f keys for bindings
|
|
||||||
|
|
||||||
NEW IN 4.0.3:
|
|
||||||
================
|
|
||||||
The build system for customizations has been changed. There is no longer a 4coder_custom.cpp.
|
|
||||||
Instead the default customizations are in 4coder_default_bindings.cpp. The batch file takes a parameter
|
|
||||||
that tells it what file to treat as the target for building, if the parameter is not defined it defaults to
|
|
||||||
4coder_default_bindings.cpp.
|
|
||||||
|
|
||||||
NEW IN 4.0.2:
|
|
||||||
================
|
|
||||||
#include "4coder_default.cpp" at the top of your own file to get a lot of the default functions
|
|
||||||
such as incremental search, various word boundry seeks, and so on.
|
|
||||||
|
|
||||||
app->buffer_seek_string_insensitive(app, &buffer, start, str, len, seek_forward, &out);
|
|
||||||
Exactly the same as app->buffer_seek_string, but the matching rule is case insensitive
|
|
||||||
|
|
||||||
app->get_command_input(app);
|
|
||||||
Returns a User_Input that represents the input event that triggered the current command.
|
|
||||||
|
|
||||||
app->print_message(app, str, len);
|
|
||||||
Put a string into the *message* buffer.
|
|
||||||
|
|
||||||
OLD API DOC:
|
|
||||||
================================================================
|
|
||||||
There is an API available to custom commands and hooks, described at length here.
|
|
||||||
The system has two main data types, buffers and views. A buffer contains text,
|
|
||||||
undo history, and tokens. Views looks at a file and has a cursor a mark a highlight
|
|
||||||
and so on. The view and buffer are not the same because not all buffers are viewed,
|
|
||||||
and there may be two views viewing the same buffer.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->memory;
|
|
||||||
app->memory_size;
|
|
||||||
Here you get 2mb of memory that are completely yours to do whatever you need to do. This is for
|
|
||||||
those who found that malloc was not working for their allocation needs. There are currently no
|
|
||||||
allocation helpers so you'll have to figure out how to manage it.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->directory_get_hot(app, out, capacity);
|
|
||||||
Fills the out buffer with the "hot directory", which is the last directory 4coder has visited.
|
|
||||||
If it cannot write out the whole name it writes only what it can.
|
|
||||||
|
|
||||||
Always returns the length of the current hot directory in bytes.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->file_exists(app, filename, len);
|
|
||||||
Filename can be either a full path or a relative path.
|
|
||||||
|
|
||||||
Returns whether the file exists.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->directory_cd(app, dir, &len, capacity, rel_path, rel_len);
|
|
||||||
Looks at dir and updates it's contents as if a "cd" command had been cone from that directory.
|
|
||||||
if rel_path is ".." then the .. is not appended as a string, the directory is shortened if possible.
|
|
||||||
|
|
||||||
Returns false if the directory does not exist or if ".." was specified but it is impossible to back up,
|
|
||||||
returns true otherwise.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_file_list(app, dir, len);
|
|
||||||
If the directory exists, generates a list of all files and folders in that directory. All File_List structs
|
|
||||||
generated by get_file_list should be freed with free_file_list.
|
|
||||||
|
|
||||||
Returns a File_List struct listing all files and folders in dir, or an empty list if dir does not exist or is empty.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->free_file_list(app, list);
|
|
||||||
Frees a File_List created by get_file_list.
|
|
||||||
|
|
||||||
================
|
|
||||||
struct File_List;
|
|
||||||
The important fields are:
|
|
||||||
File_Info *infos;
|
|
||||||
int count;
|
|
||||||
count is the number of File_Info structs in the File_Info array.
|
|
||||||
|
|
||||||
struct File_Info;
|
|
||||||
String filename;
|
|
||||||
int folder;
|
|
||||||
folder is 1 or 0 to indicate whether the entry is a file or folder.
|
|
||||||
filrname is a string which may be editted, but not resized, that is filled with the name of a file or folder.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_buffer_first(app);
|
|
||||||
app->get_buffer_next(app, &buffer);
|
|
||||||
The new method for looping over buffers is:
|
|
||||||
|
|
||||||
for (Buffer_Summary b = app->get_buffer_first(app);
|
|
||||||
b.exists;
|
|
||||||
app->get_buffer_next(app, &b)) { }
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_buffer(app, index);
|
|
||||||
Returns a Buffer_Summary which contains information about a buffer and acts as the
|
|
||||||
handle to the buffer for other functions. The parameter index can be anything in the
|
|
||||||
range [0,max) where max comes from app->get_buffer_max_index
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_active_buffer(app, index);
|
|
||||||
Returns a Buffer_Summary obtained from the active panel.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_buffer_by_name(app, str, len);
|
|
||||||
Returns a Buffer_Summary who's "full source path" exactly matches str. There is
|
|
||||||
currently no way to look a buffer up by "live name" the short name shown on the top bar.
|
|
||||||
|
|
||||||
Buffers that are not associated with real files such as *compilation* have their "full source path"
|
|
||||||
name set to the same value as their live name, therefore you can get a *compilation* buffer with
|
|
||||||
this API by the name "*compilation*".
|
|
||||||
|
|
||||||
================
|
|
||||||
app->refresh_buffer(app, &buffer);
|
|
||||||
If a changes are made to a buffer the changes are not necessarily reflected in your Buffer_Summary,
|
|
||||||
use this to get updated information on the buffer. All commands in the low level API will udpate
|
|
||||||
your Buffer_Summary if a change is made, so refreshing afterwards is not necessary in that case.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_seek_delimiter(app, &buffer, start, delim, seek_forward, &out);
|
|
||||||
Starting from start, seeks forward or backward until the first occurance of delim,
|
|
||||||
the pointer out is filled with the position of the delimiter.
|
|
||||||
|
|
||||||
If no delimiter is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_seek_string(app, &buffer, start, str, len, seek_forward, &out);
|
|
||||||
Starting from start, seeks forward or backward until the first occurance of str,
|
|
||||||
the pointer out is filled with the position of the delimiter.
|
|
||||||
|
|
||||||
If no str is found out is filled with -1 for backward seeks and the size of the buffer on forward seeks.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_read_range(app, &buffer, start, end, buffer_out);
|
|
||||||
Fills buffer_out with the text that the buffer contains in the range [start,end) it is your responsibility
|
|
||||||
to ensure that the memory pointed to by buffer_out is at least (end - start) bytes.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->buffer_replace_range(app, &buffer, start, end, str, len);
|
|
||||||
Replaces the text in the range between start and end with the the text in str. It is allowed that
|
|
||||||
start == end so that you may insert str without replacing anything, and it is allowed that len == 0
|
|
||||||
so that you may delete text without replacing it with anything. These edits are tracked by history
|
|
||||||
and cause an update in the tokens if there are tokens. Your buffer will be updated to reflect
|
|
||||||
the change in the buffer caused by this edit.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
View_Summary:
|
|
||||||
There use to be a lot of different view types and only "file views" were exposed in the API.
|
|
||||||
As of alpha 4 there are only views and you can always get a view.
|
|
||||||
|
|
||||||
Besides renaming the struct, there is also a change in the meaning of the "buffer_id" field.
|
|
||||||
A view can have a buffer attached, but not currently be looking at that file.
|
|
||||||
|
|
||||||
All of the following indicate the buffer associated with the view:
|
|
||||||
buffer_id
|
|
||||||
locked_buffer_id
|
|
||||||
hidden_buffer_id
|
|
||||||
|
|
||||||
These ids are nulled out to indicate that access at a particular level is not available.
|
|
||||||
buffer_id -
|
|
||||||
This is null if the file is not visible in the view OR if the view is locked.
|
|
||||||
A view is only locked right now for read only buffers (compilation output).
|
|
||||||
|
|
||||||
locked_buffer_id -
|
|
||||||
This is null only if the file is not visible.
|
|
||||||
|
|
||||||
hidden_buffer_id -
|
|
||||||
This is never null.
|
|
||||||
|
|
||||||
In normal circumstances you can just use buffer_id and your code will automatically do
|
|
||||||
nothing when you try to edit a buffer you should not.
|
|
||||||
|
|
||||||
If what you are writing is unusual and it SHOULD edit a buffer even if it is locked or
|
|
||||||
hidden, then you can use the other ids to get deeper access.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_view_first(app);
|
|
||||||
app->get_view_next(app, &view);
|
|
||||||
The new method for looping over views is:
|
|
||||||
|
|
||||||
for (View_Summary v = app->get_view_first(app);
|
|
||||||
v.exists;
|
|
||||||
app->get_view_next(app, &v)) { }
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_file_view(app, index);
|
|
||||||
Returns a View_Summary which contains information about a file view and acts as
|
|
||||||
the handle to the file view for other functions. The parameter index can be anything in the
|
|
||||||
range [0,max) where max comes from app->get_view_max_index
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_active_file_view(app, index);
|
|
||||||
Returns a View_Summary obtained from the active panel.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->refresh_file_view(app, &view);
|
|
||||||
If a changes are made to a view the changes are not necessarily reflected in your View_Summary,
|
|
||||||
use this to get updated information on the view. All commands in the low level API will udpate
|
|
||||||
your View_Summary if a change is made, so refreshing afterwards is not necessary in that case.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
struct Buffer_Seek;
|
|
||||||
This struct specifies how to set a position in a file, it is in 4coder_buffer_types.h look there to see
|
|
||||||
all the options.
|
|
||||||
|
|
||||||
The following helpers will return Buffer_Seek structs for you:
|
|
||||||
+ To seek to a particular position (0-based-indexing) use seek_pos(pos)
|
|
||||||
+ To seek to a particular xy you either want seek_wrapped_xy(x, y, round_down)
|
|
||||||
or seek_unwrapped_xy(x, y, round_down). Wrapped vs unwrapped refers to whether
|
|
||||||
line wrapping is on. Both seek types are valid whether or not lines are wrapped, but
|
|
||||||
the results may be surprising if you do not match the correct type. round_down is usually 0,
|
|
||||||
and the effect is subtle, it has to do with whether the y position should be rounded down or rounded
|
|
||||||
to the nearest line. x and y are specified in pixels to move the y up or down a while line use view.line_height.
|
|
||||||
+ To seek to a particular line and character index on that line use seek_line_char(line, char_index)
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_cursor(app, &view, seek, set_preferred_x)
|
|
||||||
Updates the cursor location in this view. See information on the Buffer_Seek struct above for more
|
|
||||||
information. set_preferred_x if true set's the "preferred_x" of view to match the x of the cursor. The
|
|
||||||
preferred_x is the x the cursor tries to stay at as it moves up and down. Most cursor motion does set
|
|
||||||
the preferred_x.
|
|
||||||
|
|
||||||
The function updates the data in the View_Summary.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_mark(app, &view, seek)
|
|
||||||
Updates the mark location in this view. See information on the Buffer_Seek struct above for more
|
|
||||||
information.
|
|
||||||
|
|
||||||
The function updates the data in the View_Summary.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_highlight(app, &view, start, end, on)
|
|
||||||
If on is 0 this call turns the highlight off.
|
|
||||||
If on is 1 this call turns the highlight on and sets the highlight to range from start to end.
|
|
||||||
|
|
||||||
While the highlight is on the view will follow the end of the highlight and the cursor will be hidden.
|
|
||||||
Be sure to turn the highlight off when you're done with it!
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->view_set_file(app, &view, file_id)
|
|
||||||
Set this view to look at a different buffer (the buffer must already be opened and have a file_id).
|
|
||||||
|
|
||||||
The function updates the data in the View_Summary.
|
|
||||||
|
|
||||||
The function returns 1 on success and 0 on failure.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->get_user_input(app, get_type, abort_type);
|
|
||||||
This is a blocking operation that will allow 4coder to continue operating. The next input event
|
|
||||||
will be intercepted by this command, and will not be interpreted as normal. Input events include:
|
|
||||||
pressing a key
|
|
||||||
clicking left or right
|
|
||||||
rolling the mouse wheel
|
|
||||||
moving the mouse
|
|
||||||
|
|
||||||
The get_type flags specify a filter of what types of input you'd like to be notified about. Even if you
|
|
||||||
are not notified about keyboard input events, they are still not passed to any other systems to be
|
|
||||||
interpreted as commands or text input. The same is true for mouse input with the exception of
|
|
||||||
panel resizing, which can be done durring a command.
|
|
||||||
|
|
||||||
The abort_type flags specify the set of inputs you'd like to get an abort message on. It is good to
|
|
||||||
specify abort flags so that the system will know when your command is about to finish up. After
|
|
||||||
getting an abort message you can continue to do other work and call commands with exec_command
|
|
||||||
but you should not call app->get_user_input again. It will not cause an error if you do, but it could lead
|
|
||||||
to unexpected behavior. And in the future it might be that it IS an error to call get_user_input after an abort.
|
|
||||||
|
|
||||||
================
|
|
||||||
struct User_Input;
|
|
||||||
type: either UserInputKey or UserInputMouse
|
|
||||||
abort: true if this is an abort message, false otherwise
|
|
||||||
key: information about a key event
|
|
||||||
mouse: information about a mouse event
|
|
||||||
command: if this event would be translated into a command normally, this is the command.
|
|
||||||
|
|
||||||
Use CommandEqual to compare two commands in a typeless way since
|
|
||||||
cmdid_* and custom commands have different types.
|
|
||||||
|
|
||||||
================
|
|
||||||
key is of type:
|
|
||||||
struct Key_Event_Data;
|
|
||||||
keycode: always set to exactly the key that was pressed
|
|
||||||
character: a translation of the key press that takes into account Shift/Control/Alt/AltrGr/Caps-Lock
|
|
||||||
character_no_caps_lock: same as "character" but doesn't take Caps-Lock into account
|
|
||||||
|
|
||||||
modifiers[i]: flags for modifiers were held when this key was pressed
|
|
||||||
i: MDFR_SHIFT_INDEX, MDFR_CONTROL_INDEX, MDFR_ALT_INDEX, MDFR_CAPS_INDEX
|
|
||||||
|
|
||||||
TIP! Don't use MDFR_SHIFT, MDFR_CTRL, MDFR_ALT in the array! Those are bit masks, not indices!
|
|
||||||
|
|
||||||
================
|
|
||||||
mouse is of type:
|
|
||||||
struct Mouse_State;
|
|
||||||
l - whether the left button is down
|
|
||||||
r - whether the right button is down
|
|
||||||
press_l - whether the left button was just put down
|
|
||||||
press_r - whether the right button was just put down
|
|
||||||
release_l - whether the left button was just released
|
|
||||||
release_r - whether the right button was just released
|
|
||||||
wheel - values of 1, 0, -1. Does not report wheel amount, only direction.
|
|
||||||
out_of_window - 1 if the mouse is outside of the 4coder window, 0 otherwise
|
|
||||||
x, y - position of the mouse relative to the 4coder window
|
|
||||||
|
|
||||||
================
|
|
||||||
app->start_query_bar(app, &bar, 0);
|
|
||||||
Notify 4coder that you are using a Query_Bar and you want it rendered onto the screen.
|
|
||||||
While the query bar is still running any changes you make to prompt or string will be
|
|
||||||
shown right away, you don't have to ask 4coder to update it's bar because it reads straight
|
|
||||||
out of your Query_Bar.
|
|
||||||
|
|
||||||
If the pointer you pass goes bad, because a stack frame ends or you otherwise no longer
|
|
||||||
need the bar, you should call app->end_query_bar(app, &bar); so that 4coder doesn't try
|
|
||||||
to render a query bar from garbage memory. If the command finishes and there are query
|
|
||||||
bars that haven't been ended, 4coder automatically ends them.
|
|
||||||
|
|
||||||
There is a limit of 8 simultaneous queries bars and right now only file views support them.
|
|
||||||
The abillity to make a Query_Bar in other views including the empty view will come in the future though.
|
|
||||||
|
|
||||||
The 0 is there because Iintend to add flags for query bars in the future,
|
|
||||||
for modifying their appearance and behavior.
|
|
||||||
|
|
||||||
Returns 1 if it successfully started a query bar.
|
|
||||||
|
|
||||||
================
|
|
||||||
app->end_query_bar(app, &bar);
|
|
||||||
See start_query_bar for details.
|
|
||||||
|
|
||||||
================
|
|
||||||
Theme changing API
|
|
||||||
|
|
||||||
app->change_theme(app, name, len)
|
|
||||||
Set the theme to one of the prebuilt themes by name.
|
|
||||||
|
|
||||||
app->change_font(app, name, len)
|
|
||||||
Set the font to one of the fonts by name (not by ttf file name, by the name in the list).
|
|
||||||
|
|
||||||
app->set_theme_colors(app, colors, count)
|
|
||||||
Set colors of the current theme by tag color pairs.
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
Changes from 3.3 to 3.4:
|
|
||||||
-exposed command word complete
|
|
||||||
|
|
||||||
Changes from 3.2 to 3.3:
|
|
||||||
-exposed command build and added several example uses to the example file
|
|
||||||
-introduced directory navigation API
|
|
||||||
-slight tweaks to the API, moving away from macro translation
|
|
||||||
|
|
||||||
Changes from 3.1 to 3.2:
|
|
||||||
-exposed new commands relating to auto-tab
|
|
||||||
-removed old commands for whitespace cleaning
|
|
||||||
|
|
||||||
Changes from 3.0 to 3.1:
|
|
||||||
-start_hook eliminated, now bound through set_hook durring the get_bindings function
|
|
||||||
-vanilla_keys changed so that specific keys can be overriden
|
|
||||||
-you can now specify your own maps
|
|
||||||
-new parameter stack for communicating to some commands
|
|
||||||
-fulfill_interaction has been removed (push_parameter will be used to achieve it's effect)
|
|
||||||
-new hook for opening files, intended for file setting configuration
|
|
||||||
-exposed the new commands relating to history and the timeline scrub bar
|
|
||||||
|
|
||||||
Changes from 2.2.3 to 3.0:
|
|
||||||
-exposed the new undo / redo commands
|
|
||||||
|
|
||||||
Changes from 2.2.2 to 2.2.3:
|
|
||||||
-The binding API is remarkably different, but I included a
|
|
||||||
small set of helpers with this API that make the API look
|
|
||||||
almost exactly the same.
|
|
||||||
-you can now specify size for custom fonts
|
|
||||||
-you can now fulfill interacive commands
|
|
||||||
-fixed a bug that existed when some commands were used in exec_command
|
|
||||||
|
|
||||||
Changes from 2.2.1 to 2.2.2:
|
|
||||||
-added MDFR_SHIFT
|
|
||||||
-removed redundant keys from Key_Codes struct
|
|
||||||
-added bind_me
|
|
||||||
-added exec_command
|
|
||||||
-put bind, bind_me and exec_command into a struct
|
|
||||||
-added Custom_Command_Function
|
|
||||||
-added Start_Hook_Function
|
|
||||||
|
|
||||||
|
|
||||||
|
I am deprecating this readme file now. A much better documentation than what I used to
|
||||||
|
provide here is now provided in 4coder_API.html. This is the last version that will
|
||||||
|
feature SUPERREADME.
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue