From 676cd02ce359b370b67cc2fbd0008e9a83582494 Mon Sep 17 00:00:00 2001 From: Eduardo Chappa Date: Sat, 22 Oct 2016 00:32:56 -0600 Subject: [PATCH] * Color support for the default composer and Pico. If users have configured colors to read messages in Alpine, the same colors will be used in the default composer. In the case of Pico, read the manual to understand how to configure this new feature. --- alpine/reply.c | 30 +++++ doc/man1/pico.1 | 94 ++++++++++++-- pico/display.c | 234 +++++++++++++++++++++++++++-------- pico/edef.h | 3 +- pico/estruct.h | 1 + pico/line.c | 1 + pico/main.c | 374 +++++++++++++++++++++++++++++++++++++++++++++++++++++++- pico/pico.h | 6 + pith/pine.hlp | 2 +- 9 files changed, 685 insertions(+), 60 deletions(-) diff --git a/alpine/reply.c b/alpine/reply.c index ddbd81d..e2897b8 100644 --- a/alpine/reply.c +++ b/alpine/reply.c @@ -2696,6 +2696,36 @@ colors_for_pico(void) VAR_PROMPT_BACK_COLOR); } else colors->prcp = NULL; + + if (VAR_QUOTE1_FORE_COLOR && VAR_QUOTE1_BACK_COLOR){ + colors->qlcp = new_color_pair(VAR_QUOTE1_FORE_COLOR, + VAR_QUOTE1_BACK_COLOR); + } + else colors->qlcp = NULL; + + if (VAR_QUOTE2_FORE_COLOR && VAR_QUOTE2_BACK_COLOR){ + colors->qllcp = new_color_pair(VAR_QUOTE2_FORE_COLOR, + VAR_QUOTE2_BACK_COLOR); + } + else colors->qllcp = NULL; + + if (VAR_QUOTE3_FORE_COLOR && VAR_QUOTE3_BACK_COLOR){ + colors->qlllcp = new_color_pair(VAR_QUOTE3_FORE_COLOR, + VAR_QUOTE3_BACK_COLOR); + } + else colors->qlllcp = NULL; + + if (VAR_NORM_FORE_COLOR && VAR_NORM_BACK_COLOR){ + colors->ntcp = new_color_pair(VAR_NORM_FORE_COLOR, + VAR_NORM_BACK_COLOR); + } + else colors->ntcp = NULL; + + if (VAR_SIGNATURE_FORE_COLOR && VAR_SIGNATURE_BACK_COLOR){ + colors->sbcp = new_color_pair(VAR_SIGNATURE_FORE_COLOR, + VAR_SIGNATURE_BACK_COLOR); + } + else colors->sbcp = NULL; } return colors; diff --git a/doc/man1/pico.1 b/doc/man1/pico.1 index 63c8d66..22035f8 100644 --- a/doc/man1/pico.1 +++ b/doc/man1/pico.1 @@ -1,4 +1,4 @@ -.TH pico 1 "Version 5.08" +.TH pico 1 "Version 5.07" .SH Name pico \- simple text editor in the style of the Alpine Composer .SH Syntax @@ -29,11 +29,9 @@ immediately below. Paragraphs are delimited by blank lines, or by lines beginning with a space or tab. Unjustification can be done immediately after justification using the control-U key combination. .PP -String searches are not sensitive to case, but one can be done -by pressing the control-W followed by control-^. A search begins at -the current cursor position and wraps around the end of the text. -The most recent search string is offered as the default in subsequent -searches. +String searches are not sensitive to case. A search begins at the current +cursor position and wraps around the end of the text. The most recent +search string is offered as the default in subsequent searches. .PP Blocks of text can be moved, copied or deleted with creative use of the command for mark (ctrl-^), delete (ctrl-k) and undelete (ctrl-u). @@ -148,6 +146,88 @@ SIGHUP), \fIpico\fR will save the current work if needed before exiting. Work is saved under the current filename with ".save" appended. If the current work is unnamed, it is saved under the filename "pico.save". .PP +.SH Color Support +If your terminal supports colors, Pico can be configured to color +text. Users can configure the color of the text, the text in the key menu, +the titlebar, messages and prompt in the status line. As an added feature +Pico can also be used to configure the color of up to three different +levels of quoted text, and the signature of an email message. This is +useful when Pico is used as a tool (with the -t command line switch.) +.PP +Pico can tell you the number of colors that your terminal supports, when +started with the switch -color_codes. In addition Pico will print a table +showing the numerical code of every color supported in that terminal. In order +to configure colors, one must use these numerical codes. For example, 0 is +for black, so in order to configure a black color, one must use its code, the +number 0. +.PP +In order to activate colors, one must use the option -ncolors with a numerical +value indicating the number of colors tht your teminal supports, for example, +\fI-ncolors 256\fR indicates that the user wishes to use a table of 256 colors. +.PP +All options that control color, are four letter options. Their last two +letters are either "fc" or "bc", indicating \fIforeground color\fR and +\fIbacground color\fR, respectively. The first two letters indicate the +type of text that is being configured, for example "nt" stands for +\fInormal text\fR, so that -ntfc represents the color of the normal text, +while -ntbc represents the color of the background of normal text. Here +is a complete list of the color options supported by Pico. +.IP -color_codes +displays the number of colors supported by the terminal, and a +table showing the association of colors and numerical codes +.IP -ncolors \fInumber\fR +activates color support in Pico, and tells Pico how many colors to use. +Depending on your terminal \fInumber\fR could be 8, 16, or 256. +.IP -ntfc \fInumber\fR +specifies the number \fInum\fR of the color to be used to color normal text. +.IP -ntbc \fInumber\fR +specifies the number \fInum\fR of the color of the background for normal text. +.IP -rtfc \fInumber\fR +number of the color of reverse text. Default: same as background color +of normal text (if specified.) +.IP -rtbc \fInumber\fR +number of the color of the background of reverse text. Default: same as +color of normal text (if specified.) +.IP -tbfc \fInumber\fR +number of color of text of the title bar. Default: same as +foreground color of reverse text. +.IP -tbbc \fInumber\fR +number of the color of background of the title bar. +.IP -klfc \fInumber\fR +number of the color of the text of the key label. +.IP -klbc \fInumber\fR +number of color of background of the key label. +.IP -knfc \fInumber\fR +number of color of text of the key name. +.IP -knbc \fInumber\fR +number of color of background of the key name. +.IP -stfc \fInumber\fR +number of color of text of the status line. +.IP -stbc \fInumber\fR +number of color of background of the status line. +.IP -prfc \fInumber\fR +number of color of text of a prompt. +.IP -prbc \fInumber\fR +number of color of background of a prompt. +.IP -q1fc \fInumber\fR +number of color of text of level one of quoted text. +.IP -q1bc \fnumber\fR +number of color of background of level one of quoted text. If the option +-q1bc is used, the default value of this option is the background color +or normal text. +.IP -q2fc \fInumber\fR +number of color of text of level two of quoted text. +.IP -q2bc \fInumber\fR +number of color of background of level two of quoted text. If the option +-q1bc is used, the default value of this option is the background color +or normal text. +.IP -q3fc \fInumber\fR +number of color of text of level three of quoted text. +.IP -sbfc \fInumber\fR +number of color of text of signature block text. +.IP -sbbc n\fIumber\fR +number of color of background of signature block text. +.PP .SH Bugs The manner in which lines longer than the display width are dealt is not immediately obvious. Lines that continue beyond the edge @@ -174,4 +254,4 @@ alpine(1) Source distribution (part of the Alpine Message System): .nf -$Date: 2015-04-19 12:28:01 -0500 (Sun, 19 Apr 2015) $ +$Date: 2009-02-02 13:54:23 -0600 (Mon, 02 Feb 2009) $ diff --git a/pico/display.c b/pico/display.c index dd5de6e..7cd3090 100644 --- a/pico/display.c +++ b/pico/display.c @@ -54,6 +54,7 @@ int dumbroot(int, int); int dumblroot(long, int); unsigned cellwidth_ptr_to_ptr(CELL *pstart, CELL *pend); unsigned vcellwidth_a_to_b(int row, int a, int b); +int window_signature_block(WINDOW *wp); #ifdef _WINDOWS void pico_config_menu_items (KEYMENU *); int update_scroll (void); @@ -111,6 +112,9 @@ static KEYMENU menu_compose[] = { #define VFEXT 0x0002 /* extended (beyond column 80) */ #define VFREV 0x0004 /* reverse video status */ #define VFREQ 0x0008 /* reverse video request */ +#define VFSIG 0x0010 /* in signature block */ +#define VFNOR 0x0020 /* in not signature block */ +#define VFQUO 0x0040 /* in quoted text */ int vtrow = 0; /* Row location of SW cursor */ int vtcol = 0; /* Column location of SW cursor */ @@ -137,8 +141,9 @@ vtinit(void) int i, j; VIDEO *vp; CELL ac; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; - ac.c = ' '; + ac.c = '\0'; ac.a = 0; if(Pmaster == NULL) @@ -269,8 +274,9 @@ vtputc(CELL c) int w; vp = vscreen[vtrow]; - ac.c = ' '; + ac.c = '\0'; ac.a = c.a; + ac.d = c.d; if (vtcol >= term.t_ncol) { /* @@ -299,6 +305,7 @@ vtputc(CELL c) vp->v_text[vtind-1] = ac; } else if (c.c == '\t') { + ac.c = ' '; do { vtputc(ac); } @@ -356,7 +363,7 @@ vteeol(void) register VIDEO *vp; CELL c; - c.c = ' '; + c.c = '\0'; c.a = 0; vp = vscreen[vtrow]; @@ -367,6 +374,41 @@ vteeol(void) vtcol = term.t_ncol; } +int +window_signature_block(WINDOW *wp) +{ + LINE *lp, *llp; + int in_sig, is_sig_start; + int change = 0; + + llp = wp->w_linep; + lp = lforw(wp->w_bufp->b_linep); + + do { + in_sig = lback(lp) == wp->w_bufp->b_linep ? 0 : lback(lp)->l_sig; + if(in_sig == 0){ + if(llength(lp) == 3){ + if(lgetc(lp, 0).c == '-' + && lgetc(lp, 1).c == '-' + && lgetc(lp, 2).c == ' '){ + in_sig = 1; + is_sig_start = 1; + } + } + } else { + if(lisblank(lp)) + if(is_sig_start == 0) in_sig = 0; + is_sig_start = 0; + } + if(lp->l_sig != in_sig) + change++; + lp->l_sig = in_sig; + lp = lforw(lp); + } while(lp != wp->w_bufp->b_linep); + wp->w_linep = llp; + return change; +} + /* * Make sure that the display is right. This is a three part process. First, @@ -385,7 +427,10 @@ update(void) int i; int j; int scroll = 0; + int repaint= 0; + int quoted; CELL c; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; #if TYPEAH if (typahead()) @@ -412,6 +457,8 @@ update(void) while (wp != NULL){ /* Look at any window with update flags set on. */ + if(pcolors) + repaint = window_signature_block(wp); if (wp->w_flag != 0){ /* If not force reframe, check the framing. */ @@ -564,22 +611,49 @@ out: i = wp->w_toprow; if ((wp->w_flag & ~WFMODE) == WFEDIT){ + /* if the signature separator was modified (or created) + * do the other side below + */ + if(repaint) goto other; while (lp != wp->w_dotp){ ++i; lp = lforw(lp); } - vscreen[i]->v_flag |= VFCHG; + for (j = 0, quoted = -1; j < llength(lp); ++j){ + if(quoted < 0){ + if(lgetc(lp,j).c != '>' && lgetc(lp, j).c != ' ') + quoted = 0; + else if(lgetc(lp,j).c == '>') + quoted = 1; + } + } + + vscreen[i]->v_flag &= ~(VFSIG|VFNOR|VFQUO); + vscreen[i]->v_flag |= (quoted > 0 ? VFQUO : 0)|(lp->l_sig ? VFSIG : 0)| VFCHG; vtmove(i, 0); for (j = 0; j < llength(lp); ++j) vtputc(lgetc(lp, j)); - vteeol(); } else if ((wp->w_flag & (WFEDIT | WFHARD)) != 0){ +other: while (i < wp->w_toprow+wp->w_ntrows){ - vscreen[i]->v_flag |= VFCHG; + int flag = 0; + for (j = 0, quoted = -1; j < llength(lp) && quoted < 0; ++j){ + if(quoted < 0){ + if(lgetc(lp,j).c != '>' && lgetc(lp, j).c != ' ') + quoted = 0; + else if(lgetc(lp,j).c == '>') + quoted = 1; + } + } + if(repaint && (vscreen[i]->v_flag & VFSIG) && lp->l_sig == 0) + flag |= VFNOR; + if(quoted > 0) flag |= VFQUO; + vscreen[i]->v_flag &= ~(VFSIG | VFNOR | VFQUO); + vscreen[i]->v_flag |= flag | (lp->l_sig ? VFSIG : 0 )| VFCHG; vtmove(i, 0); /* if line has been changed */ @@ -717,18 +791,22 @@ out: movecursor(wheadp->w_toprow, 0); } else{ - for (i = 0; i < term.t_nrow-term.t_mrow; ++i){ + c.c = '\0'; + c.a = 0; + for (i = 0; i < term.t_nrow-term.t_mrow; i++){ vscreen[i]->v_flag |= VFCHG; vp1 = pscreen[i]; - c.c = ' '; - c.a = 0; - for (j = 0; j < term.t_ncol; ++j) + for (j = 0; j < term.t_ncol; j++) vp1->v_text[j] = c; + if(sgarbf == FALSE){ + movecursor(i, 0); + term.t_eeol(); + } + } + if(sgarbf != FALSE){ + movecursor(0, 0); /* Erase the screen. */ + (*term.t_eeop)(); } - - movecursor(0, 0); /* Erase the screen. */ - (*term.t_eeop)(); - } sgarbf = FALSE; /* Erase-page clears */ @@ -915,6 +993,11 @@ updateline(int row, /* row on screen */ int display = TRUE; int nbflag; /* non-blanks to the right flag? */ int cleartoeol = 0; + int in_quote, quote_found = 0, level; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; + COLOR_PAIR *qcolor = NULL, *lastc = NULL; + int first = 1; + int x; /* bit to indicate if we should eXecute a block below */ if(row < 0 || row > term.t_nrow) return; @@ -925,10 +1008,12 @@ updateline(int row, /* row on screen */ cp3 = &vline[term.t_ncol]; /* advance past any common chars at the left */ - while (cp1 != cp3 && cp1[0].c == cp2[0].c && cp1[0].a == cp2[0].a) { + if(!(*flags & (VFSIG|VFNOR|VFQUO)) + && (pcolors == NULL || vline[0].c != ' ')) + while (cp1 != cp3 && cp1[0].c == cp2[0].c && cp1[0].a == cp2[0].a) { ++cp1; ++cp2; - } + } /* This can still happen, even though we only call this routine on changed * lines. A hard update is always done when a line splits, a massive @@ -948,17 +1033,17 @@ updateline(int row, /* row on screen */ cp4 = &pline[term.t_ncol]; if(cellwidth_ptr_to_ptr(cp1, cp3) == cellwidth_ptr_to_ptr(cp2, cp4)) - while (cp3[-1].c == cp4[-1].c && cp3[-1].a == cp4[-1].a) { + while (cp3 != cp1 && cp3[-1].c == cp4[-1].c && cp3[-1].a == cp4[-1].a) { --cp3; --cp4; - if (cp3[0].c != ' ' || cp3[0].a != 0) /* Note if any nonblank */ + if (cp3[0].c != '\0' || cp3[0].a != 0) /* Note if any nonblank */ nbflag = TRUE; /* in right match. */ } cp5 = cp3; if (nbflag == FALSE && TERM_EOLEXIST) { /* Erase to EOL ? */ - while (cp5 != cp1 && cp5[-1].c == ' ' && cp5[-1].a == 0) + while (cp5 != cp1 && cp5[-1].c == '\0' && cp5[-1].a == 0) --cp5; if (cp3-cp5 <= 3) /* Use only if erase is */ @@ -968,7 +1053,13 @@ updateline(int row, /* row on screen */ /* go to start of differences */ movecursor(row, cellwidth_ptr_to_ptr(&vline[0], cp1)); - if (!nbflag) { /* use insert or del char? */ + /* the next code inserts a character or deletes one in the middle + * of a line. However, we do not need this code to work when we + * are using colors that depend on what is inserted/deleted, so + * we defer this work to the code below + */ + x = pcolors && (pcolors->qlcp || pcolors->qllcp || pcolors->qlllcp); + if (!nbflag && x == 0) { /* use insert or del char? */ cp6 = cp3; cp7 = cp4; @@ -1008,9 +1099,20 @@ updateline(int row, /* row on screen */ } } + if(cp1 == cp5 && (*flags & (VFSIG|VFNOR|VFQUO))) + while(cp5 < &vline[term.t_ncol] && cp5->c != '\0') + cp5++; + if(cp1 != cp5 && display){ int w1, w2; + if(pcolors){ + lastc = pico_get_cur_color(); + if(row == 0) + pico_set_colorp(pcolors->tbcp, PSC_NONE); + else if(row < term.t_nrow - 2) + pico_set_colorp((*flags & VFSIG) ? pcolors->sbcp : pcolors->ntcp, PSC_NONE); + } /* * If we need to copy characters from cp1 to cp2 and * we need to display them, then we have to worry about @@ -1072,12 +1174,35 @@ updateline(int row, /* row on screen */ } } + in_quote = 1; + level = -1; while (cp1 != cp5) { /* Ordinary. */ int ww; if(display){ + if(pcolors){ + if(cp1->c != '>' && cp1->c != ' '){ + in_quote = 0; + } else if (in_quote && cp1->c == '>' && pcolors != NULL) + level = (level + 1) % 3; + if(level >= 0){ + if(level == 0) qcolor = pcolors->qlcp; + else if(level == 1) qcolor = pcolors->qllcp; + else if(level == 2) qcolor = pcolors->qlllcp; + pico_set_colorp(qcolor, PSC_NONE); + } + } + + /* cp1->c could be null because we set it up that way by default. Initialization + * is made with null characters. We did this because otherwise Pico does not + * color trailing spaces in lines, so this gives a way for pico to distinguish + * trailing spaces in lines from its own old default initialization of cells + * using spaces. So when we get a null character we output the corresponding + * space that would have been output in the past. If you want to see what + * would happen if we output a null character, rewrite the code below. + */ (*term.t_rev)(cp1->a); /* set inverse for this char */ - (*term.t_putchar)(cp1->c); + (*term.t_putchar)(cp1->c || pcolors == NULL ? cp1->c : ' '); } ww = wcellwidth((UCS) cp1->c); @@ -1086,6 +1211,11 @@ updateline(int row, /* row on screen */ *cp2++ = *cp1++; } + if (pcolors && lastc){ + (void)pico_set_colorp(lastc, PSC_NONE); + free_color_pair(&lastc); + } + (*term.t_rev)(0); /* turn off inverse anyway! */ if (cp5 != cp3 || cleartoeol) { /* Erase. */ @@ -1533,6 +1663,7 @@ mlyesno(UCS *prompt, int dflt) UCS buf[NLINE], lbuf[10]; KEYMENU menu_yesno[12]; COLOR_PAIR *lastc = NULL; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; #ifdef _WINDOWS if (mswin_usedialog ()) @@ -1566,12 +1697,11 @@ mlyesno(UCS *prompt, int dflt) ucs4_strncat(buf, lbuf, NLINE - ucs4_strlen(buf) - 1); buf[NLINE-1] = '\0'; mlwrite(buf, NULL); - if(Pmaster && Pmaster->colors && Pmaster->colors->prcp - && pico_is_good_colorpair(Pmaster->colors->prcp)){ + if(pcolors && pcolors->prcp + && pico_is_good_colorpair(pcolors->prcp)){ lastc = pico_get_cur_color(); - (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE); - } - else + (void) pico_set_colorp(pcolors->prcp, PSC_NONE); + } else (*term.t_rev)(1); rv = -1; @@ -1621,10 +1751,10 @@ mlyesno(UCS *prompt, int dflt) wkeyhelp(menu_yesno); /* paint generic menu */ mlwrite(buf, NULL); - if(Pmaster && Pmaster->colors && Pmaster->colors->prcp - && pico_is_good_colorpair(Pmaster->colors->prcp)){ - lastc = pico_get_cur_color(); - (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE); + if(pcolors && pcolors->prcp + && pico_is_good_colorpair(pcolors->prcp)){ + lastc = pico_get_cur_color(); + (void) pico_set_colorp(pcolors->prcp, PSC_NONE); } else (*term.t_rev)(1); @@ -1769,6 +1899,7 @@ mlreplyd(UCS *prompt, UCS *buf, int nbuf, int flg, EXTRAKEYS *extras) UCS extra_v[12]; struct display_line dline; COLOR_PAIR *lastc = NULL; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; #ifdef _WINDOWS if(mswin_usedialog()){ @@ -1887,10 +2018,10 @@ mlreplyd(UCS *prompt, UCS *buf, int nbuf, int flg, EXTRAKEYS *extras) sgarbk = 1; /* mark menu dirty */ - if(Pmaster && Pmaster->colors && Pmaster->colors->prcp - && pico_is_good_colorpair(Pmaster->colors->prcp)){ - lastc = pico_get_cur_color(); - (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE); + if(pcolors && pcolors->prcp + && pico_is_good_colorpair(pcolors->prcp)){ + lastc = pico_get_cur_color(); + (void) pico_set_colorp(pcolors->prcp, PSC_NONE); } else (*term.t_rev)(1); @@ -1970,10 +2101,10 @@ mlreplyd(UCS *prompt, UCS *buf, int nbuf, int flg, EXTRAKEYS *extras) wkeyhelp(menu_mlreply); /* paint generic menu */ plen = mlwrite(prompt, NULL); /* paint prompt */ - if(Pmaster && Pmaster->colors && Pmaster->colors->prcp - && pico_is_good_colorpair(Pmaster->colors->prcp)){ - lastc = pico_get_cur_color(); - (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE); + if(pcolors && pcolors->prcp + && pico_is_good_colorpair(pcolors->prcp)){ + lastc = pico_get_cur_color(); + (void) pico_set_colorp(pcolors->prcp, PSC_NONE); } else (*term.t_rev)(1); @@ -2154,6 +2285,7 @@ emlwrite_ucs4(UCS *message, EML *eml) UCS *bufp, *ap; int width; COLOR_PAIR *lastc = NULL; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; mlerase(); @@ -2198,10 +2330,10 @@ emlwrite_ucs4(UCS *message, EML *eml) else movecursor(term.t_nrow-term.t_mrow, 0); - if(Pmaster && Pmaster->colors && Pmaster->colors->stcp - && pico_is_good_colorpair(Pmaster->colors->stcp)){ - lastc = pico_get_cur_color(); - (void) pico_set_colorp(Pmaster->colors->stcp, PSC_NONE); + if(pcolors && pcolors->stcp + && pico_is_good_colorpair(pcolors->stcp)){ + lastc = pico_get_cur_color(); + (void) pico_set_colorp(pcolors->stcp, PSC_NONE); } else (*term.t_rev)(1); @@ -2288,6 +2420,7 @@ mlwrite(UCS *fmt, void *arg) UCS c; char *ap; COLOR_PAIR *lastc = NULL; + PCOLORS *pcolors = Pmaster && Pmaster->colors ? Pmaster->colors : Pcolors; /* * the idea is to only highlight if there is something to show @@ -2295,10 +2428,10 @@ mlwrite(UCS *fmt, void *arg) mlerase(); movecursor(ttrow, 0); - if(Pmaster && Pmaster->colors && Pmaster->colors->prcp - && pico_is_good_colorpair(Pmaster->colors->prcp)){ - lastc = pico_get_cur_color(); - (void) pico_set_colorp(Pmaster->colors->prcp, PSC_NONE); + if(pcolors && pcolors->prcp + && pico_is_good_colorpair(pcolors->prcp)){ + lastc = pico_get_cur_color(); + (void) pico_set_colorp(pcolors->prcp, PSC_NONE); } else (*term.t_rev)(1); @@ -2913,7 +3046,7 @@ peeol(void) if(ttrow < 0 || ttrow > term.t_nrow) return; - cl.c = ' '; + cl.c = '\0'; cl.a = 0; /* @@ -3107,10 +3240,13 @@ wstripe(int line, int column, char *utf8pmt, int key) if(klcp && pico_is_good_colorpair(Pmaster->colors->kncp)) kncp = Pmaster->colors->kncp; - - lastc = pico_get_cur_color(); + } + else if(Pcolors){ + klcp = Pcolors->klcp; + kncp = Pcolors->kncp; } + lastc = pico_get_cur_color(); ucs4pmt = utf8_to_ucs4_cpystr(utf8pmt); l = ucs4_strlen(ucs4pmt); while(1){ diff --git a/pico/edef.h b/pico/edef.h index 5d0c115..c8f51c5 100644 --- a/pico/edef.h +++ b/pico/edef.h @@ -31,7 +31,7 @@ /* for MAIN.C */ /* initialized global definitions */ - +PCOLORS *Pcolors = NULL; /* colors for Pico */ int direction = 0; /* direction of writing */ int fillcol = 72; /* Current fill column */ int userfillcol = -1; /* Fillcol set from cmd line */ @@ -89,6 +89,7 @@ void *input_cs; /* passed to mbtow() via kbseq() */ /* initialized global external declarations */ +extern PCOLORS *Pcolors; /* colors for Pico */ extern int direction; extern int fillcol; /* Fill column */ extern int userfillcol; /* Fillcol set from cmd line */ diff --git a/pico/estruct.h b/pico/estruct.h index 9cacc33..6223eff 100644 --- a/pico/estruct.h +++ b/pico/estruct.h @@ -270,6 +270,7 @@ typedef struct CELL { typedef struct LINE { struct LINE *l_fp; /* Link to the next line */ struct LINE *l_bp; /* Link to the previous line */ + int l_sig; /* line is part of signature */ int l_size; /* Allocated size */ int l_used; /* Used size */ CELL l_text[1]; /* A bunch of characters. */ diff --git a/pico/line.c b/pico/line.c index 2e35e93..e353e1f 100644 --- a/pico/line.c +++ b/pico/line.c @@ -90,6 +90,7 @@ lalloc(int used) lp->l_size = size; lp->l_used = used; + lp->l_sig = 0; /* assume it is not a signature line */ return (lp); } diff --git a/pico/main.c b/pico/main.c index bedff18..1123b46 100644 --- a/pico/main.c +++ b/pico/main.c @@ -79,6 +79,9 @@ char *pico_args(int, char **, int *, int *, int *); void pico_args_help(void); void pico_vers_help(void); void pico_display_args_err(char *, char **, int); +PCOLORS *pico_set_global_colors(int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int, int); +void display_color_codes(void); + /* TRANSLATORS: An error message about an unknown flag (option) on the command line */ @@ -130,6 +133,30 @@ N_("\t -cnb color \tbackground color"), N_("\t -crf color \treverse foreground color"), N_("\t -crb color \treverse background color"), #endif /* _WINDOWS */ +N_("\t -color_code \tdisplay number codes for different colors"), +N_("\t -ncolors number \tnumber of colors for screen (8, 16, or 256)"), +N_("\t -ntfc number \tnumber of color of foreground text"), +N_("\t -ntbc number \tnumber of color of the background"), +N_("\t -rtfc number \tnumber of color of reverse text"), +N_("\t -rtbc number \tnumber of color of reverse background"), +N_("\t -tbfc number \tnumber of color of foreground (text) of the title bar"), +N_("\t -tbbc number \tnumber of color of background of the title bar"), +N_("\t -klfc number \tnumber of color of foreground (text) of the key label"), +N_("\t -klbc number \tnumber of color of background of the key label"), +N_("\t -knfc number \tnumber of color of foreground (text) of the key name"), +N_("\t -knbc number \tnumber of color of background of the key name"), +N_("\t -stfc number \tnumber of color of foreground (text) of the status line"), +N_("\t -stbc number \tnumber of color of background of the status line"), +N_("\t -prfc number \tnumber of color of foreground (text) of a prompt"), +N_("\t -prbc number \tnumber of color of background of a prompt"), +N_("\t -q1fc number \tnumber of color of foreground (text) of level one of quoted text"), +N_("\t -q1bc number \tnumber of color of background of level one of quoted text"), +N_("\t -q2fc number \tnumber of color of foreground (text) of level two of quoted text"), +N_("\t -q2bc number \tnumber of color of background of level two of quoted text"), +N_("\t -q3fc number \tnumber of color of foreground (text) of level three of quoted text"), +N_("\t -q3bc number \tnumber of color of background of level three of quoted text"), +N_("\t -sbfc number \tnumber of color of foreground of signature block text"), +N_("\t -sbbc number \tnumber of color of background of signature block text"), N_("\t +[line#] \tLine - start on line# line, default=1"), N_("\t -v \t\tView - view file"), N_("\t -no_setlocale_collate\tdo not do setlocale(LC_COLLATE)"), @@ -287,6 +314,7 @@ main(int argc, char *argv[]) edinit(bname); /* Buffers, windows. */ update(); /* let the user know we are here */ + sgarbf = TRUE; /* next update, repaint all */ #ifdef _WINDOWS mswin_setwindow(NULL, NULL, NULL, NULL, NULL, NULL); @@ -381,12 +409,13 @@ main(int argc, char *argv[]) peeol(); } - update(); /* Fix up the screen */ if(km_popped){ term.t_mrow = 0; curwp->w_ntrows += 2; } + update(); /* Fix up the screen */ + #ifdef MOUSE #ifdef EX_MOUSE /* New mouse function for real mouse text seletion. */ @@ -452,6 +481,137 @@ main(int argc, char *argv[]) } } +void +display_color_codes(void) +{ +#define SPACES " " + int i, j, k, l, a, len, len_entry, row; + int ncolors; + COLOR_PAIR *lastc = NULL, *newcp; + char *fg; + + /* this is the format "SPACE COLORED_SPACES = CODE SPACE" */ + vtterminalinfo(gmode & MDTCAPWINS); + (*term.t_open)(); + (*term.t_rev)(FALSE); + + pico_toggle_color(1); + if((ncolors = pico_count_in_color_table()) <= 0){ + fprintf(stderr, "%s", "Your screen does not support colors\r\n"); + exit(1); + } + + + if(term.t_ncol < 62 || term.t_nrow < 23){ + fprintf(stderr, "%s", "Screen must have at least 24 rows and 63 columns\r\n"); + exit(1); + } + + + fprintf(stdout, "%s", "The code of a color is the number in the same row plus\r\n"); + fprintf(stdout, "%s", "the number in the same column as that color.\r\n\r\n"); + + lastc = pico_get_cur_color(); + switch(ncolors){ + case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break; + case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break; + case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break; + default : fprintf(stderr, "Unknown number of colors %d\n", ncolors); + exit(1); + break; + } + + if(ncolors != 256){ + for(k = -1; 16*k < ncolors; k++){ + for(l = -1; l < ncolors; l++){ + if(k == -1){ + if(ncolors == 8){ + if(l == -1) + fprintf(stdout, "%s", " "); + else + fprintf(stdout, "%3d", l); + } + } + else{ + if(l == -1){ + pico_toggle_color(1); + fprintf(stdout, "%3d ", k); + } + else{ + if(ncolors || l < 8){ + i = 16*k + l; + newcp = new_color_pair(colorx(0), colorx(i)); + pico_set_colorp(newcp, PSC_NONE); + fprintf(stdout, "%s", SPACES); + pico_set_colorp(lastc, PSC_NONE); + } + } + } + } + pico_toggle_color(0); + if(k == 0) + fprintf(stdout, " (%d colors)", ncolors); + if(k != -1 || ncolors == 8) + fprintf(stdout, "%s", "\r\n"); + } + } else { + fprintf(stdout, "%s", "Codes for terminal with 256 colors:\r\n"); + a = 16; + for(k = -1; 36*k < ncolors; k++){ + for(l = -1; l < ncolors && l < 16; l++){ + if(k == -1){ + if(l == -1) + fprintf(stdout, "%s", " "); + else + fprintf(stdout, "%3d", l); + } + else{ + if(l == -1){ + pico_toggle_color(1); + fprintf(stdout, "%3d ", 36*k); + } + else{ + i = 36*k + l; + newcp = new_color_pair(colorx(0), colorx(i)); + pico_set_colorp(newcp, PSC_NONE); + fprintf(stdout, "%s", SPACES); + pico_set_colorp(lastc, PSC_NONE); + } + } + } + pico_toggle_color(0); + fprintf(stdout, "%s", "\r\n"); + } + a = 20; + for(k = -1; 16 + 36*k < ncolors; k++){ + for(l = -1; l < ncolors && l < a; l++){ + if(k == -1){ + if(l == -1) + fprintf(stdout, "%s", " "); + else + fprintf(stdout, "%3d", l); + } + else{ + if(l == -1){ + pico_toggle_color(1); + fprintf(stdout, "%3d ", 16 + 36*k); + } + else{ + i = 16 + 36*k + l; + newcp = new_color_pair(colorx(0), colorx(i)); + pico_set_colorp(newcp, PSC_NONE); + fprintf(stdout, "%s", SPACES); + pico_set_colorp(lastc, PSC_NONE); + } + } + } + pico_toggle_color(0); + fprintf(stdout, "%s", "\r\n"); + } + } + pico_set_colorp(lastc, PSC_NONE); +} + /* * Parse the command line args. @@ -472,7 +632,14 @@ pico_args(int ac, char **av, int *starton, int *viewflag, int *setlocale_collate int c, usage = 0; char *str; char tmp_1k_buf[1000]; /* tmp buf to contain err msgs */ - + int ncolors, ntfc, ntbc, rtfc, rtbc; + int tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc; + int q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc; + + ncolors = 0; + ntfc = ntbc = rtfc = rtbc = tbfc = tbbc = klfc = klbc = knfc = + knbc = stfc = stbc = prfc = prbc = q1fc = q1bc = q2fc = q2bc = + q3fc = q3bc = sbfc = sbbc = -1; Loop: /* while more arguments with leading - or + */ while(--ac > 0 && (**++av == '-' || **av == '+')){ @@ -506,6 +673,84 @@ Loop: if(strcmp(*av, "version") == 0){ pico_vers_help(); } + else if(strcmp(*av, "ntfc") == 0 + || strcmp(*av, "ntbc") == 0 + || strcmp(*av, "rtfc") == 0 + || strcmp(*av, "rtbc") == 0 + || strcmp(*av, "tbfc") == 0 + || strcmp(*av, "tbbc") == 0 + || strcmp(*av, "klfc") == 0 + || strcmp(*av, "klbc") == 0 + || strcmp(*av, "knfc") == 0 + || strcmp(*av, "knbc") == 0 + || strcmp(*av, "stfc") == 0 + || strcmp(*av, "stbc") == 0 + || strcmp(*av, "prfc") == 0 + || strcmp(*av, "prbc") == 0 + || strcmp(*av, "q1fc") == 0 + || strcmp(*av, "q1bc") == 0 + || strcmp(*av, "q2fc") == 0 + || strcmp(*av, "q2bc") == 0 + || strcmp(*av, "q3fc") == 0 + || strcmp(*av, "q3bc") == 0 + || strcmp(*av, "sbfc") == 0 + || strcmp(*av, "sbbc") == 0 + || strcmp(*av, "ncolors") == 0){ + str = *av; + if(--ac) + ++av; + else{ + snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_arg), '-'); + pico_display_args_err(tmp_1k_buf, NULL, 1); + usage++; + goto Loop; + } + + if(!isdigit((unsigned char)**av)){ + snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _(args_pico_missing_num), '-'); + pico_display_args_err(tmp_1k_buf, NULL, 1); + usage++; + } + if(strcmp(str, "ntfc") == 0) ntfc = atoi(*av); + else if (strcmp(str, "ntbc") == 0) ntbc = atoi(*av); + else if (strcmp(str, "rtfc") == 0) rtfc = atoi(*av); + else if (strcmp(str, "rtbc") == 0) rtbc = atoi(*av); + else if (strcmp(str, "tbfc") == 0) tbfc = atoi(*av); + else if (strcmp(str, "tbbc") == 0) tbbc = atoi(*av); + else if (strcmp(str, "klfc") == 0) klfc = atoi(*av); + else if (strcmp(str, "klbc") == 0) klbc = atoi(*av); + else if (strcmp(str, "knfc") == 0) knfc = atoi(*av); + else if (strcmp(str, "knbc") == 0) knbc = atoi(*av); + else if (strcmp(str, "stfc") == 0) stfc = atoi(*av); + else if (strcmp(str, "stbc") == 0) stbc = atoi(*av); + else if (strcmp(str, "prfc") == 0) prfc = atoi(*av); + else if (strcmp(str, "prbc") == 0) prbc = atoi(*av); + else if (strcmp(str, "q1fc") == 0) q1fc = atoi(*av); + else if (strcmp(str, "q1bc") == 0) q1bc = atoi(*av); + else if (strcmp(str, "q2fc") == 0) q2fc = atoi(*av); + else if (strcmp(str, "q2bc") == 0) q2bc = atoi(*av); + else if (strcmp(str, "q3fc") == 0) q3fc = atoi(*av); + else if (strcmp(str, "q3bc") == 0) q3bc = atoi(*av); + else if (strcmp(str, "sbfc") == 0) sbfc = atoi(*av); + else if (strcmp(str, "sbbc") == 0) sbbc = atoi(*av); + else if (strcmp(str, "ncolors") == 0) ncolors = atoi(*av); + if(!strcmp(str, "ncolors")){ + switch(ncolors){ + case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break; + case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break; + case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break; + default : snprintf(tmp_1k_buf, sizeof(tmp_1k_buf), _("Unsupported number of colors: %d"), ncolors); + pico_display_args_err(tmp_1k_buf, NULL, 1); + exit(1); + break; + } + } + goto Loop; + } + else if(strcmp(*av, "color_codes") == 0){ + display_color_codes(); + exit(0); + } else if(strcmp(*av, "no_setlocale_collate") == 0){ *setlocale_collate = 0; goto Loop; @@ -727,6 +972,10 @@ Loop: if(usage) pico_args_help(); + Pcolors = pico_set_global_colors(ncolors, ntfc, ntbc, rtfc, rtbc, + tbfc, tbbc, klfc, klbc, knfc, knbc, stfc, stbc, prfc, prbc, + q1fc, q1bc, q2fc, q2bc, q3fc, q3bc, sbfc, sbbc); + /* return the first filename for editing */ if(ac > 0) return(*av); @@ -735,6 +984,127 @@ Loop: } +PCOLORS * +pico_set_global_colors(int nc, int ntfg, int ntbg, int rtfg, int rtbg, + int tbfg, int tbbg, int klfg, int klbg, + int knfg, int knbg, int stfg, int stbg, int prfg, int prbg, + int q1fg, int q1bg, int q2fg, int q2bg, int q3fg, int q3bg, + int sbfg, int sbbg) +{ + PCOLORS *pcolors = NULL; + char *fg, *bg; + + if(nc != 0 && nc != 8 && nc != 16 && nc != 256){ + fprintf(stderr, "number of colors must be either 8, 16 or 256\n"); + exit(1); + } + + if(nc == 0){ + if(ntfg != -1 || ntbg != -1 || tbfg != -1 || tbbg != -1 || + klfg != -1 || klbg != -1 || knfg != -1 || knbg != -1 || + stfg != -1 || stbg != -1 || prfg != -1 || prbg != -1 || + q1fg != -1 || q1bg != -1 || q2fg != -1 || q1bg != -1 || + q3fg != -1 || q3bg != -1 || sbfg != -1 || sbbg != -1 || + rtfg != -1 || rtbg != -1){ + fprintf(stderr, "can not specify color numbers without specifying number of colors\n"); + exit(1); + } + else + return pcolors; /* no colors used */ + } + + if(ntfg >= nc || ntbg >= nc || tbfg >= nc || tbbg >= nc + || klfg >= nc || klbg >= nc || knfg >= nc || knbg >= nc + || stfg >= nc || stbg >= nc || prfg >= nc || prbg >= nc + || q1fg >= nc || q1bg >= nc || q2fg >= nc || q2bg >= nc + || q3fg >= nc || q3bg >= nc || sbfg >= nc || sbbg >= nc + || rtfg >= nc || rtbg >= nc){ + fprintf(stderr, "Error: specified a color bigger than number of colors\n"); + exit(1); + } + + /* Finally, we set up colors */ + pico_toggle_color(0); + switch(nc){ + case 8: pico_set_color_options(COLOR_ANSI8_OPT|COLOR_TRANS_OPT); break; + case 16: pico_set_color_options(COLOR_ANSI16_OPT|COLOR_TRANS_OPT); break; + case 256: pico_set_color_options(COLOR_ANSI256_OPT|COLOR_TRANS_OPT); break; + default : break; /* impossible case */ + } + pico_toggle_color(1); + + pcolors = (PCOLORS *) malloc(sizeof(PCOLORS)); + memset((void *)pcolors, 0, sizeof(PCOLORS)); + /* ignore bad pair settings, also we set tbcp backwards because it will + * be reversed later in the modeline function, so tbcp->fg is actually + * tbcp->bg and viceversa. + */ + if(ntfg >= 0 && ntbg >= 0){ /* set normal text color */ + fg = colorx(ntfg); bg = colorx(ntbg); + pcolors->ntcp = new_color_pair(fg, bg); + pico_nfcolor(fg); + pico_nbcolor(bg); + } + /* reverse means reverse of normal text */ + if((rtfg < 0 || rtbg < 0) && (ntfg >= 0 && ntbg >= 0)){ + rtfg = ntbg; + rtbg = ntfg; + } + if(rtfg >= 0 && rtbg >= 0){ /* set reverse text color */ + fg = colorx(rtfg); bg = colorx(rtbg); + pcolors->rtcp = new_color_pair(fg, bg); + pico_rfcolor(fg); + pico_rbcolor(bg); + } + /* If the user does not specify this, we will set up all + * backgrounds for text to the normal text background + */ + if(ntbg >= 0){ + if(knbg < 0) knbg = ntbg; + if(q1bg < 0) q1bg = ntbg; + if(q2bg < 0) q2bg = ntbg; + if(q3bg < 0) q3bg = ntbg; + if(sbbg < 0) sbbg = ntbg; + } + if(rtfg >= 0 && rtbg >= 0){ /* set default reverse */ + if(tbfg < 0 || tbbg < 0){ /* set titlebar colors to reverse color if any missing*/ + tbfg = rtfg; tbbg = rtbg; + } + if(klfg < 0 || klbg < 0){ /* set key label colors */ + klfg = rtfg; klbg = rtbg; + } + if(stfg < 0 || stbg < 0){ /* set status colors */ + stfg = rtfg; stbg = rtbg; + } + if(prfg >= 0 && prbg >= 0){ /* set prompt colors */ + prfg = rtfg; prbg = rtbg; + } + } + if(tbfg >= 0 && tbbg >= 0) /* set titlebar colors */ + pcolors->tbcp = new_color_pair(colorx(tbbg), colorx(tbfg)); + if(klfg >= 0 && klbg >= 0) /* set key label colors */ + pcolors->klcp = new_color_pair(colorx(klfg), colorx(klbg)); + if(knfg >= 0 && knbg >= 0) /* set key name colors */ + pcolors->kncp = new_color_pair(colorx(knfg), colorx(knbg)); + if(stfg >= 0 && stbg >= 0) /* set status colors */ + pcolors->stcp = new_color_pair(colorx(stfg), colorx(stbg)); + if(prfg >= 0 && prbg >= 0) /* set prompt colors */ + pcolors->prcp = new_color_pair(colorx(prfg), colorx(prbg)); + if(q1fg >= 0 && q1bg >= 0) /* set quote level 1 colors */ + pcolors->qlcp = new_color_pair(colorx(q1fg), colorx(q1bg)); + if(q2fg >= 0 && q2bg >= 0) /* set quote level 2 colors */ + pcolors->qllcp = new_color_pair(colorx(q2fg), colorx(q2bg)); + if(q3fg >= 0 && q3bg >= 0) /* set quote level 3 colors */ + pcolors->qlllcp = new_color_pair(colorx(q3fg), colorx(q3bg)); + if(sbfg >= 0 && sbbg >= 0) /* set signature block colors */ + pcolors->sbcp = new_color_pair(colorx(sbfg), colorx(sbbg)); + + if(pico_usingcolor()) + pico_set_normal_color(); + + return pcolors; +} + #ifdef _WINDOWS /* * diff --git a/pico/pico.h b/pico/pico.h index b755244..b3509a0 100644 --- a/pico/pico.h +++ b/pico/pico.h @@ -159,11 +159,17 @@ typedef struct pico_atmt { * Structure to contain color options */ typedef struct pico_colors { + COLOR_PAIR *ntcp; /* normal text color pair */ + COLOR_PAIR *rtcp; /* reverse text color pair */ COLOR_PAIR *tbcp; /* title bar color pair */ COLOR_PAIR *klcp; /* key label color pair */ COLOR_PAIR *kncp; /* key name color pair */ COLOR_PAIR *stcp; /* status color pair */ COLOR_PAIR *prcp; /* prompt color pair */ + COLOR_PAIR *qlcp; /* quote level 1 pair */ + COLOR_PAIR *qllcp; /* quote level 2 pair */ + COLOR_PAIR *qlllcp; /* quote level 3 pair */ + COLOR_PAIR *sbcp; /* signature block color pair */ } PCOLORS; /* diff --git a/pith/pine.hlp b/pith/pine.hlp index 85c67d9..f767cf0 100644 --- a/pith/pine.hlp +++ b/pith/pine.hlp @@ -140,7 +140,7 @@ with help text for the config screen and the composer that didn't have any reasonable place to be called from. Dummy change to get revision in pine.hlp ============= h_revision ================= -Alpine Commit 176 2016-10-08 20:07:39 +Alpine Commit 177 2016-10-22 00:32:52 ============= h_news ================= -- 2.11.4.GIT