📄 screen.c
字号:
if (r->screen.tlen[row] != -1) /* XXX: think about this */ MAX_IT(r->screen.tlen[row], r->screen.cur.col);/* * If we wrote anywhere in the selected area, kill the selection * XXX: should we kill the mark too? Possibly, but maybe that * should be a similar check. */ if (clearsel) CLEAR_SELECTION(r);#ifdef DEBUG_STRICT assert(r->screen.cur.row >= 0);#else /* drive with your eyes closed */ MAX_IT(r->screen.cur.row, 0);#endif}/* ------------------------------------------------------------------------- *//* * Process Backspace. Move back the cursor back a position, wrap if have to * XTERM_SEQ: CTRL-H *//* EXTPROTO */voidrxvt_scr_backspace(rxvt_t *r){ RESET_CHSTAT(r->h); r->h->want_refresh = 1; if (r->screen.cur.col == 0) { if (r->screen.cur.row > 0) {#ifdef TERMCAP_HAS_BW r->screen.cur.col = r->TermWin.ncol - 1; r->screen.cur.row--; return;#endif } } else if ((r->screen.flags & Screen_WrapNext) == 0) rxvt_scr_gotorc(r, 0, -1, RELATIVE); r->screen.flags &= ~Screen_WrapNext;}/* ------------------------------------------------------------------------- *//* * Process Horizontal Tab * count: +ve = forward; -ve = backwards * XTERM_SEQ: CTRL-I *//* EXTPROTO */voidrxvt_scr_tab(rxvt_t *r, int count){ int i, x; D_SCREEN((stderr, "rxvt_scr_tab(%d)", count)); r->h->want_refresh = 1; RESET_CHSTAT(r->h); i = x = r->screen.cur.col; if (count == 0) return; else if (count > 0) { for (; ++i < r->TermWin.ncol; ) if (r->tabs[i]) { x = i; if (!--count) break; } if (count) x = r->TermWin.ncol - 1; } else /* if (count < 0) */ { for (; --i >= 0; ) if (r->tabs[i]) { x = i; if (!++count) break; } if (count) x = 0; } if (x != r->screen.cur.col) rxvt_scr_gotorc(r, 0, x, R_RELATIVE);}/* ------------------------------------------------------------------------- *//* * Process DEC Back Index * XTERM_SEQ: ESC 6 * Move cursor left in row. If we're at the left boundary, shift everything * in that row right. Clear left column. */#ifndef NO_FRILLS/* EXTPROTO */voidrxvt_scr_backindex(rxvt_t *r){ if (r->screen.cur.col > 0) rxvt_scr_gotorc(r, 0, -1, R_RELATIVE | C_RELATIVE); else { if (r->screen.tlen[r->screen.cur.row + r->TermWin.saveLines] == 0) return; /* um, yeah? */ rxvt_scr_insdel_chars(r, 1, INSERT); }}#endif/* ------------------------------------------------------------------------- *//* * Process DEC Forward Index * XTERM_SEQ: ESC 9 * Move cursor right in row. If we're at the right boundary, shift everything * in that row left. Clear right column. */#ifndef NO_FRILLS/* EXTPROTO */voidrxvt_scr_forwardindex(rxvt_t *r){ int row; if (r->screen.cur.col < r->TermWin.ncol - 1) rxvt_scr_gotorc(r, 0, 1, R_RELATIVE | C_RELATIVE); else { row = r->screen.cur.row + r->TermWin.saveLines; if (r->screen.tlen[row] == 0) return; /* um, yeah? */ else if (r->screen.tlen[row] == -1) r->screen.tlen[row] = r->TermWin.ncol; rxvt_scr_gotorc(r, 0, 0, R_RELATIVE); rxvt_scr_insdel_chars(r, 1, DELETE); rxvt_scr_gotorc(r, 0, r->TermWin.ncol - 1, R_RELATIVE); }}#endif/* ------------------------------------------------------------------------- *//* * Goto Row/Column *//* EXTPROTO */voidrxvt_scr_gotorc(rxvt_t *r, int row, int col, int relative){ r->h->want_refresh = 1; ZERO_SCROLLBACK(r); RESET_CHSTAT(r->h); if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, 0); D_SCREEN((stderr, "rxvt_scr_gotorc(r:%s%d,c:%s%d): from (r:%d,c:%d)", (relative & R_RELATIVE ? "+" : ""), row, (relative & C_RELATIVE ? "+" : ""), col, r->screen.cur.row, r->screen.cur.col)); r->screen.cur.col = ((relative & C_RELATIVE) ? (r->screen.cur.col + col) : col); MAX_IT(r->screen.cur.col, 0); MIN_IT(r->screen.cur.col, r->TermWin.ncol - 1); r->screen.flags &= ~Screen_WrapNext; if (relative & R_RELATIVE) { if (row > 0) { if (r->screen.cur.row <= r->screen.bscroll && (r->screen.cur.row + row) > r->screen.bscroll) r->screen.cur.row = r->screen.bscroll; else r->screen.cur.row += row; } else if (row < 0) { if (r->screen.cur.row >= r->screen.tscroll && (r->screen.cur.row + row) < r->screen.tscroll) r->screen.cur.row = r->screen.tscroll; else r->screen.cur.row += row; } } else { if (r->screen.flags & Screen_Relative) { /* relative origin mode */ r->screen.cur.row = row + r->screen.tscroll; MIN_IT(r->screen.cur.row, r->screen.bscroll); } else r->screen.cur.row = row; } MAX_IT(r->screen.cur.row, 0); MIN_IT(r->screen.cur.row, r->TermWin.nrow - 1);}/* ------------------------------------------------------------------------- *//* * direction should be UP or DN *//* EXTPROTO */voidrxvt_scr_index(rxvt_t *r, enum page_dirn direction){ int dirn; r->h->want_refresh = 1; dirn = ((direction == UP) ? 1 : -1); D_SCREEN((stderr, "rxvt_scr_index(%d)", dirn)); ZERO_SCROLLBACK(r); RESET_CHSTAT(r->h); if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, 0); r->screen.flags &= ~Screen_WrapNext; if ((r->screen.cur.row == r->screen.bscroll && direction == UP) || (r->screen.cur.row == r->screen.tscroll && direction == DN)) rxvt_scroll_text(r, r->screen.tscroll, r->screen.bscroll, dirn, 0); else r->screen.cur.row += dirn; MAX_IT(r->screen.cur.row, 0); MIN_IT(r->screen.cur.row, r->TermWin.nrow - 1); rxvt_selection_check(r, 0);}/* ------------------------------------------------------------------------- *//* * Erase part or whole of a line * XTERM_SEQ: Clear line to right: ESC [ 0 K * XTERM_SEQ: Clear line to left : ESC [ 1 K * XTERM_SEQ: Clear whole line : ESC [ 2 K *//* EXTPROTO */voidrxvt_scr_erase_line(rxvt_t *r, int mode){ unsigned int row, col, num; r->h->want_refresh = 1; D_SCREEN((stderr, "rxvt_scr_erase_line(%d) at screen row: %d", mode, r->screen.cur.row)); ZERO_SCROLLBACK(r); RESET_CHSTAT(r->h); if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, 0); rxvt_selection_check(r, 1); r->screen.flags &= ~Screen_WrapNext; row = r->TermWin.saveLines + r->screen.cur.row; switch (mode) { case 0: /* erase to end of line */ col = r->screen.cur.col; num = r->TermWin.ncol - col; MIN_IT(r->screen.tlen[row], (int16_t)col); if (ROWCOL_IN_ROW_AT_OR_AFTER(r->selection.beg, r->screen.cur) || ROWCOL_IN_ROW_AT_OR_AFTER(r->selection.end, r->screen.cur)) CLEAR_SELECTION(r); break; case 1: /* erase to beginning of line */ col = 0; num = r->screen.cur.col + 1; if (ROWCOL_IN_ROW_AT_OR_BEFORE(r->selection.beg, r->screen.cur) || ROWCOL_IN_ROW_AT_OR_BEFORE(r->selection.end, r->screen.cur)) CLEAR_SELECTION(r); break; case 2: /* erase whole line */ col = 0; num = r->TermWin.ncol; r->screen.tlen[row] = 0; if (r->selection.beg.row <= r->screen.cur.row && r->selection.end.row >= r->screen.cur.row) CLEAR_SELECTION(r); break; default: return; } if (r->screen.text[row]) rxvt_blank_line(&(r->screen.text[row][col]), &(r->screen.rend[row][col]), num, r->h->rstyle); else rxvt_blank_screen_mem(r, r->screen.text, r->screen.rend, row, r->h->rstyle);}/* ------------------------------------------------------------------------- *//* * Erase part of whole of the screen * XTERM_SEQ: Clear screen after cursor : ESC [ 0 J * XTERM_SEQ: Clear screen before cursor: ESC [ 1 J * XTERM_SEQ: Clear whole screen : ESC [ 2 J *//* EXTPROTO */voidrxvt_scr_erase_screen(rxvt_t *r, int mode){ int num; int32_t row, row_offset; rend_t ren; XGCValues gcvalue; r->h->want_refresh = 1; D_SCREEN((stderr, "rxvt_scr_erase_screen(%d) at screen row: %d", mode, r->screen.cur.row)); ZERO_SCROLLBACK(r); RESET_CHSTAT(r->h); row_offset = (int32_t)r->TermWin.saveLines; switch (mode) { case 0: /* erase to end of screen */ rxvt_selection_check(r, 1); rxvt_scr_erase_line(r, 0); row = r->screen.cur.row + 1; /* possible OOB */ num = r->TermWin.nrow - row; break; case 1: /* erase to beginning of screen */ rxvt_selection_check(r, 3); rxvt_scr_erase_line(r, 1); row = 0; num = r->screen.cur.row; break; case 2: /* erase whole screen */ rxvt_selection_check(r, 3); rxvt_Gr_ClearScreen(r); row = 0; num = r->TermWin.nrow; break; default: return; } r->h->refresh_type |= REFRESH_BOUNDS; if (r->selection.op && r->h->current_screen == r->selection.screen && ((r->selection.beg.row >= row && r->selection.beg.row <= row + num) || (r->selection.end.row >= row && r->selection.end.row <= row + num))) CLEAR_SELECTION(r); if (row >= r->TermWin.nrow) /* Out Of Bounds */ return; MIN_IT(num, (r->TermWin.nrow - row)); if (r->h->rstyle & (RS_RVid | RS_Uline)) ren = (rend_t) ~RS_None; else if (GET_BASEBG(r->h->rstyle) == Color_bg) { ren = DEFAULT_RSTYLE; CLEAR_ROWS(row, num); } else { ren = (r->h->rstyle & (RS_fgMask | RS_bgMask)); gcvalue.foreground = r->PixColors[GET_BGCOLOR(r->h->rstyle)]; XChangeGC(r->Xdisplay, r->TermWin.gc, GCForeground, &gcvalue); ERASE_ROWS(row, num); gcvalue.foreground = r->PixColors[Color_fg]; XChangeGC(r->Xdisplay, r->TermWin.gc, GCForeground, &gcvalue); } for (; num--; row++) { rxvt_blank_screen_mem(r, r->screen.text, r->screen.rend, (unsigned int)(row + row_offset), r->h->rstyle); r->screen.tlen[row + row_offset] = 0; rxvt_blank_line(r->drawn_text[row], r->drawn_rend[row], (unsigned int)r->TermWin.ncol, ren); }}/* ------------------------------------------------------------------------- *//* * Fill the screen with `E's * XTERM_SEQ: Screen Alignment Test: ESC # 8 *//* EXTPROTO */voidrxvt_scr_E(rxvt_t *r){ int i, j, k; rend_t *r1, fs; r->h->want_refresh = 1; r->h->num_scr_allow = 0; ZERO_SCROLLBACK(r); RESET_CHSTAT(r->h); rxvt_selection_check(r, 3); fs = r->h->rstyle; for (k = r->TermWin.saveLines, i = r->TermWin.nrow; i--; k++) { r->screen.tlen[k] = r->TermWin.ncol; /* make the `E's selectable */ MEMSET(r->screen.text[k], 'E', r->TermWin.ncol); for (r1 = r->screen.rend[k], j = r->TermWin.ncol; j--; ) *r1++ = fs; }}/* ------------------------------------------------------------------------- *//* * Insert/Delete <count> lines *//* EXTPROTO */voidrxvt_scr_insdel_lines(rxvt_t *r, int count, int insdel){ int end; ZERO_SCROLLBACK(r); RESET_CHSTAT(r->h); if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, 0); rxvt_selection_check(r, 1); if (r->screen.cur.row > r->screen.bscroll) return; end = r->screen.bscroll - r->screen.cur.row + 1; if (count > end) { if (insdel == DELETE) return; else if (insdel == INSERT) count = end; } r->screen.flags &= ~Screen_WrapNext; rxvt_scroll_text(r, r->screen.cur.row, r->screen.bscroll, insdel * count, 0);}/* ------------------------------------------------------------------------- *//* * Insert/Delete <count> characters from the current position *//* EXTPROTO */voidrxvt_scr_insdel_chars(rxvt_t *r, int count, int insdel){ int col, row; rend_t tr; text_t *stp; rend_t *srp; int16_t *slp; r->h->want_refresh = 1; ZERO_SCROLLBACK(r);#if 0 RESET_CHSTAT(r->h);#endif if (rxvt_Gr_Displayed(r)) rxvt_Gr_scroll(r, 0); if (count <= 0) return; rxvt_selection_check(r, 1); MIN_IT(count, (r->TermWin.ncol - r->screen.cur.col)); row = r->screen.cur.row + r->TermWin.saveLines; r->screen.flags &= ~Screen_WrapNext; stp = r->screen.text[row]; srp = r->screen.rend[row]; slp = &(r->screen.tlen[row]); switch (insdel) { case INSERT: for (col = r->TermWin.ncol - 1; (col - count) >= r->screen.cur.col; col--) { stp[col] = stp[col - count]; srp[col] = srp[col - count]; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -