あれ、どうやったっけ

(たぶん)テキストサイト風blog。文が安定するまで書き直しあるからメンゴ。

emacsのcompanyでpowershellをcompletion speed up ver

またこの記事古くなっちゃったやで

powershell-modeのみならず(shell-mode的な意味での)powershellでも補完効くようにしますた版が……どうしてこんなことに……。

とりあえずこれで終わりにしたい、emacs + company + powershell-mode + powershell(shellのほう)でだいたい補完 - あれ、どうやったっけ

ええいもうやけくそだい

昨日というか今日の朝方? 書いたやつの高速版。emacs25.2.1@windowsで試しますた。Melpaでpowershellとcompanyいれといてください。

デフォルトだと ~/.emacs.d/ps-cache って 497kbytes くらいのファイルができると思います。それキャッシュにしますのでよろしこ。

タグの再生成は M-x company-powershell-tags-generate 。要は「Get-Command」でありったけ吐かせたものです。微調整やるならGet-Commandの「-CommandType」引数を微調整しやがれください。使えるものが全部ほしいなら -CommandType All とかそういうのです。

タグの再読み込みは M-x company-powershell-tags-reset やった後に再度補完キメて下さい。バックエンドの company-powershell 側で勝手に再読み込みします。

つまり、どっかからコマンドレットをギってきたのであれば、 M-x company-powershell-tags-generate やったあと M-x company-powershell-tags-reset でキャッシュをクリアしないと反映しませんにょってことです。しませんよって書こうと思ったんですができませんでした。

なお「experimental(実験的)」なのはご勘弁を。何分まじめにelispやり始めて……何日目? レベルなんで orz いやたぶん一週間程度は過ぎたはず、もっとか、くらい?

冗談抜きでelispはわかっておらず至らぬところがあり玄人が速攻で殺しに来てくださりそうです。あとよろしこ。昨日の僕は with-temp-buffer どころか、emacsファイル読み書きする際には一遍バッファに入れないとだめぽなんてことも知らなかった……!

あとmetaとかで関数の情報出すとかなんとかあるみたいなのですがggrksで許してください。すごくつらそうです。

Get-Commandで出る奴だけは引ける版

とにかくGet-Commandでわかるものは出ます。たぶん動いてくれると思うけど……。

(setq-default ps-cache-save-path "~/.emacs.d/ps-cache")
(setq company-powershell-tags nil)

(defun company-powershell-tags-generate ()
  "generate powershell commmand cache, cache will used by company-powershell."
  (interactive)
  (let ((ps-out ""))
    (setq ps-out (shell-command-to-string
                  (concat "powershell -Nologo -Command \"Get-Command -Name * "
                          " -CommandType Alias,Function,Filter,Cmdlet"
                          " | Format-Wide -Property Name -Column 1\"")))
    (setq ps-out (string-trim ps-out))
    (with-temp-buffer
      (insert ps-out)
      (write-region (point-min) (point-max) ps-cache-save-path))))

(defun company-powershell-tags-reset ()
  "clear current powershell command candidates cache."
  (interactive)
  (setq company-powershell-tags nil))

(defun company-powershell (command &optional arg &rest ignored)
  (interactive (list 'interactive))
  (pcase command
    (`prefix (and (eq major-mode 'powershell-mode)
                  (company-grab-symbol)))
    (`candidates
     (let ((ps-out "") (completion-ignore-case t))
       (when (not (file-exists-p ps-cache-save-path))
         (company-powershell-tags-generate))
       (when (eq company-powershell-tags nil)        
         (with-temp-buffer
           (insert-file-contents ps-cache-save-path)
           (setq ps-out (buffer-substring-no-properties (point-min) (point-max))))
         (setq company-powershell-tags (split-string ps-out)))
       (all-completions arg company-powershell-tags)))))

(add-to-list 'company-backends 'company-powershell)

こっちだと貴方自身のFunctionは M-/ で補完効かしてもらう形になるかしら。

俺が今書いてるFunctionも入れろよdabbrev超大好き版

僕みたいに 俺が書いたFunctionは当然候補じゃないとダメという方はこちら。ただ誤爆しそう。変数名とか。理想的には空気読んで変数欲しそうなときは変数名出すべき、Functionの時は当然空気読んでFunction出せかとも思うのですが諦めます。

誤爆したらマジ許して。候補に無理やりdabbrev-codeの結果もネジこみましたということです orz

でこんな感じ。

(require 'company-dabbrev-code)

(setq-default ps-cache-save-path "~/.emacs.d/ps-cache")
(setq company-powershell-tags nil)

(defun company-powershell-tags-generate ()
  "generate powershell commmand cache, cache will used by company-powershell."
  (interactive)
  (let ((ps-out ""))
    (setq ps-out (shell-command-to-string
                  (concat "powershell -Nologo -Command \"Get-Command -Name * "
                          " -CommandType Alias,Function,Filter,Cmdlet"
                          " | Format-Wide -Property Name -Column 1\"")))
    (setq ps-out (string-trim ps-out))
    (with-temp-buffer
      (insert ps-out)
      (write-region (point-min) (point-max) ps-cache-save-path))))

(defun company-powershell-tags-reset ()
  "clear current powershell command candidates cache."
  (interactive)
  (setq company-powershell-tags nil))

(defun company-powershell (command &optional arg &rest ignored)
  (interactive (list 'interactive))
  (pcase command
    (`prefix (and (eq major-mode 'powershell-mode)
                  (company-grab-symbol)))
    (`candidates
     (let ((ps-out "") (final-completion-tags nil) (completion-ignore-case t))
       (when (not (file-exists-p ps-cache-save-path))
         (company-powershell-tags-generate))
       (when (eq company-powershell-tags nil)        
         (with-temp-buffer
           (insert-file-contents ps-cache-save-path)
           (setq ps-out (buffer-substring-no-properties (point-min) (point-max))))
         (setq company-powershell-tags (split-string ps-out)))
       (setq final-completion-tags (copy-alist company-powershell-tags))
       (setq final-completion-tags (append final-completion-tags
                                           (delete-dups (company-dabbrev-code 'candidates arg))))
       (all-completions arg final-completion-tags)))))

(add-to-list 'company-backends 'company-powershell)

f:id:osaka_zumai:20171121030421j:plain

そんなのでいいのだろうか。でもcompanyは初めに当たった候補見つけたらそこで終了してくれるっぽいからこっちからすると \(^o^)/オワタ (今知ってる知識では)そうするしかないんだ!

……なんか方法はありそうな気もするんですが、今のところわからん。不勉強で申し訳ない。

どうしてこんなことに…… CV: かばんちゃん

特定のディレクトリ指定したらdos2unixコマンドを流す程度のスクリプト書こうと思ったんですよ。

emacspowershell-modeするとコマンド名とかコマンドレット? だっけ? 出ないしまじわかんない、うけるーwww vs PowerShell ISEとか M-x indent-region ないしごめんむり

……flymakeとかいわないで! いややもうウチいやや!(マジ泣き)