VSCode・インテリセンスが効かない？を解消

マイクロソフトのインテリセンス（コード補完機能）は大変優秀だと個人的に思っている。
中でもVBAのインテリセンスが非常に優秀で
インテリセンスを効かせた書き方を意識して以降、生産性が数倍になった。

VSCodeでもインテリセンスの優秀さを引き継いでいるのか、
動的型付け言語のPythonでもバンバン補完機能を表示してくれる。

…が、特定のパターンでインテリセンスが出てこないことに気が付いた。
VSCodeでインテリセンスが効かない＆一部に効かない場合の
解消方法を調査＆検証した結果を整理してみた。

#前提条件
 - VSCode 1.33.1
 - CentOS7.6 64bit
 - anaconda 4.6.14
 - Python 3.7.3

#発生事象
外部モジュールをVSCodeが参照できていない模様
以下では、比較のため「標準モジュールの場合（問題なし）」と「外部モジュールの場合（問題あり）」を記載
##標準モジュールの場合（問題なし）
 - インテリセンスが有効
 - あるべき姿、ありがたや

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/fa519d7f-ba39-5392-b325-979970bee31e.png)

## 外部モジュールの場合（問題あり）
外部モジュールのインテリセンスに関して、事象が2つ発生。
<b>1. インテリセンスが完全に表示されないケース</b><br>&nbsp;&nbsp;&nbsp;&nbsp;これは、VSCode上で.を打った以降、候補が完全に表示されないのでわかりやすい（参考画像なし）<br>
<b>2. 一部インテリセンスの候補がおかしいケース</b><br>&nbsp;&nbsp;&nbsp;&nbsp;下図がその事例。</br>
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/d1c6342d-d62e-e2af-26d3-f695529e94d3.png)
&nbsp;&nbsp;&nbsp;&nbsp;本来、pyarrow.parquetモジュールは`write_`と入力すれば<br>&nbsp;&nbsp;&nbsp;&nbsp;`write_table`、`write_to_dataset`、`write_metadata`と<br>&nbsp;&nbsp;&nbsp;&nbsp;<b>`write_`から始まるファンクションが<font color="Red">3つ</font>表示されるはず</b>だが</br><br>&nbsp;&nbsp;&nbsp;&nbsp;なぜか表示されずに`_parquet_writer_arg_docs`という<font color="Red">見当違いの候補が出る。</font><br>&nbsp;&nbsp;&nbsp;&nbsp;このエラーは、モジュールのドキュメントとインテリセンスを見比べないと発見できない。<br>&nbsp;&nbsp;&nbsp;&nbsp;「なんで効かないんだろ？でもコードは動くからいいか…」で見過ごすユーザーもいると思う[^1]。


##原因と対策
<b>【原因】インテリセンスが効かない事象は、VSCodeの初期設定値が原因
</b>1. 初期値では、外部モジュールのパス指定がない（故に認識できていない）
2. 初期値のインテリセンスエンジン（jedi）がうまく動かない[^2]

<b>【対策】VSCodeの設定ファイル（settings.json）を2か所変更
</b>1. インテリセンス参照先に、外部モジュールのパスを追記
2. インテリセンスエンジンをMicroSoft Language Serverに変更

#手順
ここからは、インテリセンスを有効化するための手順を解説
### 1. 外部モジュールのパスを確認

```terminal:terminal
$ sudo find -name "pyarrow"
./home/myuser/.conda/envs/py3.7/lib/python3.7/site-packages/pyarrow
./home/myuser/.conda/pkgs/pyarrow-0.11.1-py37he6710b0_0/lib/python3.7/site-packages/pyarrow
find: ‘./run/user/1000/gvfs’: 許可がありません
$

```
2つあるけど、どちらも```site-packages/```配下が共通のようなので↓を登録してみる
```./home/myuser/.conda/envs/py3.7/lib/python3.7/site-packages/pyarrow```

### 2. 設定ファイル（settings.json）を編集
①ファイル -> ②基本設定 -> ③設定 -> ④設定の検索　に python.autoComplete.extraPaths と入力
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/215da71c-10c2-1818-82d6-9ec70a3e5087.png)

④のあと、settings.jsonをクリック、json形式でパスを記述。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/f2f1b04e-8c19-1392-d552-cd74a97909eb.png)

記述例を2つ挙げます。
ここでは、外部パスの記述と同時に、インテリセンスエンジンにjediを利用しない設定も記述してます
【例1】・・・完全に初期状態での記述の場合↓


```json:settings.json
{
    "python.autoComplete.extraPaths": [
        "/home/myuser/.conda/envs/py3.7/lib/python3.7/site-packages/"
    ],
    "python.jediEnabled": false
}
```
【例2】・・・複数の既存設定がある場合（カンマ区切りで追加。末尾でなくてもよい）↓

```json:settings.json
{
    "既存項目Ａ": false,
    "既存項目Ｂ": true,
    "既存項目Ｃ": [
        "Ｃの内容"
    ],
    "python.autoComplete.extraPaths": [
        "~.conda/envs/py3.7/lib/python3.7/site-packages/"
    ],
    "python.jediEnabled": false
}
```
###3. 保存
赤丸部分にカーソル合わせると×ボタンになる。
×ボタン押下し閉じるときに保存を選択
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/7273ea5d-89c0-c9b1-d9f0-53e14f704124.png)



###4. 結果確認
VSCodeを再起動後、インテリセンスの挙動を確認する。
外部モジュールでも、インテリセンスが無事に表示された。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/389667/c75ea57a-f183-2ac6-ac9d-b79840f5a848.png)

※下記に個人設定を記述したので、参考になれば幸いです


## 個人メモ【VSCodeの設定】
- <b>インテリセンス</b>
    - 外部モジュールパス：`"python.autoComplete.extraPaths"`
        - condaで作成した仮想環境下のライブラリを指定`"~.conda/envs/py3.7/lib/python3.7"`など
        - zip圧縮されたモジュールも読込対象とするため、拡張子.zipも記述
- <b>flake8（コードフォーマット）の設定</b>
    - 有効/無効：`"python.linting.flake8Enabled"`
        - `true` で有効
    - フォーマット設定：`"python.linting.flake8Args"`
        - `"--ignore=E501"`で、1行の記述文字長制限を外す
- <b>エディタの設定</b>
    - フォントサイズ：`"editor.fontSize"`
        - 14ポイントに設定（解像度の関係で大き目にした）
    - 保存時のフォーマット自動成型：`"editor.formatOnSave"`
        - `true`で有効
- <b>condaコマンドの設定</b>
    - condaのパス：`"python.condaPath"`
        - `"/usr/local/anaconda3/bin/conda"`を指定　※人によって違います
- <b>インテリセンスエンジンの設定</b>
    - エンジンにjediを利用するか：`"python.jediEnabled"`
        - `false` でエンジンはMicroSoft Language Serverに変更

```json:settings.json
{
    "python.autoComplete.extraPaths": [
        "~.conda/envs/py3.7/lib/python3.7/lib-dynload",
        "~.conda/envs/py3.7/lib/python3.7/site-packages"
    ],
    "python.pythonPath": "python",
    "python.jediEnabled": false,
    "python.linting.flake8Enabled": true,
    "editor.formatOnSave": true,
    "python.autoComplete.addBrackets": true,
    "python.linting.flake8Args": [
        "--ignore=E501"
    ],
    "editor.fontSize": 14,
    "python.analysis.symbolsHierarchyDepthLimit": 20,
    "python.condaPath": "/usr/local/anaconda3/bin/conda",
    "terminal.integrated.rendererType": "dom"
}
```

#参考
 - [VS CodeでPythonプログラムを快適コーディング！](https://www.atmarkit.co.jp/ait/articles/1805/29/news031.html)
 - [Editing Python in Visual Studio Code](https://code.visualstudio.com/docs/python/editing#_autocomplete-and-intellisense)

 - 一部外部モジュールの認識エラーについては、下記のqiitaの記事を参考にしました。
    - [Enable python intellisense for Visual Studio Code.]
(https://qiita.com/null_Y_K/items/b208a0049d1acd4a3ead)


[^1]: ドキュメントの記述とインテリセンスの候補が違うことに数日悩みました…
[^2]: 僕の環境下ではたまたま動かなかった可能性があります。jediから切り替えたことで、<br>逆に標準モジュールのインテリセンスが一部表示されなくなったので、悩ましいところです。<br>※osモジュールやtypingモジュールのNoReturnなど、一部がインテリセンス効かなくなりました。