RubyのRegexp.last_matchのスコープ
ちょっとハマったのでメモ。
Rubyでは正規表現を一致させた結果をRegexp.last_match
や$~
などで取得する。
リファレンスマニュアルでは次のように説明されている。
カレントスコープで最後に行った正規表現マッチの
MatchData
オ ブジェクトを返します。
このカレントスコープはレキシカルに、つまりコードの字面上だけで決定される。 正規表現を一致させた後であっても、スコープが異なれば一致させた結果にアクセスすることはできない。
実証コード:
def foo(re) re.call # ここで正規表現を一致させる p Regexp.last_match # が、外側のスコープの結果は得られない end foo(proc{ 'foo' =~ /foo/ }) p Regexp.last_match # 同じスコープなら結果を得られる
実行結果:
nil #<MatchData "foo">
次期家PC
DELLのnew XPS13 2 in 1に少し期待していたが、盆休み前に表参道のDELL Design Laboに実機を見に行ったところ、MagLevキーボードが思ったより打鍵感がペコペコで期待外れだった。持ち運びを考えなければSurface Bookが良さそうだが、今年は新機種が出るのかなあ。
追記(2019/09/24)
ビックカメラで実機を触ってみたら、以外とこのキーボードで行ける気がした。 増税前の割引セールをやってるのでどうしようかな。 10月に発表と噂のSurfaceの新型も気になるが。
追記(2019/09/26)
再度、店舗で実機をじっくりと確かめてみた。 キーボードはそんなに悪くないが、今度はディスプレイのペラさが気になった。 Surfaceの方がディスプレイの作りがかっちりしていて視認性もよさそう。 少なくともDELLは今回は見送りだな。
ivy/counselの設定
いろいろ試行錯誤して次の設定に落ち着いた。
ivy
基本設定
(require 'ivy) (ivy-mode 1) (setq ivy-height 30) (setq ivy-use-virtual-buffers t)
helmのように正規表現を順不同にする
(setq ivy-re-builders-alist '((t . ivy--regex-ignore-order)))
デフォルトで入力済みの^を消す
鬱陶しいのでデフォルト値から消した。
(setq ivy-initial-inputs-alist (seq-remove (lambda (initial-input-pair) (let ((initial-input-name (car initial-input-pair))) (or (string-prefix-p "counsel-" (symbol-name initial-input-name)) (seq-contains '(Man-completion-table woman) initial-input-name)))) ivy-initial-inputs-alist))
検索候補を語長順かつ辞書順にする
(defun ivy--sort-by-len (name candidates) "Sort CANDIDATES based on similarity of their length with NAME." (let ((name-len (length name)) (candidates-count (length candidates))) (if (< 500 candidates-count) candidates (seq-sort-by (lambda (candidate-string) (cons candidate-string (abs (- name-len (length candidate-string))))) (lambda (a b) (or (< (cdr a) (cdr b)) (and (= (cdr a) (cdr b)) (string< (car a) (car b))))) candidates)))) (dolist (i '(counsel-M-x counsel-apropos counsel-describe-function counsel-describe-variable counsel-describe-face)) (setf (alist-get i ivy-sort-matches-functions-alist) 'ivy--sort-by-len))
swiper
呼び出すだけ。
(require 'swiper)
counsel
基本設定
(require 'counsel) (counsel-mode 1) (global-set-key (kbd "M-x") 'counsel-M-x) ; replace to counsel command (global-set-key (kbd "C-x C-b") 'ivy-switch-buffer) ; replace to counsel command (global-set-key (kbd "ESC M-x") 'execute-extended-command) ; backup original command
counsel-gitにUntracked Filesを追加
helm-ls-git
に動作を近づける。
(setq counsel-git-cmd (string-join '("git status --short --untracked-files=all | awk '$1~/?/{print $2}'" ; additional untracked files "git ls-files --full-name --") ; default git command "; "))
counsel-gitのエイリアス
counsel-git-grep
と被るので、区別がつくようにエイリアスを定義。
(defalias 'counsel-git-ls 'counsel-git)
counsel-git-grepに別ウィンドウのアクションを追加
標準だとなぜか未定義なので追加した。
(defun counsel-git-grep-other-window (&rest args) "Go to occurrence X in current Git repository other window. ARGS is passed through to `counsel-git-grep-action'." (switch-to-buffer-other-window (current-buffer)) (apply #'counsel-git-grep-action args)) (ivy-add-actions 'counsel-git-grep '(("j" counsel-git-grep-other-window "other window")))
magitの設定
(with-eval-after-load "magit" (setq magit-completing-read-function 'ivy-completing-read))
prescient
基本設定
(require 'prescient) (setq prescient-aggressive-file-save t) (prescient-persist-mode 1) (require 'ivy-prescient) (ivy-prescient-mode 1)
検索候補を辞書順に並べる
デフォルトだと同じ語長のワードがランダムに並んで 気持ち悪いので、adviceを使って無理やり辞書順に並べ替えた。
(defun my-advice/ivy-prescient-sort-function-by-dictionary-order (adviced-sort-function c1 c2) "Around advice function for `ivy-prescient-sort-function'. This advice sorts candidates by dictionary order. ADVICED-SORT-FUNCTION is original function. C1 and C2 is original arguments." (or (funcall adviced-sort-function c1 c2) (progn (when (listp c1) (setq c1 (car c1))) (when (listp c2) (setq c2 (car c2))) (and (= (length c1) (length c2)) (string< c1 c2))))) (advice-add 'ivy-prescient-sort-function :around #'my-advice/ivy-prescient-sort-function-by-dictionary-order)
7月に読んだ本やマンガ
7月の読書メーター
読んだ本の数:34
読んだページ数:6928
ナイス数:1
プラネット・ウィズ 3 (3巻) (ヤングキングコミックス)
読了日:07月31日 著者:水上 悟志
データ指向アプリケーションデザイン ―信頼性、拡張性、保守性の高い分散システム設計の原理
読了日:07月30日 著者:Martin Kleppmann
天竺熱風録 6 (ヤングアニマルコミックス)
読了日:07月30日 著者:伊藤勢
はぐれアイドル地獄変 (9) (ニチブンコミックス)
読了日:07月30日 著者:高遠 るい
変女~変な女子高生 甘栗千子~ 13 (ヤングアニマルコミックス)
読了日:07月30日 著者:此ノ木よしる
暴走するネット広告: 1兆8000億円市場の落とし穴 (NHK出版新書)
読了日:07月23日 著者:NHK取材班
ヒストリエ(11) (アフタヌーンKC)
読了日:07月23日 著者:岩明 均
超人ロック ドラゴンズブラッド (3) (MFコミックス フラッパーシリーズ)
読了日:07月22日 著者:聖 悠紀
超人ロック ドラゴンズブラッド (2) (MFコミックス フラッパーシリーズ)
読了日:07月22日 著者:聖 悠紀
超人ロック ドラゴンズブラッド 1 (MFコミックス フラッパーシリーズ)
読了日:07月22日 著者:聖 悠紀
中国文明の歴史 (講談社現代新書)
読了日:07月21日 著者:岡田 英弘
ダーウィンの覗き穴〔マンガ版〕──虫たちの性生活がすごいんです
読了日:07月19日 著者:日高 トモキチ
ライドンキング(2) (シリウスKC)
読了日:07月19日 著者:馬場 康誌
ライドンキング(1) (シリウスKC)
読了日:07月19日 著者:馬場 康誌
超人ロック 荒野の騎士 (MFコミックス)
読了日:07月15日 著者:聖 悠紀
超人ロック ひとりぼっちのプリンセス
読了日:07月14日 著者:聖 悠紀
超人ロック 星辰の門 (MFコミックス)
読了日:07月14日 著者:聖 悠紀
超人ロック カデット (MFコミックス)
読了日:07月14日 著者:聖 悠紀
なぜ日本人はご先祖様に祈るのか ドイツ人禅僧が見たフシギな死生観 (幻冬舎新書)
読了日:07月14日 著者:ネルケ 無方
オイラー、リーマン、ラマヌジャン―時空を超えた数学者の接点 (岩波科学ライブラリー)
読了日:07月12日 著者:黒川 信重
超人ロック メヌエット (MFコミックス)
読了日:07月12日 著者:聖 悠紀
超人ロック 猫の散歩引き受けます (MFコミックス)
読了日:07月12日 著者:聖 悠紀
超人ロック 天空の魔法士 (MFコミックス)
読了日:07月11日 著者:聖 悠紀
超人ロック クランベールの月 (MFコミックス)
読了日:07月11日 著者:聖 悠紀
超人ロック ブレインシュリンカー/不死者たち (MFコミックス)
読了日:07月11日 著者:聖 悠紀
「宇宙のすべてを支配する数式」をパパに習ってみた 天才物理学者・浪速阪教授の70分講義 (KS科学一般書)
読了日:07月09日 著者:橋本 幸士
異種族レビュアーズ 3 (ドラゴンコミックスエイジ ま 7-1-3)
読了日:07月09日 著者:masha
ウチの使い魔がすみません(6) (アフタヌーンKC)
読了日:07月08日 著者:櫓刃 鉄火
ダーウィンズゲーム(18) (少年チャンピオン・コミックス)
読了日:07月08日 著者:FLIPFLOPs
米中もし戦わば 戦争の地政学 (文春文庫)の感想
歴史的経緯や体制の良し悪しや善悪の判断や方法論はともあれ、中国が覇権に向けて戦略的に動いているのが分かる。中国の怖さは次の一文が分かりやすい。「ペンタゴンの元アナリスト、マイケル・ピルズベリーによれば、中国は総合国力を信じられないほど正確に計算しているという。その最も注目すべき点はおそらく、軍事力が国力全体の一〇%程度にしか評価されていないことだ」
読了日:07月07日 著者:ピーター ナヴァロ
王家の遺伝子 DNAが解き明かした世界史の謎 (ブルーバックス)
読了日:07月05日 著者:石浦 章一
異種族レビュアーズ 2 (ドラゴンコミックスエイジ ま 7-1-2)
読了日:07月05日 著者:masha
異種族レビュアーズ (ドラゴンコミックスエイジ ま 7-1-1)
読了日:07月05日 著者:masha
TCP技術入門 ――進化を続ける基本プロトコル (WEB+DB PRESS plusシリーズ)
読了日:07月02日 著者:安永 遼真,中山 悠,丸田 一輝
読書メーター
Emacsの補完機能をHelmからIvyへ移行
バズってたQiitaの記事を参考に、HelmからIvyに移行してみた。
自分が加えた変更は次のとおり。
counsel-M-x
の絞り込み開始後のソーティング方法を辞書順に
長さでソートした後、さらに辞書順でソートするようにした。
(defun ivy--sort-by-len (name candidates) "Sort CANDIDATES based on similarity of their length with NAME." (let ((name-len (length name)) (candidates-count (length candidates))) (if (< 500 candidates-count) candidates (seq-sort-by (lambda (candidate-string) (cons candidate-string (abs (- name-len (length candidate-string))))) (lambda (a b) (if (not (= (cdr a) (cdr b))) (< (cdr a) (cdr b)) (string< (car a) (car b)))) candidates)))) (dolist (i '(counsel-M-x counsel-apropos counsel-describe-function counsel-describe-variable counsel-describe-face)) (setf (alist-get i ivy-sort-matches-functions-alist) 'ivy--sort-by-len))
helm-ls-gitパッケージの代替コマンドを定義
helm-ls-gitに相当するcounselのパッケージが見つからなかったので、 Find file in a Git repo with ivy · (or emacsを参考に代替コマンドを定義した。
追記: あとで見直したらcounsel-git
というコマンドが定義済みだった。なんで見逃したんだろ。
"other window"
アクションをどうしても追加したくて方法がわからず苦労したが、ソースコードやヘルプを色々と探したらどうやらivy-set-actions
で設定することが分かった。
ivy-read
のcaller
は何のために設定するのかと思ったらivy-set-actions
に登録するコマンド名と対応するようだ。
;; replaced from helm-ls-git (ivy-set-actions 'counsel-git-ls '(("j" find-file-other-window "other window") ("f" find-file-other-frame "other frame"))) (defun counsel-git-ls (&optional initial-input) "Find file in the current Git repository. When INITIAL-INPUT is non-nil, use it in the minibuffer during completion." (interactive) (let* ((default-directory (locate-dominating-file default-directory ".git")) (candidate-git-files (split-string (shell-command-to-string "git ls-files --full-name --") "\n"))) (ivy-read "Git files: " candidate-git-files :initial-input initial-input :action #'find-file :caller 'counsel-git-ls)))
AnsibleのFilter
Jinja2の公式マニュアルだと物足りないなと思ったら、Ansibleは追加のFilterを持っているようだ。
regex_escape
のように地味に便利そうなFilterも使えるようだ。
Rubyスクリプトでパスワード入力
io/console
をrquire
してからIO#getpass
を使う。
$ ri IO#getpass = IO#getpass (from ruby core) ------------------------------------------------------------------------ io.getpass(prompt=nil) -> string ------------------------------------------------------------------------ Reads and returns a line without echo back. Prints prompt unless it is nil. You must require 'io/console' to use this method.