diff options
-rw-r--r-- | mbbsd/edit.c | 389 | ||||
-rw-r--r-- | sample/etc/ve.hlp | 11 |
2 files changed, 249 insertions, 151 deletions
diff --git a/mbbsd/edit.c b/mbbsd/edit.c index 78db76c4..0b5f9ebe 100644 --- a/mbbsd/edit.c +++ b/mbbsd/edit.c @@ -18,14 +18,8 @@ * °O¾ÐÅé¤j¤p. ¥H¤è«K´ú¸Õµ²ªG. * ³oÓª©¥»¦ü¥GÁÙ¦³¦a¤è¨S¦³×¥¿¦n, ¥i¯à¾ÉP segmentation fault . * - * FIXME ¦b°Ï¶ô¼Ð°O¼Ò¦¡(blockln>=0)¤¤¹ï¼W§Rקï¥i¯à·|³y¦¨ blockln, blockpnt, - * and/or blockline ¿ù»~. ¬Æ¦Ü§â blockline ¬å±¼·| access ¨ì¤w³Q free ±¼ªº - * memory. ¥i¯àn§ï¦¨¼Ð°O¼Ò¦¡ readonly, ©Î¬O°µ¬Y¨Ç°Ê§@®É¦Û°Ê¨ú®ø¼Ð°O¼Ò¦¡ - * (blockln=-1) - * - * FIXME 20071201 piaip - * block selection ¤£ª¾¦ó®É¤wÅܬ° line level ¦Ó«D character level ¤F¡A - * ³o¼Ë¤]¤ñ¸û¦n¼g¡A©Ò¥H§â blockpnt ®³±¼§a¡I + * XXX ¥Ñ©ó¦UºØ¾Þ§@³£¤£·| maintain °Ï¶ô¼Ð°O¼Ò¦¡ªº pointer/state, + * ¦]¦¹¹ï©ó·|³y¦¨¼W§R line ªº¥\¯à, ³£±o¦Û°Ê¨ú®ø¼Ð°O¼Ò¦¡(call block_cancel()). * * 20071230 piaip * BBSmovie ¦³¤H§@¥X¤F 1.9G ªºÀÉ®×, ¬Ý¨Ón¤À hard limit ¸ò soft limit @@ -40,6 +34,10 @@ * 1M ¬° line limit * ¤S¡A©¿µMµo²{¤§«e totaln ¤§Ãþ³£¬O short... ©Ò¥H 65536 ´N°÷¤F? * «áµù: ¦ü¥G¬O¥Î announce ªº append §@¥X¨Óªº¡A¦³¬Ý¨ì > --- <- mark¡C + * + * FIXME screen resize ³y¦¨ b_lines §ïÅÜ, ¥i¯à·|³y¦¨ state ¿ù¶Ã. ¤×¨ä¬O tty + * mode ÀH®É³£¥i¯à resize. TODO editor_internal_t ¦hÓÄæ¦ì°O screen size, + * ·í¾Þ§@¨ì¤@¬q¸¨¤§«á¤~ check b_lines ¬O§_¦³§ïÅÜ. */ #include "bbs.h" @@ -150,7 +148,7 @@ typedef struct editor_internal_t { int currln; /* current line of the article. */ short currpnt; /* current column of the article. */ - int totaln; /* total lines of the article. */ + int totaln; /* last line of the article. */ int curr_window_line; /* current line to the window. */ short last_margin; short edit_margin; /* when the cursor moves out of range (say, @@ -159,8 +157,6 @@ typedef struct editor_internal_t { character. */ short lastindent; int blockln; /* the row you started to select block. */ - char insert_c; /* insert this character when shift something - in order to compensate the new space. */ char last_phone_mode; char ifuseanony :1; @@ -185,7 +181,12 @@ typedef struct editor_internal_t { static editor_internal_t *curr_buf = NULL; -static const char fp_bak[] = "bak"; +static const char * const fp_bak = "bak"; + +// forward declare +static inline int has_block_selection(void); +static textline_t * alloc_line(short length); +static void block_cancel(void); static const char * const BIG5[13] = { "¡A¡F¡G¡B¡N¡C¡H¡I¡E¡T¡]¡^¡©¡ª¡«¡¬", @@ -289,10 +290,13 @@ edit_buffer_constructor(editor_internal_t *buf) { /* all unspecified columns are 0 */ buf->blockln = -1; - buf->insert_c = ' '; buf->insert_mode = 1; buf->redraw_everything = 1; buf->lastindent = -1; + + buf->oldcurrline = buf->currline = buf->top_of_win = + buf->firstline = buf->lastline = alloc_line(WRAPMARGIN); + } static inline void @@ -317,6 +321,11 @@ free_line(textline_t *p) static inline void edit_buffer_destructor(void) { + textline_t *p, *pnext; + for (p = curr_buf->firstline; p; p = pnext) { + pnext = p->next; + free_line(p); + } if (curr_buf->deleted_line != NULL) free_line(curr_buf->deleted_line); @@ -455,6 +464,102 @@ edit_msg(void) vs_footer(" ½s¿è¤å³¹ ", buf); } +//#define SLOW_CHECK_DETAIL +static void +edit_buffer_check_healthy(textline_t *line) +{ + assert(line); + + if (line->next) + assert(line->next->prev == line); + if (line->prev) + assert(line->prev->next == line); + assert(0 <= line->len); + assert(line->len <= WRAPMARGIN); +#ifdef DEBUG + assert(line->len <= line->mlength); +#endif +#ifdef SLOW_CHECK_DETAIL + assert(strlen(line->data) == line->len); +#endif +} + +static void +edit_check_healthy() +{ +#ifdef SLOW_CHECK_DETAIL + int i; + textline_t *p; +#endif + + edit_buffer_check_healthy(curr_buf->firstline); + assert(curr_buf->firstline->prev == NULL); + + edit_buffer_check_healthy(curr_buf->lastline); + assert(curr_buf->lastline->next == NULL); + + edit_buffer_check_healthy(curr_buf->oldcurrline); + + // currline + edit_buffer_check_healthy(curr_buf->currline); + assert(0 <= curr_buf->currpnt && curr_buf->currpnt <= curr_buf->currline->len); + + if (curr_buf->deleted_line) { + edit_buffer_check_healthy(curr_buf->deleted_line); + assert(curr_buf->deleted_line->next == NULL); + assert(curr_buf->deleted_line->prev == NULL); + assert(curr_buf->deleted_line != curr_buf->firstline); + assert(curr_buf->deleted_line != curr_buf->lastline); + assert(curr_buf->deleted_line != curr_buf->currline); + assert(curr_buf->deleted_line != curr_buf->blockline); + assert(curr_buf->deleted_line != curr_buf->top_of_win); + } + + // lines + assert(0 <= curr_buf->currln); + assert(curr_buf->currln <= curr_buf->totaln); + + // window + assert(curr_buf->curr_window_line <= b_lines); + +#ifdef SLOW_CHECK_DETAIL + // firstline -> currline (0 -> currln) + p = curr_buf->firstline; + for (i = 0; i < curr_buf->currln; i++) { + edit_buffer_check_healthy(p); + p = p->next; + } + assert(p == curr_buf->currline); + + // currline -> lastline (currln -> totaln) + p = curr_buf->currline; + for (i = 0; i < curr_buf->totaln - curr_buf->currln; i++) { + edit_buffer_check_healthy(p); + p = p->next; + } + assert(p == curr_buf->lastline); + + // top_of_win -> currline (curr_window_line) + p = curr_buf->top_of_win; + for (i = 0; i < curr_buf->curr_window_line; i++) + p = p->next; + assert(p == curr_buf->currline); + +#endif + + // block + assert(curr_buf->blockln < 0 || curr_buf->blockline); + if (curr_buf->blockline) { + edit_buffer_check_healthy(curr_buf->blockline); +#ifdef SLOW_CHECK_DETAIL + p = curr_buf->firstline; + for (i = 0; i < curr_buf->blockln; i++) + p = p->next; + assert(p == curr_buf->blockline); +#endif + } +} + /** * return the middle line of the window. */ @@ -667,6 +772,21 @@ alloc_line(short length) } /** + * clone a textline_t + */ +static textline_t * +clone_line(const textline_t *line) +{ + textline_t *p; + + p = alloc_line(line->len); + p->len = line->len; + strlcpy(p->data, line->data, p->len + 1); + + return p; +} + +/** * Insert p after line in list. Keeps up with last line */ static void @@ -775,9 +895,6 @@ adjustline(textline_t *oldp, short len) newp = alloc_line(len); memcpy(newp, tmpl, len + sizeof(textline_t)); -#ifdef DEBUG - newp->mlength = len; -#endif if( oldp == curr_buf->firstline ) curr_buf->firstline = newp; if( oldp == curr_buf->lastline ) curr_buf->lastline = newp; if( oldp == curr_buf->currline ) curr_buf->currline = newp; @@ -859,6 +976,7 @@ insert_char(int ch) indigestion(1); return; } + block_cancel(); if (curr_buf->currpnt < i && !curr_buf->insert_mode) { p->data[curr_buf->currpnt++] = ch; /* Thor: ansi ½s¿è, ¥i¥Hoverwrite, ¤£»\¨ì ansi code */ @@ -923,6 +1041,7 @@ insert_string(const char *str) { char ch; + block_cancel(); while ((ch = *str++)) { if (isprint2(ch) || ch == ESC_CHR) insert_char(ch); @@ -941,35 +1060,37 @@ insert_string(const char *str) static textline_t * undelete_line(void) { - editor_internal_t tmp; + textline_t *p; if (!curr_buf->deleted_line) return NULL; - tmp.top_of_win = curr_buf->top_of_win; - tmp.indent_mode = curr_buf->indent_mode; - tmp.curr_window_line = curr_buf->curr_window_line; - - curr_buf->indent_mode = 0; - curr_buf->currpnt = 0; - curr_buf->currln++; - insert_string(curr_buf->deleted_line->data); - insert_string("\n"); + block_cancel(); + p = clone_line(curr_buf->deleted_line); - curr_buf->top_of_win = tmp.top_of_win; - curr_buf->indent_mode = tmp.indent_mode; - curr_buf->curr_window_line = tmp.curr_window_line; + // insert in front of currline + p->prev = curr_buf->currline->prev; + p->next = curr_buf->currline->next; + if (curr_buf->currline->prev) + curr_buf->currline->prev->next = p; + curr_buf->currline->prev = p; + curr_buf->totaln++; - assert(curr_buf->currline->prev); curr_buf->currline = adjustline(curr_buf->currline, curr_buf->currline->len); - curr_buf->currline = curr_buf->currline->prev; + + // maintain special line pointer + if (curr_buf->top_of_win == curr_buf->currline) + curr_buf->top_of_win = p; + if (curr_buf->firstline == curr_buf->currline) + curr_buf->firstline = p; + + // change currline + curr_buf->currline = p; curr_buf->currline = adjustline(curr_buf->currline, WRAPMARGIN); - curr_buf->oldcurrline = curr_buf->currline; + curr_buf->currpnt = 0; + + curr_buf->redraw_everything = YEA; - if (curr_buf->currline->prev == NULL) { - curr_buf->top_of_win = curr_buf->currline; - curr_buf->currln = 0; - } return curr_buf->currline; } @@ -1005,6 +1126,7 @@ join(textline_t * line) if (!*next_non_space_char(n->data)) return YEA; + ovfl = line->len + n->len - WRAPMARGIN; if (ovfl < 0) { strcat(line->data, n->data); @@ -1032,7 +1154,7 @@ join(textline_t * line) if (ovfl >= 0 && ovfl < WRAPMARGIN - 2) { s = &(n->data[ovfl]); if (*s != ' ') { - strcpy(s, " "); + strcat(s, " "); n->len++; } } @@ -1201,6 +1323,8 @@ auto_backup(void) char bakfile[PATHLEN]; int count = 0; + curr_buf->currline = NULL; + setuserfile(bakfile, fp_bak); if ((fp = fopen(bakfile, "w"))) { for (p = curr_buf->firstline; p != NULL && count < 512; p = v, count++) { @@ -1210,7 +1334,6 @@ auto_backup(void) } fclose(fp); } - curr_buf->currline = NULL; } } @@ -1442,7 +1565,7 @@ read_file(const char *fpath, int splitSig) } void -write_header(FILE * fp, const char *mytitle) // FIXME unused +write_header(FILE * fp, const char *mytitle) { assert(mytitle); if (curredit & EDIT_MAIL || curredit & EDIT_LIST) { @@ -1673,7 +1796,7 @@ static int write_file(const char *fpath, int saveheader, int *islocal, char mytitle[STRLEN], int upload, int chtitle) { FILE *fp = NULL; - textline_t *p, *v; + textline_t *p; char ans[TTLEN], *msg; int aborted = 0, line = 0, checksum[3], sum = 0, po = 1; @@ -1770,39 +1893,38 @@ write_file(const char *fpath, int saveheader, int *islocal, char mytitle[STRLEN] if (saveheader) write_header(fp, mytitle); } - for (p = curr_buf->firstline; p; p = v) { - v = p->next; - if (!aborted) { - assert(fp); + if (!aborted) { + for (p = curr_buf->firstline; p; p = p->next) { msg = p->data; - if (v || msg[0]) { - trim(msg); - - line++; - - /* check crosspost */ - if (currstat == POSTING && po ) { - int msgsum = StringHash(msg); - if (msgsum) { - if (postrecord.last_bid != currbid && - postrecord.checksum[po] == msgsum) { - po++; - if (po > 3) { - postrecord.times++; - postrecord.last_bid = currbid; - po = 0; - } - } else - po = 1; - if (line >= curr_buf->totaln / 2 && sum < 3) { - checksum[sum++] = msgsum; + + if (p->next == NULL && !msg[0]) // ignore lastline is empty + continue; + + trim(msg); + + line++; + + /* check crosspost */ + if (currstat == POSTING && po ) { + int msgsum = StringHash(msg); + if (msgsum) { + if (postrecord.last_bid != currbid && + postrecord.checksum[po] == msgsum) { + po++; + if (po > 3) { + postrecord.times++; + postrecord.last_bid = currbid; + po = 0; } + } else + po = 1; + if (line >= curr_buf->totaln / 2 && sum < 3) { + checksum[sum++] = msgsum; } } - fprintf(fp, "%s\n", msg); } + fprintf(fp, "%s\n", msg); } - free_line(p); } curr_buf->currline = NULL; @@ -1868,6 +1990,7 @@ block_cancel(void) { if (has_block_selection()) { curr_buf->blockln = -1; + curr_buf->blockline = NULL; curr_buf->redraw_everything = YEA; } } @@ -1922,7 +2045,7 @@ static void block_delete(void) { textline_t *begin, *end; - textline_t *p; + textline_t *p; if (!has_block_selection()) return; @@ -1931,54 +2054,62 @@ block_delete(void) // the block region is (currln, block) or (blockln, currln). + textline_t *pnext; + int deleted_line_count = abs(curr_buf->currln - curr_buf->blockln) + 1; + if (begin->prev) + begin->prev->next = end->next; + if (end->next) + end->next->prev = begin->prev; + if (curr_buf->currln > curr_buf->blockln) { // case (blockln, currln) - // piaip 2007/1201 ¦b³o¸Ì즳 offset-by-one issue - // ¦pªG¤S¹J¨ì¡A½ÐÀˬd³oªþªñ¡C - curr_buf->curr_window_line -= (curr_buf->currln - curr_buf->blockln); - - if (curr_buf->curr_window_line <= 0) { - curr_buf->curr_window_line = 0; - if (end->next) - (curr_buf->top_of_win = end->next)->prev = begin->prev; - else - curr_buf->top_of_win = (curr_buf->lastline = begin->prev); - } - curr_buf->currln -= (curr_buf->currln - curr_buf->blockln); + curr_buf->currln = curr_buf->blockln; + curr_buf->curr_window_line -= deleted_line_count - 1; } else { // case (currln, blockln) } + curr_buf->totaln -= deleted_line_count; - // adjust buffer after delete - if (begin->prev) - begin->prev->next = end->next; - else if (end->next) - curr_buf->top_of_win = curr_buf->firstline = end->next; - else { - curr_buf->currline = curr_buf->top_of_win = curr_buf->firstline = curr_buf->lastline = alloc_line(WRAPMARGIN); - curr_buf->currln = curr_buf->curr_window_line = curr_buf->edit_margin = 0; + curr_buf->currline = end->next; + if (curr_buf->currline == NULL) { + curr_buf->currline = begin->prev; + curr_buf->currln--; + curr_buf->curr_window_line--; } + if (curr_buf->currline == NULL) { + assert(curr_buf->currln == -1); + assert(curr_buf->totaln == -1); - // adjust current line - if (end->next) { - curr_buf->currline = end->next; - curr_buf->currline->prev = begin->prev; + curr_buf->currline = alloc_line(WRAPMARGIN); + curr_buf->currln++; + curr_buf->totaln++; + } else { + curr_buf->currline = adjustline(curr_buf->currline, WRAPMARGIN); } - else if (begin->prev) { - curr_buf->currline = (curr_buf->lastline = begin->prev); - curr_buf->currln--; - if (curr_buf->curr_window_line > 0) - curr_buf->curr_window_line--; + curr_buf->oldcurrline = curr_buf->currline; + + // maintain special line pointer + if (curr_buf->firstline == begin) + curr_buf->firstline = curr_buf->currline; + if (curr_buf->lastline == end) + curr_buf->lastline = curr_buf->currline; + if (curr_buf->curr_window_line <= 0) { + curr_buf->curr_window_line = 0; + curr_buf->top_of_win = curr_buf->currline; } // remove buffer - for (p = begin; p != end; curr_buf->totaln--) - free_line((p = p->next)->prev); - - free_line(end); - curr_buf->totaln--; + end->next = NULL; + for (p = begin; p; p = pnext) { + pnext = p->next; + free_line(p); + deleted_line_count--; + } + assert(deleted_line_count == 0); curr_buf->currpnt = 0; + + block_cancel(); } static void @@ -1989,9 +2120,6 @@ block_cut(void) block_save_to_file("buf.0", BLOCK_TRUNCATE); block_delete(); - - curr_buf->blockln = -1; - curr_buf->redraw_everything = YEA; } static void @@ -2002,8 +2130,7 @@ block_copy(void) block_save_to_file("buf.0", BLOCK_TRUNCATE); - curr_buf->blockln = -1; - curr_buf->redraw_everything = YEA; + block_cancel(); } static void @@ -2049,8 +2176,7 @@ block_prompt(void) block_save_to_file(tmpfname, mode[0] == 'a' ? BLOCK_APPEND : BLOCK_TRUNCATE); cancel_block: - curr_buf->blockln = -1; - curr_buf->redraw_everything = YEA; + block_cancel(); } static void @@ -3393,9 +3519,6 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int enter_edit_buffer(); - curr_buf->oldcurrline = curr_buf->currline = curr_buf->top_of_win = - curr_buf->firstline = curr_buf->lastline = alloc_line(WRAPMARGIN); - if (*fpath) { read_file(fpath, (flags & EDITFLAG_TEXTONLY) ? 1 : 0); } @@ -3424,6 +3547,8 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int } while (1) { + edit_check_healthy(); + if (curr_buf->redraw_everything || has_block_selection()) { refresh_window(); curr_buf->redraw_everything = NA; @@ -3439,11 +3564,6 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int ch = curr_buf->currpnt - curr_buf->edit_margin; move(curr_buf->curr_window_line, ch); -#if 0 // DEPRECATED, it's really not a well known expensive feature - if (!curr_buf->line_dirty && strcmp(editline, curr_buf->currline->data)) - strcpy(editline, curr_buf->currline->data); -#endif - ch = igetch(); /* jochang debug */ if ((interval = (now - th))) { @@ -3526,11 +3646,6 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int case 'o': ch = Ctrl('O'); break; -#if 0 // DEPRECATED, it's really not a well known expensive feature - case '-': - ch = Ctrl('_'); - break; -#endif case 's': ch = Ctrl('S'); break; @@ -3539,6 +3654,7 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int switch (ch) { case KEY_F10: case Ctrl('X'): /* Save and exit */ + block_cancel(); tmp = write_file(fpath, saveheader, islocal, title, (flags & EDITFLAG_UPLOAD) ? 1 : 0, (flags & EDITFLAG_ALLOWTITLE) ? 1 : 0); @@ -3565,11 +3681,6 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int break; case Ctrl('W'): block_cut(); - // curr_buf->oldcurrline is freed in block_cut, and currline is - // well adjusted now. This will avoid re-adjusting later. - // It's not a good implementation, try to find a better - // solution! - curr_buf->oldcurrline = curr_buf->currline; break; case Ctrl('Q'): /* Quit without saving */ grayout(0, b_lines-1, GRAYOUT_DARK); @@ -3625,14 +3736,8 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int break; case 'l': /* block delete */ case ' ': - if (has_block_selection()) { + if (has_block_selection()) block_prompt(); - // curr_buf->oldcurrline is freed in block_cut, and currline is - // well adjusted now. This will avoid re-adjusting later. - // It's not a good implementation, try to find a better - // solution! - curr_buf->oldcurrline = curr_buf->currline; - } else block_select(); break; @@ -3853,14 +3958,6 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int break; case Ctrl('O'): // better not use ^O - UNIX not sending. case KEY_INS: /* Toggle insert/overwrite */ - if (has_block_selection() && curr_buf->insert_mode) { - char ans[4]; - - getdata(b_lines - 1, 0, - "°Ï¶ô·L½Õ¥k²¾´¡¤J¦r¤¸(¹w³]¬°ªÅ¥Õ¦r¤¸)", - ans, sizeof(ans), LCECHO); - curr_buf->insert_c = ans[0] ? ans[0] : ' '; - } curr_buf->insert_mode ^= 1; break; case KEY_BS: @@ -3939,10 +4036,10 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int } break; case Ctrl('Y'): /* delete current line */ - curr_buf->currline->len = curr_buf->currpnt = 0; + curr_buf->currpnt = 0; case Ctrl('K'): /* delete to end of line */ block_cancel(); - if (curr_buf->currline->len == 0) { + if (ch == Ctrl('Y') || curr_buf->currline->len == 0) { textline_t *p = curr_buf->currline->next; if (!p) { p = curr_buf->currline->prev; @@ -4015,7 +4112,9 @@ vedit2(const char *fpath, int saveheader, int *islocal, char title[STRLEN], int outs(ANSI_RESET ANSI_CLRTOEND); edit_msg(); } - } /* redraw */ + } else { + curr_buf->last_margin = curr_buf->edit_margin; + } } /* main event loop */ exit_edit_buffer(); diff --git a/sample/etc/ve.hlp b/sample/etc/ve.hlp index 9db9dd94..2f9d21c8 100644 --- a/sample/etc/ve.hlp +++ b/sample/etc/ve.hlp @@ -5,7 +5,7 @@ [37;45m¡i´å¼Ð²¾°Ê«ü¥O¡j[m ¡ö ©¹«á²¾°Ê¤@®æ ^A,Home ²¾¨ì¦¹¦æ¶}ÀY ¡÷ ©¹«e²¾°Ê¤@®æ ^E,End ²¾¨ì¦¹¦æµ²§À - ¡ô,^P ©¹¤W²¾°Ê¤@¦æ (ESC-,) ²¾¨ìÀɮ׶}ÀY + ¡ô ©¹¤W²¾°Ê¤@¦æ (ESC-,) ²¾¨ìÀɮ׶}ÀY ¡õ ©¹¤U²¾°Ê¤@¦æ (ESC-.),^T ²¾¨ìÀÉ®×µ²§À ^B,PgUp ©¹¤W²¾°Ê¤@¶ ^F,PgDn ©¹¤U²¾°Ê¤@¶ ^S,F3 ´M§ä¦r¦ê (ESC-L),F5 ¸õ¦Ü«ü©w¦æ @@ -31,7 +31,8 @@ wb ¥Nªí¥Õ¦r¶Â©³ 1wb ¥Nªí°ª«G¥Õ¦r¶Â©³.. ¤ä´© overwrite & insert , ¥i»´©ö½s¿èÃþ¦ü Welcome µe± - ¦]¬YºØì¦], ¨ú®ø¦b ansi editing ¤Uªº backspace¥\¯à:P[m + ¦]¬YºØì¦], ¨ú®ø¦b ansi editing ¤Uªº backspace¥\¯à:P + [37;45m¡i°Ï¶ô³B²z©R¥O¡j[m (ESC-l), (ESC-SPACE) ³]©w¼Ð°O°Ï ^W Cut, §â¼Ð°O°Ï°Å¦Ü¼È¦sÀÉ 0 @@ -45,14 +46,12 @@ Y»Ýn§â¤å³¹ùتº¡u³¡¤À¡v¨ú¥X®É¡AESC-SPC ¤]¾A¥Î¡C (ESC-0/5) Paste, ª½±µ¶K¤W¼È¦sÀÉ 0/5 (ESC-6-9) ¶K¤W¼È¦sÀÉ 6-9 ¡A¶K¤W«e¥ý¹wÄý - (ESC-j) ±N¼Ð°O°Ï©¹¥ª²¾ - (ESC-k) ±N¼Ð°O°Ï©¹¥k²¾ (ESC-u) ¨ú®ø¼Ð°O°Ï [37;45m¡i¯S®í«ü¥O¡j[m ^U ¿é¤J ESC ½X(¥H * ªí¥Ü) ^C ÁÙì/³]©w ANSI ¦â±m - (ESC-y) ±Ï¦^»~§R¦æ ^_(Ctrl-/),(ESC--) ´_ì¥Ø«e¦æ + (ESC-y) ±Ï¦^»~§R¦æ (ESC-A) ¤Á´«ANSI±m¦â¼Ò¦¡ (ESC-I) ¤Á´«ÁY±Æ(indent)¼Ò¦¡ - (ESC-P) ¤Á´«ª`µª½±µ¥´¼Ò¦¡ (ESC-R) ¤Á´«ª½±µ(raw)¿é¤J¼Ò¦¡ + ^P ¤Á´«²Å¸¹¿é¤J¼Ò¦¡ (ESC-R) ¤Á´«ª½±µ(raw)¿é¤J¼Ò¦¡ ^R Åã¥Ü¤W¦¸¦©À³°T®§ (ESC-U),F8 ¨Ï¥ÎªÌ¦Cªí (ESC-i) ¶i¤Jµo§b¼Ò¦¡ |