All Downloads are FREE. Search and download functionalities are using the official Maven repository.

jvmMain.com.github.ajalt.clikt.output.Editor.kt Maven / Gradle / Ivy

package com.github.ajalt.clikt.output

import com.github.ajalt.clikt.core.CliktError
import java.io.IOException
import java.util.concurrent.TimeUnit

internal actual class Editor actual constructor(
        private val editorPath: String?,
        private val env: Map,
        private val requireSave: Boolean,
        private val extension: String
) {
    private fun getEditorPath(): String {
        return editorPath ?: inferEditorPath { editor ->
            try {
                val process = ProcessBuilder(getWhichCommand(), editor).start()
                process.waitFor(100, TimeUnit.MILLISECONDS) && process.exitValue() == 0
            } catch (err: Exception) {
                when (err) {
                    is IOException, is SecurityException, is InterruptedException,
                    is IllegalThreadStateException -> false
                    else -> throw CliktError("Error staring editor", err)
                }
            }
        }
    }


    private fun getEditorCommand(): Array {
        return getEditorPath().trim().split(" ").toTypedArray()
    }

    private fun editFileWithEditor(editorCmd: Array, filename: String) {
        try {
            val process = ProcessBuilder(*editorCmd, filename).apply {
                environment() += env
                inheritIO()
            }.start()
            val exitCode = process.waitFor()
            if (exitCode != 0) throw CliktError("${editorCmd[0]}: Editing failed!")
        } catch (err: Exception) {
            when (err) {
                is CliktError -> throw err
                else -> throw CliktError("Error staring editor", err)
            }
        }
    }

    actual fun editFile(filename: String) {
        editFileWithEditor(getEditorCommand(), filename)
    }

    actual fun edit(text: String): String? {
        val editorCmd = getEditorCommand()
        val textToEdit = normalizeEditorText(editorCmd[0], text)
        val file = createTempFile(suffix = extension)
        try {
            file.writeText(textToEdit)
            val ts = file.lastModified()
            editFileWithEditor(editorCmd, file.canonicalPath)

            if (requireSave && file.lastModified() == ts) {
                return null
            }

            return file.readText().replace("\r\n", "\n")
        } catch (err: Exception) {
            throw CliktError("Error staring editor", err)
        } finally {
            file.delete()
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy