finally, add at least a subject for each patch
[nedit-bw.git] / timer_macros.patch
blob713dfc7911ae95d814c69c2ea15e4339d9d95698
1 Subject: timer_add()/timer_remove() macros
3 This adds two new macro subroutines for handling timeouts.
5 **timer_add( func_name, timeout [, "global"] )**
6 Install a new timer that call the macro routine ~func_name~ after ~timeout~
7 milli seconds. The function is only called if the top window is the same as
8 the window from which ~timer_add()~ was called, this can be overriden with the
9 optional ~"global"~ parameter. The macro returns a timer ID which can be used
10 to remove a timer before expiration with ~timer_remove()~.
12 **timer_remove( timer_ID )**
13 Removes the timer with ID ~timer_ID~.
15 There can be a problem on LP64 architectures, the nedit macro language have
16 only int support but the XtIntervalId is defined as unsigned long, so there
17 can be domain error, I try to catch this error.
19 ---
21 doc/help.etx | 10 ++
22 source/highlightData.c | 2
23 source/macro.c | 168 +++++++++++++++++++++++++++++++++++++++++++++++++
24 3 files changed, 179 insertions(+), 1 deletion(-)
26 diff --quilt old/source/macro.c new/source/macro.c
27 --- old/source/macro.c
28 +++ new/source/macro.c
29 @@ -456,10 +456,15 @@ static int toPosMS(WindowInfo *window, D
30 static int toLineMS(WindowInfo *window, DataValue *argList, int nArgs,
31 DataValue *result, char **errMsg);
32 static int toColumnMS(WindowInfo *window, DataValue *argList, int nArgs,
33 DataValue *result, char **errMsg);
35 +static int timerAddMS(WindowInfo *window, DataValue *argList,
36 + int nArgs, DataValue *result, char **errMsg);
37 +static int timerRemoveMS(WindowInfo *window, DataValue *argList,
38 + int nArgs, DataValue *result, char **errMsg);
40 /* Built-in subroutines and variables for the macro language */
41 static const BuiltInSubrName MacroSubrs[] = {
42 { "length", lengthMS },
43 { "get_range", getRangeMS },
44 { "t_print", tPrintMS },
45 @@ -527,10 +532,12 @@ static const BuiltInSubrName MacroSubrs[
46 { "define", defineMS },
47 { "to_pos", toPosMS },
48 { "to_line", toLineMS },
49 { "to_column", toColumnMS },
50 { "set_window_title", setWindowTitleMS },
51 + { "timer_add", timerAddMS },
52 + { "timer_remove", timerRemoveMS },
53 { NULL, NULL } /* sentinel */
56 static const BuiltInSubrName SpecialVars[] = {
57 { "$cursor", cursorMV },
58 @@ -3794,10 +3801,171 @@ static int setWindowTitleMS(WindowInfo *
59 window->titleFormat = newFmt;
60 UpdateWindowTitle(window);
61 return True;
64 +typedef struct _TimerProcData {
65 + struct _TimerProcData *next;
66 + XtIntervalId id;
67 + WindowInfo *window;
68 + int global;
69 + char name[1];
70 +} TimerProcData;
72 +static TimerProcData *allTimerProcData;
74 +static void macroTimerProc(XtPointer clientData, XtIntervalId *id)
76 + TimerProcData *data = clientData, **s;
77 + WindowInfo *win;
79 + s = &allTimerProcData;
80 + while (*s) {
81 + if ((*s)->id == data->id) {
82 + *s = data->next;
83 + break;
84 + }
85 + s = &(*s)->next;
86 + }
88 + /* check if window is still there, but don't trust the pointer */
89 + for (win = WindowList; win; win = win->next) {
90 + if (win == data->window) {
91 + break;
92 + }
93 + }
94 + if (win != data->window) {
95 + goto out;
96 + }
98 + if (*id != data->id) {
99 + goto out;
102 + /* don't call macro if its not a global timer and current top-window is
103 + different from timer_add() window */
104 + if (!data->global && !IsTopDocument(data->window)) {
105 + goto out;
108 + MacroApplyHook(data->window, data->name, 0, NULL, NULL);
110 +out:
111 + XtFree((char *)data);
115 + * timer_ID = timer_add(macro_name, timeout[, "global"])
116 + */
117 +static int timerAddMS(WindowInfo *window, DataValue *argList, int nArgs,
118 + DataValue *result, char **errMsg)
120 + int timeout;
121 + char stringStorage[2][TYPE_INT_STR_SIZE(int)];
122 + char *name = NULL;
123 + int is_global = 0;
124 + char *global;
125 + TimerProcData *data;
127 + if (nArgs < 2 || nArgs > 3) {
128 + return wrongNArgsErr(errMsg);
130 + if (!readStringArg(argList[0], &name, stringStorage[0], errMsg)) {
131 + return False;
133 + if (!readIntArg(argList[1], &timeout, errMsg)) {
134 + return False;
136 + if (nArgs >= 3) {
137 + if(!readStringArg(argList[2], &global, stringStorage[1], errMsg)) {
138 + return False;
140 + if (!strcmp(global, "global")) {
141 + is_global = 1;
142 + } else {
143 + *errMsg = "unknown argument for subroutine %s";
144 + return False;
148 + if (timeout < 100) {
149 + *errMsg = "timeout too small";
150 + return False;
153 + /* terminating NIL is already in struct */
154 + data = (TimerProcData *)XtMalloc(sizeof(*data) +
155 + (strlen(name) * sizeof(char)));
156 + if (!data) {
157 + *errMsg = "internal error";
158 + return False;
161 + data->window = window;
162 + data->global = is_global;
163 + strcpy(data->name, name);
165 + data->next = allTimerProcData;
166 + allTimerProcData = data;
168 + data->id = XtAppAddTimeOut(XtWidgetToApplicationContext(window->shell),
169 + timeout, macroTimerProc, data);
171 + result->tag = INT_TAG;
172 + if (data->id != (XtIntervalId)(int)data->id) {
173 + *errMsg = "warning: can't convert from XtIntervalId to int, timer not removable";
174 + result->val.n = 0;
175 + } else {
176 + result->val.n = data->id;
179 + return True;
183 + * timer_remove(timer_ID)
184 + */
185 +static int timerRemoveMS(WindowInfo *window, DataValue *argList, int nArgs,
186 + DataValue *result, char **errMsg)
188 + int timerid;
189 + XtIntervalId id;
190 + TimerProcData *data, **s;
192 + if (nArgs != 1) {
193 + return wrongNArgsErr(errMsg);
195 + if (!readIntArg(argList[0], &timerid, errMsg)) {
196 + return False;
199 + if (0 == timerid) {
200 + /* we return 0 as timerid when we can't convert the id to int
201 + the timer can therefore not removed and the TimerProcData is freed
202 + when the timer is fired
203 + */
204 + return True;
207 + id = timerid;
209 + XtRemoveTimeOut(id);
211 + s = &allTimerProcData;
212 + while (*s) {
213 + if ((*s)->id == id) {
214 + data = *s;
215 + *s = data->next;
216 + XtFree((char *)data);
217 + break;
219 + s = &(*s)->next;
222 + return True;
225 /* T Balinski */
226 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
227 DataValue *result, char **errMsg)
229 macroCmdInfo *cmdData;
230 diff --quilt old/source/highlightData.c new/source/highlightData.c
231 --- old/source/highlightData.c
232 +++ new/source/highlightData.c
233 @@ -549,11 +549,11 @@ static char *DefaultPatternSets[] = {
234 README:\"NEdit Macro syntax highlighting patterns, version 2.6, maintainer Thorsten Haude, nedit at thorstenhau.de\":::Flag::D\n\
235 Comment:\"#\":\"$\"::Comment::\n\
236 Built-in Misc Vars:\"(?<!\\Y)\\$(?:active_pane|args|calltip_ID|column|cursor|display_width|empty_array|file_name|file_path|language_mode|line|locked|max_font_width|min_font_width|modified|n_display_lines|n_panes|rangeset_list|read_only|selection_(?:start|end|left|right)|server_name|text_length|top_line|transient|VERSION|NEDIT_HOME)>\":::Identifier::\n\
237 Built-in Pref Vars:\"(?<!\\Y)\\$(?:auto_indent|em_tab_dist|file_format|font_name|font_name_bold|font_name_bold_italic|font_name_italic|highlight_syntax|incremental_backup|incremental_search_line|make_backup_copy|match_syntax_based|overtype_mode|show_line_numbers|show_matching|statistics_line|tab_dist|use_tabs|wrap_margin|wrap_text)>\":::Identifier2::\n\
238 Built-in Special Vars:\"(?<!\\Y)\\$(?:[1-9]|list_dialog_button|n_args|read_status|search_end|shell_cmd_status|string_dialog_button|sub_sep)>\":::String1::\n\
239 - Built-in Subrs:\"<(?:append_file|beep|call|calltip|clipboard_to_string|define|dialog|filename_dialog|dict_(?:insert|complete|save|append|is_element)|focus_window|get_character|get_matching|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|highlight_calltip_line|kill_calltip|length|list_dialog|max|min|rangeset_(?:add|create|destroy|get_by_name|includes|info|invert|range|set_color|set_mode|set_name|subtract)|read_file|replace_in_string|replace_range|replace_selection|replace_substring|search|search_string|select|select_rectangle|set_cursor_pos|set_transient|set_window_title|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|to_(?:column|line|pos)|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
240 + Built-in Subrs:\"<(?:append_file|beep|call|calltip|clipboard_to_string|define|dialog|filename_dialog|dict_(?:insert|complete|save|append|is_element)|focus_window|get_character|get_matching|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|highlight_calltip_line|kill_calltip|length|list_dialog|max|min|rangeset_(?:add|create|destroy|get_by_name|includes|info|invert|range|set_color|set_mode|set_name|subtract)|read_file|replace_in_string|replace_range|replace_selection|replace_substring|search|search_string|select|select_rectangle|set_cursor_pos|set_transient|set_window_title|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|timer_(?:add|remove)|to_(?:column|line|pos)|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
241 Menu Actions:\"<(?:new(?:_tab|_opposite)?|open|open-dialog|open_dialog|open-selected|open_selected|close|save|save-as|save_as|save-as-dialog|save_as_dialog|revert-to-saved|revert_to_saved|revert_to_saved_dialog|include-file|include_file|include-file-dialog|include_file_dialog|load-macro-file|load_macro_file|load-macro-file-dialog|load_macro_file_dialog|load-tags-file|load_tags_file|load-tags-file-dialog|load_tags_file_dialog|unload_tags_file|load_tips_file|load_tips_file_dialog|unload_tips_file|print|print-selection|print_selection|exit|undo|redo|delete|select-all|select_all|shift-left|shift_left|shift-left-by-tab|shift_left_by_tab|shift-right|shift_right|shift-right-by-tab|shift_right_by_tab|find|find-dialog|find_dialog|find-again|find_again|find-selection|find_selection|find_incremental|start_incremental_find|replace|replace-dialog|replace_dialog|replace-all|replace_all|replace-in-selection|replace_in_selection|replace-again|replace_again|replace_find|replace_find_same|replace_find_again|goto-line-number|goto_line_number|goto-line-number-dialog|goto_line_number_dialog|goto-selected|goto_selected|mark|mark-dialog|mark_dialog|goto-mark|goto_mark|goto-mark-dialog|goto_mark_dialog|match|select_to_matching|goto_matching|find-definition|find_definition|show_tip|split-pane|split_pane|close-pane|close_pane|detach_document(?:_dialog)?|move_document_dialog|(?:next|previous|last)_document|uppercase|lowercase|fill-paragraph|fill_paragraph|control-code-dialog|control_code_dialog|filter-selection-dialog|filter_selection_dialog|filter-selection|filter_selection|execute-command|execute_command|execute-command-dialog|execute_command_dialog|execute-command-line|execute_command_line|shell-menu-command|shell_menu_command|macro-menu-command|macro_menu_command|bg_menu_command|post_window_bg_menu|post_tab_context_menu|beginning-of-selection|beginning_of_selection|end-of-selection|end_of_selection|repeat_macro|repeat_dialog|raise_window|focus_pane|set_statistics_line|set_incremental_search_line|set_show_line_numbers|set_auto_indent|set_wrap_text|set_wrap_margin|set_highlight_syntax|set_make_backup_copy|set_incremental_backup|set_show_matching|set_match_syntax_based|set_overtype_mode|set_locked|set_tab_dist|set_em_tab_dist|set_use_tabs|set_fonts|set_language_mode)(?=\\s*\\()\":::Subroutine::\n\
242 Text Actions:\"<(?:self-insert|self_insert|grab-focus|grab_focus|extend-adjust|extend_adjust|extend-start|extend_start|extend-end|extend_end|secondary-adjust|secondary_adjust|secondary-or-drag-adjust|secondary_or_drag_adjust|secondary-start|secondary_start|secondary-or-drag-start|secondary_or_drag_start|process-bdrag|process_bdrag|move-destination|move_destination|move-to|move_to|move-to-or-end-drag|move_to_or_end_drag|end_drag|copy-to|copy_to|copy-to-or-end-drag|copy_to_or_end_drag|exchange|process-cancel|process_cancel|paste-clipboard|paste_clipboard|copy-clipboard|copy_clipboard|cut-clipboard|cut_clipboard|copy-primary|copy_primary|cut-primary|cut_primary|newline|newline-and-indent|newline_and_indent|newline-no-indent|newline_no_indent|delete-selection|delete_selection|delete-previous-character|delete_previous_character|delete-next-character|delete_next_character|delete-previous-word|delete_previous_word|delete-next-word|delete_next_word|delete-to-start-of-line|delete_to_start_of_line|delete-to-end-of-line|delete_to_end_of_line|forward-character|forward_character|backward-character|backward_character|key-select|key_select|process-up|process_up|process-down|process_down|process-shift-up|process_shift_up|process-shift-down|process_shift_down|process-home|process_home|forward-word|forward_word|backward-word|backward_word|forward-paragraph|forward_paragraph|backward-paragraph|backward_paragraph|beginning-of-line|beginning_of_line|end-of-line|end_of_line|beginning-of-file|beginning_of_file|end-of-file|end_of_file|next-page|next_page|previous-page|previous_page|page-left|page_left|page-right|page_right|toggle-overstrike|toggle_overstrike|scroll-up|scroll_up|scroll-down|scroll_down|scroll_left|scroll_right|scroll-to-line|scroll_to_line|select-all|select_all|deselect-all|deselect_all|focusIn|focusOut|process-return|process_return|process-tab|process_tab|insert-string|insert_string|mouse_pan)(?=\\s*\\()\":::Subroutine::\n\
243 Macro Hooks:\"<(?:(?:pre|post)_(?:open|save)|cursor_moved|modified|(?:losing_)?focus)_hook(?=\\s*\\()\":::Subroutine1::\n\
244 Keyword:\"<(?:break|continue|define|delete|else|for|if|in|return|typeof|while)>\":::Keyword::\n\
245 Braces:\"[{}\\[\\]]\":::Keyword::\n\
246 diff --quilt old/doc/help.etx new/doc/help.etx
247 --- old/doc/help.etx
248 +++ new/doc/help.etx
249 @@ -2907,10 +2907,20 @@ Macro Subroutines
250 is beyond the end position, the empty string is returned.
252 **t_print( string1, string2, ... )**
253 Writes strings to the terminal (stdout) from which NEdit was started.
255 +**timer_add( func_name, timeout [, "global"] )**
256 + Install a new timer that call the macro routine ~func_name~ after ~timeout~
257 + milli seconds. The function is only called if the top window is the same as
258 + the window from which ~timer_add()~ was called, this can be overriden with the
259 + optional ~"global"~ parameter. The macro returns a timer ID which can be used
260 + to remove a timer before expiration with ~timer_remove()~.
262 +**timer_remove( timer_ID )**
263 + Removes the timer with ID ~timer_ID~.
265 **to_column( position )**
266 Convert given position to column number in current window.
268 **to_line( position )**
269 Convert given position to line number in current window.