Rename Git branch master to main


❯ git -v
git version 2.39.1

 

■ Delete local branch


git branch -d master

 

■ Rename local branch


git branch -m master main

 

■ Push the new branch, set local branch to track the new remote


git push -u origin main


git push --set-upstream origin main

 

■ Delete remote branch


git push origin :master


git push origin --delete master

I got this.


❯ git push origin :master
To https://github.com/your/project
 ! [remote rejected] master (refusing to delete the current branch: refs/heads/master)
error: failed to push some refs to 'https://github.com/your/project'

Switch default branch master to main at https://github.com/your/project

Rename Git branch master to main

 

■ Show status


❯ git status
On branch main
Your branch is up to date with 'origin/main'.
nothing to commit, working tree clean

❯ git branch -a
* main
  remotes/origin/main

❯ git branch -l
* main

❯ git branch -r
  origin/main

 

■ Conclusion



Repository default branch
Choose the default branch for your new personal repositories. You might want to change the default name due to different workflows, or because your integrations still require “master” as the default branch name. You can always change the default branch name on individual repositories.


👉 GitHub - Settings - Repositories hatena-bookmark

👉 Managing remote repositories - GitHub Docs hatena-bookmark


Android Studio Electric Eel | 2022.1.1 の JDK11 設定

一番標準的で簡単な Android Studio Electric Eel での JDK設定です。

メニューから About Android Studio で表示される内容は以下。

Build #AI-221.6008.13.2211.9477386, built on January 11, 2023


Android Studio Electric Eel | 2022.1.1
Build #AI-221.6008.13.2211.9477386, built on January 11, 2023
Runtime version: 11.0.15+0-b2043.56-8887301 x86_64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.
macOS 13.1
GC: G1 Young Generation, G1 Old Generation
Memory: 4096M
Cores: 16
Registry:
    external.system.auto.import.disabled=true
    ide.text.editor.with.preview.show.floating.toolbar=false
    documentation.show.toolbar=true

Non-Bundled Plugins:
    org.moe (1.5.2)
    org.jetbrains.compose.desktop.ide (1.2.2)
    com.jetbrains.kmm (0.5.1(221)-61)

表示されてるように Android Studio に同梱されてる JDK は OpenJDK 11.0.15 改 by JetBrains という感じでしょうか。

公式 developers.android.com には以下のように書かれています。


なので、この Android Studio に同梱された JDK を使う設定をします。

メニューから、


Settings...

  ↓

Build, Execution, Deployment

  ↓

Build Tool

  ↓

Gradle

Embedded JDK version 11.0.15 を選択します。

Android Studio Electric Eel | 2022.1.1  での JDK設定

あとは、build.gradle に以下を記述しておきます。


  compileOptions {
    sourceCompatibility JavaVersion.VERSION_11
    targetCompatibility JavaVersion.VERSION_11
  }

  kotlinOptions {
    jvmTarget = JavaVersion.VERSION_11.toString()
  }

以上です。

これが、きっと今現在では最も標準的で簡単です。

👉 【Android Studio】Settings - Build Tools - Gradle JDK の選択肢がゴミだらけで意味不明の場合 hatena-bookmark
👉 AndroidStudio 利用する Java (JDK) の選択・設定の方法 hatena-bookmark


Kotlin 1.8 で JetpackCompose を使う

Kotlin を 1.7.21 から 1.8.0 に上げます。


[versions]

# kotlin = "1.7.21"
kotlin = "1.8.0"
compose-compiler = "1.4.0-alpha02"

build します。

はい、エラーでました。


e: This version (1.4.0-alpha01) of the Compose Compiler requires Kotlin version 1.7.21
but you appear to be using Kotlin version 1.7.21 which is not known to be compatible.
Please fix your configuration (or `suppressKotlinVersionCompatibilityCheck` but don't say I didn't warn you!).
https://developer.android.com/jetpack/androidx/releases/compose-kotlin#pre-release_kotlin_compatibility

表示されてるリンクに行きます。

はい、Kotlin 1.8 ありません。

👉 Compose to Kotlin Compatibility Map  |  Android Developers hatena-bookmark

さらに、そのページにあるリンク先へ。

ここにありますね。

👉 Compose Compiler Maven Index hatena-bookmark

さらに、このページにあるリンク先の記述を参考に変更します。


# libs.versions.toml

[versions]

# kotlin = "1.7.21"
# compose-compiler = "1.4.0-alpha02" # composeOptions ↔ kotlin 1.7.21

kotlin = "1.8.0"
compose-compiler = "1.4.0-dev-k1.8.0-33c0ad36f83"


// settings.gradle

dependencyResolutionManagement {
  repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
  repositories {
    google()
    mavenCentral()

    maven {
      url "https://androidx.dev/storage/compose-compiler/repository/"
    }


// build.gradle (:app)

composeOptions {
  kotlinCompilerExtensionVersion libs.versions.compose.compiler.get()
}

👉 jimgoog/ComposeAppUsingPrereleaseComposeCompiler: Demonstrates using Compose with pre-releases of KotlinCompiler and ComposeCompiler hatena-bookmark


 

■ まとめ

Kotlin バージョンと Compose Compiler のバージョンは密接に関係しています。

ちなみに、Compose UI 側のバージョンは以前のままの alpha03 (現最新) で、まあまあ良さげです。


[versions]

kotlin = "1.8.0"
compose-compiler = "1.4.0-dev-k1.8.0-33c0ad36f83"
compose-ui = "1.4.0-alpha03"


[libraries]

compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose-ui" }
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose-ui" }
compose-ui-tooling-preview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose-ui" }
compose-ui-test-manifest = { module = "androidx.compose.ui:ui-test-manifest", version.ref = "compose-ui" }
compose-ui-test-junit4 = { module = "androidx.compose.ui:ui-test-junit4", version.ref = "compose-ui" }


dyn4j の実力を JetpackCompose wrapper Physics Layout で思い知る

やはり Java のライブラリ群を使えることは素晴らしいことです。

以下、サンプルコードを参考に Activity を書き換えます。


👉 KlassenKonstantin/ComposePhysicsLayout: A custom Compose layout backed by a physics engine hatena-bookmark





class MainActivity : ComponentActivity() {

  @SuppressLint("SourceLockedOrientationActivity")
  override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    WindowCompat.setDecorFitsSystemWindows(window, false)
    requestedOrientation = ActivityInfo.SCREEN_ORIENTATION_PORTRAIT
    setContent {
      PhysicsLayoutTheme {
        Surface(
          modifier = Modifier.fillMaxSize(),
          color = MaterialTheme.colorScheme.background
        ) {

          val simulation = rememberSimulation()
          val balls = remember { mutableStateListOf<BallMeta>() }

          GravitySensor {
            simulation.setGravity(it.copy(x = -it.x).times(3f))
          }

          LaunchedEffect(Unit) {
            var i = 0
            val count = colors.count()
            while (true) {
              balls.add(BallMeta(color = colors[i % count]))
              delay(100)
              i++
            }
          }

          LaunchedEffect(Unit) {
            delay(5000)
            while (true) {
              balls.removeFirst()
              delay(100)
            }
          }

          Box {
            PhysicsLayout(
              modifier = Modifier.systemBarsPadding(),
              simulation = simulation
            ) {

              Block(   0, -200)
              Block(-125, -100)
              Block( 125, -100)
              Block(   0,    0)
              Block(-100,  100)
              Block( 100,  100)
              Block(   0,  200)

              balls.forEach { meta ->
                Ball(0, -350, meta = meta)
              }

            }
          }

        }
      }
    }
  }
}

@Composable
fun PhysicsLayoutScope.Block(x: Int, y: Int) {
  val offset = offsetDp(x, y)
  Card(
    modifier = Modifier
      .body(
        isStatic = true,
        initialTranslation =  offset
      )
  ) {
    Spacer(
      modifier = Modifier
        .size(62.dp)
        .background(color = Color.Gray)
    )
  }
}

@Composable
fun PhysicsLayoutScope.Ball(x: Int, y: Int, meta: BallMeta) {

  val initialOffset = offsetDp(x, y)

  Card(
    modifier = Modifier.body(
      id = meta.id,
      shape = RoundedCornerShape(meta.corner),
      initialTranslation = Offset(initialOffset.x, initialOffset.y),
      initialImpulse = Offset((Random.nextFloat() - 0.5f) * 2, (Random.nextFloat()) * 2),
    ),
    shape = RoundedCornerShape(meta.corner),
    colors = CardDefaults.cardColors(containerColor = meta.color)
  ) {
    Icon(
      modifier = Modifier
        .size(32.dp)
        .padding(4.dp),
      imageVector = Icons.Rounded.Rocket,
      contentDescription = null,
      tint = Color.White
    )
  }
}

@Composable
fun offsetDp(x: Int, y: Int) = with(LocalDensity.current) { Offset(x.dp.toPx(), y.dp.toPx()) }


@Immutable
data class BallMeta(
  val id: String = System.currentTimeMillis().toString(),
  val color: Color,
  val corner: Int = listOf(0, 50).shuffled()[0]
)

private val colors = listOf(
  Color(0xFFEF5350), Color(0xFFEC407A), Color(0xFFAB47BC), Color(0xFF7E57C2),
  Color(0xFF29B6FC), Color(0xFF26C6DA), Color(0xFF26A69A), Color(0xFF66BB6A),
  Color(0xFF9CCC65), Color(0xFFD4E157), Color(0xFFFFEE58), Color(0xFFFFCA28),
  Color(0xFFFFA726), Color(0xFFFF7043), Color(0xFF8D6E63), Color(0xFFBDBDBD),
  Color(0xFF78909C)
)

強力です。

👉 dyn4j hatena-bookmark
👉 【Jetpack Compose】dp / px / sp の相互変換 hatena-bookmark




【macOS】キーマップとキーボードショートカットの変更設定

最近では、macOS ユーザーは、いくつもの重なって設定されたショートカット機能を「ほぼ無意識」にキーボードから操作することになっています。

当然、衝突したり、意図しない機能が発動されることも多くなります。

まずは、設定箇所をはっきり把握しておきたいです。

 

■ OS 設定 キーボードショートカット「修飾キー」

修飾キー (Modifier Keys) の、それぞれの機能を入れ替えたり、無効化することができます。


System Settings

  ↓

Keyboard

  ↓

Keyboard Shortcuts…

  ↓

Modifier Keys

👉 Macで修飾キーの動作を変更する - Apple サポート (日本) hatena-bookmark

 

■ キーマップ変更アプリ

修飾キー を含めたいろいろなショートカットを作成できます。⌘(command)⇧(shift) キーの左右個別の機能振り分けやカーソルキー、Fn キーなど細かく設定できるサードパーティのアプリです。

有名な2つを挙げておきます。ソースコードはともに GitHub で公開されています。無料です。

👉 Karabiner-Elements hatena-bookmark

👉 ⌘英かな hatena-bookmark

私は、⌘英かな を利用して、英数 ↔ かな の切り替えと カーソルキー のショートカット作成で使用しています。

👉 【macOS】IDE で 矢印 (カーソルキー) を使うと キーボード ホームポジション がずれる件 hatena-bookmark

 

■ OS 設定 キーボードショートカット「アプリショートカット」

OSの設定からアプリごとにショートカットを設定できます。


System Settings

  ↓

Keyboard

  ↓

Keyboard Shortcuts…

  ↓

App Shortcuts

  ↓

All Applications


👉 Mac のキーボードショートカット - Apple サポート (日本) hatena-bookmark

ショートカットに振り分ける機能の名称に関しては、スペースや大文字小文字などきちんと入力する必要があります。そこが面倒です。機能 - 名称 の一覧とかどこかにないでしょうかね。

👉 【macOS】キーボードショートカットの変更は言語設定別でイヤだ!! hatena-bookmark

 

■ 各アプリの設定

ブラウザ や エディタ、IDE など、インストールしたアプリ内の設定からもショートカットの設定ができます。

以下、Android Studio のデフォルトのショートカット。


👉 キーボード ショートカット  |  Android デベロッパー  |  Android Developers hatena-bookmark

Android Studio では、設定から、個別にショートカットの変更ができますが、それらの詰め合わせとなったIDEAプラグインをインストールしてまとめて変更することもできます。

👉 IdeaVim - IntelliJ IDEs Plugin | Marketplace hatena-bookmark
👉 VSCode Keymap - IntelliJ IDEs Plugin | Marketplace hatena-bookmark
👉 macOS For All - IntelliJ IDEs Plugin | Marketplace hatena-bookmark
👉 Emacs Keymap - IntelliJ IDEs Plugin | Marketplace hatena-bookmark

以下、Chrome のデフォルトのショートカット。

👉 Chrome のキーボード ショートカット - パソコン - Google Chrome ヘルプ hatena-bookmark

Chrome では、設定 - エクステンション - ショートカット


chrome://extensions/shortcuts

から、個別のアプリに対してのショートカットを変更できますが、これも以下のような Chrome エクステンションをインストールすると設定しやすいです。

👉 AutoControl: Keyboard shortcut, Mouse gesture - Chrome Web Store hatena-bookmark
👉 Shortkeys (Custom Keyboard Shortcuts) - Chrome Web Store hatena-bookmark
👉 Disable keyboard shortcuts - Chrome Web Store hatena-bookmark

 

■ まとめ

不必要にショートカットをカスタムするのはやめたほうが良さげ。

最小限のカスタムで今の段階でメモ。


1. os settings keyboard modifier keys

  caps lock → control


2. ⌘英かな (os app)

  left command → 英数
  right command → かな
  control + p → arrow up
  control + n → arrow down
  control + f → arrow right
  control + b → arrow left


3. os settings keyboard app shortcuts

  command + v → Paste and Match Style
  shift + command + v → Paste

  ※ Notes.app 向けに paste 2つを入れ替える。


4. app settings

  - Android Studio
    Settings… - Keymap
    → macOS のままにする

  - Chrome
    disable shortcut (chrome extension)
      command + p → Do nothing
      command + d → Do nothing
      command + s → Do nothing

    ※ 英かな切り替え直後の意図しない動作を防ぐ。

指がホームポジションから離れることがずっと気になっていました。

キーマップを自由にカスタマイズできる ⌘英かなKarabiner-Elements を使うことで カーソルキーを使った範囲選択が shift + control + p/n/f/b でできるようになったことで IDEA/Android Studio 上でエディタの Keymap を デフォルトである macOS のまま利用できるようになったことがうれしい。

衝突の警告が多少出ているが、追って調整していけば問題ないでしょう。