PyCharmでは未importのクラスや関数の入力補完ができない、と思い込んでいた話

# TL;DR

**PyCharmではCtrlを押したままSpaceを2回叩くと幸せになれる**

# PyCharmが大好き、でも

Pythonは2.7あたりの頃から使っていて、作業効率化ツール開発や[pyserial](https://github.com/pyserial/pyserial)を使った組み込み機器との通信テストなどで使用していました。当初からわりと規模が大きめなプロジェクトで使っていたので、対話シェルやコマンドラインベースではなく、[PyCharm](https://www.jetbrains.com/ja-jp/pycharm/)のお世話になりながらPythonと付き合ってきました。

私はAndroidアプリ開発もやってますが、[Android Studio](https://developer.android.com/studio/intro?hl=ja)ができる前から[Eclipse+ADT](http://www.cutt.jp/books/978-4-87783-351-0/supp/chap00_ADT-gt-and-start.html)を窓から投げ捨て[IntelliJ IDEA](https://www.jetbrains.com/ja-jp/idea/)を採用していたので、JetBrains IDEにかなり親しみを持っており、その操作感覚を引き継げるPyCharmでの開発は本当に本当に大好きでした。

ただ、ある一点を除いては・・・

# 他のJetBrains IDEと同じような感覚で入力補完できない・・・？

IntelliJ（Android Studio）や[Rider](https://www.jetbrains.com/ja-jp/rider/)は、プロジェクトの依存関係を読み取って、そのプロジェクトで使用できる全てのシンボルを把握してくれます。
そのため、ソースコードの先頭に`import`（Java, Kotlin）やら`using`（C#）やらを書かずとも、プログラマがその場で入力した文字からクラス名・関数名などの入力補完のリストを構築してくれます。

これは**未importなシンボルに対しても候補を作ってくれる**というのが強いところで、プログラマはなんとな〜くクラスやグローバル関数の存在だけを覚えておき、**てきと〜に入力して候補から見つけ出す**というのを繰り返すだけで立派なコードが書けることになります。この手の機能はJetBrains IDEに限らず他のモダンなエディタにも搭載されていて、この感覚でコーディングするのが現代のプログラミングのやり方だと思います。

この機能は新しいライブラリを投入してそれについて勉強中のときにも力を発揮します。例えば、ライブラリ内のクラスが継承関係に基づいて親の名前の一部を引き継ぐ命名規則になっている場合、親の名前を入力したときに子のクラス名も一緒に候補に出てきてくれるので、「あ〜こういうクラスツリーがあるのか〜」といった具合で全体像を楽に把握することもできます。

## PyCharmでは先にimport文を書いてないと入力候補に出してくれない？

で、この未importに対する入力補完機能、**なぜかPyCharmには搭載されてない・・・** ように見えました。

例えばpipで`pyserial`を入れてきたあと、COMポートの一覧を出すための[list_ports](https://pythonhosted.org/pyserial/tools.html#module-serial.tools.list_ports)を使おうとして`lis`と入力しても、候補リストは現れてくれません。
<img width="250" alt="スクリーンショット 2020-05-30 13.09.23.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/c18841c7-38fa-d3fc-a7cf-d3764f76b409.png">
なんと実行環境を整えてたとしても、コード側では事前にいちいち`from serial.tools import list_ports`を書いておかないと`lis`の入力時点で出てきてくれないのです。
<img width="380" alt="スクリーンショット 2020-05-30 13.10.03.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/ad586d1e-62b0-d127-4499-2f09c1f3e33c.png">

**こんなのは嫌だ。面倒臭すぎる。**PyCharmは開発マシンのPython実行環境自体を認識してますから、`lis`の入力時点で`list_ports`を提案できるはずです。

ただ、Auto Importなる機能はあります。これはコード内に解決できないシンボルがあり、かつ同名のシンボルがPyCharmによって把握されている場合において、PyCharmがimport文の挿入を提案してくれるものです（まあこれも大抵のIDEには搭載されてますよね）。
この機能を使えば、`list_ports`と正確に入力すれば、ようやくimport提案をしてくれるようになります。
<img width="352" alt="スクリーンショット 2020-05-30 13.10.42.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/abdf74a5-94c8-023a-90a7-ba5f8a7e242e.png">
ちょっと私が求めてるものとは違いますが、まあ仕方なしとして、この機能を活用してPyCharmでの大規模開発を進めてきました。が、やはりこれを軸にするのは少々無理があり、少し名前を打ち間違うとimport提案してくれませんので、長い名前のクラスを使うときにはストレスでした。


# 調べてみたらできるらしい、けど

自分が最強の開発環境だと確信しているJetBrains IDEシリーズのPyCharmを使っているのに、こんな謎の苦しい思いをするなんて、絶対何かが間違っている・・・そういう引っ掛かりが昨日までありました。

友人との会話中、久しぶりにこの疑問が再燃し、数年ぶりにこの話題を調べてみました。
すると以下の公式ブログに辿り着きました（2018年の記事って・・・気付くのが遅くてショック）

> **Let PyCharm Do Your Import Janitorial Work | PyCharm Blog**
> https://blog.jetbrains.com/pycharm/2018/11/let-pycharm-do-your-import-janitorial-work/
>
> ![CtrlSpaceSpace-02.gif](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/d666fc26-7c00-4e5b-4575-8fe3bb8354c7.gif)
>
> Start typing part of requests and **type Ctrl-Space-Space**. PyCharm will offer a completion. When you accept it, PyCharm will complete the symbol and also generate the import.
> > リクエストの一部を入力して、**Ctrl-Space-Spaceと入力します**。PyCharm が補完を提示してきます。それを受け入れると、PyCharm はシンボルを完成させ、インポートを生成します。

**！？！？！？！？！？！？！？！？　まさかのショートカットキー！？！？　しかも2回！？！？**

なぜかPyCharmは他のJetBrains IDEのノリと異なり、未importモジュールに対する入力補完は自動的には表示されず、わざわざショートカットキーを2回も押さなければならないようです。

**ナンデ！？**

# 試してみたらOSのショートカットキーと衝突してた

まあ何か大人の事情があったんだろうということで、残念感は置いといて、記事の通り`Ctrl+Space+Space`（つまりCtrlを押したままSpaceを2回叩く）を実行してみると・・・
<img width="192" alt="スクリーンショット 2020-05-30 12.10.43.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/884dab9f-61ce-4900-9de8-c93e47e66322.png">
**入力ソース切り替えと被ってるやんけ・・・・**
設定をいじってオフにしましょう・・・
<img width="615" alt="スクリーンショット 2020-05-30 13.17.08.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/b793de00-3300-93ff-75ea-146eb6c482d4.png">
これでPyCharmでも他環境と同じように、ショートカットキーさえ押していれば、未importを含む全てのシンボルに対する入力補完が効くようになりました！最高！
<img width="313" alt="スクリーンショット 2020-05-30 13.12.01.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/153167/a2315233-90a6-2d5a-4f26-d2eacef17020.png">
これからは**コードを書き出す前に毎回`Ctrl+Space+Space`を2回叩くのを習慣化する**ことで、常に候補リストとともに生活し、短時間で大量のPythonコードを書き出せるようにしたいと思います。

---

しかし、なぜPyCharmだけショートカットキー必須になってるのでしょう・・・？
Pythonはアクセスコントロールがゆるゆるですから、候補リストの生成に時間かかるようになり、そこからの性能悪化を恐れてこうしたんですかね？でも最近の開発マシンなら大したことないんじゃないかなあ。
または、[アンダースコアから始まる外に見せたくないもの](https://pep8-ja.readthedocs.io/ja/latest/#id26)が積極的に見えるようになるのを嫌がったとかですかね？

ところでVSCodeでのPython環境を実は整えてないんですが、同様の機能が使えるのであればそろそろ整備したいです。PyCharmは素晴らしいものですが、ちょっとした実験コードを書くためだけに動かすのは大袈裟ですからね。

---

※この件に関してのTwitterでの愚痴：

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">えっ、、この機能2018年のPyCharmから入ってたの、、、<br>俺の2年間返してくれ…………<a href="https://t.co/MZx4UaYgsP">https://t.co/MZx4UaYgsP</a><br>&gt; Start typing part of requests and type Ctrl-Space-Space. PyCharm will offer a completion. When you accept it, PyCharm will complete the symbol and also generate the import. <a href="https://t.co/NtQeOOVGbk">pic.twitter.com/NtQeOOVGbk</a></p>&mdash; りん@Liparhythm (@links_2_3_4) <a href="https://twitter.com/links_2_3_4/status/1266327719869988864?ref_src=twsrc%5Etfw">May 29, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>