Git Product home page Git Product logo

sttextview's Introduction

STTextView

Performant macOS TextView with line numbers and much more. (NSTextView replacement)

The goal of this project is to build NSTextView replacement component utilizing TextKit 2 framework. due to many good reasons.

The component is developed to serve Swift Studio needs as a source code editor.

Screenshot 2023-04-24 at 02 03 51

sttextview-demo-small.mp4

TextKit 2 was announced during WWDC 2021 as a TextKit 1 replacement for text layout and whatnot. Apple announced that NSTextView, the view component specialized for text editing, will adopt TextKit 2 and provide support along TextKit 1 bits. As I started to learn more about NSTextView + TextKit2, I realized as of today (Feb 2022), neither NSTextView is fully functional, nor TextKit 2 classes are fully functional. Along the way, I reported several bug reports to Apple requested DTS (support tickets). Eventually, I've got blocked by specific bugs that pushed me to start this project.

✨ Features

  • macOS text system integration
  • Performant Text editing
  • Line numbers in a ruler view
  • Ruler Markers support
  • Customization of colors and fonts
  • Toggle line wrapping on and off
  • Adjust height of lines
  • Highlight/Select ranges in the text view
  • Multi-cursor editing
  • Search/Replace the text
  • Customizable Completion support
  • Smooth scrolling of long content
  • Anchored annotations
  • LTR (Left To Right) / RTL (Right To Left) layout
  • Undo/Redo

🗓️ Roadmap

STTextView is already well suited as a text editor component, however it still need improvements before release v1.0

Suggest or vote for new features: Feature Requests

Known issues

  • undo/redo while typing need fixes
  • no text dragging

🚀 Getting Started

STTextView is distributed using the Swift Package Manager. Install it in a project by adding it as a dependency in your Package.swift manifest or through “Package Dependencies” in Xcode project settings

let package = Package(
    dependencies: [
        .package(url: "https://github.com/krzyzanowskim/STTextView", from: "0.4.0")
    ]
)

Usage

SwiftUI

The TextView is a SwiftUI view that wraps the STTextView.

import STTextViewUI

struct ContentView: View {

    @State private var text = "Hello World!"

    var body: some View {
        TextView(
            text: $text,
            font: NSFont.monospacedSystemFont(ofSize: 0, weight: .regular),
            options: [.wrapLines, .highlightSelectedLine]
        )
    }
}

Create a TextView

The STTextView is a subclass of NSView and as such can be initialized like any other view. It has an API that is similar to the one of NSTextView.

import STTextView

let textView = STTextView()
view.addSubView(textView)
let textView = STTextView()
let scrollView = NSScrollView()
scrollView.documentView = textView
let scrollView = STTextView.scrollableTextView()
let textView = scrollView.documentView as! STTextView

Customize

The text view can be customized in a variety of ways.

let paragraph = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle
// Set the line-height to 110%
paragraph.lineHeightMultiple = 1.1
paragraph.defaultTabInterval = 28

// Default Paragraph style
textView.typingAttributes[.paragraphStyle] = paragraph

// Set default font
textView.font = NSFont.monospacedSystemFont(ofSize: 14, weight: .regular)

// Set default text color
textView.textColor = .textColor

// Set text value
textView.string = "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Aenean ornare lobortis sem a vulputate."
textView.addAttributes([.foregroundColor: NSColor.red], range: NSRange(location: 10, length: 5))

// Wrap lines to editor width
textView.widthTracksTextView = true

// Highlight the selected line.
textView.highlightSelectedLine = true

Add line numbers using specialized STLineNumberRulerView (specialized subclass of NSRulerView)

let textView = STTextView()
let scrollView = NSScrollView()
scrollView.documentView = textView

// Line numbers
let rulerView = STLineNumberRulerView(textView: textView)
// Configure the ruler view
rulerView.highlightSelectedLine = true
// Set text color of the selected line number
rulerView.highlightLineNumberColor = .textColor
// Allows to set markers.
// rulerView.allowsMarkers = true

// Add to NSScrollView containing STTextView
scrollView.verticalRulerView = rulerView
scrollView.rulersVisible = true

Enable an optional search-and-replace find interface inside a view, usually a scroll view.

textView.textFinder.isIncrementalSearchingEnabled = true
textView.textFinder.incrementalSearchingShouldDimContentView = true

🐛 TextKit 2 Bug Reports List

List of TextKit 2 issues and bugs related to NSTextView and the TextKit framework I reported to Apple so far:

  • FB9856587: TextKit2 unexpected additional line fragment for last line
  • FB9925766: NSTextSelectionNavigation.deletionRanges only works at the end of the word
  • FB9925647: NSTextLayoutManager.replaceContents(in range: with attributedString:) is documented but is not part of the public API
  • FB9907261: NSTextElementProvider.replaceContents(in:with:) does not replace content as documented
  • FB9692714: Rendering attributes does not draw properly
  • FB9886911: NSTextView can't properly layout and display long lines (this one is nasty since it causes the view "jump" whenever text attribute updates)
  • FB9713415: NSTextView drawInsertionPoint(in:color:turnedOn) is never called
  • FB9971054: NSLayoutManager.enumerateCaretOffsetsInLineFragment ignores starting location
  • FB9971054: NSTextView assert on selection when setup with TextKit2
  • FB9743449, FB10019859: NSTextContentStorage.textElements(for:) returns no element, while enumerateTextElements does return elements
  • FB11898356: textSelections(interactingAt:inContainerAt:anchors:modifiers:selecting:bounds:) produces wrong selections for certain locations

... I'm aware that the list of issues is not complete. I managed to workaround most of the problems in STTextView.

Why ST?

(ST prefix stands for "Swift sTudio" because SS is not good prefix since 1939)

Suggestions or Feedback

Start a new discussion topic or a pull request.

I'd love to hear from you! Get in touch via twitter @krzyzanowskim, mastodon @[email protected].

License

Open Source license

If you are creating an open source application under a license compatible with the GNU GPL license v3, you may use STTextView under the terms of the GPLv3.

Commercial license

Get one starting from €5.

If you want to use STTextView to develop non open sourced product, and applications, the Commercial license is the appropriate license. With this option, your source code is kept proprietary. Which means, you won't have to change your whole application source code to an open source license. Purchase a STTextView Commercial License

sttextview's People

Contributors

krzyzanowskim avatar lukepistrol avatar eliulm avatar a732322918 avatar

Forkers

web-logs2

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.