📄 tktextindex.c
字号:
/* *---------------------------------------------------------------------- * * TkTextPrintIndex -- * * * This procedure generates a string description of an index, * suitable for reading in again later. * * Results: * The characters pointed to by string are modified. * * Side effects: * None. * *---------------------------------------------------------------------- */voidTkTextPrintIndex(indexPtr, string) TkTextIndex *indexPtr; /* Pointer to index. */ char *string; /* Place to store the position. Must have * at least TK_POS_CHARS characters. */{ sprintf(string, "%d.%d", TkBTreeLineIndex(indexPtr->linePtr) + 1, indexPtr->charIndex);}/* *-------------------------------------------------------------- * * TkTextIndexCmp -- * * Compare two indices to see which one is earlier in * the text. * * Results: * The return value is 0 if index1Ptr and index2Ptr refer * to the same position in the file, -1 if index1Ptr refers * to an earlier position than index2Ptr, and 1 otherwise. * * Side effects: * None. * *-------------------------------------------------------------- */intTkTextIndexCmp(index1Ptr, index2Ptr) TkTextIndex *index1Ptr; /* First index. */ TkTextIndex *index2Ptr; /* Second index. */{ int line1, line2; if (index1Ptr->linePtr == index2Ptr->linePtr) { if (index1Ptr->charIndex < index2Ptr->charIndex) { return -1; } else if (index1Ptr->charIndex > index2Ptr->charIndex) { return 1; } else { return 0; } } line1 = TkBTreeLineIndex(index1Ptr->linePtr); line2 = TkBTreeLineIndex(index2Ptr->linePtr); if (line1 < line2) { return -1; } if (line1 > line2) { return 1; } return 0;}/* *---------------------------------------------------------------------- * * ForwBack -- * * This procedure handles +/- modifiers for indices to adjust * the index forwards or backwards. * * Results: * If the modifier in string is successfully parsed then the * return value is the address of the first character after the * modifier, and *indexPtr is updated to reflect the modifier. * If there is a syntax error in the modifier then NULL is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */static char *ForwBack(string, indexPtr) char *string; /* String to parse for additional info * about modifier (count and units). * Points to "+" or "-" that starts * modifier. */ TkTextIndex *indexPtr; /* Index to update as specified in string. */{ register char *p; char *end, *units; int count, lineIndex; size_t length; /* * Get the count (how many units forward or backward). */ p = string+1; while (isspace(UCHAR(*p))) { p++; } count = strtol(p, &end, 0); if (end == p) { return NULL; } p = end; while (isspace(UCHAR(*p))) { p++; } /* * Find the end of this modifier (next space or + or - character), * then parse the unit specifier and update the position * accordingly. */ units = p; while ((*p != 0) && !isspace(UCHAR(*p)) && (*p != '+') && (*p != '-')) { p++; } length = p - units; if ((*units == 'c') && (strncmp(units, "chars", length) == 0)) { if (*string == '+') { TkTextIndexForwChars(indexPtr, count, indexPtr); } else { TkTextIndexBackChars(indexPtr, count, indexPtr); } } else if ((*units == 'l') && (strncmp(units, "lines", length) == 0)) { lineIndex = TkBTreeLineIndex(indexPtr->linePtr); if (*string == '+') { lineIndex += count; } else { lineIndex -= count; /* * The check below retains the character position, even * if the line runs off the start of the file. Without * it, the character position will get reset to 0 by * TkTextMakeIndex. */ if (lineIndex < 0) { lineIndex = 0; } } TkTextMakeIndex(indexPtr->tree, lineIndex, indexPtr->charIndex, indexPtr); } else { return NULL; } return p;}/* *---------------------------------------------------------------------- * * TkTextIndexForwChars -- * * Given an index for a text widget, this procedure creates a * new index that points "count" characters ahead of the source * index. * * Results: * *dstPtr is modified to refer to the character "count" characters * after srcPtr, or to the last character in the file if there aren't * "count" characters left in the file. * * Side effects: * None. * *---------------------------------------------------------------------- */ /* ARGSUSED */voidTkTextIndexForwChars(srcPtr, count, dstPtr) TkTextIndex *srcPtr; /* Source index. */ int count; /* How many characters forward to * move. May be negative. */ TkTextIndex *dstPtr; /* Destination index: gets modified. */{ TkTextLine *linePtr; TkTextSegment *segPtr; int lineLength; if (count < 0) { TkTextIndexBackChars(srcPtr, -count, dstPtr); return; } *dstPtr = *srcPtr; dstPtr->charIndex += count; while (1) { /* * Compute the length of the current line. */ lineLength = 0; for (segPtr = dstPtr->linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { lineLength += segPtr->size; } /* * If the new index is in the same line then we're done. * Otherwise go on to the next line. */ if (dstPtr->charIndex < lineLength) { return; } dstPtr->charIndex -= lineLength; linePtr = TkBTreeNextLine(dstPtr->linePtr); if (linePtr == NULL) { dstPtr->charIndex = lineLength - 1; return; } dstPtr->linePtr = linePtr; }}/* *---------------------------------------------------------------------- * * TkTextIndexBackChars -- * * Given an index for a text widget, this procedure creates a * new index that points "count" characters earlier than the * source index. * * Results: * *dstPtr is modified to refer to the character "count" characters * before srcPtr, or to the first character in the file if there aren't * "count" characters earlier than srcPtr. * * Side effects: * None. * *---------------------------------------------------------------------- */voidTkTextIndexBackChars(srcPtr, count, dstPtr) TkTextIndex *srcPtr; /* Source index. */ int count; /* How many characters backward to * move. May be negative. */ TkTextIndex *dstPtr; /* Destination index: gets modified. */{ TkTextSegment *segPtr; int lineIndex; if (count < 0) { TkTextIndexForwChars(srcPtr, -count, dstPtr); return; } *dstPtr = *srcPtr; dstPtr->charIndex -= count; lineIndex = -1; while (dstPtr->charIndex < 0) { /* * Move back one line in the text. If we run off the beginning * of the file then just return the first character in the text. */ if (lineIndex < 0) { lineIndex = TkBTreeLineIndex(dstPtr->linePtr); } if (lineIndex == 0) { dstPtr->charIndex = 0; return; } lineIndex--; dstPtr->linePtr = TkBTreeFindLine(dstPtr->tree, lineIndex); /* * Compute the length of the line and add that to dstPtr->charIndex. */ for (segPtr = dstPtr->linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { dstPtr->charIndex += segPtr->size; } }}/* *---------------------------------------------------------------------- * * StartEnd -- * * This procedure handles modifiers like "wordstart" and "lineend" * to adjust indices forwards or backwards. * * Results: * If the modifier is successfully parsed then the return value * is the address of the first character after the modifier, and * *indexPtr is updated to reflect the modifier. If there is a * syntax error in the modifier then NULL is returned. * * Side effects: * None. * *---------------------------------------------------------------------- */static char *StartEnd(string, indexPtr) char *string; /* String to parse for additional info * about modifier (count and units). * Points to first character of modifer * word. */ TkTextIndex *indexPtr; /* Index to mdoify based on string. */{ char *p; int c, offset; size_t length; register TkTextSegment *segPtr; /* * Find the end of the modifier word. */ for (p = string; isalnum(UCHAR(*p)); p++) { /* Empty loop body. */ } length = p-string; if ((*string == 'l') && (strncmp(string, "lineend", length) == 0) && (length >= 5)) { indexPtr->charIndex = 0; for (segPtr = indexPtr->linePtr->segPtr; segPtr != NULL; segPtr = segPtr->nextPtr) { indexPtr->charIndex += segPtr->size; } indexPtr->charIndex -= 1; } else if ((*string == 'l') && (strncmp(string, "linestart", length) == 0) && (length >= 5)) { indexPtr->charIndex = 0; } else if ((*string == 'w') && (strncmp(string, "wordend", length) == 0) && (length >= 5)) { int firstChar = 1; /* * If the current character isn't part of a word then just move * forward one character. Otherwise move forward until finding * a character that isn't part of a word and stop there. */ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { if (segPtr->typePtr == &tkTextCharType) { c = segPtr->body.chars[offset]; if (!isalnum(UCHAR(c)) && (c != '_')) { break; } firstChar = 0; } offset += 1; indexPtr->charIndex += 1; if (offset >= segPtr->size) { segPtr = TkTextIndexToSeg(indexPtr, &offset); } } if (firstChar) { TkTextIndexForwChars(indexPtr, 1, indexPtr); } } else if ((*string == 'w') && (strncmp(string, "wordstart", length) == 0) && (length >= 5)) { int firstChar = 1; /* * Starting with the current character, look for one that's not * part of a word and keep moving backward until you find one. * Then if the character found wasn't the first one, move forward * again one position. */ segPtr = TkTextIndexToSeg(indexPtr, &offset); while (1) { if (segPtr->typePtr == &tkTextCharType) { c = segPtr->body.chars[offset]; if (!isalnum(UCHAR(c)) && (c != '_')) { break; } firstChar = 0; } offset -= 1; indexPtr->charIndex -= 1; if (offset < 0) { if (indexPtr->charIndex < 0) { indexPtr->charIndex = 0; goto done; } segPtr = TkTextIndexToSeg(indexPtr, &offset); } } if (!firstChar) { TkTextIndexForwChars(indexPtr, 1, indexPtr); } } else { return NULL; } done: return p;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -