From 517e0f7c35f0756d3db480c08f733df37ea7be11 Mon Sep 17 00:00:00 2001 From: daboe01 Date: Thu, 13 Dec 2012 10:54:01 +0100 Subject: [PATCH] block indentation (nest/unnest) --- English.lproj/Edit.nib/designable.nib | 862 +++++------------- English.lproj/Edit.nib/keyedobjects.nib | Bin 32640 -> 33071 bytes NSTextView_TETextExtras.h | 98 ++ NSTextView_TETextExtras.m | 488 ++++++++++ TEFoundationExtras.h | 29 + TEFoundationExtras.m | 151 +++ TextEdit.xcodeproj/project.pbxproj | 16 + .../UserInterfaceState.xcuserstate | Bin 17348 -> 22779 bytes 8 files changed, 1024 insertions(+), 620 deletions(-) create mode 100644 NSTextView_TETextExtras.h create mode 100644 NSTextView_TETextExtras.m create mode 100644 TEFoundationExtras.h create mode 100644 TEFoundationExtras.m diff --git a/English.lproj/Edit.nib/designable.nib b/English.lproj/Edit.nib/designable.nib index 57dbc43..3360a10 100644 --- a/English.lproj/Edit.nib/designable.nib +++ b/English.lproj/Edit.nib/designable.nib @@ -2,19 +2,19 @@ 1050 - 11A399 - 1510 - 1113 - 545.00 + 12C60 + 2844 + 1187.34 + 625.00 com.apple.InterfaceBuilder.CocoaPlugin - 1510 + 2844 YES + NSCustomObject NSMenu NSMenuItem - NSCustomObject YES @@ -1505,6 +1505,22 @@ + + + Shift selection left + + 2147483647 + + + + + + Shift selection right + + 2147483647 + + + YES @@ -1665,6 +1681,62 @@ YES + + + delegate + + + + 272 + + + + terminate: + + + + 509 + + + + hide: + + + + 510 + + + + hideOtherApplications: + + + + 516 + + + + unhideAllApplications: + + + + 518 + + + + orderFrontStandardAboutPanel: + + + + 528 + + + + dockMenu + + + + 650 + selectAll: @@ -1697,22 +1769,6 @@ 134 - - - addFontTrait: - - - - 175 - - - - addFontTrait: - - - - 176 - underline: @@ -1737,14 +1793,6 @@ 179 - - - orderFrontFontPanel: - - - - 183 - toggleRich: @@ -1881,14 +1929,6 @@ 267 - - - delegate - - - - 272 - orderFrontColorPanel: @@ -2025,38 +2065,6 @@ 499 - - - terminate: - - - - 509 - - - - hide: - - - - 510 - - - - hideOtherApplications: - - - - 516 - - - - unhideAllApplications: - - - - 518 - showHelp: @@ -2065,14 +2073,6 @@ 527 - - - orderFrontStandardAboutPanel: - - - - 528 - toggleTraditionalCharacterShape: @@ -2097,22 +2097,6 @@ 542 - - - modifyFont: - - - - 548 - - - - modifyFont: - - - - 549 - stopSpeaking: @@ -2153,14 +2137,6 @@ 580 - - - orderFrontStylesPanel: - - - - 583 - pasteAsPlainText: @@ -2297,22 +2273,6 @@ 641 - - - showWindow: - - - - 644 - - - - toggleWindow: - - - - 646 - newDocument: @@ -2321,22 +2281,6 @@ 649 - - - dockMenu - - - - 650 - - - - showWindow: - - - - 652 - toggleAutomaticDashSubstitution: @@ -2513,6 +2457,86 @@ 809 + + + performTextFinderAction: + + + + 817 + + + + toggleLayoutOrientation: + + + + 819 + + + + TE_indentLeft: + + + + 826 + + + + TE_indentRight: + + + + 827 + + + + addFontTrait: + + + + 175 + + + + addFontTrait: + + + + 176 + + + + orderFrontFontPanel: + + + + 183 + + + + modifyFont: + + + + 548 + + + + modifyFont: + + + + 549 + + + + orderFrontStylesPanel: + + + + 583 + preferencesController @@ -2539,19 +2563,27 @@ - performTextFinderAction: - - + showWindow: + + - 817 + 652 - toggleLayoutOrientation: - - + showWindow: + + - 819 + 644 + + + + toggleWindow: + + + + 646 @@ -2920,6 +2952,8 @@ + + @@ -3804,357 +3838,194 @@ + + 820 + + + + + 822 + + + YES YES + -1.IBPluginDependency + -2.IBPluginDependency -3.IBPluginDependency - -3.ImportedFromIB2 101.IBPluginDependency - 101.ImportedFromIB2 108.IBPluginDependency - 108.ImportedFromIB2 112.IBPluginDependency - 112.ImportedFromIB2 - 119.IBEditorWindowLastContentRect 119.IBPluginDependency - 119.ImportedFromIB2 120.IBPluginDependency - 120.ImportedFromIB2 124.IBPluginDependency - 124.ImportedFromIB2 150.IBPluginDependency - 150.ImportedFromIB2 - 151.IBEditorWindowLastContentRect 151.IBPluginDependency - 151.ImportedFromIB2 152.IBPluginDependency - 152.ImportedFromIB2 154.IBPluginDependency - 154.ImportedFromIB2 155.IBPluginDependency - 155.ImportedFromIB2 - 156.IBEditorWindowLastContentRect 156.IBPluginDependency - 156.ImportedFromIB2 157.IBPluginDependency - 157.ImportedFromIB2 158.IBPluginDependency - 158.ImportedFromIB2 159.IBPluginDependency - 159.ImportedFromIB2 161.IBPluginDependency - 161.ImportedFromIB2 162.IBPluginDependency - 162.ImportedFromIB2 163.IBPluginDependency - 163.ImportedFromIB2 164.IBPluginDependency - 164.ImportedFromIB2 - 165.IBEditorWindowLastContentRect 165.IBPluginDependency - 165.ImportedFromIB2 167.IBPluginDependency - 167.ImportedFromIB2 168.IBPluginDependency - 168.ImportedFromIB2 169.IBPluginDependency - 169.ImportedFromIB2 171.IBPluginDependency - 171.ImportedFromIB2 172.IBPluginDependency - 172.ImportedFromIB2 239.IBPluginDependency - 239.ImportedFromIB2 - 241.IBEditorWindowLastContentRect 241.IBPluginDependency - 241.ImportedFromIB2 242.IBPluginDependency - 242.ImportedFromIB2 243.IBPluginDependency - 243.ImportedFromIB2 244.IBPluginDependency - 244.ImportedFromIB2 - 246.IBEditorWindowLastContentRect 246.IBPluginDependency - 246.ImportedFromIB2 247.IBPluginDependency - 247.ImportedFromIB2 248.IBPluginDependency - 248.ImportedFromIB2 25.IBPluginDependency - 25.ImportedFromIB2 - 250.IBEditorWindowLastContentRect 250.IBPluginDependency - 250.ImportedFromIB2 251.IBPluginDependency - 251.ImportedFromIB2 252.IBPluginDependency - 252.ImportedFromIB2 253.IBPluginDependency - 253.ImportedFromIB2 254.IBPluginDependency - 254.ImportedFromIB2 255.IBPluginDependency - 255.ImportedFromIB2 256.IBPluginDependency - 256.ImportedFromIB2 262.IBPluginDependency - 262.ImportedFromIB2 - 269.ImportedFromIB2 + 269.IBPluginDependency 274.IBPluginDependency - 274.ImportedFromIB2 276.IBPluginDependency - 276.ImportedFromIB2 277.IBPluginDependency - 277.ImportedFromIB2 278.IBPluginDependency - 278.ImportedFromIB2 - 279.IBEditorWindowLastContentRect 279.IBPluginDependency - 279.ImportedFromIB2 281.IBPluginDependency - 281.ImportedFromIB2 283.IBPluginDependency - 283.ImportedFromIB2 284.IBPluginDependency - 284.ImportedFromIB2 310.IBPluginDependency - 310.ImportedFromIB2 311.IBPluginDependency - 311.ImportedFromIB2 312.IBPluginDependency - 312.ImportedFromIB2 314.IBPluginDependency - 314.ImportedFromIB2 315.IBPluginDependency - 315.ImportedFromIB2 316.IBPluginDependency - 316.ImportedFromIB2 - 317.IBEditorWindowLastContentRect 317.IBPluginDependency - 317.ImportedFromIB2 372.IBPluginDependency - 372.ImportedFromIB2 375.IBPluginDependency - 375.ImportedFromIB2 376.IBPluginDependency - 376.ImportedFromIB2 381.IBPluginDependency - 381.ImportedFromIB2 - 393.ImportedFromIB2 + 393.IBPluginDependency 399.IBPluginDependency - 399.ImportedFromIB2 - 4.IBEditorWindowLastContentRect 4.IBPluginDependency - 4.ImportedFromIB2 404.IBPluginDependency - 404.ImportedFromIB2 406.IBPluginDependency - 406.ImportedFromIB2 410.IBPluginDependency - 410.ImportedFromIB2 419.IBPluginDependency - 419.ImportedFromIB2 422.IBPluginDependency - 422.ImportedFromIB2 424.IBPluginDependency - 424.ImportedFromIB2 433.IBPluginDependency - 433.ImportedFromIB2 451.IBPluginDependency - 451.ImportedFromIB2 452.IBPluginDependency - 452.ImportedFromIB2 453.IBPluginDependency - 453.ImportedFromIB2 459.IBPluginDependency - 459.ImportedFromIB2 460.IBPluginDependency - 460.ImportedFromIB2 461.IBPluginDependency - 461.ImportedFromIB2 474.IBPluginDependency - 474.ImportedFromIB2 - 475.IBEditorWindowLastContentRect 475.IBPluginDependency - 475.ImportedFromIB2 476.IBPluginDependency - 476.ImportedFromIB2 477.IBPluginDependency - 477.ImportedFromIB2 478.IBPluginDependency - 478.ImportedFromIB2 479.IBPluginDependency - 479.ImportedFromIB2 - 491.IBEditorWindowLastContentRect 491.IBPluginDependency - 491.ImportedFromIB2 493.IBPluginDependency - 493.ImportedFromIB2 494.IBPluginDependency - 494.ImportedFromIB2 496.IBPluginDependency - 496.ImportedFromIB2 498.IBPluginDependency - 498.ImportedFromIB2 501.IBPluginDependency - 501.ImportedFromIB2 503.IBPluginDependency - 503.ImportedFromIB2 504.IBPluginDependency - 504.ImportedFromIB2 505.IBPluginDependency - 505.ImportedFromIB2 508.IBPluginDependency - 508.ImportedFromIB2 511.IBPluginDependency - 511.ImportedFromIB2 - 512.IBEditorWindowLastContentRect 512.IBPluginDependency - 512.ImportedFromIB2 513.IBPluginDependency - 513.ImportedFromIB2 514.IBPluginDependency - 514.ImportedFromIB2 515.IBPluginDependency - 515.ImportedFromIB2 517.IBPluginDependency - 517.ImportedFromIB2 519.IBPluginDependency - 519.ImportedFromIB2 524.IBPluginDependency - 524.ImportedFromIB2 525.IBPluginDependency - 525.ImportedFromIB2 526.IBPluginDependency - 526.ImportedFromIB2 529.IBPluginDependency - 529.ImportedFromIB2 - 530.IBEditorWindowLastContentRect 530.IBPluginDependency - 530.ImportedFromIB2 531.IBPluginDependency - 531.ImportedFromIB2 534.IBPluginDependency - 534.ImportedFromIB2 537.IBPluginDependency - 537.ImportedFromIB2 - 538.IBEditorWindowLastContentRect 538.IBPluginDependency - 538.ImportedFromIB2 539.IBPluginDependency - 539.ImportedFromIB2 541.IBPluginDependency - 541.ImportedFromIB2 543.IBPluginDependency - 543.ImportedFromIB2 544.IBPluginDependency - 544.ImportedFromIB2 545.IBPluginDependency - 545.ImportedFromIB2 546.IBPluginDependency - 546.ImportedFromIB2 547.IBPluginDependency - 547.ImportedFromIB2 550.IBPluginDependency - 550.ImportedFromIB2 551.IBPluginDependency - 551.ImportedFromIB2 553.IBPluginDependency - 553.ImportedFromIB2 554.IBPluginDependency - 554.ImportedFromIB2 575.IBPluginDependency - 575.ImportedFromIB2 578.IBPluginDependency - 578.ImportedFromIB2 581.IBPluginDependency - 581.ImportedFromIB2 584.IBPluginDependency - 584.ImportedFromIB2 587.IBPluginDependency - 587.ImportedFromIB2 588.IBPluginDependency - 588.ImportedFromIB2 594.IBPluginDependency - 594.ImportedFromIB2 597.IBPluginDependency - 597.ImportedFromIB2 - 598.IBEditorWindowLastContentRect 598.IBPluginDependency - 598.ImportedFromIB2 599.IBPluginDependency - 599.ImportedFromIB2 600.IBPluginDependency - 600.ImportedFromIB2 601.IBPluginDependency - 601.ImportedFromIB2 605.IBPluginDependency - 605.ImportedFromIB2 606.IBPluginDependency - 606.ImportedFromIB2 613.IBPluginDependency - 613.ImportedFromIB2 - 622.ImportedFromIB2 + 622.IBPluginDependency 626.IBPluginDependency - 626.ImportedFromIB2 629.IBPluginDependency - 629.ImportedFromIB2 - 630.IBEditorWindowLastContentRect 630.IBPluginDependency - 630.ImportedFromIB2 631.IBPluginDependency - 631.ImportedFromIB2 632.IBPluginDependency - 632.ImportedFromIB2 633.IBPluginDependency - 633.ImportedFromIB2 - 642.ImportedFromIB2 + 642.IBPluginDependency 643.IBPluginDependency - 643.ImportedFromIB2 - 645.ImportedFromIB2 - 647.IBEditorWindowLastContentRect + 645.IBPluginDependency 647.IBPluginDependency - 647.ImportedFromIB2 648.IBPluginDependency - 648.ImportedFromIB2 654.IBPluginDependency - 655.IBEditorWindowLastContentRect 655.IBPluginDependency 656.IBPluginDependency 657.IBPluginDependency - 657.ImportedFromIB2 658.IBPluginDependency - 658.ImportedFromIB2 661.IBPluginDependency 662.IBPluginDependency - 662.ImportedFromIB2 664.IBPluginDependency 665.IBPluginDependency 669.IBPluginDependency - 67.ImportedFromIB2 + 67.IBPluginDependency 670.IBPluginDependency 674.IBPluginDependency - 674.ImportedFromIB2 676.IBPluginDependency - 676.ImportedFromIB2 677.IBPluginDependency - 677.ImportedFromIB2 678.IBPluginDependency - 678.ImportedFromIB2 683.IBPluginDependency - 683.ImportedFromIB2 759.IBPluginDependency - 759.ImportedFromIB2 782.IBPluginDependency - 782.ImportedFromIB2 785.IBPluginDependency - 785.ImportedFromIB2 786.IBPluginDependency - 787.IBEditorWindowLastContentRect 787.IBPluginDependency 788.IBPluginDependency 789.IBPluginDependency @@ -4166,358 +4037,177 @@ 798.IBPluginDependency 799.IBPluginDependency 816.IBPluginDependency - 816.ImportedFromIB2 818.IBPluginDependency + 820.IBPluginDependency + 822.IBPluginDependency 96.IBPluginDependency - 96.ImportedFromIB2 - + YES com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{642, 573}, {259, 353}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{905, 693}, {204, 213}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{686, 743}, {219, 183}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{540, 723}, {202, 343}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{742, 743}, {145, 103}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{742, 803}, {145, 63}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{742, 803}, {163, 83}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{600, 623}, {201, 303}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{901, 533}, {238, 143}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - {{510, 926}, {374, 20}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{387, 993}, {194, 73}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{500, 728}, {278, 113}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{522, 743}, {192, 183}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{742, 803}, {179, 23}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{901, 553}, {164, 43}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{536, 803}, {177, 63}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - {{901, 483}, {196, 153}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - - com.apple.InterfaceBuilder.CocoaPlugin - - - {{383, 983}, {169, 23}} com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{500, 738}, {173, 63}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin - {{1109, 643}, {164, 173}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -4529,10 +4219,18 @@ com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin + com.apple.InterfaceBuilder.CocoaPlugin @@ -4547,7 +4245,7 @@ - 819 + 827 @@ -4563,7 +4261,7 @@ preferencesController propertiesController - + YES LinePanelController Preferences @@ -4578,7 +4276,7 @@ preferencesController propertiesController - + YES lineController @@ -4610,7 +4308,7 @@ togglePageBreaks: toggleReadOnly: - + YES id id @@ -4625,7 +4323,7 @@ togglePageBreaks: toggleReadOnly: - + YES saveDocumentAsPDFTo: @@ -4727,7 +4425,7 @@ selectAll: showPanel: - + YES id id @@ -4746,7 +4444,7 @@ selectAll: showPanel: - + YES clearAll: @@ -4819,7 +4517,7 @@ toggleRich: toggleTraditionalCharacterShape: - + YES id id @@ -4880,7 +4578,7 @@ toggleRich: toggleTraditionalCharacterShape: - + YES close: @@ -5003,7 +4701,7 @@ lineFieldChanged: selectClicked: - + YES id id @@ -5016,7 +4714,7 @@ lineFieldChanged: selectClicked: - + YES lineFieldChanged: @@ -5045,139 +4743,63 @@ - NSDocument + NSTextView YES YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: + TE_indentLeft: + TE_indentRight: + TE_toggleShowsNonAsciiCharacters: + orderFrontSharingServicePicker: + toggleQuickLookPreviewPanel: - + YES id id id id id - id YES YES - printDocument: - revertDocumentToSaved: - runPageLayout: - saveDocument: - saveDocumentAs: - saveDocumentTo: + TE_indentLeft: + TE_indentRight: + TE_toggleShowsNonAsciiCharacters: + orderFrontSharingServicePicker: + toggleQuickLookPreviewPanel: - + YES - printDocument: + TE_indentLeft: id - revertDocumentToSaved: + TE_indentRight: id - runPageLayout: + TE_toggleShowsNonAsciiCharacters: id - saveDocument: + orderFrontSharingServicePicker: id - saveDocumentAs: - id - - - saveDocumentTo: - id - - - - - IBProjectSource - ./Classes/NSDocument.h - - - - NSDocumentController - - _openRecentDocument: - id - - - _openRecentDocument: - - _openRecentDocument: - id - - - - IBProjectSource - ./Classes/NSDocumentController.h - - - - NSPopover - NSResponder - - performClose: - id - - - performClose: - - performClose: - id - - - - YES - - YES - contentViewController - delegate - - - YES - NSViewController - id - - - - YES - - YES - contentViewController - delegate - - - YES - - contentViewController - NSViewController - - - delegate + toggleQuickLookPreviewPanel: id IBProjectSource - ./Classes/NSPopover.h + ./Classes/NSTextView.h @@ -5191,7 +4813,7 @@ changeRichTextFont: revertToDefault: - + YES id id @@ -5206,7 +4828,7 @@ changeRichTextFont: revertToDefault: - + YES changePlainTextFont: @@ -5267,10 +4889,10 @@ NSMenuCheckmark NSMenuMixedState - + YES - {9, 8} - {7, 2} + {11, 11} + {10, 3} diff --git a/English.lproj/Edit.nib/keyedobjects.nib b/English.lproj/Edit.nib/keyedobjects.nib index d7ebf3b11970438d6fbe35b6f500f7e38782d9e3..b7874de75f0ba36d7e1c573a30afa87d4a00ae9c 100644 GIT binary patch literal 33071 zcmeFa33wD$^EcXkPR~BwnUj6r$-XCq5NERQ3lI|a%@76%gd}8PNBe*Z$|5@gitLDh zC@6x6EQ0KafNTniAcCTZh@fn@x+gOU67YYY?>^sipL@TzePO1jyXsV(sybD_I^FcI zt*WeVh>1DLunb}_!!Zg*Y3E_***$QCxvsvlrn-AzP5&Y0iiY|gf#r1-gDc^5Sztp= ztv$oOvSb6n2N@NkW_*|cCYXt0Vwtu~duBcJ5wnHa#(c``WcD(Ln8VC5<~!zl=11lV z^Aqzk^BZ%6`Gfh3`J4HNdBh?XvmC2o^{gFhV4YZ3){S*%eb^v2f{kRO*f=(kHL>Yz z2Aj!dv3YDKwuJ4>ma^U0zHC4CdA6K2vsLUcwwkSB>)A2vSauvco~7)o>~!{Zb_P3# zUBtf0zQrzPm$7Tu_3V4>2KIgSLv|bcDZ8EhjQyNF%pPHnvR|<$*{|8N?DyA=-ScDKp98x0#BFG*&BQNBQd{6)iL*Xa_MWR@ggxaHIl!|gtF3Lms zs2G)@?x+XqiTWZlszgK3P*j6PpfPAHdJ(;XCZWmbRWuFFL37bOG#@QO%g}PP8oh@$ zp!d;-XdC(zZAZJ%eslmGL`Tur=oC7KE}|dN74#Fjimszu=udPT{f!ySVuUePVFBA= z118uBdtxu_jeT$c4#VL%0>|KX_&IFECY*vZa6T@;g}5W`hP&e)xDOtH&3GUlgoomK z+<+VLXe?riC*X;A5}uA<$20I8ya>OE-@;4rJ9rI#7q7(|@Miom-h#K{?RXE~i@(78 z@F9F0pTH;a*Z3^{9$&;i;4Ao7{2RW3Z{dINJ$xTO;8;%0X*eyXVt&J-J?7Z|-?+5I2~s9kJa>`%fxE>0#QnzI;C|=+!W9vU z7)3iplA^uBq{vcaD{>Ttiq48sMVX?zqMzbYK|D#dEWJBoFRO^Oc{A1O8~K2hva>{fiP*rzzEIIcLMIH@?J z_)hV?;-cb5#dXE6ir*Bs6#pphDefy7C8yLW?UV*3Q93C-m0n73rN1&%8Kw+ZMk^DQ z?UYGMqcT&OrOa05D?2Gml%17bm3@?bmHm_z$|1_3$|_~8a-?#Ua

1@+IZV%2$-H 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 diff --git a/NSTextView_TETextExtras.h b/NSTextView_TETextExtras.h new file mode 100644 index 0000000..6f47491 --- /dev/null +++ b/NSTextView_TETextExtras.h @@ -0,0 +1,98 @@ +// NSTextView_TETextExtras.h +// TextExtras +// +// Copyright © 1996-2006, Mike Ferris. +// All rights reserved. + +// The TabWidth and IndentWidth defaults: several of the features provided make use of these two defaults. The TabWidth default is actually used by TextEdit as well. Basically these defaults determine the number of spaces in a tab and the number of spaces in an indent level. The default values are 8 for TabWidth and 4 for IndentWidth. +// The TryToInstallExtrasMenu default controls whether the category will actually attempt to insert a new menu into the Format menu. If YES, it tries to find the Format menu and, if there is a Text menu it puts the new menu below it, otherwise it puts it at the end of the Format menu. If it can't find the Format menu it gives up. The menu provides commands for nest/unnest, and bringing up the goto panel. + +#import + +@interface NSTextView (TETextExtras) + +- (IBAction)TE_indentRight:(id)sender; +- (IBAction)TE_indentLeft:(id)sender; + // These two actions add (indentRight:) or subtract (indentLeft:) IndentWidth spaces from the beginning of each line included (even partially) in the selection. The resulting leading whitespace in each line is always minimized by using as many tabs as possible (given the TabWidth) and filling the remainder with spaces. This feature has a simple-minded notion of leading whitespace (' ' and '\t' only). + +- (void)TE_insertNewlineAndIndent:(id)sender; +- (void)TE_insertCRLFAndIndent:(id)sender; +- (void)TE_insertCRAndIndent:(id)sender; +- (void)TE_insertParagraphSeparatorAndIndent:(id)sender; +- (void)TE_insertLineSeparatorAndIndent:(id)sender; + // This is like insertNewline: (or TE_insertCRLF:, etc...) but after the newline (or whatever line ending it is) it also inserts enough whitespace to match the leading whitespace of the previous line. The resulting leading whitespace in each line is always minimized by using as many tabs as possible (given the TabWidth) and filling the remainder with spaces. This feature has a simple-minded notion of leading whitespace (' ' and '\t' only). + +- (void)TE_gotoPanel:(id)sender; + // Allows access to the goto panel provided by TEGotoPanelController. This just brings up the panel and selects the text field so you can type a line or character number and hit return. This is useful to bind if the TextExtras menu is set not to always install itself. + +- (void)TE_preferencesPanel:(id)sender; + // Allows access to the preferences panel provided by TEPreferencesController. This is useful to bind if the TextExtras menu is set not to always install itself. + +- (void)TE_specialCharactersPanel:(id)sender; + // Allows access to the special characters panel provided by TESpecialCharactersController. This is useful to bind if the TextExtras menu is set not to always install itself. + +- (void)TE_openQuickly:(id)sender; + // Allows access to the open quickly panel provided by TEOpenQuicklyController. This is useful to bind if the TextExtras menu is set not to always install itself. + +- (void)TE_executePipe:(id)sender; + // Brings up the pipe panel. + +- (void)TE_executeSelectionAppendingOutput:(id)sender; +- (void)TE_executeSelectionInsertingOutput:(id)sender; +- (void)TE_executeSelectionSendingOutputToPasteboard:(id)sender; + // These create a user pipe using the selection as the script. The command has no stdin data and stdout goes to various places for the different methods. + +- (void)TE_complete:(id)sender; +- (NSRange)TE_replacementRangeAfterReplacingCharactersInRange:(NSRange)replacementRange withCompletionText:(NSString *)string; + +// Debugging utilities +- (void)TE_logTextViewDescriptions:(id)sender; +- (void)TE_logTextContainerDescriptions:(id)sender; +- (void)TE_logLayoutManagerDescription:(id)sender; +- (void)TE_logLayoutManagerContainerDescription:(id)sender; +- (void)TE_logLayoutManagerLineFragmentDescription:(id)sender; +- (void)TE_logLayoutManagerVerboseLineFragmentDescription:(id)sender; +- (void)TE_logLayoutManagerGlyphDescription:(id)sender; +- (void)TE_logTextStorageDescription:(id)sender; + +// Control character and end of line stuff +- (void)TE_toggleShowsControlCharacters:(id)sender; + // Toggles the showsControlCharacters setting for the view's layout manager. + +- (void)TE_parseSelectionAsPropertyList:(id)sender; +- (void)TE_parseFileAsPropertyList:(id)sender; +- (void)TE_convertSelectionToXMLPropertyList:(id)sender; +- (void)TE_convertFileToXMLPropertyList:(id)sender; +- (void)TE_convertSelectionToASCIIPropertyList:(id)sender; +- (void)TE_convertFileToASCIIPropertyList:(id)sender; + +- (void)TE_standardizeEndOfLineToLF:(id)sender; +- (void)TE_standardizeEndOfLineToCRLF:(id)sender; +- (void)TE_standardizeEndOfLineToCR:(id)sender; +- (void)TE_standardizeEndOfLineToParagraphSeparator:(id)sender; +- (void)TE_standardizeEndOfLineToLineSeparator:(id)sender; + // Standardize ends of lines. + +- (void)TE_insertCRLF:(id)sender; +- (void)TE_insertCR:(id)sender; +- (void)TE_insertLineSeparator:(id)sender; + // Just like insertNewline: and insertParagraphSeparator: except it inserts different end of line sequences. + +- (void)TE_indentFriendlyDeleteBackward:(id)sender; + // Deletes whitespace at the beginning of a line by IndentWidth. Same as deleteBackward: when not in the leading whitespace. + +- (void)TE_reindentWrappedLines:(id)sender; + // This really just tweaks the text storage making it think the whole text was edited. Expensive, but this is a sledge hammer kind of solution to your problems. + +- (void)TE_indentFriendlyInsertTab:(id)sender; + // If selection is in leading whitespace this inserts spaces and or tabs as appropriate to indent by one more indent width. Same as insertTab: when not in leading whitespace. + +- (void)TE_selectNextLineWithSameOrSmallerIndent:(id)sender; +- (void)TE_selectToNextLineWithSameOrSmallerIndent:(id)sender; +- (void)TE_selectPreviousLineWithSameOrSmallerIndent:(id)sender; +- (void)TE_selectToPreviousLineWithSameOrSmallerIndent:(id)sender; + // Outline navigation helpers. + +- (IBAction)TE_toggleShowsNonAsciiCharacters:(id)sender; + +@end diff --git a/NSTextView_TETextExtras.m b/NSTextView_TETextExtras.m new file mode 100644 index 0000000..a03cc4e --- /dev/null +++ b/NSTextView_TETextExtras.m @@ -0,0 +1,488 @@ +// NSTextView_TETextExtras.m +// TextExtras +// +// Copyright © 1996-2006, Mike Ferris. +// All rights reserved. + +#import "NSTextView_TETextExtras.h" +#import "TETextUtils.h" +#import "TEFoundationExtras.h" + +#define USES_TABS YES +#define TAB_WIDTH 4 +#define INDENT_WIDTH 4 + +static BOOL _subclassOverridesSelector(Class subclass, Class baseClass, SEL selector); + // Implemented at the bottom of this file. Returns YES if the given selector is overridden for the given subclass relative to the given baseClass (or an intervening ancestor of it). + +@interface NSLayoutManager (TEPrivatesOnParade) + +// MF: Shhh... don't tell anyone about these private methods. If they stop working, tough luck. +- (NSString *)_containerDescription; +- (NSString *)_lineFragmentDescription:(BOOL)verboseFlag; +- (NSString *)_glyphDescription; + +@end + +@implementation NSTextView (TETextExtras) + +// MF: The ugliness of most of the method names in this category are because the base class and all categories share a namespace for their methods. All the methods in this category that are prefixed with TE_ are done that way to avoid conflicting with another method in another category (I mean, who else would have such ugly method names?) There are exceptions. Category methods without prefixes are inherently unwise in a loadable bundle situation like this. Where there are exceptions the overriding reasons for them are explained. + +// ********************** Nest/Unnest feature ********************** + +- (void)TE_doUserIndentByNumberOfLevels:(int)levels { + // Because of the way paragraph ranges work we will add spaces a final paragraph separator only if the selection is an insertion point at the end of the text. + // We ask for rangeForUserTextChange and extend it to paragraph boundaries instead of asking rangeForUserParagraphAttributeChange because this is not an attribute change and we don't want it to be affected by the usesRuler setting. + NSRange charRange = [[self string] lineRangeForRange:[self rangeForUserTextChange]]; + NSRange selRange = [self selectedRange]; + if (charRange.location != NSNotFound) { + NSTextStorage *textStorage = [self textStorage]; + NSAttributedString *newText; + unsigned tabWidth = TAB_WIDTH; + unsigned indentWidth = INDENT_WIDTH; + BOOL usesTabs = USES_TABS; + + selRange.location -= charRange.location; + newText = TE_attributedStringByIndentingParagraphs([textStorage attributedSubstringFromRange:charRange], levels, &selRange, [self typingAttributes], tabWidth, indentWidth, usesTabs); + selRange.location += charRange.location; + if ([self shouldChangeTextInRange:charRange replacementString:[newText string]]) { + [textStorage replaceCharactersInRange:charRange withAttributedString:newText]; + [self setSelectedRange:selRange]; + [self didChangeText]; + } + } +} + +- (IBAction)TE_indentRight:(id)sender { + [self TE_doUserIndentByNumberOfLevels:1]; +} + +- (IBAction)TE_indentLeft:(id)sender { + [self TE_doUserIndentByNumberOfLevels:-1]; +} + + +- (void)TE_standardizeEndOfLineToLF:(id)sender { + NSTextStorage *textStorage = [self textStorage]; + NSMutableString *str = [textStorage mutableString]; + NSRange charRange = NSMakeRange(0, [str length]); + + if ([self shouldChangeTextInRange:charRange replacementString:nil]) { + // -TE_standardizeEndOfLineToLF might do many separate edits, so turn on the batching in textStorage here. + [textStorage beginEditing]; + [str TE_standardizeEndOfLineToLF]; + [textStorage endEditing]; + [self didChangeText]; + } +} + +- (void)TE_standardizeEndOfLineToCRLF:(id)sender { + NSTextStorage *textStorage = [self textStorage]; + NSMutableString *str = [textStorage mutableString]; + NSRange charRange = NSMakeRange(0, [str length]); + + if ([self shouldChangeTextInRange:charRange replacementString:nil]) { + // -TE_standardizeEndOfLineToCRLF might do many separate edits, so turn on the batching in textStorage here. + [textStorage beginEditing]; + [str TE_standardizeEndOfLineToCRLF]; + [textStorage endEditing]; + [self didChangeText]; + } +} + +- (void)TE_standardizeEndOfLineToCR:(id)sender { + NSTextStorage *textStorage = [self textStorage]; + NSMutableString *str = [textStorage mutableString]; + NSRange charRange = NSMakeRange(0, [str length]); + + if ([self shouldChangeTextInRange:charRange replacementString:nil]) { + // -TE_standardizeEndOfLineToCR might do many separate edits, so turn on the batching in textStorage here. + [textStorage beginEditing]; + [str TE_standardizeEndOfLineToCR]; + [textStorage endEditing]; + [self didChangeText]; + } +} + +- (void)TE_standardizeEndOfLineToParagraphSeparator:(id)sender { + NSTextStorage *textStorage = [self textStorage]; + NSMutableString *str = [textStorage mutableString]; + NSRange charRange = NSMakeRange(0, [str length]); + + if ([self shouldChangeTextInRange:charRange replacementString:nil]) { + // -TE_standardizeEndOfLineToParagraphSeparator might do many separate edits, so turn on the batching in textStorage here. + [textStorage beginEditing]; + [str TE_standardizeEndOfLineToParagraphSeparator]; + [textStorage endEditing]; + [self didChangeText]; + } +} + +- (void)TE_standardizeEndOfLineToLineSeparator:(id)sender { + NSTextStorage *textStorage = [self textStorage]; + NSMutableString *str = [textStorage mutableString]; + NSRange charRange = NSMakeRange(0, [str length]); + + if ([self shouldChangeTextInRange:charRange replacementString:nil]) { + // -TE_standardizeEndOfLineToLineSeparator might do many separate edits, so turn on the batching in textStorage here. + [textStorage beginEditing]; + [str TE_standardizeEndOfLineToLineSeparator]; + [textStorage endEditing]; + [self didChangeText]; + } +} + +- (void)TE_insertCRLF:(id)sender { + if (_subclassOverridesSelector([self class], [NSTextView class], @selector(insertNewline:))) { + // Some text system clients do special things when they see insertNewline:. If the receiver is a subclass that has an overridden version of insertNewline:, call that. + [self insertNewline:sender]; + return; + } else if ([[self delegate] respondsToSelector:@selector(textView:doCommandBySelector:)]) { + // If the delegate wants a crack at command selectors, give it a crack at the standard selector too. + if ([[self delegate] textView:self doCommandBySelector:@selector(insertNewline:)]) { + return; + } + } + if ([self isFieldEditor]) { + // Field editors needs to do something special with newlines, and we don't know how. Let insertNewline handle it, because it does know how. + [self insertNewline:self]; + } else { + [self insertText:@"\r\n"]; + } +} + +- (void)TE_insertCR:(id)sender { + if (_subclassOverridesSelector([self class], [NSTextView class], @selector(insertNewline:))) { + // Some text system clients do special things when they see insertNewline:. If the receiver is a subclass that has an overridden version of insertNewline:, call that. + [self insertNewline:sender]; + return; + } else if ([[self delegate] respondsToSelector:@selector(textView:doCommandBySelector:)]) { + // If the delegate wants a crack at command selectors, give it a crack at the standard selector too. + if ([[self delegate] textView:self doCommandBySelector:@selector(insertNewline:)]) { + return; + } + } + if ([self isFieldEditor]) { + // Field editors needs to do something special with newlines, and we don't know how. Let insertNewline handle it, because it does know how. + [self insertNewline:self]; + } else { + [self insertText:@"\r"]; + } +} + +- (void)TE_insertLineSeparator:(id)sender { + if (_subclassOverridesSelector([self class], [NSTextView class], @selector(insertNewline:))) { + // Some text system clients do special things when they see insertNewline:. If the receiver is a subclass that has an overridden version of insertNewline:, call that. + [self insertNewline:sender]; + return; + } else if ([[self delegate] respondsToSelector:@selector(textView:doCommandBySelector:)]) { + // If the delegate wants a crack at command selectors, give it a crack at the standard selector too. + if ([[self delegate] textView:self doCommandBySelector:@selector(insertNewline:)]) { + return; + } + } + if ([self isFieldEditor]) { + // Field editors needs to do something special with newlines, and we don't know how. Let insertNewline handle it, because it does know how. + [self insertNewline:self]; + } else { + unichar lineSeparator[1]; + + lineSeparator[0] = NSLineSeparatorCharacter; + + [self insertText:[NSString stringWithCharacters:lineSeparator length:1]]; + } +} + +- (void)TE_indentFriendlyDeleteBackward:(id)sender { + if (_subclassOverridesSelector([self class], [NSTextView class], @selector(deleteBackward:))) { + // Some text system clients do special things when they see deleteBackward:. If the receiver is a subclass that has an overridden version of deleteBackward:, call that. + [self deleteBackward:sender]; + return; + } else if ([[self delegate] respondsToSelector:@selector(textView:doCommandBySelector:)]) { + // If the delegate wants a crack at command selectors, give it a crack at the standard selector too. + if ([[self delegate] textView:self doCommandBySelector:@selector(deleteBackward:)]) { + return; + } + } + if ([self isRichText]) { + // This is not appropriate for rich text. + [self deleteBackward:sender]; + } else { + NSRange charRange = [self rangeForUserTextChange]; + if (charRange.location != NSNotFound) { + if (charRange.length > 0) { + // Non-zero selection. Delete normally. + [self deleteBackward:sender]; + } else { + if (charRange.location == 0) { + // At beginning of text. Delete normally. + [self deleteBackward:sender]; + } else { + NSString *string = [self string]; + NSRange paraRange = [string lineRangeForRange:NSMakeRange(charRange.location - 1, 1)]; + if (paraRange.location == charRange.location) { + // At beginning of line. Delete normally. + [self deleteBackward:sender]; + } else { + unsigned tabWidth = TAB_WIDTH; + unsigned indentWidth = INDENT_WIDTH; + BOOL usesTabs = USES_TABS; + NSRange leadingSpaceRange = paraRange; + unsigned leadingSpaces = TE_numberOfLeadingSpacesFromRangeInString(string, &leadingSpaceRange, tabWidth); + + if (charRange.location > NSMaxRange(leadingSpaceRange)) { + // Not in leading whitespace. Delete normally. + [self deleteBackward:sender]; + } else { + NSTextStorage *text = [self textStorage]; + unsigned leadingIndents = leadingSpaces / indentWidth; + NSString *replaceString; + + // If we were indented to an fractional level just go back to the last even multiple of indentWidth, if we were exactly on, go back a full level. + if (leadingSpaces % indentWidth == 0) { + leadingIndents--; + } + leadingSpaces = leadingIndents * indentWidth; + replaceString = ((leadingSpaces > 0) ? TE_tabbifiedStringWithNumberOfSpaces(leadingSpaces, tabWidth, usesTabs) : @""); + if ([self shouldChangeTextInRange:leadingSpaceRange replacementString:replaceString]) { + NSDictionary *newTypingAttributes; + if (charRange.location < [string length]) { + newTypingAttributes = [[text attributesAtIndex:charRange.location effectiveRange:NULL] retain]; + } else { + newTypingAttributes = [[text attributesAtIndex:(charRange.location - 1) effectiveRange:NULL] retain]; + } + + [text replaceCharactersInRange:leadingSpaceRange withString:replaceString]; + + [self setTypingAttributes:newTypingAttributes]; + [newTypingAttributes release]; + + [self didChangeText]; + } + } + } + } + } + } + } +} + +static NSRange TEIntersectionRange(NSRange r1, NSRange r2) { + // This is different from NSIntersectionRange() in its handling of zero-length ranges. This does what I consider to make sense while Foundation kind of punts and tends to return 0, 0 for zero-length inputs sometimes. It returns NSNotFound, 0 when there is no intersection also, where Foundation returns 0, 0. + unsigned max1 = NSMaxRange(r1); + unsigned max2 = NSMaxRange(r2); + unsigned smallestMax = ((max1 < max2) ? max1 : max2); + unsigned biggestMin = ((r1.location > r2.location) ? r1.location : r2.location); + + if (smallestMax < biggestMin) { + // No intersection + return NSMakeRange(NSNotFound, 0); + } else { + return NSMakeRange(biggestMin, smallestMax - biggestMin); + } +} + +- (void)TE_indentFriendlyInsertTab:(id)sender { + if (_subclassOverridesSelector([self class], [NSTextView class], @selector(insertTab:))) { + // Some text system clients do special things when they see insertTab:. If the receiver is a subclass that has an overridden version of insertTab:, call that. + [self insertTab:sender]; + return; + } else if ([[self delegate] respondsToSelector:@selector(textView:doCommandBySelector:)]) { + // If the delegate wants a crack at command selectors, give it a crack at the standard selector too. + if ([[self delegate] textView:self doCommandBySelector:@selector(insertTab:)]) { + return; + } + } + if ([self isRichText] || [self isFieldEditor]) { + // This is not appropriate for rich text or field editors. + [self insertTab:sender]; + } else { + NSRange charRange = [self rangeForUserTextChange]; + if (charRange.location != NSNotFound) { + NSString *string = [self string]; + unsigned stringLen = [string length]; + NSRange paraRange, leadingSpaceRange; + unsigned tabWidth = TAB_WIDTH; + unsigned indentWidth = INDENT_WIDTH; + BOOL usesTabs = USES_TABS; + unsigned leadingSpaces; + + // Find range of paragraph where selection starts + if (charRange.location < stringLen) { + paraRange = [string lineRangeForRange:NSMakeRange(charRange.location, 1)]; + } else { + if (charRange.location == 0) { + // Empty text. + paraRange = NSMakeRange(0, 0); + } else { + // At end of text. + if (TE_IsParagraphSeparator([string characterAtIndex:charRange.location - 1], string, charRange.location - 1)) { + // Extra line frag + paraRange = NSMakeRange(charRange.location, 0); + } else { + // End of last line + paraRange = [string lineRangeForRange:NSMakeRange(charRange.location - 1, 1)]; + } + } + } + // Find the range of leading whitespace for the paragraph we are in. + leadingSpaceRange = paraRange; + leadingSpaces = TE_numberOfLeadingSpacesFromRangeInString(string, &leadingSpaceRange, tabWidth); + + // Now, see if the selection range is totally inside the leading whitespace + if (!NSEqualRanges(charRange, TEIntersectionRange(charRange, leadingSpaceRange))) { + // Range was not entirely in whitespace. + [self insertTab:sender]; + } else { + NSTextStorage *text = [self textStorage]; + unsigned leadingIndents = leadingSpaces / indentWidth; + NSString *replaceString; + + leadingIndents++; // This will go forward to the next level even if we had a partial level to begin with. + leadingSpaces = leadingIndents * indentWidth; + replaceString = ((leadingSpaces > 0) ? TE_tabbifiedStringWithNumberOfSpaces(leadingSpaces, tabWidth, usesTabs) : @""); + if ([self shouldChangeTextInRange:leadingSpaceRange replacementString:replaceString]) { + [text beginEditing]; + [text replaceCharactersInRange:leadingSpaceRange withString:replaceString]; + [text setAttributes:[self typingAttributes] range:NSMakeRange(leadingSpaceRange.location, [replaceString length])]; + [text endEditing]; + + [self didChangeText]; + } + } + } + } +} + +- (void)TE_reindentWrappedLines:(id)sender { + NSTextStorage *text = [self textStorage]; + unsigned textLength = ((text != nil) ? [text length] : 0); + + if ((textLength == 0) || [self isRichText] || [self isFieldEditor]) { + // Forget it. + return; + } + // Just tickle the text storage to trick it into fixing attributes and notifying everybody. + [text beginEditing]; + [text edited:NSTextStorageEditedCharacters range:NSMakeRange(0, textLength) changeInLength:0]; + [text endEditing]; +} + +- (NSRange)TE_rangeOfLineWithSameOrSmallerIndentSearchingBackwards:(BOOL)backwardsFlag { + NSRange charRange = [[self string] lineRangeForRange:[self selectedRange]]; + NSRange tempRange = charRange; + unsigned tabWidth = TAB_WIDTH; + unsigned leadingSpaces = TE_numberOfLeadingSpacesFromRangeInString([self string], &tempRange, tabWidth); + + // Bump it up by one so we can do a less-than-or-equal search + leadingSpaces++; + charRange = TE_rangeOfLineWithLeadingWhiteSpace([self string], charRange, leadingSpaces, NSOrderedDescending, backwardsFlag, tabWidth); + return charRange; +} + +- (void)TE_selectNextLineWithSameOrSmallerIndent:(id)sender { + NSRange newRange = [self TE_rangeOfLineWithSameOrSmallerIndentSearchingBackwards:NO]; + [self setSelectedRange:newRange]; + [self scrollRangeToVisible:newRange]; +} + +- (void)TE_selectToNextLineWithSameOrSmallerIndent:(id)sender { + NSRange charRange = [[self string] lineRangeForRange:[self selectedRange]]; + NSRange newRange = [self TE_rangeOfLineWithSameOrSmallerIndentSearchingBackwards:NO]; + + [self setSelectedRange:NSMakeRange(charRange.location, newRange.location - charRange.location)]; + [self scrollRangeToVisible:NSMakeRange(NSMaxRange(newRange), 0)]; +} + +- (void)TE_selectPreviousLineWithSameOrSmallerIndent:(id)sender { + NSRange newRange = [self TE_rangeOfLineWithSameOrSmallerIndentSearchingBackwards:YES]; + [self setSelectedRange:newRange]; + [self scrollRangeToVisible:newRange]; +} + +- (void)TE_selectToPreviousLineWithSameOrSmallerIndent:(id)sender { + NSRange charRange = [[self string] lineRangeForRange:[self selectedRange]]; + NSRange newRange = [self TE_rangeOfLineWithSameOrSmallerIndentSearchingBackwards:YES]; + + [self setSelectedRange:NSMakeRange(newRange.location, charRange.location - newRange.location)]; + [self scrollRangeToVisible:NSMakeRange(newRange.location, 0)]; +} + +- (IBAction)TE_toggleShowsNonAsciiCharacters:(id)sender { + [[self textStorage] TE_setShowsNonAsciiCharacters:![[self textStorage] TE_showsNonAsciiCharacters]]; + [self TE_reindentWrappedLines:self]; +} + +@end + +@implementation NSResponder (TETextExtras) + +// This NSResponder category implements the various selectors that we add to NSTextView that are often used to replace standard key bindings like -insertNewline:. These implementations all simply call the standard method they are a replacement for (if it is implemented). + +- (void)TE_responderImplementationForSelector:(SEL)realSelector standardSelector:(SEL)standardSelector sender:(id)sender { + if ([self respondsToSelector:standardSelector]) { + [self performSelector:standardSelector withObject:sender]; + } else { + // Pass it up the chain + [[self nextResponder] doCommandBySelector:realSelector]; + } +} + +// Replacement methods for insertNewline: +- (void)TE_insertNewlineAndIndent:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertCRLFAndIndent:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertCRAndIndent:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertParagraphSeparatorAndIndent:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertLineSeparatorAndIndent:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertCRLF:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertCR:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +- (void)TE_insertLineSeparator:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertNewline:) sender:sender]; +} + +// Replacement method for deleteBackward: +- (void)TE_indentFriendlyDeleteBackward:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(deleteBackward:) sender:sender]; +} + +// Replacement method for insertTab: +- (void)TE_indentFriendlyInsertTab:(id)sender { + [self TE_responderImplementationForSelector:_cmd standardSelector:@selector(insertTab:) sender:sender]; +} + +@end + + +#import + +static BOOL _subclassOverridesSelector(Class subclass, Class baseClass, SEL selector) { + // This function returns YES if the given selector has different implementations for subclass and baseClass. In other words, it returns whether, somewhere between baseClass and subclass, the given selector was overridden. + Method baseMethod; + Method subclassMethod; + + baseMethod = class_getInstanceMethod(baseClass, selector); + subclassMethod = class_getInstanceMethod(subclass, selector); + // return ((baseMethod->method_imp == subclassMethod->method_imp) ? NO : YES); + return NO; +} diff --git a/TEFoundationExtras.h b/TEFoundationExtras.h new file mode 100644 index 0000000..464a66a --- /dev/null +++ b/TEFoundationExtras.h @@ -0,0 +1,29 @@ +// TEFoundationExtras.h +// TextExtras +// +// Copyright © 1996-2006, Mike Ferris. +// All rights reserved. + +#import + +@interface NSString (TEFoundationExtras) + +- (NSString *)TE_stringByReplacingBackslashWithSlash; + +@end + +@interface NSMutableString (TEFoundationExtras) + +- (void)TE_standardizeEndOfLineToLF; +- (void)TE_standardizeEndOfLineToCRLF; +- (void)TE_standardizeEndOfLineToCR; +- (void)TE_standardizeEndOfLineToParagraphSeparator; +- (void)TE_standardizeEndOfLineToLineSeparator; + +@end + +@interface NSArray (TEFoundationExtras) + +- (NSString *)TE_longestCommonPrefixForStrings; + +@end diff --git a/TEFoundationExtras.m b/TEFoundationExtras.m new file mode 100644 index 0000000..76a6811 --- /dev/null +++ b/TEFoundationExtras.m @@ -0,0 +1,151 @@ +// TEFoundationExtras.m +// TextExtras +// +// Copyright © 1996-2006, Mike Ferris. +// All rights reserved. + +#import "TEFoundationExtras.h" + +@implementation NSString (TEFoundationExtras) + +- (NSString *)TE_stringByReplacingBackslashWithSlash { + NSMutableString *newStr = [self mutableCopy]; + NSRange searchRange, foundRange; + + searchRange = NSMakeRange(0, [self length]); + while ((searchRange.length > 0) && ((foundRange = [newStr rangeOfString:@"\\" options:NSLiteralSearch range:searchRange]).length > 0)) { + [newStr replaceCharactersInRange:foundRange withString:@"/"]; + searchRange = NSMakeRange(NSMaxRange(foundRange), NSMaxRange(searchRange) - NSMaxRange(foundRange)); + } + + return [newStr autorelease]; +} + +@end + +@implementation NSMutableString (TEFoundationExtras) + +static void standardizeEndOfLineInString(NSMutableString *str, NSString *newEOL) { + // This function works by replacing ParagraphSeparator, CRLF, CR, or LF with newEOL. Note that CRLF is replaced by a single newEOL. + unsigned newEOLLen; + unichar newEOLStackBuf[2]; + unichar *newEOLBuf; + BOOL freeNewEOLBuf = NO; + + unsigned length = [str length]; + unsigned curPos = 0; + unsigned start, end, contentsEnd; + + + newEOLLen = [newEOL length]; + if (newEOLLen > 2) { + newEOLBuf = NSZoneMalloc(NULL, sizeof(unichar) * newEOLLen); + freeNewEOLBuf = YES; + } else { + newEOLBuf = newEOLStackBuf; + } + [newEOL getCharacters:newEOLBuf]; + + while (curPos < length) { + [str getLineStart:&start end:&end contentsEnd:&contentsEnd forRange:NSMakeRange(curPos, 1)]; + if (contentsEnd < end) { + int changeInLength = newEOLLen - (end - contentsEnd); + BOOL alreadyNewEOL = YES; + if (changeInLength == 0) { + unsigned i; + for (i=0; i 0) ? [[self objectAtIndex:0] substringWithRange:NSMakeRange(0, charIndex)] : @""); +} + +@end diff --git a/TextEdit.xcodeproj/project.pbxproj b/TextEdit.xcodeproj/project.pbxproj index 0a8174a..e56fae7 100644 --- a/TextEdit.xcodeproj/project.pbxproj +++ b/TextEdit.xcodeproj/project.pbxproj @@ -60,6 +60,10 @@ 41FA793A0B95E61A00FA84AA /* PrintPanelAccessoryController.h in Headers */ = {isa = PBXBuildFile; fileRef = 41FA79380B95E61A00FA84AA /* PrintPanelAccessoryController.h */; }; 41FA793B0B95E61A00FA84AA /* PrintPanelAccessoryController.m in Sources */ = {isa = PBXBuildFile; fileRef = 41FA79390B95E61A00FA84AA /* PrintPanelAccessoryController.m */; }; 41FA79A10B95F0F300FA84AA /* PrintPanelAccessory.nib in Resources */ = {isa = PBXBuildFile; fileRef = 41FA799F0B95F0F300FA84AA /* PrintPanelAccessory.nib */; }; + B28C03101679CF1F00CD7C38 /* NSTextView_TETextExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = B28C030E1679CF1F00CD7C38 /* NSTextView_TETextExtras.h */; }; + B28C03111679CF1F00CD7C38 /* NSTextView_TETextExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = B28C030F1679CF1F00CD7C38 /* NSTextView_TETextExtras.m */; }; + B28C03151679D3FC00CD7C38 /* TEFoundationExtras.h in Headers */ = {isa = PBXBuildFile; fileRef = B28C03131679D3FC00CD7C38 /* TEFoundationExtras.h */; }; + B28C03161679D3FC00CD7C38 /* TEFoundationExtras.m in Sources */ = {isa = PBXBuildFile; fileRef = B28C03141679D3FC00CD7C38 /* TEFoundationExtras.m */; }; B2F74FD4166B8C450000740A /* TETextUtils.h in Headers */ = {isa = PBXBuildFile; fileRef = B2F74FD0166B8C450000740A /* TETextUtils.h */; }; B2F74FD5166B8C450000740A /* TETextUtils.m in Sources */ = {isa = PBXBuildFile; fileRef = B2F74FD1166B8C450000740A /* TETextUtils.m */; }; B2F74FD6166B8C450000740A /* TETextWatcher.h in Headers */ = {isa = PBXBuildFile; fileRef = B2F74FD2166B8C450000740A /* TETextWatcher.h */; }; @@ -129,6 +133,10 @@ 92A68B0A02972957007F9DE6 /* EncodingManager.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = EncodingManager.h; sourceTree = ""; }; 92A68B0B02972957007F9DE6 /* EncodingManager.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = EncodingManager.m; sourceTree = ""; }; 92A68B1802972AB9007F9DE6 /* English */ = {isa = PBXFileReference; lastKnownFileType = wrapper.nib; name = English; path = English.lproj/SelectEncodingsPanel.nib; sourceTree = ""; }; + B28C030E1679CF1F00CD7C38 /* NSTextView_TETextExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = NSTextView_TETextExtras.h; sourceTree = ""; }; + B28C030F1679CF1F00CD7C38 /* NSTextView_TETextExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = NSTextView_TETextExtras.m; sourceTree = ""; }; + B28C03131679D3FC00CD7C38 /* TEFoundationExtras.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TEFoundationExtras.h; sourceTree = ""; }; + B28C03141679D3FC00CD7C38 /* TEFoundationExtras.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TEFoundationExtras.m; sourceTree = ""; }; B2F74FD0166B8C450000740A /* TETextUtils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TETextUtils.h; sourceTree = ""; }; B2F74FD1166B8C450000740A /* TETextUtils.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TETextUtils.m; sourceTree = ""; }; B2F74FD2166B8C450000740A /* TETextWatcher.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TETextWatcher.h; sourceTree = ""; }; @@ -177,6 +185,8 @@ 07C9E83A13D8C5A9004E932B /* JJTypesetter.h */, 07C9E83B13D8C5A9004E932B /* JJTypesetter.m */, 6FE20936FE93D5F211CA2CEA /* README.rtf */, + B28C030E1679CF1F00CD7C38 /* NSTextView_TETextExtras.h */, + B28C030F1679CF1F00CD7C38 /* NSTextView_TETextExtras.m */, 6FE20903FE93D5F211CA2CEA /* Document.h */, 6FE208FBFE93D5F211CA2CEA /* Document.m */, FB69D01E085E20E300646BBF /* DocumentWindowController.h */, @@ -190,6 +200,8 @@ 413912140BD54AB700760A3D /* DocumentPropertiesPanelController.h */, 413912150BD54AB700760A3D /* DocumentPropertiesPanelController.m */, 6FE20907FE93D5F211CA2CEA /* ScalingScrollView.h */, + B28C03131679D3FC00CD7C38 /* TEFoundationExtras.h */, + B28C03141679D3FC00CD7C38 /* TEFoundationExtras.m */, B2F74FD0166B8C450000740A /* TETextUtils.h */, B2F74FD1166B8C450000740A /* TETextUtils.m */, B2F74FD2166B8C450000740A /* TETextWatcher.h */, @@ -310,6 +322,8 @@ 0744194F150CD92F0073CF14 /* UniversalDetector.h in Headers */, B2F74FD4166B8C450000740A /* TETextUtils.h in Headers */, B2F74FD6166B8C450000740A /* TETextWatcher.h in Headers */, + B28C03101679CF1F00CD7C38 /* NSTextView_TETextExtras.h in Headers */, + B28C03151679D3FC00CD7C38 /* TEFoundationExtras.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -440,6 +454,8 @@ 07C9E83D13D8C5A9004E932B /* JJTypesetter.m in Sources */, B2F74FD5166B8C450000740A /* TETextUtils.m in Sources */, B2F74FD7166B8C450000740A /* TETextWatcher.m in Sources */, + B28C03111679CF1F00CD7C38 /* NSTextView_TETextExtras.m in Sources */, + B28C03161679D3FC00CD7C38 /* TEFoundationExtras.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff --git a/TextEdit.xcodeproj/project.xcworkspace/xcuserdata/daboe01.xcuserdatad/UserInterfaceState.xcuserstate b/TextEdit.xcodeproj/project.xcworkspace/xcuserdata/daboe01.xcuserdatad/UserInterfaceState.xcuserstate index 175a33f1f8504f3a894d33643714da3995153864..6d87378596da8200c90e286a1a00ace610366867 100644 GIT binary patch literal 22779 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 delta 10159 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