多段SSHで入った計算サーバでJupyter Notebookをリモート起動＆Tab連打で補完

#概要
最近Jupyter Notebookを使い始めたが、計算サーバのブラウザでJupyter Notebookを起動するとカクカクするのでローカルのブラウザから起動する方法を調べた。
また、Tab補完の際に上下キーを押さないといけないのが嫌だったが、その回避法も見つけたのでメモを残す。

#環境
ローカル：Windows10
サーバ：Scientific Linux release 6.9 (Carbon)
Anaconda3-2018.12

#設定
計算サーバ上の設定から。
まずJupyter Notebookの設定ファイルを作成。

```
jupyter notebook --generate-config
```

次にパスワードの設定を行う。IPythonを起動して

```
from notebook.auth import passwd
passwd()
```
と入力。パスワードを二回（確認用含む）入力すると"sha1:"からはじまるハッシュ値が出力されるのでコピーしておく。
続いて作成した設定ファイルに以下を追記。

```~/.jupyter/jupyter_notebook_config.py
c.IPKernelApp.pylab = 'inline'
c.NotebookApp.ip = '0.0.0.0'
c.NotebookApp.open_browser = False
c.NotebookApp.port = 9000
c.NotebookApp.passwd = u'sha1:****************************************'
c.NotebookApp.notebook_dir = '/work/*user*/'
```

最終行はJupyter Notebookの起動時ディレクトリの設定なのでデフォルトでよければ書かなくてもいい。「c.NotebookApp.port」の数字もなんでもいいが、あとで使うので覚えておく。

以上でサーバー側の準備は完了。続いてローカルの設定では~/.ssh/configで以下のように記述する。

```~/.ssh/config
Host palpha
    HostName alpha.example.com
    Port 22
    User mura
    GatewayPorts yes
    LocalForward 10023 alpha.example.com:10023
    PasswordAuthentication yes

Host pbeta
    HostName beta.example.com
    Port 22
    User mura
    GatewayPorts yes
    LocalForward 10023 beta.example.com:10023
    PasswordAuthentication yes
    ProxyCommand ssh -W %h:%p palpha

Host pgamma
    HostName gamma.example.com
    Port 22
    User mura
    GatewayPorts yes
    LocalForward 10023 gamma.example.com:9000
    PasswordAuthentication yes
    ProxyCommand ssh -W %h:%p pbeta
```

環境は[前の記事](https://qiita.com/hete_mura/items/b479e065b7a8ba5c9ce9 "2段のサーバを経由してWinSCPを使う")と同じである。pgammaのLocalForward行の最後の数字は上の設定ファイルの「c.NotebookApp.port」の数字と合わせる。

続いて次のようにコマンドを打ってJupyter Notebookを起動する。

```
# pgammaでログインする
ssh pgamma
jupyter notebook
```

あとはローカルのChromeとかで「localhost:10023」にアクセスすればJupyter Notebookのトークン入力画面になる。
サクサク動くので非常に快適！

#Tab補完について
Jupyter Notebookではコードを書いているときにTabキーを押すと補完候補を表示させることができるが、そのあとTabキーをさらに押してもカーソルは動かず、補完候補を選択するために上下キーかマウスを使う必要がある。
この仕様がどうしても気になったのでいろいろ調べているとまさにこれ！という拡張機能をみつけることができた。

[jupyter-tab-autocomplete-cycle](https://github.com/ryantam626/jupyter-tab-autocomplete-cycle)

導入方法をメモしておく。

まずnbextensionsを使えるようにする。以下サーバ上でのコマンド。

```
conda install jupyter_contrib_nbextensions
```

つづいてgithubからファイルをとってくる。[このページ](https://qiita.com/flmil/items/2a2114bc73ec2a6f5e90 "git cloneしようとした時でたエラーと戦った話")のようにgit cloneでエラーが出る場合があるが、そのときはSSH鍵の設定をすればよい。100行程度のコードなので直接Web上でコピーでもいいような気がするが…

```
git clone git@github.com:ryantam626/jupyter-tab-autocomplete-cycle.git
```

インストール法はryantam626さんのページにもあるが、tab-autocomplete-cycleというディレクトリが含まれるディレクトリから以下のようにコマンドを入力すれば完了。

```
jupyter nbextension install tab-autocomplete-cycle --user
jupyter nbextension enable tab-autocomplete-cycle/main --user
```

これでJupyter Notebookを起動して補完画面をTabキーで呼び出した後につづけてTabキーを押すことでカーソルを移動させることができる。いきすぎたらShift + Tabで上にも上がれる。


非常に便利な拡張機能だと思うのだが、微妙にバグ？を確認していて、候補が一つしかないものをTab補完で自動入力した後に再度Tabを押しても補完が表示されないというものがある。
ディレクトリを補完で入力するときなんかがわかりやすくて、

```
cd /work/hogeho # Tabを押す
cd /work/hogehoge/ # hogehoge/まで入力される。ここでTabを押しても
cd /work/hogehoge/fugafuga # これは表示されない（そもそも補完候補画面が出ない）
```
このようになる。IPythonではちゃんとfugafugaの補完も表示されるだけあって微妙に気になるところではある。


#参考
https://qiita.com/syo_cream/items/05553b41277523a131fd
https://qiita.com/lasta/items/41e95a2fdded18c34dae