CVS rebase
[nedit-bw.git] / CursorLine6.diff
blob8bf5d601532343cb8687e50caed476d1a630d759
1 [INACTIVE] Highlighted Cursorline
3 This is Thorsten Haude's patch, modified from Fredrik Corneliusson's patch
4 to provide a background color for the current line. You can find it here:
6 http://sourceforge.net/tracker/index.php?func=detail&aid=683567&group_id=11005&atid=311005
7 [ 683567 ] Highlighted Cursorline
8 cursorline.ajbj.2004-03-28.1.diff 2004-03-28 05:52
10 This coloring takes precedence over rangesets, syntax highlighting
11 backgrounds (if specified) and backlighting, but not over parenthesis match
12 highlighting nor selection.
14 It still requires work, for example for turning the cursorline highlighting
15 on and off through the GUI and through macros.
17 Thorsten has taken over this patch, integrating it with other functionality.
18 Check the patch page:
20 http://sourceforge.net/tracker/index.php?func=detail&aid=1058246&group_id=11005&atid=311005
21 [ 1058246 ] Patch Collection
23 ---
25 doc/help.etx | 4
26 source/menu.c | 28 ++++++
27 source/nedit.h | 4
28 source/preferences.c | 71 ++++++++++++----
29 source/preferences.h | 2
30 source/text.c | 18 +++-
31 source/text.h | 4
32 source/textDisp.c | 220 ++++++++++++++++++++++++++++++++++++++++++++-------
33 source/textDisp.h | 16 ++-
34 source/textP.h | 2
35 source/window.c | 62 ++++++++++----
36 source/window.h | 4
37 12 files changed, 367 insertions(+), 68 deletions(-)
39 diff --quilt old/doc/help.etx new/doc/help.etx
40 --- old/doc/help.etx
41 +++ new/doc/help.etx
42 @@ -3975,10 +3975,14 @@ Preferences
44 **Show Tooltips**
45 Show file name and path in a tooltip when moving the mouse pointer over a tab.
46 (See Tabbed_Editing_.)
48 +**Show Cursorline**
49 + Background the current line with a colored bar. Use the color dialog to
50 + change the background color.
52 **Terminate with Line Break on Save**
53 Some UNIX tools expect that files end with a line feed. If this option is
54 activated, NEdit will append one if required.
56 **Sort Open Prev. Menu**
57 diff --quilt old/source/menu.c new/source/menu.c
58 --- old/source/menu.c
59 +++ new/source/menu.c
60 @@ -177,10 +177,12 @@ static void bgMenuDefCB(Widget w, Window
61 static void searchDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData);
62 static void beepOnSearchWrapDefCB(Widget w, WindowInfo *window, caddr_t callData);
63 static void keepSearchDlogsDefCB(Widget w, WindowInfo *window,
64 caddr_t callData);
65 static void searchWrapsDefCB(Widget w, WindowInfo *window, caddr_t callData);
66 +static void showCursorlineCB(Widget widget, WindowInfo *window,
67 + caddr_t callData);
68 static void appendLFCB(Widget w, WindowInfo* window, caddr_t callData);
69 static void sortOpenPrevDefCB(Widget w, WindowInfo *window, caddr_t callData);
70 static void reposDlogsDefCB(Widget w, WindowInfo *window, caddr_t callData);
71 static void autoScrollDefCB(Widget w, WindowInfo *window, caddr_t callData);
72 static void modWarnDefCB(Widget w, WindowInfo *window, caddr_t callData);
73 @@ -1015,10 +1017,15 @@ Widget CreateMenuBar(Widget parent, Wind
74 createMenuSeparator(subSubPane, "sep", SHORT);
75 window->matchSyntaxBasedDefItem = createMenuToggle(subSubPane,
76 "matchSyntax", "Syntax Based", 'S', matchSyntaxBasedDefCB, window,
77 GetPrefMatchSyntaxBased(), SHORT);
79 + /* Show Cursorline */
80 + window->showCursorlineItem = createMenuToggle(subPane,
81 + "showCursorlineItem", "Show Cursorline", 'x', showCursorlineCB,
82 + NULL, GetPrefShowCursorline(), FULL);
84 /* Append LF at end of files on save */
85 window->appendLFItem = createMenuToggle(subPane, "appendLFItem",
86 "Terminate with Line Break on Save", 'v', appendLFCB, NULL,
87 GetPrefAppendLF(), FULL);
89 @@ -2175,10 +2182,29 @@ static void searchWrapsDefCB(Widget w, W
90 if (IsTopDocument(win))
91 XmToggleButtonSetState(win->searchWrapsDefItem, state, False);
95 +static void showCursorlineCB(Widget widget, WindowInfo *unused,
96 + caddr_t callData)
98 + WindowInfo *window;
99 + Boolean state = XmToggleButtonGetState(widget);
101 + SetPrefShowCursorline(state);
102 + for (window = WindowList; window != NULL; window = window->next) {
103 + XmToggleButtonSetState(window->showCursorlineItem, state, False);
105 + if (IsTopDocument(window)) {
106 + Widget pane = (window->lastFocus
107 + ? window->lastFocus
108 + : window->textArea);
109 + XtVaSetValues(pane, textNshowCursorline, state, NULL);
114 static void appendLFCB(Widget w, WindowInfo* window, caddr_t callData)
116 WindowInfo *win;
117 int state = XmToggleButtonGetState(w);
119 @@ -3942,11 +3968,11 @@ static void focusPaneAP(Widget w, XEvent
121 if (paneIndex >= 0 && paneIndex <= window->nPanes) {
122 newFocusPane = GetPaneByIndex(window, paneIndex);
124 if (newFocusPane != NULL) {
125 - window->lastFocus = newFocusPane;
126 + ChangeLastFocus(window, newFocusPane);
127 XmProcessTraversal(window->lastFocus, XmTRAVERSE_CURRENT);
129 else {
130 XBell(TheDisplay, 0);
132 diff --quilt old/source/nedit.h new/source/nedit.h
133 --- old/source/nedit.h
134 +++ new/source/nedit.h
135 @@ -54,11 +54,11 @@
136 #define NEDIT_DEFAULT_HI_BG "red" /* matching parens. */
137 #define NEDIT_DEFAULT_LINENO_FG "black"
138 #define NEDIT_DEFAULT_CURSOR_FG "black"
139 #define NEDIT_DEFAULT_HELP_FG "black"
140 #define NEDIT_DEFAULT_HELP_BG "rgb:cc/cc/cc"
142 +#define NEDIT_DEFAULT_CURSORLINE_BG "LightSkyBlue"
144 /* Tuning parameters */
145 #define SEARCHMAX 5119 /* Maximum length of search/replace strings */
146 #define MAX_SEARCH_HISTORY 100 /* Maximum length of search string history */
147 #define MAX_PANES 6 /* Max # of ADDITIONAL text editing panes
148 @@ -191,10 +191,11 @@ enum colorTypes {
149 SELECT_BG_COLOR,
150 HILITE_FG_COLOR,
151 HILITE_BG_COLOR,
152 LINENO_FG_COLOR,
153 CURSOR_FG_COLOR,
154 + CURSORLINE_BG_COLOR,
155 NUM_COLORS
158 /* cache user menus: manage mode of user menu list element */
159 typedef enum {
160 @@ -393,10 +394,11 @@ typedef struct _WindowInfo {
161 Widget backlightCharsDefItem;
162 Widget searchDlogsDefItem;
163 Widget beepOnSearchWrapDefItem;
164 Widget keepSearchDlogsDefItem;
165 Widget searchWrapsDefItem;
166 + Widget showCursorlineItem;
167 Widget appendLFItem;
168 Widget sortOpenPrevDefItem;
169 Widget allTagsDefItem;
170 Widget smartTagsDefItem;
171 Widget reposDlogsDefItem;
172 diff --quilt old/source/preferences.c new/source/preferences.c
173 --- old/source/preferences.c
174 +++ new/source/preferences.c
175 @@ -233,10 +233,12 @@ typedef struct {
176 Widget hiliteBgErrW;
177 Widget lineNoFgW;
178 Widget lineNoFgErrW;
179 Widget cursorFgW;
180 Widget cursorFgErrW;
181 + Widget cursorlineBgW;
182 + Widget cursorlineBgErrW;
183 WindowInfo *window;
184 } colorDialog;
186 /* Repository for simple preferences settings */
187 static struct prefData {
188 @@ -318,10 +320,11 @@ static struct prefData {
189 char helpFontNames[NUM_HELP_FONTS][MAX_FONT_LEN];/* fonts for help system */
190 char helpLinkColor[MAX_COLOR_LEN]; /* Color for hyperlinks in the help system */
191 char colorNames[NUM_COLORS][MAX_COLOR_LEN];
192 char tooltipBgColor[MAX_COLOR_LEN];
193 int undoModifiesSelection;
194 + int showCursorline;
195 int focusOnRaise;
196 Boolean honorSymlinks;
197 int truncSubstitution;
198 Boolean forceOSConversion;
199 } PrefData;
200 @@ -1020,10 +1023,14 @@ static PrefDescripRec PrefDescrip[] = {
201 PrefData.colorNames[LINENO_FG_COLOR],
202 (void *)sizeof(PrefData.colorNames[LINENO_FG_COLOR]), True},
203 {"cursorFgColor", "CursorFgColor", PREF_STRING, NEDIT_DEFAULT_CURSOR_FG,
204 PrefData.colorNames[CURSOR_FG_COLOR],
205 (void *)sizeof(PrefData.colorNames[CURSOR_FG_COLOR]), True},
206 + {"cursorlineBGColor", "CursorlineBGColor", PREF_STRING,
207 + NEDIT_DEFAULT_CURSORLINE_BG,
208 + PrefData.colorNames[CURSORLINE_BG_COLOR],
209 + (void *)sizeof(PrefData.colorNames[CURSORLINE_BG_COLOR]), True},
210 {"tooltipBgColor", "TooltipBgColor", PREF_STRING, "LemonChiffon1",
211 PrefData.tooltipBgColor,
212 (void *)sizeof(PrefData.tooltipBgColor), False},
213 {"shell", "Shell", PREF_STRING, "DEFAULT", PrefData.shell,
214 (void*) sizeof(PrefData.shell), True},
215 @@ -1070,11 +1077,13 @@ static PrefDescripRec PrefDescrip[] = {
216 {"forceOSConversion", "ForceOSConversion", PREF_BOOLEAN, "True",
217 &PrefData.forceOSConversion, NULL, False},
218 {"truncSubstitution", "TruncSubstitution", PREF_ENUM, "Fail",
219 &PrefData.truncSubstitution, TruncSubstitutionModes, False},
220 {"honorSymlinks", "HonorSymlinks", PREF_BOOLEAN, "True",
221 - &PrefData.honorSymlinks, NULL, False}
222 + &PrefData.honorSymlinks, NULL, False},
223 + {"showCursorline", "ShowCursorline", PREF_BOOLEAN, "True",
224 + &PrefData.showCursorline, NULL, True},
227 static XrmOptionDescRec OpTable[] = {
228 {"-wrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"Continuous"},
229 {"-nowrap", ".autoWrap", XrmoptionNoArg, (caddr_t)"None"},
230 @@ -2194,10 +2203,20 @@ int GetPrefTruncSubstitution(void)
231 void MarkPrefsChanged(void)
233 PrefsHaveChanged = True;
236 +void SetPrefShowCursorline(Boolean value)
238 + setIntPref(&PrefData.showCursorline, (int)value);
241 +Boolean GetPrefShowCursorline(void)
243 + return PrefData.showCursorline;
247 ** Check if preferences have changed, and if so, ask the user if he wants
248 ** to re-save. Returns False if user requests cancelation of Exit (or whatever
249 ** operation triggered this call to be made).
251 @@ -6073,10 +6092,11 @@ selectFg SELECT_FG_COLOR
252 selectBg SELECT_BG_COLOR
253 hiliteFg HILITE_FG_COLOR
254 hiliteBg HILITE_BG_COLOR
255 lineNoFg LINENO_FG_COLOR
256 cursorFg CURSOR_FG_COLOR
257 +cursorlineBg CURSORLINE_BG_COLOR
260 #define MARGIN_SPACING 10
263 @@ -6136,10 +6156,17 @@ static void cursorFgModifiedCB(Widget w,
265 colorDialog *cd = (colorDialog *)clientData;
266 showColorStatus(cd, cd->cursorFgW, cd->cursorFgErrW);
269 +static void cursorlineBgModifiedCB(Widget w, XtPointer clientData,
270 + XtPointer callData)
272 + colorDialog *cd = (colorDialog *)clientData;
273 + showColorStatus(cd, cd->cursorlineBgW, cd->cursorlineBgErrW);
278 * Helper functions for validating colors
280 static int verifyAllColors(colorDialog *cd)
281 @@ -6150,11 +6177,12 @@ static int verifyAllColors(colorDialog *
282 checkColorStatus(cd, cd->selectFgW) &&
283 checkColorStatus(cd, cd->selectBgW) &&
284 checkColorStatus(cd, cd->hiliteFgW) &&
285 checkColorStatus(cd, cd->hiliteBgW) &&
286 checkColorStatus(cd, cd->lineNoFgW) &&
287 - checkColorStatus(cd, cd->cursorFgW) );
288 + checkColorStatus(cd, cd->cursorFgW) &&
289 + checkColorStatus(cd, cd->cursorlineBgW));
292 /* Returns True if the color is valid, False if it's not */
293 static Boolean checkColorStatus(colorDialog *cd, Widget colorFieldW)
295 @@ -6189,35 +6217,38 @@ static void updateColors(colorDialog *cd
296 *selectFg = XmTextGetString(cd->selectFgW),
297 *selectBg = XmTextGetString(cd->selectBgW),
298 *hiliteFg = XmTextGetString(cd->hiliteFgW),
299 *hiliteBg = XmTextGetString(cd->hiliteBgW),
300 *lineNoFg = XmTextGetString(cd->lineNoFgW),
301 - *cursorFg = XmTextGetString(cd->cursorFgW);
302 + *cursorFg = XmTextGetString(cd->cursorFgW),
303 + *cursorlineBg = XmTextGetString(cd->cursorlineBgW);
305 for (window = WindowList; window != NULL; window = window->next)
307 SetColors(window, textFg, textBg, selectFg, selectBg, hiliteFg,
308 - hiliteBg, lineNoFg, cursorFg);
309 + hiliteBg, lineNoFg, cursorFg, cursorlineBg);
312 SetPrefColorName(TEXT_FG_COLOR , textFg );
313 SetPrefColorName(TEXT_BG_COLOR , textBg );
314 SetPrefColorName(SELECT_FG_COLOR, selectFg);
315 SetPrefColorName(SELECT_BG_COLOR, selectBg);
316 SetPrefColorName(HILITE_FG_COLOR, hiliteFg);
317 SetPrefColorName(HILITE_BG_COLOR, hiliteBg);
318 SetPrefColorName(LINENO_FG_COLOR, lineNoFg);
319 SetPrefColorName(CURSOR_FG_COLOR, cursorFg);
320 + SetPrefColorName(CURSORLINE_BG_COLOR, cursorlineBg);
322 XtFree(textFg);
323 XtFree(textBg);
324 XtFree(selectFg);
325 XtFree(selectBg);
326 XtFree(hiliteFg);
327 XtFree(hiliteBg);
328 XtFree(lineNoFg);
329 XtFree(cursorFg);
330 + XtFree(cursorlineBg);
335 * Dialog button callbacks
336 @@ -6383,38 +6414,41 @@ void ChooseColors(WindowInfo *window)
337 NULL);
338 XmStringFree(s1);
340 topW = infoLbl;
342 + /* The right column (backgrounds) */
343 + tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
344 + &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
345 + textBgModifiedCB, cd );
346 + tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
347 + &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
348 + selectBgModifiedCB, cd );
349 + tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
350 + &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
351 + hiliteBgModifiedCB, cd );
352 + tmpW = addColorGroup( form, "cursorlineBg", 'r', "Cursorline Highlighting",
353 + &(cd->cursorlineBgW), &(cd->cursorlineBgErrW), tmpW, 51, 99,
354 + cursorlineBgModifiedCB, cd );
356 /* The left column (foregrounds) of color entry groups */
357 tmpW = addColorGroup( form, "textFg", 'P', "Plain Text Foreground",
358 &(cd->textFgW), &(cd->textFgErrW), topW, 1, 49,
359 textFgModifiedCB, cd );
360 tmpW = addColorGroup( form, "selectFg", 'S', "Selection Foreground",
361 &(cd->selectFgW), &(cd->selectFgErrW), tmpW, 1, 49,
362 selectFgModifiedCB, cd );
363 tmpW = addColorGroup( form, "hiliteFg", 'M', "Matching (..) Foreground",
364 &(cd->hiliteFgW), &(cd->hiliteFgErrW), tmpW, 1, 49,
365 hiliteFgModifiedCB, cd );
366 + tmpW = addColorGroup( form, "cursorFg", 'C', "Cursor Color",
367 + &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 1, 49,
368 + cursorFgModifiedCB, cd );
369 tmpW = addColorGroup( form, "lineNoFg", 'L', "Line Numbers",
370 &(cd->lineNoFgW), &(cd->lineNoFgErrW), tmpW, 1, 49,
371 lineNoFgModifiedCB, cd );
373 - /* The right column (backgrounds) */
374 - tmpW = addColorGroup( form, "textBg", 'T', "Text Area Background",
375 - &(cd->textBgW), &(cd->textBgErrW), topW, 51, 99,
376 - textBgModifiedCB, cd );
377 - tmpW = addColorGroup( form, "selectBg", 'B', "Selection Background",
378 - &(cd->selectBgW), &(cd->selectBgErrW), tmpW, 51, 99,
379 - selectBgModifiedCB, cd );
380 - tmpW = addColorGroup( form, "hiliteBg", 'h', "Matching (..) Background",
381 - &(cd->hiliteBgW), &(cd->hiliteBgErrW), tmpW, 51, 99,
382 - hiliteBgModifiedCB, cd );
383 - tmpW = addColorGroup( form, "cursorFg", 'C', "Cursor Color",
384 - &(cd->cursorFgW), &(cd->cursorFgErrW), tmpW, 51, 99,
385 - cursorFgModifiedCB, cd );
387 tmpW = XtVaCreateManagedWidget("infoLbl",
388 xmLabelGadgetClass, form,
389 XmNtopAttachment, XmATTACH_WIDGET,
390 XmNtopWidget, tmpW,
391 XmNtopOffset, MARGIN_SPACING,
392 @@ -6491,10 +6525,11 @@ void ChooseColors(WindowInfo *window)
393 XmTextSetString(cd->selectBgW, GetPrefColorName(SELECT_BG_COLOR));
394 XmTextSetString(cd->hiliteFgW, GetPrefColorName(HILITE_FG_COLOR));
395 XmTextSetString(cd->hiliteBgW, GetPrefColorName(HILITE_BG_COLOR));
396 XmTextSetString(cd->lineNoFgW, GetPrefColorName(LINENO_FG_COLOR));
397 XmTextSetString(cd->cursorFgW, GetPrefColorName(CURSOR_FG_COLOR));
398 + XmTextSetString(cd->cursorlineBgW, GetPrefColorName(CURSORLINE_BG_COLOR));
400 /* Handle mnemonic selection of buttons and focus to dialog */
401 AddDialogMnemonicHandler(form, FALSE);
403 /* put up dialog */
404 diff --quilt old/source/preferences.h new/source/preferences.h
405 --- old/source/preferences.h
406 +++ new/source/preferences.h
407 @@ -120,10 +120,12 @@ char *GetPrefBacklightCharTypes(void);
408 void SetPrefRepositionDialogs(int state);
409 int GetPrefRepositionDialogs(void);
410 void SetPrefAutoScroll(int state);
411 int GetPrefAutoScroll(void);
412 int GetVerticalAutoScroll(void);
413 +void SetPrefShowCursorline(Boolean value);
414 +Boolean GetPrefShowCursorline(void);
415 void SetPrefAppendLF(int state);
416 int GetPrefAppendLF(void);
417 void SetPrefSortOpenPrevMenu(int state);
418 int GetPrefSortOpenPrevMenu(void);
419 char *GetPrefTagFile(void);
420 diff --quilt old/source/text.c new/source/text.c
421 --- old/source/text.c
422 +++ new/source/text.c
423 @@ -641,10 +641,13 @@ static XtResource resources[] = {
424 XtOffset(TextWidget, text.calltipFGPixel), XmRString,
425 NEDIT_DEFAULT_CALLTIP_FG},
426 {textNcalltipBackground, textCcalltipBackground, XmRPixel,sizeof(Pixel),
427 XtOffset(TextWidget, text.calltipBGPixel), XmRString,
428 NEDIT_DEFAULT_CALLTIP_BG},
429 + {textNcursorlineBackground, textCCursorlineBackground, XmRPixel,sizeof(Pixel),
430 + XtOffset(TextWidget, text.cursorlineBGPixel), XmRString,
431 + NEDIT_DEFAULT_CURSORLINE_BG},
432 {textNbacklightCharTypes,textCBacklightCharTypes,XmRString,sizeof(XmString),
433 XtOffset(TextWidget, text.backlightCharTypes), XmRString, NULL},
434 {textNrows, textCRows, XmRInt,sizeof(int),
435 XtOffset(TextWidget, text.rows), XmRString, "24"},
436 {textNcolumns, textCColumns, XmRInt, sizeof(int),
437 @@ -705,11 +708,13 @@ static XtResource resources[] = {
438 sizeof(caddr_t), XtOffset(TextWidget, text.dragEndCB), XtRCallback, NULL},
439 {textNsmartIndentCallback, textCSmartIndentCallback, XmRCallback,
440 sizeof(caddr_t), XtOffset(TextWidget, text.smartIndentCB), XtRCallback,
441 NULL},
442 {textNcursorVPadding, textCCursorVPadding, XtRCardinal, sizeof(Cardinal),
443 - XtOffset(TextWidget, text.cursorVPadding), XmRString, "0"}
444 + XtOffset(TextWidget, text.cursorVPadding), XmRString, "0"},
445 + {textNshowCursorline, textCshowCursorline, XmRBoolean, sizeof(Boolean),
446 + XtOffset(TextWidget, text.showCursorline), XmRString, "False"},
449 static TextClassRec textClassRec = {
450 /* CoreClassPart */
452 @@ -823,11 +828,12 @@ static void initialize(TextWidget reques
453 new->text.selectBGPixel, new->text.highlightFGPixel,
454 new->text.highlightBGPixel, new->text.cursorFGPixel,
455 new->text.lineNumFGPixel,
456 new->text.continuousWrap, new->text.wrapMargin,
457 new->text.backlightCharTypes, new->text.calltipFGPixel,
458 - new->text.calltipBGPixel);
459 + new->text.calltipBGPixel,
460 + new->text.cursorlineBGPixel, new->text.showCursorline);
462 /* Add mandatory delimiters blank, tab, and newline to the list of
463 delimiters. The memory use scheme here is that new values are
464 always copied, and can therefore be safely freed on subsequent
465 set-values calls or destroy */
466 @@ -1121,10 +1127,18 @@ static Boolean setValues(TextWidget curr
467 if (new->text.wrapMargin != current->text.wrapMargin ||
468 new->text.continuousWrap != current->text.continuousWrap)
469 TextDSetWrapMode(current->text.textD, new->text.continuousWrap,
470 new->text.wrapMargin);
472 + if (new->text.showCursorline != current->text.showCursorline) {
473 + current->text.showCursorline = new->text.showCursorline;
474 + if (current->text.textD) {
475 + current->text.textD->showCursorline = new->text.showCursorline;
477 + TextDSetShowCursorline(current->text.textD, new->text.showCursorline);
480 /* When delimiters are changed, copy the memory, so that the caller
481 doesn't have to manage it, and add mandatory delimiters blank,
482 tab, and newline to the list */
483 if (new->text.delimiters != current->text.delimiters) {
484 char *delimiters = XtMalloc(strlen(new->text.delimiters) + 4);
485 diff --quilt old/source/text.h new/source/text.h
486 --- old/source/text.h
487 +++ new/source/text.h
488 @@ -59,10 +59,12 @@
489 #define textCLineNumForeground "LineNumForeground"
490 #define textNcalltipForeground "calltipForeground"
491 #define textCcalltipForeground "CalltipForeground"
492 #define textNcalltipBackground "calltipBackground"
493 #define textCcalltipBackground "CalltipBackground"
494 +#define textNcursorlineBackground "cursorlineBackground"
495 +#define textCCursorlineBackground "CursorlineBackground"
496 #define textNpendingDelete "pendingDelete"
497 #define textCPendingDelete "PendingDelete"
498 #define textNhScrollBar "hScrollBar"
499 #define textCHScrollBar "HScrollBar"
500 #define textNvScrollBar "vScrollBar"
501 @@ -111,10 +113,12 @@
502 #define textCEmulateTabs "EmulateTabs"
503 #define textNcursorVPadding "cursorVPadding"
504 #define textCCursorVPadding "CursorVPadding"
505 #define textNbacklightCharTypes "backlightCharTypes"
506 #define textCBacklightCharTypes "BacklightCharTypes"
507 +#define textNshowCursorline "showCursorline"
508 +#define textCshowCursorline "ShowCursorline"
511 extern WidgetClass textWidgetClass;
513 struct _TextClassRec;
514 diff --quilt old/source/textDisp.c new/source/textDisp.c
515 --- old/source/textDisp.c
516 +++ new/source/textDisp.c
517 @@ -62,46 +62,49 @@ static const char CVSID[] = "$Id: textDi
518 #include "../debug.h"
519 #endif
521 /* Masks for text drawing methods. These are or'd together to form an
522 integer which describes what drawing calls to use to draw a string */
523 +#define STYLE_LOOKUP_SHIFT 0
524 #define FILL_SHIFT 8
525 #define SECONDARY_SHIFT 9
526 #define PRIMARY_SHIFT 10
527 #define HIGHLIGHT_SHIFT 11
528 -#define STYLE_LOOKUP_SHIFT 0
529 #define BACKLIGHT_SHIFT 12
530 +#define RANGESET_SHIFT 20
531 +#define CURSORLINE_SHIFT 26
533 #define FILL_MASK (1 << FILL_SHIFT)
534 #define SECONDARY_MASK (1 << SECONDARY_SHIFT)
535 #define PRIMARY_MASK (1 << PRIMARY_SHIFT)
536 #define HIGHLIGHT_MASK (1 << HIGHLIGHT_SHIFT)
537 #define STYLE_LOOKUP_MASK (0xff << STYLE_LOOKUP_SHIFT)
538 #define BACKLIGHT_MASK (0xff << BACKLIGHT_SHIFT)
540 -#define RANGESET_SHIFT (20)
541 #define RANGESET_MASK (0x3F << RANGESET_SHIFT)
542 +#define CURSORLINE_MASK (1 << CURSORLINE_SHIFT)
544 /* If you use both 32-Bit Style mask layout:
545 Bits +----------------+----------------+----------------+----------------+
546 hex |1F1E1D1C1B1A1918|1716151413121110| F E D C B A 9 8| 7 6 5 4 3 2 1 0|
547 dec |3130292827262524|2322212019181716|151413121110 9 8| 7 6 5 4 3 2 1 0|
548 +----------------+----------------+----------------+----------------+
549 - Type | r r| r r r r b b b b| b b b b H 1 2 F| s s s s s s s s|
550 + Type | c r r| r r r r b b b b| b b b b H 1 2 F| s s s s s s s s|
551 +----------------+----------------+----------------+----------------+
552 - where: s - style lookup value (8 bits)
553 + where:
554 + s - style lookup value (8 bits)
555 F - fill (1 bit)
556 2 - secondary selection (1 bit)
557 1 - primary selection (1 bit)
558 H - highlight (1 bit)
559 b - backlighting index (8 bits)
560 r - rangeset index (6 bits)
561 - This leaves 6 "unused" bits */
562 + c - cursorline coloring (1 bit)
563 + This leaves 5 "unused" bits */
565 /* Maximum displayable line length (how many characters will fit across the
566 widest window). This amount of memory is temporarily allocated from the
567 - stack in the redisplayLine routine for drawing strings */
568 + stack in the redisplayLineCur routine for drawing strings */
569 #define MAX_DISP_LINE_LEN 1000
571 /* Macro for getting the TextPart from a textD */
572 #define TEXT_OF_TEXTD(t) (((TextWidget)((t)->w))->text)
574 @@ -113,10 +116,12 @@ static void offsetLineStarts(textDisp *t
575 static void calcLineStarts(textDisp *textD, int startLine, int endLine);
576 static void calcLastChar(textDisp *textD);
577 static int posToVisibleLineNum(textDisp *textD, int pos, int *lineNum);
578 static void redisplayLine(textDisp *textD, int visLineNum, int leftClip,
579 int rightClip, int leftCharIndex, int rightCharIndex);
580 +static void redisplayLineCur(textDisp *textD, int visLineNum, int leftClip,
581 + int rightClip, int leftCharIndex, int rightCharIndex, Boolean curLine);
582 static void drawString(textDisp *textD, int style, int x, int y, int toX,
583 char *string, int nChars);
584 static void clearRect(textDisp *textD, GC gc, int x, int y,
585 int width, int height);
586 static void drawCursor(textDisp *textD, int x, int y);
587 @@ -147,11 +152,12 @@ static int countLines(const char *string
588 static int measureVisLine(textDisp *textD, int visLineNum);
589 static int emptyLinesVisible(textDisp *textD);
590 static void blankCursorProtrusions(textDisp *textD);
591 static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct,
592 Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
593 - Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel);
594 + Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel,
595 + Pixel cursorlineBGPixel);
596 static GC allocateGC(Widget w, unsigned long valueMask,
597 unsigned long foreground, unsigned long background, Font font,
598 unsigned long dynamicMask, unsigned long dontCareMask);
599 static void releaseGC(Widget w, GC gc);
600 static void resetClipRectangles(textDisp *textD);
601 @@ -185,11 +191,12 @@ textDisp *TextDCreate(Widget widget, Wid
602 Position lineNumLeft, Position lineNumWidth, textBuffer *buffer,
603 XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel,
604 Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel,
605 Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel,
606 int continuousWrap, int wrapMargin, XmString bgClassString,
607 - Pixel calltipFGPixel, Pixel calltipBGPixel)
608 + Pixel calltipFGPixel, Pixel calltipBGPixel,
609 + Pixel cursorlineBGPixel, Boolean showCursorline)
611 textDisp *textD;
612 XGCValues gcValues;
613 int i;
615 @@ -231,14 +238,16 @@ textDisp *TextDCreate(Widget widget, Wid
616 textD->highlightFGPixel = highlightFGPixel;
617 textD->selectBGPixel = selectBGPixel;
618 textD->highlightBGPixel = highlightBGPixel;
619 textD->lineNumFGPixel = lineNumFGPixel;
620 textD->cursorFGPixel = cursorFGPixel;
621 + textD->cursorlineBGPixel = cursorlineBGPixel;
622 textD->wrapMargin = wrapMargin;
623 textD->continuousWrap = continuousWrap;
624 allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
625 - selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel);
626 + selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel,
627 + cursorlineBGPixel);
628 textD->styleGC = allocateGC(textD->w, 0, 0, 0, fontStruct->fid,
629 GCClipMask|GCForeground|GCBackground, GCArcMode);
630 textD->lineNumLeft = lineNumLeft;
631 textD->lineNumWidth = lineNumWidth;
632 textD->nVisibleLines = (height - 1) / (textD->ascent + textD->descent) + 1;
633 @@ -260,10 +269,13 @@ textDisp *TextDCreate(Widget widget, Wid
634 textD->suppressResync = 0;
635 textD->nLinesDeleted = 0;
636 textD->modifyingTabDist = 0;
637 textD->pointerHidden = False;
638 textD->graphicsExposeQueue = NULL;
639 + textD->showCursorline = showCursorline;
640 + textD->oldCursorPos = 0;
641 + textD->oldLineStart = 0;
643 /* Attach an event handler to the widget so we can know the visibility
644 (used for choosing the fastest drawing method) */
645 XtAddEventHandler(widget, VisibilityChangeMask, False,
646 visibilityEH, textD);
647 @@ -316,10 +328,12 @@ void TextDFree(textDisp *textD)
648 releaseGC(textD->w, textD->highlightGC);
649 releaseGC(textD->w, textD->selectBGGC);
650 releaseGC(textD->w, textD->highlightBGGC);
651 releaseGC(textD->w, textD->styleGC);
652 releaseGC(textD->w, textD->lineNumGC);
653 + releaseGC(textD->w, textD->cursorlineGC);
654 + releaseGC(textD->w, textD->cursorlineBGGC);
655 XtFree((char *)textD->lineStarts);
656 while (TextDPopGraphicExposeQueueEntry(textD)) {
658 XtFree((char *)textD->bgClassPixel);
659 XtFree((char *)textD->bgClass);
660 @@ -380,11 +394,12 @@ void TextDAttachHighlightData(textDisp *
663 /* Change the (non syntax-highlit) colors */
664 void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP,
665 Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP,
666 - Pixel lineNoFgP, Pixel cursorFgP)
667 + Pixel lineNoFgP, Pixel cursorFgP,
668 + Pixel cursorlineBgP)
670 XGCValues values;
671 Display *d = XtDisplay(textD->w);
673 /* Update the stored pixels */
674 @@ -394,19 +409,23 @@ void TextDSetColors(textDisp *textD, Pix
675 textD->selectBGPixel = selectBgP;
676 textD->highlightFGPixel = hiliteFgP;
677 textD->highlightBGPixel = hiliteBgP;
678 textD->lineNumFGPixel = lineNoFgP;
679 textD->cursorFGPixel = cursorFgP;
680 + textD->cursorlineBGPixel = cursorlineBgP;
682 releaseGC(textD->w, textD->gc);
683 releaseGC(textD->w, textD->selectGC);
684 releaseGC(textD->w, textD->selectBGGC);
685 releaseGC(textD->w, textD->highlightGC);
686 releaseGC(textD->w, textD->highlightBGGC);
687 releaseGC(textD->w, textD->lineNumGC);
688 + releaseGC(textD->w, textD->cursorlineGC);
689 + releaseGC(textD->w, textD->cursorlineBGGC);
690 allocateFixedFontGCs(textD, textD->fontStruct, textBgP, textFgP, selectFgP,
691 - selectBgP, hiliteFgP, hiliteBgP, lineNoFgP);
692 + selectBgP, hiliteFgP, hiliteBgP, lineNoFgP,
693 + cursorlineBgP);
695 /* Change the cursor GC (the cursor GC is not shared). */
696 values.foreground = cursorFgP;
697 XChangeGC( d, textD->cursorFGGC, GCForeground, &values );
699 @@ -414,20 +433,31 @@ void TextDSetColors(textDisp *textD, Pix
700 TextDRedisplayRect(textD, textD->left, textD->top, textD->width,
701 textD->height);
702 redrawLineNumbers(textD, True);
705 +void TextDSetShowCursorline(textDisp *textD, Boolean showCursorline)
707 + textD->showCursorline = showCursorline;
709 + /* Redisplay */
710 + TextDRedisplayRect(textD, textD->left, textD->top,
711 + textD->width, textD->height);
712 + redrawLineNumbers(textD, True);
716 ** Change the (non highlight) font
718 void TextDSetFont(textDisp *textD, XFontStruct *fontStruct)
720 Display *display = XtDisplay(textD->w);
721 int i, maxAscent = fontStruct->ascent, maxDescent = fontStruct->descent;
722 int width, height, fontWidth;
723 Pixel bgPixel, fgPixel, selectFGPixel, selectBGPixel;
724 Pixel highlightFGPixel, highlightBGPixel, lineNumFGPixel;
725 + Pixel cursorlineBGPixel;
726 XGCValues values;
727 XFontStruct *styleFont;
729 /* If font size changes, cursor will be redrawn in a new position */
730 blankCursorProtrusions(textD);
731 @@ -477,18 +507,25 @@ void TextDSetFont(textDisp *textD, XFont
732 XGetGCValues(display, textD->highlightGC,GCForeground|GCBackground,&values);
733 highlightFGPixel = values.foreground;
734 highlightBGPixel = values.background;
735 XGetGCValues(display, textD->lineNumGC, GCForeground, &values);
736 lineNumFGPixel = values.foreground;
737 + XGetGCValues(display, textD->cursorlineGC,GCForeground|GCBackground,&values);
738 + cursorlineBGPixel = values.background;
740 releaseGC(textD->w, textD->gc);
741 releaseGC(textD->w, textD->selectGC);
742 releaseGC(textD->w, textD->highlightGC);
743 releaseGC(textD->w, textD->selectBGGC);
744 releaseGC(textD->w, textD->highlightBGGC);
745 releaseGC(textD->w, textD->lineNumGC);
746 + releaseGC(textD->w, textD->cursorlineGC);
747 + releaseGC(textD->w, textD->cursorlineBGGC);
749 allocateFixedFontGCs(textD, fontStruct, bgPixel, fgPixel, selectFGPixel,
750 - selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel);
751 + selectBGPixel, highlightFGPixel, highlightBGPixel, lineNumFGPixel,
752 + cursorlineBGPixel);
753 XSetFont(display, textD->styleGC, fontStruct->fid);
755 /* Do a full resize to force recalculation of font related parameters */
756 width = textD->width;
757 height = textD->height;
758 @@ -709,11 +746,12 @@ static void textDRedisplayRange(textDisp
759 /* Reset the clipping rectangles for the drawing GCs which are shared
760 using XtAllocateGC, and may have changed since the last use */
761 resetClipRectangles(textD);
763 /* If the starting and ending lines are the same, redisplay the single
764 - line between "start" and "end" */
765 + line between "start" and "end".
766 + Add one to endIndex to catch the caret at the end of a range. */
767 if (startLine == lastLine) {
768 redisplayLine(textD, startLine, 0, INT_MAX, startIndex, endIndex);
769 return;
772 @@ -722,11 +760,12 @@ static void textDRedisplayRange(textDisp
774 /* Redisplay the lines in between at their full width */
775 for (i=startLine+1; i<lastLine; i++)
776 redisplayLine(textD, i, 0, INT_MAX, 0, INT_MAX);
778 - /* Redisplay the last line to "end" */
779 + /* Redisplay the last line to "end". Add one to the endIndex to catch
780 + the caret at the end of a range. */
781 redisplayLine(textD, lastLine, 0, INT_MAX, 0, endIndex);
785 ** Set the scroll position of the text display vertically by line number and
786 @@ -783,37 +822,37 @@ void TextDSetInsertPosition(textDisp *te
787 TextDBlankCursor(textD);
789 /* draw it at its new position */
790 textD->cursorPos = newPos;
791 textD->cursorOn = True;
792 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos + 1);
793 + textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
796 void TextDBlankCursor(textDisp *textD)
798 if (!textD->cursorOn)
799 return;
801 blankCursorProtrusions(textD);
802 textD->cursorOn = False;
803 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1);
804 + textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
807 void TextDUnblankCursor(textDisp *textD)
809 if (!textD->cursorOn) {
810 textD->cursorOn = True;
811 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1);
812 + textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
816 void TextDSetCursorStyle(textDisp *textD, int style)
818 textD->cursorStyle = style;
819 blankCursorProtrusions(textD);
820 if (textD->cursorOn) {
821 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos + 1);
822 + textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
826 void TextDSetWrapMode(textDisp *textD, int wrap, int wrapMargin)
828 @@ -1745,13 +1784,28 @@ static int posToVisibleLineNum(textDisp
829 ** "leftClip" and "rightClip" window coordinates and "leftCharIndex" and
830 ** "rightCharIndex" character positions (not including the character at
831 ** position "rightCharIndex").
833 ** The cursor is also drawn if it appears on the line.
835 +** The function actually forwards to redisplayLineCur(), passing the
836 +** showCursorline setting as appropriate.
838 static void redisplayLine(textDisp *textD, int visLineNum, int leftClip,
839 - int rightClip, int leftCharIndex, int rightCharIndex)
840 + int rightClip, int leftCharIndex, int rightCharIndex)
842 + redisplayLineCur(textD, visLineNum, leftClip, rightClip, leftCharIndex,
843 + rightCharIndex, textD->showCursorline);
847 +** The meat of redisplayLine() is handled here. The extra curLine parameter
848 +** tells redisplayLineCur() whether it should attempt to reset the previous
849 +** "current line" to a non-current line state.
851 +static void redisplayLineCur(textDisp *textD, int visLineNum, int leftClip,
852 + int rightClip, int leftCharIndex, int rightCharIndex, Boolean curLine)
854 textBuffer *buf = textD->buffer;
855 int i, x, y, startX, charIndex, lineStartPos, lineLen, fontHeight;
856 int stdCharWidth, charWidth, startIndex, charStyle, style;
857 int charLen, outStartIndex, outIndex, cursorX = 0, hasCursor = False;
858 @@ -1784,10 +1838,102 @@ static void redisplayLine(textDisp *text
859 } else {
860 lineLen = visLineLength(textD, visLineNum);
861 lineStr = BufGetRange(buf, lineStartPos, lineStartPos + lineLen);
864 + /* handle case of leftCharIndex == rightCharIndex */
865 + if (leftCharIndex == rightCharIndex) {
866 + if (lineStartPos + leftCharIndex == cursorPos) {
867 + /* we're at the cursor position */
868 + if (leftCharIndex > 0)
869 + --leftCharIndex;
870 + if (rightCharIndex < lineLen)
871 + ++rightCharIndex;
872 + if (rightCharIndex >= lineLen)
873 + rightCharIndex = INT_MAX;
874 + } else {
875 + /* hmm: not sure what gets us here, but it happens - redraw line */
876 + leftCharIndex = 0;
877 + rightCharIndex = INT_MAX;
878 + return;
882 + /* for cursorline tracking, if this is the current line, check it against
883 + the last cursorline - if different, we need to display the whole line
884 + plus anything to the extreme right */
885 + if (curLine
886 + && (textD->oldCursorPos != cursorPos
887 + || textD->oldLineStart != lineStartPos)) {
888 + int oldCursor = textD->oldCursorPos;
889 + int lineEndPos = lineStartPos + lineLen;
890 + int oldLineStart = textD->oldLineStart;
891 + int gotLineCurdiff = -1;
892 + /* store new values if we need to call redisplayLine() again */
893 + textD->oldCursorPos = cursorPos;
895 + if (lineStartPos <= cursorPos
896 + && cursorPos <= lineEndPos
897 + && !(lineStartPos <= oldCursor && oldCursor <= lineEndPos)) {
898 + /* find visible line number for oldCursor */
899 + int lineNum, startPos = -1, oldLen, endPos;
900 + int gotLine = -1;
902 + for (lineNum = 0; lineNum < textD->nVisibleLines; lineNum++) {
903 + startPos = textD->lineStarts[lineNum];
904 + if (startPos >= 0) {
905 + oldLen = visLineLength(textD, lineNum);
906 + endPos = startPos + oldLen;
907 + if (startPos >= 0
908 + && startPos <= oldCursor
909 + && oldCursor <= endPos) {
910 + gotLine = lineNum;
911 + break;
916 + if (gotLine >= 0 && gotLine != visLineNum) {
917 + redisplayLineCur(textD, gotLine, 0, INT_MAX, 0, INT_MAX, False);
918 + gotLineCurdiff = gotLine;
921 + /* right: that was the old line done - now the current line */
922 + leftCharIndex = 0;
923 + rightCharIndex = INT_MAX;
925 + /* only update oldLineStart if cursor has moved */
926 + textD->oldLineStart = lineStartPos;
929 + if (lineStartPos != oldLineStart) {
930 + /* find visible line number for oldLineStart */
931 + int lineNum;
932 + int gotLine = -1;
934 + for (lineNum = 0; lineNum < textD->nVisibleLines; lineNum++) {
935 + if (textD->lineStarts[lineNum] == oldLineStart) {
936 + gotLine = lineNum;
937 + break;
941 + if (gotLine >= 0
942 + && gotLine != visLineNum
943 + && gotLine != gotLineCurdiff) {
944 + redisplayLineCur(textD, gotLine, 0, INT_MAX, 0, INT_MAX, False);
947 + /* right: that was the old line done - now the current line */
948 + leftCharIndex = 0;
949 + rightCharIndex = INT_MAX;
951 + /* only update oldLineStart if cursor has moved */
952 + textD->oldLineStart = lineStartPos;
956 /* Space beyond the end of the line is still counted in units of characters
957 of a standardized character width (this is done mostly because style
958 changes based on character position can still occur in this region due
959 to rectangular selections). stdCharWidth must be non-zero to prevent a
960 potential infinite loop if x does not advance */
961 @@ -1949,10 +2095,11 @@ static void drawString(textDisp *textD,
962 XGCValues gcValues;
963 XFontStruct *fs = textD->fontStruct;
964 Pixel bground = textD->bgPixel;
965 Pixel fground = textD->fgPixel;
966 int underlineStyle = FALSE;
967 + int cursorline_mask = textD->showCursorline ? CURSORLINE_MASK : 0;
969 /* Don't draw if widget isn't realized */
970 if (XtWindow(textD->w) == 0)
971 return;
973 @@ -1966,10 +2113,14 @@ static void drawString(textDisp *textD,
975 else if (style & PRIMARY_MASK) {
976 gc = textD->selectGC;
977 bgGC = textD->selectBGGC;
979 + else if (style & cursorline_mask) {
980 + gc = textD->cursorlineGC;
981 + bgGC = textD->cursorlineBGGC;
983 else {
984 gc = bgGC = textD->gc;
987 if (gc == textD->styleGC) {
988 @@ -1990,22 +2141,27 @@ static void drawString(textDisp *textD,
989 else {
990 styleRec = NULL;
991 gcValues.font = fs->fid;
992 fground = textD->fgPixel;
994 - /* Background color priority order is:
995 - 1 Primary(Selection), 2 Highlight(Parens),
996 - 3 Rangeset, 4 SyntaxHighlightStyle,
997 - 5 Backlight (if NOT fill), 6 DefaultBackground */
998 + /* Background color priority order is:
999 + 1. PRIMARY (selection)
1000 + 2. Highlight (flash matching parens)
1001 + 3. Rangeset
1002 + 4. SyntaxHighlightStyle
1003 + 5. Cursorline
1004 + 6. Backlight (if NOT fill)
1005 + 7. DefaultBackground */
1006 bground =
1007 style & PRIMARY_MASK ? textD->selectBGPixel :
1008 style & HIGHLIGHT_MASK ? textD->highlightBGPixel :
1009 style & RANGESET_MASK ?
1010 getRangesetColor(textD,
1011 (style&RANGESET_MASK)>>RANGESET_SHIFT,
1012 bground) :
1013 styleRec && styleRec->bgColorName ? styleRec->bgColor :
1014 + style & cursorline_mask ? textD->cursorlineBGPixel :
1015 (style & BACKLIGHT_MASK) && !(style & FILL_MASK) ?
1016 textD->bgClassPixel[(style>>BACKLIGHT_SHIFT) & 0xff] :
1017 textD->bgPixel;
1018 if (fground == bground) /* B&W kludge */
1019 fground = textD->bgPixel;
1020 @@ -2159,10 +2315,11 @@ static void drawCursor(textDisp *textD,
1021 static int styleOfPos(textDisp *textD, int lineStartPos,
1022 int lineLen, int lineIndex, int dispIndex, int thisChar)
1024 textBuffer *buf = textD->buffer;
1025 textBuffer *styleBuf = textD->styleBuffer;
1026 + int cursorPos = textD->cursorPos;
1027 int pos, style = 0;
1029 if (lineStartPos == -1 || buf == NULL)
1030 return FILL_MASK;
1032 @@ -2193,10 +2350,12 @@ static int styleOfPos(textDisp *textD, i
1033 of the character thisChar */
1034 if (textD->bgClass)
1036 style |= (textD->bgClass[(unsigned char)thisChar]<<BACKLIGHT_SHIFT);
1038 + if (lineStartPos <= cursorPos && cursorPos <= lineStartPos + lineLen)
1039 + style |= CURSORLINE_MASK;
1040 return style;
1044 ** Find the width of a string in the font of a particular style
1045 @@ -2721,11 +2880,11 @@ static void setScroll(textDisp *textD, i
1046 else if (xOffset < 0) {
1047 TextDRedisplayRect(textD, textD->left + textD->width + xOffset,
1048 textD->top, -xOffset, textD->height);
1050 /* Restore protruding parts of the cursor */
1051 - textDRedisplayRange(textD, textD->cursorPos-1, textD->cursorPos+1);
1052 + textDRedisplayRange(textD, textD->cursorPos, textD->cursorPos);
1055 /* Refresh line number/calltip display if its up and we've scrolled
1056 vertically */
1057 if (lineDelta != 0) {
1058 @@ -3008,11 +3167,12 @@ static void blankCursorProtrusions(textD
1059 ** Allocate shared graphics contexts used by the widget, which must be
1060 ** re-allocated on a font change.
1062 static void allocateFixedFontGCs(textDisp *textD, XFontStruct *fontStruct,
1063 Pixel bgPixel, Pixel fgPixel, Pixel selectFGPixel, Pixel selectBGPixel,
1064 - Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel)
1065 + Pixel highlightFGPixel, Pixel highlightBGPixel, Pixel lineNumFGPixel,
1066 + Pixel cursorlineBGPixel)
1068 textD->gc = allocateGC(textD->w, GCFont | GCForeground | GCBackground,
1069 fgPixel, bgPixel, fontStruct->fid, GCClipMask, GCArcMode);
1070 textD->selectGC = allocateGC(textD->w, GCFont | GCForeground | GCBackground,
1071 selectFGPixel, selectBGPixel, fontStruct->fid, GCClipMask,
1072 @@ -3025,10 +3185,14 @@ static void allocateFixedFontGCs(textDis
1073 textD->highlightBGGC = allocateGC(textD->w, GCForeground, highlightBGPixel,
1074 0, fontStruct->fid, GCClipMask, GCArcMode);
1075 textD->lineNumGC = allocateGC(textD->w, GCFont | GCForeground |
1076 GCBackground, lineNumFGPixel, bgPixel, fontStruct->fid,
1077 GCClipMask, GCArcMode);
1078 + textD->cursorlineGC = allocateGC(textD->w, GCFont|GCForeground|GCBackground,
1079 + fgPixel, cursorlineBGPixel, fontStruct->fid, GCClipMask, GCArcMode);
1080 + textD->cursorlineBGGC = allocateGC(textD->w, GCForeground,
1081 + cursorlineBGPixel, 0, fontStruct->fid, GCClipMask, GCArcMode);
1085 ** X11R4 does not have the XtAllocateGC function for sharing graphics contexts
1086 ** with changeable fields. Unfortunately the R4 call for creating shared
1087 @@ -3097,10 +3261,14 @@ static void resetClipRectangles(textDisp
1088 &clipRect, 1, Unsorted);
1089 XSetClipRectangles(display, textD->highlightBGGC, 0, 0,
1090 &clipRect, 1, Unsorted);
1091 XSetClipRectangles(display, textD->styleGC, 0, 0,
1092 &clipRect, 1, Unsorted);
1093 + XSetClipRectangles(display, textD->cursorlineGC, 0, 0,
1094 + &clipRect, 1, Unsorted);
1095 + XSetClipRectangles(display, textD->cursorlineBGGC, 0, 0,
1096 + &clipRect, 1, Unsorted);
1100 ** Return the length of a line (number of displayable characters) by examining
1101 ** entries in the line starts array rather than by scanning for newlines
1102 diff --quilt old/source/textDisp.h new/source/textDisp.h
1103 --- old/source/textDisp.h
1104 +++ new/source/textDisp.h
1105 @@ -127,12 +127,12 @@ typedef struct _textDisp {
1106 int ascent, descent; /* Composite ascent and descent for
1107 primary font + all-highlight fonts */
1108 int fixedFontWidth; /* Font width if all current fonts are
1109 fixed and match in width, else -1 */
1110 Widget hScrollBar, vScrollBar;
1111 - GC gc, selectGC, highlightGC; /* GCs for drawing text */
1112 - GC selectBGGC, highlightBGGC; /* GCs for erasing text */
1113 + GC gc, selectGC, highlightGC, cursorlineGC; /* GCs for drawing text */
1114 + GC selectBGGC, highlightBGGC, cursorlineBGGC; /* GCs for erasing text */
1115 GC cursorFGGC; /* GC for drawing the cursor */
1116 GC lineNumGC; /* GC for drawing line numbers */
1117 GC styleGC; /* GC with color and font unspecified
1118 for drawing colored/styled text */
1119 Pixel fgPixel, bgPixel; /* Foreground/Background colors */
1120 @@ -140,10 +140,11 @@ typedef struct _textDisp {
1121 selectBGPixel; /* Background select color */
1122 Pixel highlightFGPixel, /* Highlight colors are used when */
1123 highlightBGPixel; /* flashing matching parens */
1124 Pixel lineNumFGPixel; /* Color for drawing line numbers */
1125 Pixel cursorFGPixel;
1126 + Pixel cursorlineBGPixel;
1127 Pixel *bgClassPixel; /* table of colors for each BG class */
1128 unsigned char *bgClass; /* obtains index into bgClassPixel[] */
1130 Widget calltipW; /* The Label widget for the calltip */
1131 Widget calltipShell; /* The Shell that holds the calltip */
1132 @@ -159,28 +160,33 @@ typedef struct _textDisp {
1133 int modifyingTabDist; /* Whether tab distance is being
1134 modified */
1135 Boolean pointerHidden; /* true if the mouse pointer is
1136 hidden */
1137 graphicExposeTranslationEntry *graphicsExposeQueue;
1138 + int oldCursorPos;
1139 + int oldLineStart;
1140 + Boolean showCursorline;
1141 } textDisp;
1143 textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar,
1144 Position left, Position top, Position width, Position height,
1145 Position lineNumLeft, Position lineNumWidth, textBuffer *buffer,
1146 XFontStruct *fontStruct, Pixel bgPixel, Pixel fgPixel,
1147 Pixel selectFGPixel, Pixel selectBGPixel, Pixel highlightFGPixel,
1148 Pixel highlightBGPixel, Pixel cursorFGPixel, Pixel lineNumFGPixel,
1149 int continuousWrap, int wrapMargin, XmString bgClassString,
1150 - Pixel calltipFGPixel, Pixel calltipBGPixel);
1151 + Pixel calltipFGPixel, Pixel calltipBGPixel,
1152 + Pixel cursorlineBGPixel, Boolean showCursorline);
1153 void TextDFree(textDisp *textD);
1154 void TextDSetBuffer(textDisp *textD, textBuffer *buffer);
1155 void TextDAttachHighlightData(textDisp *textD, textBuffer *styleBuffer,
1156 styleTableEntry *styleTable, int nStyles, char unfinishedStyle,
1157 unfinishedStyleCBProc unfinishedHighlightCB, void *cbArg);
1158 void TextDSetColors(textDisp *textD, Pixel textFgP, Pixel textBgP,
1159 Pixel selectFgP, Pixel selectBgP, Pixel hiliteFgP, Pixel hiliteBgP,
1160 - Pixel lineNoFgP, Pixel cursorFgP);
1161 + Pixel lineNoFgP, Pixel cursorFgP,
1162 + Pixel cursorlineBgP);
1163 void TextDSetFont(textDisp *textD, XFontStruct *fontStruct);
1164 int TextDMinFontWidth(textDisp *textD, Boolean considerStyles);
1165 int TextDMaxFontWidth(textDisp *textD, Boolean considerStyles);
1166 void TextDResize(textDisp *textD, int width, int height);
1167 void TextDRedisplayRect(textDisp *textD, int left, int top, int width,
1168 @@ -232,6 +238,8 @@ int TextDPreferredColumn(textDisp *textD
1170 void TextDImposeGraphicsExposeTranslation(textDisp *textD, int *xOffset, int *yOffset);
1171 Boolean TextDPopGraphicExposeQueueEntry(textDisp *textD);
1172 void TextDTranlateGraphicExposeQueue(textDisp *textD, int xOffset, int yOffset, Boolean appendEntry);
1174 +void TextDSetShowCursorline(textDisp *textD, Boolean showCursorline);
1176 #endif /* NEDIT_TEXTDISP_H_INCLUDED */
1177 diff --quilt old/source/textP.h new/source/textP.h
1178 --- old/source/textP.h
1179 +++ new/source/textP.h
1180 @@ -57,10 +57,11 @@ extern TextClassRec nTextClassRec;
1182 typedef struct _TextPart {
1183 /* resources */
1184 Pixel selectFGPixel, selectBGPixel, highlightFGPixel, highlightBGPixel;
1185 Pixel cursorFGPixel, lineNumFGPixel, calltipFGPixel, calltipBGPixel;
1186 + Pixel cursorlineBGPixel;
1187 XFontStruct *fontStruct;
1188 Boolean pendingDelete;
1189 Boolean autoShowInsertPos;
1190 Boolean autoWrap;
1191 Boolean autoWrapPastedText;
1192 @@ -69,10 +70,11 @@ typedef struct _TextPart {
1193 Boolean smartIndent;
1194 Boolean overstrike;
1195 Boolean heavyCursor;
1196 Boolean readOnly;
1197 Boolean hidePointer;
1198 + Boolean showCursorline;
1199 int rows, columns;
1200 int marginWidth, marginHeight;
1201 int cursorBlinkRate;
1202 int wrapMargin;
1203 int emulateTabs;
1204 diff --quilt old/source/window.c new/source/window.c
1205 --- old/source/window.c
1206 +++ new/source/window.c
1207 @@ -260,10 +260,11 @@ WindowInfo *CreateWindow(const char *nam
1208 window->fileMissing = True;
1209 strcpy(window->filename, name);
1210 window->undo = NULL;
1211 window->redo = NULL;
1212 window->nPanes = 0;
1213 + window->lastFocus = NULL;
1214 window->autoSaveCharCount = 0;
1215 window->autoSaveOpCount = 0;
1216 window->undoOpCount = 0;
1217 window->undoMemUsed = 0;
1218 CLEAR_ALL_LOCKS(window->lockReasons);
1219 @@ -716,22 +717,23 @@ WindowInfo *CreateWindow(const char *nam
1220 text = createTextArea(pane, window, rows,cols,
1221 GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(),
1222 GetPrefWrapMargin(), window->showLineNumbers?MIN_LINE_NUM_COLS:0);
1223 XtManageChild(text);
1224 window->textArea = text;
1225 - window->lastFocus = text;
1226 + ChangeLastFocus(window, text);
1228 /* Set the initial colors from the globals. */
1229 SetColors(window,
1230 GetPrefColorName(TEXT_FG_COLOR ),
1231 GetPrefColorName(TEXT_BG_COLOR ),
1232 GetPrefColorName(SELECT_FG_COLOR),
1233 GetPrefColorName(SELECT_BG_COLOR),
1234 GetPrefColorName(HILITE_FG_COLOR),
1235 GetPrefColorName(HILITE_BG_COLOR),
1236 GetPrefColorName(LINENO_FG_COLOR),
1237 - GetPrefColorName(CURSOR_FG_COLOR));
1238 + GetPrefColorName(CURSOR_FG_COLOR),
1239 + GetPrefColorName(CURSORLINE_BG_COLOR));
1241 /* Create the right button popup menu (note: order is important here,
1242 since the translation for popping up this menu was probably already
1243 added in createTextArea, but CreateBGMenu requires window->textArea
1244 to be set so it can attach the menu to it (because menu shells are
1245 @@ -1238,11 +1240,11 @@ void SplitPane(WindowInfo *window)
1246 XmNbackground, textD->bgPixel,
1247 NULL);
1248 TextDSetColors( newTextD, textD->fgPixel, textD->bgPixel,
1249 textD->selectFGPixel, textD->selectBGPixel, textD->highlightFGPixel,
1250 textD->highlightBGPixel, textD->lineNumFGPixel,
1251 - textD->cursorFGPixel );
1252 + textD->cursorFGPixel, textD->cursorlineBGPixel );
1254 /* Set the minimum pane height in the new pane */
1255 UpdateMinPaneHeights(window);
1257 /* adjust the heights, scroll positions, etc., to split the focus pane */
1258 @@ -1343,14 +1345,18 @@ void ClosePane(WindowInfo *window)
1259 the remaining panes, simply detroying it didn't seem enough */
1260 window->nPanes--;
1261 XtUnmanageChild(containingPane(window->textPanes[window->nPanes]));
1262 XtDestroyWidget(containingPane(window->textPanes[window->nPanes]));
1264 - if (window->nPanes == 0)
1265 - window->lastFocus = window->textArea;
1266 - else if (focusPane > window->nPanes)
1267 - window->lastFocus = window->textPanes[window->nPanes-1];
1268 + if (window->nPanes == 0) {
1269 + text = window->textArea;
1270 + } else if (focusPane > window->nPanes) {
1271 + text = window->textPanes[window->nPanes - 1];
1272 + } else {
1273 + text = window->textPanes[focusPane - 1];
1275 + ChangeLastFocus(window, text);
1277 /* adjust the heights, scroll positions, etc., to make it look
1278 like the pane with the input focus was closed */
1279 for (i=focusPane; i<=window->nPanes; i++) {
1280 insertPositions[i] = insertPositions[i+1];
1281 @@ -1874,11 +1880,12 @@ void SetFonts(WindowInfo *window, const
1282 UpdateMinPaneHeights(window);
1285 void SetColors(WindowInfo *window, const char *textFg, const char *textBg,
1286 const char *selectFg, const char *selectBg, const char *hiliteFg,
1287 - const char *hiliteBg, const char *lineNoFg, const char *cursorFg)
1288 + const char *hiliteBg, const char *lineNoFg, const char *cursorFg,
1289 + const char *cursorlineBg)
1291 int i, dummy;
1292 Pixel textFgPix = AllocColor( window->textArea, textFg,
1293 &dummy, &dummy, &dummy),
1294 textBgPix = AllocColor( window->textArea, textBg,
1295 @@ -1892,30 +1899,34 @@ void SetColors(WindowInfo *window, const
1296 hiliteBgPix = AllocColor( window->textArea, hiliteBg,
1297 &dummy, &dummy, &dummy),
1298 lineNoFgPix = AllocColor( window->textArea, lineNoFg,
1299 &dummy, &dummy, &dummy),
1300 cursorFgPix = AllocColor( window->textArea, cursorFg,
1301 + &dummy, &dummy, &dummy),
1302 + cursorlineBgPix = AllocColor( window->textArea, cursorlineBg,
1303 &dummy, &dummy, &dummy);
1304 textDisp *textD;
1306 /* Update the main pane */
1307 XtVaSetValues(window->textArea,
1308 XmNforeground, textFgPix,
1309 XmNbackground, textBgPix,
1310 NULL);
1311 textD = ((TextWidget)window->textArea)->text.textD;
1312 TextDSetColors( textD, textFgPix, textBgPix, selectFgPix, selectBgPix,
1313 - hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix );
1314 + hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix,
1315 + cursorlineBgPix );
1316 /* Update any additional panes */
1317 for (i=0; i<window->nPanes; i++) {
1318 XtVaSetValues(window->textPanes[i],
1319 XmNforeground, textFgPix,
1320 XmNbackground, textBgPix,
1321 NULL);
1322 textD = ((TextWidget)window->textPanes[i])->text.textD;
1323 TextDSetColors( textD, textFgPix, textBgPix, selectFgPix, selectBgPix,
1324 - hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix );
1325 + hiliteFgPix, hiliteBgPix, lineNoFgPix, cursorFgPix,
1326 + cursorlineBgPix );
1329 /* Redo any syntax highlighting */
1330 if (window->highlightData != NULL)
1331 UpdateHighlightStyles(window);
1332 @@ -2254,10 +2265,11 @@ static Widget createTextArea(Widget pare
1333 textNautoWrap, window->wrapMode == NEWLINE_WRAP,
1334 textNcontinuousWrap, window->wrapMode == CONTINUOUS_WRAP,
1335 textNoverstrike, window->overstrike,
1336 textNhidePointer, (Boolean) GetPrefTypingHidesPointer(),
1337 textNcursorVPadding, GetVerticalAutoScroll(),
1338 + textNshowCursorline, False,
1339 NULL);
1341 XtVaSetValues(sw, XmNworkWindow, frame, XmNhorizontalScrollBar,
1342 hScrollBar, XmNverticalScrollBar, vScrollBar, NULL);
1344 @@ -2389,11 +2401,11 @@ static void modifiedCB(int pos, int nIns
1347 static void focusCB(Widget w, WindowInfo *window, XtPointer callData)
1349 /* record which window pane last had the keyboard focus */
1350 - window->lastFocus = w;
1351 + ChangeLastFocus(window, w);
1353 /* update line number statistic to reflect current focus pane */
1354 UpdateStatsLine(window);
1356 /* finish off the current incremental search */
1357 @@ -3345,10 +3357,11 @@ WindowInfo* CreateDocument(WindowInfo* s
1358 window->lastModTime = 0;
1359 strcpy(window->filename, name);
1360 window->undo = NULL;
1361 window->redo = NULL;
1362 window->nPanes = 0;
1363 + window->lastFocus = NULL;
1364 window->autoSaveCharCount = 0;
1365 window->autoSaveOpCount = 0;
1366 window->undoOpCount = 0;
1367 window->undoMemUsed = 0;
1368 CLEAR_ALL_LOCKS(window->lockReasons);
1369 @@ -3447,22 +3460,23 @@ WindowInfo* CreateDocument(WindowInfo* s
1370 text = createTextArea(pane, window, nRows, nCols,
1371 GetPrefEmTabDist(PLAIN_LANGUAGE_MODE), GetPrefDelimiters(),
1372 GetPrefWrapMargin(), window->showLineNumbers?MIN_LINE_NUM_COLS:0);
1373 XtManageChild(text);
1374 window->textArea = text;
1375 - window->lastFocus = text;
1376 + ChangeLastFocus(window, text);
1378 /* Set the initial colors from the globals. */
1379 SetColors(window,
1380 GetPrefColorName(TEXT_FG_COLOR ),
1381 GetPrefColorName(TEXT_BG_COLOR ),
1382 GetPrefColorName(SELECT_FG_COLOR),
1383 GetPrefColorName(SELECT_BG_COLOR),
1384 GetPrefColorName(HILITE_FG_COLOR),
1385 GetPrefColorName(HILITE_BG_COLOR),
1386 GetPrefColorName(LINENO_FG_COLOR),
1387 - GetPrefColorName(CURSOR_FG_COLOR));
1388 + GetPrefColorName(CURSOR_FG_COLOR),
1389 + GetPrefColorName(CURSORLINE_BG_COLOR));
1391 /* Create the right button popup menu (note: order is important here,
1392 since the translation for popping up this menu was probably already
1393 added in createTextArea, but CreateBGMenu requires window->textArea
1394 to be set so it can attach the menu to it (because menu shells are
1395 @@ -4247,11 +4261,12 @@ static void cloneTextPanes(WindowInfo *w
1396 XtVaSetValues(text, XmNforeground, textD->fgPixel,
1397 XmNbackground, textD->bgPixel, NULL);
1398 TextDSetColors(newTextD, textD->fgPixel, textD->bgPixel,
1399 textD->selectFGPixel, textD->selectBGPixel,
1400 textD->highlightFGPixel,textD->highlightBGPixel,
1401 - textD->lineNumFGPixel, textD->cursorFGPixel);
1402 + textD->lineNumFGPixel, textD->cursorFGPixel,
1403 + textD->cursorlineBGPixel);
1406 /* Set the minimum pane height in the new pane */
1407 UpdateMinPaneHeights(window);
1409 @@ -4280,11 +4295,11 @@ static void cloneTextPanes(WindowInfo *w
1411 /* set the focus pane */
1412 for (i=0; i<=window->nPanes; i++) {
1413 text = i==0 ? window->textArea : window->textPanes[i-1];
1414 if(i == focusPane) {
1415 - window->lastFocus = text;
1416 + ChangeLastFocus(window, text);
1417 XmProcessTraversal(text, XmTRAVERSE_CURRENT);
1418 break;
1422 @@ -4811,5 +4826,22 @@ void CleanUpTabBarExposeQueue(WindowInfo
1423 ev.count = 0;
1424 XSendEvent(TheDisplay, XtWindow(window->tabBar), False,
1425 ExposureMask, (XEvent *)&ev);
1430 +** Track which text pane in this widget is/was last active (with focus).
1431 +** Also perform any tasks relating to changing pane focus.
1433 +void ChangeLastFocus(WindowInfo *window, Widget text)
1435 + Boolean showCursorline = GetPrefShowCursorline();
1437 + if (window->lastFocus) {
1438 + XtVaSetValues(window->lastFocus, textNshowCursorline, False, NULL);
1441 + XtVaSetValues(text, textNshowCursorline, showCursorline, NULL);
1443 + window->lastFocus = text;
1445 diff --quilt old/source/window.h new/source/window.h
1446 --- old/source/window.h
1447 +++ new/source/window.h
1448 @@ -51,11 +51,12 @@ void SetAutoIndent(WindowInfo *window, i
1449 void SetShowMatching(WindowInfo *window, int state);
1450 void SetFonts(WindowInfo *window, const char *fontName, const char *italicName,
1451 const char *boldName, const char *boldItalicName);
1452 void SetColors(WindowInfo *window, const char *textFg, const char *textBg,
1453 const char *selectFg, const char *selectBg, const char *hiliteFg,
1454 - const char *hiliteBg, const char *lineNoFg, const char *cursorFg);
1455 + const char *hiliteBg, const char *lineNoFg, const char *cursorFg,
1456 + const char *cursorlineBg);
1457 void SetOverstrike(WindowInfo *window, int overstrike);
1458 void SetAutoWrap(WindowInfo *window, int state);
1459 void SetAutoScroll(WindowInfo *window, int margin);
1460 void SplitPane(WindowInfo *window);
1461 Widget GetPaneByIndex(WindowInfo *window, int paneIndex);
1462 @@ -102,6 +103,7 @@ void SortTabBar(WindowInfo *window);
1463 void SetBacklightChars(WindowInfo *window, char *applyBacklightTypes);
1464 void SetToggleButtonState(WindowInfo *window, Widget w, Boolean state,
1465 Boolean notify);
1466 void SetSensitive(WindowInfo *window, Widget w, Boolean sensitive);
1467 void CleanUpTabBarExposeQueue(WindowInfo *window);
1468 +void ChangeLastFocus(WindowInfo *window, Widget text);
1469 #endif /* NEDIT_WINDOW_H_INCLUDED */