re-fresh
[nedit-bw.git] / highlight_calltip_line.patch
blobfb32e42e587f21d46ac6b9441f31096056ed0211
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/built-ins.h | 1
12 source/calltips.c | 109 ++++++++++++++++++++++++++++++++++++++++++++-----
13 source/calltips.h | 4 +
14 source/highlightData.c | 2
15 source/macro.c | 51 ++++++++++++++++++++++
16 6 files changed, 161 insertions(+), 10 deletions(-)
18 diff --quilt old/doc/help.etx new/doc/help.etx
19 --- old/doc/help.etx
20 +++ new/doc/help.etx
21 @@ -2709,6 +2709,10 @@ Macro Subroutines
22 **getenv( name )**
23 Gets the value of an environment variable.
25 +**highlight_calltip_line(calltip_ID, line)**
26 + Highlights a single line in the given calltip. Set ~line~ to 0 to remove
27 + any existing highlighting.
29 **kill_calltip( [calltip_ID] )**
30 Kills any calltip that is being displayed in the window in which the macro is
31 running. If there is no displayed calltip this does nothing. If a calltip
32 diff --quilt old/source/calltips.c new/source/calltips.c
33 --- old/source/calltips.c
34 +++ new/source/calltips.c
35 @@ -42,6 +42,7 @@
37 #include <Xm/Xm.h>
38 #include <Xm/Label.h>
39 +#include <Xm/Text.h>
40 #include <X11/Shell.h>
42 #ifdef HAVE_DEBUG_H
43 @@ -63,6 +64,9 @@ static void getTipMetrics(Widget tip,
44 Position *borderWidthPtr);
45 static void moveTip(Widget tip, Position x, Position y);
47 +static Boolean getRangeOfLine(const char *textString, unsigned line,
48 + unsigned *begin, unsigned *end);
51 ** Pop-down a calltip if one exists, else do nothing
53 @@ -373,7 +377,60 @@ void TextDKillScrolltip(textDisp *textD)
57 -** This creates a calltip of class XmLabel and its parent, a shell of class
58 +** Highlight a single line in a given calltip, erasing all other highlights.
59 +**
60 +** Return values for this one need to be a bit more expressive. Some errors
61 +** might just be the result of sloppy parameters, and the caller should
62 +** decide whether to fail hard or not. The following results are possible:
63 +**
64 +** - The calltip ID given is invalid (CT_INVALID_ID).
65 +** - The user requested to remove all highlightings (CT_OK).
66 +** - The requested line is highlighted (CT_OK).
67 +** - The requested line is not in the provided text (CT_NOLINE).
68 +*/
69 +int HighlightCalltipLine(const WindowInfo *window, int calltipID, unsigned line)
71 + textDisp *textD = ((TextWidget)window->lastFocus)->text.textD;
72 + Boolean result = False;
74 + if (calltipID == textD->calltip.ID) {
75 + Widget textWidget = textD->calltip.tip;
76 + char *textString = XmTextGetString(textWidget);
77 + XmTextPosition textLength = XmTextGetLastPosition(textWidget);
78 + unsigned begin = 0, end = 0;
79 + Boolean lineIsValid = False;
81 + /* First remove all existing highlights. */
82 + XmTextSetHighlight(textWidget, 0, textLength + 1, XmHIGHLIGHT_NORMAL);
84 + if (0 == line) {
85 + /* Just return without highlighting anything. */
86 + result = CT_OK;
87 + } else {
88 + lineIsValid = getRangeOfLine(textString, line, &begin, &end);
89 + if (lineIsValid) {
90 + XmTextSetHighlight(textWidget,
91 + (XmTextPosition)begin,
92 + (XmTextPosition)end,
93 + XmHIGHLIGHT_SELECTED);
95 + result = CT_OK;
96 + } else {
97 + /* The requested line is not in the provided text. */
98 + result = CT_NOLINE;
99 + }
102 + XtFree(textString);
103 + } else {
104 + result = CT_INVALID_ID;
107 + return result;
111 +** This creates a calltip of class XmText and its parent, a shell of class
112 ** OverrideShell (which in turn will be the child of the grandfather
113 ** parameter). The tip will have minimum size but will resize to match
114 ** the text entered (see XmNallowShellResize).
115 @@ -393,7 +450,7 @@ static Widget createTip(const char *name
117 Widget tip = NULL;
118 Widget shell = NULL;
119 - Arg args[10];
120 + Arg args[2];
121 int argcnt = 0;
122 char *shellNameBuf;
124 @@ -417,12 +474,18 @@ static Widget createTip(const char *name
125 /* Might want to make this a read-only XmText eventually so that
126 users can copy from it */
127 tip = XtVaCreateManagedWidget(name,
128 - xmLabelWidgetClass, shell,
129 - XmNborderWidth, 1, /* Thin borders */
130 + xmTextWidgetClass, shell,
131 XmNhighlightThickness, 0,
132 - XmNalignment, XmALIGNMENT_BEGINNING,
133 + XmNalignment, alignment,
134 + XmNeditable, False,
135 + XmNeditMode, XmMULTI_LINE_EDIT,
136 + XmNcursorPositionVisible, False,
137 + XmNresizeHeight, True,
138 + XmNresizeWidth, True,
139 XmNforeground, foreground,
140 XmNbackground, background,
141 + XmNheight, 1,
142 + XmNwidth, 1,
143 NULL);
145 return tip;
146 @@ -435,11 +498,14 @@ static Widget shellOfTip(Widget tip)
148 static void setTipText(Widget tip, const char *text)
150 - XmString str;
151 + /* shrink the text widget to a minimum size, so that the new text
152 + grow it to its size. */
153 + XtVaSetValues(tip,
154 + XmNheight, 1,
155 + XmNwidth, 1,
156 + NULL);
158 - str = XmStringCreateLtoR((char *)text, XmFONTLIST_DEFAULT_TAG);
159 - XtVaSetValues(tip, XmNlabelString, str, NULL);
160 - XmStringFree(str);
161 + XmTextSetString(tip, text);
164 static void showTip(Widget tip)
165 @@ -487,3 +553,28 @@ static void moveTip(Widget tip, Position
166 XmNy, y,
167 NULL);
171 +** Sets the parameters to beginning and end of the line. Returns False if
172 +** the line is not in the text, True otherwise.
174 +static Boolean getRangeOfLine(const char *textString, unsigned line,
175 + unsigned *begin, unsigned *end)
177 + int i;
178 + size_t position = 0;
180 + for (i = 0; i < line; i++) {
181 + *end = strcspn(textString + position, "\n") + position;
182 + *begin = position;
183 + position = *end + 1;
185 + if (*begin == *end) {
186 + /* Break if last line is found. */
187 + break;
191 + return (*begin != *end);
194 diff --quilt old/source/calltips.h new/source/calltips.h
195 --- old/source/calltips.h
196 +++ new/source/calltips.h
197 @@ -39,6 +39,7 @@ enum TipHAlignMode {TIP_LEFT, TIP_CENTER
198 enum TipVAlignMode {TIP_ABOVE, TIP_BELOW};
199 enum TipAlignStrict {TIP_SLOPPY, TIP_STRICT};
200 enum ScrolltipAlignMode {SCROLLTIP_LEFT, SCROLLTIP_RIGHT};
201 +enum TipHighlightError {CT_OK, CT_INVALID_ID, CT_NOLINE};
203 int ShowCalltip(WindowInfo *window, char *text, Boolean anchored,
204 int pos, int hAlign, int vAlign, int alignMode);
205 @@ -51,4 +52,7 @@ Boolean TextDShowScrolltip(textDisp *tex
206 int align);
207 void TextDKillScrolltip(textDisp *textD);
209 +int HighlightCalltipLine(const WindowInfo *window, int calltipID,
210 + unsigned line);
212 #endif /* ifndef NEDIT_CALLTIPS_H_INCLUDED */
213 diff --quilt old/source/highlightData.c new/source/highlightData.c
214 --- old/source/highlightData.c
215 +++ new/source/highlightData.c
216 @@ -551,7 +551,7 @@ static char *DefaultPatternSets[] = {
217 Built-in Misc Vars:\"(?<!\\Y)\\$(?:active_pane|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\
218 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\
219 Built-in Special Vars:\"(?<!\\Y)\\$(?:args|[1-9]|list_dialog_button|n_args|read_status|search_end|shell_cmd_status|string_dialog_button|sub_sep)>\":::String1::\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|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 + 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\
222 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\
223 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\
224 Keyword:\"<(?:break|continue|define|delete|do|else|for|if|in|return|while)>\":::Keyword::\n\
225 diff --quilt old/source/macro.c new/source/macro.c
226 --- old/source/macro.c
227 +++ new/source/macro.c
228 @@ -3136,6 +3136,57 @@ static int killCalltipMS(WindowInfo *win
232 +** highlight_calltip_line(ctID, line)
234 +static int highlightCTLineMS(WindowInfo *window, DataValue *argList, int nArgs,
235 + DataValue *result, char **errMsg)
237 + int calltipID = 0;
238 + int line;
239 + int highlightResult;
241 + if (2 != nArgs) {
242 + *errMsg = "%s() called with wrong number of arguments";
243 + return False;
246 + if (!readIntArg(argList[0], &calltipID, errMsg)) {
247 + *errMsg = "%s(): Could not read calltip ID from argument 1";
248 + return False;
251 + /* The macro function calltip() uses 0 to report an error. Catch sloppy
252 + programmers who just feed this value into this function. */
253 + if (0 == calltipID) {
254 + *errMsg = "%s(): Invalid calltip ID 0";
255 + return False;
258 + if (!readIntArg(argList[1], &line, errMsg) || line < 0) {
259 + *errMsg = "%s(): Could not read line number from argument 2";
260 + return False;
263 + result->tag = NO_TAG;
265 + highlightResult = HighlightCalltipLine(window, calltipID, (unsigned)line);
267 + if (CT_INVALID_ID == highlightResult) {
268 + /* Fail only if the calltip ID given is invalid. */
269 + *errMsg = "%s(): Invalid calltip ID";
270 + return False;
273 + /* In case NEdit ever gets a warning (!= error) mechanism. *//*
274 + if (CT_NOLINE == highlightResult) {
275 + *warnMsg = "%s(): Calltip line out of range";
277 + */
279 + return True;
283 * A subroutine to get the ID of the current calltip, or 0 if there is none.
285 static int calltipIDMV(WindowInfo *window, DataValue *argList,
286 diff --quilt old/source/built-ins.h new/source/built-ins.h
287 --- old/source/built-ins.h
288 +++ new/source/built-ins.h
289 @@ -61,6 +61,7 @@ MS(filename_dialog, filenameDialog)
290 MS(call, call)
291 MS(args, args)
292 MS(n_args, nArgs)
293 +MS(highlight_calltip_line, highlightCTLine)
295 MV(cursor, cursor)
296 MV(line, line)