[BACK]Return to mail.c CVS log [TXT][DIR] Up to [local] / src / usr.bin / mg

Annotation of src/usr.bin/mg/mail.c, Revision 1.4

1.4     ! vincent     1: /* $OpenBSD: mail.c,v 1.3 2004/01/27 23:43:37 vincent Exp $ */
1.1       vincent     2: /*
                      3:  * This file is in the public domain.
                      4:  *
                      5:  * Author: Vincent Labrecque, April 2003
                      6:  */
                      7: #include <ctype.h>
                      8:
                      9: #include "def.h"
                     10: #include "kbd.h"
                     11: #include "funmap.h"
                     12:
                     13: static int      fake_self_insert(int, int);
                     14: static int      mail(int, int);
                     15:
1.3       vincent    16: int limit = 72;
                     17:
1.1       vincent    18: /* mappings for all "printable" characters ('-' -> '~') */
                     19: static PF mail_fake[] = {
                     20:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     21:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     22:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     23:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     24:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     25:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     26:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     27:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     28:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     29:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     30:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     31:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     32:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     33:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     34:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     35:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     36:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     37:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     38:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     39:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     40:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     41:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
                     42:        fake_self_insert, fake_self_insert, fake_self_insert, fake_self_insert,
1.3       vincent    43:        fake_self_insert, fake_self_insert, fake_self_insert
1.1       vincent    44: };
                     45:
                     46: static struct KEYMAPE (1 + IMAPEXT) mailmap = {
                     47:        1,
                     48:        1 + IMAPEXT,
                     49:        rescan,
                     50:        {
                     51:                { ' ', '~', mail_fake, NULL },
                     52:        }
                     53: };
                     54:
1.3       vincent    55: int
                     56: mail_set_limit(int f, int n)
                     57: {
1.4     ! vincent    58:        char buf[32], *rep;
1.3       vincent    59:
                     60:        if ((f & FFARG) != 0) {
                     61:                limit = n;
                     62:        } else {
1.4     ! vincent    63:                if ((rep = ereply("Margin: ", buf, sizeof(buf))) == NULL)
        !            64:                        return ABORT;
        !            65:                else if (*rep == '\0')
        !            66:                        return FALSE;
        !            67:                limit = atoi(rep);
1.3       vincent    68:        }
                     69:        return TRUE;
                     70: }
                     71:
1.1       vincent    72: void
                     73: mail_init(void)
                     74: {
                     75:        funmap_add(mail, "mail-mode");
1.3       vincent    76:        funmap_add(mail_set_limit, "mail-set-margin");
1.1       vincent    77:        maps_add((KEYMAP *)&mailmap, "mail-mode");
                     78: }
                     79:
                     80: static int
                     81: mail(int f, int n)
                     82: {
                     83:        curbp->b_modes[0] = name_mode("fundamental");
                     84:        curbp->b_modes[1] = name_mode("mail-mode");
                     85:        if (curbp->b_modes[1] == NULL) {
                     86:                panic("can't happen");
                     87:                mail_init();
                     88:                curbp->b_modes[1] = name_mode("mail-mode");
                     89:        }
                     90:        curbp->b_nmodes = 1;
1.2       vincent    91:        curwp->w_flag |= WFMODE;
1.1       vincent    92:        return (TRUE);
                     93: }
                     94:
                     95: static int
                     96: fake_self_insert(int f, int n)
                     97: {
1.3       vincent    98:        int len = llength(curwp->w_dotp), col;
1.1       vincent    99:
1.3       vincent   100:        if (len + 1 > limit) {
1.1       vincent   101:                /*
1.3       vincent   102:                 * find the column at which we should cut, taking
                    103:                 * word boundaries into account
1.1       vincent   104:                 */
1.3       vincent   105:                for (col = limit; col > 0; col--)
                    106:                        if (isspace(curwp->w_dotp->l_text[col])) {
                    107:                                col++;  /* XXX - skip the space */
                    108:                                break;
                    109:                        }
                    110:
                    111:                if (curbp->b_doto == len) {
                    112:                        /*
                    113:                         * user is appending to the line; simple case.
                    114:                         */
                    115:                        if (col) {
                    116:                                curwp->w_doto = col;
                    117:                                lnewline();
                    118:                                gotoeol(0, 1);
                    119:                        }
                    120:                        curwp->w_wrapline = NULL;
                    121:                } else if ((len - col) > 0) {
                    122:                        /*
                    123:                         * user is shifting words by inserting in the middle.
                    124:                         */
                    125:                        const char *trail;
                    126:                        int save_doto = curwp->w_doto;
                    127:                        LINE *save_dotp = curwp->w_dotp;
                    128:                        int tlen = len - col;
                    129:
                    130:                        trail = curwp->w_dotp->l_text + col;
                    131:
                    132:                        /*
                    133:                         * Create a new line or reuse the last wrapping line
                    134:                         * unless we could fill it.
                    135:                         */
                    136:                        if (curwp->w_wrapline != lforw(curwp->w_dotp) ||
                    137:                            llength(curwp->w_wrapline) + tlen >= limit) {
                    138:                                curwp->w_doto = col;
                    139:                                lnewline();
                    140:                                curwp->w_wrapline = curwp->w_dotp;
                    141:                                curwp->w_dotp = save_dotp;
                    142:                        } else {
                    143:                                curwp->w_dotp = curwp->w_wrapline;
                    144:                                curwp->w_doto = 0;
                    145:
                    146:                                /* insert trail */
                    147:                                linsert_str(trail, tlen);
                    148:
                    149:                                /* delete trail */
                    150:                                curwp->w_dotp = save_dotp;
                    151:                                curwp->w_doto = col;
                    152:                                ldelete(tlen, KNONE);   /* don't store in kill ring */
                    153:                        }
                    154:
                    155:                        /*
                    156:                         * readjust dot to point at where the user expects
                    157:                         * it to be after an insertion.
                    158:                         */
                    159:                        curwp->w_doto = save_doto;
                    160:                        if (curwp->w_doto >= col) {
                    161:                                curwp->w_dotp = curwp->w_wrapline;
                    162:                                curwp->w_doto -= col;
                    163:                        }
                    164:                }
1.1       vincent   165:        }
                    166:        selfinsert(f, n);
                    167:        return (TRUE);
                    168: }