Skip to content
Permalink

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also or learn more about diff comparisons.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also . Learn more about diff comparisons here.
base repository: CodeEditApp/CodeEditTextView
Failed to load repositories. Confirm that selected base ref is valid, then try again.
Loading
base: 0.10.1
Choose a base ref
...
head repository: CodeEditApp/CodeEditTextView
Failed to load repositories. Confirm that selected head ref is valid, then try again.
Loading
compare: 0.11.0
Choose a head ref
  • 4 commits
  • 34 files changed
  • 1 contributor

Commits on Apr 21, 2025

  1. Fix Incorrect Copy/Paste Menu Actions (#91)

    ### Description
    
    Fixes a typo where copy/paste menu items were incorrectly mapped to `undo`, causing their actions to trigger an undo instead of the intended action.
    
    ### Related Issues
    
    * closes CodeEditApp/CodeEdit#1996
    
    ### Checklist
    
    - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md)
    - [x] The issues this PR addresses are related to each other
    - [x] My changes generate no new warnings
    - [x] My code builds and runs on my machine
    - [x] My changes are all related to the related issue above
    - [x] I documented my code
    
    ### Screenshots
    
    In the example CETV app:
    
    https://github.com/user-attachments/assets/8f3b3358-fa45-4cc2-8646-6bf28abdf158
    thecoolwinter authored Apr 21, 2025
    Configuration menu
    Copy the full SHA
    2a6e7c7 View commit details
    Browse the repository at this point in the history

Commits on Apr 25, 2025

  1. Share Text Storage Delegates (#92)

    ### Description
    
    Makes the text view share the `MultiStorageDelegate` if it's already installed on the text storage object. This allows for multiple editors to completely share a storage object, receiving update events and sending them to the necessary objects without removing the other text view's objects from the shared delegate.
    
    ### Related Issues
    
    * N/A
    
    ### Checklist
    
    - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md)
    - [x] The issues this PR addresses are related to each other
    - [x] My changes generate no new warnings
    - [x] My code builds and runs on my machine
    - [x] My changes are all related to the related issue above
    - [x] I documented my code
    
    ### Screenshots
    thecoolwinter authored Apr 25, 2025
    Configuration menu
    Copy the full SHA
    e35d655 View commit details
    Browse the repository at this point in the history

Commits on May 9, 2025

  1. Text Attachment Support (#93)

    ### Description
    
    Adds an API for creating "text attachments". Essentially, views that replace ranges of text and act as a single character in typesetting, layout, and selection.
    
    #### Detailed Changes
    
    Text layout consists of two steps:
    
    - Laying out whole lines
    - Typesetting line fragments
    
    The changes in this PR mostly consist of changes to the typesetting step. This step breaks down a line of text into fragments that fit into a constrained width. Text attachments are built by making 'runs' of content in that typesetting step.
    
    > These are intentionally kept separate from the text storage. If these modifications were in the storage object, they'd be shared between editors that share storage objects. Putting these in the layout system means that a user can fold lines in one editor, and view them normally in another.
    
    - Text attachments:
      - **New** `TextAttachment` protocol. A generic type that can draw it's contents in a line.
      - **New** `AnyTextAttachment` helps type-erase `any TextAttachment` and has a `range` for CETV to use. Very similar to `AnyHashable` or `AnyView`.
      - **New** `TextAttachmentManager` manages an ordered array of attachments, and manages hiding and showing text lines as needed, as well as invalidating layout when modifications happen.
    - `TextLayoutManager` changes:
      - Added a new `determineVisiblePosition` method. This method takes in a line position and returns a new (potentially larger) position by merging lines covered by attachments. This is the foundational method for merging lines that attachments cover.
      - Removing the existing `Iterator`.
      - Added two iterators, `YPositionIterator` and `RangeIterator` that iterate over a range of y positions and text offsets, respectively. These iterators are now used by the `layoutLines` method to merge lines that have attachments and not layout hidden lines.
    - Typesetting:
      - `Typesetter.swift` is marked as new, but that's because it's drastically changed.
        - `Typesetter` still performs typesetting on a text line, but it now takes into account attachments. It breaks the line into content runs, then calculates line fragments using those runs and a constrained width.
      - `TypesetContext` and `LineFragmentTypesetContext` represent partial parsing states while typesetting. They're both used once during typesetting and then discarded. Keeping them in their own structs makes `Typesetter` much more readable.
      - `CTLineTypesetData` was previously represented by a tuple, but a struct makes things clearer. It represents layout information received from a `CTTypesetter` for a `CTLine`.
      - Line break suggestion methods moved to a `CTTypesetter` extension. Each method was taking a `typesetter` argument, so moving to an extension makes them more ergonomic.
        - The only change to these methods was a change from passing a `startOffset` to instead pass a `subrange` that the typesetter finds line breaks in.
    - `LineFragment`
      - Line fragments now have to manage a series of content runs that can be either attachments or plain text.
      - Drawing methods have been updated to loop over runs and draw them.
      - Position fetching methods now take into account attachments as well as text positions.
    - Scroll view listeners - *this could have been a different PR but it's a small change, sorry!*.
      -  Fixed up the way the text view found it's enclosing scroll view, and listens to scroll changes.
    
    #### Testing
    
    - Added typesetting tests for attachments.
    - Added layout manager tests.
      - Iteration
      - Invalidation
      - Attachments
    
    ### Related Issues
    
    * CodeEditApp/CodeEditSourceEditor#43
    * CodeEditApp/CodeEditSourceEditor#287
    * CodeEditApp/CodeEdit#1623
    
    ### Checklist
    
    - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md)
    - [x] The issues this PR addresses are related to each other
    - [x] My changes generate no new warnings
    - [x] My code builds and runs on my machine
    - [x] My changes are all related to the related issue above
    - [x] I documented my code
    
    ### Screenshots
    
    > Demo menu item was a testing menu item, it either adds a demo attachment to the selected range, or removes selected attachments (if any are selected). It's not included in this PR.
    
    To test the changes like in the demo video replace `TextView+Menu.swift` with this:
    <details><summary>`TextView+Menu.swift`</summary>
    <p>
    
    ```swift
    //
    //  TextView+Menu.swift
    //  CodeEditTextView
    //
    //  Created by Khan Winter on 8/21/23.
    //
    
    import AppKit
    
    extension TextView {
        override public func menu(for event: NSEvent) -> NSMenu? {
            guard event.type == .rightMouseDown else { return nil }
    
            let menu = NSMenu()
    
            menu.items = [
                NSMenuItem(title: "Cut", action: #selector(cut(_:)), keyEquivalent: "x"),
                NSMenuItem(title: "Copy", action: #selector(copy(_:)), keyEquivalent: "c"),
                NSMenuItem(title: "Paste", action: #selector(paste(_:)), keyEquivalent: "v"),
                NSMenuItem(title: "Attach", action: #selector(toggleAttachmentAtSelection), keyEquivalent: "b")
            ]
    
            return menu
        }
    
        class DemoAttachment: TextAttachment {
            var width: CGFloat = 100
    
            func draw(in context: CGContext, rect: NSRect) {
                context.setFillColor(NSColor.red.cgColor)
                context.fill(rect)
            }
        }
    
        @objc func toggleAttachmentAtSelection() {
            if layoutManager.attachments.get(
                startingIn: selectedRange()
            ).first?.range.location == selectedRange().location {
                layoutManager.attachments.remove(atOffset: selectedRange().location)
            } else {
                layoutManager.attachments.add(DemoAttachment(), for: selectedRange())
            }
        }
    }
    
    ```
    
    </p>
    </details> 
    
    
    https://github.com/user-attachments/assets/b178fe13-d5d2-4e3d-aa55-f913df1d6c4b
    thecoolwinter authored May 9, 2025
    Configuration menu
    Copy the full SHA
    d82b1c0 View commit details
    Browse the repository at this point in the history

Commits on May 27, 2025

  1. Don't Try to Set a Negative Frame Height (#96)

    ### Description
    
    Fixes a potential recursion where CETV tries to set it's frame to a negative number (due to overscroll & scroll inset weirdness). This adds a super simple sanity check to make sure we limit the textview to a `0` frame at minimum.
    
    This hang would occur when no content is present, making the content size an odd number, which also makes scroll views freak out on macOS.
    
    ### Related Issues
    
    * CodeEditApp/CodeEdit#2049
    
    ### Checklist
    
    - [x] I read and understood the [contributing guide](https://github.com/CodeEditApp/CodeEdit/blob/main/CONTRIBUTING.md) as well as the [code of conduct](https://github.com/CodeEditApp/CodeEdit/blob/main/CODE_OF_CONDUCT.md)
    - [x] The issues this PR addresses are related to each other
    - [x] My changes generate no new warnings
    - [x] My code builds and runs on my machine
    - [x] My changes are all related to the related issue above
    - [x] I documented my code
    
    ### Screenshots
    
    N/A, fixes a hang.
    thecoolwinter authored May 27, 2025
    Configuration menu
    Copy the full SHA
    d51f3ad View commit details
    Browse the repository at this point in the history
Loading