SpacemacsでPythonの自動補完やlinterなどを効かせる

基本的には[公式developブランチのドキュメント](https://github.com/syl20bnr/spacemacs/tree/develop/layers/%2Blang/python)に従う感じで。




# WSL2 Ubuntu18.04LTSでの下準備
たのんだ

cf. https://qiita.com/v2okimochi/items/f53edcf79a4b71f519b1



# Windows10で直接やる場合の下準備
## pyenv + pipenv
Pythonの仮想環境を使いたいので準備する。
pyenvでPythonバージョンを管理し、pipenvで依存ライブラリを管理する？


### pyenvインストール
http://yamap55.hatenablog.com/entry/2019/09/12/080000

環境変数周りとか、詳しく解説されている。


### pipenvインストール
https://qiita.com/youkidkk/items/b6a6e39ee3a109001c75


使い方はこれとか良さそう (基本的にPipfile用意して `pipenv install`でよしなにやって頂ける)
https://qiita.com/subarunari/items/dcbdad68ba1809b721b9






# 依存ライブラリの準備
SpacemacsのPython Layerでは、主に以下のライブラリを使う (ので、諸々の機能を使うためには予めインストールしておく必要がある)

- jedi: 自動補完の要
- epc: emacs lispでjediと繋いでいるっぽい？
- isort: 依存ライブラリを自動で並び替える
- autoflake: 使われていないライブラリを検出する
- flake8: pycodestyle + pyflakes + mccabe の動きをするらしい (参考 https://minus9d.hatenablog.com/entry/2018/10/22/235604)
    - pycodestyle: コードスタイルチェック
    - pyflakes: 静的解析 (未使用の変数を検出したり)
    - mccabe: 複雑製チェック
- yapf: 自動フォーマッター
- importmagic: 解決可能なライブラリの自動import
- pytest: テストはこれ

開発用ライブラリなので、本番環境に適用したくない場合は `pipenv install jedi -d`のように `-d`オプションをつける。

もしPipfileに記載すらしたくない場合は、 `pipenv shell`で仮想環境のPythonに入ってから `pip install jedi`のように直接インストールすればこっそり入る。





# Spacemacsの設定
## .spacemacs ( `Space f e d`)
諸々の機能を使う (フォーマットとかは保存時に実行される)。
python-backendはデフォルトだと `anaconda`、他に `lsp`も選択できるらしい。

```emacs-lisp:.spacemacs(抜粋)
dotspacemacs-configuration-layers
'(sql
  markdown
  ;; 上のsqlやmarkdownみたいな感じで以下を追記
  (python :variables
          python-backend 'lsp ; WSL2ならlsp, Winならanacondaのおきもち
          python-formatter 'yapf
          python-format-on-save t
          python-sort-imports-on-save t
          python-pipenv-activate t
          python-test-runner 'pytest)
 )

;; jedi追加
dotspacemacs-additional-packages '(jedi)

(defun dotspacemacs/user-config ()
  ;; python-modeで `jediによる自動補完`と `flake8`によるチェックを行う
  (add-hook 'python-mode-hook
            (lambda ()
              #'(flycheck-add-next-checker 'python-flake8)
              'jedi:setup))
)
```



もう1つ小話で、Spacemacs公式曰くデフォルトでflake8を使うみたいに書いてあるが、実際にはこちらで設定を加えないと機能しなかった :innocent: 
`(flycheck-add-next-checker 'python-flake8)`でflycheckの設定に手を加える必要がある


cf. https://github.com/syl20bnr/spacemacs/issues/7568#issuecomment-451684259


## Spacemacsでpython仮想環境を認識させる
`python-pipenv-activate t`については、Macだとうまく動かなかったりして怪しい (仮想環境ではなくシステム側のPythonバージョンを見に行ってしまう)。
WSL2のUbuntu18.04LTSもダメだった :innocent: :innocent: :innocent: 

Windows10では正常に動いているようで、謎。

jediで補完してくれたとしても、import文に対してflycheckが毎回 `unresolved import`エラーを吐くのはつらい。

直すためには、シンボリックリンクを張って `.venv`を生やせば良かったらしい。ありがたい。。。。。

```shell:~/でやる
ln -s .local/share/virtualenvs/ .virtualenvs
```

```shell:Pipfileがある作業ディレクトリでやる
echo "$(basename $(pipenv --venv))" > .venv
```

cf. [SpacemacsのPython Layerにpipenvで構築した仮想環境を認識させる方法](https://qiita.com/cschappert/items/c00b5b910a1179302200)


## pyrightのほうを使っても良さそう
cf. [Spacemacsでpyrightを使う](https://qiita.com/v2okimochi/items/89aceafb53c263aeed7b)


## Windows10: isortでdiffが使えなかったら
「Pythonファイルを上書き保存したのにisortが効かないな… `*Messages*`バッファを見たらdiffがないって言われるな…」な時。

```
Searching for program: No such file or directory, diff
```

「MSYS2 (またはCygwin)入れてるしGitではdiffが動いてるんだよなぁ」であれば、MSYS2から直に `diffutils`を入れる。

c.f. [<msys2, pacman> diff を入れる。](http://nekoyukimmm.hatenablog.com/entry/2015/06/02/170244)


そして、 `.spacemacs`の設定で `diff`がインストールされたディレクトリをパスに追加してあるか確認する。

パスが追加されていない場合、こういう問題が起こる (パスの追加方法も載せてある)

c.f. [Windows10上のSpacemacsでunzipを使う（外部ライブラリへ定義ジャンプしたい）](https://qiita.com/v2okimochi/items/62246f66e0626f344e06)


> Spacemacs側では C:\msys64\mingw64\binのほう (Hunspellとかが入っていた)を実行パスに加えていたので、 No such file or directoryと言われていた。  
これを解決するため、Spacemacsに実行パス C:\msys64\usr\binも指定する。  
.spacemacs ( Space f e d)の user-init()内に追記する。





# おまけ
## ipythonを使う場合
replでipython使いたいなってなったら、Spacemacsの設定に加える。
(デフォルトだと普通のpythonを使ってしまうので)

```emacs-lisp:.spacemacs(抜粋)
(defun dotspacemacs/user-config ()
  ;; シェルを開く時pythonの代わりにipythonを使う
  (setq python-shell-interpreter "ipython")
)
```

参考 https://stackoverflow.com/questions/17817019/how-to-open-ipython-interpreter-in-emacs

Python Layerの設定だけでいい感じにやってほしいな。。。と思ったが、似たような問題で議論中の模様。
https://github.com/syl20bnr/spacemacs/issues/9321