summaryrefslogtreecommitdiffstats
path: root/mbbsd/edit.c
diff options
context:
space:
mode:
authorpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-01 12:25:56 +0800
committerpiaip <piaip@63ad8ddf-47c3-0310-b6dd-a9e9d9715204>2007-12-01 12:25:56 +0800
commit1d8009f548a41b171b7c9ef562ce043f7103b671 (patch)
tree7a4dd4ab938fc0151f30a2aefc145d4b292f13a7 /mbbsd/edit.c
parente6786e0884fafc9d23358033125338da40ffffcd (diff)
downloadpttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.tar
pttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.tar.gz
pttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.tar.bz2
pttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.tar.lz
pttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.tar.xz
pttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.tar.zst
pttbbs-1d8009f548a41b171b7c9ef562ce043f7103b671.zip
- edit: remove blockpnt (character level selection)
- edit: fixed offset-by-one (line) in block delete - edit: cancel selection (block) for every line change git-svn-id: http://opensvn.csie.org/pttbbs/trunk/pttbbs@3598 63ad8ddf-47c3-0310-b6dd-a9e9d9715204
Diffstat (limited to 'mbbsd/edit.c')
-rw-r--r--mbbsd/edit.c250
1 files changed, 102 insertions, 148 deletions
diff --git a/mbbsd/edit.c b/mbbsd/edit.c
index f129c1fa..8063b0cf 100644
--- a/mbbsd/edit.c
+++ b/mbbsd/edit.c
@@ -22,6 +22,10 @@
* and/or blockline 錯誤. 甚至把 blockline 砍掉會 access 到已被 free 掉的
* memory. 可能要改成標記模式 readonly, 或是做某些動作時自動取消標記模式
* (blockln=-1)
+ *
+ * FIXME 20071201 piaip
+ * block selection 不知何時已變為 line level 而非 character level 了,
+ * 這樣也比較好寫,所以把 blockpnt 拿掉吧!
*/
#include "bbs.h"
@@ -139,7 +143,6 @@ typedef struct editor_internal_t {
character. */
short lastindent;
short blockln; /* the row you started to select block. */
- short blockpnt; /* the column 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;
@@ -1740,18 +1743,6 @@ setup_block_begin_end(textline_t **begin, textline_t **end)
}
}
-static inline void
-setup_block_begin_end_number(short *begin, short *end)
-{
- if (curr_buf->currpnt > curr_buf->blockpnt) {
- *begin = curr_buf->blockpnt;
- *end = curr_buf->currpnt;
- } else {
- *begin = curr_buf->currpnt;
- *end = curr_buf->blockpnt;
- }
-}
-
#define BLOCK_TRUNCATE 0
#define BLOCK_APPEND 1
/**
@@ -1773,24 +1764,12 @@ block_save_to_file(const char *fname, int mode)
setuserfile(fp_tmpbuf, fname);
if ((fp = fopen(fp_tmpbuf, mode == BLOCK_APPEND ? "a+" : "w+"))) {
- if (begin == end && curr_buf->currpnt != curr_buf->blockpnt) {
- char buf[WRAPMARGIN + 2];
- if (curr_buf->currpnt > curr_buf->blockpnt) {
- strlcpy(buf, begin->data + curr_buf->blockpnt, sizeof(buf));
- buf[curr_buf->currpnt - curr_buf->blockpnt] = 0;
- } else {
- strlcpy(buf, begin->data + curr_buf->currpnt, sizeof(buf));
- buf[curr_buf->blockpnt - curr_buf->currpnt] = 0;
- }
- fputs(buf, fp);
- } else {
- textline_t *p;
+ textline_t *p;
- for (p = begin; p != end; p = p->next)
- fprintf(fp, "%s\n", p->data);
- fprintf(fp, "%s\n", end->data);
- }
+ for (p = begin; p != end; p = p->next)
+ fprintf(fp, "%s\n", p->data);
+ fprintf(fp, "%s\n", end->data);
fclose(fp);
}
}
@@ -1802,62 +1781,63 @@ static void
block_delete(void)
{
textline_t *begin, *end;
+ textline_t *p;
if (!has_block_selection())
return;
setup_block_begin_end(&begin, &end);
- if (begin == end && curr_buf->currpnt != curr_buf->blockpnt) {
- short min, max;
+ // the block region is (currln, block) or (blockln, currln).
- setup_block_begin_end_number(&min, &max);
- strcpy(begin->data + min, begin->data + max);
- begin->len -= max - min;
- curr_buf->currpnt = min;
+ if (curr_buf->currln > curr_buf->blockln) {
+ // case (blockln, currln)
+ // piaip 2007/1201 在這裡原有 offset-by-one issue
+ // 如果又遇到,請檢查這附近。
+ 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);
} else {
- textline_t *p;
+ // case (currln, blockln)
+ }
- if (curr_buf->currln >= curr_buf->blockln) {
- curr_buf->curr_window_line -= (curr_buf->currln - curr_buf->blockln + 1);
- 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);
- }
+ // 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;
+ }
- 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;
- }
+ // adjust current line
+ if (end->next) {
+ curr_buf->currline = end->next;
+ curr_buf->currline->prev = begin->prev;
+ }
+ 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--;
+ }
- if (end->next) {
- curr_buf->currline = end->next;
- curr_buf->currline->prev = begin->prev;
- }
- 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--;
- }
+ // remove buffer
+ for (p = begin; p != end; curr_buf->totaln--)
+ free_line((p = p->next)->prev);
- for (p = begin; p != end; curr_buf->totaln--)
- free_line((p = p->next)->prev);
- free_line(end);
- curr_buf->totaln--;
+ free_line(end);
+ curr_buf->totaln--;
- curr_buf->currpnt = 0;
- }
+ curr_buf->currpnt = 0;
}
static void
@@ -1934,7 +1914,6 @@ static void
block_select(void)
{
curr_buf->blockln = curr_buf->currln;
- curr_buf->blockpnt = curr_buf->currpnt;
curr_buf->blockline = curr_buf->currline;
}
@@ -1960,7 +1939,22 @@ edit_outs_attr_n(const char *text, int n, int attr)
int doReset = 0;
const char *reset = ANSI_RESET;
- if (attr & EOATTR_MOVIECODE)
+#ifdef COLORED_SELECTION
+ if (attr & EOATTR_SELECTED & EOATTR_MOVIECODE)
+ {
+ reset = ANSI_COLOR(0;7;36);
+ doReset = 1;
+ outs(reset);
+ }
+ else
+#endif // if not defined, color by priority - selection first
+ if (attr & EOATTR_SELECTED)
+ {
+ reset = ANSI_COLOR(0;7);
+ doReset = 1;
+ outs(reset);
+ }
+ else if (attr & EOATTR_MOVIECODE)
{
reset = ANSI_COLOR(0;36);
doReset = 1;
@@ -1997,8 +1991,8 @@ edit_outs_attr_n(const char *text, int n, int attr)
if(isDBCS == 1)
{
isDBCS = 2;
- outs(//ESC_STR "[1D"
- ANSI_COLOR(1;33) "?" ANSI_RESET);
+ outs(ANSI_COLOR(1;33) "?");
+ outs(reset);
}
#endif
outs(ANSI_COLOR(1) "*");
@@ -2011,7 +2005,8 @@ edit_outs_attr_n(const char *text, int n, int attr)
else if (isDBCS == 2)
{
/* ansi in middle. */
- outs(ANSI_COLOR(0;33) "?" ANSI_RESET);
+ outs(ANSI_COLOR(0;33) "?");
+ outs(reset);
isDBCS = 0;
continue;
}
@@ -2028,6 +2023,7 @@ edit_outs_attr_n(const char *text, int n, int attr)
}
}
+ // this must be ANSI_RESET, not "reset".
if(inAnsi || doReset)
outs(ANSI_RESET);
}
@@ -2086,7 +2082,7 @@ unsigned char *
#endif // PMORE_USE_ASCII_MOVIE
static inline void
-display_textline_internal(textline_t *p, int i, int min, int max)
+display_textline_internal(textline_t *p, int i)
{
short tmp;
void (*output)(const char *, int) = edit_outs_attr;
@@ -2117,7 +2113,7 @@ display_textline_internal(textline_t *p, int i, int min, int max)
curr_buf->blockln <= tmp && tmp <= curr_buf->currln) ||
(curr_buf->currln <= tmp && tmp <= curr_buf->blockln)) )
{
- outs(ANSI_COLOR(7)); // remove me when EOATTR is ready...
+ // outs(ANSI_COLOR(7)); // remove me when EOATTR is ready...
attr |= EOATTR_SELECTED;
}
@@ -2129,82 +2125,51 @@ display_textline_internal(textline_t *p, int i, int min, int max)
attr |= EOATTR_MOVIECODE;
#endif // PMORE_USE_ASCII_MOVIE
- // special: partial in block selection
- if (curr_buf->currln == curr_buf->blockln &&
- p == curr_buf->currline && max > min) {
-
- outs(ANSI_RESET); // remove me when EOATTR is ready...
- (*output_n)(p->data, min, attr);
-
- attr |= EOATTR_SELECTED;
- outs(ANSI_COLOR(7)); // remove me when EOATTR is ready...
- (*output_n)(p->data + min, max - min, attr);
-
- attr &= ~EOATTR_SELECTED;
- outs(ANSI_RESET); // remove me when EOATTR is ready...
- (*output)(p->data + max, attr);
- outs(ANSI_RESET);
-
- } else
-
#ifdef DBCSAWARE
- if(mbcs_mode && curr_buf->edit_margin > 0)
+ if(mbcs_mode && curr_buf->edit_margin > 0)
+ {
+ if(curr_buf->edit_margin >= p->len)
{
- if(curr_buf->edit_margin >= p->len)
- {
- (*output)("", attr);
- } else {
+ (*output)("", attr);
+ } else {
- int newpnt = curr_buf->edit_margin;
- unsigned char *pdata = (unsigned char*)(&p->data[0] + curr_buf->edit_margin);
+ int newpnt = curr_buf->edit_margin;
+ unsigned char *pdata = (unsigned char*)
+ (&p->data[0] + curr_buf->edit_margin);
- if(mbcs_mode)
- newpnt = fix_cursor(p->data, newpnt, FC_LEFT);
+ if(mbcs_mode)
+ newpnt = fix_cursor(p->data, newpnt, FC_LEFT);
- if(newpnt == curr_buf->edit_margin-1)
- {
- /* this should be always 'outs'? */
- // (*output)(ANSI_COLOR(1) "<" ANSI_RESET);
- outs(ANSI_COLOR(1) "<" ANSI_RESET);
- pdata++;
- }
- (*output)((char*)pdata, attr);
+ if(newpnt == curr_buf->edit_margin-1)
+ {
+ /* this should be always 'outs'? */
+ // (*output)(ANSI_COLOR(1) "<" ANSI_RESET);
+ outs(ANSI_COLOR(1) "<" ANSI_RESET);
+ pdata++;
}
+ (*output)((char*)pdata, attr);
+ }
- } else
+ } else
#endif
- (*output)((curr_buf->edit_margin < p->len) ? &p->data[curr_buf->edit_margin] : "", attr);
+ (*output)((curr_buf->edit_margin < p->len) ?
+ &p->data[curr_buf->edit_margin] : "", attr);
if (attr)
outs(ANSI_RESET);
-}
-/**
- * given a textline_t 'text' and the line number 'n' in the content,
- * display this line.
- *
- * this is not called... why? */
-/*
-static void
-display_textline(textline_t *text, int n)
-{
- short begin, end;
- setup_block_begin_end_number(&begin, &end);
- display_textline_internal(text, n, begin, end);
+ // workaround poor terminal
+ outs(ANSI_CLRTOEND);
}
-*/
static void
refresh_window(void)
{
register textline_t *p;
register int i;
- short begin, end;
-
- setup_block_begin_end_number(&begin, &end);
for (p = curr_buf->top_of_win, i = 0; i < b_lines; i++) {
- display_textline_internal(p, i, begin, end);
+ display_textline_internal(p, i);
if (p)
p = p->next;
@@ -3037,21 +3002,6 @@ vedit(char *fpath, int saveheader, int *islocal)
break;
}
break;
-#if 0 // DEPRECATED, it's really not a well known expensive feature
- case Ctrl('_'):
- // swap editline and currline's data
- if (strcmp(editline, curr_buf->currline->data)) {
- char buf[WRAPMARGIN];
-
- strlcpy(buf, curr_buf->currline->data, sizeof(buf));
- strcpy(curr_buf->currline->data, editline);
- strcpy(editline, buf);
- curr_buf->currline->len = strlen(curr_buf->currline->data);
- curr_buf->currpnt = 0;
- curr_buf->line_dirty = 1;
- }
- break;
-#endif
case Ctrl('S'):
case KEY_F3:
search_str(0);
@@ -3071,6 +3021,7 @@ vedit(char *fpath, int saveheader, int *islocal)
break;
case '\r':
case '\n':
+ block_cancel();
#ifdef MAX_EDIT_LINE
if( curr_buf->totaln == MAX_EDIT_LINE ){
outs("MAX_EDIT_LINE exceed");
@@ -3231,6 +3182,7 @@ vedit(char *fpath, int saveheader, int *islocal)
break;
case Ctrl('H'):
case '\177': /* backspace */
+ block_cancel();
if (curr_buf->ansimode) {
curr_buf->ansimode = 0;
clear();
@@ -3281,6 +3233,7 @@ vedit(char *fpath, int saveheader, int *islocal)
break;
case Ctrl('D'):
case KEY_DEL: /* delete current character */
+ block_cancel();
if (curr_buf->currline->len == curr_buf->currpnt) {
join(curr_buf->currline);
curr_buf->redraw_everything = YEA;
@@ -3305,6 +3258,7 @@ vedit(char *fpath, int saveheader, int *islocal)
case Ctrl('Y'): /* delete current line */
curr_buf->currline->len = curr_buf->currpnt = 0;
case Ctrl('K'): /* delete to end of line */
+ block_cancel();
if (curr_buf->currline->len == 0) {
textline_t *p = curr_buf->currline->next;
if (!p) {