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