📄 textbuf.c
字号:
int rectStart, int rectEnd){ selection oldSelection = buf->highlight; setRectSelect(&buf->highlight, start, end, rectStart, rectEnd); redisplaySelection(buf, &oldSelection, &buf->highlight);}int BufGetHighlightPos(textBuffer *buf, int *start, int *end, int *isRect, int *rectStart, int *rectEnd){ return getSelectionPos(&buf->highlight, start, end, isRect, rectStart, rectEnd);}char *BufGetHighlightText(textBuffer *buf){ return getSelectionText(buf, &buf->highlight);}/*** Add a callback routine to be called when the buffer is modified*/void BufAddModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, void *cbArg){ bufModifyCallbackProc *newModifyProcs; void **newCBArgs; int i; newModifyProcs = (bufModifyCallbackProc *) XtMalloc(sizeof(bufModifyCallbackProc *) * (buf->nModifyProcs+1)); newCBArgs = (void *)XtMalloc(sizeof(void *) * (buf->nModifyProcs+1)); for (i=0; i<buf->nModifyProcs; i++) { newModifyProcs[i] = buf->modifyProcs[i]; newCBArgs[i] = buf->cbArgs[i]; } if (buf->nModifyProcs != 0) { XtFree((char *)buf->modifyProcs); XtFree((char *)buf->cbArgs); } newModifyProcs[buf->nModifyProcs] = bufModifiedCB; newCBArgs[buf->nModifyProcs] = cbArg; buf->nModifyProcs++; buf->modifyProcs = newModifyProcs; buf->cbArgs = newCBArgs;}/*** Similar to the above, but makes sure that the callback is called before** normal priority callbacks.*/void BufAddHighPriorityModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, void *cbArg){ bufModifyCallbackProc *newModifyProcs; void **newCBArgs; int i; newModifyProcs = (bufModifyCallbackProc *) XtMalloc(sizeof(bufModifyCallbackProc *) * (buf->nModifyProcs+1)); newCBArgs = (void *)XtMalloc(sizeof(void *) * (buf->nModifyProcs+1)); for (i=0; i<buf->nModifyProcs; i++) { newModifyProcs[i+1] = buf->modifyProcs[i]; newCBArgs[i+1] = buf->cbArgs[i]; } if (buf->nModifyProcs != 0) { XtFree((char *)buf->modifyProcs); XtFree((char *)buf->cbArgs); } newModifyProcs[0] = bufModifiedCB; newCBArgs[0] = cbArg; buf->nModifyProcs++; buf->modifyProcs = newModifyProcs; buf->cbArgs = newCBArgs;}void BufRemoveModifyCB(textBuffer *buf, bufModifyCallbackProc bufModifiedCB, void *cbArg){ int i, toRemove = -1; bufModifyCallbackProc *newModifyProcs; void **newCBArgs; /* find the matching callback to remove */ for (i=0; i<buf->nModifyProcs; i++) { if (buf->modifyProcs[i] == bufModifiedCB && buf->cbArgs[i] == cbArg) { toRemove = i; break; } } if (toRemove == -1) { fprintf(stderr, "NEdit Internal Error: Can't find modify CB to remove\n"); return; } /* Allocate new lists for remaining callback procs and args (if any are left) */ buf->nModifyProcs--; if (buf->nModifyProcs == 0) { buf->nModifyProcs = 0; XtFree((char *)buf->modifyProcs); buf->modifyProcs = NULL; XtFree((char *)buf->cbArgs); buf->cbArgs = NULL; return; } newModifyProcs = (bufModifyCallbackProc *) XtMalloc(sizeof(bufModifyCallbackProc *) * (buf->nModifyProcs)); newCBArgs = (void *)XtMalloc(sizeof(void *) * (buf->nModifyProcs)); /* copy out the remaining members and free the old lists */ for (i=0; i<toRemove; i++) { newModifyProcs[i] = buf->modifyProcs[i]; newCBArgs[i] = buf->cbArgs[i]; } for (; i<buf->nModifyProcs; i++) { newModifyProcs[i] = buf->modifyProcs[i+1]; newCBArgs[i] = buf->cbArgs[i+1]; } XtFree((char *)buf->modifyProcs); XtFree((char *)buf->cbArgs); buf->modifyProcs = newModifyProcs; buf->cbArgs = newCBArgs;}/*** Add a callback routine to be called before text is deleted from the buffer.*/void BufAddPreDeleteCB(textBuffer *buf, bufPreDeleteCallbackProc bufPreDeleteCB, void *cbArg){ bufPreDeleteCallbackProc *newPreDeleteProcs; void **newCBArgs; int i; newPreDeleteProcs = (bufPreDeleteCallbackProc *) XtMalloc(sizeof(bufPreDeleteCallbackProc *) * (buf->nPreDeleteProcs+1)); newCBArgs = (void *)XtMalloc(sizeof(void *) * (buf->nPreDeleteProcs+1)); for (i=0; i<buf->nPreDeleteProcs; i++) { newPreDeleteProcs[i] = buf->preDeleteProcs[i]; newCBArgs[i] = buf->preDeleteCbArgs[i]; } if (buf->nPreDeleteProcs != 0) { XtFree((char *)buf->preDeleteProcs); XtFree((char *)buf->preDeleteCbArgs); } newPreDeleteProcs[buf->nPreDeleteProcs] = bufPreDeleteCB; newCBArgs[buf->nPreDeleteProcs] = cbArg; buf->nPreDeleteProcs++; buf->preDeleteProcs = newPreDeleteProcs; buf->preDeleteCbArgs = newCBArgs;}void BufRemovePreDeleteCB(textBuffer *buf, bufPreDeleteCallbackProc bufPreDeleteCB, void *cbArg){ int i, toRemove = -1; bufPreDeleteCallbackProc *newPreDeleteProcs; void **newCBArgs; /* find the matching callback to remove */ for (i=0; i<buf->nPreDeleteProcs; i++) { if (buf->preDeleteProcs[i] == bufPreDeleteCB && buf->preDeleteCbArgs[i] == cbArg) { toRemove = i; break; } } if (toRemove == -1) { fprintf(stderr, "NEdit Internal Error: Can't find pre-delete CB to remove\n"); return; } /* Allocate new lists for remaining callback procs and args (if any are left) */ buf->nPreDeleteProcs--; if (buf->nPreDeleteProcs == 0) { buf->nPreDeleteProcs = 0; XtFree((char *)buf->preDeleteProcs); buf->preDeleteProcs = NULL; XtFree((char *)buf->preDeleteCbArgs); buf->preDeleteCbArgs = NULL; return; } newPreDeleteProcs = (bufPreDeleteCallbackProc *) XtMalloc(sizeof(bufPreDeleteCallbackProc *) * (buf->nPreDeleteProcs)); newCBArgs = (void *)XtMalloc(sizeof(void *) * (buf->nPreDeleteProcs)); /* copy out the remaining members and free the old lists */ for (i=0; i<toRemove; i++) { newPreDeleteProcs[i] = buf->preDeleteProcs[i]; newCBArgs[i] = buf->preDeleteCbArgs[i]; } for (; i<buf->nPreDeleteProcs; i++) { newPreDeleteProcs[i] = buf->preDeleteProcs[i+1]; newCBArgs[i] = buf->preDeleteCbArgs[i+1]; } XtFree((char *)buf->preDeleteProcs); XtFree((char *)buf->preDeleteCbArgs); buf->preDeleteProcs = newPreDeleteProcs; buf->preDeleteCbArgs = newCBArgs;}/*** Return the text from the entire line containing position "pos"*/char *BufGetLineText(textBuffer *buf, int pos){ return BufGetRange(buf, BufStartOfLine(buf, pos), BufEndOfLine(buf, pos));}/*** Find the position of the start of the line containing position "pos"*/int BufStartOfLine(textBuffer *buf, int pos){ int startPos; if (!searchBackward(buf, pos, '\n', &startPos)) return 0; return startPos + 1;}/*** Find the position of the end of the line containing position "pos"** (which is either a pointer to the newline character ending the line,** or a pointer to one character beyond the end of the buffer)*/int BufEndOfLine(textBuffer *buf, int pos){ int endPos; if (!searchForward(buf, pos, '\n', &endPos)) endPos = buf->length; return endPos;}/*** Get a character from the text buffer expanded into it's screen** representation (which may be several characters for a tab or a** control code). Returns the number of characters written to "outStr".** "indent" is the number of characters from the start of the line** for figuring tabs. Output string is guranteed to be shorter or** equal in length to MAX_EXP_CHAR_LEN*/int BufGetExpandedChar(textBuffer *buf, int pos, int indent, char *outStr){ return BufExpandCharacter(BufGetCharacter(buf, pos), indent, outStr, buf->tabDist, buf->nullSubsChar);}/*** Expand a single character from the text buffer into it's screen** representation (which may be several characters for a tab or a** control code). Returns the number of characters added to "outStr".** "indent" is the number of characters from the start of the line** for figuring tabs. Output string is guranteed to be shorter or** equal in length to MAX_EXP_CHAR_LEN*/int BufExpandCharacter(char c, int indent, char *outStr, int tabDist, char nullSubsChar){ int i, nSpaces; /* Convert tabs to spaces */ if (c == '\t') { nSpaces = tabDist - (indent % tabDist); for (i=0; i<nSpaces; i++) outStr[i] = ' '; return nSpaces; } /* Convert ASCII (and EBCDIC in the __MVS__ (OS/390) case) control codes to readable character sequences */ if (c == nullSubsChar) { sprintf(outStr, "<nul>"); return 5; }#ifdef __MVS__ if (((unsigned char)c) <= 63) { sprintf(outStr, "<%s>", ControlCodeTable[(unsigned char)c]); return strlen(outStr); }#else if (((unsigned char)c) <= 31) { sprintf(outStr, "<%s>", ControlCodeTable[(unsigned char)c]); return strlen(outStr); } else if (c == 127) { sprintf(outStr, "<del>"); return 5; }#endif /* Otherwise, just return the character */ *outStr = c; return 1;}/*** Return the length in displayed characters of character "c" expanded** for display (as discussed above in BufGetExpandedChar). If the** buffer for which the character width is being measured is doing null** substitution, nullSubsChar should be passed as that character (or nul** to ignore).*/int BufCharWidth(char c, int indent, int tabDist, char nullSubsChar){ /* Note, this code must parallel that in BufExpandCharacter */ if (c == nullSubsChar) return 5; else if (c == '\t') return tabDist - (indent % tabDist); else if (((unsigned char)c) <= 31) return strlen(ControlCodeTable[(unsigned char)c]) + 2; else if (c == 127) return 5; return 1;}/*** Count the number of displayed characters between buffer position** "lineStartPos" and "targetPos". (displayed characters are the characters** shown on the screen to represent characters in the buffer, where tabs and** control characters are expanded)*/int BufCountDispChars(textBuffer *buf, int lineStartPos, int targetPos){ int pos, charCount = 0; char expandedChar[MAX_EXP_CHAR_LEN]; pos = lineStartPos; while (pos < targetPos) charCount += BufGetExpandedChar(buf, pos++, charCount, expandedChar); return charCount;}/*** Count forward from buffer position "startPos" in displayed characters** (displayed characters are the characters shown on the screen to represent** characters in the buffer, where tabs and control characters are expanded)*/int BufCountForwardDispChars(textBuffer *buf, int lineStartPos, int nChars){ int pos, charCount = 0; char c; pos = lineStartPos; while (charCount < nChars && pos < buf->length) { c = BufGetCharacter(buf, pos); if (c == '\n') return pos; charCount += BufCharWidth(c, charCount, buf->tabDist,buf->nullSubsChar); pos++; } return pos;}/*** Count the number of newlines between startPos and endPos in buffer "buf".** The character at position "endPos" is not counted.*/int BufCountLines(textBuffer *buf, int startPos, int endPos){ int pos, gapLen = buf->gapEnd - buf->gapStart; int lineCount = 0; pos = startPos; while (pos < buf->gapStart) { if (pos == endPos) return lineCount; if (buf->buf[pos++] == '\n') lineCount++; } while (pos < buf->length) { if (pos == endPos) return lineCount; if (buf->buf[pos++ + gapLen] == '\n') lineCount++; } return lineCount;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -