Skip to content

Commit

Permalink
Add "format on save" for rider users
Browse files Browse the repository at this point in the history
  • Loading branch information
aarcangeli committed Nov 2, 2024
1 parent 40dd33a commit 383ee2a
Show file tree
Hide file tree
Showing 9 changed files with 117 additions and 1 deletion.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
- Detect indentation style and column limit from `.clang-format` file
- Format code using `clang-format` binary
- Settings page to configure `clang-format` binary path
- Format on save option
- On Rider, format code on save (other IDEs already have this feature)

[Unreleased]: https://github.com/aarcangeli/idea-clang-format/compare/v1.0.0...HEAD
[1.0.0]: https://github.com/aarcangeli/idea-clang-format/commits/v1.0.0
9 changes: 9 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -63,10 +63,19 @@ Note: At the moment, it is not possible to format only a selection of the code.

To enable the format on save feature, follow these steps:

**For Most JetBrains IDEs**

1. Go to `File | Settings | Tools | Actions on Save`
2. Enable the `Reformat code` action
3. Optionally, choose the file types you want to format on save

**For Rider**

Unfortunately, Rider is not supported by the `Actions on Save` feature, but you can use the `Clang-Format` action instead.

1. Go to `File | Settings | Tools | Actions on Save`
2. Enable the `Clang-Format` action

### Configuration

This plugin should work out of the box, but if you want to customize the behavior, you can do so in the settings.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ class ClangFormatConfig : SimplePersistentStateComponent<ClangFormatConfig.State
class State : BaseState() {
var enabled by property(true)

var formatOnSave by property(false)

/// The path to the clang-format executable.
/// If null, the plugin will try to find it in the PATH.
var customPath by string()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package com.github.aarcangeli.ideaclangformat.configurable
import com.github.aarcangeli.ideaclangformat.ClangFormatConfig
import com.github.aarcangeli.ideaclangformat.exceptions.ClangFormatError
import com.github.aarcangeli.ideaclangformat.services.ClangFormatService
import com.github.aarcangeli.ideaclangformat.utils.ClangFormatCommons
import com.intellij.openapi.components.service
import com.intellij.openapi.options.Configurable.NoScroll
import com.intellij.openapi.options.DslConfigurableBase
Expand Down Expand Up @@ -42,6 +43,13 @@ class AppConfigurable : DslConfigurableBase(), SearchableConfigurable, NoScroll
}
}
}
if (ClangFormatCommons.isUsingCustomFormatOnSave()) {
row {
combobox = checkBox("Format on save")
.bindSelected(settings::formatOnSave)
.enabledIf(combobox.selected)
}
}
}

group("Location") {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
package com.github.aarcangeli.ideaclangformat.onsave

import com.github.aarcangeli.ideaclangformat.ClangFormatConfig
import com.github.aarcangeli.ideaclangformat.services.ClangFormatService
import com.github.aarcangeli.ideaclangformat.utils.ClangFormatCommons
import com.intellij.ide.actionsOnSave.impl.ActionsOnSaveFileDocumentManagerListener.ActionOnSave
import com.intellij.openapi.components.service
import com.intellij.openapi.editor.Document
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.project.Project
import com.intellij.psi.PsiDocumentManager

class ClangFormatOnSave : ActionOnSave() {
override fun isEnabledForProject(project: Project): Boolean {
return service<ClangFormatConfig>().state.formatOnSave && ClangFormatCommons.isUsingCustomFormatOnSave()
}

override fun processDocuments(project: Project, documents: Array<Document?>) {
val fileDocumentManager = service<FileDocumentManager>()

for (document in documents) {
val virtualFile = fileDocumentManager.getFile(document ?: continue) ?: continue
val psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document) ?: continue
if (service<ClangFormatService>().mayBeFormatted(psiFile, false)) {
service<ClangFormatService>().reformatFileSync(project, virtualFile)
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2000-2021 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file.
package com.github.aarcangeli.ideaclangformat.onsave

import com.github.aarcangeli.ideaclangformat.ClangFormatConfig
import com.intellij.ide.actionsOnSave.ActionOnSaveContext
import com.intellij.ide.actionsOnSave.ActionOnSaveInfo
import com.intellij.openapi.components.service


class ClangFormatOnSaveActionInfo(context: ActionOnSaveContext) : ActionOnSaveInfo(context) {
private val settings = service<ClangFormatConfig>().state
private var isFormatOnSaveEnabled: Boolean = settings.formatOnSave

override fun apply() {
settings.formatOnSave = isFormatOnSaveEnabled
}

override fun isModified(): Boolean {
return isFormatOnSaveEnabled != settings.formatOnSave
}

override fun getActionOnSaveName(): String {
return "Run clang-format"
}

override fun isActionOnSaveEnabled(): Boolean {
return isFormatOnSaveEnabled
}

override fun setActionOnSaveEnabled(enabled: Boolean) {
isFormatOnSaveEnabled = enabled
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package com.github.aarcangeli.ideaclangformat.onsave

import com.github.aarcangeli.ideaclangformat.utils.ClangFormatCommons
import com.intellij.ide.actionsOnSave.ActionOnSaveContext
import com.intellij.ide.actionsOnSave.ActionOnSaveInfo
import com.intellij.ide.actionsOnSave.ActionOnSaveInfoProvider

class ClangFormatOnSaveInfoProvider : ActionOnSaveInfoProvider() {
override fun getActionOnSaveInfos(context: ActionOnSaveContext): Collection<ActionOnSaveInfo> {
if (ClangFormatCommons.isUsingCustomFormatOnSave()) {
return mutableListOf(ClangFormatOnSaveActionInfo(context))
}
return emptyList()
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -133,4 +133,17 @@ object ClangFormatCommons {
}
return virtualFile.name
}

/**
* Rider doesn't work with "Reformat on save" option, so we need to create a custom provider.
*/
fun isUsingCustomFormatOnSave(): Boolean {
return isRider()
}

private fun isRider(): Boolean {
val prefix = System.getProperty("idea.platform.prefix", null)
val isRider = prefix == "Rider"
return isRider
}
}
7 changes: 7 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@
<applicationConfigurable id="aarcangeli.ideaclangformat.appconfig" parentId="language"
instance="com.github.aarcangeli.ideaclangformat.configurable.AppConfigurable"
displayName="Clang-Format Tools"/>

<!-- Format on save -->
<!-- IntelliJ already has this feature, but Rider uses his internal formatter instead -->
<actionOnSave id="aarcangeli.ClangFormatOnSave" implementation="com.github.aarcangeli.ideaclangformat.onsave.ClangFormatOnSave"/>
<actionOnSaveInfoProvider id="aarcangeli.ClangFormatOnSaveInfoProvider"
implementation="com.github.aarcangeli.ideaclangformat.onsave.ClangFormatOnSaveInfoProvider"/>

</extensions>

<!-- BEGIN .clang-format language support -->
Expand Down

0 comments on commit 383ee2a

Please sign in to comment.