⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 textbuf.c

📁 nedit 是一款linux下的开发源码的功能强大的编辑器
💻 C
📖 第 1 页 / 共 5 页
字号:
    expText = expandTabs(insText, 0, buf->tabDist, buf->nullSubsChar,	    &expInsLen);    XtFree(expText);    outStr = XtMalloc(expReplLen + expInsLen +    	    nLines * (column + insWidth + MAX_EXP_CHAR_LEN) + 1);        /* Loop over all lines in the buffer between start and end inserting       text at column, splitting tabs and adding padding appropriately */    outPtr = outStr;    lineStart = start;    insPtr = insText;    while (True) {    	lineEnd = BufEndOfLine(buf, lineStart);    	line = BufGetRange(buf, lineStart, lineEnd);    	insLine = copyLine(insPtr, &len);    	insPtr += len;    	insertColInLine(line, insLine, column, insWidth, buf->tabDist,    		buf->useTabs, buf->nullSubsChar, outPtr, &len, &endOffset);    	XtFree(line);    	XtFree(insLine);#if 0   /* Earlier comments claimed that trailing whitespace could multiply on        the ends of lines, but insertColInLine looks like it should never        add space unnecessarily, and this trimming interfered with        paragraph filling, so lets see if it works without it. MWE */        {            char *c;    	    for (c=outPtr+len-1; c>outPtr && (*c == ' ' || *c == '\t'); c--)                len--;        }#endif	outPtr += len;	*outPtr++ = '\n';    	lineStart = lineEnd < buf->length ? lineEnd + 1 : buf->length;    	if (*insPtr == '\0')    	    break;    	insPtr++;    }    if (outPtr != outStr)    	outPtr--; /* trim back off extra newline */    *outPtr = '\0';        /* replace the text between start and end with the new stuff */    delete(buf, start, end);    insert(buf, start, outStr);    *nInserted = outPtr - outStr;    *nDeleted = end - start;    *endPos = start + (outPtr - outStr) - len + endOffset;    XtFree(outStr);}/*** Delete a rectangle of text without calling the modify callbacks.  Returns** the number of characters replacing those between start and end.  Note that** in some pathological cases, deleting can actually increase the size of** the buffer because of tab expansions.  "endPos" returns the buffer position** of the point in the last line where the text was removed (as a hint for** routines which need to position the cursor after a delete operation)*/static void deleteRect(textBuffer *buf, int start, int end, int rectStart,	int rectEnd, int *replaceLen, int *endPos){    int nLines, lineStart, lineEnd, len, endOffset;    char *outStr, *outPtr, *line, *text, *expText;        /* allocate a buffer for the replacement string large enough to hold        possibly expanded tabs as well as an additional  MAX_EXP_CHAR_LEN * 2       characters per line for padding where tabs and control characters cross       the edges of the selection */    start = BufStartOfLine(buf, start);    end = BufEndOfLine(buf, end);    nLines = BufCountLines(buf, start, end) + 1;    text = BufGetRange(buf, start, end);    expText = expandTabs(text, 0, buf->tabDist, buf->nullSubsChar, &len);    XtFree(text);    XtFree(expText);    outStr = XtMalloc(len + nLines * MAX_EXP_CHAR_LEN * 2 + 1);        /* loop over all lines in the buffer between start and end removing       the text between rectStart and rectEnd and padding appropriately */    lineStart = start;    outPtr = outStr;    while (lineStart <= buf->length && lineStart <= end) {    	lineEnd = BufEndOfLine(buf, lineStart);    	line = BufGetRange(buf, lineStart, lineEnd);    	deleteRectFromLine(line, rectStart, rectEnd, buf->tabDist,    		buf->useTabs, buf->nullSubsChar, outPtr, &len, &endOffset);    	XtFree(line);	outPtr += len;	*outPtr++ = '\n';    	lineStart = lineEnd + 1;    }    if (outPtr != outStr)    	outPtr--; /* trim back off extra newline */    *outPtr = '\0';        /* replace the text between start and end with the newly created string */    delete(buf, start, end);    insert(buf, start, outStr);    *replaceLen = outPtr - outStr;    *endPos = start + (outPtr - outStr) - len + endOffset;    XtFree(outStr);}/*** Overlay a rectangular area of text without calling the modify callbacks.** "nDeleted" and "nInserted" return the number of characters deleted and** inserted beginning at the start of the line containing "startPos".** "endPos" returns buffer position of the lower left edge of the inserted** column (as a hint for routines which need to set a cursor position).*/static void overlayRect(textBuffer *buf, int startPos, int rectStart,    	int rectEnd, const char *insText,	int *nDeleted, int *nInserted, int *endPos){    int nLines, start, end, lineStart, lineEnd;    int expInsLen, len, endOffset;    char *c, *outStr, *outPtr, *line, *expText, *insLine;    const char *insPtr;    /* Allocate a buffer for the replacement string large enough to hold       possibly expanded tabs in the inserted text, as well as per line: 1)       an additional 2*MAX_EXP_CHAR_LEN characters for padding where tabs       and control characters cross the column of the selection, 2) up to       "column" additional spaces per line for padding out to the position       of "column", 3) padding up to the width of the inserted text if that       must be padded to align the text beyond the inserted column.  (Space       for additional newlines if the inserted text extends beyond the end       of the buffer is counted with the length of insText) */    start = BufStartOfLine(buf, startPos);    nLines = countLines(insText) + 1;    end = BufEndOfLine(buf, BufCountForwardNLines(buf, start, nLines-1));    expText = expandTabs(insText, 0, buf->tabDist, buf->nullSubsChar,	    &expInsLen);    XtFree(expText);    outStr = XtMalloc(end-start + expInsLen +    	    nLines * (rectEnd + MAX_EXP_CHAR_LEN) + 1);        /* Loop over all lines in the buffer between start and end overlaying the       text between rectStart and rectEnd and padding appropriately.  Trim       trailing space from line (whitespace at the ends of lines otherwise       tends to multiply, since additional padding is added to maintain it */    outPtr = outStr;    lineStart = start;    insPtr = insText;    while (True) {    	lineEnd = BufEndOfLine(buf, lineStart);    	line = BufGetRange(buf, lineStart, lineEnd);    	insLine = copyLine(insPtr, &len);    	insPtr += len;    	overlayRectInLine(line, insLine, rectStart, rectEnd, buf->tabDist,		buf->useTabs, buf->nullSubsChar, outPtr, &len, &endOffset);    	XtFree(line);    	XtFree(insLine);    	for (c=outPtr+len-1; c>outPtr && (*c == ' ' || *c == '\t'); c--)    	    len--;	outPtr += len;	*outPtr++ = '\n';    	lineStart = lineEnd < buf->length ? lineEnd + 1 : buf->length;    	if (*insPtr == '\0')    	    break;    	insPtr++;    }    if (outPtr != outStr)    	outPtr--; /* trim back off extra newline */    *outPtr = '\0';        /* replace the text between start and end with the new stuff */    delete(buf, start, end);    insert(buf, start, outStr);    *nInserted = outPtr - outStr;    *nDeleted = end - start;    *endPos = start + (outPtr - outStr) - len + endOffset;    XtFree(outStr);}/*** Insert characters from single-line string "insLine" in single-line string** "line" at "column", leaving "insWidth" space before continuing line.** "outLen" returns the number of characters written to "outStr", "endOffset"** returns the number of characters from the beginning of the string to** the right edge of the inserted text (as a hint for routines which need** to position the cursor).*/static void insertColInLine(const char *line, const char *insLine,        int column, int insWidth, int tabDist, int useTabs, char nullSubsChar,	char *outStr, int *outLen, int *endOffset){    char *c, *outPtr, *retabbedStr;    const char *linePtr;    int indent, toIndent, len, postColIndent;            /* copy the line up to "column" */     outPtr = outStr;    indent = 0;    for (linePtr=line; *linePtr!='\0'; linePtr++) {	len = BufCharWidth(*linePtr, indent, tabDist, nullSubsChar);	if (indent + len > column)    	    break;    	indent += len;	*outPtr++ = *linePtr;    }        /* If "column" falls in the middle of a character, and the character is a       tab, leave it off and leave the indent short and it will get padded       later.  If it's a control character, insert it and adjust indent       accordingly. */    if (indent < column && *linePtr != '\0') {    	postColIndent = indent + len;    	if (*linePtr == '\t')    	    linePtr++;    	else {    	    *outPtr++ = *linePtr++;    	    indent += len;    	}    } else    	postColIndent = indent;        /* If there's no text after the column and no text to insert, that's all */    if (*insLine == '\0' && *linePtr == '\0') {    	*outLen = *endOffset = outPtr - outStr;    	return;    }        /* pad out to column if text is too short */    if (indent < column) {	addPadding(outPtr, indent, column, tabDist, useTabs, nullSubsChar,&len);	outPtr += len;	indent = column;    }        /* Copy the text from "insLine" (if any), recalculating the tabs as if       the inserted string began at column 0 to its new column destination */    if (*insLine != '\0') {	retabbedStr = realignTabs(insLine, 0, indent, tabDist, useTabs,		nullSubsChar, &len);	for (c=retabbedStr; *c!='\0'; c++) {    	    *outPtr++ = *c;    	    len = BufCharWidth(*c, indent, tabDist, nullSubsChar);    	    indent += len;	}	XtFree(retabbedStr);    }        /* If the original line did not extend past "column", that's all */    if (*linePtr == '\0') {    	*outLen = *endOffset = outPtr - outStr;    	return;    }        /* Pad out to column + width of inserted text + (additional original       offset due to non-breaking character at column) */    toIndent = column + insWidth + postColIndent-column;    addPadding(outPtr, indent, toIndent, tabDist, useTabs, nullSubsChar, &len);    outPtr += len;    indent = toIndent;        /* realign tabs for text beyond "column" and write it out */    retabbedStr = realignTabs(linePtr, postColIndent, indent, tabDist,    	useTabs, nullSubsChar, &len);    strcpy(outPtr, retabbedStr);    XtFree(retabbedStr);    *endOffset = outPtr - outStr;    *outLen = (outPtr - outStr) + len;}/*** Remove characters in single-line string "line" between displayed positions** "rectStart" and "rectEnd", and write the result to "outStr", which is** assumed to be large enough to hold the returned string.  Note that in** certain cases, it is possible for the string to get longer due to** expansion of tabs.  "endOffset" returns the number of characters from** the beginning of the string to the point where the characters were** deleted (as a hint for routines which need to position the cursor).*/static void deleteRectFromLine(const char *line, int rectStart, int rectEnd,	int tabDist, int useTabs, char nullSubsChar, char *outStr, int *outLen,	int *endOffset){    int indent, preRectIndent, postRectIndent, len;    const char *c;    char *outPtr;    char *retabbedStr;        /* copy the line up to rectStart */    outPtr = outStr;    indent = 0;    for (c=line; *c!='\0'; c++) {	if (indent > rectStart)	    break;	len = BufCharWidth(*c, indent, tabDist, nullSubsChar);	if (indent + len > rectStart && (indent == rectStart || *c == '\t'))    	    break;    	indent += len;	*outPtr++ = *c;    }    preRectIndent = indent;        /* skip the characters between rectStart and rectEnd */    for(; *c!='\0' && indent<rectEnd; c++)	indent += BufCharWidth(*c, indent, tabDist, nullSubsChar);    postRectIndent = indent;        /* If the line ended before rectEnd, there's nothing more to do */    if (*c == '\0') {    	*outPtr = '\0';    	*outLen = *endOffset = outPtr - outStr;    	return;    }        /* fill in any space left by removed tabs or control characters       which straddled the boundaries */    indent = max(rectStart + postRectIndent-rectEnd, preRectIndent);    addPadding(outPtr, preRectIndent, indent, tabDist, useTabs, nullSubsChar,	    &len);    outPtr += len;    /* Copy the rest of the line.  If the indentation has changed, preserve       the position of non-whitespace characters by converting tabs to       spaces, then back to tabs with the correct offset */    retabbedStr = realignTabs(c, postRectIndent, indent, tabDist, useTabs,    	    nullSubsChar, &len);    strcpy(outPtr, retabbedStr);    XtFree(retabbedStr);    *endOffset = outPtr - outStr;    *outLen = (outPtr - outStr) + len;}/*** Overlay characters from single-line string "insLine" on single-line string** "line" between displayed character offsets "rectStart" and "rectEnd".** "outLen" returns the number of characters written to "outStr", "endOffset"** returns the number of characters from the beginning of the string to** the right edge of the inserted text (as a hint for routines which need** to position the cursor).**** This code does not handle control characters very well, but oh well.*/static void overlayRectInLine(const char *line, const char *insLine,        int rectStart, int rectEnd, int tabDist, int useTabs,	char nullSubsChar, char *outStr, int *outLen, int *endOffset){    char *c, *outPtr, *retabbedStr;    const char *linePtr;    int inIndent, outIndent, len, postRectIndent;            /* copy the line up to "rectStart" or just before the char that         contains it*/     outPtr = outStr;    inIndent = outIndent = 0;    for (linePtr=line; *linePtr!='\0'; linePtr++) {	len = BufCharWidth(*linePtr, inIndent, tabDist, nullSubsChar);	if (inIndent + len > rectStart)    	    break;    	inIndent += len;    	outIndent += len;	*outPtr++ = *linePtr;    }        /* If "rectStart" falls in the middle of a character, and the character       is a tab, leave it off and leave the outIndent short and it will get       padded later.  If it's a control character, insert it and adjust       outIndent accordingly. */    if (inIndent < rectStart && *linePtr != '\0') {    	if (*linePtr == '\t') {            /* Skip past the tab */    	    linePtr++;    	    inIndent += len;    	} else {    	    *outPtr++ = *linePtr++;    	    outIndent += len;    	    inIndent += len;    	}    }        /* skip the characters between rectStart and rectEnd */    for(; *linePtr!='\0' && inIndent < rectEnd; linePtr++)	inIndent += BufCharWidth(*linePtr, inIndent, tabDist, nullSubsChar);    postRectIndent = inIndent;        /* After this inIndent is dead and 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -