Tk Source Code

Check-in [ac2df497]
Login

Many hyperlinks are disabled.
Use anonymous login to enable hyperlinks.

Overview
Comment:(1) Bugfix for handling of last line deletion. (2) Redo of deletion fixed. (3) Additional test case text-37.12 testing a critical edge case. (4) Test cases 37.1-11 re-formatted, but not changed.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | revised_text | tip-466
Files: files | file ages | folders
SHA1: ac2df497761e41440d4b286fd241220eacd12a35
User & Date: gcramer 2017-04-27 11:33:41
Context
2017-04-27
15:27
(1) Bugfix in delete algorithm with test case text-37.12. (2) Test case text-37.12 fixed. (3) Optimization in space when deleting chars, very significant if the range is large. (4) Adaption of UndoDeleteInspect(), but it is still unclear how to show the surrogate newline. check-in: 1324fb8c user: gcramer tags: revised_text, tip-466
11:33
(1) Bugfix for handling of last line deletion. (2) Redo of deletion fixed. (3) Additional test case text-37.12 testing a critical edge case. (4) Test cases 37.1-11 re-formatted, but not changed. check-in: ac2df497 user: gcramer tags: revised_text, tip-466
2017-04-26
19:20
(1) Watch command now triggers changes in image or window. (2) Handling of the watch command a bit simplified. (3) Update of manual. (4) Minor fix in text-27.26. check-in: 40340286 user: gcramer tags: revised_text, tip-466
Changes
Hide Diffs Unified Diffs Ignore Whitespace Patch

Changes to generic/tkText.c.

2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428

	TkTextIndexSave(&textPtr->topIndex);
	if (triggerWatch) {
	    TkTextSaveCursorIndex(textPtr);
	}

	TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);
	if (TkTextIndexCompare(&indexFrom, &index) < 0
		&& TkTextIndexCompare(&index, &indexTo) <= 0) {
	    /*
	     * The insertion point is inside the range to be replaced, so
	     * we have to do some calculations to ensure it doesn't move
	     * unnecessarily.
	     */

	    int deleteInsertOffset, insertLength, j;







|
|







2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428

	TkTextIndexSave(&textPtr->topIndex);
	if (triggerWatch) {
	    TkTextSaveCursorIndex(textPtr);
	}

	TkTextMarkSegToIndex(textPtr, textPtr->insertMarkPtr, &index);

	if (TkTextIndexCompare(&indexFrom, &index) < 0 && TkTextIndexCompare(&index, &indexTo) <= 0) {
	    /*
	     * The insertion point is inside the range to be replaced, so
	     * we have to do some calculations to ensure it doesn't move
	     * unnecessarily.
	     */

	    int deleteInsertOffset, insertLength, j;
5716
5717
5718
5719
5720
5721
5722





5723
5724
5725
5726
5727
5728
5729
		    TkTextClearTags(sharedTextPtr, textPtr, &index1, &index3, false);
		} else {
		    assert(TkTextTagSetIsEmpty(lastLinePtr->prevPtr->lastPtr->tagInfoPtr));
		}
	    }
	    return true; /* nothing to do */
	}





    }

    /*
     * Call the "watch" command for deletion. Take into account that the
     * receiver might change the text content inside the callback, although
     * he shouldn't do this.
     */







>
>
>
>
>







5716
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727
5728
5729
5730
5731
5732
5733
5734
		    TkTextClearTags(sharedTextPtr, textPtr, &index1, &index3, false);
		} else {
		    assert(TkTextTagSetIsEmpty(lastLinePtr->prevPtr->lastPtr->tagInfoPtr));
		}
	    }
	    return true; /* nothing to do */
	}

	if (lastLinePtr->prevPtr->lastPtr->tagInfoPtr != sharedTextPtr->emptyTagInfoPtr) {
	    /* last newline is tagged, so we have to re-include this character */
	    index2 = index3;
	}
    }

    /*
     * Call the "watch" command for deletion. Take into account that the
     * receiver might change the text content inside the callback, although
     * he shouldn't do this.
     */

Changes to generic/tkText.h.

1664
1665
1666
1667
1668
1669
1670
1671

1672
1673
1674
1675
1676
1677
1678
 * Used as 'action' values in calls to TkTextInvalidateLineMetrics
 */

typedef enum {
    TK_TEXT_INVALIDATE_ONLY,
    TK_TEXT_INVALIDATE_INSERT,
    TK_TEXT_INVALIDATE_DELETE,
    TK_TEXT_INVALIDATE_ELIDE

} TkTextInvalidateAction;

/*
 * Used as special 'pickPlace' values in calls to TkTextSetYView. Zero or
 * positive values indicate a number of pixels.
 */








|
>







1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
 * Used as 'action' values in calls to TkTextInvalidateLineMetrics
 */

typedef enum {
    TK_TEXT_INVALIDATE_ONLY,
    TK_TEXT_INVALIDATE_INSERT,
    TK_TEXT_INVALIDATE_DELETE,
    TK_TEXT_INVALIDATE_ELIDE,
    TK_TEXT_INVALIDATE_REINSERTED
} TkTextInvalidateAction;

/*
 * Used as special 'pickPlace' values in calls to TkTextSetYView. Zero or
 * positive values indicate a number of pixels.
 */

Changes to generic/tkTextBTree.c.

1560
1561
1562
1563
1564
1565
1566














1567
1568
1569
1570
1571
1572
1573
{
    const UndoTokenDelete *token = (const UndoTokenDelete *) undoInfo->token;

    if (token->startIndex.lineIndex == -1 && token->endIndex.lineIndex == -1) {
	TkTextSegment *segPtr1 = token->startIndex.u.markPtr;
	TkTextSegment *segPtr2 = token->endIndex.u.markPtr;
	int flags = token->inclusive ? DELETE_INCLUSIVE : 0;















	DeleteRange(sharedTextPtr, segPtr1, segPtr2, flags, redoInfo);

	assert(segPtr1 != segPtr2);
	segPtr1->protectionFlag = true;
	segPtr2->protectionFlag = true;
	CleanupSplitPoint(segPtr1, sharedTextPtr);







>
>
>
>
>
>
>
>
>
>
>
>
>
>







1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
{
    const UndoTokenDelete *token = (const UndoTokenDelete *) undoInfo->token;

    if (token->startIndex.lineIndex == -1 && token->endIndex.lineIndex == -1) {
	TkTextSegment *segPtr1 = token->startIndex.u.markPtr;
	TkTextSegment *segPtr2 = token->endIndex.u.markPtr;
	int flags = token->inclusive ? DELETE_INCLUSIVE : 0;

	if (redoInfo) {
	    UndoTokenDelete *redoToken;

	    redoToken = malloc(sizeof(UndoTokenDelete));
	    redoToken->undoType = &undoTokenDeleteType;
	    redoToken->segments = NULL;
	    redoToken->numSegments = 0;
	    redoToken->startIndex = token->startIndex;
	    redoToken->endIndex = token->endIndex;
	    redoInfo->token = (TkTextUndoToken *) redoToken;
	    redoInfo->byteSize = 0;
	    DEBUG_ALLOC(tkTextCountNewUndoToken++);
	}

	DeleteRange(sharedTextPtr, segPtr1, segPtr2, flags, redoInfo);

	assert(segPtr1 != segPtr2);
	segPtr1->protectionFlag = true;
	segPtr2->protectionFlag = true;
	CleanupSplitPoint(segPtr1, sharedTextPtr);
2788
2789
2790
2791
2792
2793
2794

2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806





2807
2808
2809
2810
2811
2812
2813
    int changeToPixels = 0;

    assert(textPtr->pixelReference != -1);

    for ( ; numLines > 0; --numLines) {
	TkTextPixelInfo *pixelInfo = TkBTreeLinePixelInfo(textPtr, linePtr);


	changeToDispLines += (int) GetDisplayLines(linePtr, pixelReference);
	changeToPixels += pixelInfo->height;
	pixelInfo->epoch = 0;
	pixelInfo->height = 0;
	linePtr = linePtr->nextPtr;

	if (pixelInfo->dispLineInfo) {
	    free(pixelInfo->dispLineInfo);
	    pixelInfo->dispLineInfo = NULL;
	    DEBUG_ALLOC(tkTextCountDestroyDispInfo++);
	}






	if (nodePtr != linePtr->parentPtr) {
	    PropagateDispLineChange(nodePtr, pixelReference, changeToDispLines, changeToPixels);
	    changeToDispLines = 0;
	    changeToPixels = 0;
	    nodePtr = linePtr->parentPtr;
	}
    }







>












>
>
>
>
>







2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2814
2815
2816
2817
2818
2819
2820
2821
2822
2823
2824
2825
2826
2827
2828
2829
2830
2831
2832
2833
    int changeToPixels = 0;

    assert(textPtr->pixelReference != -1);

    for ( ; numLines > 0; --numLines) {
	TkTextPixelInfo *pixelInfo = TkBTreeLinePixelInfo(textPtr, linePtr);

	pixelInfo = TkBTreeLinePixelInfo(textPtr, linePtr);
	changeToDispLines += (int) GetDisplayLines(linePtr, pixelReference);
	changeToPixels += pixelInfo->height;
	pixelInfo->epoch = 0;
	pixelInfo->height = 0;
	linePtr = linePtr->nextPtr;

	if (pixelInfo->dispLineInfo) {
	    free(pixelInfo->dispLineInfo);
	    pixelInfo->dispLineInfo = NULL;
	    DEBUG_ALLOC(tkTextCountDestroyDispInfo++);
	}

	if (!linePtr) {
	    assert(numLines == 1);
	    break;
	}
	
	if (nodePtr != linePtr->parentPtr) {
	    PropagateDispLineChange(nodePtr, pixelReference, changeToDispLines, changeToPixels);
	    changeToDispLines = 0;
	    changeToPixels = 0;
	    nodePtr = linePtr->parentPtr;
	}
    }
7312
7313
7314
7315
7316
7317
7318



7319
7320
7321
7322
7323
7324
7325
	    TkTextIndexSetSegment(&index, beforeSurrogate);
	} else {
	    TkTextIndexSetupToStartOfText(&index, NULL, sharedTextPtr->tree);
	}
	DEBUG(tkBTreeDebug = false); /* otherwise protected segment will be complained */
	TkBTreeInsertChars(sharedTextPtr->tree, &index, "\n",
		sharedTextPtr->emptyTagInfoPtr, NULL, NULL);



	DEBUG(tkBTreeDebug = oldTreeDebug);
    }
}

/*
 *----------------------------------------------------------------------
 *







>
>
>







7332
7333
7334
7335
7336
7337
7338
7339
7340
7341
7342
7343
7344
7345
7346
7347
7348
	    TkTextIndexSetSegment(&index, beforeSurrogate);
	} else {
	    TkTextIndexSetupToStartOfText(&index, NULL, sharedTextPtr->tree);
	}
	DEBUG(tkBTreeDebug = false); /* otherwise protected segment will be complained */
	TkBTreeInsertChars(sharedTextPtr->tree, &index, "\n",
		sharedTextPtr->emptyTagInfoPtr, NULL, NULL);
	/* don't forget to reset pixel info of very last line */
	TkTextInvalidateLineMetrics(treePtr->sharedTextPtr, NULL,
		sharedTextPtr->endMarker->sectionPtr->linePtr, 0, TK_TEXT_INVALIDATE_REINSERTED);
	DEBUG(tkBTreeDebug = oldTreeDebug);
    }
}

/*
 *----------------------------------------------------------------------
 *

Changes to generic/tkTextDisp.c.

6918
6919
6920
6921
6922
6923
6924
6925


6926
6927
6928
6929
6930
6931
6932
6933
6934
6935
6936
6937
6938
6939
    unsigned totalLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
    unsigned epoch = textPtr->dInfoPtr->lineMetricUpdateEpoch;
    bool isMonospaced = UseMonospacedLineHeights(textPtr);
    unsigned lineNum = 0; /* suppress compiler warning */

    assert(linePtr || action == TK_TEXT_INVALIDATE_ONLY);
    assert(TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, NULL) + lineCount
	    < totalLines + (action == TK_TEXT_INVALIDATE_INSERT || action == TK_TEXT_INVALIDATE_DELETE));



    if (linePtr) {
	int deviation;

	lineNum = TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, &deviation);

	assert(lineNum < totalLines);
	assert(deviation >= 0);

	if (deviation) {
	    lineCount -= MIN((int) lineCount, deviation);
	}
	if (action == TK_TEXT_INVALIDATE_INSERT
	    	&& !isMonospaced







|
>
>






<







6918
6919
6920
6921
6922
6923
6924
6925
6926
6927
6928
6929
6930
6931
6932
6933

6934
6935
6936
6937
6938
6939
6940
    unsigned totalLines = TkBTreeNumLines(textPtr->sharedTextPtr->tree, textPtr);
    unsigned epoch = textPtr->dInfoPtr->lineMetricUpdateEpoch;
    bool isMonospaced = UseMonospacedLineHeights(textPtr);
    unsigned lineNum = 0; /* suppress compiler warning */

    assert(linePtr || action == TK_TEXT_INVALIDATE_ONLY);
    assert(TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, NULL) + lineCount
	    < totalLines + (action == TK_TEXT_INVALIDATE_INSERT
			    || action == TK_TEXT_INVALIDATE_DELETE
			    || action == TK_TEXT_INVALIDATE_REINSERTED));

    if (linePtr) {
	int deviation;

	lineNum = TkBTreeLinesTo(textPtr->sharedTextPtr->tree, textPtr, linePtr, &deviation);


	assert(deviation >= 0);

	if (deviation) {
	    lineCount -= MIN((int) lineCount, deviation);
	}
	if (action == TK_TEXT_INVALIDATE_INSERT
	    	&& !isMonospaced
6962
6963
6964
6965
6966
6967
6968










6969
6970
6971
6972
6973
6974
6975
	    int high = TkRangeListHigh(ranges);

	    TkRangeListClear(ranges);
	    ranges = TkRangeListAdd(ranges, low, high);
	}

	switch (action) {










	case TK_TEXT_INVALIDATE_ONLY: {
	    int counter = MIN(lineCount, totalLines - lineNum);

	    if (isMonospaced) {
		TkBTreeUpdatePixelHeights(textPtr, linePtr, lineCount, epoch);
	    } else {
		TkTextLine *logicalLinePtr;







>
>
>
>
>
>
>
>
>
>







6963
6964
6965
6966
6967
6968
6969
6970
6971
6972
6973
6974
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985
6986
	    int high = TkRangeListHigh(ranges);

	    TkRangeListClear(ranges);
	    ranges = TkRangeListAdd(ranges, low, high);
	}

	switch (action) {
	case TK_TEXT_INVALIDATE_REINSERTED: {
	    /*
	     * Special case: the very last line has been re-inserted.
	     */
	    assert(lineNum == totalLines);
	    assert(lineNum > 0);
	    TkRangeListTruncateAtEnd(ranges, lineNum - 1);
	    TkBTreeResetDisplayLineCounts(textPtr, linePtr, 1);
	    break;
	}
	case TK_TEXT_INVALIDATE_ONLY: {
	    int counter = MIN(lineCount, totalLines - lineNum);

	    if (isMonospaced) {
		TkBTreeUpdatePixelHeights(textPtr, linePtr, lineCount, epoch);
	    } else {
		TkTextLine *logicalLinePtr;
7079
7080
7081
7082
7083
7084
7085


7086
7087
7088
7089
7090
7091
7092
		    FreeDLines(textPtr, dlPtr, FindDLine(textPtr, dlPtr, &index), DLINE_UNLINK);
		}
	    }
	    if (lineNum + lineCount < totalLines) {
		ranges = TkRangeListAdd(ranges, lineNum, lineNum);
	    } else {
		TkRangeListTruncateAtEnd(ranges, lineNum - 1);


	    }
	    ResetPixelInfo(TkBTreeLinePixelInfo(textPtr,
		    TkBTreeGetLogicalLine(textPtr->sharedTextPtr, textPtr, linePtr)));
	    break;
	case TK_TEXT_INVALIDATE_INSERT:
	    if (lineCount > 0 && lineNum + 1 < totalLines) {
		int lastLine = MIN(lineNum + lineCount, totalLines - 1);







>
>







7090
7091
7092
7093
7094
7095
7096
7097
7098
7099
7100
7101
7102
7103
7104
7105
		    FreeDLines(textPtr, dlPtr, FindDLine(textPtr, dlPtr, &index), DLINE_UNLINK);
		}
	    }
	    if (lineNum + lineCount < totalLines) {
		ranges = TkRangeListAdd(ranges, lineNum, lineNum);
	    } else {
		TkRangeListTruncateAtEnd(ranges, lineNum - 1);
		ResetPixelInfo(TkBTreeLinePixelInfo(textPtr,
			textPtr->sharedTextPtr->endMarker->sectionPtr->linePtr));
	    }
	    ResetPixelInfo(TkBTreeLinePixelInfo(textPtr,
		    TkBTreeGetLogicalLine(textPtr->sharedTextPtr, textPtr, linePtr)));
	    break;
	case TK_TEXT_INVALIDATE_INSERT:
	    if (lineCount > 0 && lineNum + 1 < totalLines) {
		int lastLine = MIN(lineNum + lineCount, totalLines - 1);

Changes to tests/text.test.

7774
7775
7776
7777
7778
7779
7780
7781
7782

7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798
7799
7800

7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816
7817
7818

7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834
7835
7836

7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847


7848
7849
7850
7851
7852

7853
7854
7855
7856
7857
7858
7859
7860
7861
7862

7863

7864
7865
7866
7867
7868

7869
7870
7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886

7887
7888
7889
7890
7891
7892
7893
7894
7895
7896

7897

7898
7899
7900
7901
7902

7903
7904
7905
7906
7907
7908
7909
7910
7911
7912
7913


7914
7915
7916
7917
7918
7919

7920
7921
7922
7923
7924
7925
7926
7927
7928
7929
7930


7931
7932
7933
7934

7935
7936
7937
7938
7939
7940
7941
7942
7943
7944
7945
7946

7947
7948
7949
7950
7951
7952
7953
7954
7955
7956




















7957
7958
7959
7960
7961
7962
7963
} -cleanup {
    destroy $w
} -result {}

test text-37.1 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
} -body {
    set res {}

    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
{{break {}}}}
test text-37.2 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
} -body {
    set res {}

    .t delete 2.0 end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {break {}}}\
{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
{{text 1 {}} {break {n1}} {break {}}}}
test text-37.3 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
} -body {
    set res {}

    .t delete 1.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {}}}\
{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
{{text 1 {}} {break {}}}}
test text-37.4 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}
} -body {
    set res {}

    .t delete 2.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {text 2 {}} {break {}}} {{break {}}} {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}}


test text-37.5 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
} -body {
    set res {}

    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res

} -result {{{break {}}} {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}} {{break {}}}}

test text-37.6 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
} -body {
    set res {}

    .t delete 2.0 end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {break {}}}\
{{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
{{text 1 {}} {break {n1}} {break {}}}}
test text-37.7 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
} -body {
    set res {}

    .t delete 1.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res

} -result {{{text 1 {}} {break {}}} {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}} {{text 1 {}} {break {}}}}

test text-37.8 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}
} -body {
    set res {}

    .t delete 2.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {text 2 {}} {break {}}} {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}} {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}}


test text-37.9 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately
} -body {
    set res {}

    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}} {{break {n}}} {{break {}}}}


test text-37.10 {deletion - clean widget} -setup {
    text .t -undo on
} -body {
    set res {}

    lappend res [.t inspect -chars -tag]
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    catch {
	.t edit undo
	lappend res [.t inspect -chars -tag]
    }
    set res
} -cleanup {
   destroy .t
   unset res
} -result {{{break {}}} {{break {}}}}

test text-37.11 {deletion - test optimization} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately
} -body {
    .t delete begin end
    .t edit inspect
} -cleanup {
    destroy .t
} -result {{{{tag clear {n 0 1}}} {{tag add n}}} {}}





















# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl







<

>











|
|



<

>











|
|



<

>











|
|



<

>










|
>
>



<

>










>
|
>



<

>











|
|



<

>










>
|
>



<

>










|
>
>




<

>










|
>
>


<

>











|
>










>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>
>







7774
7775
7776
7777
7778
7779
7780

7781
7782
7783
7784
7785
7786
7787
7788
7789
7790
7791
7792
7793
7794
7795
7796
7797
7798

7799
7800
7801
7802
7803
7804
7805
7806
7807
7808
7809
7810
7811
7812
7813
7814
7815
7816

7817
7818
7819
7820
7821
7822
7823
7824
7825
7826
7827
7828
7829
7830
7831
7832
7833
7834

7835
7836
7837
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849
7850
7851
7852

7853
7854
7855
7856
7857
7858
7859
7860
7861
7862
7863
7864
7865
7866
7867
7868
7869
7870

7871
7872
7873
7874
7875
7876
7877
7878
7879
7880
7881
7882
7883
7884
7885
7886
7887
7888

7889
7890
7891
7892
7893
7894
7895
7896
7897
7898
7899
7900
7901
7902
7903
7904
7905
7906

7907
7908
7909
7910
7911
7912
7913
7914
7915
7916
7917
7918
7919
7920
7921
7922
7923
7924
7925

7926
7927
7928
7929
7930
7931
7932
7933
7934
7935
7936
7937
7938
7939
7940
7941
7942

7943
7944
7945
7946
7947
7948
7949
7950
7951
7952
7953
7954
7955
7956
7957
7958
7959
7960
7961
7962
7963
7964
7965
7966
7967
7968
7969
7970
7971
7972
7973
7974
7975
7976
7977
7978
7979
7980
7981
7982
7983
7984
7985
7986
7987
7988
7989
7990
7991
7992
7993
7994
} -cleanup {
    destroy $w
} -result {}

test text-37.1 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}

    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{break {}}}}
test text-37.2 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}

    set res {}
} -body {
    .t delete 2.0 end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {break {}}}}
test text-37.3 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}

    set res {}
} -body {
    .t delete 1.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{text 1 {}} {break {}}}}
test text-37.4 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {}

    set res {}
} -body {
    .t delete 2.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}}
test text-37.5 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}

    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{break {}}}}
test text-37.6 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}

    set res {}
} -body {
    .t delete 2.0 end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{text 1 {}} {break {n1}} {break {}}}}
test text-37.7 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}

    set res {}
} -body {
    .t delete 1.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{text 1 {}} {break {}}}}
test text-37.8 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1" {} "\n" n1 "2" {} "\n" {n2}

    set res {}
} -body {
    .t delete 2.end end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{text 1 {}} {break {n1}} {text 2 {}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {n2}} {break {}}}\
    {{text 1 {}} {break {n1}} {text 2 {}} {break {}}}}
test text-37.9 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately

    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{break {n}}}\
    {{break {}}}}
test text-37.10 {deletion - clean widget} -setup {
    text .t -undo on

    set res {}
} -body {
    lappend res [.t inspect -chars -tag]
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    catch {
	.t edit undo
	lappend res [.t inspect -chars -tag]
    }
    set res
} -cleanup {
   destroy .t
   unset res
} -result {{{break {}}}\
    {{break {}}}}
test text-37.11 {deletion - test optimization} -setup {
    text .t -undo on
    .t tag add n begin
    .t edit separator -immediately
} -body {
    .t delete begin end
    .t edit inspect
} -cleanup {
    destroy .t
} -result {{{{tag clear {n 0 1}}} {{tag add n}}} {}}
test text-37.12 {deletion - newline behavior - undo/redo behavior} -setup {
    text .t -undo on
    .t insert end "1"
    .t tag add n begin end
    .t edit separator -immediately
    set res {}
} -body {
    .t delete begin end
    lappend res [.t inspect -chars -tag]
    .t edit undo
    lappend res [.t inspect -chars -tag]
    .t edit redo
    lappend res [.t inspect -chars -tag]
    set res
} -cleanup {
    destroy .t
    unset res
} -result {{{break {}}}\
    {{break {}} {text 1 {n}} {break {n}}}\
    {{break {}}}}

# cleanup
cleanupTests
return

# Local Variables:
# mode: tcl