├── .gitignore ├── History.md ├── Makefile ├── Readme.md ├── example.c ├── package.json ├── src ├── term.c └── term.h └── test.c /.gitignore: -------------------------------------------------------------------------------- 1 | test 2 | -------------------------------------------------------------------------------- /History.md: -------------------------------------------------------------------------------- 1 | 2 | 0.0.2 / 2013-01-25 3 | ================== 4 | 5 | * use stdout fd instead of stdin for term_size() 6 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | 2 | test: test.c src/term.c 3 | $(CC) $^ -o $@ 4 | 5 | example: example.c src/term.c 6 | $(CC) -std=c99 $^ -o $@ 7 | 8 | .PHONY: test example -------------------------------------------------------------------------------- /Readme.md: -------------------------------------------------------------------------------- 1 | 2 | # term.c 3 | 4 | Terminal goodies. 5 | 6 | ## Example 7 | 8 | Check out ./example.c: 9 | 10 | ![](http://f.cl.ly/items/2q2S3s3g0E122N0O2521/Screen%20Shot%202012-07-03%20at%2011.27.19%20PM.png) 11 | 12 | ## Installation 13 | 14 | Install with [clib](https://github.com/clibs/clib): 15 | 16 | ``` 17 | $ clib install clibs/term 18 | ``` 19 | 20 | ## API 21 | 22 | ```c 23 | 24 | // aliases 25 | 26 | #define term_bold term_bright 27 | #define term_clear term_erase 28 | 29 | // display 30 | 31 | #define term_reset() term_write("0m") 32 | #define term_bright() term_write("1m") 33 | #define term_dim() term_write("2m") 34 | #define term_underline() term_write("4m") 35 | #define term_blink() term_write("5m") 36 | #define term_reverse() term_write("7m") 37 | #define term_hidden() term_write("8m") 38 | 39 | // cursor 40 | 41 | #define term_hide_cursor() term_write("?25l") 42 | #define term_show_cursor() term_write("?25h") 43 | 44 | // size 45 | 46 | int 47 | term_size(int *width, int *height); 48 | 49 | // movement 50 | 51 | void 52 | term_move_by(int x, int y); 53 | 54 | void 55 | term_move_to(int x, int y); 56 | 57 | // erasing 58 | 59 | const char * 60 | term_erase_from_name(const char *name); 61 | 62 | int 63 | term_erase(const char *name); 64 | 65 | // colors 66 | 67 | int 68 | term_color_from_name(const char *name); 69 | 70 | int 71 | term_color(const char *name); 72 | 73 | int 74 | term_background(const char *name); 75 | ``` 76 | -------------------------------------------------------------------------------- /example.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include "src/term.h" 7 | 8 | void 9 | on_sigint(int sig) { 10 | term_clear("screen"); 11 | term_show_cursor(); 12 | exit(1); 13 | } 14 | 15 | void 16 | show(float data[]) { 17 | int pad = 4; 18 | int n = 0; 19 | 20 | int w, h; 21 | term_size(&w, &h); 22 | 23 | // clear 24 | term_clear("screen"); 25 | 26 | // y-axis 27 | term_move_to(pad, 1); 28 | while (n < (h - pad - 1)) { 29 | term_move_by(0, 2); 30 | term_color("grey"); 31 | printf("․"); 32 | n += 2; 33 | } 34 | 35 | // x-axis 36 | n = 0; 37 | term_move_to(pad, h - 2); 38 | while (n < (w - pad * 3)) { 39 | term_color("grey"); 40 | printf("․"); 41 | term_move_by(6, 0); 42 | n += 6; 43 | } 44 | 45 | // plot data 46 | 47 | int x = 0; 48 | for (int i = 0; -1 != data[i]; ++i) { 49 | float y = data[i]; 50 | while (y--) { 51 | term_move_to(x * 6 + pad, y - h + pad); 52 | term_reset(); 53 | printf("█"); 54 | } 55 | x++; 56 | } 57 | 58 | term_move_to(w, h - 1); 59 | 60 | // flush 61 | printf("\n"); 62 | } 63 | 64 | int 65 | main(int argc, char **argv){ 66 | term_hide_cursor(); 67 | signal(SIGINT, on_sigint); 68 | 69 | start: 70 | { 71 | float data[] = { 0, 2, 3, 5, 3, 7, 3, 8, 10, 12, 4, 2, 4, 3, -1 }; 72 | show(data); 73 | sleep(1); 74 | } 75 | 76 | { 77 | float data[] = { 0, 2, 3, 1, 3, 3, 3, 8, 2, 12, 4, 2, 4, 3, -1 }; 78 | show(data); 79 | sleep(1); 80 | } 81 | 82 | { 83 | float data[] = { 0, 0, 1, 2, 3, 7, 3, 8, 2, 12, 2, 2, 1, 3, -1 }; 84 | show(data); 85 | sleep(1); 86 | goto start; 87 | } 88 | 89 | return 0; 90 | } -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "term", 3 | "version": "0.0.2", 4 | "repo": "clibs/term", 5 | "description": "Terminal ansi escape goodies", 6 | "keywords": ["terminal", "term", "tty", "ansi", "escape", "colors", "console"], 7 | "license": "MIT", 8 | "src": ["src/term.c", "src/term.h"] 9 | } 10 | -------------------------------------------------------------------------------- /src/term.c: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // term.c 4 | // 5 | // Copyright (c) 2012 TJ Holowaychuk 6 | // 7 | 8 | #include 9 | #include 10 | #include 11 | #include "term.h" 12 | 13 | /* 14 | * X pos. 15 | */ 16 | 17 | static int _x = 0; 18 | 19 | /* 20 | * Y pos. 21 | */ 22 | 23 | static int _y = 0; 24 | 25 | /* 26 | * Move to `(x, y)`. 27 | */ 28 | 29 | void 30 | term_move_to(int x, int y) { 31 | _x = x; 32 | _y = y; 33 | printf("\e[%d;%d;f", y, x); 34 | } 35 | 36 | /* 37 | * Move by `(x, y)`. 38 | */ 39 | 40 | void 41 | term_move_by(int x, int y) { 42 | term_move_to(_x + x, _y + y); 43 | } 44 | 45 | /* 46 | * Set `w` and `h` to the terminal dimensions. 47 | */ 48 | 49 | int 50 | term_size(int *w, int *h) { 51 | struct winsize ws; 52 | int ret = ioctl(1, TIOCGWINSZ, &ws); 53 | if (ret < 0) return ret; 54 | *w = ws.ws_col; 55 | *h = ws.ws_row; 56 | return 0; 57 | } 58 | 59 | /* 60 | * Return the erase code for `name` or -1. 61 | */ 62 | 63 | const char * 64 | term_erase_from_name(const char *name) { 65 | if (!strcmp("end", name)) return "K"; 66 | if (!strcmp("start", name)) return "1K"; 67 | if (!strcmp("line", name)) return "2K"; 68 | if (!strcmp("up", name)) return "1J"; 69 | if (!strcmp("down", name)) return "J"; 70 | if (!strcmp("screen", name)) return "1J"; 71 | return NULL; 72 | } 73 | 74 | /* 75 | * Erase with `name`: 76 | * 77 | * - "end" 78 | * - "start" 79 | * - "line" 80 | * - "up" 81 | * - "down" 82 | * - "screen" 83 | * 84 | */ 85 | 86 | int 87 | term_erase(const char *name) { 88 | const char *s = term_erase_from_name(name); 89 | if (!s) return -1; 90 | printf("\e[%s", s); 91 | return 0; 92 | } 93 | 94 | /* 95 | * Return the color code for `name` or -1. 96 | */ 97 | 98 | int 99 | term_color_from_name(const char *name) { 100 | if (!strcmp("black", name)) return 0; 101 | if (!strcmp("red", name)) return 1; 102 | if (!strcmp("green", name)) return 2; 103 | if (!strcmp("yellow", name)) return 3; 104 | if (!strcmp("blue", name)) return 4; 105 | if (!strcmp("magenta", name)) return 5; 106 | if (!strcmp("cyan", name)) return 6; 107 | if (!strcmp("white", name)) return 7; 108 | return -1; 109 | } 110 | 111 | /* 112 | * Set color by `name` or return -1. 113 | */ 114 | 115 | int 116 | term_color(const char *name) { 117 | // TODO: refactor term_color_from_name() 118 | if (!strcmp("gray", name) || !strcmp("grey", name)) { 119 | printf("\e[90m"); 120 | return 0; 121 | } 122 | 123 | int n = term_color_from_name(name); 124 | if (-1 == n) return n; 125 | printf("\e[3%dm", n); 126 | return 0; 127 | } 128 | 129 | /* 130 | * Set background color by `name` or return -1. 131 | */ 132 | 133 | int 134 | term_background(const char *name) { 135 | int n = term_color_from_name(name); 136 | if (-1 == n) return n; 137 | printf("\e[4%dm", n); 138 | return 0; 139 | } 140 | -------------------------------------------------------------------------------- /src/term.h: -------------------------------------------------------------------------------- 1 | 2 | // 3 | // term.h 4 | // 5 | // Copyright (c) 2012 TJ Holowaychuk 6 | // 7 | 8 | #ifndef TERM_H 9 | #define TERM_H 10 | 11 | // output 12 | 13 | #define term_write(c) printf("\e[" c); 14 | 15 | // aliases 16 | 17 | #define term_bold term_bright 18 | #define term_clear term_erase 19 | 20 | // display 21 | 22 | #define term_reset() term_write("0m") 23 | #define term_bright() term_write("1m") 24 | #define term_dim() term_write("2m") 25 | #define term_underline() term_write("4m") 26 | #define term_blink() term_write("5m") 27 | #define term_reverse() term_write("7m") 28 | #define term_hidden() term_write("8m") 29 | 30 | // cursor 31 | 32 | #define term_hide_cursor() term_write("?25l") 33 | #define term_show_cursor() term_write("?25h") 34 | 35 | // size 36 | 37 | int 38 | term_size(int *width, int *height); 39 | 40 | // movement 41 | 42 | void 43 | term_move_by(int x, int y); 44 | 45 | void 46 | term_move_to(int x, int y); 47 | 48 | // erasing 49 | 50 | const char * 51 | term_erase_from_name(const char *name); 52 | 53 | int 54 | term_erase(const char *name); 55 | 56 | // colors 57 | 58 | int 59 | term_color_from_name(const char *name); 60 | 61 | int 62 | term_color(const char *name); 63 | 64 | int 65 | term_background(const char *name); 66 | 67 | #endif /* TERM_H */ -------------------------------------------------------------------------------- /test.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include "src/term.h" 4 | 5 | int 6 | main(int argc, char **argv){ 7 | term_bold(); 8 | term_underline(); 9 | printf("bold and underlined\n"); 10 | 11 | term_reset(); 12 | printf("reset\n"); 13 | 14 | term_color("green"); 15 | printf("ok\n"); 16 | 17 | term_bold(); 18 | term_color("red"); 19 | term_background("red"); 20 | printf("fail"); 21 | term_reset(); 22 | 23 | term_move_to(50, 10); 24 | printf("hey"); 25 | term_move_by(1, 1); 26 | printf("there"); 27 | term_move_to(0, 15); 28 | 29 | int w = 0, h = 0; 30 | term_size(&w, &h); 31 | printf("%dx%d\n", w, h); 32 | 33 | return 0; 34 | } --------------------------------------------------------------------------------