diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.pbxproj b/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.pbxproj new file mode 100644 index 00000000..97a0dffc --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.pbxproj @@ -0,0 +1,408 @@ +// !$*UTF8*$! +{ + archiveVersion = 1; + classes = { + }; + objectVersion = 77; + objects = { + +/* Begin PBXBuildFile section */ + 6C2265DF2D306AB7008710D7 /* CodeEditTextView in Frameworks */ = {isa = PBXBuildFile; productRef = 6C2265DE2D306AB7008710D7 /* CodeEditTextView */; }; + 6C2265E42D306B90008710D7 /* SwiftUITextView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2265E32D306B90008710D7 /* SwiftUITextView.swift */; }; + 6C2265E62D306D37008710D7 /* TextViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6C2265E52D306D37008710D7 /* TextViewController.swift */; }; + 6CCDA29B2D306A25007CD84A /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 6CCDA2942D306A25007CD84A /* Assets.xcassets */; }; + 6CCDA29D2D306A25007CD84A /* CodeEditTextViewExampleApp.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDA2952D306A25007CD84A /* CodeEditTextViewExampleApp.swift */; }; + 6CCDA29E2D306A25007CD84A /* CodeEditTextViewExampleDocument.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDA2962D306A25007CD84A /* CodeEditTextViewExampleDocument.swift */; }; + 6CCDA29F2D306A25007CD84A /* ContentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 6CCDA2972D306A25007CD84A /* ContentView.swift */; }; +/* End PBXBuildFile section */ + +/* Begin PBXFileReference section */ + 6C2265E12D306B58008710D7 /* CodeEditTextViewExample.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = CodeEditTextViewExample.entitlements; sourceTree = ""; }; + 6C2265E32D306B90008710D7 /* SwiftUITextView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SwiftUITextView.swift; sourceTree = ""; }; + 6C2265E52D306D37008710D7 /* TextViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TextViewController.swift; sourceTree = ""; }; + 6CCDA27D2D306A1B007CD84A /* CodeEditTextViewExample.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = CodeEditTextViewExample.app; sourceTree = BUILT_PRODUCTS_DIR; }; + 6CCDA2942D306A25007CD84A /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; + 6CCDA2952D306A25007CD84A /* CodeEditTextViewExampleApp.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeEditTextViewExampleApp.swift; sourceTree = ""; }; + 6CCDA2962D306A25007CD84A /* CodeEditTextViewExampleDocument.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CodeEditTextViewExampleDocument.swift; sourceTree = ""; }; + 6CCDA2972D306A25007CD84A /* ContentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ContentView.swift; sourceTree = ""; }; + 6CCDA2982D306A25007CD84A /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; + 6CCDA2A12D306A5B007CD84A /* CodeEditTextView */ = {isa = PBXFileReference; lastKnownFileType = wrapper; name = CodeEditTextView; path = ../..; sourceTree = ""; }; +/* End PBXFileReference section */ + +/* Begin PBXFrameworksBuildPhase section */ + 6CCDA27A2D306A1B007CD84A /* Frameworks */ = { + isa = PBXFrameworksBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C2265DF2D306AB7008710D7 /* CodeEditTextView in Frameworks */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXFrameworksBuildPhase section */ + +/* Begin PBXGroup section */ + 6C2265E02D306AEB008710D7 /* Documents */ = { + isa = PBXGroup; + children = ( + 6CCDA2962D306A25007CD84A /* CodeEditTextViewExampleDocument.swift */, + ); + path = Documents; + sourceTree = ""; + }; + 6C2265E22D306B69008710D7 /* Views */ = { + isa = PBXGroup; + children = ( + 6CCDA2972D306A25007CD84A /* ContentView.swift */, + 6C2265E32D306B90008710D7 /* SwiftUITextView.swift */, + 6C2265E52D306D37008710D7 /* TextViewController.swift */, + ); + path = Views; + sourceTree = ""; + }; + 6CCDA2742D306A1B007CD84A = { + isa = PBXGroup; + children = ( + 6CCDA2A12D306A5B007CD84A /* CodeEditTextView */, + 6CCDA2992D306A25007CD84A /* CodeEditTextViewExample */, + 6CCDA2A02D306A5B007CD84A /* Frameworks */, + 6CCDA27E2D306A1B007CD84A /* Products */, + ); + sourceTree = ""; + }; + 6CCDA27E2D306A1B007CD84A /* Products */ = { + isa = PBXGroup; + children = ( + 6CCDA27D2D306A1B007CD84A /* CodeEditTextViewExample.app */, + ); + name = Products; + sourceTree = ""; + }; + 6CCDA2992D306A25007CD84A /* CodeEditTextViewExample */ = { + isa = PBXGroup; + children = ( + 6CCDA2952D306A25007CD84A /* CodeEditTextViewExampleApp.swift */, + 6C2265E02D306AEB008710D7 /* Documents */, + 6C2265E22D306B69008710D7 /* Views */, + 6CCDA2942D306A25007CD84A /* Assets.xcassets */, + 6CCDA2982D306A25007CD84A /* Info.plist */, + 6C2265E12D306B58008710D7 /* CodeEditTextViewExample.entitlements */, + ); + path = CodeEditTextViewExample; + sourceTree = ""; + }; + 6CCDA2A02D306A5B007CD84A /* Frameworks */ = { + isa = PBXGroup; + children = ( + ); + name = Frameworks; + sourceTree = ""; + }; +/* End PBXGroup section */ + +/* Begin PBXNativeTarget section */ + 6CCDA27C2D306A1B007CD84A /* CodeEditTextViewExample */ = { + isa = PBXNativeTarget; + buildConfigurationList = 6CCDA28D2D306A1C007CD84A /* Build configuration list for PBXNativeTarget "CodeEditTextViewExample" */; + buildPhases = ( + 6CCDA2792D306A1B007CD84A /* Sources */, + 6CCDA27A2D306A1B007CD84A /* Frameworks */, + 6CCDA27B2D306A1B007CD84A /* Resources */, + ); + buildRules = ( + ); + dependencies = ( + ); + name = CodeEditTextViewExample; + packageProductDependencies = ( + 6C2265DE2D306AB7008710D7 /* CodeEditTextView */, + ); + productName = CodeEditTextViewExample; + productReference = 6CCDA27D2D306A1B007CD84A /* CodeEditTextViewExample.app */; + productType = "com.apple.product-type.application"; + }; +/* End PBXNativeTarget section */ + +/* Begin PBXProject section */ + 6CCDA2752D306A1B007CD84A /* Project object */ = { + isa = PBXProject; + attributes = { + BuildIndependentTargetsInParallel = 1; + LastSwiftUpdateCheck = 1620; + LastUpgradeCheck = 1620; + TargetAttributes = { + 6CCDA27C2D306A1B007CD84A = { + CreatedOnToolsVersion = 16.2; + }; + }; + }; + buildConfigurationList = 6CCDA2782D306A1B007CD84A /* Build configuration list for PBXProject "CodeEditTextViewExample" */; + developmentRegion = en; + hasScannedForEncodings = 0; + knownRegions = ( + en, + Base, + ); + mainGroup = 6CCDA2742D306A1B007CD84A; + minimizedProjectReferenceProxies = 1; + preferredProjectObjectVersion = 77; + productRefGroup = 6CCDA27E2D306A1B007CD84A /* Products */; + projectDirPath = ""; + projectRoot = ""; + targets = ( + 6CCDA27C2D306A1B007CD84A /* CodeEditTextViewExample */, + ); + }; +/* End PBXProject section */ + +/* Begin PBXResourcesBuildPhase section */ + 6CCDA27B2D306A1B007CD84A /* Resources */ = { + isa = PBXResourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6CCDA29B2D306A25007CD84A /* Assets.xcassets in Resources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXResourcesBuildPhase section */ + +/* Begin PBXSourcesBuildPhase section */ + 6CCDA2792D306A1B007CD84A /* Sources */ = { + isa = PBXSourcesBuildPhase; + buildActionMask = 2147483647; + files = ( + 6C2265E62D306D37008710D7 /* TextViewController.swift in Sources */, + 6CCDA29D2D306A25007CD84A /* CodeEditTextViewExampleApp.swift in Sources */, + 6CCDA29E2D306A25007CD84A /* CodeEditTextViewExampleDocument.swift in Sources */, + 6CCDA29F2D306A25007CD84A /* ContentView.swift in Sources */, + 6C2265E42D306B90008710D7 /* SwiftUITextView.swift in Sources */, + ); + runOnlyForDeploymentPostprocessing = 0; + }; +/* End PBXSourcesBuildPhase section */ + +/* Begin XCBuildConfiguration section */ + 6CCDA28E2D306A1C007CD84A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = CodeEditTextViewExample/CodeEditTextViewExample.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"CodeEditTextViewExample/Preview Content\""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = CodeEditTextViewExample/Info.plist; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportsDocumentBrowser = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 13; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditTextViewExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = NO; + SUPPORTED_PLATFORMS = macosx; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Debug; + }; + 6CCDA28F2D306A1C007CD84A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; + ASSETCATALOG_COMPILER_GLOBAL_ACCENT_COLOR_NAME = AccentColor; + CODE_SIGN_ENTITLEMENTS = CodeEditTextViewExample/CodeEditTextViewExample.entitlements; + CODE_SIGN_STYLE = Automatic; + CURRENT_PROJECT_VERSION = 1; + DEVELOPMENT_ASSET_PATHS = "\"CodeEditTextViewExample/Preview Content\""; + DEVELOPMENT_TEAM = ""; + ENABLE_PREVIEWS = YES; + GENERATE_INFOPLIST_FILE = YES; + INFOPLIST_FILE = CodeEditTextViewExample/Info.plist; + INFOPLIST_KEY_UIApplicationSceneManifest_Generation = YES; + INFOPLIST_KEY_UIApplicationSupportsIndirectInputEvents = YES; + INFOPLIST_KEY_UILaunchScreen_Generation = YES; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPad = "UIInterfaceOrientationPortrait UIInterfaceOrientationPortraitUpsideDown UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportedInterfaceOrientations_iPhone = "UIInterfaceOrientationPortrait UIInterfaceOrientationLandscapeLeft UIInterfaceOrientationLandscapeRight"; + INFOPLIST_KEY_UISupportsDocumentBrowser = YES; + LD_RUNPATH_SEARCH_PATHS = ( + "$(inherited)", + "@executable_path/Frameworks", + ); + MACOSX_DEPLOYMENT_TARGET = 13; + MARKETING_VERSION = 1.0; + PRODUCT_BUNDLE_IDENTIFIER = app.codeedit.CodeEditTextViewExample; + PRODUCT_NAME = "$(TARGET_NAME)"; + REGISTER_APP_GROUPS = NO; + SUPPORTED_PLATFORMS = macosx; + SUPPORTS_MACCATALYST = NO; + SUPPORTS_MAC_DESIGNED_FOR_IPHONE_IPAD = NO; + SUPPORTS_XR_DESIGNED_FOR_IPHONE_IPAD = NO; + SWIFT_EMIT_LOC_STRINGS = YES; + SWIFT_VERSION = 5.0; + }; + name = Release; + }; + 6CCDA2902D306A1C007CD84A /* Debug */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = dwarf; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_TESTABILITY = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_DYNAMIC_NO_PIC = NO; + GCC_NO_COMMON_BLOCKS = YES; + GCC_OPTIMIZATION_LEVEL = 0; + GCC_PREPROCESSOR_DEFINITIONS = ( + "DEBUG=1", + "$(inherited)", + ); + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = INCLUDE_SOURCE; + MTL_FAST_MATH = YES; + ONLY_ACTIVE_ARCH = YES; + SDKROOT = iphoneos; + SWIFT_ACTIVE_COMPILATION_CONDITIONS = "DEBUG $(inherited)"; + SWIFT_OPTIMIZATION_LEVEL = "-Onone"; + }; + name = Debug; + }; + 6CCDA2912D306A1C007CD84A /* Release */ = { + isa = XCBuildConfiguration; + buildSettings = { + ALWAYS_SEARCH_USER_PATHS = NO; + ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES; + CLANG_ANALYZER_NONNULL = YES; + CLANG_ANALYZER_NUMBER_OBJECT_CONVERSION = YES_AGGRESSIVE; + CLANG_CXX_LANGUAGE_STANDARD = "gnu++20"; + CLANG_ENABLE_MODULES = YES; + CLANG_ENABLE_OBJC_ARC = YES; + CLANG_ENABLE_OBJC_WEAK = YES; + CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; + CLANG_WARN_BOOL_CONVERSION = YES; + CLANG_WARN_COMMA = YES; + CLANG_WARN_CONSTANT_CONVERSION = YES; + CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; + CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; + CLANG_WARN_DOCUMENTATION_COMMENTS = YES; + CLANG_WARN_EMPTY_BODY = YES; + CLANG_WARN_ENUM_CONVERSION = YES; + CLANG_WARN_INFINITE_RECURSION = YES; + CLANG_WARN_INT_CONVERSION = YES; + CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; + CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; + CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; + CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; + CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = YES; + CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; + CLANG_WARN_STRICT_PROTOTYPES = YES; + CLANG_WARN_SUSPICIOUS_MOVE = YES; + CLANG_WARN_UNGUARDED_AVAILABILITY = YES_AGGRESSIVE; + CLANG_WARN_UNREACHABLE_CODE = YES; + CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; + COPY_PHASE_STRIP = NO; + DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; + ENABLE_NS_ASSERTIONS = NO; + ENABLE_STRICT_OBJC_MSGSEND = YES; + ENABLE_USER_SCRIPT_SANDBOXING = YES; + GCC_C_LANGUAGE_STANDARD = gnu17; + GCC_NO_COMMON_BLOCKS = YES; + GCC_WARN_64_TO_32_BIT_CONVERSION = YES; + GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; + GCC_WARN_UNDECLARED_SELECTOR = YES; + GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; + GCC_WARN_UNUSED_FUNCTION = YES; + GCC_WARN_UNUSED_VARIABLE = YES; + IPHONEOS_DEPLOYMENT_TARGET = 18.2; + LOCALIZATION_PREFERS_STRING_CATALOGS = YES; + MTL_ENABLE_DEBUG_INFO = NO; + MTL_FAST_MATH = YES; + SDKROOT = iphoneos; + SWIFT_COMPILATION_MODE = wholemodule; + VALIDATE_PRODUCT = YES; + }; + name = Release; + }; +/* End XCBuildConfiguration section */ + +/* Begin XCConfigurationList section */ + 6CCDA2782D306A1B007CD84A /* Build configuration list for PBXProject "CodeEditTextViewExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6CCDA2902D306A1C007CD84A /* Debug */, + 6CCDA2912D306A1C007CD84A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; + 6CCDA28D2D306A1C007CD84A /* Build configuration list for PBXNativeTarget "CodeEditTextViewExample" */ = { + isa = XCConfigurationList; + buildConfigurations = ( + 6CCDA28E2D306A1C007CD84A /* Debug */, + 6CCDA28F2D306A1C007CD84A /* Release */, + ); + defaultConfigurationIsVisible = 0; + defaultConfigurationName = Release; + }; +/* End XCConfigurationList section */ + +/* Begin XCSwiftPackageProductDependency section */ + 6C2265DE2D306AB7008710D7 /* CodeEditTextView */ = { + isa = XCSwiftPackageProductDependency; + productName = CodeEditTextView; + }; +/* End XCSwiftPackageProductDependency section */ + }; + rootObject = 6CCDA2752D306A1B007CD84A /* Project object */; +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata new file mode 100644 index 00000000..919434a6 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -0,0 +1,7 @@ + + + + + diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved b/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved new file mode 100644 index 00000000..c39b388a --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved @@ -0,0 +1,41 @@ +{ + "pins" : [ + { + "identity" : "rearrange", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/Rearrange", + "state" : { + "revision" : "5ff7f3363f7a08f77e0d761e38e6add31c2136e1", + "version" : "1.8.1" + } + }, + { + "identity" : "swift-collections", + "kind" : "remoteSourceControl", + "location" : "https://github.com/apple/swift-collections.git", + "state" : { + "revision" : "671108c96644956dddcd89dd59c203dcdb36cec7", + "version" : "1.1.4" + } + }, + { + "identity" : "swiftlintplugin", + "kind" : "remoteSourceControl", + "location" : "https://github.com/lukepistrol/SwiftLintPlugin", + "state" : { + "revision" : "87454f5c9ff4d644086aec2a0df1ffba678e7f3c", + "version" : "0.57.1" + } + }, + { + "identity" : "textstory", + "kind" : "remoteSourceControl", + "location" : "https://github.com/ChimeHQ/TextStory", + "state" : { + "revision" : "8dc9148b46fcf93b08ea9d4ef9bdb5e4f700e008", + "version" : "0.9.0" + } + } + ], + "version" : 2 +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/AccentColor.colorset/Contents.json b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/AccentColor.colorset/Contents.json new file mode 100644 index 00000000..eb878970 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/AccentColor.colorset/Contents.json @@ -0,0 +1,11 @@ +{ + "colors" : [ + { + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/AppIcon.appiconset/Contents.json b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/AppIcon.appiconset/Contents.json new file mode 100644 index 00000000..23058801 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/AppIcon.appiconset/Contents.json @@ -0,0 +1,35 @@ +{ + "images" : [ + { + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "dark" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + }, + { + "appearances" : [ + { + "appearance" : "luminosity", + "value" : "tinted" + } + ], + "idiom" : "universal", + "platform" : "ios", + "size" : "1024x1024" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/Contents.json b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/Contents.json new file mode 100644 index 00000000..73c00596 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Assets.xcassets/Contents.json @@ -0,0 +1,6 @@ +{ + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/CodeEditTextViewExample.entitlements b/Example/CodeEditTextViewExample/CodeEditTextViewExample/CodeEditTextViewExample.entitlements new file mode 100644 index 00000000..19afff14 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/CodeEditTextViewExample.entitlements @@ -0,0 +1,10 @@ + + + + + com.apple.security.app-sandbox + + com.apple.security.files.user-selected.read-write + + + diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/CodeEditTextViewExampleApp.swift b/Example/CodeEditTextViewExample/CodeEditTextViewExample/CodeEditTextViewExampleApp.swift new file mode 100644 index 00000000..682e67bb --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/CodeEditTextViewExampleApp.swift @@ -0,0 +1,17 @@ +// +// CodeEditTextViewExampleApp.swift +// CodeEditTextViewExample +// +// Created by Khan Winter on 1/9/25. +// + +import SwiftUI + +@main +struct CodeEditTextViewExampleApp: App { + var body: some Scene { + DocumentGroup(newDocument: CodeEditTextViewExampleDocument()) { file in + ContentView(document: file.$document) + } + } +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Documents/CodeEditTextViewExampleDocument.swift b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Documents/CodeEditTextViewExampleDocument.swift new file mode 100644 index 00000000..43a1bdcb --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Documents/CodeEditTextViewExampleDocument.swift @@ -0,0 +1,35 @@ +// +// CodeEditTextViewExampleDocument.swift +// CodeEditTextViewExample +// +// Created by Khan Winter on 1/9/25. +// + +import SwiftUI +import UniformTypeIdentifiers + +struct CodeEditTextViewExampleDocument: FileDocument { + var text: String + + init(text: String = "") { + self.text = text + } + + static var readableContentTypes: [UTType] { + [ + .item + ] + } + + init(configuration: ReadConfiguration) throws { + guard let data = configuration.file.regularFileContents else { + throw CocoaError(.fileReadCorruptFile) + } + text = String(decoding: data, as: UTF8.self) + } + + func fileWrapper(configuration: WriteConfiguration) throws -> FileWrapper { + let data = Data(text.utf8) + return .init(regularFileWithContents: data) + } +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Info.plist b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Info.plist new file mode 100644 index 00000000..6951ec92 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Info.plist @@ -0,0 +1,39 @@ + + + + + CFBundleDocumentTypes + + + CFBundleTypeRole + Editor + LSItemContentTypes + + com.example.plain-text + + NSUbiquitousDocumentUserActivityType + $(PRODUCT_BUNDLE_IDENTIFIER).exampledocument + + + UTImportedTypeDeclarations + + + UTTypeConformsTo + + public.plain-text + + UTTypeDescription + Example Text + UTTypeIdentifier + com.example.plain-text + UTTypeTagSpecification + + public.filename-extension + + exampletext + + + + + + diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/ContentView.swift b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/ContentView.swift new file mode 100644 index 00000000..f914a802 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/ContentView.swift @@ -0,0 +1,20 @@ +// +// ContentView.swift +// CodeEditTextViewExample +// +// Created by Khan Winter on 1/9/25. +// + +import SwiftUI + +struct ContentView: View { + @Binding var document: CodeEditTextViewExampleDocument + + var body: some View { + SwiftUITextView(text: $document.text) + } +} + +#Preview { + ContentView(document: .constant(CodeEditTextViewExampleDocument())) +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/SwiftUITextView.swift b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/SwiftUITextView.swift new file mode 100644 index 00000000..8dd341c2 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/SwiftUITextView.swift @@ -0,0 +1,59 @@ +// +// SwiftUITextView.swift +// CodeEditTextViewExample +// +// Created by Khan Winter on 1/9/25. +// + +import SwiftUI +import AppKit +import CodeEditTextView + +struct SwiftUITextView: NSViewControllerRepresentable { + @Binding var text: String + + func makeNSViewController(context: Context) -> TextViewController { + let controller = TextViewController(string: text) + context.coordinator.controller = controller + return controller + } + + func updateNSViewController(_ nsViewController: TextViewController, context: Context) { + // Do nothing, our binding has to be a one-way binding + } + + func makeCoordinator() -> Coordinator { + Coordinator(text: $text) + } + + @MainActor + public class Coordinator: NSObject { + weak var controller: TextViewController? + var text: Binding + + init(text: Binding) { + self.text = text + super.init() + + NotificationCenter.default.addObserver( + self, + selector: #selector(textViewDidChangeText(_:)), + name: TextView.textDidChangeNotification, + object: nil + ) + } + + @objc func textViewDidChangeText(_ notification: Notification) { + guard let textView = notification.object as? TextView, + let controller, + controller.textView === textView else { + return + } + text.wrappedValue = textView.string + } + + deinit { + NotificationCenter.default.removeObserver(self) + } + } +} diff --git a/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/TextViewController.swift b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/TextViewController.swift new file mode 100644 index 00000000..0e568b55 --- /dev/null +++ b/Example/CodeEditTextViewExample/CodeEditTextViewExample/Views/TextViewController.swift @@ -0,0 +1,58 @@ +// +// TextViewController.swift +// CodeEditTextViewExample +// +// Created by Khan Winter on 1/9/25. +// + +import AppKit +import CodeEditTextView + +class TextViewController: NSViewController { + var scrollView: NSScrollView! + var textView: TextView! + + init(string: String) { + textView = TextView(string: string) + super.init(nibName: nil, bundle: nil) + } + + required init?(coder: NSCoder) { + fatalError("init(coder:) has not been implemented") + } + + override func loadView() { + scrollView = NSScrollView() + textView.translatesAutoresizingMaskIntoConstraints = false + + scrollView.translatesAutoresizingMaskIntoConstraints = false + scrollView.documentView = textView + scrollView.contentView.postsFrameChangedNotifications = true + scrollView.contentView.postsBoundsChangedNotifications = true + scrollView.hasVerticalScroller = true + + self.view = scrollView + + NSLayoutConstraint.activate([ + scrollView.leadingAnchor.constraint(equalTo: view.leadingAnchor), + scrollView.trailingAnchor.constraint(equalTo: view.trailingAnchor), + scrollView.topAnchor.constraint(equalTo: view.topAnchor), + scrollView.bottomAnchor.constraint(equalTo: view.bottomAnchor) + ]) + + // Layout on scroll change + NotificationCenter.default.addObserver( + forName: NSView.frameDidChangeNotification, + object: scrollView.contentView, + queue: .main + ) { [weak self] _ in + self?.textView.updatedViewport(self?.scrollView.documentVisibleRect ?? .zero) + } + + textView.updateFrameIfNeeded() + } + + deinit { + NotificationCenter.default.removeObserver(self) + } +}