tterm.c - neatvi - [fork] simple vi-type editor with UTF-8 support
git clone git://src.adamsgaard.dk/neatvi
Log
Files
Refs
README
---
tterm.c (3557B)
---
     1 #include 
     2 #include 
     3 #include 
     4 #include 
     5 #include 
     6 #include 
     7 #include 
     8 #include 
     9 #include "vi.h"
    10 
    11 static struct sbuf *term_sbuf;
    12 static int rows, cols;
    13 static struct termios termios;
    14 
    15 void term_init(void)
    16 {
    17         struct winsize win;
    18         struct termios newtermios;
    19         tcgetattr(0, &termios);
    20         newtermios = termios;
    21         newtermios.c_lflag &= ~(ICANON | ISIG);
    22         newtermios.c_lflag &= ~ECHO;
    23         tcsetattr(0, TCSAFLUSH, &newtermios);
    24         if (getenv("LINES"))
    25                 rows = atoi(getenv("LINES"));
    26         if (getenv("COLUMNS"))
    27                 cols = atoi(getenv("COLUMNS"));
    28         if (!ioctl(0, TIOCGWINSZ, &win)) {
    29                 cols = win.ws_col;
    30                 rows = win.ws_row;
    31         }
    32         cols = cols ? cols : 80;
    33         rows = rows ? rows : 25;
    34         term_str("\33[m");
    35 }
    36 
    37 void term_done(void)
    38 {
    39         term_commit();
    40         tcsetattr(0, 0, &termios);
    41 }
    42 
    43 void term_suspend(void)
    44 {
    45         term_done();
    46         kill(getpid(), SIGSTOP);
    47         term_init();
    48 }
    49 
    50 void term_record(void)
    51 {
    52         if (!term_sbuf)
    53                 term_sbuf = sbuf_make();
    54 }
    55 
    56 void term_commit(void)
    57 {
    58         if (term_sbuf) {
    59                 write(1, sbuf_buf(term_sbuf), sbuf_len(term_sbuf));
    60                 sbuf_free(term_sbuf);
    61                 term_sbuf = NULL;
    62         }
    63 }
    64 
    65 static void term_out(char *s)
    66 {
    67         if (term_sbuf)
    68                 sbuf_str(term_sbuf, s);
    69         else
    70                 write(1, s, strlen(s));
    71 }
    72 
    73 void term_str(char *s)
    74 {
    75         term_out(s);
    76 }
    77 
    78 void term_chr(int ch)
    79 {
    80         char s[4] = {ch};
    81         term_out(s);
    82 }
    83 
    84 void term_kill(void)
    85 {
    86         term_out("\33[K");
    87 }
    88 
    89 void term_room(int n)
    90 {
    91         char cmd[16];
    92         if (n < 0)
    93                 sprintf(cmd, "\33[%dM", -n);
    94         if (n > 0)
    95                 sprintf(cmd, "\33[%dL", n);
    96         if (n)
    97                 term_out(cmd);
    98 }
    99 
   100 void term_pos(int r, int c)
   101 {
   102         char buf[32] = "\r";
   103         if (c < 0)
   104                 c = 0;
   105         if (c >= xcols)
   106                 c = cols - 1;
   107         if (r < 0)
   108                 sprintf(buf, "\r\33[%d%c", abs(c), c > 0 ? 'C' : 'D');
   109         else
   110                 sprintf(buf, "\33[%d;%dH", r + 1, c + 1);
   111         term_out(buf);
   112 }
   113 
   114 int term_rows(void)
   115 {
   116         return rows;
   117 }
   118 
   119 int term_cols(void)
   120 {
   121         return cols;
   122 }
   123 
   124 static char ibuf[4096];                /* input character buffer */
   125 static char icmd[4096];                /* read after the last term_cmd() */
   126 static int ibuf_pos, ibuf_cnt;        /* ibuf[] position and length */
   127 static int icmd_pos;                /* icmd[] position */
   128 
   129 /* read s before reading from the terminal */
   130 void term_push(char *s, int n)
   131 {
   132         n = MIN(n, sizeof(ibuf) - ibuf_cnt);
   133         memcpy(ibuf + ibuf_cnt, s, n);
   134         ibuf_cnt += n;
   135 }
   136 
   137 /* return a static buffer containing inputs read since the last term_cmd() */
   138 char *term_cmd(int *n)
   139 {
   140         *n = icmd_pos;
   141         icmd_pos = 0;
   142         return icmd;
   143 }
   144 
   145 int term_read(void)
   146 {
   147         struct pollfd ufds[1];
   148         int n, c;
   149         if (ibuf_pos >= ibuf_cnt) {
   150                 ufds[0].fd = 0;
   151                 ufds[0].events = POLLIN;
   152                 if (poll(ufds, 1, -1) <= 0)
   153                         return -1;
   154                 /* read a single input character */
   155                 if ((n = read(0, ibuf, 1)) <= 0)
   156                         return -1;
   157                 ibuf_cnt = n;
   158                 ibuf_pos = 0;
   159         }
   160         c = ibuf_pos < ibuf_cnt ? (unsigned char) ibuf[ibuf_pos++] : -1;
   161         if (icmd_pos < sizeof(icmd))
   162                 icmd[icmd_pos++] = c;
   163         return c;
   164 }
   165 
   166 /* return a static string that changes text attributes from old to att */
   167 char *term_att(int att, int old)
   168 {
   169         static char buf[128];
   170         char *s = buf;
   171         int fg = SYN_FG(att);
   172         int bg = SYN_BG(att);
   173         if (att == old)
   174                 return "";
   175         s += sprintf(s, "\33[");
   176         if (att & SYN_BD)
   177                 s += sprintf(s, ";1");
   178         if (att & SYN_IT)
   179                 s += sprintf(s, ";3");
   180         else if (att & SYN_RV)
   181                 s += sprintf(s, ";7");
   182         if (SYN_FGSET(att)) {
   183                 if ((fg & 0xff) < 8)
   184                         s += sprintf(s, ";%d", 30 + (fg & 0xff));
   185                 else
   186                         s += sprintf(s, ";38;5;%d", (fg & 0xff));
   187         }
   188         if (SYN_BGSET(att)) {
   189                 if ((bg & 0xff) < 8)
   190                         s += sprintf(s, ";%d", 40 + (bg & 0xff));
   191                 else
   192                         s += sprintf(s, ";48;5;%d", (bg & 0xff));
   193         }
   194         s += sprintf(s, "m");
   195         return buf;
   196 }