diff --git a/src/CompositorView.swift b/src/CompositorView.swift index d2cec3b..f00d623 100644 --- a/src/CompositorView.swift +++ b/src/CompositorView.swift @@ -1299,62 +1299,54 @@ struct CompositorRepresentable: NSViewRepresentable { } } - // Collapse source lines and create gaps via paragraph spacing isUpdatingTables = true let tinyFont = NSFont.systemFont(ofSize: 0.1) + let collapsedPara = NSMutableParagraphStyle() + collapsedPara.minimumLineHeight = 0.1 + collapsedPara.maximumLineHeight = 0.1 + collapsedPara.lineSpacing = 0 + collapsedPara.paragraphSpacing = 0 + collapsedPara.paragraphSpacingBefore = 0 + ts.beginEditing() for (range, height) in blockSpacings { - // Make source text invisible: tiny font, zero foreground alpha ts.addAttribute(.font, value: tinyFont, range: range) ts.addAttribute(.foregroundColor, value: NSColor.clear, range: range) + ts.addAttribute(.paragraphStyle, value: collapsedPara.copy() as! NSParagraphStyle, range: range) - // Collapse line heights and add spacing for the block view - let para = NSMutableParagraphStyle() - para.minimumLineHeight = 0.1 - para.maximumLineHeight = 0.1 - para.lineSpacing = 0 - para.paragraphSpacing = 0 - para.paragraphSpacingBefore = 0 - ts.addAttribute(.paragraphStyle, value: para, range: range) - - // On the last line, add paragraph spacing equal to block height let lastLineRange = text.lineRange(for: NSRange(location: max(0, NSMaxRange(range) - 1), length: 0)) - let lastPara = NSMutableParagraphStyle() - lastPara.minimumLineHeight = 0.1 - lastPara.maximumLineHeight = 0.1 - lastPara.lineSpacing = 0 - lastPara.paragraphSpacing = height - lastPara.paragraphSpacingBefore = 0 - ts.addAttribute(.paragraphStyle, value: lastPara, range: lastLineRange) + let spacerPara = collapsedPara.mutableCopy() as! NSMutableParagraphStyle + spacerPara.paragraphSpacing = height + ts.addAttribute(.paragraphStyle, value: spacerPara, range: lastLineRange) } ts.endEditing() isUpdatingTables = false lm.ensureLayout(for: tc) - // Position blocks at the origin of their collapsed source text + // Position blocks using first-glyph origin of collapsed source text var tableIdx = 0 var hrIdx = 0 + let x = origin.x + 4 for block in lm.blockRanges { let glyphRange = lm.glyphRange(forCharacterRange: block.range, actualCharacterRange: nil) - let rect = lm.boundingRect(forGlyphRange: glyphRange, in: tc) - let x = origin.x + 4 + guard glyphRange.length > 0 else { continue } + let lineRect = lm.lineFragmentRect(forGlyphAt: glyphRange.location, effectiveRange: nil) + let blockY = lineRect.origin.y + origin.y switch block.kind { case .tableBlock: guard tableIdx < tableBlocks.count else { continue } let tb = tableBlocks[tableIdx] tableIdx += 1 - let tableW = tb.view.frame.width - tb.view.frame = NSRect(x: x, y: rect.origin.y + origin.y, width: tableW, height: tb.blockHeight) + tb.view.frame = NSRect(x: x, y: blockY, width: tb.view.frame.width, height: tb.blockHeight) tv.addSubview(tb.view) case .horizontalRule: guard hrIdx < hrBlocks.count else { continue } let hb = hrBlocks[hrIdx] hrIdx += 1 - let w = tc.containerSize.width - 8 - hb.view.frame = NSRect(x: x, y: rect.origin.y + origin.y, width: w, height: hb.blockHeight) + hb.view.frame = NSRect(x: x, y: blockY, width: tc.containerSize.width - 8, height: hb.blockHeight) tv.addSubview(hb.view) default: @@ -1373,32 +1365,6 @@ struct CompositorRepresentable: NSViewRepresentable { ts.beginEditing() ts.replaceCharacters(in: sourceRange, with: newMarkdown) applySyntaxHighlighting(to: ts, format: parent.fileFormat) - - // Collapse new source text and set paragraph spacing for updated table height - let newRange = NSRange(location: sourceRange.location, length: (newMarkdown as NSString).length) - let blockHeight: CGFloat = 28 + CGFloat(table.rows.count) * 26 + 2 - let tinyFont = NSFont.systemFont(ofSize: 0.1) - ts.addAttribute(.font, value: tinyFont, range: newRange) - ts.addAttribute(.foregroundColor, value: NSColor.clear, range: newRange) - - let collapsePara = NSMutableParagraphStyle() - collapsePara.minimumLineHeight = 0.1 - collapsePara.maximumLineHeight = 0.1 - collapsePara.lineSpacing = 0 - collapsePara.paragraphSpacing = 0 - collapsePara.paragraphSpacingBefore = 0 - ts.addAttribute(.paragraphStyle, value: collapsePara, range: newRange) - - let text = ts.string as NSString - let lastLineRange = text.lineRange(for: NSRange(location: max(0, NSMaxRange(newRange) - 1), length: 0)) - let lastPara = NSMutableParagraphStyle() - lastPara.minimumLineHeight = 0.1 - lastPara.maximumLineHeight = 0.1 - lastPara.lineSpacing = 0 - lastPara.paragraphSpacing = blockHeight - lastPara.paragraphSpacingBefore = 0 - ts.addAttribute(.paragraphStyle, value: lastPara, range: lastLineRange) - ts.endEditing() (tv as? LineNumberTextView)?.applyEvalSpacing() tv.selectedRanges = sel