次にShift+矢印キーで参照先を移動する機能を改善します。
改善点:
- @だけの場合 (@の後に数字等が無い場合も含む)
- $だけの場合 ($の後に数字等が無い場合も含む)
- 参照が無いところでの新規追加
@< や @>> 、 @I+1 への対応
$< や $>> への対応
(defun my-org-table-fedit-shift-reference (dir)
(cond
((org-in-regexp "\\(\\<[a-zA-Z]\\)&")
(if (memq dir '(left right))
(org-table--rematch-and-replace 1 (eq dir 'left))
(user-error "Cannot shift reference in this direction")))
((org-in-regexp "\\(\\<[a-zA-Z]\\{1,2\\}\\)\\([0-9]+\\)")
(if (memq dir '(up down))
(org-table--rematch-and-replace 2 (eq dir 'up))
(org-table--rematch-and-replace 1 (eq dir 'left))))
((org-in-regexp
(concat
"\\("
"\\(?:@\\|\\.\\.\\)"
"\\(?:\\(?:[-+]?I+\\([-+][0-9]+\\)\\)"
"\\|\\([-+]?\\(?:I+\\>\\|[0-9]+\\)\\|<+\\|>+\\)\\)?"
"\\)"
"\\(\\$\\([-+]?[0-9]+\\|<+\\|>+\\)?\\)?"
"\\|" "\\(\\$\\([-+]?[0-9]+\\|<+\\|>+\\)?\\)"))
(cond
((memq dir '(up down))
(cond
((match-beginning 2) (org-table--rematch-and-replace 2 (eq dir 'up) t))
((match-beginning 3) (org-table--rematch-and-replace 3 (eq dir 'up) t))
((match-beginning 1) (goto-char (1+ (match-beginning 1)))
(insert (my-org-table-fedit-current-line-str dir)))
(t
(when (or (match-beginning 4) (match-beginning 6)) (goto-char (or (match-beginning 4) (match-beginning 6))))
(insert "@" (my-org-table-fedit-current-line-str dir)))))
(t
(cond
((match-beginning 5) (org-table--rematch-and-replace 5 (eq dir 'left)))
((match-beginning 4) (goto-char (1+ (match-beginning 4)))
(insert (my-org-table-fedit-current-column-str dir)))
((match-beginning 7) (org-table--rematch-and-replace 7 (eq dir 'left)))
((match-beginning 6) (goto-char (1+ (match-beginning 6)))
(insert (my-org-table-fedit-current-column-str dir)))
(t
(when (match-end 1) (goto-char (match-end 1)))
(insert "$" (my-org-table-fedit-current-column-str dir)))))))
(t
(if (memq dir '(up down))
(insert "@" (my-org-table-fedit-current-line-str dir))
(insert "$" (my-org-table-fedit-current-column-str dir))))))
(advice-add #'org-table-fedit-shift-reference :override
#'my-org-table-fedit-shift-reference)
(defun my-org-table-fedit-current-column-str (&optional dir)
(number-to-string
(+
(with-current-buffer (marker-buffer org-pos) (org-table-current-column))
(pcase dir ('left -1) ('right 1) (_ 0)))))
(defun my-org-table-fedit-current-line-str (&optional dir)
(pcase dir ('up "-1") ('down "+1") (_ "+0"))
)
(defun my-org-table-shift-refpart:around (old-fun ref &optional decr hline)
(if (and (stringp ref) (> (length ref) 0) (memq (aref ref 0) '(?< ?>)))
(let* ((ch (aref ref 0))
(delta (if (xor decr (eq ch ?>)) -1 1))
(new-len (max 1 (+ (length ref) delta))))
(make-string new-len ch))
(funcall old-fun ref decr hline)))
(advice-add #'org-table-shift-refpart :around
#'my-org-table-shift-refpart:around)
org-table-fedit-shift-referenceは丸丸置き換えてしまうことにしました。
ハイライトが@>や$<といった形式に対応していない問題が残っていますが、org-table-show-referenceは手を入れづらい構造なので諦めました。