
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