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