ファイルの末尾に改行を追加するように Android Studio を設定するにはどうすればよいですか?

🧑‍💻 NewLineAtEndOfFile

👉 【AndroidStudio】detekt で JetpackCompose 記述をチェックする hatena-bookmark

つい忘れてしまうファイル最後の改行。


[ Settings... ]

  ↓

[ Editor ]

  ↓

[ General ]

  ↓

[ Ensure every saved file ends with a line break ]

ファイルの末尾に新しい行を追加するように Android Studio を設定するにはどうすればよいですか?

これで、ファイルを開いた時点で最終行の改行は自動で必ず付いている、自動保存なので。

てか、IDE デフォルトで ON でもいいように思う機能。

 

🧑‍💻 と思ったら付かないので「Keep tarailing spaces on caret line」を OFF に

「Keep tarailing spaces on caret line」 を OFF にしないと付きません。

あと、余計な末尾の空白行は、「Remove trailing blank lines at the end of saved files」を ON にすると自動で消してくれます。

 

🧑‍💻 自動保存のタイミングはいつなのか

AndroidStudio デフォルトの設定では、

アプリを切り替えたとき、

または、ビルトインのターミナルに切り替えたとき

に自動保存されるようです。

自動保存のタイミングはいつなのか

なので、上で述べた最終行まわりの自動処理はその時に行われます。

自動保存のタイミングはいつなのか

 

🧑‍💻 まとめ

自動保存時に、

ファイル末尾の改行がなかったら付ける。

ファイル末尾の無駄な空白行は削除する。

の AndroidStudio の設定は以下。


[ Settings... ]

  ↓

[ Editor ]

  ↓

[ General ]

  ↓

□ [ Keep tarailing spaces on caret line ] OFF
✅ [ Ensure every saved file ends with a line break ] ON
✅ [ Remove trailing blank lines at the end of saved files ] ON

こんな機能あるとは知らなかったです。便利です。

👉 【AndroidStudio】detekt で JetpackCompose 記述をチェックする hatena-bookmark


【AndroidStudio】detekt で JetpackCompose 記述をチェックする

あちこちの著名なアプリ開発で使われているようなので、標準的な正しい記述を学ぶことができると思います。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)
👉 Welcome | detekt hatena-bookmark

 

🧑‍💻 インストール方法

いくつかの方法があるのでどれを使ったらいいのか分からない。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

一通り「Getting Started」を読んでみたけど、まず初めは手っ取り早い「IDE プラグイン」か「Gradle プラグイン」でしょうか。

 

🧑‍💻 IDE プラグインをインストール

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

👉 detekt - IntelliJ IDEs Plugin | Marketplace hatena-bookmark
👉 detekt/detekt-intellij-plugin: detekt plugin for IntelliJ hatena-bookmark

ファイルから右クリックで実行できるので便利そう。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)

しかし、detekt.yml を利用してのチェックポリシー変更がなぜか反映されない。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする (随時更新)
👉 Issues · detekt/detekt-intellij-plugin hatena-bookmark

issues にもそのような事例多く上がっているのでとりあえず捨てる。

 

🧑‍💻 Gradle プラグインをインストール

きっと、リポジトリに mavenCentral() は設定済みだと思うので、追加するのは1行。


// build.gradle.kts

plugins {
  id("io.gitlab.arturbosch.detekt") version("1.23.1" )
}

インストールはこれだけです。

タスクに登録されているか確認します。


❯ ./gradlew tasks | grep detekt

detekt
detektBaseline - Creates a detekt baseline on the given --baseline path.
detektBaselineDebug - EXPERIMENTAL: Creates detekt baseline for debug classes with type resolution
detektBaselineDebugAndroidTest - EXPERIMENTAL: Creates detekt baseline for debugAndroidTest classes with type resolution
detektBaselineDebugUnitTest - EXPERIMENTAL: Creates detekt baseline for debugUnitTest classes with type resolution
detektBaselineMain - EXPERIMENTAL: Creates detekt baseline files for production classes across all variants with type resolution
detektBaselineRelease - EXPERIMENTAL: Creates detekt baseline for release classes with type resolution
detektBaselineReleaseUnitTest - EXPERIMENTAL: Creates detekt baseline for releaseUnitTest classes with type resolution
detektBaselineTest - EXPERIMENTAL: Creates detekt baseline files for test classes across all variants with type resolution
detektDebug - EXPERIMENTAL: Run detekt analysis for debug classes with type resolution
detektDebugAndroidTest - EXPERIMENTAL: Run detekt analysis for debugAndroidTest classes with type resolution
detektDebugUnitTest - EXPERIMENTAL: Run detekt analysis for debugUnitTest classes with type resolution
detektGenerateConfig - Generate a detekt configuration file inside your project.
detektMain - EXPERIMENTAL: Run detekt analysis for production classes across all variants with type resolution
detektRelease - EXPERIMENTAL: Run detekt analysis for release classes with type resolution
detektReleaseUnitTest - EXPERIMENTAL: Run detekt analysis for releaseUnitTest classes with type resolution
detektTest - EXPERIMENTAL: Run detekt analysis for test classes across all variants with type resolution

❯ ./gradlew tasks | grep detekt | grep -v EXPERIMENTAL

detekt
detektBaseline - Creates a detekt baseline on the given --baseline path.
detektGenerateConfig - Generate a detekt configuration file inside your project.

これらの Gradle プラグインによって登録された Gradle タスクを実行することでコード記述のチェックができるようです。

インストール方法としては、これで進めていきます。

 

🧑‍💻 設定ファイル

Gradle タスクを使って書き出します。


❯ ./gradlew detektGenerateConfig

> Task :app:detektGenerateConfig
Successfully copied default config to /path/to/project/config/detekt/detekt.yml

デフォルトの設定のコピー detekt.yml が表示されてる位置に書き出されました。

【AndroidStudio】detekt で JetpackCompose 記述をチェックする

【AndroidStudio】detekt で JetpackCompose 記述をチェックする

チェックポリシーを変更する場合は、この YML 形式のファイルを書き換えます。

820行もあります。

 

🧑‍💻 実行する

では、実行してチェックしてみます。


❯ ./gradlew detekt              

> Task :app:detekt FAILED
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Theme.kt:41:5: Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]
/path/to/project/app/src/main/java/com/example/ea/MainActivity.kt:92:5: Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:5:22: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:6:26: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:7:20: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:9:22: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:10:26: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]
/path/to/project/app/src/main/java/com/example/ea/ui/theme/Color.kt:11:20: This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]


FAILURE: Build failed with an exception.

* What went wrong:
Execution failed for task ':app:detekt'.
> Analysis failed with 8 weighted issues.

* Try:
> Run with --stacktrace option to get the stack trace.
> Run with --info or --debug option to get more log output.
> Run with --scan to get full insights.
> Get more help at https://help.gradle.org.

BUILD FAILED in 545ms
1 actionable task: 1 executed

8箇所に2種類のエラーがでました。


Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]


This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]

チェックするコードとして、AndroidStudio 同梱の新規プロジェクトテンプレート「Empty Activity」を書き出しただけのプロジェクトなのですが。

それぞれ内容を見ていきます。

 

🧑‍💻 Function names should match the pattern: [a-z][a-zA-Z0-9]* [FunctionNaming]


@Composable
fun FooButton(text: String, onClick: () -> Unit) {

Unit を返す @Composable 関数名は PascalCase なので、JetpackCompose に向けて設定ファイル detekt.yml を以下のいずれかに変更します。


  FunctionNaming:
    active: true
    excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
#   functionPattern: '[a-z][a-zA-Z0-9]*'
    functionPattern: '[a-zA-Z][a-zA-Z0-9]*'
    excludeClassPattern: '$^'


  FunctionNaming:
    active: true
    excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
    functionPattern: '[a-z][a-zA-Z0-9]*'
    excludeClassPattern: '$^'
    ignoreAnnotated: ['Composable'] # 追加


  FunctionNaming:
    active: true
    excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**']
    functionPattern: '[a-z][a-zA-Z0-9]*'
    excludeClassPattern: '$^'
    ignoreAnnotated: # 追加
      - 'Composable' # 追加

どうやら、detekt デフォルトの設定は JetpackCompose に十分には対応してないようです。

 

🧑‍💻 This expression contains a magic number. Consider defining it to a well named constant. [MagicNumber]


val color1 = Color(0xFFEA6D7E)

クラス、コンパニオンオブジェクト、トップレベルのプロパティのオブジェクト記述は、名前付きパラメータを指定しないと違反となるようです。

以下のいずれかで。


val color1 = Color(color = 0xFFEA6D7E)


  MagicNumber:
    active: true
    excludes: ['**/test/**', '**/androidTest/**', '**/commonTest/**', '**/jvmTest/**', '**/androidUnitTest/**', '**/androidInstrumentedTest/**', '**/jsTest/**', '**/iosTest/**', '**/*.kts']
    ignoreNumbers:
      - '-1'
      - '0'
      - '1'
      - '2'
    ignoreHashCodeFunction: true
#   ignorePropertyDeclaration: false
    ignorePropertyDeclaration: true

あまり、ignore* 系は使わない方がいいような気もする。

 

🧑‍💻 まとめ

などと書いてきましたが、これらは以下の detekt 公式ページにまとめられています。

Configuration for Compose | detekt hatena-bookmark
👉 Configuration for Compose | detekt hatena-bookmark

逆にいえば、これらは、

「Kotlin と JetpackCompose の記述ルールの違い」

ということになるのでしょう。

detekt を使わない方も一読しておくといいと思われます。

👉 【Gradle Plugin】detekt「baseline」とは hatena-bookmark

👉 ファイルの末尾に改行を追加するように Android Studio を設定するにはどうすればよいですか? hatena-bookmark


【AndroidStudio / IDEA】プラグイン「Indent Rainbow」を使う

階層が深くなって見づらいので、対応するカッコを色付けするプラグインを入れましたが、

izhangzhihao/intellij-rainbow-brackets: Rainbow Brackets / Rainbow Parentheses for IntelliJ IDEA based IDEs
👉 IntelliJ IDEA プラグイン「Rainbow Brackets」を使う hatena-bookmark

つづいてインデントも「Indent Rainbow」で色付けします。

【AndroidStudio / IDEA】プラグイン「Indend Rainbow」を使う
👉 Indent Rainbow - IntelliJ IDEs Plugin | Marketplace hatena-bookmark

【AndroidStudio / IDEA】プラグイン「Indend Rainbow」を使う

【AndroidStudio / IDEA】プラグイン「Indend Rainbow」を使う

いいんじゃないですかね、とりあえず。

うざくなった捨てます。