Coder Social home page Coder Social logo

ktlint-intellij-plugin's Introduction

Plugin set

Contrary to the default plugin setup this plugin is set up as a multi-module project. This is required as the Ktlint artifact for the KtlintRuleEngine encloses the embeddable Kotlin compiler which conflicts with the IDE compiler.

The "ktlint-lib" project relocates the conflicting classes, and provides the different versions of the rulesets. The "plugin" project uses the "lib" to include the (modified) Ktlint artifacts.

Installation

Once the plugin has been tested with the Run Plugin.run.xml run configuration, the development version of the plugin can also be installed on the local machine of yourself and other beta testers.

  • Modify the name of the plugin plugin/src/main/resources/META-INF/plugin.xml and/or the pluginVersion in the (root) gradle.properties so that the specific version can be recognized easily:
    <name>Ktlint (dev-version YYYY-MM-DD)</name>
  • Perform a clean build
  • Run the Plugin so that the IDEA sandbox is refreshed
  • Create zip file with development version of plugin from IDEA sandbox
    ./create-ktlint-plugin-zip.sh
  • Install the zip file manually using Preferences > Plugins > โš™๏ธ > Install plugin from disk...

Building with local ktlint SNAPSHOT

In case you need to build the plugin based on a SNAPSHOT version of ktlint on your local machine, then follow procedure below:

  • In the "ktlint" project execute ./gradlew publishMavenPublicationToMavenLocal to publish the SNAPSHOT artifacts to your local maven repository.
  • In the "ktlint-intellij-plugin" project:
    • Change the ktlint version in libs.version.toml
    • Include mavenLocal() repository in all build.gradle.kts files as follows:
       repositories {
           mavenCentral()
           mavenLocal()
       }
    • Build the lib module
    • Build the plugin module
    • Run the plugin

ktlint-intellij-plugin's People

Contributors

actions-user avatar badan004 avatar dependabot[bot] avatar github-actions[bot] avatar nbadal avatar paul-dingemans avatar tlusk avatar westfort avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

ktlint-intellij-plugin's Issues

ParseException from KtLint causes crash

It seems like some syntax errors cause KtLint to throw a ParseException, which if uncaught cause the plugin to crash.

We should catch these at the linting level and skip results, not crash entirely.

Add support for multiple/runtime-specific versions of ktlint

I have a code like this:

  val someVar = when (ctx.path()) {
      "/some/path/here" -> {
        println("hello")
      }
      else -> ctx.attribute<AttributeClassName>(Attributes.ATTRIBUTE_IDENTIFIER)
        ?: throw MyException("some error message")
    }
    println(someVar.toString())

IDE with installed ktlint plugin is happy with this code, i.e. doesn't put red marks.
But when I run my Gradle build, ktlint check compains at the same code:

SourceFileName.kt:123:13: Missing newline after "->"

I'm expecting that should plugin also detect this inconsistency, but actually it is not.

Run ktlint on save

It would be nice if it did really automatically format your code every time a file is saved.

Intellij version to 203.*

Can you increase the version of intellij to 203.*

I've tried to open a PR for you, but looks like we are not allowed.
Thanks

Trailing comma behaviour different from gradle plugin

Over time, our team developed certain standards about where we want to use trailing commas. We like to use them in many places like injected service constructors, list builders etc. (places where it is common to add lines later) but we don't use them in more static places like method calls that just get one parameter.
Ktlint itself is fine with this and although our fuzzy rules can't be enforced, it at least leaves everything as we wrote it.
However, since I updated the IntelliJ Plugin (to 0.10.0), I get my trailing commas marked as a format error with the message Unnecessary trailing comma before ")" (trailing-comma). Of course I could enable ij_kotlin_allow_trailing_comma and ij_kotlin_allow_trailing_comma_on_call_site in editorconfig, but then also sets the commas in places where I don't want them.

Expected Behaviour: unless explicitly specified, ignore trailing commas, just like the default Kotlin formatter

0.9.0 cannot be installed with IJ2022.2 EAP

The ktlint plugin cannot be installed on the fresh available IntelliJ 2022.2 EAP. It would be nice if you could support it.
Maybe you can just extend the compatibility range.

ktlint reformating does not show up as an intellij on save action

As the title says, I've installed the plugin and played with it for a bit, everything seems to work ok (there were a couple of errors at first which led to the plugin crashing, but I didn't take a screenshot of them) , but the "on save action" does not appear to be there. I saw that there was a recent feature about this and that it should work. I've tried invalidating the caches a couple of times, but that didn't fix anything. Here are some screenshots:

onSaveActions
pluginIsEnabled
intellijVersion

ktlint 0.45 crashes plugin with java.lang.LinkageError

This seems to have been caused by the addition of a new logging library in this change

Caused by: java.lang.LinkageError: loader constraint violation: when resolving method 'org.slf4j.ILoggerFactory org.slf4j.impl.StaticLoggerBinder.getLoggerFactory()' the class loader com.intellij.ide.plugins.cl.PluginClassLoader @15016895 of the current class, org/slf4j/LoggerFactory, and the class loader com.intellij.util.lang.UrlClassLoader @675d3402 for the method's defining class, org/slf4j/impl/StaticLoggerBinder, have different Class objects for the type org/slf4j/ILoggerFactory used in the signature (org.slf4j.LoggerFactory is in unnamed module of loader com.intellij.ide.plugins.cl.PluginClassLoader @15016895, parent loader 'bootstrap'; org.slf4j.impl.StaticLoggerBinder is in unnamed module of loader com.intellij.util.lang.UrlClassLoader @675d3402, parent loader 'platform')
	at org.slf4j.LoggerFactory.getILoggerFactory(LoggerFactory.java:423)
	at org.slf4j.LoggerFactory.getLogger(LoggerFactory.java:362)
	at mu.KotlinLogging.logger(KotlinLogging.kt:32)
	at com.pinterest.ktlint.core.internal.EditorConfigLoaderKt.<clinit>(EditorConfigLoader.kt:20)
	at com.pinterest.ktlint.core.internal.EditorConfigLoader.loadPropertiesForFile(EditorConfigLoader.kt:111)
	at com.pinterest.ktlint.core.KtLint.prepareCodeForLinting(KtLint.kt:234)
	at com.pinterest.ktlint.core.KtLint.lint(KtLint.kt:176)
	at com.pinterest.ktlint.core.KtLint.lint(KtLint.kt:152)
	at com.pinterest.ktlint.core.KtLint.lint(KtLint.kt:148)
	at com.nbadal.ktlint.KtLintWrapper.lint(KtLintWrapper.kt:10)
        [...]

External ruleset JARS not annotating issues.

I have created a jar file with my custom ruleset, it works fine when I run ktlint from command line, my custom rules are picked up. When I set this jar in External ruleset JARS --ruleset in the plugin, it doesn't pick up on my issues in the IDE (Android Studio 4.1.2).
In fact, it doesn't pick up on any rules, seems that it doesn't use the pre-packaged ruleset either.

My expectation would be that I could add my custom ruleset jar in addition to current rules, but when I set it, IDE doesn't annotate any rules.

experimental rules checkbox not working?

I enabled the experimental rules in my gradle config, and the gradle build now fails in places where I am violating them as I would expect. However, I also checked the "Use experimental rules" checkbox in the IDEA plugin config dialog, and the errors that are causing the compile failures are not being highlighted in the editor window. Is there another setting I need to toggle?

Add mechanism to disable rule for all projects

Hi,

I like the plugin a lot, what I am missing is an option, to have a few rules disabled not on a project-level, but for all projects together. I would see it as kind of a hierarchy, that you have the rules that are disabled for all projects, and then you have the rules that are disabled for one particular project

Use Intellij built-in code formatter

It would be great to integrate the plugin with the built-in code formatter (CTRL-ALT-L). This would not only be easier regarding the shortcut, but would also give the possibility of checking "reformat code" when commiting code and reformat it automatically.

As an example, the plugin of prettier in the world of javascript is capable of doing so.

Disable inspections while also having "Lint after Reformat" active

Personally I don't like ktlint violations showing up as inspections (with a highlighted background etc), it can be rather distracting, especially with big multi-line ranges being highlighted. As far as I can tell, "Disable ktlint", which disables this, also disables everything else. However, I still want to have "Lint after Reformat" enabled.

My use case is basically just "format on save" - I have "Reformat Code" assigned to Ctrl+S which I press every so often while writing code to fix the formatting. That allows me to write code without being distracted by getting the formatting details right manually. Well, unless those formatting issues distract me via inspections. :)

So far I've been using the IntelliJ formatter config generated by ktlint, but unfortunately there's some edge cases where ktlint -F and the IntelliJ formatter behave differently, so this plugin seems to be exactly what I'm looking for.

RFE: add quick fix for just formatting specific issue at hand

when ktlint finds an issue, I can either:

  • ignore it
  • format the entire file
  • manually fix the issue at hand

This is quite inflexible, as most often, I don't want to go to either extreme, but just fix the issue at hand, as is common in IntelliJ inspections and quick fix actions.
It would be great if ktlint followed this pattern, too.

.editorconfig override path

Hi there

Great plugin, our team loves using it!

I recently upgraded to 0.7.0 and started to notice that previously acceptable kotlin files were now marked with ktlint errors. Specifically the line length error. On closer inspection it seemed to be reporting the line length and import ordering as the default ktlint values and not the values that we have set in our .editorconfig file.

I don't remember having to manually configure the editorconfig file in previous versions of the plugin but as a workaround I added the folder that contains this file to the .editorconfig override path in the settings menu and that worked.

The location of our editorconfig hasn't changed ever and has always been in the root of the project.

android
  | app
    | build.gradle
  | settings.gradle
  | gradlew
  | build.gradle
  | .editorconfig

I'm running Windows if that matters.

ParseException: 1:1 Expecting a top level declaration

This exception occurred for me locally, and likely in the wild but before Rollbar was fixed:

...
Caused by: com.pinterest.ktlint.core.ParseException: 1:1 Expecting a top level declaration
	at com.pinterest.ktlint.core.KtLint.prepareCodeForLinting(KtLint.kt:119)
	at com.pinterest.ktlint.core.KtLint.lint(KtLint.kt:71)
	at com.nbadal.ktlint.KtlintProcessingKt.doLint(KtlintProcessing.kt:60)
	at com.nbadal.ktlint.KtlintAnnotator.doAnnotate(KtlintAnnotator.kt:19)
	at com.nbadal.ktlint.KtlintAnnotator.doAnnotate(KtlintAnnotator.kt:10)
...

Maybe when the file had an incorrect number of curly braces? If the linter fails on these kinds of cases, we should just skip the annotation pass, or insert it as a full-file error perhaps.

Make path to ktlint-executable configurable instead of using a bundled ktlint-version

Thank you for this great plugin!

The thing that would make my (and maybe your) life easier, would be to set the path to the ktlint-executable used by this plugin (similar to how the Git-executable is configured in Android Studio et al).

As it is now, the plugin-bundled version of ktlint is 0.46.1 according to the changelog on the plugin-homepage.
The latest released official version of ktlint from pinterest is 0.47.1.

Right now I cannot be sure that the latest ktlint-version used by CI and local proxy-installation is reporting / fixing the same issues as the plugin-bundled version.

By using a separate installation of ktlint would enable me to use the same version of ktlint everywhere.

For you as the plugin-author this enhancement would lift the burden of updating the plugin for every new ktlint-version from you.

I understand there may be issues parsing the ktlint-output with an unknown plugin-external ktlint-installation as incompatible changes in the report-format might break the plugin.
If that is the case/concern, then feel free to close this issue as a wontfix (in that case could you please update the plugin to use the latest ktlint-version?).

Thank you for your support!

Suggestion: Run ktlint analysis on demand

When opening a file, the plugin immediately checks the file. Also, in some situations, I can see that, while changing the file, the checks are stopped and I need to close and reopen the file to force the checks to run again (sometimes this even fails).

As a user, I would like to have:

  1. Have an option to force the ktlint checks on the file. For example, an action with the name "Run ktlint checks on file" will force the checks on the current file. It does not format, it will just check and if any issue found, show them as warnings/error/none accordingly to the setting.
  2. Have a checkbox in settings (just like "Enable ktlint") with "Only perform checks on demand". When that setting is enabled, opening a file does not automatically trigger the ktlint checks. If we want to check we will make use of point 1 above.

P.S. - You added "Format With ktlint" to the refactor menu but it's missing when we use the shortcut for "Refactor this".

image

Lint after reformat setting changes reformat code behavior

If I have the Lint after reformat setting enabled when I use the Reformat Code option (OPTION+COMMAND+L shortcut on mac) on a block of code, all the file gets reformated.

If I disable the setting, Reformat Code behaves as expected, that is, it only formats the current code block and not the all file.

Ktlint 0.7.1

misconfigures the import order when using Mockito

Found a bug today where the lexicographical order is unable to correct order Mockito import for when containing the character `

import org.mockito.Mockito.`when`
import org.mockito.Mockito.after
import org.mockito.Mockito.any
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.doThrow

This is the correct order, however ktlint shows this as an error and then after running it. The import are incorrectly ordered to

import org.mockito.Mockito.after
import org.mockito.Mockito.any
import org.mockito.Mockito.doReturn
import org.mockito.Mockito.doThrow
import org.mockito.Mockito.`when`

due to the ` character

IllegalArgumentException: Argument for @NotNull parameter 'fileOrDir' of com/intellij/openapi/roots

Hello, saw the following in IDE bottom right corner - unfortunately unsure exactly how was it triggered.

java.lang.IllegalArgumentException: Argument for @NotNull parameter 'fileOrDir' of com/intellij/openapi/roots/impl/ProjectFileIndexImpl.isInContent must not be null
	at com.intellij.openapi.roots.impl.ProjectFileIndexImpl.$$$reportNull$$$0(ProjectFileIndexImpl.java)
	at com.intellij.openapi.roots.impl.ProjectFileIndexImpl.isInContent(ProjectFileIndexImpl.java)
	at com.nbadal.ktlint.KtlintPostFormatProcessor.shouldLint(KtlintPostFormatProcessor.kt:27)
	at com.nbadal.ktlint.KtlintPostFormatProcessor.processText(KtlintPostFormatProcessor.kt:16)
	at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.postProcessEnabledRanges(CodeStyleManagerImpl.java:904)
	at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.postProcessElement(CodeStyleManagerImpl.java:107)
	at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformat(CodeStyleManagerImpl.java:98)
	at com.intellij.psi.impl.source.codeStyle.CodeStyleManagerImpl.reformat(CodeStyleManagerImpl.java:76)
	at org.jetbrains.kotlin.idea.completion.handlers.HandlerUtilsKt.createKeywordConstructLookupElement(handlerUtils.kt:115)
	at org.jetbrains.kotlin.idea.completion.handlers.HandlerUtilsKt.createKeywordConstructLookupElement$default(handlerUtils.kt:112)
	at org.jetbrains.kotlin.idea.completion.KeywordCompletion.complete(KeywordCompletion.kt:141)
	at org.jetbrains.kotlin.idea.completion.BasicCompletionSession$KEYWORDS_ONLY$1.doComplete(BasicCompletionSession.kt:582)
	at org.jetbrains.kotlin.idea.completion.BasicCompletionSession$ALL$1.doComplete(BasicCompletionSession.kt:234)
	at org.jetbrains.kotlin.idea.completion.BasicCompletionSession.doComplete(BasicCompletionSession.kt:141)
	at org.jetbrains.kotlin.idea.completion.CompletionSession._complete(CompletionSession.kt:243)
	at org.jetbrains.kotlin.idea.completion.CompletionSession.complete(CompletionSession.kt:218)
	at org.jetbrains.kotlin.idea.completion.KotlinCompletionContributor.doComplete(KotlinCompletionContributor.kt:315)
	at org.jetbrains.kotlin.idea.completion.KotlinCompletionContributor.doComplete$default(KotlinCompletionContributor.kt:274)
	at org.jetbrains.kotlin.idea.completion.KotlinCompletionContributor.performCompletion(KotlinCompletionContributor.kt:267)
	at org.jetbrains.kotlin.idea.completion.KotlinCompletionContributor.access$performCompletion(KotlinCompletionContributor.kt:39)
	at org.jetbrains.kotlin.idea.completion.KotlinCompletionContributor$provider$1.addCompletions(KotlinCompletionContributor.kt:57)
	at com.intellij.codeInsight.completion.CompletionProvider.addCompletionVariants(CompletionProvider.java:32)
	at com.intellij.codeInsight.completion.CompletionContributor.fillCompletionVariants(CompletionContributor.java:155)
	at com.intellij.codeInsight.completion.CompletionService.getVariantsFromContributors(CompletionService.java:77)
	at com.intellij.codeInsight.completion.CompletionResultSet.runRemainingContributors(CompletionResultSet.java:154)
	at com.intellij.codeInsight.completion.CompletionResultSet.runRemainingContributors(CompletionResultSet.java:146)
	at com.intellij.codeInsight.completion.CompletionResultSet.runRemainingContributors(CompletionResultSet.java:142)
	at com.intellij.codeInsight.template.impl.LiveTemplateCompletionContributor$1.addCompletions(LiveTemplateCompletionContributor.java:88)
	at com.intellij.codeInsight.completion.CompletionProvider.addCompletionVariants(CompletionProvider.java:32)
	at com.intellij.codeInsight.completion.CompletionContributor.fillCompletionVariants(CompletionContributor.java:155)
	at com.intellij.codeInsight.completion.CompletionService.getVariantsFromContributors(CompletionService.java:77)
	at com.intellij.codeInsight.completion.CompletionService.getVariantsFromContributors(CompletionService.java:60)
	at com.intellij.codeInsight.completion.CompletionService.performCompletion(CompletionService.java:133)
	at com.intellij.codeInsight.completion.BaseCompletionService.performCompletion(BaseCompletionService.java:41)
	at com.intellij.codeInsight.completion.CompletionProgressIndicator.lambda$calculateItems$12(CompletionProgressIndicator.java:862)
	at com.intellij.util.indexing.FileBasedIndex.lambda$ignoreDumbMode$0(FileBasedIndex.java:179)
	at com.intellij.openapi.util.RecursionManager$1.computePreventingRecursion(RecursionManager.java:111)
	at com.intellij.util.indexing.FileBasedIndexEx.ignoreDumbMode(FileBasedIndexEx.java:543)
	at com.intellij.util.indexing.FileBasedIndex.ignoreDumbMode(FileBasedIndex.java:178)
	at com.intellij.codeInsight.completion.CompletionProgressIndicator.calculateItems(CompletionProgressIndicator.java:858)
	at com.intellij.codeInsight.completion.CompletionProgressIndicator.runContributors(CompletionProgressIndicator.java:846)
	at com.intellij.codeInsight.completion.CodeCompletionHandlerBase.lambda$startContributorThread$6(CodeCompletionHandlerBase.java:353)
	at com.intellij.codeInsight.completion.AsyncCompletion.lambda$tryReadOrCancel$5(CompletionThreading.java:172)
	at com.intellij.openapi.application.impl.ApplicationImpl.tryRunReadAction(ApplicationImpl.java:1137)
	at com.intellij.codeInsight.completion.AsyncCompletion.tryReadOrCancel(CompletionThreading.java:170)
	at com.intellij.codeInsight.completion.CodeCompletionHandlerBase.lambda$startContributorThread$7(CodeCompletionHandlerBase.java:345)
	at com.intellij.codeInsight.completion.AsyncCompletion.lambda$startThread$0(CompletionThreading.java:95)
	at com.intellij.openapi.progress.impl.CoreProgressManager.lambda$runProcess$2(CoreProgressManager.java:178)
	at com.intellij.openapi.progress.impl.CoreProgressManager.registerIndicatorAndRun(CoreProgressManager.java:658)
	at com.intellij.openapi.progress.impl.CoreProgressManager.executeProcessUnderProgress(CoreProgressManager.java:610)
	at com.intellij.openapi.progress.impl.ProgressManagerImpl.executeProcessUnderProgress(ProgressManagerImpl.java:65)
	at com.intellij.openapi.progress.impl.CoreProgressManager.runProcess(CoreProgressManager.java:165)
	at com.intellij.codeInsight.completion.AsyncCompletion.lambda$startThread$1(CompletionThreading.java:91)
	at com.intellij.util.RunnableCallable.call(RunnableCallable.java:20)
	at com.intellij.util.RunnableCallable.call(RunnableCallable.java:11)
	at com.intellij.openapi.application.impl.ApplicationImpl$1.call(ApplicationImpl.java:270)
	at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264)
	at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
	at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:668)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1$1.run(Executors.java:665)
	at java.base/java.security.AccessController.doPrivileged(Native Method)
	at java.base/java.util.concurrent.Executors$PrivilegedThreadFactory$1.run(Executors.java:665)
	at java.base/java.lang.Thread.run(Thread.java:834)

Minimal Ktlint actions for IdeaVim

I use IdeaVim and tend to hook up formatting actions to keystrokes. Running :actionlist using IdeaVim shows me that there aren't any actions available to bind. Would it be possible to present some to users so that we can do stuff like the following?

" binds ctrl+shift+i to the action `KtlistFormatFile`
nnoremap <C-S-i> :action KtlintFormatFile<CR>

Great idea for a plugin, thank you! Gonna try to incorporate it into my workflow ๐Ÿ˜„

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.