    Allow rangesets to be displayed underlined.

    This patch depends on the UnderlineStyle.diff patch (or its derivative).
    APPLY THAT PATCH FIRST! This patch uses the syntax highlighting style's
    underlining mechanism (from the earlier patch) to provide an underline for a
    rangeset.

    To apply underlining to a rangeset, use the following macro functioon:
	    rangeset_set_underline(id, mode)
    where mode is one of "leave" (don't change underlining from syntax
    highlighting's attributes), "remove" (don't show syntax highlighting
    underlines for the ranges of the set, and "add" (make sure all text in
    the rangeset is undelined). The ramgeset_info() function will return
    the underline mode keyword for a set.

diff -ur nedit_official nedit_mod
diff -ur nedit_official/doc/help.etx nedit_mod/doc/help.etx
--- nedit_official/doc/help.etx	2008-02-19 23:31:51.000000000 +0100
+++ nedit_mod/doc/help.etx	2008-04-07 23:39:16.000000000 +0200
@@ -2956,6 +2956,12 @@
   regarding the validity of color: if the color is invalid (a bad name,
   or not supported by the hardware) this has unpredictable effects.
 
+**rangeset_set_underline( r, mode )**
+  Change whether text over which the rangeset is defined should be displayed
+  as underlined. **mode** can be "leave" (the text will show any underlining
+  according to syntax highlighting settings), "remove" (any underliining is
+  removed), or "add" (underlining is added to the text).
+
 **rangeset_set_name( r, name )**
   Apply the name to the rangeset r.
 
diff -ur nedit_official/source/macro.c nedit_mod/source/macro.c
--- nedit_official/source/macro.c	2007-10-04 18:04:25.000000000 +0200
+++ nedit_mod/source/macro.c	2008-04-07 23:39:16.000000000 +0200
@@ -383,6 +383,8 @@
       int nArgs, DataValue *result, char **errMsg);
 static int rangesetSetColorMS(WindowInfo *window, DataValue *argList,
       int nArgs, DataValue *result, char **errMsg);
+static int rangesetSetUnderlineMS(WindowInfo *window, DataValue *argList,
+      int nArgs, DataValue *result, char **errMsg);
 static int rangesetSetNameMS(WindowInfo *window, DataValue *argList,
       int nArgs, DataValue *result, char **errMsg);
 static int rangesetSetModeMS(WindowInfo *window, DataValue *argList,
@@ -420,7 +422,8 @@
         rangesetCreateMS, rangesetDestroyMS,
         rangesetAddMS, rangesetSubtractMS, rangesetInvertMS,
         rangesetInfoMS, rangesetRangeMS, rangesetIncludesPosMS,
-        rangesetSetColorMS, rangesetSetNameMS, rangesetSetModeMS,
+        rangesetSetColorMS, rangesetSetUnderlineMS,
+        rangesetSetNameMS, rangesetSetModeMS,
         rangesetGetByNameMS,
         getPatternByNameMS, getPatternAtPosMS,
         getStyleByNameMS, getStyleAtPosMS, filenameDialogMS
@@ -439,7 +442,8 @@
         "rangeset_create", "rangeset_destroy",
         "rangeset_add", "rangeset_subtract", "rangeset_invert",
         "rangeset_info", "rangeset_range", "rangeset_includes",
-        "rangeset_set_color", "rangeset_set_name", "rangeset_set_mode",
+        "rangeset_set_color", "rangeset_set_underline",
+        "rangeset_set_name", "rangeset_set_mode",
         "rangeset_get_by_name",
         "get_pattern_by_name", "get_pattern_at_pos",
         "get_style_by_name", "get_style_at_pos", "filename_dialog"
@@ -5000,7 +5004,7 @@
 {
     RangesetTable *rangesetTable = window->buffer->rangesetTable;
     Rangeset *rangeset = NULL;
-    int count, defined;
+    int count, defined, uline;
     char *color, *name, *mode;
     DataValue element;
     int label = 0;
@@ -5017,7 +5021,8 @@
         rangeset = RangesetFetch(rangesetTable, label);
     }
 
-    RangesetGetInfo(rangeset, &defined, &label, &count, &color, &name, &mode);
+    RangesetGetInfo(rangeset, &defined, &label, &count, &uline,
+                    &color, &name, &mode);
     
     /* set up result */    
     result->tag = ARRAY_TAG;
@@ -5051,7 +5056,15 @@
         M_FAILURE("Failed to allocate array value \"mode\" in %s");
     if (!ArrayInsert(result, PERM_ALLOC_STR("mode"), &element))
         M_FAILURE("Failed to insert array element \"mode\" in %s");
-  
+
+    element.tag = STRING_TAG;
+    element.val.str.rep = (uline < 0) ? PERM_ALLOC_STR("remove") :
+                          (uline > 0) ? PERM_ALLOC_STR("add")    :
+                                        PERM_ALLOC_STR("leave");
+    element.val.str.len = strlen(element.val.str.rep);
+    if (!ArrayInsert(result, PERM_ALLOC_STR("underline"), &element))
+        M_FAILURE("Failed to insert array element \"count\" in %s");
+
     return True;
 }
 
@@ -5224,6 +5237,60 @@
 }
 
 /*
+** Set underline flag for a range set's ranges. Returns true if the rangeset
+** is valid. It takes two arguments: the id of the rangeset to change and
+** the underlineMode string, which should be specified as "leave" (let any
+** syntax highlighting underlines to appear as undisturbed), "add" or "remove".
+*/
+static int rangesetSetUnderlineMS(WindowInfo *window, DataValue *argList,
+      int nArgs, DataValue *result, char **errMsg)
+{
+    char stringStorage[1][TYPE_INT_STR_SIZE(int)];
+    textBuffer *buffer = window->buffer;
+    RangesetTable *rangesetTable = buffer->rangesetTable;
+    Rangeset *rangeset;
+    int label = 0;
+    char *underlineMode;
+
+    if (nArgs != 2) {
+        return wrongNArgsErr(errMsg);
+    }
+
+    if (!readIntArg(argList[0], &label, errMsg)
+            || !RangesetLabelOK(label)) {
+        M_FAILURE("First parameter is an invalid rangeset label in %s");
+    }
+
+    if (rangesetTable == NULL) {
+        M_FAILURE("Rangeset does not exist in %s");
+    }
+
+    rangeset = RangesetFetch(rangesetTable, label);
+    if (rangeset == NULL) {
+        M_FAILURE("Rangeset does not exist in %s");
+    }
+
+    if (readStringArg(argList[1], &underlineMode, stringStorage[0], errMsg)) {
+        if (strcmp(underlineMode, "leave") == 0)
+            RangesetAssignUnderline(rangeset, 0);
+        else
+        if (strcmp(underlineMode, "remove") == 0)
+            RangesetAssignUnderline(rangeset, -1);
+        else
+        if (strcmp(underlineMode, "add") == 0)
+            RangesetAssignUnderline(rangeset, 1);
+        else
+            M_FAILURE("Second parameter must be \"leave\", \"remove\" or \"add\" in %s");
+    }
+    else
+        M_FAILURE("Second parameter must be \"leave\", \"remove\" or \"add\" in %s");
+
+    /* set up result */
+    result->tag = NO_TAG;
+    return True;
+}
+
+/*
 ** Set the name of a range set's ranges. Returns
 ** true if the rangeset is valid.
 */
diff -ur nedit_official/source/rangeset.c nedit_mod/source/rangeset.c
--- nedit_official/source/rangeset.c	2008-02-11 20:50:53.000000000 +0100
+++ nedit_mod/source/rangeset.c	2008-04-07 23:57:00.000000000 +0200
@@ -64,6 +64,7 @@
     unsigned char label;		/* a number 1-63 */
 
     signed char color_set;              /* 0: unset; 1: set; -1: invalid */
+    signed char underline;              /* underline it? */
     char *color_name;			/* the name of an assigned color */
     Pixel color;			/* the value of a particular color */
     textBuffer *buf;			/* the text buffer of the rangeset */
@@ -251,6 +252,7 @@
     rangeset->color_name = (char *)0;
     rangeset->name = (char *)0;
     rangeset->color_set = 0;
+    rangeset->underline = 0;                    /* "no change" value */
     rangeset->buf = buf;
 
     rangeset->maxpos = buf->length;
@@ -693,12 +695,13 @@
 ** Get information about rangeset.
 */
 void RangesetGetInfo(Rangeset *rangeset, int *defined, int *label, 
-        int *count, char **color, char **name, char **mode)
+        int *count, int *uline, char **color, char **name, char **mode)
 {
     if (rangeset == NULL) {
         *defined = False;
         *label = 0;
         *count = 0;
+        *uline = 0;
         *color = "";
         *name = "";
         *mode = "";
@@ -707,6 +710,7 @@
         *defined = True;
         *label = (int)rangeset->label;
         *count = rangeset->n_ranges;
+        *uline = rangeset->underline;
         *color = rangeset->color_name ? rangeset->color_name : "";
         *name = rangeset->name ? rangeset->name : "";
         *mode = rangeset->update_name;
@@ -776,6 +780,7 @@
     destRangeset->last_index  = srcRangeset->last_index;
     destRangeset->n_ranges    = srcRangeset->n_ranges;
     destRangeset->color_set   = srcRangeset->color_set;
+    destRangeset->underline   = srcRangeset->underline;
     destRangeset->color       = srcRangeset->color;
 
     if (srcRangeset->color_name) {
@@ -1068,11 +1073,15 @@
 	return 0;
 
     for (i = 0; i < table->n_set; i++) {
-	rangeset = &table->set[(int)table->order[i]];
-	if (RangesetCheckRangeOfPos(rangeset, pos) >= 0) {
-	    if (needs_color && rangeset->color_set >= 0 && rangeset->color_name)
-		return table->order[i] + 1;
-	}
+        rangeset = &table->set[(int)table->order[i]];
+        if (RangesetCheckRangeOfPos(rangeset, pos) >= 0) {
+            if (needs_color) {
+                if ((rangeset->color_set >= 0 && rangeset->color_name) ||
+                    (rangeset->underline != 0)) {
+                    return table->order[i] + 1;
+                }
+            }
+        }
     }
     return 0;
 }
@@ -1109,6 +1118,27 @@
 }
 
 /*
+** Assign the underline to a rangeset via the rangeset table.
+*/
+
+int RangesetAssignUnderline(Rangeset *rangeset, int under)
+{
+    rangeset->underline = (0 < under) - (under < 0);
+
+    rangesetRefreshAllRanges(rangeset);
+    return 1;
+}
+
+/*
+** Fetch the underline mode value.
+*/
+
+int RangesetGetUnderline(Rangeset *rangeset)
+{
+    return rangeset->underline;
+}
+
+/*
 ** Assign a name to a rangeset via the rangeset table.
 */
 
@@ -1159,6 +1189,16 @@
 }
 
 /*
+** Return the underlining mode.
+*/
+
+int RangesetTableGetUnderline(RangesetTable *table, int index)
+{
+    Rangeset *rangeset = &table->set[index];
+    return rangeset->underline;
+}
+
+/*
 ** Return the color validity, if any, and the value in *color.
 */
 
diff -ur nedit_official/source/rangeset.h nedit_mod/source/rangeset.h
--- nedit_official/source/rangeset.h	2008-01-04 23:11:04.000000000 +0100
+++ nedit_mod/source/rangeset.h	2008-04-07 23:39:16.000000000 +0200
@@ -53,7 +53,7 @@
 int RangesetRemoveBetween(Rangeset *rangeset, int start, int end);
 int RangesetGetNRanges(Rangeset *rangeset);
 void RangesetGetInfo(Rangeset *rangeset, int *defined, int *label, 
-        int *count, char **color, char **name, char **mode);
+        int *count, int *uline, char **color, char **name, char **mode);
 RangesetTable *RangesetTableAlloc(textBuffer *buf);
 RangesetTable *RangesetTableFree(RangesetTable *table);
 RangesetTable *RangesetTableClone(RangesetTable *srcTable,
@@ -69,12 +69,15 @@
 void RangesetBufModifiedCB(int pos, int nInserted, int nDeleted, int nRestyled,
 	const char *deletedText, void *cbArg);
 int RangesetIndex1ofPos(RangesetTable *table, int pos, int needs_color);
+int RangesetAssignUnderline(Rangeset *rangeset, int under);
+int RangesetGetUnderline(Rangeset *rangeset);
 int RangesetAssignColorName(Rangeset *rangeset, char *color_name);
 int RangesetAssignColorPixel(Rangeset *rangeset, Pixel color, int ok);
 char *RangesetGetName(Rangeset *rangeset);
 int RangesetAssignName(Rangeset *rangeset, char *name);
 int RangesetGetColorValid(Rangeset *rangeset, Pixel *color);
 char *RangesetTableGetColorName(RangesetTable *table, int index);
+int RangesetTableGetUnderline(RangesetTable *table, int index);
 int RangesetTableGetColorValid(RangesetTable *table, int index, Pixel *color);
 int RangesetTableAssignColorPixel(RangesetTable *table, int index, Pixel color,
 	int ok);
diff -ur nedit_official/source/textDisp.c nedit_mod/source/textDisp.c
--- nedit_official/source/textDisp.c	2008-01-04 23:31:48.000000000 +0100
+++ nedit_mod/source/textDisp.c	2008-04-07 23:39:16.000000000 +0200
@@ -178,6 +178,7 @@
         const int colNum, const int pos);
 static Pixel allocBGColor(Widget w, char *colorName, int *ok);
 static Pixel getRangesetColor(textDisp *textD, int ind, Pixel bground);
+static int getRangesetUnderline(textDisp *textD, int ind, int old);
 static void textDRedisplayRange(textDisp *textD, int start, int end);
 
 textDisp *TextDCreate(Widget widget, Widget hScrollBar, Widget vScrollBar,
@@ -2013,6 +2014,10 @@
         gcValues.foreground = gcValues.background = bground;
         XChangeGC(XtDisplay(textD->w), gc,
                 GCFont | GCForeground | GCBackground, &gcValues);
+        /* adjust underline according to rangeset underline style */
+        underlineStyle = getRangesetUnderline(textD,
+                          (style&RANGESET_MASK)>>RANGESET_SHIFT,
+                          underlineStyle);
     }
 
     /* Draw blank area rather than text, if that was the request */
@@ -3693,6 +3698,29 @@
 }
 
 /*
+** Return an adjusted underline flag. The original flag value (true if needed
+** by the syntax highlighting style) is left alone if the rangeset's underline
+** mode is 0; cleared if the mode is less than 0, or set if greater.
+*/
+static int getRangesetUnderline(textDisp *textD, int ind, int old)
+{
+    textBuffer *buf;
+    RangesetTable *tab;
+    int under;
+
+    if (ind > 0) {
+        ind--;
+        buf = textD->buffer;
+        tab = buf->rangesetTable;
+
+        under = RangesetTableGetUnderline(tab, ind);
+        if (under != 0)
+            return under > 0;
+    }
+    return old;
+}
+
+/*
 ** Read the background color class specification string in str, allocating the
 ** necessary colors, and allocating and setting up the character->class_no and
 ** class_no->pixel map arrays, returned via *pp_bgClass and *pp_bgClassPixel
