📄 textbuf.c
字号:
memcpy(&toBuf->buf[toPos], &fromBuf->buf[fromStart], length); } else if (fromStart >= fromBuf->gapStart) { memcpy(&toBuf->buf[toPos], &fromBuf->buf[fromStart+(fromBuf->gapEnd-fromBuf->gapStart)], length); } else { part1Length = fromBuf->gapStart - fromStart; memcpy(&toBuf->buf[toPos], &fromBuf->buf[fromStart], part1Length); memcpy(&toBuf->buf[toPos+part1Length], &fromBuf->buf[fromBuf->gapEnd], length-part1Length); } toBuf->gapStart += length; toBuf->length += length; updateSelections(toBuf, toPos, 0, length);} /*** Insert "text" columnwise into buffer starting at displayed character** position "column" on the line beginning at "startPos". Opens a rectangular** space the width and height of "text", by moving all text to the right of** "column" right. If charsInserted and charsDeleted are not NULL, the** number of characters inserted and deleted in the operation (beginning** at startPos) are returned in these arguments*/void BufInsertCol(textBuffer *buf, int column, int startPos, const char *text, int *charsInserted, int *charsDeleted){ int nLines, lineStartPos, nDeleted, insertDeleted, nInserted; char *deletedText; nLines = countLines(text); lineStartPos = BufStartOfLine(buf, startPos); nDeleted = BufEndOfLine(buf, BufCountForwardNLines(buf, startPos, nLines)) - lineStartPos; callPreDeleteCBs(buf, lineStartPos, nDeleted); deletedText = BufGetRange(buf, lineStartPos, lineStartPos + nDeleted); insertCol(buf, column, lineStartPos, text, &insertDeleted, &nInserted, &buf->cursorPosHint); if (nDeleted != insertDeleted) fprintf(stderr, "NEdit internal consistency check ins1 failed"); callModifyCBs(buf, lineStartPos, nDeleted, nInserted, 0, deletedText); XtFree(deletedText); if (charsInserted != NULL) *charsInserted = nInserted; if (charsDeleted != NULL) *charsDeleted = nDeleted;}/*** Overlay "text" between displayed character positions "rectStart" and** "rectEnd" on the line beginning at "startPos". If charsInserted and** charsDeleted are not NULL, the number of characters inserted and deleted** in the operation (beginning at startPos) are returned in these arguments.** If rectEnd equals -1, the width of the inserted text is measured first.*/void BufOverlayRect(textBuffer *buf, int startPos, int rectStart, int rectEnd, const char *text, int *charsInserted, int *charsDeleted){ int nLines, lineStartPos, nDeleted, insertDeleted, nInserted; char *deletedText; nLines = countLines(text); lineStartPos = BufStartOfLine(buf, startPos); if(rectEnd == -1) rectEnd = rectStart + textWidth(text, buf->tabDist, buf->nullSubsChar); lineStartPos = BufStartOfLine(buf, startPos); nDeleted = BufEndOfLine(buf, BufCountForwardNLines(buf, startPos, nLines)) - lineStartPos; callPreDeleteCBs(buf, lineStartPos, nDeleted); deletedText = BufGetRange(buf, lineStartPos, lineStartPos + nDeleted); overlayRect(buf, lineStartPos, rectStart, rectEnd, text, &insertDeleted, &nInserted, &buf->cursorPosHint); if (nDeleted != insertDeleted) fprintf(stderr, "NEdit internal consistency check ovly1 failed"); callModifyCBs(buf, lineStartPos, nDeleted, nInserted, 0, deletedText); XtFree(deletedText); if (charsInserted != NULL) *charsInserted = nInserted; if (charsDeleted != NULL) *charsDeleted = nDeleted;}/*** Replace a rectangular area in buf, given by "start", "end", "rectStart",** and "rectEnd", with "text". If "text" is vertically longer than the** rectangle, add extra lines to make room for it.*/void BufReplaceRect(textBuffer *buf, int start, int end, int rectStart, int rectEnd, const char *text){ char *deletedText; char *insText=NULL; int i, nInsertedLines, nDeletedLines, insLen, hint; int insertDeleted, insertInserted, deleteInserted; int linesPadded = 0; /* Make sure start and end refer to complete lines, since the columnar delete and insert operations will replace whole lines */ start = BufStartOfLine(buf, start); end = BufEndOfLine(buf, end); callPreDeleteCBs(buf, start, end-start); /* If more lines will be deleted than inserted, pad the inserted text with newlines to make it as long as the number of deleted lines. This will indent all of the text to the right of the rectangle to the same column. If more lines will be inserted than deleted, insert extra lines in the buffer at the end of the rectangle to make room for the additional lines in "text" */ nInsertedLines = countLines(text); nDeletedLines = BufCountLines(buf, start, end); if (nInsertedLines < nDeletedLines) { char *insPtr; insLen = strlen(text); insText = XtMalloc(insLen + nDeletedLines - nInsertedLines + 1); strcpy(insText, text); insPtr = insText + insLen; for (i=0; i<nDeletedLines-nInsertedLines; i++) *insPtr++ = '\n'; *insPtr = '\0'; } else if (nDeletedLines < nInsertedLines) { linesPadded = nInsertedLines-nDeletedLines; for (i=0; i<linesPadded; i++) insert(buf, end, "\n"); } else /* nDeletedLines == nInsertedLines */ { } /* Save a copy of the text which will be modified for the modify CBs */ deletedText = BufGetRange(buf, start, end); /* Delete then insert */ deleteRect(buf, start, end, rectStart, rectEnd, &deleteInserted, &hint); if (insText) { insertCol(buf, rectStart, start, insText, &insertDeleted, &insertInserted, &buf->cursorPosHint); XtFree(insText); } else insertCol(buf, rectStart, start, text, &insertDeleted, &insertInserted, &buf->cursorPosHint); /* Figure out how many chars were inserted and call modify callbacks */ if (insertDeleted != deleteInserted + linesPadded) fprintf(stderr, "NEdit: internal consistency check repl1 failed\n"); callModifyCBs(buf, start, end-start, insertInserted, 0, deletedText); XtFree(deletedText);}/*** Remove a rectangular swath of characters between character positions start** and end and horizontal displayed-character offsets rectStart and rectEnd.*/void BufRemoveRect(textBuffer *buf, int start, int end, int rectStart, int rectEnd){ char *deletedText; int nInserted; start = BufStartOfLine(buf, start); end = BufEndOfLine(buf, end); callPreDeleteCBs(buf, start, end-start); deletedText = BufGetRange(buf, start, end); deleteRect(buf, start, end, rectStart, rectEnd, &nInserted, &buf->cursorPosHint); callModifyCBs(buf, start, end-start, nInserted, 0, deletedText); XtFree(deletedText);}/*** Clear a rectangular "hole" out of the buffer between character positions** start and end and horizontal displayed-character offsets rectStart and** rectEnd.*/void BufClearRect(textBuffer *buf, int start, int end, int rectStart, int rectEnd){ int i, nLines; char *newlineString; nLines = BufCountLines(buf, start, end); newlineString = XtMalloc(nLines+1); for (i=0; i<nLines; i++) newlineString[i] = '\n'; newlineString[i] = '\0'; BufOverlayRect(buf, start, rectStart, rectEnd, newlineString, NULL, NULL); XtFree(newlineString);}char *BufGetTextInRect(textBuffer *buf, int start, int end, int rectStart, int rectEnd){ int lineStart, selLeft, selRight, len; char *textOut, *textIn, *outPtr, *retabbedStr; start = BufStartOfLine(buf, start); end = BufEndOfLine(buf, end); textOut = XtMalloc((end - start) + 1); lineStart = start; outPtr = textOut; while (lineStart <= end) { findRectSelBoundariesForCopy(buf, lineStart, rectStart, rectEnd, &selLeft, &selRight); textIn = BufGetRange(buf, selLeft, selRight); len = selRight - selLeft; memcpy(outPtr, textIn, len); XtFree(textIn); outPtr += len; lineStart = BufEndOfLine(buf, selRight) + 1; *outPtr++ = '\n'; } if (outPtr != textOut) outPtr--; /* don't leave trailing newline */ *outPtr = '\0'; /* If necessary, realign the tabs in the selection as if the text were positioned at the left margin */ retabbedStr = realignTabs(textOut, rectStart, 0, buf->tabDist, buf->useTabs, buf->nullSubsChar, &len); XtFree(textOut); return retabbedStr;}/*** Get the hardware tab distance used by all displays for this buffer,** and used in computing offsets for rectangular selection operations.*/int BufGetTabDistance(textBuffer *buf){ return buf->tabDist;}/*** Set the hardware tab distance used by all displays for this buffer,** and used in computing offsets for rectangular selection operations.*/void BufSetTabDistance(textBuffer *buf, int tabDist){ char *deletedText; /* First call the pre-delete callbacks with the previous tab setting still active. */ callPreDeleteCBs(buf, 0, buf->length); /* Change the tab setting */ buf->tabDist = tabDist; /* Force any display routines to redisplay everything (unfortunately, this means copying the whole buffer contents to provide "deletedText" */ deletedText = BufGetAll(buf); callModifyCBs(buf, 0, buf->length, buf->length, 0, deletedText); XtFree(deletedText);}void BufCheckDisplay(textBuffer *buf, int start, int end){ /* just to make sure colors in the selected region are up to date */ callModifyCBs(buf, start, 0, 0, end-start, NULL);}void BufSelect(textBuffer *buf, int start, int end){ selection oldSelection = buf->primary; setSelection(&buf->primary, start, end); redisplaySelection(buf, &oldSelection, &buf->primary);}void BufUnselect(textBuffer *buf){ selection oldSelection = buf->primary; buf->primary.selected = False; buf->primary.zeroWidth = False; redisplaySelection(buf, &oldSelection, &buf->primary);}void BufRectSelect(textBuffer *buf, int start, int end, int rectStart, int rectEnd){ selection oldSelection = buf->primary; setRectSelect(&buf->primary, start, end, rectStart, rectEnd); redisplaySelection(buf, &oldSelection, &buf->primary);}int BufGetSelectionPos(textBuffer *buf, int *start, int *end, int *isRect, int *rectStart, int *rectEnd){ return getSelectionPos(&buf->primary, start, end, isRect, rectStart, rectEnd);}/* Same as above, but also returns TRUE for empty selections */int BufGetEmptySelectionPos(textBuffer *buf, int *start, int *end, int *isRect, int *rectStart, int *rectEnd){ return getSelectionPos(&buf->primary, start, end, isRect, rectStart, rectEnd) || buf->primary.zeroWidth;}char *BufGetSelectionText(textBuffer *buf){ return getSelectionText(buf, &buf->primary);}void BufRemoveSelected(textBuffer *buf){ removeSelected(buf, &buf->primary);}void BufReplaceSelected(textBuffer *buf, const char *text){ replaceSelected(buf, &buf->primary, text);}void BufSecondarySelect(textBuffer *buf, int start, int end){ selection oldSelection = buf->secondary; setSelection(&buf->secondary, start, end); redisplaySelection(buf, &oldSelection, &buf->secondary);}void BufSecondaryUnselect(textBuffer *buf){ selection oldSelection = buf->secondary; buf->secondary.selected = False; buf->secondary.zeroWidth = False; redisplaySelection(buf, &oldSelection, &buf->secondary);}void BufSecRectSelect(textBuffer *buf, int start, int end, int rectStart, int rectEnd){ selection oldSelection = buf->secondary; setRectSelect(&buf->secondary, start, end, rectStart, rectEnd); redisplaySelection(buf, &oldSelection, &buf->secondary);}int BufGetSecSelectPos(textBuffer *buf, int *start, int *end, int *isRect, int *rectStart, int *rectEnd){ return getSelectionPos(&buf->secondary, start, end, isRect, rectStart, rectEnd);}char *BufGetSecSelectText(textBuffer *buf){ return getSelectionText(buf, &buf->secondary);}void BufRemoveSecSelect(textBuffer *buf){ removeSelected(buf, &buf->secondary);}void BufReplaceSecSelect(textBuffer *buf, const char *text){ replaceSelected(buf, &buf->secondary, text);}void BufHighlight(textBuffer *buf, int start, int end){ selection oldSelection = buf->highlight; setSelection(&buf->highlight, start, end); redisplaySelection(buf, &oldSelection, &buf->highlight);}void BufUnhighlight(textBuffer *buf){ selection oldSelection = buf->highlight; buf->highlight.selected = False; buf->highlight.zeroWidth = False; redisplaySelection(buf, &oldSelection, &buf->highlight);}void BufRectHighlight(textBuffer *buf, int start, int end,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -