diff options
Diffstat (limited to '.emacs.d/lisp/markdown-mode.el')
| -rw-r--r-- | .emacs.d/lisp/markdown-mode.el | 178 |
1 files changed, 177 insertions, 1 deletions
diff --git a/.emacs.d/lisp/markdown-mode.el b/.emacs.d/lisp/markdown-mode.el index f1aee9d..8094e02 100644 --- a/.emacs.d/lisp/markdown-mode.el +++ b/.emacs.d/lisp/markdown-mode.el | |||
| @@ -659,6 +659,44 @@ markdown-header-face-* faces." | |||
| 659 | :safe 'booleanp | 659 | :safe 'booleanp |
| 660 | :package-version '(markdown-mode . "2.5")) | 660 | :package-version '(markdown-mode . "2.5")) |
| 661 | 661 | ||
| 662 | (defcustom markdown-special-ctrl-a/e nil | ||
| 663 | "Non-nil means `C-a' and `C-e' behave specially in headlines and items. | ||
| 664 | |||
| 665 | When t, `C-a' will bring back the cursor to the beginning of the | ||
| 666 | headline text. In an item, this will be the position after bullet | ||
| 667 | and check-box, if any. When the cursor is already at that | ||
| 668 | position, another `C-a' will bring it to the beginning of the | ||
| 669 | line. | ||
| 670 | |||
| 671 | `C-e' will jump to the end of the headline, ignoring the presence | ||
| 672 | of closing tags in the headline. A second `C-e' will then jump to | ||
| 673 | the true end of the line, after closing tags. This also means | ||
| 674 | that, when this variable is non-nil, `C-e' also will never jump | ||
| 675 | beyond the end of the heading of a folded section, i.e. not after | ||
| 676 | the ellipses. | ||
| 677 | |||
| 678 | When set to the symbol `reversed', the first `C-a' or `C-e' works | ||
| 679 | normally, going to the true line boundary first. Only a directly | ||
| 680 | following, identical keypress will bring the cursor to the | ||
| 681 | special positions. | ||
| 682 | |||
| 683 | This may also be a cons cell where the behavior for `C-a' and | ||
| 684 | `C-e' is set separately." | ||
| 685 | :group 'markdown | ||
| 686 | :type '(choice | ||
| 687 | (const :tag "off" nil) | ||
| 688 | (const :tag "on: after hashes/bullet and before closing tags first" t) | ||
| 689 | (const :tag "reversed: true line boundary first" reversed) | ||
| 690 | (cons :tag "Set C-a and C-e separately" | ||
| 691 | (choice :tag "Special C-a" | ||
| 692 | (const :tag "off" nil) | ||
| 693 | (const :tag "on: after hashes/bullet first" t) | ||
| 694 | (const :tag "reversed: before hashes/bullet first" reversed)) | ||
| 695 | (choice :tag "Special C-e" | ||
| 696 | (const :tag "off" nil) | ||
| 697 | (const :tag "on: before closing tags first" t) | ||
| 698 | (const :tag "reversed: after closing tags first" reversed)))) | ||
| 699 | :package-version '(markdown-mode . "2.7")) | ||
| 662 | 700 | ||
| 663 | ;;; Markdown-Specific `rx' Macro ============================================== | 701 | ;;; Markdown-Specific `rx' Macro ============================================== |
| 664 | 702 | ||
| @@ -5531,6 +5569,9 @@ Assumes match data is available for `markdown-regex-italic'." | |||
| 5531 | (define-key map (kbd "C-x n s") 'markdown-narrow-to-subtree) | 5569 | (define-key map (kbd "C-x n s") 'markdown-narrow-to-subtree) |
| 5532 | (define-key map (kbd "M-RET") 'markdown-insert-list-item) | 5570 | (define-key map (kbd "M-RET") 'markdown-insert-list-item) |
| 5533 | (define-key map (kbd "C-c C-j") 'markdown-insert-list-item) | 5571 | (define-key map (kbd "C-c C-j") 'markdown-insert-list-item) |
| 5572 | ;; Lines | ||
| 5573 | (define-key map [remap move-beginning-of-line] 'markdown-beginning-of-line) | ||
| 5574 | (define-key map [remap move-end-of-line] 'markdown-end-of-line) | ||
| 5534 | ;; Paragraphs (Markdown context aware) | 5575 | ;; Paragraphs (Markdown context aware) |
| 5535 | (define-key map [remap backward-paragraph] 'markdown-backward-paragraph) | 5576 | (define-key map [remap backward-paragraph] 'markdown-backward-paragraph) |
| 5536 | (define-key map [remap forward-paragraph] 'markdown-forward-paragraph) | 5577 | (define-key map [remap forward-paragraph] 'markdown-forward-paragraph) |
| @@ -6474,6 +6515,130 @@ a list." | |||
| 6474 | 6515 | ||
| 6475 | ;;; Movement ================================================================== | 6516 | ;;; Movement ================================================================== |
| 6476 | 6517 | ||
| 6518 | ;; This function was originally derived from `org-beginning-of-line' from org.el. | ||
| 6519 | (defun markdown-beginning-of-line (&optional n) | ||
| 6520 | "Go to the beginning of the current visible line. | ||
| 6521 | |||
| 6522 | If this is a headline, and `markdown-special-ctrl-a/e' is not nil | ||
| 6523 | or symbol `reversed', on the first attempt move to where the | ||
| 6524 | headline text hashes, and only move to beginning of line when the | ||
| 6525 | cursor is already before the hashes of the text of the headline. | ||
| 6526 | |||
| 6527 | If `markdown-special-ctrl-a/e' is symbol `reversed' then go to | ||
| 6528 | the hashes of the text on the second attempt. | ||
| 6529 | |||
| 6530 | With argument N not nil or 1, move forward N - 1 lines first." | ||
| 6531 | (interactive "^p") | ||
| 6532 | (let ((origin (point)) | ||
| 6533 | (special (pcase markdown-special-ctrl-a/e | ||
| 6534 | (`(,C-a . ,_) C-a) (_ markdown-special-ctrl-a/e))) | ||
| 6535 | deactivate-mark) | ||
| 6536 | ;; First move to a visible line. | ||
| 6537 | (if visual-line-mode | ||
| 6538 | (beginning-of-visual-line n) | ||
| 6539 | (move-beginning-of-line n) | ||
| 6540 | ;; `move-beginning-of-line' may leave point after invisible | ||
| 6541 | ;; characters if line starts with such of these (e.g., with | ||
| 6542 | ;; a link at column 0). Really move to the beginning of the | ||
| 6543 | ;; current visible line. | ||
| 6544 | (forward-line 0)) | ||
| 6545 | (cond | ||
| 6546 | ;; No special behavior. Point is already at the beginning of | ||
| 6547 | ;; a line, logical or visual. | ||
| 6548 | ((not special)) | ||
| 6549 | ;; `beginning-of-visual-line' left point before logical beginning | ||
| 6550 | ;; of line: point is at the beginning of a visual line. Bail | ||
| 6551 | ;; out. | ||
| 6552 | ((and visual-line-mode (not (bolp)))) | ||
| 6553 | ((looking-at markdown-regex-header-atx) | ||
| 6554 | ;; At a header, special position is before the title. | ||
| 6555 | (let ((refpos (match-beginning 2)) | ||
| 6556 | (bol (point))) | ||
| 6557 | (if (eq special 'reversed) | ||
| 6558 | (when (and (= origin bol) (eq last-command this-command)) | ||
| 6559 | (goto-char refpos)) | ||
| 6560 | (when (or (> origin refpos) (<= origin bol)) | ||
| 6561 | (goto-char refpos))) | ||
| 6562 | ;; Prevent automatic cursor movement caused by the command loop. | ||
| 6563 | ;; Enable disable-point-adjustment to avoid unintended cursor repositioning. | ||
| 6564 | (when (and markdown-hide-markup | ||
| 6565 | (equal (get-char-property (point) 'display) "")) | ||
| 6566 | (setq disable-point-adjustment t)))) | ||
| 6567 | ((looking-at markdown-regex-list) | ||
| 6568 | ;; At a list item, special position is after the list marker or checkbox. | ||
| 6569 | (let ((refpos (or (match-end 4) (match-end 3)))) | ||
| 6570 | (if (eq special 'reversed) | ||
| 6571 | (when (and (= (point) origin) (eq last-command this-command)) | ||
| 6572 | (goto-char refpos)) | ||
| 6573 | (when (or (> origin refpos) (<= origin (line-beginning-position))) | ||
| 6574 | (goto-char refpos))))) | ||
| 6575 | ;; No special case, already at beginning of line. | ||
| 6576 | (t nil)))) | ||
| 6577 | |||
| 6578 | ;; This function was originally derived from `org-end-of-line' from org.el. | ||
| 6579 | (defun markdown-end-of-line (&optional n) | ||
| 6580 | "Go to the end of the line, but before ellipsis, if any. | ||
| 6581 | |||
| 6582 | If this is a headline, and `markdown-special-ctrl-a/e' is not nil | ||
| 6583 | or symbol `reversed', ignore closing tags on the first attempt, | ||
| 6584 | and only move to after the closing tags when the cursor is | ||
| 6585 | already beyond the end of the headline. | ||
| 6586 | |||
| 6587 | If `markdown-special-ctrl-a/e' is symbol `reversed' then ignore | ||
| 6588 | closing tags on the second attempt. | ||
| 6589 | |||
| 6590 | With argument N not nil or 1, move forward N - 1 lines first." | ||
| 6591 | (interactive "^p") | ||
| 6592 | (let ((origin (point)) | ||
| 6593 | (special (pcase markdown-special-ctrl-a/e | ||
| 6594 | (`(,_ . ,C-e) C-e) (_ markdown-special-ctrl-a/e))) | ||
| 6595 | deactivate-mark) | ||
| 6596 | ;; First move to a visible line. | ||
| 6597 | (if visual-line-mode | ||
| 6598 | (beginning-of-visual-line n) | ||
| 6599 | (move-beginning-of-line n)) | ||
| 6600 | (cond | ||
| 6601 | ;; At a headline, with closing tags. | ||
| 6602 | ((save-excursion | ||
| 6603 | (forward-line 0) | ||
| 6604 | (and (looking-at markdown-regex-header-atx) (match-end 3))) | ||
| 6605 | (let ((refpos (match-end 2)) | ||
| 6606 | (visual-end (and visual-line-mode | ||
| 6607 | (save-excursion | ||
| 6608 | (end-of-visual-line) | ||
| 6609 | (point))))) | ||
| 6610 | ;; If `end-of-visual-line' brings us before end of line or even closing | ||
| 6611 | ;; tags, i.e., the headline spans over multiple visual lines, move | ||
| 6612 | ;; there. | ||
| 6613 | (cond ((and visual-end | ||
| 6614 | (< visual-end refpos) | ||
| 6615 | (<= origin visual-end)) | ||
| 6616 | (goto-char visual-end)) | ||
| 6617 | ((not special) (end-of-line)) | ||
| 6618 | ((eq special 'reversed) | ||
| 6619 | (if (and (= origin (line-end-position)) | ||
| 6620 | (eq this-command last-command)) | ||
| 6621 | (goto-char refpos) | ||
| 6622 | (end-of-line))) | ||
| 6623 | (t | ||
| 6624 | (if (or (< origin refpos) (>= origin (line-end-position))) | ||
| 6625 | (goto-char refpos) | ||
| 6626 | (end-of-line)))) | ||
| 6627 | ;; Prevent automatic cursor movement caused by the command loop. | ||
| 6628 | ;; Enable disable-point-adjustment to avoid unintended cursor repositioning. | ||
| 6629 | (when (and markdown-hide-markup | ||
| 6630 | (equal (get-char-property (point) 'display) "")) | ||
| 6631 | (setq disable-point-adjustment t)))) | ||
| 6632 | (visual-line-mode | ||
| 6633 | (let ((bol (line-beginning-position))) | ||
| 6634 | (end-of-visual-line) | ||
| 6635 | ;; If `end-of-visual-line' gets us past the ellipsis at the | ||
| 6636 | ;; end of a line, backtrack and use `end-of-line' instead. | ||
| 6637 | (when (/= bol (line-beginning-position)) | ||
| 6638 | (goto-char bol) | ||
| 6639 | (end-of-line)))) | ||
| 6640 | (t (end-of-line))))) | ||
| 6641 | |||
| 6477 | (defun markdown-beginning-of-defun (&optional arg) | 6642 | (defun markdown-beginning-of-defun (&optional arg) |
| 6478 | "`beginning-of-defun-function' for Markdown. | 6643 | "`beginning-of-defun-function' for Markdown. |
| 6479 | This is used to find the beginning of the defun and should behave | 6644 | This is used to find the beginning of the defun and should behave |
| @@ -10042,7 +10207,18 @@ rows and columns and the column alignment." | |||
| 10042 | 10207 | ||
| 10043 | ;; add live preview export hook | 10208 | ;; add live preview export hook |
| 10044 | (add-hook 'after-save-hook #'markdown-live-preview-if-markdown t t) | 10209 | (add-hook 'after-save-hook #'markdown-live-preview-if-markdown t t) |
| 10045 | (add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t)) | 10210 | (add-hook 'kill-buffer-hook #'markdown-live-preview-remove-on-kill t t) |
| 10211 | |||
| 10212 | ;; Add a custom keymap for `visual-line-mode' so that activating | ||
| 10213 | ;; this minor mode does not override markdown-mode's keybindings. | ||
| 10214 | ;; FIXME: Probably `visual-line-mode' should take care of this. | ||
| 10215 | (let ((oldmap (cdr (assoc 'visual-line-mode minor-mode-map-alist))) | ||
| 10216 | (newmap (make-sparse-keymap))) | ||
| 10217 | (set-keymap-parent newmap oldmap) | ||
| 10218 | (define-key newmap [remap move-beginning-of-line] nil) | ||
| 10219 | (define-key newmap [remap move-end-of-line] nil) | ||
| 10220 | (make-local-variable 'minor-mode-overriding-map-alist) | ||
| 10221 | (push `(visual-line-mode . ,newmap) minor-mode-overriding-map-alist))) | ||
| 10046 | 10222 | ||
| 10047 | ;;;###autoload | 10223 | ;;;###autoload |
| 10048 | (add-to-list 'auto-mode-alist | 10224 | (add-to-list 'auto-mode-alist |
