final step to context based macro interpreter
[nedit-bw.git] / highlight_calltip_line.patch
blob561ef25037e43c7cd46b407459542280351faaff
1 From: Thorsten Haude <yoo@vranx.de>
2 Subject: highlight_calltip_line() macro
4 Highlight a line in the currently shown calltip.
6 This uses a XmText as the widget for the calltip.
8 ---
10 doc/help.etx | 4 +
11 source/calltips.c | 109 ++++++++++++++++++++++++++++++++++++++++++++-----
12 source/calltips.h | 4 +
13 source/highlightData.c | 2
14 source/macro.c | 54 ++++++++++++++++++++++++
15 5 files changed, 163 insertions(+), 10 deletions(-)
17 diff --quilt old/doc/help.etx new/doc/help.etx
18 --- old/doc/help.etx
19 +++ new/doc/help.etx
20 @@ -2709,6 +2709,10 @@ Macro Subroutines
21 **getenv( name )**
22 Gets the value of an environment variable.
24 +**highlight_calltip_line(calltip_ID, line)**
25 + Highlights a single line in the given calltip. Set ~line~ to 0 to remove
26 + any existing highlighting.
28 **kill_calltip( [calltip_ID] )**
29 Kills any calltip that is being displayed in the window in which the macro is
30 running. If there is no displayed calltip this does nothing. If a calltip
31 diff --quilt old/source/calltips.c new/source/calltips.c
32 --- old/source/calltips.c
33 +++ new/source/calltips.c
34 @@ -42,6 +42,7 @@
36 #include <Xm/Xm.h>
37 #include <Xm/Label.h>
38 +#include <Xm/Text.h>
39 #include <X11/Shell.h>
41 #ifdef HAVE_DEBUG_H
42 @@ -63,6 +64,9 @@ static void getTipMetrics(Widget tip,
43 Position *borderWidthPtr);
44 static void moveTip(Widget tip, Position x, Position y);
46 +static Boolean getRangeOfLine(const char *textString, unsigned line,
47 + unsigned *begin, unsigned *end);
50 ** Pop-down a calltip if one exists, else do nothing
52 @@ -373,7 +377,60 @@ void TextDKillScrolltip(textDisp *textD)
56 -** This creates a calltip of class XmLabel and its parent, a shell of class
57 +** Highlight a single line in a given calltip, erasing all other highlights.
58 +**
59 +** Return values for this one need to be a bit more expressive. Some errors
60 +** might just be the result of sloppy parameters, and the caller should
61 +** decide whether to fail hard or not. The following results are possible:
62 +**
63 +** - The calltip ID given is invalid (CT_INVALID_ID).
64 +** - The user requested to remove all highlightings (CT_OK).
65 +** - The requested line is highlighted (CT_OK).
66 +** - The requested line is not in the provided text (CT_NOLINE).
67 +*/
68 +int HighlightCalltipLine(const WindowInfo *window, int calltipID, unsigned line)
70 + textDisp *textD = ((TextWidget)window->lastFocus)->text.textD;
71 + Boolean result = False;
73 + if (calltipID == textD->calltip.ID) {
74 + Widget textWidget = textD->calltip.tip;
75 + char *textString = XmTextGetString(textWidget);
76 + XmTextPosition textLength = XmTextGetLastPosition(textWidget);
77 + unsigned begin = 0, end = 0;
78 + Boolean lineIsValid = False;
80 + /* First remove all existing highlights. */
81 + XmTextSetHighlight(textWidget, 0, textLength + 1, XmHIGHLIGHT_NORMAL);
83 + if (0 == line) {
84 + /* Just return without highlighting anything. */
85 + result = CT_OK;
86 + } else {
87 + lineIsValid = getRangeOfLine(textString, line, &begin, &end);
88 + if (lineIsValid) {
89 + XmTextSetHighlight(textWidget,
90 + (XmTextPosition)begin,
91 + (XmTextPosition)end,
92 + XmHIGHLIGHT_SELECTED);
94 + result = CT_OK;
95 + } else {
96 + /* The requested line is not in the provided text. */
97 + result = CT_NOLINE;
98 + }
99 + }
101 + XtFree(textString);
102 + } else {
103 + result = CT_INVALID_ID;
106 + return result;
110 +** This creates a calltip of class XmText and its parent, a shell of class
111 ** OverrideShell (which in turn will be the child of the grandfather
112 ** parameter). The tip will have minimum size but will resize to match
113 ** the text entered (see XmNallowShellResize).
114 @@ -393,7 +450,7 @@ static Widget createTip(const char *name
116 Widget tip = NULL;
117 Widget shell = NULL;
118 - Arg args[10];
119 + Arg args[2];
120 int argcnt = 0;
121 char *shellNameBuf;
123 @@ -417,12 +474,18 @@ static Widget createTip(const char *name
124 /* Might want to make this a read-only XmText eventually so that
125 users can copy from it */
126 tip = XtVaCreateManagedWidget(name,
127 - xmLabelWidgetClass, shell,
128 - XmNborderWidth, 1, /* Thin borders */
129 + xmTextWidgetClass, shell,
130 XmNhighlightThickness, 0,
131 - XmNalignment, XmALIGNMENT_BEGINNING,
132 + XmNalignment, alignment,
133 + XmNeditable, False,
134 + XmNeditMode, XmMULTI_LINE_EDIT,
135 + XmNcursorPositionVisible, False,
136 + XmNresizeHeight, True,
137 + XmNresizeWidth, True,
138 XmNforeground, foreground,
139 XmNbackground, background,
140 + XmNheight, 1,
141 + XmNwidth, 1,
142 NULL);
144 return tip;
145 @@ -435,11 +498,14 @@ static Widget shellOfTip(Widget tip)
147 static void setTipText(Widget tip, const char *text)
149 - XmString str;
150 + /* shrink the text widget to a minimum size, so that the new text
151 + grow it to its size. */
152 + XtVaSetValues(tip,
153 + XmNheight, 1,
154 + XmNwidth, 1,
155 + NULL);
157 - str = XmStringCreateLtoR((char *)text, XmFONTLIST_DEFAULT_TAG);
158 - XtVaSetValues(tip, XmNlabelString, str, NULL);
159 - XmStringFree(str);
160 + XmTextSetString(tip, text);
163 static void showTip(Widget tip)
164 @@ -487,3 +553,28 @@ static void moveTip(Widget tip, Position
165 XmNy, y,
166 NULL);
170 +** Sets the parameters to beginning and end of the line. Returns False if
171 +** the line is not in the text, True otherwise.
173 +static Boolean getRangeOfLine(const char *textString, unsigned line,
174 + unsigned *begin, unsigned *end)
176 + int i;
177 + size_t position = 0;
179 + for (i = 0; i < line; i++) {
180 + *end = strcspn(textString + position, "\n") + position;
181 + *begin = position;
182 + position = *end + 1;
184 + if (*begin == *end) {
185 + /* Break if last line is found. */
186 + break;
190 + return (*begin != *end);
193 diff --quilt old/source/calltips.h new/source/calltips.h
194 --- old/source/calltips.h
195 +++ new/source/calltips.h
196 @@ -39,6 +39,7 @@ enum TipHAlignMode {TIP_LEFT, TIP_CENTER
197 enum TipVAlignMode {TIP_ABOVE, TIP_BELOW};
198 enum TipAlignStrict {TIP_SLOPPY, TIP_STRICT};
199 enum ScrolltipAlignMode {SCROLLTIP_LEFT, SCROLLTIP_RIGHT};
200 +enum TipHighlightError {CT_OK, CT_INVALID_ID, CT_NOLINE};
202 int ShowCalltip(WindowInfo *window, char *text, Boolean anchored,
203 int pos, int hAlign, int vAlign, int alignMode);
204 @@ -51,4 +52,7 @@ Boolean TextDShowScrolltip(textDisp *tex
205 int align);
206 void TextDKillScrolltip(textDisp *textD);
208 +int HighlightCalltipLine(const WindowInfo *window, int calltipID,
209 + unsigned line);
211 #endif /* ifndef NEDIT_CALLTIPS_H_INCLUDED */
212 diff --quilt old/source/highlightData.c new/source/highlightData.c
213 --- old/source/highlightData.c
214 +++ new/source/highlightData.c
215 @@ -551,7 +551,7 @@ static char *DefaultPatternSets[] = {
216 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|VERSION|NEDIT_HOME)>\":::Identifier::\n\
217 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\
218 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\
219 - Built-in Subrs:\"<(?:args|append_file|beep|call|calltip|clipboard_to_string|dialog|filename_dialog|focus_window|get_character|get_pattern_(by_name|at_pos)|get_range|get_selection|get_style_(by_name|at_pos)|getenv|kill_calltip|length|list_dialog|max|min|n_args|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|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
220 + Built-in Subrs:\"<(?:args|append_file|beep|call|calltip|clipboard_to_string|dialog|filename_dialog|focus_window|get_character|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|n_args|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|shell_command|split|string_compare|string_dialog|string_to_clipboard|substring|t_print|tolower|toupper|valid_number|write_file)(?=\\s*\\()\":::Subroutine::\n\
221 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\
222 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\
223 Keyword:\"<(?:break|continue|define|delete|do|else|for|if|in|return|while)>\":::Keyword::\n\
224 diff --quilt old/source/macro.c new/source/macro.c
225 --- old/source/macro.c
226 +++ new/source/macro.c
227 @@ -252,6 +252,8 @@ static int calltipMS(WindowInfo *window,
228 DataValue *result, char **errMsg);
229 static int killCalltipMS(WindowInfo *window, DataValue *argList, int nArgs,
230 DataValue *result, char **errMsg);
231 +static int highlightCTLineMS(WindowInfo *window, DataValue *argList, int nArgs,
232 + DataValue *result, char **errMsg);
233 /* T Balinski */
234 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
235 DataValue *result, char **errMsg);
236 @@ -465,6 +467,7 @@ static const BuiltInSubrName MacroSubrs[
237 { "split", splitMS },
238 { "calltip", calltipMS },
239 { "kill_calltip", killCalltipMS },
240 + { "highlight_calltip_line", highlightCTLineMS },
241 /* DISABLED for 5.4
242 { "set_backlight_string", setBacklightStringMS },
244 @@ -3443,6 +3446,57 @@ static int killCalltipMS(WindowInfo *win
248 +** highlight_calltip_line(ctID, line)
250 +static int highlightCTLineMS(WindowInfo *window, DataValue *argList, int nArgs,
251 + DataValue *result, char **errMsg)
253 + int calltipID = 0;
254 + int line;
255 + int highlightResult;
257 + if (2 != nArgs) {
258 + *errMsg = "%s() called with wrong number of arguments";
259 + return False;
262 + if (!readIntArg(argList[0], &calltipID, errMsg)) {
263 + *errMsg = "%s(): Could not read calltip ID from argument 1";
264 + return False;
267 + /* The macro function calltip() uses 0 to report an error. Catch sloppy
268 + programmers who just feed this value into this function. */
269 + if (0 == calltipID) {
270 + *errMsg = "%s(): Invalid calltip ID 0";
271 + return False;
274 + if (!readIntArg(argList[1], &line, errMsg) || line < 0) {
275 + *errMsg = "%s(): Could not read line number from argument 2";
276 + return False;
279 + result->tag = NO_TAG;
281 + highlightResult = HighlightCalltipLine(window, calltipID, (unsigned)line);
283 + if (CT_INVALID_ID == highlightResult) {
284 + /* Fail only if the calltip ID given is invalid. */
285 + *errMsg = "%s(): Invalid calltip ID";
286 + return False;
289 + /* In case NEdit ever gets a warning (!= error) mechanism. *//*
290 + if (CT_NOLINE == highlightResult) {
291 + *warnMsg = "%s(): Calltip line out of range";
293 + */
295 + return True;
299 * A subroutine to get the ID of the current calltip, or 0 if there is none.
301 static int calltipIDMV(WindowInfo *window, DataValue *argList,