mydotfiles/emacs.d/xah.el
2023-11-15 12:57:11 +03:00

258 lines
9.7 KiB
EmacsLisp
Executable file
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

(defun xah-select-line ()
"Select current line. If region is active, extend selection downward by line.
If `visual-line-mode' is on, consider line as visual line.
URL `http://xahlee.info/emacs/emacs/modernization_mark-word.html'
Version: 2017-11-01 2021-03-19 2023-07-16"
(interactive)
(if (region-active-p)
(if visual-line-mode
(let ((xp1 (point)))
(end-of-visual-line 1)
(when (eq xp1 (point))
(end-of-visual-line 2)))
(progn
(forward-line 1)
(end-of-line)))
(if visual-line-mode
(progn (beginning-of-visual-line)
(push-mark (point) t t)
(end-of-visual-line))
(progn
(push-mark (line-beginning-position) t t)
(end-of-line)))))
;; Copy current line if no selection
(defun xah-copy-line-or-region ()
"Copy current line or selection.
When called repeatedly, append copy subsequent lines.
When `universal-argument' is called first, copy whole buffer (respects `narrow-to-region').
URL `http://xahlee.info/emacs/emacs/emacs_copy_cut_current_line.html'
Version: 2010-05-21 2022-10-03"
(interactive)
(let ((inhibit-field-text-motion nil))
(if current-prefix-arg
(progn
(copy-region-as-kill (point-min) (point-max)))
(if (region-active-p)
(progn
(copy-region-as-kill (region-beginning) (region-end)))
(if (eq last-command this-command)
(if (eobp)
(progn )
(progn
(kill-append "\n" nil)
(kill-append
(buffer-substring-no-properties (line-beginning-position) (line-end-position))
nil)
(progn
(end-of-line)
(forward-char))))
(if (eobp)
(if (eq (char-before) 10 )
(progn )
(progn
(copy-region-as-kill (line-beginning-position) (line-end-position))
(end-of-line)))
(progn
(copy-region-as-kill (line-beginning-position) (line-end-position))
(end-of-line)
(forward-char))))))))
;; Cut current line if no selection
(defun xah-cut-line-or-region ()
"Cut current line or selection.
When `universal-argument' is called first, cut whole buffer (respects `narrow-to-region').
URL `http://xahlee.info/emacs/emacs/emacs_copy_cut_current_line.html'
Version: 2010-05-21 2015-06-10"
(interactive)
(if current-prefix-arg
(progn ; not using kill-region because we don't want to include previous kill
(kill-new (buffer-string))
(delete-region (point-min) (point-max)))
(progn (if (region-active-p)
(kill-region (region-beginning) (region-end) t)
(kill-region (line-beginning-position) (line-beginning-position 2))))))
;; Move the current line up or down by N lines.
(defun move-line (n)
(interactive "p")
(setq col (current-column))
(beginning-of-line) (setq start (point))
(end-of-line) (forward-char) (setq end (point))
(let ((line-text (delete-and-extract-region start end)))
(forward-line n)
(insert line-text)
;; restore point to original column in moved line
(forward-line -1)
(forward-char col)))
(defmacro save-column (&rest body)
`(let ((column (current-column)))
(unwind-protect
(progn ,@body)
(move-to-column column))))
(put 'save-column 'lisp-indent-function 0)
(defun move-line-up ()
(interactive)
(save-column
(transpose-lines 1)
(forward-line -2)))
(defun move-line-down ()
(interactive)
(save-column
(forward-line 1)
(transpose-lines 1)
(forward-line -1)))
;; Delete the matching brackets
(defun xah-delete-forward-bracket-pairs (&optional DeleteInnerTextQ)
"Delete the matching brackets to the right of cursor including the inner text.
e.g. ▮(a b c)
In lisp code, if DeleteInnerTextQ is true, also delete the inner text.
After the command, mark is set at the left matching bracket position, so you can `exchange-point-and-mark' to select it.
This command assumes the char to the right of point is a left bracket or quote, and have a matching one after.
What char is considered bracket or quote is determined by current syntax table.
URL `http://xahlee.info/emacs/emacs/emacs_delete_backward_char_or_bracket_text.html'
Version: 2017-07-02 2023-07-30"
(interactive (list t))
(if DeleteInnerTextQ
(progn
(mark-sexp)
(kill-region (region-beginning) (region-end)))
(let ((xpt (point)))
(forward-sexp)
(delete-char -1)
(push-mark (point) t)
(goto-char xpt)
(delete-char 1))))
(defun xah-delete-backward-bracket-text ()
"Delete the matching brackets to the left of cursor, including the inner text.
e.g. (a b c)▮
This command assumes the left of cursor is a right bracket, and there is a matching one before it.
What char is considered bracket or quote is determined by current syntax table.
URL `http://xahlee.info/emacs/emacs/emacs_delete_backward_char_or_bracket_text.html'
Version: 2017-09-21 2023-07-30"
(interactive)
(progn
(forward-sexp -1)
(mark-sexp)
(kill-region (region-beginning) (region-end))))
(defun xah-delete-backward-bracket-pair ()
"Delete the matching brackets/quotes to the left of cursor.
After call, mark is set at the matching bracket position, so you can `exchange-point-and-mark' to select it.
This command assumes the left of point is a right bracket, and there is a matching one before it.
What char is considered bracket or quote is determined by current syntax table.
URL `http://xahlee.info/emacs/emacs/emacs_delete_backward_char_or_bracket_text.html'
Version: 2017-07-02"
(interactive)
(let ((xp0 (point)) xp1)
(forward-sexp -1)
(setq xp1 (point))
(goto-char xp0)
(delete-char -1)
(goto-char xp1)
(delete-char 1)
(push-mark (point) t)
(goto-char (- xp0 2))))
(defun xah-delete-backward-char-or-bracket-text ()
"Delete 1 character or delete quote/bracket pair and inner text.
If the char to the left of cursor is a matching pair, delete it along with inner text, push the deleted text to `kill-ring'.
What char is considered bracket or quote is determined by current syntax table.
If `universal-argument' is called first, do not delete inner text.
URL `http://xahlee.info/emacs/emacs/emacs_delete_backward_char_or_bracket_text.html'
Version: 2017-07-02 2023-07-22 2023-07-30"
(interactive)
(if (and delete-selection-mode (region-active-p))
(delete-region (region-beginning) (region-end))
(cond
((prog2 (backward-char) (looking-at "\\s)") (forward-char))
(if current-prefix-arg
(xah-delete-backward-bracket-pair)
(xah-delete-backward-bracket-text))
)
((prog2 (backward-char) (looking-at "\\s(") (forward-char))
(message "left of cursor is opening bracket")
(let (xpOpenBracketLeft
(xpOpenBracketRight (point)) xisComment)
(backward-char)
(setq xpOpenBracketLeft (point))
(goto-char xpOpenBracketRight)
(forward-char)
(setq xisComment (nth 4 (syntax-ppss)))
(if xisComment
(progn
(message "cursor is in comment")
(goto-char xpOpenBracketLeft)
(if (forward-comment 1)
(kill-region (point) xpOpenBracketLeft)
(message "error hSnRp: parsing comment failed.")))
(progn
(message "right 1 char of cursor is not in comment")
(goto-char xpOpenBracketLeft)
(forward-sexp)
(if current-prefix-arg
(xah-delete-backward-bracket-pair)
(xah-delete-backward-bracket-text))))))
((prog2 (backward-char) (looking-at "\\s\"") (forward-char))
(if (nth 3 (syntax-ppss))
(progn
(backward-char)
(xah-delete-forward-bracket-pairs (not current-prefix-arg)))
(if current-prefix-arg
(xah-delete-backward-bracket-pair)
(xah-delete-backward-bracket-text))))
(t
(delete-char -1)))))
(defvar xah-brackets '("“”" "()" "[]" "{}" "<>" "" "" "" "" "⦅⦆" "〚〛" "⦃⦄" "" "«»" "「」" "〈〉" "《》" "【】" "" "⦗⦘" "『』" "〖〗" "〘〙" "「」" "⟦⟧" "⟨⟩" "⟪⟫" "⟮⟯" "⟬⟭" "⌈⌉" "⌊⌋" "⦇⦈" "⦉⦊" "❛❜" "❝❞" "" "❪❫" "" "❬❭" "" "❰❱" "" "〈〉" "⦑⦒" "⧼⧽" "﹙﹚" "﹛﹜" "﹝﹞" "⁽⁾" "₍₎" "⦋⦌" "⦍⦎" "⦏⦐" "⁅⁆" "⸢⸣" "⸤⸥" "⟅⟆" "⦓⦔" "⦕⦖" "⸦⸧" "⸨⸩" "⦅⦆")
"A list of strings, each element is a string of 2 chars, the left bracket and a matching right bracket.
Used by `xah-select-text-in-quote' and others.")
(defconst xah-left-brackets
(mapcar (lambda (x) (substring x 0 1)) xah-brackets)
"List of left bracket chars. Each element is a string.")
(defconst xah-right-brackets
(mapcar (lambda (x) (substring x 1 2)) xah-brackets)
"List of right bracket chars. Each element is a string.")
(defun xah-goto-matching-bracket ()
"Move cursor to the matching bracket.
If cursor is not on a bracket, call `backward-up-list'.
The list of brackets to jump to is defined by `xah-left-brackets' and `xah-right-brackets'.
URL `http://xahlee.info/emacs/emacs/emacs_navigating_keys_for_brackets.html'
Version: 2016-11-22 2023-07-22"
(interactive)
(if (nth 3 (syntax-ppss))
(backward-up-list 1 'ESCAPE-STRINGS 'NO-SYNTAX-CROSSING)
(cond
((eq (char-after) ?\") (forward-sexp))
((eq (char-before) ?\") (backward-sexp))
((looking-at (regexp-opt xah-left-brackets))
(forward-sexp))
((prog2 (backward-char) (looking-at (regexp-opt xah-right-brackets)) (forward-char))
(backward-sexp))
(t (backward-up-list 1 'ESCAPE-STRINGS 'NO-SYNTAX-CROSSING)))))