Skip to content

GtkSourceView

GtkSourceView is an open-source library that provides a text widget for syntax-highlighted code editing and related features like auto-indentation, code folding, and line numbering, making it ideal for text editors and IDEs. This project offers Kotlin/Native bindings for easy integration into GTK applications.

Enabling GtkSourceView

GtkSourceView bindings are not enabled by default and need to be manually added. To do so, move the GtkSourceView entry from ignoredLibraries to libraries in the gtkkn.json file.

Requirements

To generate bindings, install GtkSourceView on your system:

sudo apt install libgtksourceview-5-dev

Example

The following example demonstrates how to create a simple application using GtkSourceView with syntax highlighting for Kotlin code. The app includes options to show or hide line numbers and toggle between using spaces or tabs for indentation.

samples/gtksource/sample/src/nativeMain/kotlin/org/gtkkn/samples/gtksource/sample/Main.kt
fun main() = Application {
    // set up a HeaderBar since adw windows don't have any by default
    val headerBar = HeaderBar().apply {
        title = "gtk-kn GtkSourceView"
    }

    // setup window layout
    val layout = Box(Orientation.VERTICAL, 0)

    val sourceView = View()
    val buffer = Buffer(sourceView.getBuffer().gtkTextBufferPointer.reinterpret())

    val kotlinLanguage = LanguageManager.getDefault().getLanguage("kotlin")

    if (kotlinLanguage != null) {
        buffer.language = kotlinLanguage
    } else {
        log(WARNING) { "Kotlin language not found" }
    }

    buffer.setText(HELLO_WORLD_TEXT)

    sourceView.showLineNumbers = true
    sourceView.insertSpacesInsteadOfTabs = true

    val scrolledWindow = ScrolledWindow().apply {
        vexpand = true
        hexpand = true
        child = sourceView
    }

    val spacesForTabCheckButton = CheckButton.newWithLabel("Spaces for tab").apply {
        active = sourceView.insertSpacesInsteadOfTabs
        connectToggled {
            log { "spacesForTabCheckButton Toggled = $active" }
            sourceView.insertSpacesInsteadOfTabs = active
        }
    }

    val showLineNumberButton = CheckButton.newWithLabel("Show line number").apply {
        active = sourceView.showLineNumbers
        connectToggled {
            log { "showLineNumberButton Toggled = $active" }
            sourceView.showLineNumbers = active
        }
    }

    headerBar.apply {
        packStart(showLineNumberButton)
        packStart(spacesForTabCheckButton)
    }

    // and add your widget to the layout to display it
    layout.apply {
        append(headerBar)
        append(scrolledWindow)
    }
    content = layout
}