📄 rangeset.c
字号:
n = table->n_set - 1; for (i = depth; i < n; i++) { j = table->order[i] = table->order[i + 1]; table->depth[j] = i; } /* reinsert the old one: at max (active) depth */ table->order[n] = active; table->depth[active] = n; /* and finally... */ table->active[active] = 0; table->n_set--; RangesetTableListSet(table); return 1;}/*** Return the number of rangesets that are inactive*/int nRangesetsAvailable(RangesetTable *table){ return(N_RANGESETS - table->n_set);}/*** Create a new empty rangeset*/int RangesetCreate(RangesetTable *table){ int label; int setIndex; size_t firstAvailableIndex = strspn((char*)rangeset_labels, (char*)table->list); if(firstAvailableIndex >= sizeof(rangeset_labels)) return 0; label = rangeset_labels[firstAvailableIndex]; setIndex = RangesetFindIndex(table, label, 0); if (setIndex < 0) return 0; if (table->active[setIndex]) return label; if (activateRangeset(table, setIndex)) RangesetInit(&table->set[setIndex], rangeset_labels[setIndex], table->buf); return label;} /*** Forget the rangeset identified by label - clears it, renders it inactive.*/Rangeset *RangesetForget(RangesetTable *table, int label){ int set_ind = RangesetFindIndex(table, label, 1); if (set_ind < 0) return (Rangeset *)0; if (deactivateRangeset(table, set_ind)) RangesetEmpty(&table->set[set_ind]); return &table->set[set_ind];} /*** Fetch the rangeset identified by label - initialise it if not active and** make_active is true, and make it the most visible.*/Rangeset *RangesetFetch(RangesetTable *table, int label){ int rangesetIndex = RangesetFindIndex(table, label, 0); if (rangesetIndex < 0) return (Rangeset *)NULL; if (table->active[rangesetIndex]) return &table->set[rangesetIndex]; else return (Rangeset *)NULL;}unsigned char *RangesetGetList(RangesetTable *table){ return table ? table->list : (unsigned char *)"";}/* -------------------------------------------------------------------------- */void RangesetTableUpdatePos(RangesetTable *table, int pos, int ins, int del){ int i; Rangeset *p; if (!table || (ins == 0 && del == 0)) return; for (i = 0; i < table->n_set; i++) { p = &table->set[(int)table->order[i]]; p->update_fn(p, pos, ins, del); }}void RangesetBufModifiedCB(int pos, int nInserted, int nDeleted, int nRestyled, char *deletedText, void *cbArg){ RangesetTable *table = (RangesetTable *)cbArg; if ((nInserted != nDeleted) || BufCmp(table->buf, pos, nInserted, deletedText) != 0) { RangesetTableUpdatePos(table, pos, nInserted, nDeleted); }}/* -------------------------------------------------------------------------- *//*** Find the index of the first range in depth order which includes the position.** Returns the index of the rangeset in the rangeset table + 1 if an including** rangeset was found, 0 otherwise. If needs_color is true, "colorless" ranges** will be skipped.*/int RangesetIndex1ofPos(RangesetTable *table, int pos, int needs_color){ int i; Rangeset *rangeset; if (!table) return 0; for (i = 0; i < table->n_set; i++) { rangeset = &table->set[(int)table->order[i]]; if (RangesetCheckRangeOfPos(rangeset, pos) >= 0) { if (needs_color && rangeset->color_set >= 0 && rangeset->color_name) return table->order[i] + 1; } } return 0;}/* -------------------------------------------------------------------------- *//*** Assign a color name to a rangeset via the rangeset table.*/int RangesetAssignColorName(Rangeset *rangeset, char *color_name){ char *cp; if (color_name && color_name[0] == '\0') color_name = (char *)0; /* "" invalid */ /* store new color name value */ if (color_name) { cp = XtMalloc(strlen(color_name) + 1); strcpy(cp, color_name); } else cp = color_name; /* free old color name value */ if (rangeset->color_name) XtFree(rangeset->color_name); rangeset->color_name = cp; rangeset->color_set = 0; RangesetRefreshAllRanges(rangeset); return 1;}/*** Assign a name to a rangeset via the rangeset table.*/int RangesetAssignName(Rangeset *rangeset, char *name){ char *cp; if (name && name[0] == '\0') name = (char *)0; /* store new name value */ if (name) { cp = XtMalloc(strlen(name) + 1); strcpy(cp, name); } else { cp = name; } /* free old name value */ if (rangeset->name) { XtFree(rangeset->name); } rangeset->name = cp; return 1;}/*** Assign a color pixel value to a rangeset via the rangeset table. If ok is** false, the color_set flag is set to an invalid (negative) value.*/int RangesetAssignColorPixel(Rangeset *rangeset, Pixel color, int ok){ rangeset->color_set = ok ? 1 : -1; rangeset->color = color; return 1;}/*** Return the color name, if any.*/char *RangesetGetColorName(Rangeset *rangeset){ return rangeset->color_name;}/*** Return the name, if any.*/char *RangesetGetName(Rangeset *rangeset){ return rangeset->name;}/*** Return the color validity, if any, and the value in *color.*/int RangesetGetColorValid(Rangeset *rangeset, Pixel *color){ *color = rangeset->color; return rangeset->color_set;}/*** Return the color name, if any.*/char *RangesetTableGetColorName(RangesetTable *table, int index){ Rangeset *rangeset = &table->set[index]; return rangeset->color_name;}/*** Return the color color validity, if any, and the value in *color.*/int RangesetTableGetColorValid(RangesetTable *table, int index, Pixel *color){ Rangeset *rangeset = &table->set[index]; *color = rangeset->color; return rangeset->color_set;}/*** Assign a color pixel value to a rangeset via the rangeset table. If ok is** false, the color_set flag is set to an invalid (negative) value.*/int RangesetTableAssignColorPixel(RangesetTable *table, int index, Pixel color, int ok){ Rangeset *rangeset = &table->set[index]; rangeset->color_set = ok ? 1 : -1; rangeset->color = color; return 1;}/* -------------------------------------------------------------------------- */#define is_start(i) !((i) & 1) /* true if i is even */#define is_end(i) ((i) & 1) /* true if i is odd *//*** Find the index of the first entry in the range set's ranges table (viewed as** an int array) whose value is equal to or greater than pos. As a side effect,** update the lasi_index value of the range set. Return's the index value. This** will be twice p->n_ranges if pos is beyond the end.*/static int rangesetWeightedAtOrBefore(Rangeset *rangeset, int pos){ int i, last, n, *rangeTable = (int *)rangeset->ranges; n = rangeset->n_ranges; if (n == 0) return 0; last = rangeset->last_index; if (last >= n || last < 0) last = 0; n *= 2; last *= 2; if (pos >= rangeTable[last]) /* ranges[last_index].start */ i = weighted_at_or_before(rangeTable, last, n, pos); /* search end only */ else i = weighted_at_or_before(rangeTable, 0, last, pos); /* search front only */ rangeset->last_index = i / 2; return i;}/*** Adjusts values in tab[] by an amount delta, perhaps moving them meanwhile.*/static int rangesetShuffleToFrom(int *rangeTable, int to, int from, int n, int delta){ int end, diff = from - to; if (n <= 0) return 0; if (delta != 0) { if (diff > 0) { /* shuffle entries down */ for (end = to + n; to < end; to++) rangeTable[to] = rangeTable[to + diff] + delta; } else if (diff < 0) { /* shuffle entries up */ for (end = to, to += n; --to >= end;) rangeTable[to] = rangeTable[to + diff] + delta; } else { /* diff == 0: just run through */ for (end = n; end--;) rangeTable[to++] += delta; } } else { if (diff > 0) { /* shuffle entries down */ for (end = to + n; to < end; to++) rangeTable[to] = rangeTable[to + diff]; } else if (diff < 0) { /* shuffle entries up */ for (end = to, to += n; --to >= end;) rangeTable[to] = rangeTable[to + diff]; } /* else diff == 0: nothing to do */ } return n;}/*** Functions to adjust a rangeset to include new text or remove old.** *** NOTE: No redisplay: that's outside the responsability of these routines.*//* "Insert/Delete": if the start point is in or at the end of a range** (start < pos && pos <= end), any text inserted will extend that range.** Insertions appear to occur before deletions. This will never add new ranges.*/static Rangeset *rangesetInsDelMaintain(Rangeset *rangeset, int pos, int ins, int del){ int i, j, n, *rangeTable = (int *)rangeset->ranges; int end_del, movement; n = 2 * rangeset->n_ranges; i = rangesetWeightedAtOrBefore(rangeset, pos); if (i == n) return rangesetFixMaxpos(rangeset, ins, del); /* all beyond the end */ end_del = pos + del; movement = ins - del; /* the idea now is to determine the first range not concerned with the movement: its index will be j. For indices j to n-1, we will adjust position by movement only. (They may need shuffling up or down, depending on whether ranges have been deleted or created by the change.) */ j = i; while (j < n && rangeTable[j] <= end_del) /* skip j to first ind beyond changes */ j++; /* if j moved forward, we have deleted over rangeTable[i] - reduce it accordingly, accounting for inserts. */ if (j > i) rangeTable[i] = pos + ins; /* If i and j both index starts or ends, just copy all the rangeTable[] values down by j - i spaces, adjusting on the way. Otherwise, move beyond rangeTable[i] before doing this. */ if (is_start(i) != is_start(j)) i++; rangesetShuffleToFrom(rangeTable, i, j, n - j, movement); n -= j - i; rangeset->n_ranges = n / 2; rangeset->ranges = RangesRealloc(rangeset->ranges, rangeset->n_ranges); /* final adjustments */ return rangesetFixMaxpos(rangeset, ins, del);}/* "Inclusive": if the start point is in, at the start of, or at the end of a** range (start <= pos && pos <= end), any text inserted will extend that range.** Insertions appear to occur before deletions. This will never add new ranges.** (Almost identical to rangesetInsDelMaintain().)*/static Rangeset *rangesetInclMaintain(Rangeset *rangeset, int pos, int ins, int del){ int i, j, n, *rangeTable = (int *)rangeset->ranges;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -