1 From: Tony Balinski <ajbj@free.fr>
2 Subject: Change the registration of macro built-ins to improve maintenance
4 The association of name and value (either a function pointer or an integer)
5 is made explicit here. It also allows for other tables of such associations
6 elsewhere, allowing for separate (theme-based) macro function definition
7 files. It makes macro definition more like the action routine naming too.
11 source/macro.c | 280 +++++++++++++++++++++++++++++++++++++--------------------
12 source/macro.h | 22 ++++
13 2 files changed, 203 insertions(+), 99 deletions(-)
15 diff --quilt old/source/macro.c new/source/macro.c
16 --- old/source/macro.c
17 +++ new/source/macro.c
18 @@ -416,90 +416,140 @@ static int getStyleAtPosMS(WindowInfo *w
19 DataValue *result, char **errMsg);
20 static int filenameDialogMS(WindowInfo* window, DataValue* argList, int nArgs,
21 DataValue* result, char** errMsg);
23 /* Built-in subroutines and variables for the macro language */
24 -static BuiltInSubr MacroSubrs[] = {lengthMS, getRangeMS, tPrintMS,
25 - dialogMS, stringDialogMS, replaceRangeMS, replaceSelectionMS,
26 - setCursorPosMS, getCharacterMS, minMS, maxMS, searchMS,
27 - searchStringMS, substringMS, replaceSubstringMS, readFileMS,
28 - writeFileMS, appendFileMS, beepMS, getSelectionMS, validNumberMS,
29 - replaceInStringMS, selectMS, selectRectangleMS, focusWindowMS,
30 - shellCmdMS, stringToClipboardMS, clipboardToStringMS, toupperMS,
31 - tolowerMS, listDialogMS, getenvMS,
32 - stringCompareMS, splitMS, calltipMS, killCalltipMS,
33 -/* DISABLED for 5.4 setBacklightStringMS,*/
34 - rangesetCreateMS, rangesetDestroyMS,
35 - rangesetAddMS, rangesetSubtractMS, rangesetInvertMS,
36 - rangesetInfoMS, rangesetRangeMS, rangesetIncludesPosMS,
37 - rangesetSetColorMS, rangesetSetNameMS, rangesetSetModeMS,
38 - rangesetGetByNameMS,
39 - getPatternByNameMS, getPatternAtPosMS,
40 - getStyleByNameMS, getStyleAtPosMS, filenameDialogMS
42 -#define N_MACRO_SUBRS (sizeof MacroSubrs/sizeof *MacroSubrs)
43 -static const char *MacroSubrNames[N_MACRO_SUBRS] = {"length", "get_range", "t_print",
44 - "dialog", "string_dialog", "replace_range", "replace_selection",
45 - "set_cursor_pos", "get_character", "min", "max", "search",
46 - "search_string", "substring", "replace_substring", "read_file",
47 - "write_file", "append_file", "beep", "get_selection", "valid_number",
48 - "replace_in_string", "select", "select_rectangle", "focus_window",
49 - "shell_command", "string_to_clipboard", "clipboard_to_string",
50 - "toupper", "tolower", "list_dialog", "getenv",
51 - "string_compare", "split", "calltip", "kill_calltip",
52 -/* DISABLED for 5.4 "set_backlight_string", */
53 - "rangeset_create", "rangeset_destroy",
54 - "rangeset_add", "rangeset_subtract", "rangeset_invert",
55 - "rangeset_info", "rangeset_range", "rangeset_includes",
56 - "rangeset_set_color", "rangeset_set_name", "rangeset_set_mode",
57 - "rangeset_get_by_name",
58 - "get_pattern_by_name", "get_pattern_at_pos",
59 - "get_style_by_name", "get_style_at_pos", "filename_dialog"
61 -static BuiltInSubr SpecialVars[] = {cursorMV, lineMV, columnMV,
62 - fileNameMV, filePathMV, lengthMV, selectionStartMV, selectionEndMV,
63 - selectionLeftMV, selectionRightMV, wrapMarginMV, tabDistMV,
64 - emTabDistMV, useTabsMV, languageModeMV, modifiedMV,
65 - statisticsLineMV, incSearchLineMV, showLineNumbersMV,
66 - autoIndentMV, wrapTextMV, highlightSyntaxMV,
67 - makeBackupCopyMV, incBackupMV, showMatchingMV, matchSyntaxBasedMV,
68 - overTypeModeMV, readOnlyMV, lockedMV, fileFormatMV,
69 - fontNameMV, fontNameItalicMV,
70 - fontNameBoldMV, fontNameBoldItalicMV, subscriptSepMV,
71 - minFontWidthMV, maxFontWidthMV, topLineMV, numDisplayLinesMV,
72 - displayWidthMV, activePaneMV, nPanesMV, emptyArrayMV,
73 - serverNameMV, calltipIDMV,
74 -/* DISABLED for 5.4 backlightStringMV, */
75 - rangesetListMV, versionMV
77 -#define N_SPECIAL_VARS (sizeof SpecialVars/sizeof *SpecialVars)
78 -static const char *SpecialVarNames[N_SPECIAL_VARS] = {"$cursor", "$line", "$column",
79 - "$file_name", "$file_path", "$text_length", "$selection_start",
80 - "$selection_end", "$selection_left", "$selection_right",
81 - "$wrap_margin", "$tab_dist", "$em_tab_dist", "$use_tabs",
82 - "$language_mode", "$modified",
83 - "$statistics_line", "$incremental_search_line", "$show_line_numbers",
84 - "$auto_indent", "$wrap_text", "$highlight_syntax",
85 - "$make_backup_copy", "$incremental_backup", "$show_matching", "$match_syntax_based",
86 - "$overtype_mode", "$read_only", "$locked", "$file_format",
87 - "$font_name", "$font_name_italic",
88 - "$font_name_bold", "$font_name_bold_italic", "$sub_sep",
89 - "$min_font_width", "$max_font_width", "$top_line", "$n_display_lines",
90 - "$display_width", "$active_pane", "$n_panes", "$empty_array",
91 - "$server_name", "$calltip_ID",
92 -/* DISABLED for 5.4 "$backlight_string", */
93 - "$rangeset_list", "$VERSION"
96 -/* Global symbols for returning values from built-in functions */
97 -#define N_RETURN_GLOBALS 5
98 -enum retGlobalSyms {STRING_DIALOG_BUTTON, SEARCH_END, READ_STATUS,
99 - SHELL_CMD_STATUS, LIST_DIALOG_BUTTON};
100 -static const char *ReturnGlobalNames[N_RETURN_GLOBALS] = {"$string_dialog_button",
101 - "$search_end", "$read_status", "$shell_cmd_status",
102 - "$list_dialog_button"};
103 -static Symbol *ReturnGlobals[N_RETURN_GLOBALS];
104 +static const BuiltInSubrName MacroSubrs[] = {
105 + { "length", lengthMS },
106 + { "get_range", getRangeMS },
107 + { "t_print", tPrintMS },
108 + { "dialog", dialogMS },
109 + { "string_dialog", stringDialogMS },
110 + { "replace_range", replaceRangeMS },
111 + { "replace_selection", replaceSelectionMS },
112 + { "set_cursor_pos", setCursorPosMS },
113 + { "get_character", getCharacterMS },
116 + { "search", searchMS },
117 + { "search_string", searchStringMS },
118 + { "substring", substringMS },
119 + { "replace_substring", replaceSubstringMS },
120 + { "read_file", readFileMS },
121 + { "write_file", writeFileMS },
122 + { "append_file", appendFileMS },
123 + { "beep", beepMS },
124 + { "get_selection", getSelectionMS },
125 + { "valid_number", validNumberMS },
126 + { "replace_in_string", replaceInStringMS },
127 + { "select", selectMS },
128 + { "select_rectangle", selectRectangleMS },
129 + { "focus_window", focusWindowMS },
130 + { "shell_command", shellCmdMS },
131 + { "string_to_clipboard", stringToClipboardMS },
132 + { "clipboard_to_string", clipboardToStringMS },
133 + { "toupper", toupperMS },
134 + { "tolower", tolowerMS },
135 + { "list_dialog", listDialogMS },
136 + { "getenv", getenvMS },
137 + { "string_compare", stringCompareMS },
138 + { "split", splitMS },
139 + { "calltip", calltipMS },
140 + { "kill_calltip", killCalltipMS },
142 + { "set_backlight_string", setBacklightStringMS },
144 + { "rangeset_create", rangesetCreateMS },
145 + { "rangeset_destroy", rangesetDestroyMS },
146 + { "rangeset_add", rangesetAddMS },
147 + { "rangeset_subtract", rangesetSubtractMS },
148 + { "rangeset_invert", rangesetInvertMS },
149 + { "rangeset_info", rangesetInfoMS },
150 + { "rangeset_range", rangesetRangeMS },
151 + { "rangeset_includes", rangesetIncludesPosMS },
152 + { "rangeset_set_color", rangesetSetColorMS },
153 + { "rangeset_set_name", rangesetSetNameMS },
154 + { "rangeset_set_mode", rangesetSetModeMS },
155 + { "rangeset_get_by_name", rangesetGetByNameMS },
156 + { "get_pattern_by_name", getPatternByNameMS },
157 + { "get_pattern_at_pos", getPatternAtPosMS },
158 + { "get_style_by_name", getStyleByNameMS },
159 + { "get_style_at_pos", getStyleAtPosMS },
160 + { "filename_dialog", filenameDialogMS },
161 + { NULL, NULL } /* sentinel */
164 +static const BuiltInSubrName SpecialVars[] = {
165 + { "$cursor", cursorMV },
166 + { "$line", lineMV },
167 + { "$column", columnMV },
168 + { "$file_name", fileNameMV },
169 + { "$file_path", filePathMV },
170 + { "$text_length", lengthMV },
171 + { "$selection_start", selectionStartMV },
172 + { "$selection_end", selectionEndMV },
173 + { "$selection_left", selectionLeftMV },
174 + { "$selection_right", selectionRightMV },
175 + { "$wrap_margin", wrapMarginMV },
176 + { "$tab_dist", tabDistMV },
177 + { "$em_tab_dist", emTabDistMV },
178 + { "$use_tabs", useTabsMV },
179 + { "$language_mode", languageModeMV },
180 + { "$modified", modifiedMV },
181 + { "$statistics_line", statisticsLineMV },
182 + { "$incremental_search_line", incSearchLineMV },
183 + { "$show_line_numbers", showLineNumbersMV },
184 + { "$auto_indent", autoIndentMV },
185 + { "$wrap_text", wrapTextMV },
186 + { "$highlight_syntax", highlightSyntaxMV },
187 + { "$make_backup_copy", makeBackupCopyMV },
188 + { "$incremental_backup", incBackupMV },
189 + { "$show_matching", showMatchingMV },
190 + { "$match_syntax_based", matchSyntaxBasedMV },
191 + { "$overtype_mode", overTypeModeMV },
192 + { "$read_only", readOnlyMV },
193 + { "$locked", lockedMV },
194 + { "$file_format", fileFormatMV },
195 + { "$font_name", fontNameMV },
196 + { "$font_name_italic", fontNameItalicMV },
197 + { "$font_name_bold", fontNameBoldMV },
198 + { "$font_name_bold_italic", fontNameBoldItalicMV },
199 + { "$sub_sep", subscriptSepMV },
200 + { "$min_font_width", minFontWidthMV },
201 + { "$max_font_width", maxFontWidthMV },
202 + { "$top_line", topLineMV },
203 + { "$n_display_lines", numDisplayLinesMV },
204 + { "$display_width", displayWidthMV },
205 + { "$active_pane", activePaneMV },
206 + { "$n_panes", nPanesMV },
207 + { "$empty_array", emptyArrayMV },
208 + { "$server_name", serverNameMV },
209 + { "$calltip_ID", calltipIDMV },
211 + { "$backlight_string", backlightStringMV },
213 + { "$rangeset_list", rangesetListMV },
214 + { "$VERSION", versionMV },
215 + { NULL, NULL } /* sentinel */
218 +/* Global symbols for "returning" secondary values from built-in functions */
219 +static int STRING_DIALOG_BUTTON, SEARCH_END, READ_STATUS,
220 + SHELL_CMD_STATUS, LIST_DIALOG_BUTTON;
222 +static ReturnGlobalName ReturnGlobalNames[] = {
223 + /* name, pIndex: *pIndex will be set to the symbol's
224 + index in ReturnGlobals */
225 + { "$string_dialog_button", &STRING_DIALOG_BUTTON },
226 + { "$search_end", &SEARCH_END },
227 + { "$read_status", &READ_STATUS },
228 + { "$shell_cmd_status", &SHELL_CMD_STATUS },
229 + { "$list_dialog_button", &LIST_DIALOG_BUTTON },
230 + { NULL, NULL } /* sentinel */
233 +static Symbol **ReturnGlobals = NULL;
235 /* List of actions not useful when learning a macro sequence (also see below) */
236 static char* IgnoredActions[] = {"focusIn", "focusOut"};
238 /* List of actions intended to be attached to mouse buttons, which the user
239 @@ -537,34 +587,70 @@ static WindowInfo *MacroRecordWindow = N
240 /* Arrays for translating escape characters in escapeStringChars */
241 static char ReplaceChars[] = "\\\"ntbrfav";
242 static char EscapeChars[] = "\\\"\n\t\b\r\f\a\v";
245 +** Installs a set of built-in macro subroutines as symbols of given type.
247 +void RegisterMacroSubroutineSet(const BuiltInSubrName *set, enum symTypes type)
249 + static DataValue subrPtr = {NO_TAG, {0}};
252 + for (i = 0; set[i].name; i++) {
253 + subrPtr.val.subr = set[i].macroSubr;
254 + InstallSymbol(set[i].name, type, subrPtr);
259 +** Installs a set of built-in macro secondary return values as symbols of
262 +void RegisterGlobalReturnValuesSet(ReturnGlobalName *set, enum symTypes type)
265 + Symbol **newRetGlobals;
266 + static DataValue noValue = {NO_TAG, {0}};
270 + /* count the entries in the new table */
271 + while (set[n].name) n++;
272 + /* and existing entries if any */
273 + while (ReturnGlobals && ReturnGlobals[oldn]) oldn++;
275 + /* reallocate symbol reference table with space for a sentinel at the end */
276 + newRetGlobals = realloc(ReturnGlobals, (oldn + n + 1) * sizeof(Symbol *));
277 + if (!newRetGlobals) {
278 + fprintf(stderr, "nedit: failed to build macro return globals table\n");
279 + exit(EXIT_FAILURE);
282 + ReturnGlobals = newRetGlobals;
283 + /* now assign the (new) symbols at the newly allocated end of the table
284 + and store the indices in set */
285 + for (i = 0, n = oldn; set[i].name; i++, n++) {
286 + ReturnGlobals[n] = InstallSymbol(set[i].name, type, noValue);
287 + *set[i].pIndex = n;
289 + /* add the sentinel */
290 + ReturnGlobals[n] = NULL;
294 ** Install built-in macro subroutines and special variables for accessing
295 ** editor information
297 void RegisterMacroSubroutines(void)
299 - static DataValue subrPtr = {NO_TAG, {0}}, noValue = {NO_TAG, {0}};
302 /* Install symbols for built-in routines and variables, with pointers
303 to the appropriate c routines to do the work */
304 - for (i=0; i<N_MACRO_SUBRS; i++) {
305 - subrPtr.val.subr = MacroSubrs[i];
306 - InstallSymbol(MacroSubrNames[i], C_FUNCTION_SYM, subrPtr);
308 - for (i=0; i<N_SPECIAL_VARS; i++) {
309 - subrPtr.val.subr = SpecialVars[i];
310 - InstallSymbol(SpecialVarNames[i], PROC_VALUE_SYM, subrPtr);
313 - /* Define global variables used for return values, remember their
314 - locations so they can be set without a LookupSymbol call */
315 - for (i=0; i<N_RETURN_GLOBALS; i++)
316 - ReturnGlobals[i] = InstallSymbol(ReturnGlobalNames[i], GLOBAL_SYM,
318 + RegisterMacroSubroutineSet(MacroSubrs, C_FUNCTION_SYM);
319 + RegisterMacroSubroutineSet(SpecialVars, PROC_VALUE_SYM);
320 + /* Define global variables used for return values */
321 + RegisterGlobalReturnValuesSet(ReturnGlobalNames, GLOBAL_SYM);
324 #define MAX_LEARN_MSG_LEN ((2 * MAX_ACCEL_LEN) + 60)
325 void BeginLearn(WindowInfo *window)
327 diff --quilt old/source/macro.h new/source/macro.h
328 --- old/source/macro.h
329 +++ new/source/macro.h
331 *******************************************************************************/
333 #ifndef NEDIT_MACRO_H_INCLUDED
334 #define NEDIT_MACRO_H_INCLUDED
337 +#include "interpret.h"
339 #include <X11/Intrinsic.h>
341 #define REPEAT_TO_END -1
342 #define REPEAT_IN_SEL -2
345 +typedef struct BuiltInSubrNameTag {
346 + const char *name; /* its macro identifier */
347 + BuiltInSubr macroSubr; /* pointer to the function to call */
350 +/* Structure used to build an initialized static array, each entry describing a
351 +** macro built-in global result variable's symbol. The array should provide the
352 +** macro identifier eg "$search_end", and a value for pIndex, pointing to a
353 +** static integer variable to store its index. As the macro identifiers are
354 +** registered (creating symbols), by scanning the static array, each one is
355 +** given a unique index value to be able to retrieve the symbol using a direct
358 +typedef struct ReturnGlobalNameTag {
359 + const char *name; /* macro identifier eg "$search_end" */
360 + int *pIndex; /* a place to store its index */
363 void RegisterMacroSubroutines(void);
364 void AddLastCommandActionHook(XtAppContext context);
365 void BeginLearn(WindowInfo *window);
366 void FinishLearn(void);
367 void CancelMacroOrLearn(WindowInfo *window);