title: Subclassing NSTextStorage breaks list editing
body: <p>I have a basic Mac app with a standard <code>NSTextView</code>. I'm trying to implement and use a subclass of <code>NSTextStorage</code>, but even a very basic implementation breaks list editing behavior:</p>
  
  <ol>
  <li>I add a bulleted list with two items</li>
  <li>I copy &amp; paste that list further down into the document</li>
  <li>Pressing Enter in the pasted list breaks formatting for the last list item.</li>
  </ol>
  
  <p>Here's a quick video:</p>
  
  <p><a href="https://i.stack.imgur.com/RljZl.gif" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/RljZl.gif" alt="NSTextStorage list issue"></a></p>
  
  <p>Two issues:</p>
  
  <ol>
  <li>The bullet points of the pasted list use a smaller font size</li>
  <li>Pressing Enter after the second list item breaks the third item</li>
  </ol>
  
  <p>This works fine when I don't replace the text storage.</p>
  
  <p>Here's my code:</p>
  
  <p><strong>ViewController.swift</strong></p>
  
  <pre><code>@IBOutlet var textView:NSTextView!
  
  override func viewDidLoad() {
     [...]
     textView.layoutManager?.replaceTextStorage(TestTextStorage())
  }
  </code></pre>
  
  <p><strong>TestTextStorage.swift</strong></p>
  
  <pre><code>class TestTextStorage: NSTextStorage {
  
      let backingStore = NSMutableAttributedString()
  
      override var string: String {
          return backingStore.string
      }
  
      override func attributes(at location: Int, effectiveRange range: NSRangePointer?) -&gt; [NSAttributedString.Key:Any] {
          return backingStore.attributes(at: location, effectiveRange: range)
      }
  
      override func replaceCharacters(in range: NSRange, with str: String) {
          beginEditing()
          backingStore.replaceCharacters(in: range, with:str)
          edited(.editedCharacters, range: range,
                 changeInLength: (str as NSString).length - range.length)
          endEditing()
      }
  
      override func setAttributes(_ attrs: [NSAttributedString.Key: Any]?, range: NSRange) {
          beginEditing()
          backingStore.setAttributes(attrs, range: range)
          edited(.editedAttributes, range: range, changeInLength: 0)
          endEditing()
      }
  }
  </code></pre>