📄 lystrings.c
字号:
switch(c) { case KEY_DOWN: /* The four arrow keys ... */ c = DNARROW; break; case KEY_UP: c = UPARROW; break; case KEY_LEFT: c = LTARROW; break; case KEY_RIGHT: /* ... */ c = RTARROW; break; case KEY_HOME: /* Home key (upward+left arrow) */ c = HOME; break; case KEY_CLEAR: /* Clear screen */ c = 18; /* CTRL-R */ break; case KEY_NPAGE: /* Next page */ c = PGDOWN; break; case KEY_PPAGE: /* Previous page */ c = PGUP; break; case KEY_LL: /* home down or bottom (lower left) */ c = END; break; /* The keypad is arranged like this:*/ /* a1 up a3 */ /* left b2 right */ /* c1 down c3 */ case KEY_A1: /* upper left of keypad */ c = HOME; break; case KEY_A3: /* upper right of keypad */ c = PGUP; break; case KEY_B2: /* center of keypad */ c = DO_NOTHING; break; case KEY_C1: /* lower left of keypad */ c = END; break; case KEY_C3: /* lower right of keypad */ c = PGDOWN; break;#ifdef KEY_END case KEY_END: /* end key 001 */ c = END; break;#endif /* KEY_END */#ifdef KEY_HELP case KEY_HELP: /* help key 001 */ c = F1; break;#endif /* KEY_HELP */#ifdef KEY_BACKSPACE case KEY_BACKSPACE: c = 127; /* backspace key (delete, not Ctrl-H) */ break;#endif /* KEY_BACKSPACE */#ifdef KEY_F case KEY_F(1): c = F1; /* VTxxx Help */ break; case KEY_F(16): c = DO_KEY; /* VTxxx Do */ break;#endif /* KEY_F */#ifdef KEY_REDO case KEY_REDO: /* VTxxx Do */ c = DO_KEY; break;#endif /* KEY_REDO */#ifdef KEY_FIND case KEY_FIND: c = FIND_KEY; /* VTxxx Find */ break;#endif /* KEY_FIND */#ifdef KEY_SELECT case KEY_SELECT: c = SELECT_KEY; /* VTxxx Select */ break;#endif /* KEY_SELECT */#ifdef KEY_IC case KEY_IC: c = INSERT_KEY; /* VTxxx Insert */ break;#endif /* KEY_IC */#ifdef KEY_DC case KEY_DC: c = REMOVE_KEY; /* VTxxx Remove */ break;#endif /* KEY_DC */#ifdef NCURSES_MOUSE_VERSION case KEY_MOUSE: {#ifndef DOSPATH MEVENT event; int err; c = -1; mouse_link = -1; err=getmouse(&event); if (event.bstate & BUTTON1_CLICKED) { c = set_clicked_link(event.x, event.y); } else if (event.bstate & BUTTON3_CLICKED) { c = map_function_to_key (LYK_PREV_DOC); }#else /* pdcurses version */ int left,right; /* yes, I am assuming that my screen will be a certain width. */ left = 6; right = LYcols-6; c = -1; mouse_link = -1; request_mouse_pos(); if (Mouse_status.button[0] & BUTTON_CLICKED) { if (Mouse_status.y == (LYlines-1)) if (Mouse_status.x < left) c=LTARROW; else if (Mouse_status.x > right) c='\b'; else c=PGDOWN; else if (Mouse_status.y == 0) if (Mouse_status.x < left) c=LTARROW; else if (Mouse_status.x > right) c='\b'; else c=PGUP; else c = set_clicked_link(Mouse_status.x, Mouse_status.y); }#endif /* _WINDOWS */ } break;#endif /* NCURSES_MOUSE_VERSION */ } }#endif /* HAVE_KEYPAD */ if (c > DO_NOTHING) { /* * Don't return raw values for KEYPAD symbols which we may have * missed in the switch above if they are obviously invalid when * used as an index into (e.g.) keypad[]. - KW */ return (0); } else { return(c); }}/*** Display the current value of the string and allow the user** to edit it.*/#define EDREC EditFieldData/* * Shorthand to get rid of all most of the "edit->suchandsos". */#define Buf edit->buffer#define Pos edit->pos#define StrLen edit->strlen#define MaxLen edit->maxlen#define DspWdth edit->dspwdth#define DspStart edit->xpan#define Margin edit->marginPUBLIC void LYSetupEdit ARGS4( EDREC *, edit, char *, old, int, maxstr, int, maxdsp){ /* * Initialize edit record */ LYGetYX(edit->sy, edit->sx); edit->pad = ' '; edit->dirty = TRUE; edit->panon = FALSE; StrLen = strlen(old); MaxLen = maxstr; DspWdth = maxdsp; Margin = 0; Pos = strlen(old); DspStart = 0; if (maxstr > maxdsp) { /* Need panning? */ if (DspWdth > 4) /* Else "{}" take up precious screen space */ edit->panon = TRUE; /* * Figure out margins. If too big, we do a lot of unnecessary * scrolling. If too small, user doesn't have sufficient * look-ahead. Let's say 25% for each margin, upper bound is * 10 columns. */ Margin = DspWdth/4; if (Margin > 10) Margin = 10; } /* * We expect the called function to pass us a default (old) value * with a length that is less than or equal to maxstr, and to * handle any messaging associated with actions to achieve that * requirement. However, in case the calling function screwed * up, we'll check it here, and ensure that no buffer overrun can * occur by loading only as much of the head as fits. - FM */ if (strlen(old) >= maxstr) { strncpy(edit->buffer, old, maxstr); edit->buffer[maxstr] = '\0'; StrLen = maxstr; } else { strcpy(edit->buffer, old); }}PUBLIC int LYEdit1 ARGS4( EDREC *, edit, int, ch, int, action, BOOL, maxMessage){ /* returns 0 character processed * ch otherwise */ int i; int length; if (MaxLen <= 0) return(0); /* Be defensive */ length=strlen(&Buf[0]); StrLen = length; switch (action) { case LYE_AIX: /* * Hex 97. * Fall through as a character for CJK, or if this is a valid * character in the current display character set. * Otherwise, we treat this as LYE_ENTER. */ if (HTCJK == NOCJK && LYlowest_eightbit[current_char_set] > 0x97) return(ch); case LYE_CHAR: /* * ch is printable or ISO-8859-1 escape character. */ if (Pos <= (MaxLen) && StrLen < (MaxLen)) { for(i = length; i >= Pos; i--) /* Make room */ Buf[i+1] = Buf[i]; Buf[length+1]='\0'; Buf[Pos] = (unsigned char) ch; Pos++; } else if (maxMessage) { _statusline(MAXLEN_REACHED_DEL_OR_MOV); } break; case LYE_BACKW: /* * Backword. * Definition of word is very naive: 1 or more a/n characters. */ while (Pos && !isalnum(Buf[Pos-1])) Pos--; while (Pos && isalnum(Buf[Pos-1])) Pos--; break; case LYE_FORWW: /* * Word forward. */ while (isalnum(Buf[Pos])) Pos++; /* '\0' is not a/n */ while (!isalnum(Buf[Pos]) && Buf[Pos]) Pos++ ; break; case LYE_ERASE: /* * Erase the line to start fresh. */ Buf[0] = '\0'; /* fall through */ case LYE_BOL: /* * Go to first column. */ Pos = 0; break; case LYE_EOL: /* * Go to last column. */ Pos = length; break; case LYE_DELNW: /* * Delete next word. */ { int pos0 = Pos; LYEdit1 (edit, 0, LYE_FORWW, FALSE); while (Pos > pos0) LYEdit1(edit, 0, LYE_DELP, FALSE); } break; case LYE_DELPW: /* * Delete previous word. */ { int pos0 = Pos; LYEdit1 (edit, 0, LYE_BACKW, FALSE); pos0 -= Pos; while (pos0--) LYEdit1(edit, 0, LYE_DELN, FALSE); } break; case LYE_DELN: /* * Delete next character */ if (Pos >= length) break; Pos++; /* fall through */ case LYE_DELP: /* * Delete preceding character. */ if (length == 0 || Pos == 0) break; Pos--; for (i = Pos; i < length; i++) Buf[i] = Buf[i+1]; i--; Buf[i] = 0; break; case LYE_DELC: /* * Delete current character. */ if (length == 0 || Pos == length) break; for (i = Pos; i < length; i++) Buf[i] = Buf[i+1]; i--; Buf[i] = 0; break; case LYE_FORW: /* * Move cursor to the right. */ if (Pos < length) Pos++; break; case LYE_BACK: /* * Left-arrow move cursor to the left. */ if (Pos > 0) Pos--; break; case LYE_UPPER: for (i = 0; Buf[i]; i++) Buf[i] = TOUPPER(Buf[i]); break; case LYE_LOWER: for (i = 0; Buf[i]; i++) Buf[i] = TOLOWER(Buf[i]); break; default: return(ch); } edit->dirty = TRUE; StrLen = strlen(&Buf[0]); return(0);}PUBLIC void LYRefreshEdit ARGS1( EDREC *, edit){ int i; int length; int nrdisplayed; int padsize; char *str; char buffer[3]; buffer[0] = buffer[1] = buffer[2] = '\0'; if (!edit->dirty || (DspWdth == 0)) return; edit->dirty = FALSE; length=strlen(&Buf[0]); edit->strlen = length;/* * Now we have: * .--DspWdth---. * +---------+=============+-----------+ * | |M M| | (M=margin) * +---------+=============+-----------+ * 0 DspStart length * * Insertion point can be anywhere between 0 and stringlength. * Figure out new display starting point. * * The first "if" below makes Lynx scroll several columns at a time when * extending the string. Looks awful, but that way we can keep up with * data entry at low baudrates. */ if ((DspStart + DspWdth) <= length) if (Pos >= (DspStart + DspWdth) - Margin) DspStart=(Pos - DspWdth) + Margin; if (Pos < DspStart + Margin) { DspStart = Pos - Margin; if (DspStart < 0) DspStart = 0; } str = &Buf[DspStart]; nrdisplayed = length-DspStart; if (nrdisplayed > DspWdth) nrdisplayed = DspWdth; move(edit->sy, edit->sx); if (edit->hidden) { for (i = 0; i < nrdisplayed; i++) addch('*'); } else { for (i = 0; i < nrdisplayed; i++) if ((buffer[0] = str[i]) == 1 || buffer[0] == 2 || ((unsigned char)buffer[0] == 160 && !(HTPassHighCtrlRaw || HTCJK != NOCJK || (LYCharSet_UC[current_char_set].enc != UCT_ENC_8859 && !(LYCharSet_UC[current_char_set].like8859 & UCT_R_8859SPECL))))) { addch(' '); } else { /* For CJK strings, by Masanobu Kimura */ if (HTCJK != NOCJK && !isascii(buffer[0])) { if (i < (nrdisplayed - 1)) buffer[1] = str[++i]; addstr(buffer); buffer[1] = '\0'; } else { addstr(buffer); } } } /* * Erase rest of input area. */ padsize = DspWdth-nrdisplayed; while (padsize--) addch((unsigned char)edit->pad); /* * Scrolling indicators. */ if (edit->panon) { if ((DspStart + nrdisplayed) < length) { move(edit->sy, edit->sx+nrdisplayed-1); addch('}'); } if (DspStart) { move(edit->sy, edit->sx); addch('{'); } } move(edit->sy, edit->sx + Pos - DspStart); refresh();}PUBLIC int LYgetstr ARGS4( char *, inputline, int, hidden, size_t, bufsize, int, recall){ int x, y, MaxStringSize; int ch; EditFieldData MyEdit; LYGetYX(y, x); /* Use screen from cursor position to eol */ MaxStringSize = (bufsize < sizeof(MyEdit.buffer)) ? (bufsize - 1) : (sizeof(MyEdit.buffer) - 1); LYSetupEdit(&MyEdit, inputline, MaxStringSize, (LYcols-1)-x); MyEdit.hidden = hidden ; for (;;) {again: LYRefreshEdit(&MyEdit); ch = LYgetch();#ifdef VMS if (term_letter || term_options || term_message || HadVMSInterrupt) { HadVMSInterrupt = FALSE; ch = 7; }#else if (term_letter || term_options || term_message) ch = 7;#endif /* VMS */ if (recall && (ch == UPARROW || ch == DNARROW)) { strcpy(inputline, MyEdit.buffer); return(ch); } if (keymap[ch + 1] == LYK_REFRESH) goto again; switch (EditBinding(ch)) { case LYE_TAB: ch = '\t'; /* fall through */ case LYE_AIX: /* * Hex 97. * Treat as a character for CJK, or if this is a valid * character in the current display character set. * Otherwise, we treat this as LYE_ENTER. */ if (ch != '\t' && (HTCJK != NOCJK || LYlowest_eightbit[current_char_set] <= 0x97)) { LYLineEdit(&MyEdit,ch, FALSE); break; } case LYE_ENTER: /* * Terminate the string and return. */ strcpy(inputline, MyEdit.buffer); return(ch); break; case LYE_ABORT: /*
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -