diff options
author | 2008-06-15 13:42:03 -0400 | |
---|---|---|
committer | 2008-06-15 13:42:03 -0400 | |
commit | e56e9f1c1a635bd205bfde9ff8120ad2e81274c0 (patch) | |
tree | bce6dea11c3947ac681234ac4167c436ecb34fde | |
parent | 0e1787a267d9a9ecf38e7eb88e01f1b585821185 (diff) | |
download | textadept-e56e9f1c1a635bd205bfde9ff8120ad2e81274c0.tar.gz textadept-e56e9f1c1a635bd205bfde9ff8120ad2e81274c0.zip |
Added doxygen documentation to source files.
-rw-r--r-- | src/find_replace.c | 27 | ||||
-rw-r--r-- | src/lua_interface.c | 312 | ||||
-rw-r--r-- | src/pm.c | 94 | ||||
-rw-r--r-- | src/properties.h | 9 | ||||
-rw-r--r-- | src/textadept.c | 152 |
5 files changed, 559 insertions, 35 deletions
diff --git a/src/find_replace.c b/src/find_replace.c index 54c3f9e1..8564ff75 100644 --- a/src/find_replace.c +++ b/src/find_replace.c @@ -21,6 +21,9 @@ static bool static void button_clicked(GtkWidget *button, gpointer); +/** + * Creates the Find/Replace text frame. + */ GtkWidget* find_create_ui() { findbox = gtk_table_new(2, 6, false); @@ -81,6 +84,10 @@ GtkWidget* find_create_ui() { return findbox; } +/** + * Toggles the focus between the Find/Replace frame and the current Scintilla + * window. + */ void find_toggle_focus() { if (!GTK_WIDGET_HAS_FOCUS(findbox)) { gtk_widget_show(findbox); @@ -91,6 +98,10 @@ void find_toggle_focus() { } } +/** + * Builds the integer flags for a Find/Replace depending on the options that are + * checked. + */ static int get_flags() { int flags = 0; if (toggled(match_case_opt)) flags |= SCFIND_MATCHCASE; // 2 @@ -99,8 +110,10 @@ static int get_flags() { return flags; } -/** Find entry key event. - * Enter - Find next or previous. +/** + * Signal for a Find entry keypress. + * Currently handled keypresses: + * - Enter - Find next or previous. */ static bool fe_keypress(GtkWidget *, GdkEventKey *event, gpointer) { // TODO: if incremental, call l_find() @@ -110,8 +123,10 @@ static bool fe_keypress(GtkWidget *, GdkEventKey *event, gpointer) { } else return false; } -/** Replace entry key event. - * Enter - Find next or previous. +/** + * Signal for a Replace entry keypress. + * Currently handled keypresses: + * - Enter - Find next or previous. */ static bool re_keypress(GtkWidget *, GdkEventKey *event, gpointer) { if (event->keyval == 0xff0d) { @@ -120,6 +135,10 @@ static bool re_keypress(GtkWidget *, GdkEventKey *event, gpointer) { } else return false; } +/** + * Signal for a button click. + * Performs the appropriate action depending on the button clicked. + */ static void button_clicked(GtkWidget *button, gpointer) { if (button == ra_button) l_find_replace_all(find_text, repl_text, get_flags()); diff --git a/src/lua_interface.c b/src/lua_interface.c index 8f7445e6..95a286e5 100644 --- a/src/lua_interface.c +++ b/src/lua_interface.c @@ -52,12 +52,21 @@ const char *views_dne = "textadept.views doesn't exist or was overwritten.", *buffers_dne = "textadept.buffers doesn't exist or was overwritten."; +/** + * Inits or re-inits the Lua State. + * Populates the state with global variables and functions, then runs the + * 'core/init.lua' script. + * @param argc The number of command line parameters. + * @param argv The array of command line parameters. + * @param reinit Flag indicating whether or not to reinitialize the Lua State. + */ void l_init(int argc, char **argv, bool reinit) { if (!reinit) { lua = lua_open(); lua_newtable(lua); for (int i = 0; i < argc; i++) { - lua_pushstring(lua, argv[i]); lua_rawseti(lua, -2, i); + lua_pushstring(lua, argv[i]); + lua_rawseti(lua, -2, i); } lua_setfield(lua, LUA_REGISTRYINDEX, "arg"); lua_newtable(lua); lua_setfield(lua, LUA_REGISTRYINDEX, "buffers"); @@ -101,12 +110,21 @@ void l_init(int argc, char **argv, bool reinit) { l_load_script("core/init.lua"); } +/** + * Loads and runs a given Lua script. + * @param script_file The path of the Lua script relative to textadept_home. + */ void l_load_script(const char *script_file) { char *script = g_strconcat(textadept_home, "/", script_file, NULL); if (luaL_dofile(lua, script) != 0) l_handle_error(lua); g_free(script); } +/** + * Retrieves the value of a given key in the global 'textadept' table. + * @param lua The Lua State. + * @param k The string key to lookup. + */ bool l_ta_get(LS *lua, const char *k) { lua_getglobal(lua, "textadept"); lua_pushstring(lua, k); lua_rawget(lua, -2); @@ -114,21 +132,40 @@ bool l_ta_get(LS *lua, const char *k) { return lua_istable(lua, -1); } -// value is at stack top +/** + * Sets the value for a given key in the global 'textadept' table. + * The value to set should be at the top of the stack in the Lua State. + * @param lua The Lua State. + * @param k The string key to set the value of. + */ void l_ta_set(LS *lua, const char *k) { lua_getglobal(lua, "textadept"); lua_pushstring(lua, k); lua_pushvalue(lua, -3); lua_rawset(lua, -3); lua_pop(lua, 2); // value and textadept } -// value is at stack top +/** + * Sets the value for a given key in the LUA_REGISTRYINDEX and global + * 'textadept' table. + * The value to set should be at the top of the stack in the Lua State. + * @param lua The Lua State. + * @param k The string key to set the value of. + */ void l_reg_set(LS *lua, const char *k) { lua_setfield(lua, LUA_REGISTRYINDEX, k); lua_getfield(lua, LUA_REGISTRYINDEX, k); l_ta_set(lua, k); } -/** Checks for a view and returns the GtkWidget associated with it. */ +/** + * Checks a specified stack element to see if it is a Scintilla window and + * returns it as a GtkWidget. + * @param lua The Lua State. + * @param narg Relative stack index to check for a Scintilla window. + * @param errstr Error string to use if the stack element is not a Scintilla + * window. + * Defaults to "View argument expected.". + */ static GtkWidget* l_checkview(LS *lua, int narg, const char *errstr=NULL) { if (lua_type(lua, narg) == LUA_TTABLE) { lua_pushstring(lua, "widget_pointer"); @@ -141,6 +178,10 @@ static GtkWidget* l_checkview(LS *lua, int narg, const char *errstr=NULL) { return editor; } +/** + * Adds a Scintilla window to the global 'views' table with a metatable. + * @param editor The Scintilla window to add. + */ void l_add_scintilla_window(GtkWidget *editor) { if (!l_ta_get(lua, "views")) luaL_error(lua, views_dne); lua_newtable(lua); @@ -155,6 +196,10 @@ void l_add_scintilla_window(GtkWidget *editor) { lua_pop(lua, 1); // views } +/** + * Removes a Scintilla window from the global 'views' table. + * @param editor The Scintilla window to remove. + */ void l_remove_scintilla_window(GtkWidget *editor) { lua_newtable(lua); if (!l_ta_get(lua, "views")) luaL_error(lua, views_dne); @@ -165,6 +210,15 @@ void l_remove_scintilla_window(GtkWidget *editor) { l_reg_set(lua, "views"); } +/** + * Changes focus a Scintilla window in the global 'views' table. + * @param editor The currently focused Scintilla window. + * @param n The index of the window in the 'views' table to focus. + * @param absolute Flag indicating whether or not the index specified in 'views' + * is absolute. If false, focuses the window relative to the currently focused + * window for the given index. + * Defaults to true. + */ void l_goto_scintilla_window(GtkWidget *editor, int n, bool absolute) { if (!l_ta_get(lua, "views")) luaL_error(lua, views_dne); if (!absolute) { @@ -187,6 +241,10 @@ void l_goto_scintilla_window(GtkWidget *editor, int n, bool absolute) { lua_pop(lua, 2); // view table and views } +/** + * Sets the global 'view' variable to be the specified Scintilla window. + * @param editor The Scintilla window to set 'view' to. + */ void l_set_view_global(GtkWidget *editor) { if (!l_ta_get(lua, "views")) luaL_error(lua, views_dne); lua_pushnil(lua); @@ -199,7 +257,14 @@ void l_set_view_global(GtkWidget *editor) { lua_pop(lua, 1); // views } -/** Checks for a buffer and returns the doc_pointer associated with it. */ +/** + * Checks a specified element to see if it is a buffer table and returns the + * Scintilla document pointer associated with it. + * @param lua The Lua State. + * @param narg Relative stack index to check for a buffer table. + * @param errstr Error string to use if the stack element is not a buffer table. + * Defaults to "Buffer argument expected.". + */ static sptr_t l_checkdocpointer(LS *lua, int narg, const char *errstr=NULL) { if (lua_type(lua, narg) == LUA_TTABLE) { lua_pushstring(lua, "doc_pointer"); @@ -212,6 +277,10 @@ static sptr_t l_checkdocpointer(LS *lua, int narg, const char *errstr=NULL) { return doc; } +/** + * Adds a Scintilla document to the global 'buffers' table with a metatable. + * @param doc The Scintilla document to add. + */ int l_add_scintilla_buffer(sptr_t doc) { if (!l_ta_get(lua, "buffers")) luaL_error(lua, buffers_dne); lua_newtable(lua); @@ -227,8 +296,13 @@ int l_add_scintilla_buffer(sptr_t doc) { return index; } +/** + * Removes a Scintilla document from the global 'buffers' table. + * If any views currently show the document to be removed, change the documents + * they show first. + * @param doc The Scintilla buffer to remove. + */ void l_remove_scintilla_buffer(sptr_t doc) { - // Switch documents for all views that show the current document. if (!l_ta_get(lua, "views")) luaL_error(lua, views_dne); lua_pushnil(lua); while (lua_next(lua, -2)) { @@ -246,6 +320,11 @@ void l_remove_scintilla_buffer(sptr_t doc) { l_reg_set(lua, "buffers"); } +/** + * Retrieves the index in the global 'buffers' table for a given Scintilla + * document. + * @param doc The Scintilla document to get the index of. + */ unsigned int l_get_docpointer_index(sptr_t doc) { if (!l_ta_get(lua, "buffers")) luaL_error(lua, buffers_dne); unsigned int idx = 1; @@ -264,6 +343,19 @@ unsigned int l_get_docpointer_index(sptr_t doc) { { lua_pushstring(lua, k); lua_pushinteger(lua, v); lua_rawset(lua, -3); } #define l_get_bufferp(k, i) \ { lua_pushstring(lua, k); lua_rawget(lua, i < 0 ? i - 1 : i); } + +/** + * Changes a Scintilla window's document to one in the global 'buffers' table. + * Before doing so, it saves the scroll and caret positions in the current + * Scintilla document. Then when the new document is shown, its scroll and caret + * positions are restored. + * @param editor The Scintilla window to change the document of. + * @param n The index of the document in 'buffers' to focus. + * @param absolute Flag indicating whether or not the index specified in 'views' + * is absolute. If false, focuses the document relative to the currently + * focused document for the given index. + * Defaults to true. + */ void l_goto_scintilla_buffer(GtkWidget *editor, int n, bool absolute) { if (!l_ta_get(lua, "buffers")) luaL_error(lua, buffers_dne); ScintillaObject *sci = SCINTILLA(editor); @@ -301,6 +393,11 @@ void l_goto_scintilla_buffer(GtkWidget *editor, int n, bool absolute) { lua_pop(lua, 2); // buffer table and buffers } +/** + * Sets the global 'buffer' variable to be the document in the specified + * Scintilla object. + * @param sci The Scintilla object whose buffer is to be 'buffer'. + */ void l_set_buffer_global(ScintillaObject *sci) { sptr_t doc = SS(sci, SCI_GETDOCPOINTER); if (!l_ta_get(lua, "buffers")) luaL_error(lua, buffers_dne); @@ -314,6 +411,11 @@ void l_set_buffer_global(ScintillaObject *sci) { lua_pop(lua, 1); // buffers } +/** + * Closes the Lua State. + * Unsplits all Scintilla windows recursively, removes all Scintilla documents, + * and deletes the last Scintilla window before closing the state. + */ void l_close() { closing = true; while (unsplit_window(focused_editor)); @@ -330,6 +432,12 @@ void l_close() { // Utility Functions +/** + * Recurses through a Lua table, setting each of its keys and values to nil, + * effectively clearing the table. + * @param lua The Lua State. + * @param abs_index The absolute stack index of the table to clear. + */ static void clear_table(LS *lua, int abs_index) { lua_pushnil(lua); while (lua_next(lua, abs_index)) { @@ -339,6 +447,12 @@ static void clear_table(LS *lua, int abs_index) { } } +/** + * Checks if the Scintilla document of the buffer table at the index specified + * is the document of the focused Scintilla window. + * @param lua The Lua State. + * @param narg The relative stack position of the buffer table. + */ static void l_check_focused_buffer(LS *lua, int narg) { ScintillaObject *sci = SCINTILLA(focused_editor); sptr_t cur_doc = SS(sci, SCI_GETDOCPOINTER); @@ -346,6 +460,13 @@ static void l_check_focused_buffer(LS *lua, int narg) { luaL_error(lua, "The indexed buffer is not the focused one."); } +/** + * Checks whether or not a table in the global 'textadept' table has the + * specified key and returns true or false. + * @param lua The Lua State. + * @param table The table in 'textadept' to check for key in. + * @param key String key to check for in table. + */ static bool l_is_ta_table_key(LS *lua, const char *table, const char *key) { if (l_ta_get(lua, table)) { lua_getfield(lua, -1, key); @@ -356,6 +477,12 @@ static bool l_is_ta_table_key(LS *lua, const char *table, const char *key) { return false; } +/** + * Checks whether or not a table in the global 'textadept' table has the + * specified function and returns true or false. + * @param table The table in 'textadept' to check for function in. + * @param function String function name to check for in table. + */ bool l_is_ta_table_function(const char *table, const char *function) { if (l_ta_get(lua, table)) { lua_getfield(lua, -1, function); @@ -366,6 +493,17 @@ bool l_is_ta_table_function(const char *table, const char *function) { return false; } +/** + * Calls a Lua function with a number of arguments and expected return values. + * The last argument is at the stack top, and each argument in reverse order is + * one element lower on the stack with the Lua function being under the first + * argument. + * @param nargs The number of arguments to pass to the Lua function to call. + * @param retn The number of expected return values. Defaults to 0. + * @param keep_return Flag indicating whether or not to keep the return values + * at the top of the stack. If false, discards the return values. + * Defaults to false. + */ bool l_call_function(int nargs, int retn=0, bool keep_return=false) { int ret = lua_pcall(lua, nargs, retn, 0); if (ret == 0) { @@ -376,6 +514,12 @@ bool l_call_function(int nargs, int retn=0, bool keep_return=false) { return false; } +/** + * Performs a Lua rawget on a table at a given stack index and returns an int. + * @param lua The Lua State. + * @param index The relative index of the table to rawget from. + * @param n The index in the table to rawget. + */ static int l_rawgeti_int(LS *lua, int index, int n) { lua_rawgeti(lua, index, n); int ret = static_cast<int>(lua_tointeger(lua, -1)); @@ -383,6 +527,12 @@ static int l_rawgeti_int(LS *lua, int index, int n) { return ret; } +/** + * Performs a Lua rawget on a table at a given stack index and returns a string. + * @param lua The Lua State. + * @param index The relative index of the table to rawget from. + * @param k String key in the table to rawget. + */ static const char* l_rawget_str(LS *lua, int index, const char *k) { lua_pushstring(lua, k); lua_rawget(lua, index); const char *str = lua_tostring(lua, -1); @@ -390,7 +540,14 @@ static const char* l_rawget_str(LS *lua, int index, const char *k) { return str; } -/** Get a long for Scintilla w or l parameter based on type. */ +/** + * Convert the stack element at a specified index to a Scintilla w and/or l long + * parameter based on type. + * @param lua The Lua State. + * @param type The Lua type the top stack element is. + * @param arg_idx The initial stack index to start converting at. It is + * incremented as parameters are read from the stack. + */ static long l_toscintillaparam(LS *lua, int type, int &arg_idx) { if (type == tSTRING) return reinterpret_cast<long>(lua_tostring(lua, arg_idx++)); @@ -405,6 +562,14 @@ static long l_toscintillaparam(LS *lua, int type, int &arg_idx) { else return 0; } +/** + * Creates a GtkMenu from a table at the top of the Lua stack. + * The table has a key 'title' and a numeric list of subitems. + * @param lua The Lua State. + * @param callback A GCallback associated with each menu item. + * @param submenu Flag indicating whether or not this menu is a submenu. + * Defaults to false. + */ GtkWidget* l_create_gtkmenu(LS *lua, GCallback callback, bool submenu=false) { GtkWidget *menu = gtk_menu_new(), *menu_item = 0, *submenu_root = 0; const char *label; @@ -434,7 +599,12 @@ GtkWidget* l_create_gtkmenu(LS *lua, GCallback callback, bool submenu=false) { // Notification/event handlers -// error message is at stack top +/** + * Handles a Lua error. + * The main error message is at the top of the Lua stack. + * @param lua The Lua State. + * @param errmsg An additional error message to display. Defaults to NULL. + */ void l_handle_error(LS *lua, const char *errmsg) { if (focused_editor && l_is_ta_table_function("events", "error")) { l_insert(lua, -1); // shift error message down @@ -447,16 +617,32 @@ void l_handle_error(LS *lua, const char *errmsg) { lua_settop(lua, 0); } +/** + * Handles a Textadept event. + * @param s String event name. + */ bool l_handle_event(const char *s) { return l_is_ta_table_function("events", s) ? l_call_function(0, 1) : true; } +/** + * Handles a Textadept event. + * @param s String event name. + * @param arg String first argument. + */ bool l_handle_event(const char *s, const char *arg) { if (!l_is_ta_table_function("events", s)) return false; lua_pushstring(lua, arg); return l_call_function(1, 1); } +/** + * Handles a Textadept keypress. + * @param keyval The key value of the key pressed. + * @param shift Flag indicating whether or not the shift modifier was held. + * @param control Flag indicating whether or not the control modifier was held. + * @param alt Flag indicating whether or not the alt modifier was held. + */ bool l_handle_keypress(int keyval, bool shift, bool control, bool alt) { if (!l_is_ta_table_function("events", "keypress")) return false; lua_pushinteger(lua, keyval); @@ -468,6 +654,11 @@ bool l_handle_keypress(int keyval, bool shift, bool control, bool alt) { #define l_scn_int(i, n) { lua_pushinteger(lua, i); lua_setfield(lua, -2, n); } #define l_scn_str(s, n) { lua_pushstring(lua, s); lua_setfield(lua, -2, n); } + +/** + * Handles a Scintilla notification. + * @param n The Scintilla notification struct. + */ void l_handle_scnnotification(SCNotification *n) { if (!l_is_ta_table_function("events", "notification")) return; lua_newtable(lua); @@ -496,6 +687,10 @@ void l_handle_scnnotification(SCNotification *n) { l_call_function(1); } +/** + * Executes a given command string as Lua code. + * @param command Lua code to execute. + */ void l_ta_command(const char *command) { int top = lua_gettop(lua); if (luaL_dostring(lua, command) == 0) { @@ -506,7 +701,16 @@ void l_ta_command(const char *command) { // Project Manager -// full_path is at stack top if entry_text is NULL +/** + * Requests contents for the Project Manager. + * @param entry_text The text in the Project Manager Entry. If NULL, the full + * path table is at the top of the Lua stack. + * @param expanding Flag indicating whether or not a treenode is being expanded. + * If true, the tree is walked up from the node to top creating a full path + * table at the stack top to be used essentially as entry_text. + * Defaults to false. + * @see l_pm_get_full_path + */ bool l_pm_get_contents_for(const char *entry_text, bool expanding) { if (!l_is_ta_table_function("pm", "get_contents_for")) return false; if (entry_text) { @@ -518,7 +722,13 @@ bool l_pm_get_contents_for(const char *entry_text, bool expanding) { return l_call_function(2, 1, true); } -// table is at stack top +/** + * Populates the Project Manager pane with the contents of a Lua table at the + * stack top. + * @param initial_iter The initial GtkTreeIter. If not NULL, it is a treenode + * being expanded and the contents will be added to that expanding node. + * Defaults to NULL. + */ void l_pm_populate(GtkTreeIter *initial_iter) { GtkTreeIter iter, child; if (!lua_istable(lua, -1)) @@ -549,8 +759,13 @@ void l_pm_populate(GtkTreeIter *initial_iter) { } lua_pop(lua, 1); // returned table } +/** + * For a Project Manager given node, get the full path to that node. + * It leaves a full path table at the top of the Lua stack. + * @param path The GtkTreePath of the node. + */ void l_pm_get_full_path(GtkTreePath *path) { - lua_newtable(lua); // will be at stack top + lua_newtable(lua); lua_pushstring(lua, gtk_entry_get_text(GTK_ENTRY(pm_entry))); lua_rawseti(lua, -2, 1); if (!path) return; @@ -566,6 +781,11 @@ void l_pm_get_full_path(GtkTreePath *path) { } } +/** + * Requests and pops up a context menu for the Project Manager. + * @param event The mouse button event. + * @param callback The GCallback associated with each menu item. + */ void l_pm_popup_context_menu(GdkEventButton *event, GCallback callback) { if (!l_is_ta_table_function("pm", "get_context_menu")) return; GtkTreeIter iter; @@ -589,14 +809,22 @@ void l_pm_popup_context_menu(GdkEventButton *event, GCallback callback) { } else warn("pm.get_context_menu return was not a table."); } -// full_path is at stack top +/** + * Performs an action for an activated item in the Project Manager. + * The full path table for the item is at the top of the Lua stack. + */ void l_pm_perform_action() { if (!l_is_ta_table_function("pm", "perform_action")) return; l_insert(lua, -1); // shift full_path down l_call_function(1); } -// full_path is at stack top +/** + * Performs a selected menu action from an item's context menu in the Project + * Manager. + * The full path table for the item is at the top of the Lua stack. + * @param menu_item The label text for the menu item clicked. + */ void l_pm_perform_menu_action(const char *menu_item) { if (!l_is_ta_table_function("pm", "perform_menu_action")) return; l_insert(lua, -1); // shift full_path down @@ -607,6 +835,13 @@ void l_pm_perform_menu_action(const char *menu_item) { // Find/Replace +/** + * Finds text in the current document. + * @param ftext The text to find. + * @param flags Integer flags for the find. + * @param next Flag indicating whether or not to find next. If false, finds + * previous matches. + */ void l_find(const char *ftext, int flags, bool next) { if (!l_is_ta_table_function("find", "find")) return; lua_pushstring(lua, ftext); @@ -615,12 +850,22 @@ void l_find(const char *ftext, int flags, bool next) { l_call_function(3); } +/** + * Replaces text in the current document. + * @param rtext The text to replace the found text with. + */ void l_find_replace(const char *rtext) { if (!l_is_ta_table_function("find", "replace")) return; lua_pushstring(lua, rtext); l_call_function(1); } +/** + * Replaces all found text in the current document. + * @param ftext The text to find. + * @param rtext The text to replace the found text with. + * @param flags Integer flags for the find. + */ void l_find_replace_all(const char *ftext, const char *rtext, int flags) { if (!l_is_ta_table_function("find", "replace_all")) return; lua_pushstring(lua, ftext); @@ -631,10 +876,15 @@ void l_find_replace_all(const char *ftext, const char *rtext, int flags) { // Lua functions (stack maintenence is unnecessary) -/** Calls Scintilla returning appropriate values. - * The p1, p2, and rt types are integer types of the w, l, and return - * parameters respectively. arg is the Lua stack index where user arguments - * begin. The appropriate value(s) are returned to Lua. +/** + * Calls Scintilla with appropriate parameters and returs appropriate values. + * @param lua The Lua State. + * @param sci The Scintilla object to call. + * @param msg The integer message index to call Scintilla with. + * @param p1_type The Lua type of p1, the Scintilla w parameter. + * @param p2_type The Lua type of p2, the Scintilla l parameter. + * @param rt_type The Lua type of the Scintilla return parameter. + * @param arg The index on the Lua stack where arguments to Scintilla begin. */ LF l_call_scintilla(LS *lua, ScintillaObject *sci, int msg, int p1_type, int p2_type, int rt_type, int arg) { @@ -672,6 +922,11 @@ LF l_call_scintilla(LS *lua, ScintillaObject *sci, int msg, return lua_gettop(lua) - arg; } +/** + * Calls a Scintilla buffer function with upvalues from a closure. + * @param lua The Lua State. + * @see l_buffer_mt_index + */ LF l_call_buffer_function(LS *lua) { int sci_idx = lua_upvalueindex(1); // closure from __index ScintillaObject *sci = @@ -684,6 +939,14 @@ LF l_call_buffer_function(LS *lua) { return l_call_scintilla(lua, sci, msg, p1_type, p2_type, rt_type, 2); } +/** + * Metatable index for a buffer table. + * If the key is a Scintilla buffer function, push a closure so it can be called + * as a function. If the key is a non-indexable buffer property, call Scintilla + * to get it. If the key is an indexible buffer property, push a table with a + * metatable to access buffer property indices. + * @param lua The Lua State. + */ LF l_buffer_mt_index(LS *lua) { ScintillaObject *sci = SCINTILLA(focused_editor); const char *key = luaL_checkstring(lua, 2); @@ -710,11 +973,14 @@ LF l_buffer_mt_index(LS *lua) { return 1; } -/** Helper function for the buffer property metatable. - * n indicates a getter or setter (1 or 2) and arg is the Lua stack index - * where user arguments begin. For setting buffer properties, it is 3 because - * the index is not an argument, but for getting and setting indexed buffer - * properties it is 2 because the index is an argument. +/** + * Helper function for the buffer property metatable. + * @param lua The Lua State. + * @param n 1 for getter property, 2 for setter. + * @param prop String property name. + * @param arg The index on the Lua stack where arguments to Scintilla begin. + * For setter properties, it is 3 because the index is not an argument. For + * getter and setter properties, it is 2 because the index is an argument. */ LF l_bufferp_mt_(LS *lua, int n, const char *prop, int arg) { ScintillaObject *sci = SCINTILLA(focused_editor); @@ -856,7 +1122,7 @@ LF l_find_mt_newindex(LS *lua) { return 0; } -// Lua CFunctions +// Lua CFunctions. For documentation, consult the LuaDoc. LF l_cf_ta_buffer_new(LS *lua) { new_scintilla_buffer(SCINTILLA(focused_editor), true, true); @@ -23,6 +23,12 @@ static bool pm_button_press(GtkTreeView *, GdkEventButton *event, gpointer); static bool pm_popup_menu(GtkWidget *, gpointer); static void pm_menu_activate(GtkWidget *menu_item, gpointer); +/** + * Creates the Project Manager pane. + * It consists of an entry box and a treeview called 'textadept-pm-entry' and + * 'textadept-pm-view' respectively for styling via gtkrc. The treeview model + * consists of a gdk-pixbuf for icons and markup text. + */ GtkWidget* pm_create_ui() { pm_container = gtk_vbox_new(false, 1); @@ -72,6 +78,14 @@ GtkWidget* pm_create_ui() { return pm_container; } +/** + * Requests contents for a Project Manager parent node being opened. + * Since parents have a dummy child by default just to indicate they are indeed + * parents, that dummy child is removed now. + * @param iter The parent GtkTreeIter. + * @param path The parent GtkTreePath. + * @see l_pm_get_contents_for + */ void pm_open_parent(GtkTreeIter *iter, GtkTreePath *path) { l_pm_get_full_path(path); if (l_pm_get_contents_for(NULL, true)) l_pm_populate(iter); @@ -84,6 +98,12 @@ void pm_open_parent(GtkTreeIter *iter, GtkTreePath *path) { g_free(filename); } +/** + * Removes all Project Manager children from a parent node being closed. + * It does add a dummy child by default to indicate the parent is indeed a + * parent. It will be removed when the parent is opened. + * @param iter The parent GtkTreeIter. + */ void pm_close_parent(GtkTreeIter *iter, GtkTreePath *) { GtkTreeIter child; gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(pm_store), &child, iter, 0); @@ -93,6 +113,12 @@ void pm_close_parent(GtkTreeIter *iter, GtkTreePath *) { gtk_tree_store_set(pm_store, &child, 1, "\0dummy", -1); } +/** + * Performs the appropriate action on a selected Project Manager node. + * If the node is a collapsed parent, it is expanded; otherwise the parent is + * collapsed. If the node is not a parent at all, a Lua action is performed. + * @see l_pm_perform_action + */ void pm_activate_selection() { GtkTreeIter iter; GtkTreePath *path; @@ -111,10 +137,20 @@ void pm_activate_selection() { gtk_tree_path_free(path); } +/** + * Pops up a context menu for the selected Project Manager node. + * @param event The mouse button event. + * @see l_pm_popup_context_menu + */ void pm_popup_context_menu(GdkEventButton *event) { l_pm_popup_context_menu(event, G_CALLBACK(pm_menu_activate)); } +/** + * Performs a Lua action for a selected Project Manager menu item. + * @param menu_item The menu item. + * @see l_pm_perform_menu_action + */ void pm_process_selected_menu_item(GtkWidget *menu_item) { GtkWidget *label = gtk_bin_get_child(GTK_BIN(menu_item)); const char *text = gtk_label_get_text(GTK_LABEL(label)); @@ -125,11 +161,23 @@ void pm_process_selected_menu_item(GtkWidget *menu_item) { l_pm_perform_menu_action(text); } +/** + * Toggles the focus between the Project Manager and the current Scintilla + * window. + */ void pm_toggle_focus() { gtk_widget_grab_focus( GTK_WIDGET_HAS_FOCUS(focused_editor) ? pm_entry : focused_editor); } +/** + * When searching the Project Manager treeview, matches are tree items that + * contain the search text as a substring. + * @param model The GtkTreeModel for the treeview. + * @param col The column number to use for comparing search text to. + * @param key The search text. + * @param iter The GtkTreeIter for each tree node being compared. + */ static int pm_search_equal_func(GtkTreeModel *model, int col, const char *key, GtkTreeIter *iter, gpointer) { const char *text; @@ -137,6 +185,12 @@ static int pm_search_equal_func(GtkTreeModel *model, int col, const char *key, return strstr(text, key) == NULL; // false is really a match like strcmp } +/** + * Sorts the Project Manager treeview case sensitively. + * @param model The GtkTreeModel for the treeview. + * @param a The GtkTreeIter for one tree node being compared. + * @param b The GtkTreeIter for the other tree node being compared. + */ static int pm_sort_iter_compare_func(GtkTreeModel *model, GtkTreeIter *a, GtkTreeIter *b, gpointer) { const char *a_text, *b_text; @@ -149,14 +203,22 @@ static int pm_sort_iter_compare_func(GtkTreeModel *model, GtkTreeIter *a, } // Signals + +/** + * Signal for the activation of the Project Manager entry. + * Requests contents for the treeview. + * @see l_pm_get_contents_for + */ static void pm_entry_activated(GtkWidget *widget, gpointer) { const char *entry_text = gtk_entry_get_text(GTK_ENTRY(widget)); if (l_pm_get_contents_for(entry_text)) l_pm_populate(); } -/** Project manager key events. - * Ctrl+Tab - Refocuses the Scintilla view. - * Escape - Refocuses the Scintilla view. +/** + * Signal for a Project Manager keypress. + * Currently handled keypresses: + * - Ctrl+Tab - Refocuses the Scintilla view. + * - Escape - Refocuses the Scintilla view. */ static bool pm_keypress(GtkWidget *, GdkEventKey *event, gpointer) { if (event->keyval == 0xff09 && event->state == GDK_CONTROL_MASK || @@ -166,30 +228,56 @@ static bool pm_keypress(GtkWidget *, GdkEventKey *event, gpointer) { } else return false; } +/** + * Signal for a Project Manager parent expansion. + * @see pm_open_parent + */ static void pm_row_expanded(GtkTreeView *, GtkTreeIter *iter, GtkTreePath *path, gpointer) { pm_open_parent(iter, path); } +/** + * Signal for a Project Manager parent collapse. + * @see pm_close_parent + */ static void pm_row_collapsed(GtkTreeView *, GtkTreeIter *iter, GtkTreePath *path, gpointer) { pm_close_parent(iter, path); } +/** + * Signal for the activation of a Project Manager node. + * @see pm_activate_selection + */ static void pm_row_activated(GtkTreeView *, GtkTreePath *, GtkTreeViewColumn *, gpointer) { pm_activate_selection(); } +/** + * Signal for a Project Manager mouse click. + * If it is a right-click, popup a context menu for the selected node. + * @see pm_popup_context_menu + */ static bool pm_button_press(GtkTreeView *, GdkEventButton *event, gpointer) { if (event->type != GDK_BUTTON_PRESS || event->button != 3) return false; pm_popup_context_menu(event); return true; } +/** + * Signal for popping up a Project Manager context menu. + * Typically Shift+F10 activates this event. + * @see pm_popup_context_menu + */ static bool pm_popup_menu(GtkWidget *, gpointer) { pm_popup_context_menu(NULL); return true; } +/** + * Signal for a selected Project Manager menu item. + * @see pm_process_selected_menu_item + */ static void pm_menu_activate(GtkWidget *menu_item, gpointer) { pm_process_selected_menu_item(menu_item); } diff --git a/src/properties.h b/src/properties.h index 24f10507..0ea11a2e 100644 --- a/src/properties.h +++ b/src/properties.h @@ -8,6 +8,10 @@ #define sp(k, v) SSS(sci, SCI_SETPROPERTY, k, v) #define color(r, g, b) r | (g << 8) | (b << 16) +/** + * Sets the default properties for a Scintilla window. + * @param sci The Scintilla window to set default properties for. + */ void set_default_editor_properties(ScintillaObject *sci) { sp("lexer.lua.home", "/usr/share/textadept/lexers/"); sp("lexer.lua.script", "/usr/share/textadept/lexers/lexer.lua"); @@ -64,6 +68,11 @@ void set_default_editor_properties(ScintillaObject *sci) { SS(sci, SCI_SETCARETSTICKY, 0); } +/** + * Sets the default properties for a Scintilla document. + * @param sci The Scintilla window containing the document to set default + * properties for. + */ void set_default_buffer_properties(ScintillaObject *sci) { sp("fold", "1"); sp("fold.by.indentation", "1"); diff --git a/src/textadept.c b/src/textadept.c index 8ae255f4..e05acc36 100644 --- a/src/textadept.c +++ b/src/textadept.c @@ -18,6 +18,13 @@ static bool w_focus(GtkWidget*, GdkEventFocus *, gpointer); static bool w_keypress(GtkWidget*, GdkEventKey *event, gpointer); static bool w_exit(GtkWidget*, GdkEventAny*, gpointer); +/** + * Runs Textadept. + * Inits the Lua State, creates the user interface, and loads the core/init.lua + * script. + * @param argc The number of command line params. + * @param argv The array of command line params. + */ int main(int argc, char **argv) { gtk_init(&argc, &argv); l_init(argc, argv, false); @@ -27,6 +34,19 @@ int main(int argc, char **argv) { return 0; } +/** + * Creates the user interface. + * The UI consists of: + * - A menubar initially hidden and empty. It should be populated by script + * and then shown. + * - A side pane. It contains a treeview for hierarchical data sets, such as + * a file structure for project management. + * - A frame for Scintilla windows. + * - A find text frame initially hidden. + * - A command entry initially hidden. This entry accepts and runs Lua code + * in the current Lua state. + * - Two status bars: one for notifications, the other for document status. + */ void create_ui() { window = gtk_window_new(GTK_WINDOW_TOPLEVEL); gtk_window_set_default_size(GTK_WINDOW(window), 500, 400); @@ -70,6 +90,18 @@ void create_ui() { gtk_widget_grab_focus(editor); } +/** + * Creates a new Scintilla window. + * The Scintilla window is the GTK widget that displays a Scintilla buffer. + * The window's default properties are set via 'set_default_editor_properties'. + * Generates a 'view_new' event. + * @param buffer_id A Scintilla buffer ID to load into the new window. If NULL, + * creates a new Scintilla buffer and loads it into the new window. + * Defaults to NULL. + * @return the Scintilla window. + * @see set_default_editor_properties + * @see l_add_scintilla_window + */ GtkWidget* new_scintilla_window(sptr_t buffer_id) { GtkWidget *editor = scintilla_new(); gtk_widget_set_size_request(editor, 1, 1); // minimum size @@ -88,11 +120,36 @@ GtkWidget* new_scintilla_window(sptr_t buffer_id) { return editor; } +/** + * Removes a Scintilla window. + * @param editor The Scintilla window to remove. + * @see l_remove_scintilla_window + */ void remove_scintilla_window(GtkWidget *editor) { l_remove_scintilla_window(editor); gtk_widget_destroy(editor); } +/** + * Creates a new Scintilla buffer for a newly created Scintilla window. + * The buffer's default properties are set via 'set_default_buffer_properties', + * but the default style is set here. + * Generates a 'buffer_new' event. + * @param sci The ScintillaObject to associate the buffer with. + * @param create Flag indicating whether or not to create a buffer. If false, + * the ScintillaObject already has a buffer associated with it (typically + * because new_scintilla_window was passed a non-NULL buffer_id). + * Defaults to true. + * @param addref Flag indicating whether or not to add a reference to the buffer + * in the ScintillaObject when create is false. This is necessary for creating + * Scintilla windows in split views. If a buffer appears in two separate + * Scintilla windows, that buffer should have multiple references so when one + * Scintilla window closes, the buffer is not deleted because its reference + * count is not zero. + * Defaults to true. + * @see set_default_buffer_properties + * @see l_add_scintilla_buffer + */ void new_scintilla_buffer(ScintillaObject *sci, bool create, bool addref) { sptr_t doc; doc = SS(sci, SCI_GETDOCPOINTER); @@ -115,11 +172,24 @@ void new_scintilla_buffer(ScintillaObject *sci, bool create, bool addref) { l_handle_event("buffer_new"); } +/** + * Removes the Scintilla buffer from the current Scintilla window. + * @param doc The Scintilla buffer ID to remove. + * @see l_remove_scintilla_buffer + */ void remove_scintilla_buffer(sptr_t doc) { l_remove_scintilla_buffer(doc); SS(SCINTILLA(focused_editor), SCI_RELEASEDOCUMENT, 0, doc); } +/** + * Splits a Scintilla window into two windows separated by a GTK pane. + * The buffer in the original pane is also shown in the new pane. + * @param editor The Scintilla window to split. + * @param vertical Flag indicating whether to split the window vertically or + * horozontally. + * Defaults to true. + */ void split_window(GtkWidget *editor, bool vertical) { g_object_ref(editor); int first_line = SS(SCINTILLA(editor), SCI_GETFIRSTVISIBLELINE); @@ -146,6 +216,11 @@ void split_window(GtkWidget *editor, bool vertical) { g_object_unref(editor); } +/** + * For a given GTK pane, remove the Scintilla windows inside it recursively. + * @param pane The GTK pane to remove Scintilla windows from. + * @see remove_scintilla_window + */ void remove_scintilla_windows_in_pane(GtkWidget *pane) { GtkWidget *child1 = gtk_paned_get_child1(GTK_PANED(pane)); GtkWidget *child2 = gtk_paned_get_child2(GTK_PANED(pane)); @@ -155,6 +230,14 @@ void remove_scintilla_windows_in_pane(GtkWidget *pane) { : remove_scintilla_window(child2); } +/** + * Unsplits the pane a given Scintilla window is in and keeps that window. + * If the pane to discard contains other Scintilla windows, they are removed + * recursively. + * @param editor The Scintilla window to keep when unsplitting. + * @see remove_scintilla_windows_in_pane + * @see remove_scintilla_window + */ bool unsplit_window(GtkWidget *editor) { GtkWidget *pane = gtk_widget_get_parent(editor); if (!GTK_IS_PANED(pane)) return false; @@ -180,12 +263,27 @@ bool unsplit_window(GtkWidget *editor) { return true; } +/** + * Resizes a GTK pane. + * @param editor The Scintilla window (typically the current one) contained in + * the GTK pane to resize. + * @param pos The position to resize to. + * @param increment Flag indicating whether or not the resizing is incremental. + * If true, pos is added to the current pane position; otherwise the position + * is absolute. + * Defaults to true. + */ void resize_split(GtkWidget *editor, int pos, bool increment) { GtkWidget *pane = gtk_widget_get_parent(editor); int width = gtk_paned_get_position(GTK_PANED(pane)); gtk_paned_set_position(GTK_PANED(pane), pos + (increment ? width : 0)); } +/** + * Sets a user-defined GTK menubar and displays it. + * @param new_menubar The GTK menubar. + * @see l_ta_mt_newindex + */ void set_menubar(GtkWidget *new_menubar) { GtkWidget *vbox = gtk_widget_get_parent(menubar); gtk_container_remove(GTK_CONTAINER(vbox), menubar); @@ -195,16 +293,29 @@ void set_menubar(GtkWidget *new_menubar) { gtk_widget_show_all(menubar); } +/** + * Sets the notification statusbar text. + * @param text The text to display. + */ void set_statusbar_text(const char *text) { gtk_statusbar_pop(GTK_STATUSBAR(statusbar), 0); gtk_statusbar_push(GTK_STATUSBAR(statusbar), 0, text); } +/** + * Sets the document status statusbar text. + * This is typically set via a Scintilla 'UpdateUI' notification. + * @param text The text to display. + */ void set_docstatusbar_text(const char *text) { gtk_statusbar_pop(GTK_STATUSBAR(docstatusbar), 0); gtk_statusbar_push(GTK_STATUSBAR(docstatusbar), 0, text); } +/** + * Toggles focus between a Scintilla window and the Lua command entry. + * When the entry is visible, the statusbars are temporarily hidden. + */ void command_toggle_focus() { if (!GTK_WIDGET_HAS_FOCUS(command_entry)) { gtk_widget_hide(statusbar); gtk_widget_hide(docstatusbar); @@ -219,15 +330,23 @@ void command_toggle_focus() { // Notifications/signals +/** + * Signal for the 'enter' key being pressed in the Lua command entry. + * Evaluates the input text as Lua code. + * Generates a 'hide_completions' event. + */ static void c_activated(GtkWidget *widget, gpointer) { l_handle_event("hide_completions"); l_ta_command(gtk_entry_get_text(GTK_ENTRY(widget))); command_toggle_focus(); } -/** Command entry key events. - * Escape - Hide the completion buffer if it's open. - * Tab - Show completion buffer. +/** + * Signal for a keypress inside the Lua command entry. + * Currently handled keypresses: + * - Escape - Hide the completion buffer if it is open. + * - Tab - Show completion buffer. + * Generates a 'hide_completions' or 'show_completions' event as necessary. */ static bool c_keypress(GtkWidget *widget, GdkEventKey *event, gpointer) { if (event->state == 0) @@ -244,11 +363,18 @@ static bool c_keypress(GtkWidget *widget, GdkEventKey *event, gpointer) { return false; } +/** + * Signal for a Scintilla notification. + */ static void t_notification(GtkWidget*, gint, gpointer lParam, gpointer) { SCNotification *n = reinterpret_cast<SCNotification*>(lParam); l_handle_scnnotification(n); } +/** + * Signal for a Scintilla command. + * Currently handles SCEN_SETFOCUS. + */ static void t_command(GtkWidget *editor, gint wParam, gpointer, gpointer) { if (wParam >> 16 == SCEN_SETFOCUS) { focused_editor = editor; @@ -257,6 +383,11 @@ static void t_command(GtkWidget *editor, gint wParam, gpointer, gpointer) { } } +/** + * Signal for a Scintilla keypress. + * Collects the modifier states as flags and calls Lua to handle the keypress. + * @see l_handle_keypress + */ static bool t_keypress(GtkWidget*, GdkEventKey *event, gpointer) { bool shift = event->state & GDK_SHIFT_MASK; bool control = event->state & GDK_CONTROL_MASK; @@ -264,14 +395,19 @@ static bool t_keypress(GtkWidget*, GdkEventKey *event, gpointer) { return l_handle_keypress(event->keyval, shift, control, alt); } +/** + * Signal for a Textadept window focus change. + */ static bool w_focus(GtkWidget*, GdkEventFocus*, gpointer) { if (focused_editor && !GTK_WIDGET_HAS_FOCUS(focused_editor)) gtk_widget_grab_focus(focused_editor); return false; } -/** Window key events. - * Escape - hides the search dialog if it's open. +/** + * Signal for a Textadept keypress. + * Currently handled keypresses: + * - Escape - hides the search frame if it's open. */ static bool w_keypress(GtkWidget*, GdkEventKey *event, gpointer) { if (event->keyval == 0xff1b && GTK_WIDGET_VISIBLE(findbox)) { @@ -281,6 +417,12 @@ static bool w_keypress(GtkWidget*, GdkEventKey *event, gpointer) { } else return false; } +/** + * Signal for exiting Textadept. + * Closes the Lua State and releases resources. + * Generates a 'quit' event. + * @see l_close + */ static bool w_exit(GtkWidget*, GdkEventAny*, gpointer) { if (!l_handle_event("quit")) return true; l_close(); |