Skip to content

Commit

Permalink
Unify -D option and color handling between MS-DOS and non-MS-DOS builds.
Browse files Browse the repository at this point in the history
  • Loading branch information
gwsw committed Jan 31, 2021
1 parent cd1fa3c commit c6eb7aa
Show file tree
Hide file tree
Showing 4 changed files with 236 additions and 203 deletions.
62 changes: 33 additions & 29 deletions less.nro.VER
Original file line number Diff line number Diff line change
Expand Up @@ -570,10 +570,7 @@ The \-d option does not otherwise change the behavior of
.I less
on a dumb terminal.
.IP "\-D\fBx\fP\fIcolor\fP or \-\-color=\fBx\fP\fIcolor\fP"
[this section is for non-MS-DOS systems only; for MS-DOS systems see below]
.br
When the \-\-use-color option is enabled, this option
changes the color of different parts of the displayed text.
Changes the color of different parts of the displayed text.
\fBx\fP is a single character which selects the type of text
whose color is being set:
.RS
Expand All @@ -595,12 +592,30 @@ The rscroll character.
Search results.
.IP "W"
The highlight enabled via the \-w option.
.IP "d"
Bold text.
.IP "k"
Blinking text.
.IP "s"
Standout text.
.IP "u"
Underlined text.
.RE
.PP
.RS
\fIcolor\fP is either a 4-bit color string or a 6-bit color string:
The uppercase letters can be used only when the \-\-use-color option is enabled.
When text color is specified by both an uppercase letter and a lowercase letter,
the uppercase letter takes precedence.
For example, error messages are normally displayed as standout text.
So if both "s" and "E" are given a color, the "E" color applies
to error messages, and the "s" color applies to other standout text.
The "d" and "u" letters refer to bold and underline text formed by
overstriking with backspaces (see the \-u option),
not to text using ANSI escape sequences with the \-R option.
.PP
\fIcolor\fP is either a 4-bit color string or a 8-bit color string:
.PP
A 4-bit color string is one or two characters where
A 4-bit color string is zero, one or two characters, where
the first character specifies the foreground color and
the second specifies the background color as follows:
.IP "b"
Expand All @@ -621,38 +636,27 @@ White
Yellow
.PP
The corresponding upper-case letter denotes a brighter shade of the color.
For example, \-DLGk displays line numbers as bright green text on a black
For example, \-DNGk displays line numbers as bright green text on a black
background, and \-DEbR displays error messages as blue text on a
bright red background.
If either character is a "-", the corresponding color is not changed.
If the background character is omitted, the background color is not changed.
If either character is a "-" or is omitted, the corresponding color
is set to that of normal text.
.PP
A 6-bit color string is one or two decimal integers separated by a dot,
A 8-bit color string is one or two decimal integers separated by a dot,
where the first integer specifies the foreground color and
the second specifies the background color.
Each integer is a value between 0 and 255 inclusive which selects
a CSI 38;5 color (see
.br
https://en.wikipedia.org/wiki/ANSI_escape_code#SGR_parameters)
If either integer is a "-", the corresponding color is not changed.
If the dot and background integer are omitted, the background color is not changed.
If either integer is a "-" or is omitted,
the corresponding color is set to that of normal text.
On MS-DOS versions of
.IR less ,
8-bit color is not supported; instead, decimal values are interpreted as 4-bit
CHAR_INFO.Attributes values
(see https://docs.microsoft.com/en-us/windows/console/char-info-str).
.RE
.IP "\-D\fBx\fP\fIcolor\fP or \-\-color=\fBx\fP\fIcolor\fP"
[this section is for MS-DOS systems only]
.br
Sets the color of the text displayed.
\fBx\fP is a single character which selects the type of text whose color is
being set: n=normal, s=standout, d=bold, u=underlined, k=blink.
\fIcolor\fP is a pair of numbers separated by a period.
The first number selects the foreground color and the second selects
the background color of the text.
A single number \fIN\fP is the same as \fIN.M\fP,
where \fIM\fP is the normal background color.
The color may start or end with \fBu\fP to use underline (with the normal
color, if by itself), if the system supports it (Windows only).
\fBx\fP may also be \fBa\fP to toggle strict ANSI sequence rendering
(SGR mode).
.
.IP "\-e or \-\-quit-at-eof"
Causes
.I less
Expand Down
47 changes: 35 additions & 12 deletions line.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,10 @@ static char color_map[AT_NUM_COLORS][12] = {
"kC", /* AT_COLOR_PROMPT */
"kc", /* AT_COLOR_RSCROLL */
"kG", /* AT_COLOR_SEARCH */
"", /* AT_UNDERLINE */
"", /* AT_BOLD */
"", /* AT_BLINK */
"", /* AT_STANDOUT */
};

/* State while processing an ANSI escape sequence */
Expand Down Expand Up @@ -953,7 +957,8 @@ store_bs(ch, rep, pos)
{
if (bs_mode == BS_CONTROL)
return store_control_char(ch, rep, pos);
if (linebuf.end <= linebuf.print ||
if (linebuf.end > 0 &&
(linebuf.end <= linebuf.print && linebuf.buf[linebuf.end-1] == '\0') ||
(linebuf.end > 0 && linebuf.attr[linebuf.end - 1] & (AT_ANSI|AT_BINARY)))
STORE_PRCHAR('\b', pos);
else if (bs_mode == BS_NORMAL)
Expand Down Expand Up @@ -1407,10 +1412,30 @@ rrshift(VOID_PARAM)
color_index(attr)
int attr;
{
int cx = (attr & AT_COLOR) >> AT_COLOR_SHIFT;
if (cx == 0 || cx > AT_NUM_COLORS)
return -1;
return cx-1;
if (use_color)
{
switch (attr & AT_COLOR)
{
case AT_COLOR_ATTN: return 0;
case AT_COLOR_BIN: return 1;
case AT_COLOR_CTRL: return 2;
case AT_COLOR_ERROR: return 3;
case AT_COLOR_LINENUM: return 4;
case AT_COLOR_MARK: return 5;
case AT_COLOR_PROMPT: return 6;
case AT_COLOR_RSCROLL: return 7;
case AT_COLOR_SEARCH: return 8;
}
}
if (attr & AT_UNDERLINE)
return 9;
if (attr & AT_BOLD)
return 10;
if (attr & AT_BLINK)
return 11;
if (attr & AT_STANDOUT)
return 12;
return -1;
}

static int
Expand All @@ -1431,10 +1456,11 @@ set_color_map(attr, colorstr)
int cx = color_index(attr);
if (cx < 0)
return -1;
if (tput_color(colorstr, null_putc) < 0)
if (*colorstr != '\0' && tput_color(colorstr, null_putc) < 0)
return -1;
if (strlen(colorstr)+1 > sizeof(color_map[cx]))
return -1;
strncpy(color_map[cx], colorstr, sizeof(color_map[cx]));
color_map[cx][strlen(colorstr)] = '\0';
strcpy(color_map[cx], colorstr);
return 0;
}

Expand All @@ -1445,10 +1471,7 @@ set_color_map(attr, colorstr)
get_color_map(attr)
int attr;
{
int cx;
if (!use_color)
return NULL;
cx = color_index(attr);
int cx = color_index(attr);
if (cx < 0)
return NULL;
return color_map[cx];
Expand Down
108 changes: 53 additions & 55 deletions optfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ extern int wheel_lines;
extern int less_is_more;
extern int linenum_width;
extern int status_col_width;
extern int use_color;
#if LOGFILE
extern char *namelogfile;
extern int force_logfile;
Expand Down Expand Up @@ -585,59 +586,7 @@ colordesc(s, fg_color, bg_color)
*fg_color = fg;
*bg_color = bg;
}

/*
* Handler for the -D option.
*/
/*ARGSUSED*/
public void
opt_D(type, s)
int type;
char *s;
{
PARG p;

switch (type)
{
case INIT:
case TOGGLE:
switch (*s++)
{
case 'n':
colordesc(s, &nm_fg_color, &nm_bg_color);
break;
case 'd':
colordesc(s, &bo_fg_color, &bo_bg_color);
break;
case 'u':
colordesc(s, &ul_fg_color, &ul_bg_color);
break;
case 'k':
colordesc(s, &bl_fg_color, &bl_bg_color);
break;
case 's':
colordesc(s, &so_fg_color, &so_bg_color);
break;
case 'a':
sgr_mode = !sgr_mode;
break;
default:
error("-D must be followed by n, d, u, k, s or a", NULL_PARG);
break;
}
if (type == TOGGLE)
{
at_enter(AT_STANDOUT);
at_exit();
}
break;
case QUERY:
p.p_string = (sgr_mode) ? "on" : "off";
error("SGR mode is %s", &p);
break;
}
}
#else
#endif

static int
color_from_namechar(namechar)
Expand All @@ -654,6 +603,10 @@ color_from_namechar(namechar)
case 'P': return AT_COLOR_PROMPT;
case 'R': return AT_COLOR_RSCROLL;
case 'S': return AT_COLOR_SEARCH;
case 's': return AT_STANDOUT;
case 'd': return AT_BOLD;
case 'u': return AT_UNDERLINE;
case 'k': return AT_BLINK;
default: return 0;
}
}
Expand All @@ -674,23 +627,68 @@ opt_D(type, s)
{
case INIT:
case TOGGLE:
#if MSDOS_COMPILER
if (*s == 'a')
{
sgr_mode = !sgr_mode;
break;
}
#endif
attr = color_from_namechar(s[0]);
if (attr <= 0)
if (attr == 0)
{
p.p_char = s[0];
error("Invalid color specifier '%c'", &p);
return;
}
if (!use_color && (attr & AT_COLOR))
{
error("Set --use-color before changing colors", NULL_PARG);
return;
}
#if MSDOS_COMPILER
if (!(attr & AT_COLOR))
{
switch (attr)
{
case AT_NORMAL:
colordesc(s, &nm_fg_color, &nm_bg_color);
break;
case AT_BOLD:
colordesc(s, &bo_fg_color, &bo_bg_color);
break;
case AT_UNDERLINE:
colordesc(s, &ul_fg_color, &ul_bg_color);
break;
case AT_BLINK:
colordesc(s, &bl_fg_color, &bl_bg_color);
break;
case AT_STANDOUT:
colordesc(s, &so_fg_color, &so_bg_color);
break;
}
if (type == TOGGLE)
{
at_enter(AT_STANDOUT);
at_exit();
}
} else
#endif
if (set_color_map(attr, s+1) < 0)
{
p.p_string = s+1;
error("Invalid color string \"%s\"", &p);
return;
}
break;
#if MSDOS_COMPILER
case QUERY:
p.p_string = (sgr_mode) ? "on" : "off";
error("SGR mode is %s", &p);
break;
#endif
}
}
#endif

/*
* Handler for the -x option.
Expand Down

0 comments on commit c6eb7aa

Please sign in to comment.