Added more plugin files to Pijul

[?]
Mar 27, 2021, 3:54 PM
FNNW5IEAXQ43WKB6QSQB7DFLG3Y3T5FYPXIUX7KQ2URR2GU3QLTAC

Dependencies

Change contents

  • file addition: services (d--r------)
    [2.455]
  • file addition: com.github.jonathanxd.dracon.pijul.Pijul (----------)
    [0.11]
    com.github.jonathanxd.dracon.cmd.PijulCmd
  • file addition: dracon (d--r------)
    [2.2445]
  • file addition: vfs (d--r------)
    [0.107]
  • file addition: PijulVirtualFileStatusProvider.kt (----------)
    [0.114]
    package com.github.jonathanxd.dracon.vfs
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.FileStatus
    import com.intellij.openapi.vcs.impl.FileStatusProvider
    import com.intellij.openapi.vfs.VirtualFile
    class PijulVirtualFileStatusProvider(val project: Project): FileStatusProvider {
    override fun getFileStatus(virtualFile: VirtualFile): FileStatus {
    TODO("Not yet implemented")
    }
    }
  • file addition: DraconVfsUtil.kt (----------)
    [0.114]
    package com.github.jonathanxd.dracon.vfs
    import com.intellij.openapi.vfs.VfsUtil
    import com.intellij.openapi.vfs.VirtualFile
    object DraconVfsUtil {
    fun refreshVfs(roots: List<VirtualFile>) {
    VfsUtil.markDirtyAndRefresh(false, true, false, *roots.toTypedArray());
    }
    }
  • file addition: vcs (d--r------)
    [0.107]
  • file addition: NotificationIds.kt (----------)
    [0.889]
    package com.github.jonathanxd.dracon.vcs
    object NotificationIds {
    const val FAILED_TO_INIT = "pijul.init.failed"
    }
  • file addition: DraconVcsUtil.kt (----------)
    [0.889]
    package com.github.jonathanxd.dracon.vcs
    import com.github.jonathanxd.dracon.vfs.DraconVfsUtil
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.ProjectLevelVcsManager
    import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager
    import com.intellij.openapi.vfs.VirtualFile
    import com.intellij.vcsUtil.VcsUtil
    object DraconVcsUtil {
    fun refreshAfterInit(project: Project, root: VirtualFile) {
    DraconVfsUtil.refreshVfs(listOf(root))
    val manager = ProjectLevelVcsManager.getInstance(project)
    manager.directoryMappings = VcsUtil.addMapping(manager.directoryMappings, root.path, "Pijul")
    VcsDirtyScopeManager.getInstance(project).dirDirtyRecursively(root)
    }
    }
  • file addition: util (d--r------)
    [0.107]
  • file addition: Path.kt (----------)
    [0.1784]
    package com.github.jonathanxd.dracon.util
    import java.nio.file.Files
    import java.nio.file.Path
    fun Path.existsOrNull(): Path? =
    if (Files.exists(this)) this
    else null
    fun Path.isDirectoryOrNull(): Path? =
    if (Files.isDirectory(this)) this
    else null
    fun Path.isRegularFileOrNull(): Path? =
    if (Files.isRegularFile(this)) this
    else null
    fun Path.isExecutableOrNull(): Path? =
    if (Files.isExecutable(this)) this
    else null
  • file addition: Message.kt (----------)
    [0.1784]
    package com.github.jonathanxd.dracon.util
    import com.intellij.openapi.util.text.StringUtil
    import com.intellij.xml.util.XmlStringUtil
    fun String.wrapInHml() =
    XmlStringUtil.wrapInHtml(this)
    fun String.escapeXml() =
    StringUtil.escapeXmlEntities(this)
  • file addition: Flow.kt (----------)
    [0.1784]
    package com.github.jonathanxd.dracon.util
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.flow.asFlow
    import kotlinx.coroutines.flow.flowOn
    import java.io.InputStream
    fun InputStream.linesToFlow() = bufferedReader().lineSequence().asFlow().flowOn(Dispatchers.IO)
  • file addition: roots (d--r------)
    [0.107]
  • file addition: PijulRootChecker.kt (----------)
    [0.2827]
    package com.github.jonathanxd.dracon.roots
    import com.github.jonathanxd.dracon.PijulVcs
    import com.github.jonathanxd.dracon.pijul.Pijul
    import com.intellij.openapi.vcs.VcsKey
    import com.intellij.openapi.vcs.VcsRootChecker
    import java.nio.file.Paths
    class PijulRootChecker : VcsRootChecker() {
    override fun getSupportedVcs(): VcsKey = PijulVcs.KEY
    override fun isRoot(path: String): Boolean =
    Pijul.isPijulRepository(Paths.get(path))
    override fun isVcsDir(dirName: String): Boolean =
    dirName.equals(".pijul", ignoreCase = true)
    }
  • file addition: pijul (d--r------)
    [0.107]
  • file addition: PijulPristine.kt (----------)
    [0.3420]
    package com.github.jonathanxd.dracon.pijul
    /**
    * An interface which provides introspection of [Pijul] `pristine` channels data.
    */
    interface PijulPristine {
    }
  • file addition: PijulOperationResult.kt (----------)
    [0.3420]
    package com.github.jonathanxd.dracon.pijul
    sealed class StatusCode(val code: Int)
    object SuccessStatusCode : StatusCode(0)
    data class NonZeroExitStatusCode(val exitCode: Int, val message: String) : StatusCode(exitCode)
    data class PijulOperationResult<R>(val operation: String,
    val statusCode: StatusCode,
    val result: R?)
  • file addition: PijulExecution.kt (----------)
    [0.3420]
    package com.github.jonathanxd.dracon.pijul
    import kotlinx.coroutines.flow.Flow
    class PijulExecution(
    val regularStream: Flow<String>,
    val errorStream: Flow<String>,
    val status: Flow<Int>
    )
  • file addition: PijulChanges.kt (----------)
    [0.3420]
    package com.github.jonathanxd.dracon.pijul
    /**
    * An interface which provides introspection of [Pijul] `changes` data.
    */
    interface PijulChanges {
    }
  • file addition: Pijul.kt (----------)
    [0.3420]
    package com.github.jonathanxd.dracon.pijul
    import com.github.jonathanxd.dracon.util.existsOrNull
    import com.github.jonathanxd.dracon.util.isDirectoryOrNull
    import com.intellij.openapi.application.ApplicationManager
    import com.intellij.openapi.components.service
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.FilePath
    import com.intellij.openapi.vcs.FileStatus
    import com.intellij.openapi.vfs.LocalFileSystem
    import com.intellij.openapi.vfs.VirtualFile
    import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
    import com.intellij.vcsUtil.VcsUtil
    import java.nio.file.Files
    import java.nio.file.Path
    import java.nio.file.Paths
    import java.util.*
    val PIJUL_DIR = ".pijul"
    val PIJUL_INSTANCE get() = service<Pijul>()
    fun pijul(project: Project): Pijul = project.service()
    /**
    * Base interface for Pijul-IntelliJ communication.
    *
    * This interface provides all methods for communication with [Pijul], as well some basic implementations
    * for operations that does not requires communication with [Pijul] backend.
    *
    * However, some functionalities are not provided through this interface, for example, Pijul changes are stored in binary
    * format in the `.pijul/changes` directory and channels (like branches in git) are stored in `.pijul/pristine` directory,
    * as binary data as well, introspecting this data is done through [PijulChanges] and [PijulPristine] interfaces.
    */
    interface Pijul {
    companion object {
    fun isPijulRepository(root: Path) =
    root.resolve(PIJUL_DIR).existsOrNull()?.isDirectoryOrNull() != null
    }
    fun findPijulDirectory(root: VirtualFile): VirtualFile? {
    var dir: Path? = Paths.get(VcsUtil.getFilePath(root).path)
    while (dir != null) {
    if (isPijulRepository(dir)) {
    return LocalFileSystem.getInstance().findFileByNioFile(dir)
    }
    dir = dir.parent
    }
    return null
    }
    fun isUnderPijul(root: VirtualFile): Boolean = this.findPijulDirectory(root) != null
    @RequiresBackgroundThread
    fun init(project: Project, root: VirtualFile): PijulOperationResult<Unit>
    @RequiresBackgroundThread
    fun add(project: Project, root: VirtualFile, paths: List<FilePath>): PijulOperationResult<Unit>
    @RequiresBackgroundThread
    fun fileStatus(project: Project, file: VirtualFile): PijulOperationResult<FileStatus>
    }
  • file addition: log (d--r------)
    [0.107]
  • file addition: DraconConsoleWriter.kt (----------)
    [0.6847]
    package com.github.jonathanxd.dracon.log
    import com.intellij.execution.ui.ConsoleViewContentType
    import com.intellij.openapi.application.ApplicationManager
    import com.intellij.openapi.components.Service
    import com.intellij.openapi.components.service
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.util.NlsSafe
    import com.intellij.openapi.util.text.StringUtil
    import com.intellij.openapi.vcs.ProjectLevelVcsManager
    fun draconConsoleWriter(project: Project): DraconConsoleWriter =
    project.service()
    @Service
    class DraconConsoleWriter(val project: Project) {
    fun logCommand(@NlsSafe command: String, @NlsSafe args: List<String>, @NlsSafe message: String) {
    this.log("$ $command ${args.joinToString(separator = " ")} > $message", ConsoleViewContentType.NORMAL_OUTPUT)
    }
    fun logCommandError(@NlsSafe command: String, @NlsSafe args: List<String>, @NlsSafe message: String) {
    this.log("$ $command ${args.joinToString(separator = " ")} > $message", ConsoleViewContentType.ERROR_OUTPUT)
    }
    fun log(@NlsSafe message: String) {
    this.log(message, ConsoleViewContentType.NORMAL_OUTPUT)
    }
    fun logError(@NlsSafe message: String) {
    this.log(message, ConsoleViewContentType.ERROR_OUTPUT)
    }
    fun log(@NlsSafe message: String, contentType: ConsoleViewContentType) {
    ProjectLevelVcsManager.getInstance(this.project).addMessageToConsoleWindow(message, contentType)
    }
    }
  • file addition: i18n (d--r------)
    [0.107]
  • file addition: DraconBundle.kt (----------)
    [0.8344]
    package com.github.jonathanxd.dracon.i18n
    import com.github.jonathanxd.dracon.util.escapeXml
    import com.github.jonathanxd.dracon.util.wrapInHml
    import com.intellij.DynamicBundle
    import org.jetbrains.annotations.Nls
    import org.jetbrains.annotations.PropertyKey
    import java.util.function.Supplier
    const val BUNDLE = "messages.DraconBundle"
    object DraconBundle : DynamicBundle(BUNDLE) {
    fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): @Nls String {
    return this.getMessage(key, *params)
    }
    fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any): Supplier<String> {
    return this.getLazyMessage(key, *params)
    }
    object Init {
    val title
    get() = message("init.title")
    val description
    get() = message("init.description")
    val error
    get() = message("init.error")
    fun alreadyUnderPijul(arg: Any) =
    message("init.warning.already.under.pijul", arg)
    fun alreadyUnderPijulForHtml(arg: String) =
    message("init.warning.already.under.pijul", arg.escapeXml()).wrapInHml()
    }
    object Dracon {
    val nameSupplier
    get() = DraconBundle.messagePointer("dracon.vcs.name")
    val mnemonic
    get() = DraconBundle.message("dracon.vcs.name.with.mnemonic")
    val refreshing
    get() = message("dracon.refresh")
    }
    }
  • file addition: executor (d--r------)
    [0.107]
  • file addition: PijulCommitAndPushExecutor.kt (----------)
    [0.9833]
    package com.github.jonathanxd.dracon.executor
    import com.intellij.dvcs.ui.DvcsBundle
    import com.intellij.openapi.util.Key
    import com.intellij.openapi.vcs.changes.CommitContext
    import com.intellij.openapi.vcs.changes.CommitExecutor
    import com.intellij.openapi.vcs.changes.CommitSession
    import com.intellij.vcs.commit.commitProperty
    import org.jetbrains.annotations.Nls
    private val IS_PUSH_AFTER_COMMIT_KEY = Key.create<Boolean>("Pijul.Commit.IsPushAfterCommit")
    internal var CommitContext.isPushAfterCommit: Boolean by commitProperty(IS_PUSH_AFTER_COMMIT_KEY)
    class PijulCommitAndPushExecutor : CommitExecutor {
    @Nls
    override fun getActionText(): String = DvcsBundle.message("action.commit.and.push.text")
    override fun useDefaultAction(): Boolean = false
    override fun getId(): String = ID
    override fun createCommitSession(commitContext: CommitContext): CommitSession {
    commitContext.isPushAfterCommit = true
    return CommitSession.VCS_COMMIT
    }
    companion object {
    internal const val ID = "Pijul.Commit.And.Push.Executor"
    }
    }
  • file addition: cmd (d--r------)
    [0.107]
  • file addition: PijulCmd.kt (----------)
    [0.10957]
    package com.github.jonathanxd.dracon.cmd
    import com.github.jonathanxd.dracon.log.draconConsoleWriter
    import com.github.jonathanxd.dracon.pijul.*
    import com.github.jonathanxd.dracon.util.existsOrNull
    import com.github.jonathanxd.dracon.util.isExecutableOrNull
    import com.github.jonathanxd.dracon.util.isRegularFileOrNull
    import com.github.jonathanxd.dracon.util.linesToFlow
    import com.intellij.openapi.components.Service
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.FilePath
    import com.intellij.openapi.vcs.FileStatus
    import com.intellij.openapi.vfs.VirtualFile
    import com.intellij.util.concurrency.annotations.RequiresBackgroundThread
    import com.intellij.vcsUtil.VcsFileUtil
    import com.intellij.vcsUtil.VcsUtil
    import kotlinx.coroutines.Dispatchers
    import kotlinx.coroutines.delay
    import kotlinx.coroutines.flow.*
    import kotlinx.coroutines.runBlocking
    import java.io.File
    import java.nio.file.Files
    import java.nio.file.Path
    import java.nio.file.Paths
    /**
    * Command-line based implementation of [Pijul] interface.
    *
    * An IPC (Inter Process Communication) version of [Pijul] could be implemented in the future,
    * however, an command-line based is enough for now.
    */
    class PijulCmd(val project: Project) : Pijul {
    @RequiresBackgroundThread
    override fun init(project: Project, root: VirtualFile): PijulOperationResult<Unit> {
    val path = Paths.get(VcsUtil.getFilePath(root).path)
    val execution = this.execPijul(project, path, listOf("init", path.toString()))
    return this.doExecution("init", execution)
    }
    @RequiresBackgroundThread
    override fun add(project: Project, root: VirtualFile, paths: List<FilePath>): PijulOperationResult<Unit> {
    val path = Paths.get(VcsUtil.getFilePath(root).path)
    val results = mutableListOf<PijulOperationResult<Unit>>()
    if (paths.isEmpty()) {
    val execution = this.execPijul(project, path, listOf("add", "-r") + root.path)
    results + this.doExecution("add", execution)
    } else {
    for (pathList in VcsFileUtil.chunkPaths(root, paths)) {
    val execution = this.execPijul(project, path, listOf("add", "-r") + pathList)
    results + this.doExecution("add", execution)
    }
    }
    for (result in results) {
    if (result.statusCode !is SuccessStatusCode)
    return result
    }
    return PijulOperationResult("add", SuccessStatusCode, Unit)
    }
    @RequiresBackgroundThread
    override fun fileStatus(project: Project, file: VirtualFile): PijulOperationResult<FileStatus> {
    }
    fun doExecution(name: String, execution: PijulExecution): PijulOperationResult<Unit> {
    val status = runBlocking(Dispatchers.IO) {
    execution.status.first()
    }
    return if (status == 0) {
    PijulOperationResult(name, SuccessStatusCode, Unit)
    } else {
    val error = runBlocking(Dispatchers.IO) {
    execution.errorStream.toList().joinToString("\n")
    }
    PijulOperationResult(name, NonZeroExitStatusCode(status, error), Unit)
    }
    }
    /**
    * TODO: Support configurable Pijul path.
    *
    * Executes a pijul command and waits for the output status
    */
    @RequiresBackgroundThread
    private fun execPijul(project: Project,
    dir: Path,
    args: List<String>): PijulExecution {
    val process = ProcessBuilder()
    .command(listOf(this.findPijul()) + args)
    .directory(dir.toFile())
    .start()
    val input = process.inputStream
    val error = process.errorStream
    return PijulExecution(
    input.linesToFlow().onEach {
    draconConsoleWriter(project).logCommand("pijul", args, it)
    },
    error.linesToFlow().onEach {
    draconConsoleWriter(project).logCommandError("pijul", args, it)
    },
    flow {
    while (process.isAlive)
    delay(1000L)
    val exit = process.exitValue()
    if (exit == 0) {
    draconConsoleWriter(project).logCommand("pijul", args, "<Exit status> $exit")
    } else {
    draconConsoleWriter(project).logCommandError("pijul", args, "<Exit status> $exit")
    }
    emit(exit)
    }.flowOn(Dispatchers.IO)
    )
    }
    private fun findPijul(): String {
    // Works in Windows, Linux and MacOS when Pijul is installed with cargo.
    val localPijul = this.findCargoPijul()
    // For Homebrew/Linuxbrew installations
    val brewPijul = this.findBrewPijul()
    // For *nix only.
    val usrBinPijul = Paths.get(File.pathSeparator, "usr", "bin", "pijul").asPijulExecutableStringOrNull()
    val usrLocalBinPijul = Paths.get(File.pathSeparator, "usr", "local", "bin", "pijul").asPijulExecutableStringOrNull()
    val binPijul = Paths.get(File.pathSeparator, "bin", "pijul").asPijulExecutableStringOrNull()
    // For Windows only.
    // Windows could download Pijul binaries from https://github.com/boringcactus/pijul-windows-builds/releases/latest
    // However, Dracon plugin could not detect Pijul outside from these directories, for the cases where
    // Pijul is not in these locations, a search through $PATH variable will be made, so if the $PATH is correctly
    // configured to point to Pijul executable, then it will be found, this applies to all OSes.
    val programFiles = Paths.get("C:"+ File.pathSeparator, "Program Files", "pijul", "pijul.exe").asPijulExecutableStringOrNull()
    val programFiles86 = Paths.get("C:"+ File.pathSeparator, "Program Files (x86)", "pijul", "pijul.exe").asPijulExecutableStringOrNull()
    return localPijul
    ?: brewPijul
    ?: usrBinPijul
    ?: usrLocalBinPijul
    ?: binPijul
    ?: programFiles
    ?: programFiles86
    ?: this.findExecutableOnPath("pijul")
    ?: "pijul"
    }
    private fun Path.asPijulExecutableStringOrNull(): String? =
    this.existsOrNull()?.isRegularFileOrNull()?.isExecutableOrNull()?.toAbsolutePath()?.toString()
    private fun findCargoPijul(): String? {
    return System.getProperty("user.dir")?.let {
    Paths.get(it, ".cargo", "bin", "pijul")
    }?.asPijulExecutableStringOrNull()
    }
    private fun findBrewPijul(): String? {
    return System.getenv("HOMEBREW_PREFIX")?.ifBlank { null }?.ifEmpty { null }?.let {
    Paths.get(it, "bin", "pijul")
    }?.asPijulExecutableStringOrNull()
    }
    fun findExecutableOnPath(name: String): String? {
    for (dirname in System.getenv("PATH").split(File.pathSeparator)) {
    val path = Paths.get(dirname, name)
    if (Files.isRegularFile(path) && Files.isExecutable(path)) {
    return path.toAbsolutePath().toString()
    }
    }
    return null
    }
    }
  • file addition: actions (d--r------)
    [0.107]
  • file addition: PijulMenu.kt (----------)
    [0.18106]
    package com.github.jonathanxd.dracon.actions
    import com.github.jonathanxd.dracon.NAME
    import com.github.jonathanxd.dracon.pijulVcs
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.AbstractVcs
    import com.intellij.openapi.vcs.actions.StandardVcsGroup
    class PijulMenu : StandardVcsGroup() {
    override fun getVcs(project: Project): AbstractVcs =
    pijulVcs(project)
    override fun getVcsName(project: Project): String = NAME
    }
  • file addition: PijulInit.kt (----------)
    [0.18106]
    package com.github.jonathanxd.dracon.actions
    import com.github.jonathanxd.dracon.i18n.DraconBundle
    import com.github.jonathanxd.dracon.pijul.NonZeroExitStatusCode
    import com.github.jonathanxd.dracon.pijul.pijul
    import com.github.jonathanxd.dracon.util.wrapInHml
    import com.github.jonathanxd.dracon.vcs.DraconVcsUtil
    import com.github.jonathanxd.dracon.vcs.NotificationIds
    import com.github.jonathanxd.dracon.vfs.DraconVfsUtil
    import com.intellij.openapi.actionSystem.AnActionEvent
    import com.intellij.openapi.actionSystem.CommonDataKeys
    import com.intellij.openapi.fileChooser.FileChooser
    import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
    import com.intellij.openapi.progress.ProgressIndicator
    import com.intellij.openapi.progress.Task
    import com.intellij.openapi.project.DumbAwareAction
    import com.intellij.openapi.project.ProjectManager
    import com.intellij.openapi.ui.Messages
    import com.intellij.openapi.vcs.ProjectLevelVcsManager
    import com.intellij.openapi.vcs.VcsNotifier
    import com.intellij.openapi.vcs.changes.VcsDirtyScopeManager
    import com.intellij.vcsUtil.VcsUtil
    class PijulInit: DumbAwareAction() {
    override fun actionPerformed(e: AnActionEvent) {
    val project = e.getData(CommonDataKeys.PROJECT) ?: ProjectManager.getInstance().defaultProject
    val fcd = FileChooserDescriptorFactory.createSingleFileDescriptor()
    fcd.isShowFileSystemRoots = true
    fcd.title = DraconBundle.Init.title
    fcd.description = DraconBundle.Init.description
    fcd.isHideIgnored = false
    val baseDir = e.getData(CommonDataKeys.VIRTUAL_FILE)?.let { if (it.isDirectory) null else it } ?: project.baseDir
    FileChooser.chooseFile(fcd, project, baseDir) { root ->
    if (pijul(project).isUnderPijul(root)) {
    val dialog = Messages.showYesNoCancelDialog(
    project,
    DraconBundle.Init.alreadyUnderPijulForHtml(root.presentableUrl),
    DraconBundle.Init.title,
    Messages.getWarningIcon()
    )
    if (dialog != Messages.YES) {
    return@chooseFile
    }
    }
    object : Task.Backgroundable(project, DraconBundle.Dracon.refreshing) {
    override fun run(indicator: ProgressIndicator) {
    indicator.isIndeterminate = true
    val init = pijul(project).init(project, root)
    if (init.statusCode is NonZeroExitStatusCode) {
    VcsNotifier
    .getInstance(this.project)
    .notifyError(
    NotificationIds.FAILED_TO_INIT,
    DraconBundle.Init.error,
    init.statusCode.message.wrapInHml(),
    true
    )
    }
    if (project.isDefault) {
    return
    }
    // Refresh VCS?
    DraconVcsUtil.refreshAfterInit(project, root)
    }
    }.queue()
    }
    }
    }
  • file addition: PijulCommitAndPushExecutorAction.kt (----------)
    [0.18106]
    package com.github.jonathanxd.dracon.actions
    import com.github.jonathanxd.dracon.executor.PijulCommitAndPushExecutor
    import com.intellij.dvcs.ui.DvcsBundle
    import com.intellij.dvcs.commit.getCommitAndPushActionName
    import com.intellij.openapi.actionSystem.AnActionEvent
    import com.intellij.openapi.vcs.VcsDataKeys
    import com.intellij.openapi.vcs.changes.actions.BaseCommitExecutorAction
    import com.intellij.vcs.commit.CommitWorkflowHandler
    import com.intellij.vcs.commit.NonModalCommitWorkflowHandler
    class PijulCommitAndPushExecutorAction : BaseCommitExecutorAction() {
    init {
    templatePresentation.setText(DvcsBundle.messagePointer("action.commit.and.push.text"))
    }
    override fun update(e: AnActionEvent) {
    // update presentation before synchronizing its state with button
    val workflowHandler = e.getData(VcsDataKeys.COMMIT_WORKFLOW_HANDLER)
    if (workflowHandler != null) {
    e.presentation.text = workflowHandler.getCommitAndPushActionName()
    }
    super.update(e)
    }
    override val executorId: String = PijulCommitAndPushExecutor.ID
    }
  • file addition: PijulAddExtension.kt (----------)
    [0.18106]
    package com.github.jonathanxd.dracon.actions
    import com.github.jonathanxd.dracon.pijul.pijul
    import com.github.jonathanxd.dracon.pijulVcs
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.AbstractVcs
    import com.intellij.openapi.vcs.FilePath
    import com.intellij.openapi.vcs.FileStatus
    import com.intellij.openapi.vcs.changes.actions.ScheduleForAdditionActionExtension
    import com.intellij.openapi.vfs.VirtualFile
    class PijulAddExtension : ScheduleForAdditionActionExtension {
    override fun getSupportedVcs(project: Project): AbstractVcs = pijulVcs(project)
    override fun isStatusForAddition(status: FileStatus): Boolean {
    // TODO: Change check after fully integrated.
    return true/*status === FileStatus.MODIFIED ||
    status === FileStatus.MERGED_WITH_CONFLICTS ||
    status === FileStatus.ADDED ||
    status === FileStatus.DELETED ||
    status === FileStatus.IGNORED*/
    }
    override fun doAddFiles(project: Project, vcsRoot: VirtualFile, paths: List<FilePath>, containsIgnored: Boolean) {
    pijul(project).add(project, vcsRoot, paths)
    }
    }
  • file addition: PijulVcs.kt (----------)
    [0.107]
    package com.github.jonathanxd.dracon
    import com.github.jonathanxd.dracon.i18n.DraconBundle
    import com.intellij.openapi.progress.ProgressManager
    import com.intellij.openapi.project.Project
    import com.intellij.openapi.vcs.AbstractVcs
    import com.intellij.openapi.vcs.ProjectLevelVcsManager
    import com.intellij.openapi.vcs.VcsType
    import com.intellij.openapi.vfs.VirtualFile
    const val NAME = "Pijul"
    const val ID = "pijul"
    val DISPLAY_NAME_SUPPLIER = DraconBundle.Dracon.nameSupplier
    fun pijulVcs(project: Project): PijulVcs {
    val vcs = ProjectLevelVcsManager.getInstance(project).findVcsByName(NAME) as PijulVcs
    ProgressManager.checkCanceled()
    return vcs
    }
    class PijulVcs(project: Project) : AbstractVcs(project, NAME) {
    override fun getDisplayName(): String =
    DISPLAY_NAME_SUPPLIER.get()
    override fun getType(): VcsType =
    VcsType.distributed
    override fun isVersionedDirectory(dir: VirtualFile?): Boolean {
    return super.isVersionedDirectory(dir)
    }
    override fun getShortNameWithMnemonic(): String =
    DraconBundle.Dracon.mnemonic
    companion object {
    val KEY = createKey(NAME)
    }
    }