CVS rebase
[nedit-bw.git] / HairlineMargin9.diff
blobfc9407211a8bb4126d737aefff4909fad72e9bda
1 Add a visual hairline to show any fixed wrap margin
3 This patch is based on
4 http://www.vranx.de/nedit/hairline.2004-07-13.1.diff.gz
6 ---
8 doc/help.etx | 8 ++
9 source/menu.c | 16 ++++
10 source/nedit.h | 6 +
11 source/preferences.c | 128 ++++++++++++++++++++++++++++++++--
12 source/preferences.h | 2
13 source/text.c | 12 ++-
14 source/text.h | 4 +
15 source/textDisp.c | 188 ++++++++++++++++++++++++++++++++++++++++++++-------
16 source/textDisp.h | 9 +-
17 source/textP.h | 2
18 source/window.c | 63 +++++++++++++++--
19 source/window.h | 3
20 12 files changed, 398 insertions(+), 43 deletions(-)
22 diff --quilt old/doc/help.etx new/doc/help.etx
23 --- old/doc/help.etx
24 +++ new/doc/help.etx
25 @@ -3835,10 +3835,18 @@ Preferences
26 **Wrap Margin**
27 Set margin for Auto Newline Wrap, Continuous Wrap, and Fill Paragraph. Lines
28 may, be wrapped at the right margin of the window, or the margin can be set
29 at a specific column.
31 +**Show Wrap Margin**
32 + Visually indicate which column is set as the wrap margin by drawing a vertical
33 + line. Choose between never, always and when wrap is enabled. "Never" turns
34 + this feature off. "Always" will show the wrap margin irrespecitive of the
35 + wrapping style. "When Wrap is Enabled" will show the wrap margin only if
36 + continuous or auto-newline wrap styles is choosen and does not show the wrap
37 + margin if wrapping is turned off.
39 **Tab Stops**
40 Set the tab distance (number of characters between tab stops) for tab
41 characters, and control tab emulation and use of tab characters in padding
42 and emulated tabs.
44 diff --quilt old/source/menu.c new/source/menu.c
45 --- old/source/menu.c
46 +++ new/source/menu.c
47 @@ -394,10 +394,12 @@ static void setAutoIndentAP(Widget w, XE
48 Cardinal *nArgs);
49 static void setWrapTextAP(Widget w, XEvent *event, String *args,
50 Cardinal *nArgs);
51 static void setWrapMarginAP(Widget w, XEvent *event, String *args,
52 Cardinal *nArgs);
53 +static void setShowWrapMarginAP(Widget w, XEvent *event, String *args,
54 + Cardinal *nArgs);
55 static void setHighlightSyntaxAP(Widget w, XEvent *event, String *args,
56 Cardinal *nArgs);
57 static void setMakeBackupCopyAP(Widget w, XEvent *event, String *args,
58 Cardinal *nArgs);
59 static void setIncrementalBackupAP(Widget w, XEvent *event, String *args,
60 @@ -568,10 +570,11 @@ static XtActionsRec Actions[] = {
61 {"set_incremental_search_line", setIncrementalSearchLineAP},
62 {"set_show_line_numbers", setShowLineNumbersAP},
63 {"set_auto_indent", setAutoIndentAP},
64 {"set_wrap_text", setWrapTextAP},
65 {"set_wrap_margin", setWrapMarginAP},
66 + {"set_show_wrap_margin", setShowWrapMarginAP},
67 {"set_highlight_syntax", setHighlightSyntaxAP},
68 #ifndef VMS
69 {"set_make_backup_copy", setMakeBackupCopyAP},
70 #endif
71 {"set_incremental_backup", setIncrementalBackupAP},
72 @@ -4111,10 +4114,23 @@ static void setWrapMarginAP(Widget w, XE
73 else {
74 fprintf(stderr, "nedit: set_wrap_margin requires argument\n");
78 +static void setShowWrapMarginAP(Widget w, XEvent *event, String *args,
79 + Cardinal *nArgs)
81 + WindowInfo *window = WidgetToWindow(w);
82 + int showWrapMargin = 0;
84 + if (*nArgs > 0) {
85 + if (sscanf(args[0], "%d", &showWrapMargin) == 1) {
86 + SetShowWrapMargin(window, showWrapMargin);
87 + }
88 + }
91 static void setHighlightSyntaxAP(Widget w, XEvent *event, String *args,
92 Cardinal *nArgs)
94 WindowInfo *window = WidgetToWindow(w);
95 Boolean newState;
96 diff --quilt old/source/nedit.h new/source/nedit.h
97 --- old/source/nedit.h
98 +++ new/source/nedit.h
99 @@ -55,10 +55,11 @@
100 #define NEDIT_DEFAULT_LINENO_FG "black"
101 #define NEDIT_DEFAULT_CURSOR_FG "black"
102 #define NEDIT_DEFAULT_HELP_FG "black"
103 #define NEDIT_DEFAULT_HELP_BG "rgb:cc/cc/cc"
104 #define NEDIT_DEFAULT_CURSORLINE_BG "LightSkyBlue"
105 +#define NEDIT_DEFAULT_WRAPMARGIN_FG "black"
107 /* Tuning parameters */
108 #define SEARCHMAX 5119 /* Maximum length of search/replace strings */
109 #define MAX_SEARCH_HISTORY 100 /* Maximum length of search string history */
110 #define MAX_PANES 6 /* Max # of ADDITIONAL text editing panes
111 @@ -103,10 +104,12 @@
112 enum indentStyle {NO_AUTO_INDENT, AUTO_INDENT, SMART_INDENT};
113 enum wrapStyle {NO_WRAP, NEWLINE_WRAP, CONTINUOUS_WRAP};
114 enum showMatchingStyle {NO_FLASH, FLASH_DELIMIT, FLASH_RANGE};
115 enum virtKeyOverride { VIRT_KEY_OVERRIDE_NEVER, VIRT_KEY_OVERRIDE_AUTO,
116 VIRT_KEY_OVERRIDE_ALWAYS };
117 +enum showWrapMarginEnums {SHOW_WRAP_MARGIN_NEVER, SHOW_WRAP_MARGIN_ALWAYS,
118 + SHOW_WRAP_MARGIN_ON_WRAP, N_SHOW_WRAP_MARGIN_STYLES};
120 /* This enum must be kept in parallel to the array TruncSubstitutionModes[]
121 in preferences.c */
122 enum truncSubstitution {TRUNCSUBST_SILENT, TRUNCSUBST_FAIL, TRUNCSUBST_WARN, TRUNCSUBST_IGNORE};
124 @@ -192,10 +195,11 @@ enum colorTypes {
125 HILITE_FG_COLOR,
126 HILITE_BG_COLOR,
127 LINENO_FG_COLOR,
128 CURSOR_FG_COLOR,
129 CURSORLINE_BG_COLOR,
130 + WRAPMARGIN_FG_COLOR,
131 NUM_COLORS
134 /* cache user menus: manage mode of user menu list element */
135 typedef enum {
136 @@ -497,10 +501,12 @@ typedef struct _WindowInfo {
137 Boolean autoSave; /* is autosave turned on? */
138 Boolean saveOldVersion; /* keep old version in filename.bck */
139 char indentStyle; /* whether/how to auto indent */
140 char wrapMode; /* line wrap style: NO_WRAP,
141 NEWLINE_WRAP or CONTINUOUS_WRAP */
142 + int showWrapMargin; /* show wrap margin style: NEVER,
143 + ALWAYS, ON-WRAP as enums */
144 Boolean overstrike; /* is overstrike mode turned on ? */
145 char showMatchingStyle; /* How to show matching parens:
146 NO_FLASH, FLASH_DELIMIT, or
147 FLASH_RANGE */
148 char matchSyntaxBased; /* Use syntax info to show matching */
149 diff --quilt old/source/preferences.c new/source/preferences.c
150 --- old/source/preferences.c
151 +++ new/source/preferences.c
152 @@ -138,10 +138,13 @@ static char *AutoWrapTypes[N_WRAP_STYLES
153 static char *AutoIndentTypes[N_INDENT_STYLES+3] = {"None", "Auto",
154 "Smart", "True", "False", NULL};
155 #define N_VIRTKEY_OVERRIDE_MODES 3
156 static char *VirtKeyOverrideModes[N_VIRTKEY_OVERRIDE_MODES+1] = { "Never",
157 "Auto", "Always", NULL};
158 +#define N_SHOW_WRAP_MARGIN_STYLES 3
159 +static char *ShowWrapMarginStrings[N_SHOW_WRAP_MARGIN_STYLES+1] = { "Never",
160 + "Always", "When Wrap is Enabled", NULL};
162 #define N_SHOW_MATCHING_STYLES 3
163 /* For backward compatibility, "False" and "True" are still accepted.
164 They are internally converted to "Off" and "Delimiter" respectively.
165 NOTE: N_SHOW_MATCHING_STYLES must correspond to the number of
166 @@ -235,18 +238,21 @@ typedef struct {
167 Widget lineNoFgErrW;
168 Widget cursorFgW;
169 Widget cursorFgErrW;
170 Widget cursorlineBgW;
171 Widget cursorlineBgErrW;
172 + Widget wrapMarginFgW;
173 + Widget wrapMarginFgErrW;
174 WindowInfo *window;
175 } colorDialog;
177 /* Repository for simple preferences settings */
178 static struct prefData {
179 int openInTab; /* open files in new tabs */
180 int wrapStyle; /* what kind of wrapping to do */
181 int wrapMargin; /* 0=wrap at window width, other=wrap margin */
182 + int showWrapMargin; /* whether to draw line at wrap margin */
183 int autoIndent; /* style for auto-indent */
184 int autoSave; /* whether automatic backup feature is on */
185 int saveOldVersion; /* whether to preserve a copy of last version */
186 int searchDlogs; /* whether to show explanatory search dialogs */
187 int searchWrapBeep; /* 1=beep when search restarts at begin/end */
188 @@ -848,10 +854,12 @@ static PrefDescripRec PrefDescrip[] = {
189 "Default", &TempStringPrefs.smartIndentCommon, NULL, True},
190 {"autoWrap", "AutoWrap", PREF_ENUM, "Continuous",
191 &PrefData.wrapStyle, AutoWrapTypes, True},
192 {"wrapMargin", "WrapMargin", PREF_INT, "0",
193 &PrefData.wrapMargin, NULL, True},
194 + {"showWrapMargin", "ShowWrapMargin", PREF_ENUM, "Never",
195 + &PrefData.showWrapMargin, ShowWrapMarginStrings, True},
196 {"autoIndent", "AutoIndent", PREF_ENUM, "Auto",
197 &PrefData.autoIndent, AutoIndentTypes, True},
198 {"autoSave", "AutoSave", PREF_BOOLEAN, "True",
199 &PrefData.autoSave, NULL, True},
200 {"openInTab", "OpenInTab", PREF_BOOLEAN, "True",
201 @@ -1030,10 +1038,13 @@ static PrefDescripRec PrefDescrip[] = {
202 PrefData.colorNames[CURSORLINE_BG_COLOR],
203 (void *)sizeof(PrefData.colorNames[CURSORLINE_BG_COLOR]), True},
204 {"tooltipBgColor", "TooltipBgColor", PREF_STRING, "LemonChiffon1",
205 PrefData.tooltipBgColor,
206 (void *)sizeof(PrefData.tooltipBgColor), False},
207 + {"wrapMarginForeground", "WrapMarginForeground", PREF_STRING,
208 + NEDIT_DEFAULT_LINENO_FG, PrefData.colorNames[WRAPMARGIN_FG_COLOR],
209 + (void *)sizeof(PrefData.colorNames[WRAPMARGIN_FG_COLOR]), True},
210 {"shell", "Shell", PREF_STRING, "DEFAULT", PrefData.shell,
211 (void*) sizeof(PrefData.shell), True},
212 {"geometry", "Geometry", PREF_STRING, "",
213 PrefData.geometry, (void *)sizeof(PrefData.geometry), False},
214 {"remapDeleteKey", "RemapDeleteKey", PREF_BOOLEAN, "False",
215 @@ -1133,11 +1144,13 @@ static WindowInfo *TabsDialogForWindow;
216 static Widget TabDistText, EmTabText, EmTabToggle, UseTabsToggle, EmTabLabel;
218 /* Module-global variables for Wrap Margin dialog */
219 static int DoneWithWrapDialog;
220 static WindowInfo *WrapDialogForWindow;
221 -static Widget WrapText, WrapTextLabel, WrapWindowToggle;
222 +static Widget WrapText, WrapTextLabel, WrapWindowToggle, ShowWrapMarginPulldown,
223 + ShowWrapMarginPulldownItems[N_SHOW_WRAP_MARGIN_STYLES],
224 + ShowWrapMarginOptMenu, ShowWrapMarginLabel;
226 /* Module-global variables for shell selection dialog */
227 static int DoneWithShellSelDialog = False;
229 static void translatePrefFormats(int convertOld, int fileVer);
230 @@ -1568,10 +1581,20 @@ void SetPrefWrapMargin(int margin)
231 int GetPrefWrapMargin(void)
233 return PrefData.wrapMargin;
236 +void SetPrefShowWrapMargin(int state)
238 + setIntPref(&PrefData.showWrapMargin, state);
241 +int GetPrefShowWrapMargin(void)
243 + return PrefData.showWrapMargin;
246 void SetPrefSearch(int searchType)
248 setIntPref(&PrefData.searchMethod, searchType);
251 @@ -2696,10 +2719,13 @@ void WrapMarginDialog(Widget parent, Win
253 Widget form, selBox;
254 Arg selBoxArgs[2];
255 XmString s1;
256 int margin;
257 + int showWrapMargin;
258 + int i, n;
259 + Arg args[20];
261 XtSetArg(selBoxArgs[0], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL);
262 XtSetArg(selBoxArgs[1], XmNautoUnmanage, False);
263 selBox = CreatePromptDialog(parent, "wrapMargin", selBoxArgs, 2);
264 XtAddCallback(selBox, XmNokCallback, (XtCallbackProc)wrapOKCB, NULL);
265 @@ -2738,20 +2764,73 @@ void WrapMarginDialog(Widget parent, Win
266 XmNrightWidget, WrapText,
267 XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
268 XmNbottomWidget, WrapText, NULL);
269 XmStringFree(s1);
271 + ShowWrapMarginPulldown = CreatePulldownMenu(form,
272 + "ShowWrapMarginPulldown", NULL, 0);
273 + for(i = 0; i < N_SHOW_WRAP_MARGIN_STYLES; i++) {
274 + s1 = XmStringCreateSimple(ShowWrapMarginStrings[i]);
275 + ShowWrapMarginPulldownItems[i] = XtVaCreateManagedWidget(
276 + "ShowWrapMarginPulldown",
277 + xmPushButtonWidgetClass, ShowWrapMarginPulldown,
278 + XmNlabelString, s1,
279 + XmNmarginHeight, 0,
280 + XmNuserData, (XtPointer)(long)i,
281 + NULL);
282 + XmStringFree(s1);
284 + n = 0;
285 + XtSetArg(args[n], XmNspacing, 0); n++;
286 + XtSetArg(args[n], XmNmarginWidth, 0); n++;
287 + XtSetArg(args[n], XmNtopAttachment, XmATTACH_WIDGET); n++;
288 + XtSetArg(args[n], XmNtopWidget, WrapText); n++;
289 + XtSetArg(args[n], XmNrightAttachment, XmATTACH_FORM); n++;
290 + XtSetArg(args[n], XmNsubMenuId, ShowWrapMarginPulldown); n++;
291 + ShowWrapMarginOptMenu = XmCreateOptionMenu(form,
292 + "ShowWrapMarginOptMenu", args, n);
293 + XtManageChild(ShowWrapMarginOptMenu);
295 + ShowWrapMarginLabel = XtVaCreateManagedWidget("ShowWrapMarginLabel",
296 + xmLabelGadgetClass, form,
297 + XmNlabelString, s1=XmStringCreateSimple("Show Wrap Margin"),
298 + XmNmnemonic, 'S',
299 + XmNuserData, XtParent(ShowWrapMarginOptMenu),
300 + XmNalignment, XmALIGNMENT_END,
301 + XmNtopAttachment, XmATTACH_WIDGET,
302 + XmNtopWidget, WrapText,
303 + XmNleftAttachment, XmATTACH_FORM,
304 + XmNrightAttachment, XmATTACH_WIDGET,
305 + XmNrightWidget, ShowWrapMarginOptMenu,
306 + XmNbottomAttachment, XmATTACH_OPPOSITE_WIDGET,
307 + XmNbottomWidget, ShowWrapMarginOptMenu,
308 + NULL);
309 + XmStringFree(s1);
311 /* Set default value */
312 - if (forWindow == NULL)
313 + if (forWindow == NULL) {
314 margin = GetPrefWrapMargin();
315 - else
316 + showWrapMargin = GetPrefShowWrapMargin();
317 + } else {
318 XtVaGetValues(forWindow->textArea, textNwrapMargin, &margin, NULL);
319 + showWrapMargin = forWindow->showWrapMargin;
322 + if (showWrapMargin > N_SHOW_WRAP_MARGIN_STYLES || showWrapMargin < 0) {
323 + fprintf(stderr, "NEdit: internal error: illegal value for showWrapMargin: %d\n", showWrapMargin);
324 + showWrapMargin = SHOW_WRAP_MARGIN_NEVER;
327 XmToggleButtonSetState(WrapWindowToggle, margin==0, True);
328 + XtVaSetValues(ShowWrapMarginOptMenu, XmNmenuHistory,
329 + ShowWrapMarginPulldownItems[showWrapMargin], NULL);
330 if (margin != 0)
331 SetIntText(WrapText, margin);
332 XtSetSensitive(WrapText, margin!=0);
333 XtSetSensitive(WrapTextLabel, margin!=0);
334 + XtSetSensitive(ShowWrapMarginOptMenu, margin!=0);
335 + XtSetSensitive(ShowWrapMarginLabel, margin!=0);
337 /* Handle mnemonic selection of buttons and focus to dialog */
338 AddDialogMnemonicHandler(form, FALSE);
340 /* put up dialog and wait for user to press ok or cancel */
341 @@ -2770,10 +2849,13 @@ void WrapMarginDialog(Widget parent, Win
343 static void wrapOKCB(Widget w, XtPointer clientData, XtPointer callData)
345 int wrapAtWindow, margin, stat;
346 WindowInfo *window = WrapDialogForWindow;
347 + int showWrapMargin;
348 + Widget showWrapMarginSelectedItem;
349 + XtPointer userData;
351 /* get the values that the user entered and make sure they're ok */
352 wrapAtWindow = XmToggleButtonGetState(WrapWindowToggle);
353 if (wrapAtWindow)
354 margin = 0;
355 @@ -2789,10 +2871,18 @@ static void wrapOKCB(Widget w, XtPointer
356 return;
361 + XtVaGetValues(ShowWrapMarginOptMenu, XmNmenuHistory,
362 + &showWrapMarginSelectedItem, NULL);
363 + XtVaGetValues(showWrapMarginSelectedItem, XmNuserData, &userData, NULL);
364 + showWrapMargin = (int)(long)userData;
365 + if (showWrapMargin > N_SHOW_WRAP_MARGIN_STYLES || showWrapMargin < 0) {
366 + showWrapMargin = SHOW_WRAP_MARGIN_NEVER;
369 #ifdef SGI_CUSTOM
370 /* Ask the user about saving as a default preference */
371 if (WrapDialogForWindow != NULL) {
372 int setDefault;
373 if (!shortPrefToDefault(window->shell, "Wrap Margin Settings",
374 @@ -2800,24 +2890,29 @@ static void wrapOKCB(Widget w, XtPointer
375 DoneWithWrapDialog = True;
376 return;
378 if (setDefault) {
379 SetPrefWrapMargin(margin);
380 + SetPrefShowWrapMargin(showWrapMargin);
381 SaveNEditPrefs(window->shell, GetPrefShortMenus());
384 #endif
386 /* Set the value in either the requested window or default preferences */
387 - if (WrapDialogForWindow == NULL)
388 + if (WrapDialogForWindow == NULL) {
389 SetPrefWrapMargin(margin);
390 - else {
391 + SetPrefShowWrapMargin(showWrapMargin);
392 + } else {
393 char *params[1];
394 char marginStr[25];
395 sprintf(marginStr, "%d", margin);
396 params[0] = marginStr;
397 XtCallActionProc(window->textArea, "set_wrap_margin", NULL, params, 1);
398 + sprintf(marginStr, "%d", showWrapMargin);
399 + params[0] = marginStr;
400 + XtCallActionProc(window->textArea, "set_show_wrap_margin", NULL, params, 1);
402 DoneWithWrapDialog = True;
405 static void wrapCancelCB(Widget w, XtPointer clientData, XtPointer callData)
406 @@ -2829,10 +2924,12 @@ static void wrapWindowCB(Widget w, XtPoi
408 int wrapAtWindow = XmToggleButtonGetState(w);
410 XtSetSensitive(WrapTextLabel, !wrapAtWindow);
411 XtSetSensitive(WrapText, !wrapAtWindow);
412 + XtSetSensitive(ShowWrapMarginOptMenu, !wrapAtWindow);
413 + XtSetSensitive(ShowWrapMarginLabel, !wrapAtWindow);
417 ** Create and show a dialog for selecting the shell
419 @@ -6163,10 +6260,17 @@ static void cursorlineBgModifiedCB(Widge
421 colorDialog *cd = (colorDialog *)clientData;
422 showColorStatus(cd, cd->cursorlineBgW, cd->cursorlineBgErrW);
425 +static void wrapMarginFgModifiedCB(Widget w, XtPointer clientData,
426 + XtPointer callData)
428 + colorDialog *cd = (colorDialog *)clientData;
429 + showColorStatus(cd, cd->wrapMarginFgW, cd->wrapMarginFgErrW);
434 * Helper functions for validating colors
436 static int verifyAllColors(colorDialog *cd)
437 @@ -6178,11 +6282,12 @@ static int verifyAllColors(colorDialog *
438 checkColorStatus(cd, cd->selectBgW) &&
439 checkColorStatus(cd, cd->hiliteFgW) &&
440 checkColorStatus(cd, cd->hiliteBgW) &&
441 checkColorStatus(cd, cd->lineNoFgW) &&
442 checkColorStatus(cd, cd->cursorFgW) &&
443 - checkColorStatus(cd, cd->cursorlineBgW));
444 + checkColorStatus(cd, cd->cursorlineBgW) &&
445 + checkColorStatus(cd, cd->wrapMarginFgW));
448 /* Returns True if the color is valid, False if it's not */
449 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW)
451 @@ -6218,16 +6323,17 @@ static void updateColors(colorDialog *cd
452 *selectBg = XmTextGetString(cd->selectBgW),
453 *hiliteFg = XmTextGetString(cd->hiliteFgW),
454 *hiliteBg = XmTextGetString(cd->hiliteBgW),
455 *lineNoFg = XmTextGetString(cd->lineNoFgW),
456 *cursorFg = XmTextGetString(cd->cursorFgW),
457 - *cursorlineBg = XmTextGetString(cd->cursorlineBgW);
458 + *cursorlineBg = XmTextGetString(cd->cursorlineBgW),
459 + *wrapMarginFg = XmTextGetString(cd->wrapMarginFgW);
461 for (window = WindowList; window != NULL; window = window->next)
463 SetColors(window, textFg, textBg, selectFg, selectBg, hiliteFg,
464 - hiliteBg, lineNoFg, cursorFg, cursorlineBg);
465 + hiliteBg, lineNoFg, cursorFg, cursorlineBg, wrapMarginFg);
468 SetPrefColorName(TEXT_FG_COLOR , textFg );
469 SetPrefColorName(TEXT_BG_COLOR , textBg );
470 SetPrefColorName(SELECT_FG_COLOR, selectFg);
471 @@ -6235,20 +6341,22 @@ static void updateColors(colorDialog *cd
472 SetPrefColorName(HILITE_FG_COLOR, hiliteFg);
473 SetPrefColorName(HILITE_BG_COLOR, hiliteBg);
474 SetPrefColorName(LINENO_FG_COLOR, lineNoFg);
475 SetPrefColorName(CURSOR_FG_COLOR, cursorFg);
476 SetPrefColorName(CURSORLINE_BG_COLOR, cursorlineBg);
477 + SetPrefColorName(WRAPMARGIN_FG_COLOR, wrapMarginFg);
479 XtFree(textFg);
480 XtFree(textBg);
481 XtFree(selectFg);
482 XtFree(selectBg);
483 XtFree(hiliteFg);
484 XtFree(hiliteBg);
485 XtFree(lineNoFg);
486 XtFree(cursorFg);
487 XtFree(cursorlineBg);
488 + XtFree(wrapMarginFg);
493 * Dialog button callbacks
494 @@ -6427,10 +6535,13 @@ void ChooseColors(WindowInfo *window)
495 &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
496 hiliteBgModifiedCB, cd );
497 tmpW = addColorGroup( form, "cursorlineBg", 'r', "Cursorline Highlighting",
498 &(cd->cursorlineBgW), &(cd->cursorlineBgErrW), tmpW, 51, 99,
499 cursorlineBgModifiedCB, cd );
500 + tmpW = addColorGroup( form, "wrapMarginFg", 'w', "Wrap Margin Color",
501 + &(cd->wrapMarginFgW), &(cd->wrapMarginFgErrW), tmpW, 51, 99,
502 + wrapMarginFgModifiedCB, cd );
504 /* The left column (foregrounds) of color entry groups */
505 tmpW = addColorGroup( form, "textFg", 'P', "Plain Text Foreground",
506 &(cd->textFgW), &(cd->textFgErrW), topW, 1, 49,
507 textFgModifiedCB, cd );
508 @@ -6526,10 +6637,11 @@ void ChooseColors(WindowInfo *window)
509 XmTextSetString(cd->hiliteFgW, GetPrefColorName(HILITE_FG_COLOR));
510 XmTextSetString(cd->hiliteBgW, GetPrefColorName(HILITE_BG_COLOR));
511 XmTextSetString(cd->lineNoFgW, GetPrefColorName(LINENO_FG_COLOR));
512 XmTextSetString(cd->cursorFgW, GetPrefColorName(CURSOR_FG_COLOR));
513 XmTextSetString(cd->cursorlineBgW, GetPrefColorName(CURSORLINE_BG_COLOR));
514 + XmTextSetString(cd->wrapMarginFgW, GetPrefColorName(WRAPMARGIN_FG_COLOR));
516 /* Handle mnemonic selection of buttons and focus to dialog */
517 AddDialogMnemonicHandler(form, FALSE);
519 /* put up dialog */
520 diff --quilt old/source/preferences.h new/source/preferences.h
521 --- old/source/preferences.h
522 +++ new/source/preferences.h
523 @@ -57,10 +57,12 @@ void MarkPrefsChanged(void);
524 int CheckPrefsChangesSaved(Widget dialogParent);
525 void SetPrefWrap(int state);
526 int GetPrefWrap(int langMode);
527 void SetPrefWrapMargin(int margin);
528 int GetPrefWrapMargin(void);
529 +void SetPrefShowWrapMargin(int state);
530 +int GetPrefShowWrapMargin(void);
531 void SetPrefSearchDlogs(int state);
532 int GetPrefSearchDlogs(void);
533 void SetPrefKeepSearchDlogs(int state);
534 int GetPrefKeepSearchDlogs(void);
535 void SetPrefSearchWraps(int state);
536 diff --quilt old/source/text.c new/source/text.c
537 --- old/source/text.c
538 +++ new/source/text.c
539 @@ -644,10 +644,13 @@ static XtResource resources[] = {
540 XtOffset(TextWidget, text.calltipBGPixel), XmRString,
541 NEDIT_DEFAULT_CALLTIP_BG},
542 {textNcursorlineBackground, textCCursorlineBackground, XmRPixel,sizeof(Pixel),
543 XtOffset(TextWidget, text.cursorlineBGPixel), XmRString,
544 NEDIT_DEFAULT_CURSORLINE_BG},
545 + {textNwrapMarginForeground, textCWrapMarginForeground, XmRPixel,sizeof(Pixel),
546 + XtOffset(TextWidget, text.wrapMarginFGPixel), XmRString,
547 + NEDIT_DEFAULT_WRAPMARGIN_FG},
548 {textNbacklightCharTypes,textCBacklightCharTypes,XmRString,sizeof(XmString),
549 XtOffset(TextWidget, text.backlightCharTypes), XmRString, NULL},
550 {textNrows, textCRows, XmRInt,sizeof(int),
551 XtOffset(TextWidget, text.rows), XmRString, "24"},
552 {textNcolumns, textCColumns, XmRInt, sizeof(int),
553 @@ -674,10 +677,12 @@ static XtResource resources[] = {
554 XtOffset(TextWidget, text.readOnly), XmRString, "False"},
555 {textNhidePointer, textCHidePointer, XmRBoolean, sizeof(Boolean),
556 XtOffset(TextWidget, text.hidePointer), XmRString, "False"},
557 {textNwrapMargin, textCWrapMargin, XmRInt, sizeof(int),
558 XtOffset(TextWidget, text.wrapMargin), XmRString, "0"},
559 + {textNshowWrapMargin, textCShowWrapMargin, XmRBoolean, sizeof(Boolean),
560 + XtOffset(TextWidget, text.showWrapMargin), XmRString, "True"},
561 {textNhScrollBar, textCHScrollBar, XmRWidget, sizeof(Widget),
562 XtOffset(TextWidget, text.hScrollBar), XmRString, ""},
563 {textNvScrollBar, textCVScrollBar, XmRWidget, sizeof(Widget),
564 XtOffset(TextWidget, text.vScrollBar), XmRString, ""},
565 {textNlineNumCols, textCLineNumCols, XmRInt, sizeof(int),
566 @@ -829,11 +834,12 @@ static void initialize(TextWidget reques
567 new->text.highlightBGPixel, new->text.cursorFGPixel,
568 new->text.lineNumFGPixel,
569 new->text.continuousWrap, new->text.wrapMargin,
570 new->text.backlightCharTypes, new->text.calltipFGPixel,
571 new->text.calltipBGPixel,
572 - new->text.cursorlineBGPixel, new->text.showCursorline);
573 + new->text.cursorlineBGPixel, new->text.showCursorline,
574 + new->text.wrapMarginFGPixel, new->text.showWrapMargin);
576 /* Add mandatory delimiters blank, tab, and newline to the list of
577 delimiters. The memory use scheme here is that new values are
578 always copied, and can therefore be safely freed on subsequent
579 set-values calls or destroy */
580 @@ -1135,10 +1141,14 @@ static Boolean setValues(TextWidget curr
581 current->text.textD->showCursorline = new->text.showCursorline;
583 TextDSetShowCursorline(current->text.textD, new->text.showCursorline);
586 + if (new->text.showWrapMargin != current->text.showWrapMargin) {
587 + TextDSetShowWrapMargin(current->text.textD, new->text.showWrapMargin);
590 /* When delimiters are changed, copy the memory, so that the caller
591 doesn't have to manage it, and add mandatory delimiters blank,
592 tab, and newline to the list */
593 if (new->text.delimiters != current->text.delimiters) {
594 char *delimiters = XtMalloc(strlen(new->text.delimiters) + 4);
595 diff --quilt old/source/textDisp.c new/source/textDisp.c
596 --- old/source/textDisp.c
597 +++ new/source/textDisp.c
598 @@ -153,11 +153,11 @@ static int measureVisLine(textDisp *text
599 static int emptyLinesVisible(textDisp *textD);
600 static void blankCursorProtrusions(textDisp *textD);
601 static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct,
602 Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
603 Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel,
604 - Pixel cursorlineBGPixel);
605 + Pixel cursorlineBGPixel, Pixel wrapMarginFGPixel);
606 static GC allocateGC(Widget w, unsigned long valueMask,
607 unsigned long foreground, unsigned long background, Font font,
608 unsigned long dynamicMask, unsigned long dontCareMask);
609 static void releaseGC(Widget w, GC gc);
610 static void resetClipRectangles(textDisp *textD);
611 @@ -183,20 +183,23 @@ static void resetAbsLineNum(textDisp *te
612 static int measurePropChar(const textDisp* textD, const char c,
613 const int colNum, const int pos);
614 static Pixel allocBGColor(Widget w, char *colorName, int *ok);
615 static Pixel getRangesetColor(textDisp *textD, int ind, Pixel bground);
616 static void textDRedisplayRange(textDisp *textD, int start, int end);
617 +static void drawWrapMargin(textDisp *textD);
618 +static void redisplayCursor(textDisp *textD);
620 textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar,
621 Position left, Position top, Position width, Position height,
622 Position lineNumLeft, Position lineNumWidth, textBuffer *buffer,
623 XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel,
624 Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel,
625 Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel,
626 int continuousWrap, int wrapMargin, XmString bgClassString,
627 Pixel calltipFGPixel, Pixel calltipBGPixel,
628 - Pixel cursorlineBGPixel, Boolean showCursorline)
629 + Pixel cursorlineBGPixel, Boolean showCursorline,
630 + Pixel wrapMarginFGPixel, Boolean showWrapMargin)
632 textDisp *textD;
633 XGCValues gcValues;
634 int i;
636 @@ -239,15 +242,17 @@ textDisp *TextDCreate(Widget widget, Wid
637 textD->selectBGPixel = selectBGPixel;
638 textD->highlightBGPixel = highlightBGPixel;
639 textD->lineNumFGPixel = lineNumFGPixel;
640 textD->cursorFGPixel = cursorFGPixel;
641 textD->cursorlineBGPixel = cursorlineBGPixel;
642 + textD->wrapMarginFGPixel = wrapMarginFGPixel;
643 textD->wrapMargin = wrapMargin;
644 textD->continuousWrap = continuousWrap;
645 + textD->showWrapMargin = showWrapMargin;
646 allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
647 selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel,
648 - cursorlineBGPixel);
649 + cursorlineBGPixel, wrapMarginFGPixel);
650 textD->styleGC = allocateGC(textD->w, 0, 0, 0, fontStruct->fid,
651 GCClipMask|GCForeground|GCBackground, GCArcMode);
652 textD->lineNumLeft = lineNumLeft;
653 textD->lineNumWidth = lineNumWidth;
654 textD->nVisibleLines = (height - 1) / (textD->ascent + textD->descent) + 1;
655 @@ -330,10 +335,11 @@ void TextDFree(textDisp *textD)
656 releaseGC(textD->w, textD->highlightBGGC);
657 releaseGC(textD->w, textD->styleGC);
658 releaseGC(textD->w, textD->lineNumGC);
659 releaseGC(textD->w, textD->cursorlineGC);
660 releaseGC(textD->w, textD->cursorlineBGGC);
661 + releaseGC(textD->w, textD->wrapMarginGC);
662 XtFree((char *)textD->lineStarts);
663 while (TextDPopGraphicExposeQueueEntry(textD)) {
665 XtFree((char *)textD->bgClassPixel);
666 XtFree((char *)textD->bgClass);
667 @@ -395,11 +401,11 @@ void TextDAttachHighlightData(textDisp *
669 /* Change the (non syntax-highlit) colors */
670 void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP,
671 Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP,
672 Pixel lineNoFgP, Pixel cursorFgP,
673 - Pixel cursorlineBgP)
674 + Pixel cursorlineBgP, Pixel wrapMarginFgP)
676 XGCValues values;
677 Display *d = XtDisplay(textD->w);
679 /* Update the stored pixels */
680 @@ -410,22 +416,24 @@ void TextDSetColors(textDisp *textD, Pix
681 textD->highlightFGPixel = hiliteFgP;
682 textD->highlightBGPixel = hiliteBgP;
683 textD->lineNumFGPixel = lineNoFgP;
684 textD->cursorFGPixel = cursorFgP;
685 textD->cursorlineBGPixel = cursorlineBgP;
686 + textD->wrapMarginFGPixel = wrapMarginFgP;
688 releaseGC(textD->w, textD->gc);
689 releaseGC(textD->w, textD->selectGC);
690 releaseGC(textD->w, textD->selectBGGC);
691 releaseGC(textD->w, textD->highlightGC);
692 releaseGC(textD->w, textD->highlightBGGC);
693 releaseGC(textD->w, textD->lineNumGC);
694 releaseGC(textD->w, textD->cursorlineGC);
695 releaseGC(textD->w, textD->cursorlineBGGC);
696 + releaseGC(textD->w, textD->wrapMarginGC);
697 allocateFixedFontGCs(textD, textD->fontStruct, textBgP, textFgP, selectFgP,
698 selectBgP, hiliteFgP, hiliteBgP, lineNoFgP,
699 - cursorlineBgP);
700 + cursorlineBgP, wrapMarginFgP);
702 /* Change the cursor GC (the cursor GC is not shared). */
703 values.foreground = cursorFgP;
704 XChangeGC( d, textD->cursorFGGC, GCForeground, &values );
706 @@ -454,10 +462,11 @@ void TextDSetFont(textDisp *textD, XFont
707 int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent;
708 int width, height, fontWidth;
709 Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel;
710 Pixel highlightFGPixel, highlightBGPixel, lineNumFGPixel;
711 Pixel cursorlineBGPixel;
712 + Pixel wrapMarginFGPixel;
713 XGCValues values;
714 XFontStruct *styleFont;
716 /* If font size changes, cursor will be redrawn in a new position */
717 blankCursorProtrusions(textD);
718 @@ -509,23 +518,26 @@ void TextDSetFont(textDisp *textD, XFont
719 highlightBGPixel = values.background;
720 XGetGCValues(display, textD->lineNumGC, GCForeground, &values);
721 lineNumFGPixel = values.foreground;
722 XGetGCValues(display, textD->cursorlineGC,GCForeground|GCBackground,&values);
723 cursorlineBGPixel = values.background;
724 + XGetGCValues(display, textD->wrapMarginGC, GCForeground, &values);
725 + wrapMarginFGPixel = values.foreground;
727 releaseGC(textD->w, textD->gc);
728 releaseGC(textD->w, textD->selectGC);
729 releaseGC(textD->w, textD->highlightGC);
730 releaseGC(textD->w, textD->selectBGGC);
731 releaseGC(textD->w, textD->highlightBGGC);
732 releaseGC(textD->w, textD->lineNumGC);
733 releaseGC(textD->w, textD->cursorlineGC);
734 releaseGC(textD->w, textD->cursorlineBGGC);
735 + releaseGC(textD->w, textD->wrapMarginGC);
737 allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
738 selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel,
739 - cursorlineBGPixel);
740 + cursorlineBGPixel, wrapMarginFGPixel);
741 XSetFont(display, textD->styleGC, fontStruct->fid);
743 /* Do a full resize to force recalculation of font related parameters */
744 width = textD->width;
745 height = textD->height;
746 @@ -679,10 +691,13 @@ void TextDRedisplayRect(textDisp *textD,
747 redisplayLine(textD, line, left, left+width, 0, INT_MAX);
749 /* draw the line numbers if exposed area includes them */
750 if (textD->lineNumWidth != 0 && left <= textD->lineNumLeft + textD->lineNumWidth)
751 redrawLineNumbers(textD, False);
753 + /* draw wrap margin incase it got erased */
754 + drawWrapMargin(textD);
758 ** Refresh all of the text between buffer positions "start" and "end"
759 ** not including the character at the position "end".
760 @@ -750,23 +765,98 @@ static void textDRedisplayRange(textDisp
761 /* If the starting and ending lines are the same, redisplay the single
762 line between "start" and "end".
763 Add one to endIndex to catch the caret at the end of a range. */
764 if (startLine == lastLine) {
765 redisplayLine(textD, startLine, 0, INT_MAX, startIndex, endIndex);
766 - return;
768 + if (-1 != textD->lineStarts[startLine]
769 + || (textD->wrapMargin >= BufCountDispChars(
770 + textD->buffer, textD->lineStarts[startLine], start)
771 + && textD->wrapMargin <= BufCountDispChars(
772 + textD->buffer, textD->lineStarts[startLine], end))) {
773 + /* redraw wrap margin if it got erased */
774 + drawWrapMargin(textD);
776 + } else {
777 + /* Redisplay the first line from "start" */
778 + redisplayLine(textD, startLine, 0, INT_MAX, startIndex, INT_MAX);
780 + /* Redisplay the lines in between at their full width */
781 + for (i = startLine + 1; i < lastLine; i++) {
782 + redisplayLine(textD, i, 0, INT_MAX, 0, INT_MAX);
785 + /* Redisplay the last line to "end". Add one to the endIndex to catch
786 + the caret at the end of a range. */
787 + redisplayLine(textD, lastLine, 0, INT_MAX, 0, endIndex);
789 + /* redraw wrap margin */
790 + drawWrapMargin(textD);
793 - /* Redisplay the first line from "start" */
794 - redisplayLine(textD, startLine, 0, INT_MAX, startIndex, INT_MAX);
796 - /* Redisplay the lines in between at their full width */
797 - for (i=startLine+1; i<lastLine; i++)
798 - redisplayLine(textD, i, 0, INT_MAX, 0, INT_MAX);
800 - /* Redisplay the last line to "end". Add one to the endIndex to catch
801 - the caret at the end of a range. */
802 - redisplayLine(textD, lastLine, 0, INT_MAX, 0, endIndex);
806 +** Custom version of TextDRedisplayRange that only updates the area around
807 +** the cursor.
809 +static void redisplayCursor(textDisp *textD)
811 + int cursorLine, lineStart, start, end, startIndex, endIndex;
812 + int pos = textD->cursorPos;
813 + Boolean cursorLineChanged;
815 + /* If the cursor is outside of the displayed text, just return */
816 + if (pos + 1 < textD->firstChar || pos - 1 > textD->lastChar) {
817 + return;
820 + if (!posToVisibleLineNum(textD, pos, &cursorLine)) {
821 + /* At first sight, this can only be reached when redisplayCursor()
822 + is miscalled or when the catch above didn't work. There is at
823 + least one situation though which makes the catch helpless: If
824 + your caret is in the last line, column 1 and you move it down,
825 + textD->cursorPos will be changed *before* this function is
826 + called, the automatic scroll will be done after. */
827 + return;
830 + /* Find the position right before and after the cursor,
831 + but make sure that we stay on the same line. */
832 + lineStart = TextDStartOfLine(textD, pos);
833 + start = max(lineStart, pos - 1);
834 + end = min(pos + 1, TextDEndOfLine(textD, lineStart, True) + 1);
836 + /* Get the starting and ending positions within the line. */
837 + startIndex = start - lineStart;
838 + endIndex = end - lineStart;
840 + /* Reset the clipping rectangles for the drawing GCs which are shared
841 + using XtAllocateGC, and may have changed since the last use */
842 + resetClipRectangles(textD);
844 + cursorLineChanged = (textD->oldCursorPos != textD->cursorPos
845 + || textD->oldLineStart != lineStart);
847 + redisplayLine(textD, cursorLine, 0, INT_MAX, startIndex, endIndex);
849 + if (cursorLineChanged) {
850 + /* Hairline destroyed in old cursor line! Redraw neccessary. */
851 + drawWrapMargin(textD);
852 + return;
855 + if (BufCountDispChars(textD->buffer, lineStart, end) < textD->wrapMargin) {
856 + /* hairline is off-screen, most common case */
857 + return;
860 + if (BufCountDispChars(textD->buffer, lineStart, start)
861 + > textD->wrapMargin) {
862 + return;
865 + drawWrapMargin(textD);
869 ** Set the scroll position of the text display vertically by line number and
870 ** horizontally by pixel offset from the left margin
871 @@ -822,37 +912,44 @@ void TextDSetInsertPosition(textDisp *te
872 TextDBlankCursor(textD);
874 /* draw it at its new position */
875 textD->cursorPos = newPos;
876 textD->cursorOn = True;
877 - textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
879 + redisplayCursor(textD);
881 + /* We have to force redraw of the hairline here: The hairline will be
882 + erased if the cursorline changes, but will not be redrawn by
883 + redisplayCursor() (only works on the area immedietely surrounding
884 + the cursor). */
885 + drawWrapMargin(textD);
888 void TextDBlankCursor(textDisp *textD)
890 if (!textD->cursorOn)
891 return;
893 blankCursorProtrusions(textD);
894 textD->cursorOn = False;
895 - textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
896 + redisplayCursor(textD);
899 void TextDUnblankCursor(textDisp *textD)
901 if (!textD->cursorOn) {
902 textD->cursorOn = True;
903 - textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
904 + redisplayCursor(textD);
908 void TextDSetCursorStyle(textDisp *textD, int style)
910 textD->cursorStyle = style;
911 blankCursorProtrusions(textD);
912 if (textD->cursorOn) {
913 - textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
914 + redisplayCursor(textD);
918 void TextDSetWrapMode(textDisp *textD, int wrap, int wrapMargin)
920 @@ -884,10 +981,19 @@ void TextDSetWrapMode(textDisp *textD, i
921 /* Do a full redraw */
922 TextDRedisplayRect(textD, 0, textD->top, textD->width + textD->left,
923 textD->height);
926 +void TextDSetShowWrapMargin(textDisp *textD, Boolean state)
928 + textD->showWrapMargin = state;
930 + /* Do a full redraw */
931 + TextDRedisplayRect(textD, 0, textD->top, textD->width + textD->left,
932 + textD->height);
935 int TextDGetInsertPosition(textDisp *textD)
937 return textD->cursorPos;
940 @@ -2880,11 +2986,11 @@ static void setScroll(textDisp *textD, i
941 else if (xOffset < 0) {
942 TextDRedisplayRect(textD, textD->left + textD->width + xOffset,
943 textD->top, -xOffset, textD->height);
945 /* Restore protruding parts of the cursor */
946 - textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
947 + redisplayCursor(textD);
950 /* Refresh line number/calltip display if its up and we've scrolled
951 vertically */
952 if (lineDelta != 0) {
953 @@ -3168,11 +3274,11 @@ static void blankCursorProtrusions(textD
954 ** re-allocated on a font change.
956 static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct,
957 Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
958 Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel,
959 - Pixel cursorlineBGPixel)
960 + Pixel cursorlineBGPixel, Pixel wrapMarginFGPixel)
962 textD->gc = allocateGC(textD->w, GCFont | GCForeground | GCBackground,
963 fgPixel, bgPixel, fontStruct->fid, GCClipMask, GCArcMode);
964 textD->selectGC = allocateGC(textD->w, GCFont | GCForeground | GCBackground,
965 selectFGPixel, selectBGPixel, fontStruct->fid, GCClipMask,
966 @@ -3189,10 +3295,12 @@ static void allocateFixedFontGCs(textDis
967 GCClipMask, GCArcMode);
968 textD->cursorlineGC = allocateGC(textD->w, GCFont|GCForeground|GCBackground,
969 fgPixel, cursorlineBGPixel, fontStruct->fid, GCClipMask, GCArcMode);
970 textD->cursorlineBGGC = allocateGC(textD->w, GCForeground,
971 cursorlineBGPixel, 0, fontStruct->fid, GCClipMask, GCArcMode);
972 + textD->wrapMarginGC = allocateGC(textD->w, GCForeground | GCBackground,
973 + wrapMarginFGPixel, bgPixel, fontStruct->fid, GCClipMask, GCArcMode);
977 ** X11R4 does not have the XtAllocateGC function for sharing graphics contexts
978 ** with changeable fields. Unfortunately the R4 call for creating shared
979 @@ -3265,10 +3373,12 @@ static void resetClipRectangles(textDisp
980 &clipRect, 1, Unsorted);
981 XSetClipRectangles(display, textD->cursorlineGC, 0, 0,
982 &clipRect, 1, Unsorted);
983 XSetClipRectangles(display, textD->cursorlineBGGC, 0, 0,
984 &clipRect, 1, Unsorted);
985 + XSetClipRectangles(display, textD->wrapMarginGC, 0, 0,
986 + &clipRect, 1, Unsorted);
990 ** Return the length of a line (number of displayable characters) by examining
991 ** entries in the line starts array rather than by scanning for newlines
992 @@ -3968,5 +4078,35 @@ void TextDSetupBGClasses(Widget w, XmStr
993 return;
995 memcpy(*pp_bgClass, bgClass, 256);
996 memcpy(*pp_bgClassPixel, bgClassPixel, class_no * sizeof (Pixel));
1000 +** Draw wrap margin if requested
1002 +static void drawWrapMargin(textDisp *textD)
1004 + int fromX, fromY;
1005 + int fontHeight, lineHeight;
1007 + /* attempt to draw the wrap margin # only if
1008 + - widget has been realized
1009 + - font width is not -1, ie. not using different/proportional width fonts
1010 + - show wrap margins is enabled */
1011 + if (XtWindow(textD->w) != 0
1012 + && textD->fixedFontWidth != -1
1013 + && textD->showWrapMargin) {
1014 + fromX = textD->left + (textD->fixedFontWidth * textD->wrapMargin)
1015 + - textD->horizOffset - 1;
1017 + /* compute rest of coordinates if line is to right of left margin */
1018 + if (fromX > textD->left) {
1019 + fromY = textD->top;
1020 + fontHeight = textD->ascent + textD->descent;
1021 + lineHeight = textD->nVisibleLines * fontHeight - 1;
1022 + XDrawLine(XtDisplay(textD->w), XtWindow(textD->w),
1023 + textD->wrapMarginGC, fromX, fromY, fromX,
1024 + fromY + lineHeight);
1028 diff --quilt old/source/textDisp.h new/source/textDisp.h
1029 --- old/source/textDisp.h
1030 +++ new/source/textDisp.h
1031 @@ -101,10 +101,11 @@ typedef struct _textDisp {
1032 either to a newline or one character
1033 beyond the end of the buffer) */
1034 int continuousWrap; /* Wrap long lines when displaying */
1035 int wrapMargin; /* Margin in # of char positions for
1036 wrapping in continuousWrap mode */
1037 + Boolean showWrapMargin; /* draw line at wrap margin */
1038 int *lineStarts;
1039 int topLineNum; /* Line number of top displayed line
1040 of file (first line of file is 1) */
1041 int absTopLineNum; /* In continuous wrap mode, the line
1042 number of the top line if the text
1043 @@ -149,10 +150,12 @@ typedef struct _textDisp {
1044 Widget calltipW; /* The Label widget for the calltip */
1045 Widget calltipShell; /* The Shell that holds the calltip */
1046 calltipStruct calltip; /* The info for the calltip itself */
1047 Pixel calltipFGPixel;
1048 Pixel calltipBGPixel;
1049 + Pixel wrapMarginFGPixel; /* color for drawing wrap margin */
1050 + GC wrapMarginGC; /* GC for drawing wrap margin */
1051 int suppressResync; /* Suppress resynchronization of line
1052 starts during buffer updates */
1053 int nLinesDeleted; /* Number of lines deleted during
1054 buffer modification (only used
1055 when resynchronization is
1056 @@ -173,20 +176,21 @@ textDisp *TextDCreate(Widget widget, Wid
1057 XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel,
1058 Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel,
1059 Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel,
1060 int continuousWrap, int wrapMargin, XmString bgClassString,
1061 Pixel calltipFGPixel, Pixel calltipBGPixel,
1062 - Pixel cursorlineBGPixel, Boolean showCursorline);
1063 + Pixel cursorlineBGPixel, Boolean showCursorline,
1064 + Pixel wrapMarginFGPixel, Boolean showWrapMargin);
1065 void TextDFree(textDisp *textD);
1066 void TextDSetBuffer(textDisp *textD, textBuffer *buffer);
1067 void TextDAttachHighlightData(textDisp *textD, textBuffer *styleBuffer,
1068 styleTableEntry *styleTable, int nStyles, char unfinishedStyle,
1069 unfinishedStyleCBProc unfinishedHighlightCB, void *cbArg);
1070 void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP,
1071 Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP,
1072 Pixel lineNoFgP, Pixel cursorFgP,
1073 - Pixel cursorlineBgP);
1074 + Pixel cursorlineBgP, Pixel wrapMarginFgP);
1075 void TextDSetFont(textDisp *textD, XFontStruct *fontStruct);
1076 int TextDMinFontWidth(textDisp *textD, Boolean considerStyles);
1077 int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles);
1078 void TextDResize(textDisp *textD, int width, int height);
1079 void TextDRedisplayRect(textDisp *textD, int left, int top, int width,
1080 @@ -214,10 +218,11 @@ int TextDMoveUp(textDisp *textD, int abs
1081 int TextDMoveDown(textDisp *textD, int absolute);
1082 void TextDBlankCursor(textDisp *textD);
1083 void TextDUnblankCursor(textDisp *textD);
1084 void TextDSetCursorStyle(textDisp *textD, int style);
1085 void TextDSetWrapMode(textDisp *textD, int wrap, int wrapMargin);
1086 +void TextDSetShowWrapMargin(textDisp *textD, Boolean state);
1087 int TextDEndOfLine(const textDisp* textD, const int pos,
1088 const Boolean startPosIsLineStart);
1089 int TextDStartOfLine(const textDisp* textD, const int pos);
1090 int TextDCountForwardNLines(const textDisp* textD, const int startPos,
1091 const unsigned nLines, const Boolean startPosIsLineStart);
1092 diff --quilt old/source/text.h new/source/text.h
1093 --- old/source/text.h
1094 +++ new/source/text.h
1095 @@ -61,10 +61,12 @@
1096 #define textCcalltipForeground "CalltipForeground"
1097 #define textNcalltipBackground "calltipBackground"
1098 #define textCcalltipBackground "CalltipBackground"
1099 #define textNcursorlineBackground "cursorlineBackground"
1100 #define textCCursorlineBackground "CursorlineBackground"
1101 +#define textNwrapMarginForeground "wrapMarginForeground"
1102 +#define textCWrapMarginForeground "WrapMarginForeground"
1103 #define textNpendingDelete "pendingDelete"
1104 #define textCPendingDelete "PendingDelete"
1105 #define textNhScrollBar "hScrollBar"
1106 #define textCHScrollBar "HScrollBar"
1107 #define textNvScrollBar "vScrollBar"
1108 @@ -95,10 +97,12 @@
1109 #define textCAutoWrap "AutoWrap"
1110 #define textNcontinuousWrap "continuousWrap"
1111 #define textCContinuousWrap "ContinuousWrap"
1112 #define textNwrapMargin "wrapMargin"
1113 #define textCWrapMargin "WrapMargin"
1114 +#define textNshowWrapMargin "showWrapMargin"
1115 +#define textCShowWrapMargin "ShowWrapMargin"
1116 #define textNautoIndent "autoIndent"
1117 #define textCAutoIndent "AutoIndent"
1118 #define textNsmartIndent "smartIndent"
1119 #define textCSmartIndent "SmartIndent"
1120 #define textNoverstrike "overstrike"
1121 diff --quilt old/source/textP.h new/source/textP.h
1122 --- old/source/textP.h
1123 +++ new/source/textP.h
1124 @@ -58,10 +58,11 @@ extern TextClassRec nTextClassRec;
1125 typedef struct _TextPart {
1126 /* resources */
1127 Pixel selectFGPixel, selectBGPixel, highlightFGPixel, highlightBGPixel;
1128 Pixel cursorFGPixel, lineNumFGPixel, calltipFGPixel, calltipBGPixel;
1129 Pixel cursorlineBGPixel;
1130 + Pixel wrapMarginFGPixel;
1131 XFontStruct *fontStruct;
1132 Boolean pendingDelete;
1133 Boolean autoShowInsertPos;
1134 Boolean autoWrap;
1135 Boolean autoWrapPastedText;
1136 @@ -75,10 +76,11 @@ typedef struct _TextPart {
1137 Boolean showCursorline;
1138 int rows, columns;
1139 int marginWidth, marginHeight;
1140 int cursorBlinkRate;
1141 int wrapMargin;
1142 + Boolean showWrapMargin;
1143 int emulateTabs;
1144 int lineNumCols;
1145 char *delimiters;
1146 Cardinal cursorVPadding;
1147 Widget hScrollBar, vScrollBar;
1148 diff --quilt old/source/window.c new/source/window.c
1149 --- old/source/window.c
1150 +++ new/source/window.c
1151 @@ -270,10 +270,11 @@ WindowInfo *CreateWindow(const char *nam
1152 CLEAR_ALL_LOCKS(window->lockReasons);
1153 window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE);
1154 window->autoSave = GetPrefAutoSave();
1155 window->saveOldVersion = GetPrefSaveOldVersion();
1156 window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE);
1157 + window->showWrapMargin = GetPrefShowWrapMargin();
1158 window->overstrike = False;
1159 window->showMatchingStyle = GetPrefShowMatching();
1160 window->matchSyntaxBased = GetPrefMatchSyntaxBased();
1161 window->showStats = GetPrefStatsLine();
1162 window->showISearchLine = GetPrefISearchLine();
1163 @@ -729,11 +730,12 @@ WindowInfo *CreateWindow(const char *nam
1164 GetPrefColorName(SELECT_BG_COLOR),
1165 GetPrefColorName(HILITE_FG_COLOR),
1166 GetPrefColorName(HILITE_BG_COLOR),
1167 GetPrefColorName(LINENO_FG_COLOR),
1168 GetPrefColorName(CURSOR_FG_COLOR),
1169 - GetPrefColorName(CURSORLINE_BG_COLOR));
1170 + GetPrefColorName(CURSORLINE_BG_COLOR),
1171 + GetPrefColorName(WRAPMARGIN_FG_COLOR));
1173 /* Create the right button popup menu (note: order is important here,
1174 since the translation for popping up this menu was probably already
1175 added in createTextArea, but CreateBGMenu requires window->textArea
1176 to be set so it can attach the menu to it (because menu shells are
1177 @@ -1240,11 +1242,12 @@ void SplitPane(WindowInfo *window)
1178 XmNbackground, textD->bgPixel,
1179 NULL);
1180 TextDSetColors( newTextD, textD->fgPixel, textD->bgPixel,
1181 textD->selectFGPixel, textD->selectBGPixel, textD->highlightFGPixel,
1182 textD->highlightBGPixel, textD->lineNumFGPixel,
1183 - textD->cursorFGPixel, textD->cursorlineBGPixel );
1184 + textD->cursorFGPixel, textD->cursorlineBGPixel,
1185 + textD->wrapMarginFGPixel );
1187 /* Set the minimum pane height in the new pane */
1188 UpdateMinPaneHeights(window);
1190 /* adjust the heights, scroll positions, etc., to split the focus pane */
1191 @@ -1881,11 +1884,11 @@ void SetFonts(WindowInfo *window, const
1194 void SetColors(WindowInfo *window, const char *textFg, const char *textBg,
1195 const char *selectFg, const char *selectBg, const char *hiliteFg,
1196 const char *hiliteBg, const char *lineNoFg, const char *cursorFg,
1197 - const char *cursorlineBg)
1198 + const char *cursorlineBg, const char *wrapMarginFg)
1200 int i, dummy;
1201 Pixel textFgPix = AllocColor( window->textArea, textFg,
1202 &dummy, &dummy, &dummy),
1203 textBgPix = AllocColor( window->textArea, textBg,
1204 @@ -1901,10 +1904,12 @@ void SetColors(WindowInfo *window, const
1205 lineNoFgPix = AllocColor( window->textArea, lineNoFg,
1206 &dummy, &dummy, &dummy),
1207 cursorFgPix = AllocColor( window->textArea, cursorFg,
1208 &dummy, &dummy, &dummy),
1209 cursorlineBgPix = AllocColor( window->textArea, cursorlineBg,
1210 + &dummy, &dummy, &dummy),
1211 + wrapMarginFgPix = AllocColor( window->textArea, wrapMarginFg,
1212 &dummy, &dummy, &dummy);
1213 textDisp *textD;
1215 /* Update the main pane */
1216 XtVaSetValues(window->textArea,
1217 @@ -1912,21 +1917,21 @@ void SetColors(WindowInfo *window, const
1218 XmNbackground, textBgPix,
1219 NULL);
1220 textD = ((TextWidget)window->textArea)->text.textD;
1221 TextDSetColors( textD, textFgPix, textBgPix, selectFgPix, selectBgPix,
1222 hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix,
1223 - cursorlineBgPix );
1224 + cursorlineBgPix, wrapMarginFgPix );
1225 /* Update any additional panes */
1226 for (i=0; i<window->nPanes; i++) {
1227 XtVaSetValues(window->textPanes[i],
1228 XmNforeground, textFgPix,
1229 XmNbackground, textBgPix,
1230 NULL);
1231 textD = ((TextWidget)window->textPanes[i])->text.textD;
1232 TextDSetColors( textD, textFgPix, textBgPix, selectFgPix, selectBgPix,
1233 hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix,
1234 - cursorlineBgPix );
1235 + cursorlineBgPix, wrapMarginFgPix );
1238 /* Redo any syntax highlighting */
1239 if (window->highlightData != NULL)
1240 UpdateHighlightStyles(window);
1241 @@ -1963,10 +1968,12 @@ void SetAutoWrap(WindowInfo *window, int
1242 if (IsTopDocument(window)) {
1243 XmToggleButtonSetState(window->newlineWrapItem, autoWrap, False);
1244 XmToggleButtonSetState(window->continuousWrapItem, contWrap, False);
1245 XmToggleButtonSetState(window->noWrapItem, state == NO_WRAP, False);
1248 + SetShowWrapMargin(window, window->showWrapMargin);
1252 ** Set the auto-scroll margin
1254 @@ -1978,10 +1985,40 @@ void SetAutoScroll(WindowInfo *window, i
1255 for (i=0; i<window->nPanes; i++)
1256 XtVaSetValues(window->textPanes[i], textNcursorVPadding, margin, NULL);
1260 +** Set show-wrap-margin style, one of NEVER, ALWAYS, ON-WRAP
1262 +void SetShowWrapMargin(WindowInfo *window, int state)
1264 + int i;
1265 + Boolean alwaysShowWrapMargin = (state == SHOW_WRAP_MARGIN_ALWAYS);
1266 + Boolean onWrapShowWrapMargin = (state == SHOW_WRAP_MARGIN_ON_WRAP);
1267 + Boolean autoWrap = (window->wrapMode == NEWLINE_WRAP);
1268 + Boolean contWrap = (window->wrapMode == CONTINUOUS_WRAP);
1269 + /* true or false only. not never/always/on-wrap. text widget does need to know
1270 + exact details. it just needs to know that wrap margin should be shown */
1271 + Boolean showWrapMargin = (alwaysShowWrapMargin
1272 + || (onWrapShowWrapMargin && autoWrap)
1273 + || (onWrapShowWrapMargin && contWrap));
1275 + XtVaSetValues(window->textArea,
1276 + textNshowWrapMargin, showWrapMargin,
1277 + NULL);
1278 + for (i = 0; i < window->nPanes; i++) {
1279 + XtVaSetValues(window->textPanes[i],
1280 + textNshowWrapMargin, showWrapMargin,
1281 + NULL);
1284 + /* never/always/on-wrap needs to be stored in window settings, for generating
1285 + menu, etc */
1286 + window->showWrapMargin = state;
1290 ** Recover the window pointer from any widget in the window, by searching
1291 ** up the widget hierarcy for the top level container widget where the
1292 ** window pointer is stored in the userData field. In a tabbed window,
1293 ** this is the window pointer of the top (active) document, which is
1294 ** returned if w is 'shell-level' widget - menus, find/replace dialogs, etc.
1295 @@ -2235,10 +2272,19 @@ void MakeSelectionVisible(WindowInfo *wi
1296 static Widget createTextArea(Widget parent, WindowInfo *window, int rows,
1297 int cols, int emTabDist, char *delimiters, int wrapMargin,
1298 int lineNumCols)
1300 Widget text, sw, hScrollBar, vScrollBar, frame;
1301 + int alwaysShowWrapMargin = (window->showWrapMargin == SHOW_WRAP_MARGIN_ALWAYS);
1302 + int onWrapShowWrapMargin = (window->showWrapMargin == SHOW_WRAP_MARGIN_ON_WRAP);
1303 + int autoWrap = (window->wrapMode == NEWLINE_WRAP);
1304 + int contWrap = (window->wrapMode == CONTINUOUS_WRAP);
1305 + /* true or false only. not never/always/on-wrap. text widget does need to know
1306 + exact details. it just needs to know that wrap margin should be shown */
1307 + int showWrapMargin = (alwaysShowWrapMargin
1308 + || (onWrapShowWrapMargin && autoWrap)
1309 + || (onWrapShowWrapMargin && contWrap));
1311 /* Create a text widget inside of a scrolled window widget */
1312 sw = XtVaCreateManagedWidget("scrolledW", xmScrolledWindowWidgetClass,
1313 parent, XmNpaneMaximum, SHRT_MAX,
1314 XmNpaneMinimum, PANE_MIN_HEIGHT, XmNhighlightThickness, 0, NULL);
1315 @@ -2258,10 +2304,11 @@ static Widget createTextArea(Widget pare
1316 textNfont, GetDefaultFontStruct(window->fontList),
1317 textNhScrollBar, hScrollBar, textNvScrollBar, vScrollBar,
1318 textNreadOnly, IS_ANY_LOCKED(window->lockReasons),
1319 textNwordDelimiters, delimiters,
1320 textNwrapMargin, wrapMargin,
1321 + textNshowWrapMargin, showWrapMargin,
1322 textNautoIndent, window->indentStyle == AUTO_INDENT,
1323 textNsmartIndent, window->indentStyle == SMART_INDENT,
1324 textNautoWrap, window->wrapMode == NEWLINE_WRAP,
1325 textNcontinuousWrap, window->wrapMode == CONTINUOUS_WRAP,
1326 textNoverstrike, window->overstrike,
1327 @@ -3367,10 +3414,11 @@ WindowInfo* CreateDocument(WindowInfo* s
1328 CLEAR_ALL_LOCKS(window->lockReasons);
1329 window->indentStyle = GetPrefAutoIndent(PLAIN_LANGUAGE_MODE);
1330 window->autoSave = GetPrefAutoSave();
1331 window->saveOldVersion = GetPrefSaveOldVersion();
1332 window->wrapMode = GetPrefWrap(PLAIN_LANGUAGE_MODE);
1333 + window->showWrapMargin = GetPrefShowWrapMargin();
1334 window->overstrike = False;
1335 window->showMatchingStyle = GetPrefShowMatching();
1336 window->matchSyntaxBased = GetPrefMatchSyntaxBased();
1337 window->highlightSyntax = GetPrefHighlightSyntax();
1338 window->backlightCharTypes = NULL;
1339 @@ -3472,11 +3520,12 @@ WindowInfo* CreateDocument(WindowInfo* s
1340 GetPrefColorName(SELECT_BG_COLOR),
1341 GetPrefColorName(HILITE_FG_COLOR),
1342 GetPrefColorName(HILITE_BG_COLOR),
1343 GetPrefColorName(LINENO_FG_COLOR),
1344 GetPrefColorName(CURSOR_FG_COLOR),
1345 - GetPrefColorName(CURSORLINE_BG_COLOR));
1346 + GetPrefColorName(CURSORLINE_BG_COLOR),
1347 + GetPrefColorName(WRAPMARGIN_FG_COLOR));
1349 /* Create the right button popup menu (note: order is important here,
1350 since the translation for popping up this menu was probably already
1351 added in createTextArea, but CreateBGMenu requires window->textArea
1352 to be set so it can attach the menu to it (because menu shells are
1353 @@ -4262,11 +4311,11 @@ static void cloneTextPanes(WindowInfo *w
1354 XmNbackground, textD->bgPixel, NULL);
1355 TextDSetColors(newTextD, textD->fgPixel, textD->bgPixel,
1356 textD->selectFGPixel, textD->selectBGPixel,
1357 textD->highlightFGPixel,textD->highlightBGPixel,
1358 textD->lineNumFGPixel, textD->cursorFGPixel,
1359 - textD->cursorlineBGPixel);
1360 + textD->cursorlineBGPixel, textD->wrapMarginFGPixel);
1363 /* Set the minimum pane height in the new pane */
1364 UpdateMinPaneHeights(window);
1366 diff --quilt old/source/window.h new/source/window.h
1367 --- old/source/window.h
1368 +++ new/source/window.h
1369 @@ -52,11 +52,11 @@ void SetShowMatching(WindowInfo *window,
1370 void SetFonts(WindowInfo *window, const char *fontName, const char *italicName,
1371 const char *boldName, const char *boldItalicName);
1372 void SetColors(WindowInfo *window, const char *textFg, const char *textBg,
1373 const char *selectFg, const char *selectBg, const char *hiliteFg,
1374 const char *hiliteBg, const char *lineNoFg, const char *cursorFg,
1375 - const char *cursorlineBg);
1376 + const char *cursorlineBg, const char *wrapMarginFg);
1377 void SetOverstrike(WindowInfo *window, int overstrike);
1378 void SetAutoWrap(WindowInfo *window, int state);
1379 void SetAutoScroll(WindowInfo *window, int margin);
1380 void SplitPane(WindowInfo *window);
1381 Widget GetPaneByIndex(WindowInfo *window, int paneIndex);
1382 @@ -104,6 +104,7 @@ void SetBacklightChars(WindowInfo *windo
1383 void SetToggleButtonState(WindowInfo *window, Widget w, Boolean state,
1384 Boolean notify);
1385 void SetSensitive(WindowInfo *window, Widget w, Boolean sensitive);
1386 void CleanUpTabBarExposeQueue(WindowInfo *window);
1387 void ChangeLastFocus(WindowInfo *window, Widget text);
1388 +void SetShowWrapMargin(WindowInfo *window, int state);
1389 #endif /* NEDIT_WINDOW_H_INCLUDED */