以前Helm用に作ったのですが、Ivy/Counselへ移行して以降放置していたのを復活させました。
misohena/el-winsearch: Access Windows Search from Emacs
とりあえずHelmと分離して M-x winsearch でgrep風に結果を表示させてみました。
その上で counsel-winsearch も作ってあります。
最近検索メニューを整備しているのでその一環です。
以前Helm用に作ったのですが、Ivy/Counselへ移行して以降放置していたのを復活させました。
misohena/el-winsearch: Access Windows Search from Emacs
とりあえずHelmと分離して M-x winsearch でgrep風に結果を表示させてみました。
その上で counsel-winsearch も作ってあります。
最近検索メニューを整備しているのでその一環です。
(2022-01-16追記: 切り取る範囲の計算を修正しました。invisibleな文字があるので複数の答えがあり得て、その中で最も長いものを選ばなければなりませんでした)
phscrollのついでと言っては何ですがこれも以前から気になっていたので。
見るからに指定した幅以上の最小の幅で切り取っているのが原因ですね。私がカラム幅の指定をあまり使ってこなかったのはこういうのがあるからだったりします。超えない最大の幅で切り取って足りない分を埋めるのが良いでしょう。
問題は org-table–shrink-field 内にあるのでこれにadviceを追加することにしました。
(defun my-org-table--shrink-field (old-fun width align start end contents) (if (or (= start end) (org-table--shrunk-field) (= 0 width) (eq contents 'hline) (equal contents "")) ;; 関係ないところは従来のコードを呼び出す。 (funcall old-fun width align start end contents) (let* ((lead (org-with-point-at start (skip-chars-forward " "))) (trail (org-with-point-at end (abs (skip-chars-backward " ")))) (contents-width (org-string-width (buffer-substring (+ start lead) (- end trail))))) (cond ((<= width contents-width) (let ((pre (and (> lead 0) (org-table--make-shrinking-overlay start (+ start lead) "" contents t))) (post ;; widthを超えない最後の位置を分割点とする。 ;; Find cut location so that WIDTH characters are ;; visible using dichotomy. (let* ((begin (+ start lead)) (lower begin) (upper (1+ (1- end))) ;;+ ;; Compensate the absence of leading space, ;; thus preserving alignment. (width (if (= lead 0) (1+ width) width)) (divpos (progn (while (> upper lower) (let ((mean (ash (+ lower upper) -1))) (if (< width (org-string-width (buffer-substring begin mean))) (setq upper mean) (setq lower (1+ mean))))) (1- upper))) ;; 分割点までの幅を計算する。 (str-w (org-string-width (buffer-substring begin divpos)))) (org-table--make-shrinking-overlay divpos end ;; 足りない分を空白で埋める。 (make-string (- width str-w) ? ) contents)))) (if pre (list pre post) (list post)))) (t ;; 関係ないところは従来のコードを呼び出す。 (funcall old-fun width align start end contents)))))) (advice-add #'org-table--shrink-field :around #'my-org-table--shrink-field) ;; (advice-remove #'org-table--shrink-field ;; #'my-org-table--shrink-field)
丸丸差し替えても良いのですが、結構長い関数だったので影響のある部分だけ別の処理をしてそれ以外は従来のコードを呼び出すようにしてみました。
幅広文字を考慮しているようでしていないというなんともよく分からないコードですね。
https://git.savannah.gnu.org/cgit/emacs/org-mode.git/tree/lisp/org-table.el?h=release_9.5.2#n3977
折り返しモードでも水平スクロールさせる件。前々から気になっていた問題を色々修正した。
misohena/phscroll: Enable partial horizontal scroll in Emacs
修正点:
これまでは<と>でスクロールできることを表示していたのだけど、フリンジに表示すれば良いことに気がついた。幅が広がって見た目も良くなった。
ソートするとフリーズすることがあるので時々タスクマネージャからプロセスを強制終了していた。原因はsort-linesが内部でナローイングしていることで、modification-hooks経由でphscrollがスクロール領域を更新するときにforward-lineで更新終了ポイントまで到達できず無限ループに陥っていた。sort-linesはご丁寧にinhibit-quitを立てるので停止できないというわけ。
org-tableが作る様々なオーバーレイ表示に正式に対応した。これまでもカラムの伸縮くらいは最低限の対応をしていたが、伸縮した直後にレイアウトが乱れていた。座標表示はbefore-stringを使っているのでさらに特別な対応が必要だった。ヘッドラインモードは表内の一行に丸丸オーバーレイを被せ、それをpost-command-hookで更新する。phscrollと丸被りするので調整に手こずった。基本的にオーバーレイの追加・更新を効率よく確実に検出する一般的な方法はないので、個別の対応が必要。オーバーレイを追加・削除する関数をadviceでフックして解決した。
org-indentはファイルを開いた直後によくレイアウトが乱れるので不快だった(更新すればすぐに直ったが)。これも関連する関数にadviceを追加して解決した。
phscrollは仕組み的にかなり無理があるものだがギリギリ実用に耐えるのが面白い(複数のウィンドウで同一の場所を見ない限りね!)。しかしできればEmacs側に行毎に折り返しを制御するようなプロパティを追加してほしいものだ。