{"id":20683193,"url":"https://github.com/chimehq/textviewplus","last_synced_at":"2025-04-22T12:21:17.080Z","repository":{"id":63906880,"uuid":"231910934","full_name":"ChimeHQ/TextViewPlus","owner":"ChimeHQ","description":"Make life better with NSTextView+TextKit 1/2","archived":false,"fork":false,"pushed_at":"2024-03-25T11:14:35.000Z","size":99,"stargazers_count":42,"open_issues_count":1,"forks_count":5,"subscribers_count":5,"default_branch":"main","last_synced_at":"2024-04-25T19:42:30.633Z","etag":null,"topics":["appkit","cocoa","macos","nstextview","swift","textkit","textkit2"],"latest_commit_sha":null,"homepage":"","language":"Swift","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ChimeHQ.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":["mattmassicotte"]}},"created_at":"2020-01-05T12:02:58.000Z","updated_at":"2024-01-24T16:14:10.000Z","dependencies_parsed_at":"2022-11-28T22:45:11.707Z","dependency_job_id":"07938fa4-c9fd-45ac-a251-1cc66c0f6084","html_url":"https://github.com/ChimeHQ/TextViewPlus","commit_stats":{"total_commits":16,"total_committers":1,"mean_commits":16.0,"dds":0.0,"last_synced_commit":"afcf70c518e33217ca04e25a8af66ab9f59c27ce"},"previous_names":[],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FTextViewPlus","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FTextViewPlus/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FTextViewPlus/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ChimeHQ%2FTextViewPlus/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ChimeHQ","download_url":"https://codeload.github.com/ChimeHQ/TextViewPlus/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":250237851,"owners_count":21397403,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appkit","cocoa","macos","nstextview","swift","textkit","textkit2"],"created_at":"2024-11-16T22:15:53.046Z","updated_at":"2025-04-22T12:21:17.051Z","avatar_url":"https://github.com/ChimeHQ.png","language":"Swift","funding_links":["https://github.com/sponsors/mattmassicotte"],"categories":[],"sub_categories":[],"readme":"[![Build Status][build status badge]][build status]\n[![Platforms][platforms badge]][platforms]\n\n# TextViewPlus\n\nThis project aims to make it easier to use `NSTextView`. It was originally built to support TextKit 1. But, now a major goal is to support TextKit 2.\n\n## Integration\n\n```swift\ndependencies: [\n    .package(url: \"https://github.com/ChimeHQ/TextViewPlus\")\n],\ntargets: [\n    .target(\n        name: \"UseCoreFunctionality\",\n        dependencies: [\"TextViewPlus\"]\n    ),\n    .target(\n        name: \"UseBaseTextView\",\n        dependencies: [.product(name: \"BaseTextView\", package: \"TextViewPlus\")]\n    ),\n]\n```\n\n## BaseTextView\n\nThis is an TextKit 2-only `NSTextView` subclass that aims for an absolute minimal amount of changes. Things are allowed only if they are required for correct functionality. It is intended to be a drop-in replacement for `NSTextView`, and should maintain compatibilty with existing subclasses. Behaviors are appropriate for all types of text.\n\n- Disables all support for TextKit 1\n- Workaround for `scrollRangeToVisible` bug (FB13100459)\n- Minimum `textContainerInset` enforcement to address more `scrollRangeToVisible` bugs\n- Additional routing to `NSTextViewDelegate.textView(_:, doCommandBy:) -\u003e Bool`:  `paste`, `pasteAsRichText`, `pasteAsPlainText`\n- Hooks for `onKeyDown`, `onFlagsChanged`, `onMouseDown`\n- Configurable selection notifcation delivery via `continuousSelectionNotifications`\n\n## NSTextView Extensions\n\n### Ranges\n\nHandy methods for computing ranges of text within the view.\n\n```swift\nfunc textRange(for rect: NSRect) -\u003e NSRange\nvar visibleTextRange: NSRange\n```\n\n### Selection\n\nConvenience methods for computing selection ranges/locations.\n\n```swift\nvar selectedTextRanges: [NSRange]\nvar selectedContinuousRange: NSRange?\nvar insertionLocation: Int?\n```\n\n### Style\n\nStyling changes can be very expensive, this method is much faster in certain common cases.\n\n```swift\nfunc updateFont(_ newFont: NSFont, color newColor: NSColor)\n```\n\n### Bounding\n\nComputing bounding rectangles of displayed text.\n\n```swift\nfunc boundingRect(for range: NSRange) -\u003e NSRect?\nfunc boundingRect(forGlyphRange range: NSRange) -\u003e NSRect?\nfunc boundingSelectionRects(forRange range: NSRange) -\u003e [NSRect]\n```\n\n### Attributed Strings\n\nProgrammatic modification of the underlying attributed string in the `NSTextStorage`, with support for delegate callbacks and undo.\n\n```swift\nfunc replaceCharacters(in range: NSRange, with attributedString: NSAttributedString)\n\n// with undo supported\nfunc replaceString(in range: NSRange, with attributedString: NSAttributedString)\n```\n\n### Behavior\n\nChanging `NSTextView` behaviors can be tricky, and often involve complex interactions with the whole system (`NSLayoutManager`, `NSTextContainer`, `NSScrollView`, etc).\n\n```swift\npublic var wrapsTextToHorizontalBounds: Bool\n```\n\n## TextKit 2 Features\n\n### Workarounds\n\nIn versions of macOS before 13, TextKit 2 doesn't correctly apply rendering attributes. You can sub in this `NSTextLayoutFragment` to workaround the issue.\n\n```swift\nextension YourClass: NSTextLayoutManagerDelegate {\n    func textLayoutManager(_ textLayoutManager: NSTextLayoutManager, textLayoutFragmentFor location: NSTextLocation, in textElement: NSTextElement) -\u003e NSTextLayoutFragment {\n        let range = textElement.elementRange\n\n        switch textElement {\n        case let paragraph as NSTextParagraph:\n            return ParagraphRenderingAttributeTextLayoutFragment(textParagraph: paragraph, range: range)\n        default:\n            return NSTextLayoutFragment(textElement: textElement, range: range)\n        }\n    }\n}\n```\n\n## TextKit 1 Features\n\n### `NSLayoutManager` extensions\n\n```swift\nfunc enumerateLineFragments(for range: NSRange, block: (NSRect, NSRange) -\u003e Void)\nfunc enumerateLineFragments(for rect: NSRect, block: (NSRect, NSRange) -\u003e Void)\n```\n\n## Contributing and Collaboration\n\nI'd love to hear from you! Get in touch via an issue or pull request.\n\nI prefer collaboration, and would love to find ways to work together if you have a similar project.\n\nI prefer indentation with tabs for improved accessibility. But, I'd rather you use the system you want and make a PR than hesitate because of whitespace.\n\nBy participating in this project you agree to abide by the [Contributor Code of Conduct](CODE_OF_CONDUCT.md).\n\n[build status]: https://github.com/ChimeHQ/TextViewPlus/actions\n[build status badge]: https://github.com/ChimeHQ/TextViewPlus/workflows/CI/badge.svg\n[platforms]: https://swiftpackageindex.com/ChimeHQ/TextViewPlus\n[platforms badge]: https://img.shields.io/endpoint?url=https%3A%2F%2Fswiftpackageindex.com%2Fapi%2Fpackages%2FChimeHQ%2FTextViewPlus%2Fbadge%3Ftype%3Dplatforms\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchimehq%2Ftextviewplus","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fchimehq%2Ftextviewplus","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fchimehq%2Ftextviewplus/lists"}