📄 selection.c
字号:
else { EditExistingFile(WindowList, filename, pathname, 0, NULL, False, NULL); } } for (i=0; i<nFiles; i++) { XtFree(nameList[i]); } XtFree((char *)nameList); }#else { glob_t globbuf; int i; glob(nameText, GLOB_NOCHECK, NULL, &globbuf); for (i=0; i<(int)globbuf.gl_pathc; i++) { if (ParseFilename(globbuf.gl_pathv[i], filename, pathname) != 0) XBell(TheDisplay, 0); else EditExistingFile(WindowList, filename, pathname, 0, NULL, False, NULL); } globfree(&globbuf); }#endif CheckCloseDim();}static void getAnySelectionCB(Widget widget, char **result, Atom *sel, Atom *type, char *value, int *length, int *format){ /* Confirm that the returned value is of the correct type */ if (*type != XA_STRING || *format != 8) { XBell(TheDisplay, 0); if (value != NULL) XtFree((char *)value); *result = NULL; return; } /* Append a null, and return the string */ *result = XtMalloc(*length + 1); strncpy(*result, value, *length); XtFree(value); (*result)[*length] = '\0';}void SelectNumberedLine(WindowInfo *window, int lineNum){ int i, lineStart = 0, lineEnd; /* count lines to find the start and end positions for the selection */ if (lineNum < 1) lineNum = 1; lineEnd = -1; for (i=1; i<=lineNum && lineEnd<window->buffer->length; i++) { lineStart = lineEnd + 1; lineEnd = BufEndOfLine(window->buffer, lineStart); } /* highlight the line */ if (i>lineNum) { /* Line was found */ if (lineEnd < window->buffer->length) { BufSelect(window->buffer, lineStart, lineEnd+1); } else { /* Don't select past the end of the buffer ! */ BufSelect(window->buffer, lineStart, window->buffer->length); } } else { /* Line was not found -> position the selection & cursor at the end without making a real selection and beep */ lineStart = window->buffer->length; BufSelect(window->buffer, lineStart, lineStart); XBell(TheDisplay, 0); } MakeSelectionVisible(window, window->lastFocus); TextSetCursorPos(window->lastFocus, lineStart);}void MarkDialog(WindowInfo *window){ char letterText[DF_MAX_PROMPT_LENGTH], *params[1]; int response; response = DialogF(DF_PROMPT, window->shell, 2, "Mark", "Enter a single letter label to use for recalling\n" "the current selection and cursor position.\n\n" "(To skip this dialog, use the accelerator key,\n" "followed immediately by a letter key (a-z))", letterText, "OK", "Cancel"); if (response == 2) return; if (strlen(letterText) != 1 || !isalpha((unsigned char)letterText[0])) { XBell(TheDisplay, 0); return; } params[0] = letterText; XtCallActionProc(window->lastFocus, "mark", NULL, params, 1);}void GotoMarkDialog(WindowInfo *window, int extend){ char letterText[DF_MAX_PROMPT_LENGTH], *params[2]; int response; response = DialogF(DF_PROMPT, window->shell, 2, "Goto Mark", "Enter the single letter label used to mark\n" "the selection and/or cursor position.\n\n" "(To skip this dialog, use the accelerator\n" "key, followed immediately by the letter)", letterText, "OK", "Cancel"); if (response == 2) return; if (strlen(letterText) != 1 || !isalpha((unsigned char)letterText[0])) { XBell(TheDisplay, 0); return; } params[0] = letterText; params[1] = "extend"; XtCallActionProc(window->lastFocus, "goto_mark", NULL, params, extend ? 2 : 1);}/*** Process a command to mark a selection. Expects the user to continue** the command by typing a label character. Handles both correct user** behavior (type a character a-z) or bad behavior (do nothing or type** something else).*/void BeginMarkCommand(WindowInfo *window){ XtInsertEventHandler(window->lastFocus, KeyPressMask, False, markKeyCB, window, XtListHead); window->markTimeoutID = XtAppAddTimeOut( XtWidgetToApplicationContext(window->shell), 4000, markTimeoutProc, window->lastFocus);}/*** Process a command to go to a marked selection. Expects the user to** continue the command by typing a label character. Handles both correct** user behavior (type a character a-z) or bad behavior (do nothing or type** something else).*/void BeginGotoMarkCommand(WindowInfo *window, int extend){ XtInsertEventHandler(window->lastFocus, KeyPressMask, False, extend ? gotoMarkExtendKeyCB : gotoMarkKeyCB, window, XtListHead); window->markTimeoutID = XtAppAddTimeOut( XtWidgetToApplicationContext(window->shell), 4000, markTimeoutProc, window->lastFocus);}/*** Xt timer procedure for removing event handler if user failed to type a** mark character withing the allowed time*/static void markTimeoutProc(XtPointer clientData, XtIntervalId *id){ Widget w = (Widget)clientData; WindowInfo *window = WidgetToWindow(w); XtRemoveEventHandler(w, KeyPressMask, False, markKeyCB, window); XtRemoveEventHandler(w, KeyPressMask, False, gotoMarkKeyCB, window); XtRemoveEventHandler(w, KeyPressMask, False, gotoMarkExtendKeyCB, window); window->markTimeoutID = 0;}/*** Temporary event handlers for keys pressed after the mark or goto-mark** commands, If the key is valid, grab the key event and call the action** procedure to mark (or go to) the selection, otherwise, remove the handler** and give up.*/static void processMarkEvent(Widget w, XtPointer clientData, XEvent *event, Boolean *continueDispatch, char *action, int extend){ XKeyEvent *e = (XKeyEvent *)event; WindowInfo *window = WidgetToWindow(w); Modifiers modifiers; KeySym keysym; char *params[2], string[2]; XtTranslateKeycode(TheDisplay, e->keycode, e->state, &modifiers, &keysym); if ((keysym >= 'A' && keysym <= 'Z') || (keysym >= 'a' && keysym <= 'z')) { string[0] = toupper(keysym); string[1] = '\0'; params[0] = string; params[1] = "extend"; XtCallActionProc(window->lastFocus, action, event, params, extend ? 2 : 1); *continueDispatch = False; } XtRemoveEventHandler(w, KeyPressMask, False, markKeyCB, window); XtRemoveEventHandler(w, KeyPressMask, False, gotoMarkKeyCB, window); XtRemoveEventHandler(w, KeyPressMask, False, gotoMarkExtendKeyCB, window); XtRemoveTimeOut(window->markTimeoutID);}static void markKeyCB(Widget w, XtPointer clientData, XEvent *event, Boolean *continueDispatch){ processMarkEvent(w, clientData, event, continueDispatch, "mark", False);}static void gotoMarkKeyCB(Widget w, XtPointer clientData, XEvent *event, Boolean *continueDispatch){ processMarkEvent(w, clientData, event, continueDispatch, "goto_mark",False);}static void gotoMarkExtendKeyCB(Widget w, XtPointer clientData, XEvent *event, Boolean *continueDispatch){ processMarkEvent(w, clientData, event, continueDispatch, "goto_mark", True);}void AddMark(WindowInfo *window, Widget widget, char label){ int index; /* look for a matching mark to re-use, or advance nMarks to create a new one */ label = toupper(label); for (index=0; index<window->nMarks; index++) { if (window->markTable[index].label == label) break; } if (index >= MAX_MARKS) { fprintf(stderr, "no more marks allowed\n"); /* shouldn't happen */ return; } if (index == window->nMarks) window->nMarks++; /* store the cursor location and selection position in the table */ window->markTable[index].label = label; memcpy(&window->markTable[index].sel, &window->buffer->primary, sizeof(selection)); window->markTable[index].cursorPos = TextGetCursorPos(widget);}void GotoMark(WindowInfo *window, Widget w, char label, int extendSel){ int index, oldStart, newStart, oldEnd, newEnd, cursorPos; selection *sel, *oldSel; /* look up the mark in the mark table */ label = toupper(label); for (index=0; index<window->nMarks; index++) { if (window->markTable[index].label == label) break; } if (index == window->nMarks) { XBell(TheDisplay, 0); return; } /* reselect marked the selection, and move the cursor to the marked pos */ sel = &window->markTable[index].sel; oldSel = &window->buffer->primary; cursorPos = window->markTable[index].cursorPos; if (extendSel) { oldStart = oldSel->selected ? oldSel->start : TextGetCursorPos(w); oldEnd = oldSel->selected ? oldSel->end : TextGetCursorPos(w); newStart = sel->selected ? sel->start : cursorPos; newEnd = sel->selected ? sel->end : cursorPos; BufSelect(window->buffer, oldStart < newStart ? oldStart : newStart, oldEnd > newEnd ? oldEnd : newEnd); } else { if (sel->selected) { if (sel->rectangular) BufRectSelect(window->buffer, sel->start, sel->end, sel->rectStart, sel->rectEnd); else BufSelect(window->buffer, sel->start, sel->end); } else BufUnselect(window->buffer); } /* Move the window into a pleasing position relative to the selection or cursor. MakeSelectionVisible is not great with multi-line selections, and here we will sometimes give it one. And to set the cursor position without first using the less pleasing capability of the widget itself for bringing the cursor in to view, you have to first turn it off, set the position, then turn it back on. */ XtVaSetValues(w, textNautoShowInsertPos, False, NULL); TextSetCursorPos(w, cursorPos); MakeSelectionVisible(window, window->lastFocus); XtVaSetValues(w, textNautoShowInsertPos, True, NULL);}/*** Keep the marks in the windows book-mark table up to date across** changes to the underlying buffer*/void UpdateMarkTable(WindowInfo *window, int pos, int nInserted, int nDeleted){ int i; for (i=0; i<window->nMarks; i++) { maintainSelection(&window->markTable[i].sel, pos, nInserted, nDeleted); maintainPosition(&window->markTable[i].cursorPos, pos, nInserted, nDeleted); }}/*** Update a selection across buffer modifications specified by** "pos", "nDeleted", and "nInserted".*/static void maintainSelection(selection *sel, int pos, int nInserted, int nDeleted){ if (!sel->selected || pos > sel->end) return; maintainPosition(&sel->start, pos, nInserted, nDeleted); maintainPosition(&sel->end, pos, nInserted, nDeleted); if (sel->end <= sel->start) sel->selected = False;}/*** Update a position across buffer modifications specified by** "modPos", "nDeleted", and "nInserted".*/static void maintainPosition(int *position, int modPos, int nInserted, int nDeleted){ if (modPos > *position) return; if (modPos+nDeleted <= *position) *position += nInserted - nDeleted; else *position = modPos;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -