なぜ Android Studio のコピーは使いづらいのか? - 「常にプレーンテキストでコピーする」設定方法

Android Studio でテキストをコピーすると、コードの色やフォントなどの装飾(リッチテキスト)が一緒についてきます。

一見便利に見えますが、Slack やドキュメントに貼り付けたとき、意図せずスタイルが保持されてしまい、かえって見づらくなります。

特に、コードをブログやチャットに共有する場合、「ただのテキストとして貼りたいだけなのに……」という不満が出やすいです。

この問題は、標準のコピー操作(Cmd+C / Ctrl+C)がリッチテキスト形式を優先していることに起因しています。

 

🤔「常にプレーンテキストでコピーする」設定方法

この挙動は設定から変更可能です。Android Studio の Preferences(または Settings)を開いて、次の手順で設定を変えましょう:

1. メニューから Editor → General → Smart Keys に移動

2.「Copy as rich text」のチェックを外す

これで、今後 Cmd+C / Ctrl+C を押した際にも、余計な装飾を含まないプレーンテキストとしてコピーされるようになります。

特別なショートカットを使わなくても、普段通りの操作でコードだけをきれいにコピーできるので、ストレスが激減します。

 

🤔 コード共有の効率を上げるために

この設定変更は、日常的にコードを共有する開発者にとって大きなメリットになります。

Markdown に貼るとき、Google ドキュメントや Notion に記録するとき、いちいち「Copy as Plain Text」を選ぶ必要がなくなるため、作業効率が向上します。

また、受け取った側も余計なスタイルに惑わされず、コードそのものを読みやすくなります。

Android Studio はデフォルトで「見た目のきれいさ」を重視しますが、実際の開発現場では「シンプルで確実な共有」が求められる場面も多いです。

このような小さな設定変更が、日々の開発体験を大きく快適にしてくれます。

 

🤔 まとめ:小さな設定で大きな快適さを

Android Studio のコピー動作は、初期設定のままだと意図しないリッチテキスト形式でのコピーとなり、共有時に不便を感じがちです。

しかし、「Copy as rich text」のチェックを外すだけで、常にプレーンテキストとしてコピーできるようになり、

コード共有が格段にスムーズになります。

日々のちょっとしたストレスを減らし、開発に集中するためにも、ぜひ一度この設定を見直してみてください。


Mac OS Sequoia 15.4 で Android Studio を含む IDEA系 IDE が起動できないとかクラッシュの件

いろいろ問題起きてます。

Android Studio など IDEA Intellij 系 IDE すべて起動できない。

 

🤔 JBR の入れ替え

同梱されているブートに利用されているJBRを変えなさい、と。

👉 IntelliJ-based apps (and Fleet) crashes on macOS 15.4 Beta 3 (developer beta) : JBR-8422

仕方なく記述されているリンクから入れる。

👉 Mac に Homebrew で OpenJDK11 を インストール する


❯ java -version
openjdk version "21.0.6" 2025-01-21
OpenJDK Runtime Environment JBR-21.0.6+9-895.105-jcef (build 21.0.6+9-b895.105)
OpenJDK 64-Bit Server VM JBR-21.0.6+9-895.105-jcef (build 21.0.6+9-b895.105, mixed mode, sharing)

私の場合これだけでは起動できませんでした。

 

🤔 Sequoia 新機能 キーボードショートカット

便利な新機能なのですが。


これが影響していました。

すべて OFF に。

👉 IDEa crashes at startup on macOS if macOS keyboard shortcuts for Window tiling have been changed : JBR-8562

これでいけた。

いったん OS ログアウトするといけるようになる。

 

🤔 まとめ

2つの問題を乗り越えてやっと起動できるようになりました。

まだ待ったほういいかもしれん。

他にもいろいろありそう。

 

🧑🏻‍💻 追記: 2025-04-23

👉 【Fixed】Android Studio startup crashes on macOS 15.4 Sequoia


GitHub + SSH で複数アカウント切替え

Git HTTPS Credential Helper がややこしいので SSH に切り替える。

GitHub リポジトリを指す remote origin の変更が必要となりますので、ざっくり概要を見ておきます。


# HTTPS 利用していたとする
git remote -v
> origin https://github.com/OWNER/REPOSITORY.git (fetch)
> origin https://github.com/OWNER/REPOSITORY.git (push)

# SSH 形式の URL に変更
git remote set-url origin [email protected]:OWNER/REPOSITORY.git

# 確認
git remote -v
# Verify new remote URL
> origin [email protected]:OWNER/REPOSITORY.git (fetch)
> origin [email protected]:OWNER/REPOSITORY.git (push)

👉 リモートリポジトリを管理する - GitHub Docs

🧑🏻‍💻 手順

1. 鍵をPC側で作成。


❯ ssh-keygen -t ed25519 -C [email protected] -f ~/.ssh/id_ed25519_main

👉 新しい SSH キーを生成して ssh-agent に追加する - GitHub Docs

2. GitHub にログインして貼る。Authentication keys


❯ pbcopy < ~/.ssh/id_ed25519_main.pub

👉 SSH and GPG keys - GitHub

3. ~/.ssh/config を設定する。


❯ vi ~/.ssh/config

Host github-main
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_ed25519_main
  TCPKeepAlive yes
  IdentitiesOnly yes # need for multiple accounts

Host github-sub
  HostName github.com
  User git
  Port 22
  IdentityFile ~/.ssh/id_ed25519_sub
  TCPKeepAlive yes
  IdentitiesOnly yes # need for multiple accounts

4. PC側プロジェクト内で remote origin を書き換える。


git@github-main:your-main/Sample.git


❯ git remote -v
origin https://github.com/your-main/Sample.git (fetch)
origin https://github.com/your-main/Sample.git (push)

❯ git remote set-url origin git@github-main:your-main/Sample.git

❯ git remote -v
origin git@github-main:your-main/Sample.git (fetch)
origin git@github-main:your-main/Sample.git  (push)

❯ cat .git/config
[remote "origin"]
url = git@github-main:your-main/Sample.git
fetch = +refs/heads/*:refs/remotes/origin/*

5. 接続を確認する。


❯ ssh -T git@github-main
Hi your-main! You've successfully authenticated, but GitHub does not provide shell access.

👉 [備忘] 複数Githubアカウントでssh接続設定(config)を使い分ける手順 #GitHub - Qiita

 

🧑🏻‍💻 まとめ

URL 記述部分は、ssh:// がついてるほうが意味が分かりやすい気がします。

その場合は ~/.ssh/config の port 22 の記述は不要のようですが、

現在 GitHub ではスキーマ部分消えています。

などとダラダラ書きましたが、以下読んでみるとよく分かります。

👉 Multiple GitHub Accounts & SSH Config - Stack Overflow
👉 Using multiple github accounts with ssh keys
👉 【Git】Obsidian を GitHub と連携する
👉 初心者向け Git コマンドと領域の移動をシーケンス図で書いてみた


【Jetpack Compose】回転するアニメーションの作り方

これ、おもしろい!!




👉 回転おじさん - Facebook

ちょっと画像をお借りして、

やってみましたが、、、


@Composable
fun Humans() {
  var currentRotation by remember { mutableFloatStateOf(0f) }
  val rotation = remember { Animatable(currentRotation) }

  LaunchedEffect(Unit) {
    rotation.animateTo(
      targetValue = currentRotation + 360f,
      animationSpec = infiniteRepeatable(
        animation = tween(3000, easing = LinearEasing),
        repeatMode = RepeatMode.Restart
      )
    ) {
      currentRotation = rotation.value
    }
  }
  Image(
    modifier = Modifier
      .fillMaxSize()
      .rotate(rotation.value)
      .aspectRatio(1.0f),
    painter = painterResource(R.drawable.humans),
    contentDescription = null
  )
}

ダメでした。。。

なんで、おじさんが走ってくれないのでしょうかー。


【Jetpack Compose】@Composable のライフサイクルをシンプルに使うには DisposableEffect

なんか、いろんな方法があるんだなあ、と。

👉 Lifecycle を Compose と統合する  |  App architecture  |  Android Developers

👉 ComposeでLifecycleを監視する(2023年9月バージョン) - Kenji Abe - Medium

いろいろ試しながらどこから使っていくのがいいか。を考える。

 

🤔 参考になるコードたち

調べてみると、

DisposableEffect を中心に考えるのがいいだろう、

と思える。


@Composable
fun LifecycleEffect(
  onCreate: () -> Unit = { },
  onStart: () -> Unit = { },
  onResume: () -> Unit = { },
  onPause: () -> Unit = { },
  onStop: () -> Unit = { },
  onDestroy: () -> Unit = { },
  onAny: () -> Unit = { }
) {
  val lifecycleOwner = LocalLifecycleOwner.current
  DisposableEffect(lifecycleOwner) {
    val observer = LifecycleEventObserver { _, event ->
      when (event) {
        Event.ON_CREATE -> onCreate()
        Event.ON_START -> onStart()
        Event.ON_RESUME -> onResume()
        Event.ON_PAUSE -> onPause()
        Event.ON_STOP -> onStop()
        Event.ON_DESTROY -> onDestroy()
        Event.ON_ANY -> onAny()
      }
    }
    lifecycleOwner.lifecycle.addObserver(observer)
    onDispose {
      lifecycleOwner.lifecycle.removeObserver(observer)
    }
  }
}

👉 PatchNote-Android/app/src/main/java/com/easyhz/patchnote/core/common/util/Lifecycle.kt at e24ff1d32831b54177348e079412c95b17e3f0f4 · easyhz/PatchNote-Android


@Composable
fun LifecycleEffect(
  lifecycleOwner: LifecycleOwner = LocalLifecycleOwner.current,
  onStart: (suspend () -> Unit)? = null,
  onPause: (suspend () -> Unit)? = null,
  onStop: (suspend () -> Unit)? = null
) {
  val scope = rememberCoroutineScope()
  val currentOnStart by rememberUpdatedState(onStart)
  val currentOnPause by rememberUpdatedState(onPause)
  val currentOnStop by rememberUpdatedState(onStop)

  DisposableEffect(lifecycleOwner) {
    val observer = LifecycleEventObserver { _, event ->
      scope.launch {
        when (event) {
          Lifecycle.Event.ON_START -> currentOnStart?.invoke()
          Lifecycle.Event.ON_PAUSE -> currentOnPause?.invoke()
          Lifecycle.Event.ON_STOP -> currentOnStop?.invoke()
          else -> {}
        }
      }
    }
    lifecycleOwner.lifecycle.addObserver(observer)

    onDispose {
      lifecycleOwner.lifecycle.removeObserver(observer)
    }
  }
}

👉 itunes/app/src/main/java/com/simgesengun/itunes/ui/launchedEffect/LifecycleEffect.kt at cc63faa4eb78f22a7e2e8b95c78e1ca30f4f11ad · simgesengun/itunes


@Immutable
enum class LifecycleEvent {
  OnStop
}

@Immutable
data class LifecycleHandler(
  val id: String,
  val event: LifecycleEvent,
  val onEvent: () -> Unit
)

@Composable
fun <R : Any> DestinationScope<R>.LifecycleEffect(
  event: LifecycleEvent,
  onEvent: () -> Unit
) {
  val id = remember { randomUUID() }
  DisposableEffect(this, id, event, onEvent) {
    navigator.update {
      it.copy(lifecycleHandlers = it.lifecycleHandlers + LifecycleHandler(
        id = id,
        event = event,
        onEvent = onEvent
      ))
    }
    onDispose {
      navigator.update { dest ->
        dest.copy(lifecycleHandlers = dest.lifecycleHandlers.filter { it.id != id })
      }
    }
  }
}

👉 showcase/common/src/iosMain/kotlin/dev/ahmedmourad/showcase/common/navigation/LifecycleHandler.kt at 83cc58c29acc2dc3bbcc4de0644e79e74826514e · AhmedMourad0/showcase

 

🤔 まとめ

まずは、ここらから記述していくのがいいのではないか。


@Composable
@NonRestartableComposable
fun DisposableLifecycleEffect(
  lifecycle: Lifecycle = LocalLifecycleOwner.current.lifecycle,
  onResume: () -> Unit,
  onPause: () -> Unit,
) {
  DisposableEffect(lifecycle) {
    val observer = LifecycleEventObserver { _, event ->
      when (event) {
        Lifecycle.Event.ON_RESUME -> onResume()
        Lifecycle.Event.ON_PAUSE -> onPause()
        else -> { }
      }
    }
    lifecycle.addObserver(observer)
    onDispose {
      lifecycle.removeObserver(observer)
    }
  }
}

👉 florisboard/app/src/main/kotlin/dev/patrickgold/florisboard/lib/compose/DisposableLifecycleEffect.kt at 35fd70ce6d2de05cf8be44fcd9a16b3b6d537453 · florisboard/florisboard

記述位置は Screen。

@NonRestartableComposable の意味を考えながら書く。

フォアグラウンド、バックグラウンドの切り分けにも使えるか。