4 source/calltips.c | 109 ++++++++++++++++++++++++++++++++++++++++++++-----
5 source/calltips.h | 4 +
6 source/highlightData.c | 2
7 source/macro.c | 54 ++++++++++++++++++++++++
8 5 files changed, 163 insertions(+), 10 deletions(-)
10 diff --quilt old/doc/help.etx new/doc/help.etx
13 @@ -2708,10 +2708,14 @@ Macro Subroutines
14 the screen (keyword "any").
17 Gets the value of an environment variable.
19 +**highlight_calltip_line(calltip_ID, line)**
20 + Highlights a single line in the given calltip. Set ~line~ to 0 to remove
21 + any existing highlighting.
23 **kill_calltip( [calltip_ID] )**
24 Kills any calltip that is being displayed in the window in which the macro is
25 running. If there is no displayed calltip this does nothing. If a calltip
26 ID is supplied then the calltip is killed only if its ID is calltip_ID.
28 diff --quilt old/source/calltips.c new/source/calltips.c
29 --- old/source/calltips.c
30 +++ new/source/calltips.c
38 #include <X11/Shell.h>
43 @@ -61,10 +62,13 @@ static void realizeTip(Widget tip);
44 static void getTipMetrics(Widget tip,
45 Position *widthPtr, Position *heightPtr,
46 Position *borderWidthPtr);
47 static void moveTip(Widget tip, Position x, Position y);
49 +static Boolean getRangeOfLine(const char *textString, unsigned line,
50 + unsigned *begin, unsigned *end);
53 ** Pop-down a calltip if one exists, else do nothing
55 void KillCalltip(WindowInfo *window, int calltipID) {
56 textDisp *textD = ((TextWidget)window->lastFocus)->text.textD;
57 @@ -371,11 +375,64 @@ void TextDKillScrolltip(textDisp *textD)
58 hideTip(textD->scrolltip);
63 -** This creates a calltip of class XmLabel and its parent, a shell of class
64 +** Highlight a single line in a given calltip, erasing all other highlights.
66 +** Return values for this one need to be a bit more expressive. Some errors
67 +** might just be the result of sloppy parameters, and the caller should
68 +** decide whether to fail hard or not. The following results are possible:
70 +** - The calltip ID given is invalid (CT_INVALID_ID).
71 +** - The user requested to remove all highlightings (CT_OK).
72 +** - The requested line is highlighted (CT_OK).
73 +** - The requested line is not in the provided text (CT_NOLINE).
75 +int HighlightCalltipLine(const WindowInfo *window, int calltipID, unsigned line)
77 + textDisp *textD = ((TextWidget)window->lastFocus)->text.textD;
78 + Boolean result = False;
80 + if (calltipID == textD->calltip.ID) {
81 + Widget textWidget = textD->calltip.tip;
82 + char *textString = XmTextGetString(textWidget);
83 + XmTextPosition textLength = XmTextGetLastPosition(textWidget);
84 + unsigned begin = 0, end = 0;
85 + Boolean lineIsValid = False;
87 + /* First remove all existing highlights. */
88 + XmTextSetHighlight(textWidget, 0, textLength + 1, XmHIGHLIGHT_NORMAL);
91 + /* Just return without highlighting anything. */
94 + lineIsValid = getRangeOfLine(textString, line, &begin, &end);
96 + XmTextSetHighlight(textWidget,
97 + (XmTextPosition)begin,
98 + (XmTextPosition)end,
99 + XmHIGHLIGHT_SELECTED);
103 + /* The requested line is not in the provided text. */
104 + result = CT_NOLINE;
108 + XtFree(textString);
110 + result = CT_INVALID_ID;
117 +** This creates a calltip of class XmText and its parent, a shell of class
118 ** OverrideShell (which in turn will be the child of the grandfather
119 ** parameter). The tip will have minimum size but will resize to match
120 ** the text entered (see XmNallowShellResize).
122 ** Color is picked by the two parameters foreground and background.
123 @@ -391,11 +448,11 @@ void TextDKillScrolltip(textDisp *textD)
124 static Widget createTip(const char *name, Widget grandfather,
125 Pixel foreground, Pixel background, unsigned char alignment)
134 shellNameBuf = XtMalloc(strlen(name) + strlen("shell") + 1);
135 if (NULL == shellNameBuf) {
136 @@ -415,16 +472,22 @@ static Widget createTip(const char *name
137 XtFree(shellNameBuf);
139 /* Might want to make this a read-only XmText eventually so that
140 users can copy from it */
141 tip = XtVaCreateManagedWidget(name,
142 - xmLabelWidgetClass, shell,
143 - XmNborderWidth, 1, /* Thin borders */
144 + xmTextWidgetClass, shell,
145 XmNhighlightThickness, 0,
146 - XmNalignment, XmALIGNMENT_BEGINNING,
147 + XmNalignment, alignment,
148 + XmNeditable, False,
149 + XmNeditMode, XmMULTI_LINE_EDIT,
150 + XmNcursorPositionVisible, False,
151 + XmNresizeHeight, True,
152 + XmNresizeWidth, True,
153 XmNforeground, foreground,
154 XmNbackground, background,
162 @@ -433,15 +496,18 @@ static Widget shellOfTip(Widget tip)
163 return tip ? XtParent(tip) : NULL;
166 static void setTipText(Widget tip, const char *text)
169 + /* shrink the text widget to a minimum size, so that the new text
170 + grow it to its size. */
176 - str = XmStringCreateLtoR((char *)text, XmFONTLIST_DEFAULT_TAG);
177 - XtVaSetValues(tip, XmNlabelString, str, NULL);
179 + XmTextSetString(tip, text);
182 static void showTip(Widget tip)
184 XtPopup(shellOfTip(tip), XtGrabNone);
185 @@ -485,5 +551,30 @@ static void moveTip(Widget tip, Position
186 XtVaSetValues(shellOfTip(tip),
193 +** Sets the parameters to beginning and end of the line. Returns False if
194 +** the line is not in the text, True otherwise.
196 +static Boolean getRangeOfLine(const char *textString, unsigned line,
197 + unsigned *begin, unsigned *end)
200 + size_t position = 0;
202 + for (i = 0; i < line; i++) {
203 + *end = strcspn(textString + position, "\n") + position;
205 + position = *end + 1;
207 + if (*begin == *end) {
208 + /* Break if last line is found. */
213 + return (*begin != *end);
216 diff --quilt old/source/calltips.h new/source/calltips.h
217 --- old/source/calltips.h
218 +++ new/source/calltips.h
221 enum TipHAlignMode {TIP_LEFT, TIP_CENTER, TIP_RIGHT};
222 enum TipVAlignMode {TIP_ABOVE, TIP_BELOW};
223 enum TipAlignStrict {TIP_SLOPPY, TIP_STRICT};
224 enum ScrolltipAlignMode {SCROLLTIP_LEFT, SCROLLTIP_RIGHT};
225 +enum TipHighlightError {CT_OK, CT_INVALID_ID, CT_NOLINE};
227 int ShowCalltip(WindowInfo *window, char *text, Boolean anchored,
228 int pos, int hAlign, int vAlign, int alignMode);
229 void KillCalltip(WindowInfo *window, int calltipID);
230 void TextDKillCalltip(textDisp *textD, int calltipID);
231 @@ -49,6 +50,9 @@ void TextDRedrawCalltip(textDisp *textD,
233 Boolean TextDShowScrolltip(textDisp *textD, unsigned line, int x, int y,
235 void TextDKillScrolltip(textDisp *textD);
237 +int HighlightCalltipLine(const WindowInfo *window, int calltipID,
240 #endif /* ifndef NEDIT_CALLTIPS_H_INCLUDED */
241 diff --quilt old/source/highlightData.c new/source/highlightData.c
242 --- old/source/highlightData.c
243 +++ new/source/highlightData.c
244 @@ -549,11 +549,11 @@ static char *DefaultPatternSets[] = {
245 README:\"NEdit Macro syntax highlighting patterns, version 2.6, maintainer Thorsten Haude, nedit at thorstenhau.de\":::Flag::D\n\
246 Comment:\"#\":\"$\"::Comment::\n\
247 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\
248 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\
249 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\
250 - Built-in Subrs:\"<(?: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|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\
251 + Built-in Subrs:\"<(?: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|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\
252 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\
253 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\
254 Keyword:\"<(?:break|continue|define|delete|else|for|if|in|return|while)>\":::Keyword::\n\
255 Braces:\"[{}\\[\\]]\":::Keyword::\n\
256 Global Variable:\"\\$[A-Za-z0-9_]+\":::Identifier1::\n\
257 diff --quilt old/source/macro.c new/source/macro.c
258 --- old/source/macro.c
259 +++ new/source/macro.c
260 @@ -235,10 +235,12 @@ static void stringDialogEscCB(Widget w,
261 #endif /* LESSTIF_VERSION */
262 static int calltipMS(WindowInfo *window, DataValue *argList, int nArgs,
263 DataValue *result, char **errMsg);
264 static int killCalltipMS(WindowInfo *window, DataValue *argList, int nArgs,
265 DataValue *result, char **errMsg);
266 +static int highlightCTLineMS(WindowInfo *window, DataValue *argList, int nArgs,
267 + DataValue *result, char **errMsg);
269 static int listDialogMS(WindowInfo *window, DataValue *argList, int nArgs,
270 DataValue *result, char **errMsg);
271 static void listDialogBtnCB(Widget w, XtPointer clientData,
273 @@ -446,10 +448,11 @@ static const BuiltInSubrName MacroSubrs[
274 { "getenv", getenvMS },
275 { "string_compare", stringCompareMS },
276 { "split", splitMS },
277 { "calltip", calltipMS },
278 { "kill_calltip", killCalltipMS },
279 + { "highlight_calltip_line", highlightCTLineMS },
281 { "set_backlight_string", setBacklightStringMS },
283 { "rangeset_create", rangesetCreateMS },
284 { "rangeset_destroy", rangesetDestroyMS },
285 @@ -3446,10 +3449,61 @@ static int killCalltipMS(WindowInfo *win
286 result->tag = NO_TAG;
291 +** highlight_calltip_line(ctID, line)
293 +static int highlightCTLineMS(WindowInfo *window, DataValue *argList, int nArgs,
294 + DataValue *result, char **errMsg)
298 + int highlightResult;
301 + *errMsg = "%s() called with wrong number of arguments";
305 + if (!readIntArg(argList[0], &calltipID, errMsg)) {
306 + *errMsg = "%s(): Could not read calltip ID from argument 1";
310 + /* The macro function calltip() uses 0 to report an error. Catch sloppy
311 + programmers who just feed this value into this function. */
312 + if (0 == calltipID) {
313 + *errMsg = "%s(): Invalid calltip ID 0";
317 + if (!readIntArg(argList[1], &line, errMsg) || line < 0) {
318 + *errMsg = "%s(): Could not read line number from argument 2";
322 + result->tag = NO_TAG;
324 + highlightResult = HighlightCalltipLine(window, calltipID, (unsigned)line);
326 + if (CT_INVALID_ID == highlightResult) {
327 + /* Fail only if the calltip ID given is invalid. */
328 + *errMsg = "%s(): Invalid calltip ID";
332 + /* In case NEdit ever gets a warning (!= error) mechanism. *//*
333 + if (CT_NOLINE == highlightResult) {
334 + *warnMsg = "%s(): Calltip line out of range";
342 * A subroutine to get the ID of the current calltip, or 0 if there is none.
344 static int calltipIDMV(WindowInfo *window, DataValue *argList,
345 int nArgs, DataValue *result, char **errMsg)