[ \n]?\\|[ \n]?\\| [ \n]?\\|[ \n]?\\)\\([a-z]\\)" nil :move)
- (upcase-region (match-beginning 2) (match-end 2))
- (overlay-put (make-overlay (match-beginning 2) (match-end 2)) 'face 'highlight))))
- (goto-char (point-max)))
- (skip-chars-forward " \n\t")))
-
-(defun xah-title-case-region-or-line (&optional Begin End)
- "Title case text between nearest brackets, or current line or selection.
-Capitalize first letter of each word, except words like {to, of, the, a, in, or, and}. If a word already contains cap letters such as HTTP, URL, they are left as is.
-
-When called in a elisp program, Begin End are region boundaries.
-
-URL `http://xahlee.info/emacs/emacs/elisp_title_case_text.html'
-Created: 2017-01-11
-Version: 2021-09-19"
- (interactive)
- (let* ((xskipChars "^\"<>(){}[]“”‘’‹›«»「」『』【】〖〗《》〈〉〔〕")
- (xp0 (point))
- (xbeg (if Begin
- Begin
- (if (region-active-p)
- (region-beginning)
- (progn
- (skip-chars-backward xskipChars (line-beginning-position)) (point)))))
- (xend (if End
- End
- (if (region-active-p)
- (region-end)
- (progn (goto-char xp0)
- (skip-chars-forward xskipChars (line-end-position)) (point)))))
- (xstrPairs [
- [" A " " a "]
- [" An " " an "]
- [" And " " and "]
- [" At " " at "]
- [" As " " as "]
- [" By " " by "]
- [" Be " " be "]
- [" Into " " into "]
- [" In " " in "]
- [" Is " " is "]
- [" It " " it "]
- [" For " " for "]
- [" Of " " of "]
- [" Or " " or "]
- [" On " " on "]
- [" Via " " via "]
- [" The " " the "]
- [" That " " that "]
- [" To " " to "]
- [" Vs " " vs "]
- [" With " " with "]
- [" From " " from "]
- ["'S " "'s "]
- ["'T " "'t "]
- ]))
- (save-excursion
- (save-restriction
- (narrow-to-region xbeg xend)
- (upcase-initials-region (point-min) (point-max))
- (let ((case-fold-search nil))
- (mapc
- (lambda (xx)
- (goto-char (point-min))
- (while
- (search-forward (aref xx 0) nil t)
- (replace-match (aref xx 1) t t)))
- xstrPairs))))))
-
-(defun xah-add-space-after-comma ()
- "Add a space after comma of current block or selection.
-and highlight changes made.
-Created: 2022-01-20
-Version: 2025-03-25"
- (interactive)
- (let (xbeg xend)
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min))
- (while
- (re-search-forward ",\\b" nil t)
- (replace-match ", ")
- (overlay-put
- (make-overlay
- (match-beginning 0)
- (match-end 0)) 'face 'highlight)))))
-
-(defun xah-toggle-read-novel-mode ()
- "Setup current frame to be suitable for reading long novel/article text.
-• Set frame width to 70
-• Line wrap at word boundaries.
-• Line spacing is increased.
-• Proportional width font is used.
-Call again to toggle back.
-
-URL `http://xahlee.info/emacs/emacs/emacs_novel_reading_mode.html'
-Created: 2019-01-30
-Version: 2021-01-16"
- (interactive)
- (if (eq (frame-parameter (selected-frame) 'width) 70)
- (progn
- (set-frame-parameter (selected-frame) 'width 106)
- (variable-pitch-mode 0)
- (setq line-spacing nil)
- (setq word-wrap nil))
- (progn
- (set-frame-parameter (selected-frame) 'width 70)
- (variable-pitch-mode 1)
- (setq line-spacing 0.5)
- (setq word-wrap t)))
- (redraw-frame (selected-frame)))
-
-(defun xah-fill-or-unfill ()
- "Reformat current block or selection to short/long line.
-First call will break into multiple short lines. Repeated call toggles between short and long lines.
-This commands calls `fill-region' to do its work. Set `fill-column' for short line length.
-
-URL `http://xahlee.info/emacs/emacs/modernization_fill-paragraph.html'
-Created: 2020-11-22
-Version: 2025-03-25"
- (interactive)
- ;; This command symbol has a property “'longline-p”, the possible values are t and nil. This property is used to easily determine whether to compact or uncompact, when this command is called again
- (let ( (xisLongline (if (eq last-command this-command) (get this-command 'longline-p) t))
- (deactivate-mark nil)
- xbeg xend )
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (if xisLongline
- (fill-region xbeg xend)
- (let ((fill-column 99999 ))
- (fill-region xbeg xend)))
- (put this-command 'longline-p (not xisLongline))))
-
-(defun xah-unfill-paragraph ()
- "Replace newline chars in current paragraph by single spaces.
-This command does the inverse of `fill-paragraph'.
-
-URL `http://xahlee.info/emacs/emacs/emacs_unfill-paragraph.html'
-Created: 2010-05-12
-Version: 2022-05-20"
- (interactive)
- (let ((fill-column 90002000))
- (fill-paragraph)))
-
-(defun xah-unfill-region (Begin End)
- "Replace newline chars in region by single spaces.
-This command does the inverse of `fill-region'.
-
-URL `http://xahlee.info/emacs/emacs/emacs_unfill-paragraph.html'
-Created: 2010-05-12
-Version: 2022-05-20"
- (interactive "r")
- (let ((fill-column 90002000))
- (fill-region Begin End)))
-
-(defun xah-change-newline-chars-to-one (Begin End)
- "Replace newline char sequence by just one.
-
-URL `http://xahlee.info/emacs/emacs/emacs_reformat_lines.html'
-Version: 2021-07-06"
- (interactive "r")
- (save-excursion
- (save-restriction
- (narrow-to-region Begin End)
- (goto-char (point-min))
- (while (re-search-forward "\n\n+" nil :move) (replace-match "\n")))))
-
-(defun xah-reformat-whitespaces-to-one-space (Begin End)
- "Replace whitespaces by one space.
-
-URL `http://xahlee.info/emacs/emacs/emacs_reformat_lines.html'
-Created: 2017-01-11
-Version: 2022-01-08"
- (interactive "r")
- (save-restriction
- (narrow-to-region Begin End)
- (goto-char (point-min))
- (while (search-forward "\n" nil :move) (replace-match " "))
- (goto-char (point-min))
- (while (search-forward "\t" nil :move) (replace-match " "))
- (goto-char (point-min))
- (while (re-search-forward " +" nil :move) (replace-match " "))
- (goto-char (point-max))))
-
-(defun xah-reformat-to-multi-lines ( &optional Begin End MinLength)
- "Replace spaces by a newline at ~70 chars, on current block or selection.
-If `universal-argument' is called first, ask user for max width.
-
-URL `http://xahlee.info/emacs/emacs/emacs_reformat_lines.html'
-Created: 2018-12-16
-Version: 2025-03-25"
- (interactive)
- (let ( xbeg xend xminlen )
- (setq xminlen (if MinLength MinLength (if current-prefix-arg (prefix-numeric-value current-prefix-arg) fill-column)))
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point)))))))
- (save-excursion
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min))
- (while (re-search-forward " +" nil :move)
- (when (> (- (point) (line-beginning-position)) xminlen)
- (replace-match "\n" )))))))
-
-(defun xah-reformat-lines (&optional Width)
- "Reformat current block or selection into short lines or 1 long line.
-When called for the first time, change to one line. Second call change it to multi-lines. Repeated call toggles.
-If `universal-argument' is called first, ask user to type max length of line. By default, it is 66.
-
-Note: this command is different from emacs `fill-region' or `fill-paragraph'.
-This command never adds or delete non-whitespace chars. It only exchange whitespace sequence.
-
-URL `http://xahlee.info/emacs/emacs/emacs_reformat_lines.html'
-Created: 2016
-Version: 2025-03-25"
- (interactive)
- ;; This symbol has a property 'is-long-p, the possible values are t and nil. This property is used to easily determine whether to compact or uncompact, when this command is called again
- (let (xisLong xwidth xbeg xend)
- (setq xwidth (if Width Width (if current-prefix-arg (prefix-numeric-value current-prefix-arg) 66)))
- (setq xisLong (if (eq last-command this-command) (get this-command 'is-long-p) nil))
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (if current-prefix-arg
- (xah-reformat-to-multi-lines xbeg xend xwidth)
- (if xisLong
- (xah-reformat-to-multi-lines xbeg xend xwidth)
- (progn
- (xah-reformat-whitespaces-to-one-space xbeg xend))))
- (put this-command 'is-long-p (not xisLong))))
-
-(defun xah-reformat-to-sentence-lines ()
- "Reformat current block or selection into multiple lines by ending period.
-Move cursor to the beginning of next text block.
-After this command is called, press `xah-repeat-key' to repeat it.
-
-URL `http://xahlee.info/emacs/emacs/elisp_reformat_to_sentence_lines.html'
-Created: 2020-12-02
-Version: 2025-03-25"
- (interactive)
- (let (xbeg xend)
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min)) (while (search-forward "。" nil t) (replace-match "。\n"))
- ;; (goto-char (point-min)) (while (search-forward " " nil t) (replace-match "\n"))
- (goto-char (point-min))
- (while (re-search-forward "\\([A-Za-z0-9]+\\)[ \t]*\n[ \t]*\\([A-Za-z0-9]+\\)" nil t)
- (replace-match "\\1 \\2"))
- (goto-char (point-min))
- (while (re-search-forward "\\([,]\\)[ \t]*\n[ \t]*\\([A-Za-z0-9]+\\)" nil t)
- (replace-match "\\1 \\2"))
- (goto-char (point-min))
- (while (re-search-forward " +" nil t) (replace-match " "))
- (goto-char (point-min))
- (while (re-search-forward "\\([.?!]\\) +\\([(0-9A-Za-z]+\\)" nil t) (replace-match "\\1\n\\2"))
- (goto-char (point-max))
- (while (eq (char-before) 32) (delete-char -1))))
- (re-search-forward "\n+" nil :move)
- (set-transient-map (let ((xkmap (make-sparse-keymap))) (define-key xkmap (kbd (if (boundp 'xah-repeat-key) xah-repeat-key "m")) this-command) xkmap))
- (set-transient-map (let ((xkmap (make-sparse-keymap))) (define-key xkmap (kbd "DEL") this-command) xkmap)))
-
-(defun xah-space-to-newline ()
- "Replace space sequence to a newline char in current block or selection.
-
-URL `http://xahlee.info/emacs/emacs/emacs_space_to_newline.html'
-Created: 2017-08-19
-Version: 2025-03-25"
- (interactive)
- (let (xbeg xend)
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min))
- (while (re-search-forward " +" nil t)
- (replace-match "\n")))))
-
-(defun xah-slash-to-backslash (&optional Begin End)
- "Replace slash by backslash on current line or region.
-Created: 2021-07-14
-Version: 2021-09-12"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (while (search-forward "/" nil t)
- (replace-match "\\\\"))))))
-
-(defun xah-backslash-to-slash (&optional Begin End)
- "Replace backslash by slash on current line or region.
-Version: 2021-09-11"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (while (search-forward "\\" nil t)
- (replace-match "/"))))))
-
-(defun xah-double-backslash (&optional Begin End)
- "Replace backslash by two backslash on current line or region.
-Version: 2021-11-09"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (while (search-forward "\\" nil t)
- (replace-match "\\\\\\\\"))))))
-
-(defun xah-double-backslash-to-single (&optional Begin End)
- "Replace double backslash by single backslash on current line or region.
-Version: 2021-11-09"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (while (search-forward "\\\\" nil t)
- (replace-match "\\\\"))))))
-
-(defun xah-slash-to-double-backslash (&optional Begin End)
- "Replace slash by double backslash on current line or region.
-Version: 2021-07-14"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (while (search-forward "/" nil t)
- (replace-match "\\\\\\\\"))))))
-
-(defun xah-double-backslash-to-slash (&optional Begin End)
- "Replace double backslash by slash on current line or region.
-Version: 2021-07-14"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-restriction
- (narrow-to-region xbeg xend)
- (let ((case-fold-search nil))
- (goto-char (point-min))
- (while (search-forward "\\\\" nil t)
- (replace-match "/"))))))
-
-(defun xah-comment-dwim ()
- "Toggle comment in programing language code.
-
-Like `comment-dwim', but toggle comment if cursor is not at end of line.
-If cursor is at end of line, either add comment at the line end or move cursor to start of line end comment. call again to comment out whole line.
-
-URL `http://xahlee.info/emacs/emacs/emacs_toggle_comment_by_line.html'
-Created: 2016-10-25
-Version: 2023-07-10"
- (interactive)
- (if (region-active-p)
- (comment-dwim nil)
- (let ((xbegin (line-beginning-position))
- (xend (line-end-position)))
- (if (eq xbegin xend)
- (progn
- (comment-dwim nil))
- (if (eq (point) xend)
- (progn
- (comment-dwim nil))
- (progn
- (comment-or-uncomment-region xbegin xend)
- (forward-line )))))))
-
-(defun xah-quote-lines (QuoteL QuoteR Sep)
- "Add quotes/brackets and separator (comma) to lines.
-Act on current block or selection.
-
-For example,
-
- cat
- dog
- cow
-
-becomes
-
- \"cat\",
- \"dog\",
- \"cow\",
-
-or
-
- (cat)
- (dog)
- (cow)
-
-In lisp code, QuoteL QuoteR Sep are strings.
-
-URL `http://xahlee.info/emacs/emacs/emacs_quote_lines.html'
-Created: 2020-06-26
-Version: 2025-03-25"
- (interactive
- (let ((xbrackets
- '(
- "\"QUOTATION MARK\""
- "'APOSTROPHE'"
- "(paren)"
- "{brace}"
- "[square]"
- ""
- "`emacs'"
- "`markdown`"
- "~tilde~"
- "=equal="
- "“curly double”"
- "‘curly single’"
- "‹french angle›"
- "«french double angle»"
- "「corner」"
- "none"
- "other"
- ))
- (xcomma '("comma ," "semicolon ;" "none" "other"))
- xbktChoice xsep xsepChoice xquoteL xquoteR)
- (let ((completion-ignore-case t))
- (setq xbktChoice (completing-read "Quote to use:" xbrackets nil t nil nil (car xbrackets)))
- (setq xsepChoice (completing-read "line separator:" xcomma nil t nil nil (car xcomma))))
- (cond
- ((string-equal xbktChoice "none")
- (setq xquoteL "" xquoteR ""))
- ((string-equal xbktChoice "other")
- (let ((xx (read-string "Enter 2 chars, for begin/end quote:")))
- (setq xquoteL (substring xx 0 1)
- xquoteR (substring xx 1 2))))
- (t (setq xquoteL (substring xbktChoice 0 1)
- xquoteR (substring xbktChoice -1))))
- (setq xsep
- (cond
- ((string-equal xsepChoice "comma ,") ",")
- ((string-equal xsepChoice "semicolon ;") ";")
- ((string-equal xsepChoice "none") "")
- ((string-equal xsepChoice "other") (read-string "Enter separator:"))
- (t xsepChoice)))
- (list xquoteL xquoteR xsep)))
- (let (xbeg xend (xquoteL QuoteL) (xquoteR QuoteR) (xsep Sep))
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (save-excursion
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min))
- (catch 'EndReached
- (while t
- (skip-chars-forward "\t ")
- (insert xquoteL)
- (end-of-line)
- (insert xquoteR xsep)
- (if (eq (point) (point-max))
- (throw 'EndReached t)
- (forward-char))))))))
-
-(defun xah-escape-quotes (Begin End)
- "Add slash before double quote in current line or selection.
-Double quote is codepoint 34.
-See also: `xah-unescape-quotes'
-URL `http://xahlee.info/emacs/emacs/elisp_escape_quotes.html'
-Version: 2017-01-11"
- (interactive
- (if (region-active-p)
- (list (region-beginning) (region-end))
- (list (line-beginning-position) (line-end-position))))
- (save-excursion
- (save-restriction
- (narrow-to-region Begin End)
- (goto-char (point-min))
- (while (search-forward "\"" nil t)
- (replace-match "\\\"" t t)))))
-
-(defun xah-unescape-quotes (&optional Begin End)
- "Replace 「\\\"」 by 「\"」 in current line or selection.
-See also: `xah-escape-quotes'
-
-URL `http://xahlee.info/emacs/emacs/elisp_escape_quotes.html'
-Created: 2017-01-11
-Version: 2023-11-02"
- (interactive)
- (let (xbeg xend)
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position))))
- (save-excursion
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min))
- (while (search-forward "\\\"" nil t)
- (replace-match "\"" t t))))))
-
-(defun xah-cycle-hyphen-lowline-space (&optional Begin End)
- "Cycle {hyphen lowline space} chars.
-
-The region to work on is by this order:
- 1. if there is a selection, use that.
- 2. If cursor is in a string quote or any type of bracket, and is within current line, work on that region.
- 3. else, work on current line.
-
-After this command is called, press `xah-repeat-key' to repeat it.
-
-URL `http://xahlee.info/emacs/emacs/elisp_change_space-hyphen_underscore.html'
-Created: 2019-02-12
-Version: 2025-01-24"
- (interactive)
- ;; this function sets a property 'state. Possible values are 0 to length of xcharArray.
- (let (xbeg xend xlen
- (xcharArray ["-" "_" " "])
- (xregionWasActive-p (region-active-p))
- (xnowState (if (eq last-command this-command) (get 'xah-cycle-hyphen-lowline-space 'state) 0))
- xchangeTo)
- (setq
- xlen (length xcharArray)
- xchangeTo (elt xcharArray xnowState))
- (if (and Begin End)
- (setq xbeg Begin xend End)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (let ((xskipChars "^\"<>(){}[]“”‘’‹›«»「」『』【】〖〗《》〈〉〔〕()"))
- (skip-chars-backward xskipChars (line-beginning-position))
- (setq xbeg (point))
- (skip-chars-forward xskipChars (line-end-position))
- (setq xend (point))
- (push-mark xbeg))))
- (save-excursion
- (save-restriction
- (narrow-to-region xbeg xend)
- (goto-char (point-min))
- (while (re-search-forward (elt xcharArray (% (+ xnowState 2) xlen)) (point-max) 1)
- (replace-match xchangeTo t t))))
- (when (or (string-equal xchangeTo " ") xregionWasActive-p)
- (goto-char xend)
- (push-mark xbeg)
- (setq deactivate-mark nil))
- (put 'xah-cycle-hyphen-lowline-space 'state (% (+ xnowState 1) xlen)))
- (set-transient-map (let ((xkmap (make-sparse-keymap))) (define-key xkmap (kbd (if (boundp 'xah-repeat-key) xah-repeat-key "m")) this-command) xkmap)))
-
-(defun xah-copy-file-path (&optional DirPathOnlyQ)
- "Copy current buffer file path or dired path.
-Result is full path.
-If `universal-argument' is called first, copy only the dir path.
-
-If in dired, copy the current or marked files.
-
-If a buffer is not file and not dired, copy value of `default-directory'.
-
-URL `http://xahlee.info/emacs/emacs/emacs_copy_file_path.html'
-Created: 2018-06-18
-Version: 2024-12-15"
- (interactive "P")
- (let ((xfpath
- (if (eq major-mode 'dired-mode)
- (progn
- (let ((xresult (mapconcat #'identity
- (dired-get-marked-files) "\n")))
- (if (equal (length xresult) 0)
- (progn default-directory)
- (progn xresult))))
- (or buffer-file-name default-directory))))
- (kill-new
- (if DirPathOnlyQ
- (progn
- (message "Directory copied: %s" (file-name-directory xfpath))
- (file-name-directory xfpath))
- (progn
- (message "File path copied: %s" xfpath)
- xfpath)))))
-
-(defun xah-delete-current-text-block ()
- "Delete the current text block plus blank lines, or selection, and copy to `kill-ring'.
-
-If cursor is between blank lines, delete following blank lines.
-
-URL `http://xahlee.info/emacs/emacs/emacs_delete_block.html'
-Created: 2017-07-09
-Version: 2024-10-07"
- (interactive)
- (let (xbeg xend (xp (point)))
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (progn
- (setq xbeg
- (if (re-search-backward "\n[ \t]*\n+" nil :move)
- (match-end 0)
- (point)))
- (goto-char xp)
- (setq xend (if (re-search-forward "\n[ \t]*\n+" nil :move)
- (match-end 0)
- (point-max)))))
- (kill-region xbeg xend)))
-
-(defun xah-copy-to-register-1 ()
- "Copy current line or selection to register 1.
-
-See also:
-`xah-copy-to-register-1'
-`xah-append-to-register-1'
-`xah-paste-from-register-1'
-`xah-clear-register-1'
-
-URL `http://xahlee.info/emacs/emacs/elisp_copy-paste_register_1.html'
-Created: 2012-07-17
-Version: 2023-08-05"
- (interactive)
- (let (xbeg xend)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position)))
- (copy-to-register ?1 xbeg xend)
- (message "Copied to register 1: [%s]." (buffer-substring xbeg xend))))
-
-(defun xah-append-to-register-1 ()
- "Append current line or selection to register 1.
-When no selection, append current line, with newline char.
-
-See also:
-`xah-copy-to-register-1'
-`xah-append-to-register-1'
-`xah-paste-from-register-1'
-`xah-clear-register-1'
-
-URL `http://xahlee.info/emacs/emacs/emacs_copy_append.html'
-Created: 2015-12-08
-Version: 2023-08-05"
- (interactive)
- (let (xbeg xend)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (setq xbeg (line-beginning-position) xend (line-end-position)))
- (append-to-register ?1 xbeg xend)
- (with-temp-buffer (insert "\n")
- (append-to-register ?1 (point-min) (point-max)))
- (message "Appended to register 1: [%s]." (buffer-substring xbeg xend))))
-
-(defun xah-paste-from-register-1 ()
- "Paste text from register 1.
-
-See also:
-`xah-copy-to-register-1'
-`xah-append-to-register-1'
-`xah-paste-from-register-1'
-`xah-clear-register-1'
-
-URL `http://xahlee.info/emacs/emacs/elisp_copy-paste_register_1.html'
-Created: 2015-12-08
-Version: 2023-04-07"
- (interactive)
- (when (region-active-p)
- (delete-region (region-beginning) (region-end)))
- (insert-register ?1 t))
-
-(defun xah-clear-register-1 ()
- "Clear register 1.
-
-See also:
-`xah-copy-to-register-1'
-`xah-append-to-register-1'
-`xah-paste-from-register-1'
-`xah-clear-register-1'
-
-URL `http://xahlee.info/emacs/emacs/elisp_copy-paste_register_1.html'
-Created: 2015-12-08
-Version: 2023-04-07"
- (interactive)
- (progn
- (copy-to-register ?1 (point-min) (point-min))
- (message "Cleared register 1.")))
-
-;; HHHH------------------------------
-;; insertion commands
-
-(defun xah-insert-date ()
- "Insert current date time.
-Insert date in this format: yyyy-mm-dd.
-If `universal-argument' is called first, prompt for a format to use.
-If there is selection, delete it first.
-
-URL `http://xahlee.info/emacs/emacs/elisp_insert-date-time.html'
-Created: 2013-05-10
-Version: 2025-03-07"
- (interactive)
- (let (xmenu xstyle)
- (setq
- xmenu
- '(("ISO date • 2018-04-12" . (format-time-string "%Y-%m-%d"))
- ("all digits datetime • 20180412224611" . (format-time-string "%Y%m%d%H%M%S"))
- ("date _ time digits • 2018-04-12_224611" . (format-time-string "%Y-%m-%d_%H%M%S"))
- ("ISO datetime full • 2018-04-12T22:46:11-07:00" .
- (concat
- (format-time-string "%Y-%m-%dT%T")
- (funcall (lambda (xx) (format "%s:%s" (substring xx 0 3) (substring xx 3 5)))
- (format-time-string "%z"))))
- ("ISO datetime w space • 2018-04-12 22:46:11-07:00" .
- (concat
- (format-time-string "%Y-%m-%d %T")
- (funcall
- (lambda (xx) (format "%s:%s" (substring xx 0 3) (substring xx 3 5)))
- (format-time-string "%z"))))
- ("ISO date + weekday • 2018-04-12 Thursday" . (format-time-string "%Y-%m-%d %A"))
- ("USA date + weekday • Thursday, April 12, 2018" . (format-time-string "%A, %B %d, %Y"))
- ("USA date + weekday abbrev • Thu, Apr 12, 2018" . (format-time-string "%a, %b %d, %Y"))
- ("USA date • April 12, 2018" . (format-time-string "%B %d, %Y"))
- ("USA date abbrev • Apr 12, 2018" . (format-time-string "%b %d, %Y")))
-
- xstyle
- (if current-prefix-arg
- (let ((completion-ignore-case t))
- (completing-read "Style:" xmenu nil t nil nil (caar xmenu)))
- (caar xmenu)))
- (when (region-active-p) (delete-region (region-beginning) (region-end)))
- (insert (eval (cdr (assoc xstyle xmenu))))))
-
-(defun xah-insert-bracket-pair (LBracket RBracket &optional WrapMethod)
- "Insert brackets around selection, word, at point, and maybe move cursor in between.
-
- LBracket and RBracket are strings. WrapMethod must be either `line' or `block'. `block' means between empty lines.
-
-• If there is a active region, wrap around region.
-Else
-• If WrapMethod is `line', wrap around line.
-• If WrapMethod is `block', wrap around block.
-Else
-• If cursor is at beginning of line and its not empty line and contain at least 1 space, wrap around the line.
-• If cursor is at end of a word or buffer, one of the following will happen:
- xyz▮ → xyz(▮)
- xyz▮ → (xyz▮) if in one of the lisp modes.
-• wrap brackets around word if any. e.g. xy▮z → (xyz▮). Or just (▮)
-
-URL `http://xahlee.info/emacs/emacs/elisp_insert_brackets_by_pair.html'
-Created: 2017-01-17
-Version: 2025-03-25"
- (if (region-active-p)
- (progn
- (let ((xbeg (region-beginning)) (xend (region-end)))
- (goto-char xend) (insert RBracket)
- (goto-char xbeg) (insert LBracket)
- (goto-char (+ xend 2))))
- (let (xbeg xend)
- (cond
- ((eq WrapMethod 'line)
- (setq xbeg (line-beginning-position) xend (line-end-position))
- (goto-char xend)
- (insert RBracket)
- (goto-char xbeg)
- (insert LBracket)
- (goto-char (+ xend (length LBracket))))
- ((eq WrapMethod 'block)
- (save-excursion
- (seq-setq (xbeg xend) (if (region-active-p) (list (region-beginning) (region-end)) (list (save-excursion (if (re-search-backward "\n[ \t]*\n" nil 1) (match-end 0) (point))) (save-excursion (if (re-search-forward "\n[ \t]*\n" nil 1) (match-beginning 0) (point))))))
- (goto-char xend)
- (insert RBracket)
- (goto-char xbeg)
- (insert LBracket)
- (goto-char (+ xend (length LBracket)))))
- ( ; do line. line must contain space
- (and
- (eq (point) (line-beginning-position))
- (not (eq (line-beginning-position) (line-end-position))))
- (insert LBracket)
- (end-of-line)
- (insert RBracket))
- ((and
- (or ; cursor is at end of word or buffer. i.e. xyz▮
- (looking-at "[^-_[:alnum:]]")
- (eq (point) (point-max)))
- (not (or
- (eq major-mode 'xah-elisp-mode)
- (eq major-mode 'emacs-lisp-mode)
- (eq major-mode 'lisp-mode)
- (eq major-mode 'lisp-interaction-mode)
- (eq major-mode 'common-lisp-mode)
- (eq major-mode 'clojure-mode)
- (eq major-mode 'xah-clojure-mode)
- (eq major-mode 'scheme-mode))))
- (progn
- (setq xbeg (point) xend (point))
- (insert LBracket RBracket)
- (search-backward RBracket)))
- (t (progn
- ;; wrap around “word”. basically, want all alphanumeric, plus hyphen and underscore, but don't want space or punctuations. Also want chinese chars
- ;; 我有一帘幽梦,不知与谁能共。多少秘密在其中,欲诉无人能懂。
- (skip-chars-backward "-_[:alnum:]")
- (setq xbeg (point))
- (skip-chars-forward "-_[:alnum:]")
- (setq xend (point))
- (goto-char xend)
- (insert RBracket)
- (goto-char xbeg)
- (insert LBracket)
- (goto-char (+ xend (length LBracket)))))))))
-
-(defun xah-insert-paren () (interactive) (xah-insert-bracket-pair "(" ")"))
-(defun xah-insert-square-bracket () (interactive) (xah-insert-bracket-pair "[" "]"))
-(defun xah-insert-brace () (interactive) (xah-insert-bracket-pair "{" "}"))
-
-(defun xah-insert-ascii-double-quote () (interactive) (xah-insert-bracket-pair "\"" "\""))
-(defun xah-insert-ascii-single-quote () (interactive) (xah-insert-bracket-pair "'" "'"))
-(defun xah-insert-ascii-angle-bracket () (interactive) (xah-insert-bracket-pair "<" ">"))
-
-(defun xah-insert-emacs-quote () (interactive) (xah-insert-bracket-pair "`" "'"))
-(defun xah-insert-markdown-quote () (interactive) (xah-insert-bracket-pair "`" "`"))
-(defun xah-insert-markdown-triple-quote () (interactive) (xah-insert-bracket-pair "```\n" "\n```"))
-
-(defun xah-insert-double-curly-quote“” () (interactive) (xah-insert-bracket-pair "“" "”"))
-(defun xah-insert-curly-single-quote‘’ () (interactive) (xah-insert-bracket-pair "‘" "’"))
-(defun xah-insert-single-angle-quote‹› () (interactive) (xah-insert-bracket-pair "‹" "›"))
-(defun xah-insert-double-angle-quote«» () (interactive) (xah-insert-bracket-pair "«" "»"))
-
-(defun xah-insert-corner-bracket「」 () (interactive) (xah-insert-bracket-pair "「" "」"))
-(defun xah-insert-white-corner-bracket『』 () (interactive) (xah-insert-bracket-pair "『" "』"))
-(defun xah-insert-angle-bracket〈〉 () (interactive) (xah-insert-bracket-pair "〈" "〉"))
-(defun xah-insert-double-angle-bracket《》 () (interactive) (xah-insert-bracket-pair "《" "》"))
-(defun xah-insert-white-lenticular-bracket〖〗 () (interactive) (xah-insert-bracket-pair "〖" "〗"))
-(defun xah-insert-black-lenticular-bracket【】 () (interactive) (xah-insert-bracket-pair "【" "】"))
-(defun xah-insert-tortoise-shell-bracket〔〕 () (interactive) (xah-insert-bracket-pair "〔" "〕"))
-(defun xah-insert-deco-angle-bracket❮❯ () (interactive) (xah-insert-bracket-pair "❮" "❯"))
-(defun xah-insert-deco-angle-fat-bracket❰❱ () (interactive) (xah-insert-bracket-pair "❰" "❱"))
-
-(defun xah-insert-hyphen ()
- "Insert a HYPHEN-MINUS character."
- (interactive)
- (insert "-"))
-
-(defun xah-insert-low-line ()
- "Insert a LOW LINE character."
- (interactive)
- (insert "_"))
-
-(defun xah-insert-string-assignment ()
- "Insert =\"\""
- (interactive)
- (progn (insert "=\"\"")
- (left-char)))
-
-(defun xah-insert-space-before ()
- "Insert space before cursor."
- (interactive)
- (insert " "))
-
-(defun xah-insert-space-after ()
- "Insert space after cursor"
- (interactive)
- (insert " ")
- (left-char))
-
-(defun xah-insert-seperator ()
- "Insert a visual seperator line."
- (interactive)
- (cond
- ((and buffer-file-name (string-equal "html" (file-name-extension buffer-file-name))) (insert " \n"))
- ((not comment-start)
- (insert "\nHHHH------------------------------\n"))
- (t (insert "\nHHHH------------------------------\n")
- (backward-char)
- (comment-line 1))))
-
-(defvar xah-unicode-list nil
- "A alist.
-Each item is (prompStr . xString). Used by `xah-insert-unicode'.
-prompStr is used for prompt.
-xString is is the char to insert.
-xString can be multiple chars or any string.
-")
-
-(setq
- xah-unicode-list
- '(
- ;;
- ("smile beaming 😊" . "😊")
- ("tears of joy" . "😂")
- ("hug 🤗" . "🤗")
- ("heart eyes 😍" . "😍")
- ("heart face 🥰" . "🥰")
- ("angry 😠" . "😠")
- ("vomit 🤮" . "🤮")
- ("thumb up 👍" . "👍")
- ("thumb down 👎" . "👎")
- ("tv 📺" . "📺")
- ("checkmark ✅" . "✅")
- ("new 🆕" . "🆕")
- ("glowing star 🌟" . "🌟")
- ("star ⭐" . "⭐")
- ("sparkles ✨" . "✨")
- ("rocket 🚀" . "🚀")
- ("sun 🌞" . "🌞")
- ("heart 🧡" . "🧡")
- ("clown 🤡" . "🤡")
- ("large circle" . "⭕")
- ("cross ❌" . "❌")
- ("red triangle 🔺" . "🔺")
- ("diamond 💠" . "💠")
- ("square ⬛" . "⬛")
- ("script 📜" . "📜")
- ("package 📦" . "📦")
- ("cursor ▮" . "▮")
- ("music 🎵" . "🎵")
-
- ("dagger †" . "†")
- ("double dagger ‡" . "‡")
-
- ("double angle bracket" . "《》")
- ("black lenticular bracket" . "【】")
- ("corner-bracket" . "「」")
- ("tortoise shell bracket" . "〔〕")
- ("angle bracket" . "〈〉")
- ("double angle quote" . "«»")
-
- ("bullet •" . "•")
- ("diamond ◆" . "◆")
- ("...ellipsis …" . "…")
- ("nbsp non breaking space" . " ")
- ("chinese comma 、" . "、")
- ("emdash —" . "—")
- ("fullwidth ampersand &" . "&")
- ("left arrow ←" . "←")
- ("right arrow →" . "→")
- ("up arrow ↑" . "↑")
- ("down arrow ↓" . "↓")
- ("f hook ƒ" . "ƒ")
- ("chinese space" . " ")
-
- ;;
- ))
-
-(defun xah-insert-unicode ()
- "Insert a unicode from a custom list `xah-unicode-list'.
-URL `http://xahlee.info/emacs/emacs/emacs_insert_unicode.html'
-Created: 2021-01-05
-Version: 2023-09-19"
- (interactive)
- (let ((xkey
- (let ((completion-ignore-case t))
- (completing-read "Insert:" xah-unicode-list nil t))))
- (insert (cdr (assoc xkey xah-unicode-list)))))
-
-;; HHHH------------------------------
-;; text selection
-
-(defun xah-select-block ()
- "Select the current/next block plus 1 blankline.
-If region is active, extend selection downward by block.
-
-URL `http://xahlee.info/emacs/emacs/emacs_select_text_block.html'
-Created: 2019-12-26
-Version: 2023-11-14"
- (interactive)
- (if (region-active-p)
- (re-search-forward "\n[ \t]*\n[ \t]*\n*" nil :move)
- (progn
- (skip-chars-forward " \n\t")
- (when (re-search-backward "\n[ \t]*\n" nil :move)
- (goto-char (match-end 0)))
- (push-mark (point) t t)
- (re-search-forward "\n[ \t]*\n" nil :move))))
-
-(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/emacs_select_line.html'
-Created: 2017-11-01
-Version: 2023-11-14"
- (interactive)
- (if (region-active-p)
- (if visual-line-mode
- (let ((xbeg (point)))
- (end-of-visual-line 1)
- (when (eq xbeg (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)))))
-
-(defun xah-extend-selection ()
- "Select the current word, bracket/quote expression, or expand selection.
-Subsequent calls expands the selection.
-
-when there is no selection,
-• If cursor is on any type of bracket (including parenthesis, quotation mark), select whole bracketed thing including bracket
-• else, select current word.
-
-when there is a selection, the selection extension behavior is still experimental. But when cursor is on a any type of bracket (parenthesis, quote), it extends selection to outer bracket.
-
-URL `http://xahlee.info/emacs/emacs/emacs_extend_selection.html'
-Created: 2020-02-04
-Version: 2023-11-14"
- (interactive)
-
- (cond
- ((region-active-p)
- (let ((xbeg (region-beginning)) (xend (region-end)))
- (goto-char xbeg)
- (cond
- ((looking-at "\\s(")
- (if (eq (nth 0 (syntax-ppss)) 0)
- (progn
- ;; (message "debug: left bracket, depth 0.")
- (end-of-line) ; select current line
- (push-mark (line-beginning-position) t t))
- (progn
- ;; (message "debug: left bracket, depth not 0")
- (up-list -1 t t)
- (mark-sexp))))
- ((eq xbeg (line-beginning-position))
- (progn
- (goto-char xbeg)
- (let ((xfirstLineEndPos (line-end-position)))
- (cond
- ((eq xend xfirstLineEndPos)
- (progn
- ;; (message "debug: exactly 1 line. extend to next whole line." )
- (forward-line 1)
- (end-of-line)))
- ((< xend xfirstLineEndPos)
- (progn
- ;; (message "debug: less than 1 line. complete the line." )
- (end-of-line)))
- ((> xend xfirstLineEndPos)
- (progn
- ;; (message "debug: beginning of line, but end is greater than 1st end of line" )
- (goto-char xend)
- (if (eq (point) (line-end-position))
- (progn
- ;; (message "debug: exactly multiple lines" )
- (forward-line 1)
- (end-of-line))
- (progn
- ;; (message "debug: multiple lines but end is not eol. make it so" )
- (goto-char xend)
- (end-of-line)))))
- (t (error "%s: logic error 42946" real-this-command))))))
- ((and (> (point) (line-beginning-position)) (<= (point) (line-end-position)))
- (progn
- ;; (message "debug: less than 1 line" )
- (end-of-line) ; select current line
- (push-mark (line-beginning-position) t t)))
- (t
- ;; (message "debug: last resort" )
- nil))))
-
- ((looking-at "\\s(")
- ;; (message "debug: left bracket")
- (mark-sexp))
-
- ((looking-at "\\s)")
- ;; (message "debug: right bracket")
- (backward-up-list) (mark-sexp))
-
- ((looking-at "\\s\"")
- ;; (message "debug: string quote")
- (mark-sexp))
-
- ((looking-at "[ \t\n]")
- ;; (message "debug: is white space")
- (skip-chars-backward " \t\n")
- (push-mark)
- (skip-chars-forward " \t\n")
- (setq mark-active t))
-
- ((looking-at "[-_a-zA-Z0-9]")
- ;; (message "debug: left is word or symbol")
- (skip-chars-backward "-_a-zA-Z0-9")
- (push-mark)
- (skip-chars-forward "-_a-zA-Z0-9")
- (setq mark-active t))
-
- ;; ((and (looking-at "[[:blank:]]")
- ;; (prog2 (backward-char) (looking-at "[[:blank:]]") (forward-char)))
- ;; ;; (message "debug: left and right both space" )
- ;; (skip-chars-backward "[[:blank:]]") (push-mark (point) t t)
- ;; (skip-chars-forward "[[:blank:]]"))
-
- ((and (looking-at "\n")
- (eq (char-before) 10))
- ;; (message "debug: left and right both newline")
- (skip-chars-forward "\n")
- (push-mark (point) t t)
- (re-search-forward "\n[ \t]*\n"))
-
- (t
- ;; (message "debug: just mark sexp" )
- (mark-sexp)
- (exchange-point-and-mark))))
-
-(defun xah-select-text-in-quote ()
- "Select text between the nearest left and right delimiters.
-Delimiters here includes QUOTATION MARK, GRAVE ACCENT, and anything in variable `xah-brackets'.
-This command ignores nesting. For example, if text is
-「(a(b)c▮)」
-the selected char is 「c」, not 「a(b)c」.
-
-URL `http://xahlee.info/emacs/emacs/emacs_select_quote_text.html'
-Created: 2020-11-24
-Version: 2023-11-14"
- (interactive)
- (let ((xskipChars (concat "^\"`" (mapconcat #'identity xah-brackets ""))))
- (skip-chars-backward xskipChars)
- (push-mark (point) t t)
- (skip-chars-forward xskipChars)))
-
-(defun xah-cut-text-in-quote ()
- "Cut text between the nearest left and right delimiters.
-See `xah-select-text-in-quote'
-
-Created: 2023-07-23
-Version: 2024-10-02"
- (interactive)
- (let (xbeg xend
- (xskipChars (concat "^\"`" (mapconcat #'identity xah-brackets ""))))
- (skip-chars-backward xskipChars)
- (setq xbeg (point))
- (skip-chars-forward xskipChars)
- (setq xend (point))
- (kill-region xbeg xend)))
-
-;; HHHH------------------------------
-;; misc
-
-(defvar xah-fly-switch-buffer-map nil "repeat key map for `xah-next-user-buffer' etc.")
-(setq xah-fly-switch-buffer-map
- (let ((xkmap (make-sparse-keymap)))
- (define-key xkmap (kbd "") 'xah-previous-emacs-buffer)
- (define-key xkmap (kbd "") 'xah-next-emacs-buffer)
- (define-key xkmap (kbd "") 'xah-previous-user-buffer)
- (define-key xkmap (kbd "") 'xah-next-user-buffer)
- xkmap))
-
-(defun xah-user-buffer-p ()
- "Return t if current buffer is a user buffer, else nil.
-A user buffer has buffer name NOT starts with * or space, and is not dired mode, help mode, etc.
-This function is used by buffer switching command and close buffer command, so that next buffer shown is a user buffer.
-You can override this function to get your idea of “user buffer”.
-Created: 2016-06-18
-Version: 2024-09-23"
- (interactive)
- (cond
- ((string-match "^\*" (buffer-name)) nil)
- ((eq major-mode 'dired-mode) nil)
- ((eq major-mode 'eww-mode) nil)
- ((eq major-mode 'help-mode) nil)
- (t t)))
-
-(defun xah-next-user-buffer ()
- "Switch to the next user buffer.
-User Buffer here is determined by `xah-user-buffer-p'.
-
-Press left or right arrow key to switch to prev next user.
-Press up or down arrow to switch to prev next emacs buffer.
-Any other key to exit.
-
-URL `http://xahlee.info/emacs/emacs/elisp_next_prev_user_buffer.html'
-Created: 2016-06-19
-Version: 2024-09-23"
- (interactive)
- (next-buffer)
- (let ((i 0))
- (while (< i 30)
- (if (not (xah-user-buffer-p))
- (progn (next-buffer)
- (setq i (1+ i)))
- (progn (setq i 100)))))
- (set-transient-map xah-fly-switch-buffer-map))
-
-(defun xah-previous-user-buffer ()
- "Switch to the previous user buffer.
-User Buffer here is determined by `xah-user-buffer-p'.
-
-Press left or right arrow key to switch to prev next user.
-Press up or down arrow to switch to prev next emacs buffer.
-Any other key to exit.
-
-URL `http://xahlee.info/emacs/emacs/elisp_next_prev_user_buffer.html'
-Created: 2016-06-19
-Version: 2024-05-01"
- (interactive)
- (previous-buffer)
- (let ((i 0))
- (while (< i 29)
- (if (not (xah-user-buffer-p))
- (progn (previous-buffer)
- (setq i (1+ i)))
- (progn (setq i 100)))))
- (set-transient-map xah-fly-switch-buffer-map))
-
-(defun xah-next-emacs-buffer ()
- "Switch to the next emacs buffer.
-Emacs buffer here means `xah-user-buffer-p' return nil.
-
-Press left or right arrow key to switch to prev next user.
-Press up or down arrow to switch to prev next emacs buffer.
-Any other key to exit.
-
-URL `http://xahlee.info/emacs/emacs/elisp_next_prev_user_buffer.html'
-Created: 2013-05-22
-Version: 2024-09-16"
- (interactive)
- (next-buffer)
- (let ((i 0))
- (while (and (xah-user-buffer-p) (< i 20))
- (setq i (1+ i)) (next-buffer)))
- (set-transient-map xah-fly-switch-buffer-map))
-
-(defun xah-previous-emacs-buffer ()
- "Switch to the previous emacs buffer.
-Emacs buffer here means `xah-user-buffer-p' return nil.
-
-Press left or right arrow key to switch to prev next user.
-Press up or down arrow to switch to prev next emacs buffer.
-Any other key to exit.
-
-URL `http://xahlee.info/emacs/emacs/elisp_next_prev_user_buffer.html'
-Created: 2013-05-22
-Version: 2024-09-16"
- (interactive)
- (previous-buffer)
- (let ((i 0))
- (while (and (xah-user-buffer-p) (< i 20))
- (setq i (1+ i)) (previous-buffer)))
- (set-transient-map xah-fly-switch-buffer-map))
-
-(defun xah-new-empty-buffer ()
- "Create a new empty buffer.
-Returns the buffer object.
-New buffer is named untitled, untitled<2>, etc.
-
-Warning: new buffer is not prompted for save when killed, see `kill-buffer'.
-Or manually `save-buffer'
-
-URL `http://xahlee.info/emacs/emacs/emacs_new_empty_buffer.html'
-Created: 2017-11-01
-Version: 2022-04-05"
- (interactive)
- (let ((xbuf (generate-new-buffer "untitled")))
- (switch-to-buffer xbuf)
- (funcall initial-major-mode)
- xbuf
- ))
-
-(declare-function minibuffer-keyboard-quit "delsel" ())
-(declare-function org-edit-src-save "org-src" ())
-
-(defcustom xah-recently-closed-buffers-max 40 "The maximum length for `xah-recently-closed-buffers'."
- :type 'integer)
-
-(defvar xah-recently-closed-buffers nil "A Alist of recently closed buffers.
-Each element is (bufferName . filePath).
-The max number to track is controlled by the variable `xah-recently-closed-buffers-max'.")
-
-(defun xah-add-to-recently-closed (&optional BufferName BufferFileName)
- "Add to `xah-recently-closed-buffers'.
-Version: 2023-03-02"
- (let ((xbn (if BufferName BufferName (buffer-name)))
- (xbfn (if BufferFileName BufferFileName buffer-file-name)))
- (setq xah-recently-closed-buffers (cons (cons xbn xbfn) xah-recently-closed-buffers)))
- (when (> (length xah-recently-closed-buffers) xah-recently-closed-buffers-max)
- (setq xah-recently-closed-buffers (butlast xah-recently-closed-buffers 1))))
-
-(defvar xah-create-buffer-backup nil "If true, `xah-close-current-buffer' creates a backup file when closing non-file buffer. Version: 2024-11-09")
-
-(setq xah-create-buffer-backup t)
-
-(defvar xah-temp-dir-path nil "Path to temp dir used by xah commands.
-by default, the value is dir named temp at `user-emacs-directory'.
-Version: 2023-03-21")
-
-(setq xah-temp-dir-path (concat user-emacs-directory "temp/"))
-
-(defun xah-close-current-buffer ()
- "Close the current buffer with possible backup.
-
-• If the buffer is a file and not modified, kill it. If is modified, do nothing. Print a message.
-• If the buffer is not a file, and variable `xah-create-buffer-backup' is true, then save a backup to `xah-temp-dir-path' named untitled_‹datetime›_‹randomhex›.txt.
-
-If `universal-argument' is called first, call `kill-buffer'. (this is useful to force kill.)
-
-If the buffer is a file, add the path to the list `xah-recently-closed-buffers'.
-
-URL `http://xahlee.info/emacs/emacs/elisp_close_buffer_open_last_closed.html'
-Created: 2016-06-19
-Version: 2024-11-09"
- (interactive)
- (widen)
- (cond
- (current-prefix-arg (kill-buffer))
- ;; ((eq major-mode 'minibuffer-inactive-mode) (minibuffer-keyboard-quit))
- ;; ((active-minibuffer-window) (minibuffer-keyboard-quit))
- ((minibufferp (current-buffer)) (minibuffer-keyboard-quit))
-
- ((eq major-mode 'dired-mode)
- (xah-add-to-recently-closed (buffer-name) default-directory)
- (kill-buffer))
-
- ((and buffer-file-name (not (buffer-modified-p)))
- (xah-add-to-recently-closed (buffer-name) buffer-file-name)
- (kill-buffer))
-
- ((and buffer-file-name (buffer-modified-p))
- (message "buffer file modified. Save it first.\n%s" buffer-file-name))
- ((and xah-create-buffer-backup (not buffer-file-name) (xah-user-buffer-p) (not (eq (point-max) 1)))
- (let ((xnewName (format "%suntitled_%s_%x.txt"
- xah-temp-dir-path
- (format-time-string "%Y%m%d_%H%M%S")
- (random #xfffff))))
- (when (not (file-exists-p xah-temp-dir-path)) (make-directory xah-temp-dir-path))
- (write-region (point-min) (point-max) xnewName)
- (xah-add-to-recently-closed (buffer-name) xnewName)
- (kill-buffer)))
- (t (kill-buffer))))
-
-(defun xah-open-last-closed ()
- "Open the last closed file.
-URL `http://xahlee.info/emacs/emacs/elisp_close_buffer_open_last_closed.html'
-Created: 2016-06-19
-Version: 2022-03-22"
- (interactive)
- (if (> (length xah-recently-closed-buffers) 0)
- (find-file (cdr (pop xah-recently-closed-buffers)))
- (progn (message "No recently close buffer in this session."))))
-
-(defun xah-open-recently-closed ()
- "Open recently closed file.
-Prompt for a choice.
-
-URL `http://xahlee.info/emacs/emacs/elisp_close_buffer_open_last_closed.html'
-Created: 2016-06-19
-Version: 2023-09-19"
- (interactive)
- (find-file
- (let ((completion-ignore-case t))
- (completing-read
- "Open:"
- (mapcar (lambda (f) (cdr f)) xah-recently-closed-buffers)
- nil t
- ))))
-
-(defun xah-list-recently-closed ()
- "List recently closed file.
-
-URL `http://xahlee.info/emacs/emacs/elisp_close_buffer_open_last_closed.html'
-Version: 2016-06-19"
- (interactive)
- (let ((xbuf (generate-new-buffer "*recently closed*")))
- (switch-to-buffer xbuf)
- (mapc (lambda (xf) (insert (cdr xf) "\n"))
- xah-recently-closed-buffers)))
-
-(defvar xah-open-file-at-cursor-pre-hook nil "Hook for `xah-open-file-at-cursor'.
-Functions in the hook is called in order, each given the raw input text (path) as arg.
-The first return non-nil, its value is given to `xah-open-file-at-cursor' as input. rest functions in hook is ignored.
-This is useful for transforming certain url into file path. e.g. change
-http://xahlee.info/emacs/index.html
-to
-C:/Users/xah/web/xahlee_info/emacs/index.html
-, so instead of opening in browser, it opens in emacs as file.")
-
-(defun xah-open-file-at-cursor ()
- "Open the file path under cursor.
-
-• If there is selection, use it for path.
-• Path can be {relative, full path, URL}.
-• If the path starts with 「https*://」, open the URL in browser.
-• Path may have a trailing 「:‹n›」 that indicates line number, or 「:‹n›:‹m›」 with line and column number. If so, jump to that line number.
-
-If path does not have a file extension, automatically try with .el for elisp files.
-
-See also `xah-open-file-at-cursor-pre-hook'.
-
-This command is similar to `find-file-at-point' but without prompting for confirmation.
-
-URL `http://xahlee.info/emacs/emacs/emacs_open_file_path_fast.html'
-Created: 2020-10-17
-Version: 2024-09-25"
- (interactive)
- (let (xinput xinput2 xpath)
- (setq xinput (if (region-active-p)
- (buffer-substring-no-properties (region-beginning) (region-end))
- (let ((xp0 (point)) xbeg xend
- (xpathStops "^ \t\n\"`'‘’“”|()[]{}「」<>〔〕〈〉《》【】〖〗«»‹›❮❯❬❭〘〙·。\\"))
- (skip-chars-backward xpathStops)
- (setq xbeg (point))
- (goto-char xp0)
- (skip-chars-forward xpathStops)
- (setq xend (point))
- (goto-char xp0)
- (buffer-substring-no-properties xbeg xend))))
- (setq xinput2 (if (> (length xah-open-file-at-cursor-pre-hook) 0)
- (let ((xprehook (run-hook-with-args-until-success 'xah-open-file-at-cursor-pre-hook xinput)))
- (if xprehook xprehook xinput))
- xinput))
-
- (setq xpath
- (cond
- ((string-match "\\`file:///[A-Za-z]:/" xinput2) (substring xinput2 8))
- ((string-match "\\`file://[A-Za-z]:/" xinput2) (substring xinput2 7))
- (t xinput2)))
-
- (if (string-match-p "\\`https?://" xpath)
- (browse-url xpath)
- (let ((xpathNoQ
- (let ((xHasQuery (string-match "\?[a-z]+=" xpath)))
- (if xHasQuery
- (substring xpath 0 xHasQuery)
- xpath))))
- (cond
- ((string-match "#" xpathNoQ)
- (let ((xfpath (substring xpathNoQ 0 (match-beginning 0)))
- (xfractPart (substring xpathNoQ (1+ (match-beginning 0)))))
- (if (file-exists-p xfpath)
- (progn
- (find-file xfpath)
- (goto-char (point-min))
- (search-forward xfractPart))
- (progn
- (message "File does not exist. Created at\n%s" xfpath)
- (find-file xfpath)))))
- ((string-match "\\`\\(.+?\\):\\([0-9]+\\)\\(:[0-9]+\\)?\\'" xpathNoQ)
- (let ((xfpath (match-string-no-properties 1 xpathNoQ))
- (xlineNum (string-to-number (match-string-no-properties 2 xpathNoQ))))
- (if (file-exists-p xfpath)
- (progn
- (find-file xfpath)
- (goto-char (point-min))
- (forward-line (1- xlineNum)))
- (progn
- (message "File does not exist. Created at\n%s" xfpath)
- (find-file xfpath)))))
- ((file-exists-p xpathNoQ)
- (progn ; open f.ts instead of f.js
- (let ((xext (file-name-extension xpathNoQ))
- (xfnamecore (file-name-sans-extension xpathNoQ)))
- (if (and (string-equal xext "js")
- (file-exists-p (concat xfnamecore ".ts")))
- (progn
- (find-file (concat xfnamecore ".ts"))
- (warn "Typescript file .ts exist, opening it"))
-
- (find-file xpathNoQ)))))
- ((file-exists-p (concat xpathNoQ ".el"))
- (find-file (concat xpathNoQ ".el")))
- (t (progn
- (message "File does not exist. Created at\n%s" xpathNoQ)
- (find-file xpathNoQ))))))))
-
-;; HHHH------------------------------
-
-(defvar xah-run-current-file-dispatch nil
-"A dispatch table used by `xah-run-current-file' to call dedicated function to run code.
-Value is a association list.
-Each item is (EXT . FUNCTION).
-EXT is filename extension (sans the dot), type string.
-FUNCTION is a elisp function name to call, type symbol.
-If file extension match, and FUNCTION is defined, call it, pass current buffer's filepath as arg.
-Else, `xah-run-current-file-map' is looked up." )
-
-(setq xah-run-current-file-dispatch
- '(("el" . load)
- ("elc" . load)
- ("java" . xah-java-compile-and-run)))
-
-(defvar xah-run-current-file-map
- "A association list that maps file extension to a command for running the file, used by `xah-run-current-file'.
-Each item is (EXT . PROGRAM).
-EXT is filename extension (sans the dot), type string.
-PROGRAM is program name or path, with command options to run a file, type string.
-A filename is appended after the PROGRAM string as external command to call.")
-
-(setq xah-run-current-file-map
- '(
- ;; following are tested as of 2024-12-20
-
- ("fs" . "dotnet fsi")
- ("fsx" . "dotnet fsi")
- ("go" . "go run")
- ("js" . "deno run")
- ("php" . "php")
- ("pl" . "perl")
- ("ps1" . "pwsh")
- ("py" . "python")
- ("py2" . "python2")
- ("py3" . "python3")
- ("rb" . "ruby")
- ("ts" . "deno run")
- ("m" . "wolframscript -print all -file")
- ("wl" . "wolframscript -print all -file")
- ("wls" . "wolframscript -print all -file")
-
- ;; following may be outdated
-
- ("clj" . "clj")
- ("hs" . "runhaskell")
- ("latex" . "pdflatex")
- ("ml" . "ocaml")
- ("rkt" . "racket")
- ("sh" . "bash")
- ("tex" . "pdflatex")
- ("tsx" . "tsc")
- ("vbs" . "cscript")
- ("pov" . "povray +R2 +A0.1 +J1.2 +Am2 +Q9 +H480 +W640")))
-
-(defun xah-java-compile-and-run (Filename)
- "Compile and run java of current buffer.
-Buffer is saved first if modified.
-
-This command is designed for a simple single java class source file.
-requires the commands 「javac」 and 「java」.
-
-If compile fails, the error is displayed in a buffer.
-
-Created: 2024-12-20
-Version: 2024-12-20"
- (interactive (if buffer-file-name (progn (when (buffer-modified-p) (save-buffer)) (list buffer-file-name)) (user-error "Buffer is not file. Save it first.")))
- (let ((xoutbuf (get-buffer-create "*xah java output*" t))
- (xjavac-buf (get-buffer-create "*xah java compile output*" t)))
- (with-current-buffer xjavac-buf (erase-buffer))
- (call-process "javac" nil xjavac-buf nil Filename)
- (if (eq 1 (with-current-buffer xjavac-buf (point-max)))
- (progn
- (save-current-buffer (set-buffer xoutbuf) (erase-buffer))
- (call-process "java" nil xoutbuf nil (file-name-nondirectory (file-name-sans-extension Filename)))
- (display-buffer xoutbuf))
- (display-buffer xjavac-buf))))
-
-(defun xah-run-current-file (Filename)
- "Execute the current file.
-Output is printed to buffer *xah-run output*.
-
-File suffix is used to determine what external command to run, in the variable `xah-run-current-file-map'.
-
-If file is modified, it is auto saved before run.
-
-The variable `xah-run-current-file-dispatch' allows you to customize this command to call other function to run the current file.
-
-URL `http://xahlee.info/emacs/emacs/elisp_run_current_file.html'
-Created: 2020-09-24
-Version: 2024-12-25"
- (interactive (if buffer-file-name (progn (when (buffer-modified-p) (save-buffer)) (list buffer-file-name)) (user-error "Buffer is not file. Save it first.")))
- (let ((xoutbuf (get-buffer-create "*xah-run output*" t))
- (xext (file-name-extension Filename))
- xdispatch)
- (setq xdispatch (assoc xext xah-run-current-file-dispatch))
- (if xdispatch
- (if (fboundp (cdr xdispatch))
- (progn
- (message "calling %s" (cdr xdispatch))
- (funcall (cdr xdispatch) Filename))
- (warn "`xah-run-current-file' found function %s in xah-run-current-file-dispatch but it is unbound. Normal run continues using `xah-run-current-file-map'." xdispatch))
- (let ((xappCmdStr (cdr (assoc xext xah-run-current-file-map))))
- (when (not xappCmdStr) (error "%s: Unknown file extension: %s. check `xah-run-current-file-map'" real-this-command xext))
- (progn
- (save-current-buffer (set-buffer xoutbuf) (erase-buffer))
- (apply 'start-process (append (list "xah-run" xoutbuf) (split-string xappCmdStr " +" t) (list Filename) nil))
- ;; (display-buffer xoutbuf)
- (pop-to-buffer xoutbuf)
- ;; (with-current-buffer xoutbuf (goto-char (point-min)))
- )))))
-
-(defun xah-clean-empty-lines ()
- "Replace repeated blank lines to just 1, in whole buffer or selection.
-Respects `narrow-to-region'.
-
-URL `http://xahlee.info/emacs/emacs/elisp_compact_empty_lines.html'
-Created: 2017-09-22
-Version: 2020-09-08"
- (interactive)
- (let (xbegin xend)
- (if (region-active-p)
- (setq xbegin (region-beginning) xend (region-end))
- (setq xbegin (point-min) xend (point-max)))
- (save-excursion
- (save-restriction
- (narrow-to-region xbegin xend)
- (progn
- (goto-char (point-min))
- (while (re-search-forward "\n\n\n+" nil :move)
- (replace-match "\n\n")))))))
-
-(defun xah-clean-whitespace ()
- "Delete trailing whitespace, and replace repeated blank lines to just 1.
-Only space and tab is considered whitespace here.
-Works on whole buffer or selection, respects `narrow-to-region'.
-
-URL `http://xahlee.info/emacs/emacs/elisp_compact_empty_lines.html'
-Created: 2017-09-22
-Version: 2022-08-06"
- (interactive)
- (let (xbegin xend)
- (if (region-active-p)
- (setq xbegin (region-beginning) xend (region-end))
- (setq xbegin (point-min) xend (point-max)))
- (save-excursion
- (save-restriction
- (narrow-to-region xbegin xend)
- (goto-char (point-min))
- (while (re-search-forward "[ \t]+\n" nil :move) (replace-match "\n"))
- (goto-char (point-min))
- (while (re-search-forward "\n\n\n+" nil :move) (replace-match "\n\n"))
- (goto-char (point-max))
- (while (eq (char-before) 32) (delete-char -1)))))
- (message "%s done" real-this-command))
-
-(defun xah-make-backup ()
- "Make a backup copy of current file or dired marked files.
-If in dired, backup current file or marked files.
-
-The backup file name is the original name with the datetime .yyyymmddhhmmss~ appended.
-
-Overwrite existing file.
-
-If the current buffer is not associated with a file, do nothing.
-
-URL `http://xahlee.info/emacs/emacs/elisp_make-backup.html'
-Created: 2018-06-06
-Version: 2024-10-21"
- (interactive)
- (let ((xfname buffer-file-name)
- (xtimestamp (format-time-string "%Y%m%d%H%M%S")))
- (if xfname
- (let ((xbackupName
- (concat xfname "." xtimestamp "~")))
- (copy-file xfname xbackupName t)
- (message (concat "\nBackup saved at: " xbackupName)))
- (if (eq major-mode 'dired-mode)
- (progn
- (mapc (lambda (xx)
- (let ((xbackupName
- (concat xx "." xtimestamp "~")))
- (copy-file xx xbackupName t)))
- (dired-get-marked-files))
- (revert-buffer))
- (user-error "%s: buffer not file nor dired" real-this-command)))))
-
-(defun xah-make-backup-and-save ()
- "Backup of current file and save, or backup dired marked files.
-For detail, see `xah-make-backup'.
-If the current buffer is not associated with a file nor dired, nothing's done.
-
-URL `http://xahlee.info/emacs/emacs/elisp_make-backup.html'
-Version: 2015-10-14"
- (interactive)
- (if buffer-file-name
- (progn
- (xah-make-backup)
- (when (buffer-modified-p)
- (save-buffer)))
- (progn
- (xah-make-backup))))
-
-(defun xah-delete-current-file-make-backup ()
- "Makes a backup~, delete current file, close the buffer.
-
-Backup filename is ‹name›.‹dateTimeStamp›~
-Overwrite existing file.
-
-If buffer is not a file, copy content to `kill-ring', delete buffer.
-
-If buffer is not a file, the backup file name starts with “xx_”.
-
-Call `xah-open-last-closed' to open the backup file.
-
-URL `http://xahlee.info/emacs/emacs/elisp_delete-current-file.html'
-Created: 2018-05-15
-Version: 2024-10-21"
- (interactive)
- (when (eq major-mode 'dired-mode)
- (user-error "%s: In dired. Nothing is done." real-this-command))
- (let ((xfname buffer-file-name)
- (xbuffname (buffer-name)))
- (if xfname
- (let ((xbackupPath
- (concat
- xfname "."
- (format-time-string "%Y%m%d%H%M%S") "~")))
- (save-buffer xfname)
- (kill-buffer xbuffname)
- (rename-file xfname xbackupPath t)
- (message "File deleted.
-Backup at
-%s
-Call `xah-open-last-closed' to open." xbackupPath)
- (when (boundp 'xah-recently-closed-buffers)
- (push (cons nil xbackupPath) xah-recently-closed-buffers)))
- (progn
- (widen)
- (kill-new (buffer-string))
- (kill-buffer xbuffname)
- (message "non-file buffer killed. buffer text copied to `kill-ring'."))))
- (when (eq major-mode 'dired-mode) (revert-buffer)))
-
-;; HHHH------------------------------
-
-(defun xah-search-current-word ()
- "Call `isearch' on current word or selection.
-“word” here is A to Z, a to z, and hyphen [-] and lowline [_], independent of syntax table.
-
-URL `http://xahlee.info/emacs/emacs/modernization_isearch.html'
-Created: 2010-05-29
-Version: 2025-02-21"
- (interactive)
- (let (xbeg xend)
- (if (region-active-p)
- (setq xbeg (region-beginning) xend (region-end))
- (save-excursion
- (skip-chars-backward "-_A-Za-z0-9")
- (setq xbeg (point))
- (right-char)
- (skip-chars-forward "-_A-Za-z0-9")
- (setq xend (point))))
- (deactivate-mark)
- (when (< xbeg (point)) (goto-char xbeg))
- (isearch-mode t)
- (isearch-yank-string (buffer-substring-no-properties xbeg xend))))
-
-(declare-function w32-shell-execute "w32fns.c" (operation document &optional parameters show-flag)) ; (w32-shell-execute "open" default-directory)
-
-(defun xah-show-in-desktop ()
- "Show current file in desktop.
- (Mac Finder, Microsoft Windows File Explorer, Linux file manager)
-This command can be called when in a file buffer or in `dired'.
-
-URL `http://xahlee.info/emacs/emacs/emacs_show_in_desktop.html'
-Created: 2020-11-20
-Version: 2023-09-09"
- (interactive)
- (let ((xpath (if (eq major-mode 'dired-mode)
- (if (eq nil (dired-get-marked-files))
- default-directory
- (car (dired-get-marked-files)))
- (if buffer-file-name buffer-file-name default-directory))))
- (cond
- ((eq system-type 'windows-nt)
- (shell-command (format "PowerShell -Command invoke-item '%s'" default-directory ))
- ;; (let ((xcmd (format "Explorer /select,%s"
- ;; (replace-regexp-in-string "/" "\\" xpath t t)
- ;; ;; (shell-quote-argument (replace-regexp-in-string "/" "\\" xpath t t ))
- ;; )))
- ;; (shell-command xcmd))
- )
- ((eq system-type 'darwin)
- (shell-command
- (concat "open -R " (shell-quote-argument xpath))))
- ((eq system-type 'gnu/linux)
- (call-process shell-file-name nil 0 nil
- shell-command-switch
- (format "%s %s"
- "xdg-open"
- (file-name-directory xpath)))
- ;; (shell-command "xdg-open .") ;; 2013-02-10 this sometimes froze emacs till the folder is closed. eg with nautilus
- ))))
-
-(defun xah-open-in-vscode ()
- "Open current file or dir in vscode.
-URL `http://xahlee.info/emacs/emacs/emacs_open_in_vscode.html'
-
-Created: 2020-02-13
-Version: 2024-12-15"
- (interactive)
- (let ((xpath (or buffer-file-name default-directory)))
- (message "path is %s" xpath)
- (cond
- ((eq system-type 'darwin)
- (shell-command (format "open -a Visual\\ Studio\\ Code.app %s" (shell-quote-argument xpath))))
- ((eq system-type 'windows-nt)
- (shell-command (format "code.cmd %s" (shell-quote-argument xpath))))
- ((eq system-type 'gnu/linux)
- (shell-command (format "code %s" (shell-quote-argument xpath)))))))
-
-(defun xah-open-in-external-app (&optional Fname)
- "Open the current file or dired marked files in external app.
-When called in emacs lisp, if Fname is given, open that.
-
-URL `http://xahlee.info/emacs/emacs/emacs_dired_open_file_in_ext_apps.html'
-Created: 2019-11-04
-Version: 2023-06-26"
- (interactive)
- (let (xfileList xdoIt)
- (setq xfileList
- (if Fname
- (list Fname)
- (if (eq major-mode 'dired-mode)
- (dired-get-marked-files)
- (list buffer-file-name))))
- (setq xdoIt (if (<= (length xfileList) 10) t (y-or-n-p "Open more than 10 files? ")))
- (when xdoIt
- (cond
- ((eq system-type 'windows-nt)
- (let ((xoutBuf (get-buffer-create "*xah open in external app*"))
- (xcmdlist (list "PowerShell" "-Command" "Invoke-Item" "-LiteralPath")))
- (mapc
- (lambda (x)
- (message "%s" x)
- (apply 'start-process (append (list "xah open in external app" xoutBuf) xcmdlist (list (format "'%s'" (if (string-match "'" x) (replace-match "`'" t t x) x))) nil)))
- xfileList)))
- ((eq system-type 'darwin)
- (mapc (lambda (xfpath) (shell-command (concat "open " (shell-quote-argument xfpath)))) xfileList))
- ((eq system-type 'gnu/linux)
- (mapc (lambda (xfpath)
- (call-process shell-file-name nil 0 nil
- shell-command-switch
- (format "%s %s"
- "xdg-open"
- (shell-quote-argument xfpath))))
- xfileList))
- ((eq system-type 'berkeley-unix)
- (mapc (lambda (xfpath) (let ((process-connection-type nil)) (start-process "" nil "xdg-open" xfpath))) xfileList))))))
-
-(defvar xah-fly-mswin-terminal
- "wt"
- "A string. Value should be one of: wt (for Windows Terminal) or pwsh (for PowerShell Core (cross-platform)) or powershell (for Microsoft PowerShell).")
-
-(defun xah-open-in-terminal ()
- "Open the current dir in a new terminal window.
-On Microsoft Windows, which terminal it starts depends on `xah-fly-mswin-terminal'.
-
-URL `http://xahlee.info/emacs/emacs/emacs_open_in_terminal.html'
-Created: 2020-11-21
-Version: 2023-06-26"
- (interactive)
- (cond
- ((eq system-type 'windows-nt)
- (cond
- ((string-equal xah-fly-mswin-terminal "wt")
- (shell-command (format "wt -d \"%s\"" default-directory)))
- ((string-equal xah-fly-mswin-terminal "pwsh")
- (shell-command
- (format "pwsh -Command Start-Process pwsh -WorkingDirectory '%s'" (shell-quote-argument default-directory))))
- ((string-equal xah-fly-mswin-terminal "powershell")
- (shell-command
- (format "powershell -Command Start-Process powershell -WorkingDirectory '%s'" (shell-quote-argument default-directory))))
- (t (error "Error 702919: value of `xah-fly-mswin-terminal' is not expected. Its value is %s" xah-fly-mswin-terminal))))
- ((eq system-type 'darwin)
- (shell-command (concat "open -a terminal " (shell-quote-argument default-directory))))
- ((eq system-type 'gnu/linux)
- (let ((process-connection-type nil)) (start-process "" nil "x-terminal-emulator" (concat "--working-directory=" default-directory))))
- ((eq system-type 'berkeley-unix)
- (let ((process-connection-type nil)) (start-process "" nil "x-terminal-emulator" (concat "--working-directory=" default-directory))))))
-
-(defun xah-next-window-or-frame ()
- "Switch to next window or frame.
-If current frame has only one window, switch to next frame.
-If `universal-argument' is called first, do switch frame.
-Version: 2017-01-27"
- (interactive)
- (if current-prefix-arg
- (other-frame 1)
- (if (one-window-p)
- (other-frame 1)
- (other-window 1))))
-
-(defun xah-unsplit-window-or-next-frame ()
- "Unsplit window. If current frame has only one window, switch to next frame.
-Version: 2017-01-29"
- (interactive)
- (if (one-window-p)
- (other-frame 1)
- (delete-other-windows)))
-
-;; HHHH------------------------------
-;; layout lookup tables for key conversion
-
-(defvar xah-fly-layout-diagrams (make-hash-table :test 'equal)
- "A hashtable.
-Key is string, of keyboard layout name.
-Value is a string, of text-art (aka ASCII-art) form of the layout.
-The text-art string, each key (sequence of chars) is separated by whitespace.
-The string is split by white space, and each item is considered a key.
-The key is usually a single char, can be unicode, but may also be alt ctrl tab shift return and other.
-It is used to generate key conversion table of a key from layout to layout.
-")
-
-(progn
-
- (puthash "adnw" "
-~ ! @ # $ % ^ & * ( ) { }
-` 1 2 3 4 5 6 7 8 9 0 [ ]
-
-k u ü . ä v g c l j f = \\
-h i e a o d t r n s ß
-x y ö , q b p w m z
-
-K U Ü > Ä V G C L J F + |
-H I E A O D T R N S ẞ
-X Y Ö < Q B P W M Z
-" xah-fly-layout-diagrams)
-
- (puthash "azerty"
- "
-~ ! @ # $ % ^ & * ( ) { }
-² & é \" ' ( - è _ ç à ) =
-
-a z e r t y u i o p ^ $ *
-q s d f g h j k l m ù
-w x c v b n , ; : !
-
-A Z E R T Y U I O P ? + |
-Q S D F G H J K L M Ù
-W X C V B N ? . / §
-" xah-fly-layout-diagrams)
-
- (puthash "azerty-be"
- "
-~ ! @ # $ % ^ & * ( ) { }
-² & é \" ' ( § è ! ç à ) -
-
-a z e r t y u i o p ^ $ µ
-q s d f g h j k l m ù
-w x c v b n , ; : =
-
-A Z E R T Y U I O P ^ $ Μ
-Q S D F G H J K L M Ù
-W X C V B N ? . / +
-" xah-fly-layout-diagrams)
-
- (puthash "bepo" "
-# 1 2 3 4 5 6 7 8 9 0 ° `
-$ \" « » ( ) @ + - / * = %
-
-b é p o è ^ v d l j z w \\
-a u i e , c t s r n m
-à y x . k ' q g h f
-
-B É P O È ! V D L J Z W |
-A U I E ; C T S R N M
-À Y X : K ? Q G H F
-" xah-fly-layout-diagrams)
-
- (puthash "colemak" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w f p g j l u y ; [ ] \\
-a r s t d h n e i o '
-z x c v b k m , . /
-
-Q W F P G J L U Y : { } |
-A R S T D H N E I O \"
-Z X C V B K M < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "colemak-dh" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w f p b j l u y ; [ ] \\
-a r s t g m n e i o '
-z x c d v k h , . /
-
-Q W F P B J L U Y : { } |
-A R S T G M N E I O \"
-Z X C D V K H < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "dvorak" "
-~ ! @ # $ % ^ & * ( ) { }
-` 1 2 3 4 5 6 7 8 9 0 [ ]
-
-' , . p y f g c r l / = \\
-a o e u i d h t n s -
-; q j k x b m w v z
-
-\" < > P Y F G C R L ? + |
-A O E U I D H T N S _
-: Q J K X B M W V Z
-" xah-fly-layout-diagrams)
-
- (puthash "engrammer" "
-~ ! @ # $ % ^ & * ( ) { }
-` 1 2 3 4 5 6 7 8 9 0 [ ]
-
-b y o u ' ; l d w v z = \\
-c i e a , . h t s n q
-g x j k - / r m f p
-
-B Y O U \" : L D W V Z + |
-C I E A < > H T S N Q
-G X J K _ ? R M F P
-" xah-fly-layout-diagrams)
-
- (puthash "koy" "
-^ ! @ # $ % ^ & * ( ) _ ~
-˘ 1 2 3 4 5 6 7 8 9 0 - `
-
-k . o , y v g c l ß / = \\
-h a e i u d t r n s f
-x q ä ü ö b p w m j
-
-K > O < Y V G C L ẞ ? + |
-H A E I U D T R N S F
-X Q Ä Ü Ö B P W M J
-" xah-fly-layout-diagrams)
-
- (puthash "halmak" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-w l r b z ; q u d j [ ] \\
-s h n t , . a e o i '
-f m v c / g p x k y
-
-W L R B Z : Q U D J { } |
-S H N T < > A E O I \"
-F M V C ? G P X K Y
-" xah-fly-layout-diagrams)
-
- (puthash "minimak" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w d r k y u i o p [ ] \\
-a s t f g h j e l ; '
-z x c v b n m , . /
-
-Q W D R K Y U I O P { } |
-A S T F G H J E L : \"
-Z X C V B N M < > ?
-" xah-fly-layout-diagrams)
-
- ;; todo. need fix
- (puthash "neo2" "
-^ ! @ # $ % ^ & * ( ) { }
-` 1 2 3 4 5 6 7 8 9 0 - ]
-
-x v l c w k h g f q ß = \\
-u i a e o s n r t d y
-ü ö ä p z b m , . j
-
-X V L C W K H G F Q ? + |
-U I A E O S N R T D Y
-Ü Ö Ä P Z B M , . J
-" xah-fly-layout-diagrams)
-
- (puthash "norman" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w d f k j u r l ; [ ] \\
-a s e t g y n i o h '
-z x c v b p m , . /
-
-Q W D F K J U R L : { } |
-A S E T G Y N I O H \"
-Z X C V B P M < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "programer-dvorak" "
-~ % 7 5 3 1 9 0 2 4 6 8 `
-$ & [ { } ( = * ) + ] ! #
-
-; , . p y f g c r l / @ \\
-a o e u i d h t n s -
-' q j k x b m w v z
-
-: < > P Y F G C R L ? ^ |
-A O E U I D H T N S _
-\" Q J K X B M W V Z
-" xah-fly-layout-diagrams)
-
- (puthash "pt-nativo" "
-* ! \" # $ % & / ( ) = ª >
-+ 1 2 3 4 5 6 7 8 9 0 º <
-
-' , . h x w l t c p ~ - \\
-i e a o u m d s r n ´
-« ç j b k q v g f z
-
-? ; : H X W L T C P ^ _ |
-I E A O U M D S R N `
-Y Ç J B K Q V G F Z
-" xah-fly-layout-diagrams)
-
- (puthash "qfmlwy" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q f m l w y u o b j [ ] \\
-d s t n r i a e h ; '
-z v g c x p k , . /
-
-Q F M L W Y U O B J { } |
-D S T N R I A E H : \"
-Z V G C X P K < > ?
-" xah-fly-layout-diagrams)
-
-(puthash "qgmlwb" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q g m l w b y u v ; [ ] \\
-d s t n r i a e o h '
-z x c f j k p , . /
-
-Q G M L W B Y U V : { } |
-D S T N R I A E O H \"
-Z X C F J K P < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "qwerty" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w e r t y u i o p [ ] \\
-a s d f g h j k l ; '
-z x c v b n m , . /
-
-Q W E R T Y U I O P { } |
-A S D F G H J K L : \"
-Z X C V B N M < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "qwerty-abnt" "
-\" ! @ # $ % ^ & * ( ) _ +
- ' 1 2 3 4 5 6 7 8 9 0 - =
-
-q w e r t y u i o p ´ [ ]
-a s d f g h j k l ç ~
-z x c v b n m , . ;
-
-Q W E R T Y U I O P ` + |
-A S D F G H J K L Ç ^
-Z X C V B N M < > :
-" xah-fly-layout-diagrams)
-
- (puthash "qwerty-no" "
-§ ! \" # ¤ % & / ( ) = ? `
-| 1 2 3 4 5 6 7 8 9 0 + \\
-
-q w e r t y u i o p å ¨ '
-a s d f g h j k l ø æ
-z x c v b n m , . -
-
-Q W E R T Y U I O P Å ^ *
-A S D F G H J K L Ø Æ
-Z X C V B N M < > _
-" xah-fly-layout-diagrams)
-
- (puthash "qwerty-se" "
-§ ! \" # ¤ % & / ( ) = ? `
-| 1 2 3 4 5 6 7 8 9 0 + \\
-
-q w e r t y u i o p å ¨ '
-a s d f g h j k l ö ä
-z x c v b n m , . -
-
-Q W E R T Y U I O P Å ^ *
-A S D F G H J K L Ö Ä
-Z X C V B N M < > _
-" xah-fly-layout-diagrams)
-
- (puthash "qwertz" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w e r t z u i o p [ ] \\
-a s d f g h j k l ; '
-y x c v b n m , . /
-
-Q W E R T Z U I O P { } |
-A S D F G H J K L : \"
-Y X C V B N M < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "qwpr" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q w p r f y u k l ; [ ] \\
-a s d t g h n i o e '
-z x c v b j m , . /
-
-Q W P R F Y U K L : { } |
-A S D T G H N I O E \"
-Z X C V B J M < > ?
-" xah-fly-layout-diagrams)
-
- (puthash "russian" "
-Ё ! \" № ; % : ? * ( ) _ +
-ё 1 2 3 4 5 6 7 8 9 0 - =
-
-й ц у к е н г ш щ з х ъ \\
-ф ы в а п р о л д ж э
-я ч с м и т ь б ю .
-
-Й Ц У К Е Н Г Ш Щ З Х Ъ |
-Ф Ы В А П Р О Л Д Ж Э
-Я Ч С М И Т Ь Б Ю ,
-" xah-fly-layout-diagrams)
-
- (puthash "workman" "
-~ ! @ # $ % ^ & * ( ) _ +
-` 1 2 3 4 5 6 7 8 9 0 - =
-
-q d r w b j f u p ; [ ] \\
-a s h t g y n e o i '
-z x m c v k l , . /
-
-Q D R W B J F U P : { } |
-A S H T G Y N E O I \"
-Z X M C V K L < > ?
-" xah-fly-layout-diagrams))
-
-(defun xah-fly-create-key-conv-table (Layout1 Layout2)
- "Takes two text diagrams Layout1 Layout2, return a hashtable.
-For remapping key from layout1 to layout2.
-
-example:
-
-Layout1 is a string. e.g.
-
-a b c d
-e f shift
-
-Layout2 is a string. e.g.
-
-a o e i
-m n ctrl
-
-return a hashtable, e.g.
-
-b → o
-c → e
-d → i
-e → m
-f → n
-shift → ctrl
-
-If the keys in layouts are the same, it's not in the table.
-
-Created: 2024-04-19
-Version: 2024-04-23"
- (let (xkeys1 xkeys2 (xtable (make-hash-table :test 'equal)))
- (setq xkeys1 (split-string Layout1 "[ \n]+" t))
- (setq xkeys2 (split-string Layout2 "[ \n]+" t))
- (when (not (eq (length xkeys1) (length xkeys2)))
- (error "layout %s and %s lengths not same." (length Layout1) (length Layout2)))
- (seq-mapn
- (lambda (x y)
- (if (string-equal x y)
- nil
- (puthash x y xtable)))
- xkeys1 xkeys2)
- xtable
- ))
-
-;; (xah-fly-create-key-conv-table
-;; (gethash "qwerty" xah-fly-layout-diagrams)
-;; (gethash "dvorak" xah-fly-layout-diagrams))
-
-(defvar xah-fly-key-current-layout nil
- "The current keyboard layout.
-Value is a key in `xah-fly-layout-diagrams'.
-Do not set this variable manually.
-Use `xah-fly-keys-set-layout' to set it.
-Default to qwerty.
-Version: 2022-10-22")
-
-(if xah-fly-key-current-layout nil (setq xah-fly-key-current-layout "qwerty"))
-
-(defvar xah-fly--key-convert-table nil
- "A alist that's the conversion table from dvorak to current layout.
-Value is a hashtable.
-Created: 2019-02-12
-Version: 2024-04-22" )
-
-(setq
- xah-fly--key-convert-table
- (xah-fly-create-key-conv-table
- (gethash "dvorak" xah-fly-layout-diagrams)
- (gethash xah-fly-key-current-layout xah-fly-layout-diagrams)))
-
-(defun xah-fly--convert-key (Keystr)
- "Return the corresponding Keystr according to variable `xah-fly--key-convert-table'.
-Keystr must be a string that is the valid argument to `kbd'.
-Keystr may be a single key, or key sequence separated by whitespaces.
-Created: 2022-10-25
-Version: 2024-04-22"
- (interactive)
- (mapconcat
- 'identity
- (mapcar
- (lambda (x)
- (let ((xnew (gethash x xah-fly--key-convert-table)))
- (if xnew xnew x)))
- (split-string Keystr " +"))
- " "))
-
-(defun xah-fly--define-keys (KeymapName KeyCmdAlist &optional Direct-p)
- "Map `define-key' over a alist KeyCmdAlist, with key layout remap.
-The key is remapped from Dvorak to the current keyboard layout by `xah-fly--convert-key'.
-If Direct-p is t, do not remap key to current keyboard layout.
-Example usage:
- (xah-fly--define-keys
- (define-prefix-command \\='xyz-map)
- \\='(
- (\"h\" . highlight-symbol-at-point)
- (\".\" . isearch-forward-symbol-at-point)
- (\"w\" . isearch-forward-word)))
-Created: 2020-04-18
-Version: 2023-08-21"
- (mapcar
- (lambda (x)
- (define-key
- KeymapName
- (kbd (if Direct-p (car x) (xah-fly--convert-key (car x))))
- (cdr x)))
- KeyCmdAlist))
-
-;; HHHH------------------------------
-;; keymaps
-
-(defvar xah-fly-key-map (make-sparse-keymap)
- "If `xah-fly-insert-state-p' is true, point to `xah-fly-insert-map', else, points to `xah-fly-command-map'.")
-
-(defvar xah-fly-command-map (make-sparse-keymap)
- "Keymap when in command mode.")
-
-(defvar xah-fly-insert-map (make-sparse-keymap)
- "Keymap when in insert mode.")
-
-(defvar xah-fly--deactivate-command-mode-func nil)
-
-;; HHHH------------------------------
-;; setting keys
-
-(defun xah-fly-define-keys ()
- "Define the keys for xah-fly-keys.
-Created: 2022-10-31
-Version: 2024-04-22"
- (interactive)
- (let ()
-
- ;; Movement key integrations with built-in Emacs packages
- (xah-fly--define-keys
- indent-rigidly-map
- '(("h" . indent-rigidly-left)
- ("n" . indent-rigidly-right)))
-
- (xah-fly--define-keys
- xah-fly-command-map
- '(("" . xah-fly-command-mode-activate)
- ("" . xah-fly-command-mode-activate)
- ("" . xah-fly-command-mode-activate))
- :direct)
-
- (xah-fly--define-keys
- xah-fly-insert-map
- '(("" . xah-fly-command-mode-activate)
- ("" . xah-fly-command-mode-activate)
- ("" . xah-fly-command-mode-activate))
- :direct)
-
- (when xah-fly-use-isearch-arrows
- (xah-fly--define-keys
- isearch-mode-map
- '(("" . isearch-ring-retreat)
- ("" . isearch-ring-advance)
- ("" . isearch-repeat-backward)
- ("" . isearch-repeat-forward)
- ("C-v" . isearch-yank-kill))
- :direct)
- (xah-fly--define-keys
- minibuffer-local-isearch-map
- '(("" . isearch-reverse-exit-minibuffer)
- ("" . isearch-forward-exit-minibuffer))
- :direct))
-
- (xah-fly--define-keys
- (define-prefix-command 'xah-fly-leader-key-map)
- '(("SPC" . xah-fly-insert-mode-activate)
- ("RET" . execute-extended-command)
-
- ("TAB" . nil)
-
- ("TAB TAB" . indent-for-tab-command)
-
- ("TAB i" . complete-symbol)
- ("TAB g" . indent-rigidly)
- ("TAB r" . indent-region)
- ("TAB s" . indent-sexp)
-
- (". ." . highlight-symbol-at-point)
- (". g" . unhighlight-regexp)
- (". c" . highlight-lines-matching-regexp)
- (". h" . highlight-regexp)
- (". t" . highlight-phrase)
- (". e" . isearch-forward-symbol-at-point)
- (". u" . isearch-forward-symbol)
- (". p" . isearch-forward-word)
-
- ("'" . xah-fill-or-unfill)
-
- (", t" . xref-find-definitions)
- (", n" . xref-pop-marker-stack)
-
- ;; - / ; = [
- ("\\" . toggle-input-method)
- ;; `
-
- ("3" . delete-window)
- ("4" . split-window-right)
- ("5" . balance-windows)
- ("6" . xah-upcase-sentence)
-
- ("9" . ispell-word)
-
- ("a" . mark-whole-buffer)
- ("b" . end-of-buffer)
-
- ("c ," . xah-open-in-external-app)
- ("c ." . find-file)
- ("c c" . bookmark-bmenu-list)
- ("c e" . ibuffer)
- ("c f" . xah-open-recently-closed)
- ("c g" . xah-open-in-terminal)
- ("c h" . recentf-open-files)
- ("c j" . xah-copy-file-path)
- ("c l" . bookmark-set)
- ("c n" . xah-new-empty-buffer)
- ("c o" . xah-show-in-desktop)
- ("c p" . xah-open-last-closed)
- ("c r" . bookmark-jump)
- ("c s" . write-file)
- ("c u" . xah-open-file-at-cursor)
- ("c x" . set-buffer-file-coding-system)
- ("c y" . xah-list-recently-closed)
- ("c z" . revert-buffer-with-coding-system)
-
- ;; set-buffer-process-coding-system
- ;; set-file-name-coding-system
- ;; set-keyboard-coding-system
- ;; set-language-environment
- ;; set-next-selection-coding-system
- ;; set-selection-coding-system
- ;; set-terminal-coding-system
- ;; universal-coding-system-argument
-
- ("d" . beginning-of-buffer)
-
- ("e 6" . xah-insert-white-corner-bracket『』)
-
- ("e a" . xah-insert-double-angle-bracket《》)
- ("e b" . xah-insert-black-lenticular-bracket【】)
-
- ("e c r" . expand-region-abbrevs)
- ("e c t" . edit-abbrevs)
- ("e c u" . expand-abbrev)
-
- ("e c g" . add-mode-abbrev)
- ("e c c" . add-global-abbrev)
- ("e c m" . inverse-add-mode-abbrev)
- ("e c w" . inverse-add-global-abbrev)
-
- ("e c f" . unexpand-abbrev)
-
- ("e c h" . expand-jump-to-previous-slot)
- ("e c n" . expand-jump-to-next-slot)
- ("e c y" . abbrev-prefix-mark)
-
- ("e d" . xah-insert-double-curly-quote“”)
- ("e e" . xah-insert-unicode)
- ("e f" . xah-insert-emacs-quote)
- ("e g" . xah-insert-ascii-double-quote)
-
- ("e h" . xah-insert-brace)
- ("e i" . xah-insert-curly-single-quote‘’)
- ("e j" . insert-char)
- ("e k" . xah-insert-markdown-quote)
- ("e l" . xah-insert-seperator)
- ("e m" . xah-insert-corner-bracket「」)
- ("e n" . xah-insert-square-bracket)
- ("e o" . xah-insert-ascii-single-quote)
- ("e p" . xah-insert-single-angle-quote‹›)
- ("e q" . xah-insert-deco-angle-fat-bracket❰❱)
- ("e r" . xah-insert-tortoise-shell-bracket〔〕)
- ("e s" . xah-insert-ascii-angle-bracket)
- ("e t" . xah-insert-paren)
- ("e u" . xah-insert-date)
- ("e v" . xah-insert-markdown-triple-quote)
- ("e w" . xah-insert-angle-bracket〈〉)
- ("e x" . xah-insert-white-lenticular-bracket〖〗)
- ("e y" . xah-insert-double-angle-quote«»)
- ("e z" . xah-insert-deco-angle-bracket❮❯)
-
- ("f" . xah-search-current-word)
- ("g" . xah-close-current-buffer)
-
- ("h a" . apropos-command)
- ("h b" . describe-bindings)
- ("h c" . describe-char)
- ("h d" . apropos-documentation)
- ("h e" . view-echo-area-messages)
- ("h f" . describe-face)
- ("h g" . info-lookup-symbol)
- ;; ("h h" . describe-function)
- ("h i" . info)
- ("h j" . man)
- ("h k" . describe-key)
- ("h l" . view-lossage)
- ("h m" . describe-mode)
- ("h n" . describe-variable)
- ("h o" . describe-language-environment)
- ;; p q
- ("h r" . apropos-variable)
- ("h s" . describe-syntax)
- ("h t" . describe-function)
- ("h u" . elisp-index-search)
- ("h v" . apropos-value)
- ("h x" . describe-command) ; emacs 28
- ;; y
- ("h z" . describe-coding-system)
-
- ("i" . kill-line)
- ("j" . xah-copy-all-or-region)
- ("k" . xah-show-kill-ring)
-
- ("l" . recenter-top-bottom)
-
- ("m" . dired-jump)
-
- ;; ("m e" . delete-other-windows)
- ;; ("m u" . split-window-below)
- ;; ("m w" . universal-argument)
-
- ;; commands here are “harmless”, they don't modify text etc. they turn on modes, change display, prompt, start shell, etc.
- ("n SPC" . whitespace-mode)
- ("n ," . abbrev-mode)
- ("n ." . toggle-frame-maximized)
- ("n 1" . set-input-method)
- ("n 2" . global-hl-line-mode)
- ("n 4" . global-display-line-numbers-mode)
- ("n 6" . calendar)
- ("n 7" . calc)
- ("n 9" . shell-command)
- ("n 0" . shell-command-on-region)
-
- ("n " . xah-page-up)
- ("n " . xah-page-down)
-
- ("n a" . text-scale-adjust)
- ("n b" . toggle-debug-on-error)
- ("n c" . toggle-case-fold-search)
- ("n d" . display-line-numbers-mode)
- ("n e" . eshell)
- ("n f" . nil)
- ("n g" . xah-toggle-read-novel-mode)
- ("n h" . widen)
- ("n i" . make-frame-command)
- ("n j" . flyspell-buffer)
- ("n k" . menu-bar-open)
- ("n l" . toggle-word-wrap)
- ("n m" . jump-to-register)
- ("n n" . xah-narrow-to-region)
- ("n o" . variable-pitch-mode)
- ("n p" . read-only-mode)
- ("n q" . enlarge-window)
- ("n r" . count-words)
- ("n s" . count-matches)
- ("n t" . narrow-to-defun)
- ("n u" . shell)
- ("n v" . visual-line-mode)
- ("n w" . eww)
- ("n x" . save-some-buffers)
- ("n y" . toggle-truncate-lines)
- ("n z" . abort-recursive-edit)
-
- ("o" . exchange-point-and-mark)
- ("p" . query-replace)
- ("q" . xah-cut-all-or-region)
-
- ;; roughly text replacement related
-
- ("r ," . apply-macro-to-region-lines)
- ("r ." . kmacro-start-macro)
- ("r /" . xah-slash-to-double-backslash)
- ("r 3" . number-to-register)
- ("r 4" . increment-register)
- ("r RET" . nil)
- ("r SPC" . nil)
- ("r \\" . xah-slash-to-backslash)
-
- ("r a" . nil)
- ("r b" . nil)
- ("r c" . string-rectangle)
- ("r d" . delete-rectangle)
- ("r e" . call-last-kbd-macro)
- ("r f" . nil)
- ("r g" . nil)
- ("r h" . xah-change-bracket-pairs)
- ("r i" . xah-space-to-newline)
- ("r j" . copy-rectangle-to-register)
- ("r k" . yank-rectangle)
- ("r l" . clear-rectangle)
-
- ("r m" . nil)
- ("r n" . rectangle-number-lines)
- ("r o" . open-rectangle)
- ("r p" . kmacro-end-macro)
- ("r q" . kill-rectangle)
-
- ("r r" . rectangle-mark-mode)
- ("r s" . nil)
- ;; kmacro-end-and-call-macro
- ("r t RET" . #'kmacro-edit-macro)
- ("r t SPC" . #'kmacro-step-edit-macro)
- ("r t TAB" . #'kmacro-insert-counter)
- ("r t a" . #'kmacro-add-counter)
- ("r t b" . #'kmacro-bind-to-key)
- ("r t c" . #'kmacro-set-counter)
- ("r t d" . #'kmacro-redisplay)
- ("r t e" . #'edit-kbd-macro)
- ("r t f" . #'kmacro-set-format)
- ("r t g" . #'kmacro-delete-ring-head)
- ("r t h" . #'kmacro-edit-macro-repeat)
- ("r t i" . #'kmacro-call-ring-2nd-repeat)
- ("r t j" . #'kmacro-cycle-ring-next)
- ("r t k" . #'kmacro-end-or-call-macro-repeat)
- ("r t l" . #'kmacro-edit-lossage)
-
- ("r t n" . #'kmacro-name-last-macro)
- ("r t p" . #'kmacro-cycle-ring-previous)
- ("r t q" . #'kbd-macro-query)
- ("r t t" . #'kmacro-swap-ring)
- ("r t v" . #'kmacro-view-macro-repeat)
- ("r t x" . #'kmacro-to-register)
- ("r u" . xah-quote-lines)
- ("r v" . nil)
- ("r w" . nil)
- ("r x" . xah-double-backslash-to-slash)
- ("r y" . delete-whitespace-rectangle)
- ("r z" . nil)
-
- ("s" . save-buffer)
-
- ;; most frequently used
- ("t " . xah-move-block-up)
- ("t " . xah-move-block-down)
-
- ("t ," . sort-numeric-fields)
- ("t ." . xah-sort-lines)
- ("t 1" . xah-append-to-register-1)
- ("t 2" . xah-clear-register-1)
- ("t 3" . xah-copy-to-register-1)
- ("t 4" . xah-paste-from-register-1)
- ("t 7" . xah-append-to-register-1)
- ("t 8" . xah-clear-register-1)
- ("t a" . nil)
- ("t b" . xah-backward-punct)
- ("t c" . copy-matching-lines)
- ("t d" . mark-defun)
- ("t e" . list-matching-lines)
- ("t f" . move-to-column)
- ("t g" . goto-line)
- ("t h" . repeat-complex-command)
- ("t i" . delete-non-matching-lines)
- ("t j" . copy-to-register)
- ("t k" . insert-register)
- ("t l" . nil)
- ("t m" . xah-make-backup-and-save)
- ("t n" . goto-char)
- ("t o" . xah-clean-whitespace)
- ("t p" . query-replace-regexp)
- ("t q" . xah-cut-text-in-quote)
- ("t r" . xah-escape-quotes)
- ("t s" . xah-reformat-to-sentence-lines)
- ("t t" . repeat)
- ("t u" . kill-matching-lines)
- ("t v" . nil)
- ("t w" . xah-next-window-or-frame)
- ("t x" . xah-title-case-region-or-line)
- ("t y" . delete-duplicate-lines)
- ("t z" . nil)
- ("u" . switch-to-buffer)
- ("v" . universal-argument)
-
- ;; dangerous map. run program, delete file, etc
- ("w DEL" . xah-delete-current-file-make-backup)
- ("w ." . eval-buffer)
- ("w e" . eval-defun)
- ("w m" . eval-last-sexp)
- ("w p" . eval-expression)
- ("w u" . eval-region)
- ("w q" . save-buffers-kill-terminal)
- ("w w" . delete-frame)
- ("w j" . xah-run-current-file)
-
- ("x" . xah-toggle-previous-letter-case)
- ;; y
-
- ;; vc command keys subject to change. need a frequency stat of the commands.
-
- ("z b" . vc-root-diff) ; D
- ("z c" . vc-update) ; git pull, +
- ("z d" . vc-annotate) ; g
- ("z f" . vc-revert) ; u
- ("z g" . vc-push) ; git push, P
- ("z h" . vc-diff) ; git diff, =
- ("z l" . vc-print-root-log) ; L
- ("z m" . vc-dir) ; git status, C-x v d
- ("z n" . vc-print-log) ; git log, l
- ("z r" . vc-merge) ; m
- ("z t" . vc-register) ; git add, i
- ("z z" . vc-next-action) ; v
-
- ("z 1" . vc-create-tag) ; s
- ("z 2" . vc-insert-headers) ; h
- ("z 4" . vc-retrieve-tag) ; r
- ("z 5" . vc-revision-other-window) ; ~
- ("z 6" . vc-switch-backend) ; b
- ("z 7" . vc-update-change-log) ; a
-
- ;;
- ))
-
- (xah-fly--define-keys
- xah-fly-command-map
- '(("SPC" . xah-fly-leader-key-map)
- ("'" . xah-reformat-lines)
- ("," . xah-shrink-whitespaces)
- ("-" . delete-other-windows)
- ("." . backward-kill-word)
- ("/" . hippie-expand)
- (";" . xah-comment-dwim)
- ("[" . split-window-below)
- ("\\" . xah-cycle-hyphen-lowline-space)
- ("]" . split-window-right)
- ("`" . other-frame)
-
- ;; ("1" . nil)
- ;; ("2" . nil)
- ("3" . delete-other-windows)
- ("4" . split-window-below)
- ("5" . delete-char)
- ("6" . xah-select-block)
- ("7" . xah-select-line)
- ("8" . xah-extend-selection)
- ("9" . xah-select-text-in-quote)
- ("0" . xah-pop-local-mark-ring)
-
- ("a" . execute-extended-command)
- ("b" . isearch-forward)
- ("c" . previous-line)
- ("d" . xah-beginning-of-line-or-block)
- ("e" . xah-smart-delete)
- ("f" . undo)
- ("g" . backward-word)
- ("h" . backward-char)
- ("i" . xah-delete-current-text-block)
- ("j" . xah-copy-line-or-region)
- ("k" . xah-paste-or-paste-previous)
- ;; ("l" . xah-fly-insert-mode-activate-space-before)
- ("l" . xah-insert-space-before)
- ("m" . xah-backward-left-bracket)
- ("n" . forward-char)
- ("o" . open-line)
- ("p" . kill-word)
- ("q" . xah-cut-line-or-region)
- ("r" . forward-word)
- ("s" . xah-end-of-line-or-block)
- ("t" . next-line)
- ("u" . xah-fly-insert-mode-activate)
- ("v" . xah-forward-right-bracket)
- ("w" . xah-next-window-or-frame)
- ("x" . xah-toggle-letter-case)
- ("y" . set-mark-command)
- ("z" . xah-goto-matching-bracket)))
-
- ;;
- ))
-
-(xah-fly-define-keys)
-
-;; HHHH------------------------------
-;; set control meta, etc keys
-
-(defcustom xah-fly-unset-useless-key t
- "If true, unbind many obsolete or useless or redundant
- keybinding. e.g. , ."
- :type 'boolean)
-
-(when xah-fly-unset-useless-key
- (global-set-key (kbd "") nil)
- (global-set-key (kbd "") nil))
-
-(when xah-fly-use-meta-key
-
- (global-set-key (kbd "M-") nil) ; beginning-of-buffer-other-window
- (global-set-key (kbd "M-") nil) ; end-of-buffer-other-window
-
- (global-set-key (kbd "M-SPC") #'xah-fly-command-mode-activate)
- (global-set-key (kbd "M-\\") nil) ; delete-horizontal-space
- (global-set-key (kbd "M-!") nil) ; shell-command
- (global-set-key (kbd "M-$") nil) ; ispell-word
- (global-set-key (kbd "M-%") nil) ; query-replace
- (global-set-key (kbd "M-&") nil) ; async-shell-command
- (global-set-key (kbd "M-'") nil) ; abbrev-prefix-mark
- (global-set-key (kbd "M-(") nil) ; insert-parentheses
- (global-set-key (kbd "M-)") nil) ; move-past-close-and-reindent
- ;; (global-set-key (kbd "M-,") nil) ; xref-pop-marker-stack
- ;; (global-set-key (kbd "M-.") nil) ; xref-find-definitions
- (global-set-key (kbd "M-/") nil) ; dabbrev-expand
- (global-set-key (kbd "M-:") nil) ; eval-expression
- ;; (global-set-key (kbd "M-;") nil) ; comment-dwim
- (global-set-key (kbd "M-<") nil) ; beginning-of-buffer
- (global-set-key (kbd "M-=") nil) ; count-words-region
- (global-set-key (kbd "M->") nil) ; end-of-buffer
- ;; (global-set-key (kbd "M-?") nil) ; xref-find-references
- (global-set-key (kbd "M-@") nil) ; mark-word
- (global-set-key (kbd "M-^") nil) ; delete-indentation
- (global-set-key (kbd "M-`") nil) ; tmm-menubar
- (global-set-key (kbd "M-a") nil) ; backward-sentence
- (global-set-key (kbd "M-b") nil) ; backward-word
- (global-set-key (kbd "M-c") nil) ; capitalize-word
- (global-set-key (kbd "M-d") nil) ; kill-word
- (global-set-key (kbd "M-e") nil) ; forward-sentence
- (global-set-key (kbd "M-f") nil) ; forward-word
- (global-set-key (kbd "M-g") nil) ; Prefix Command
- (global-set-key (kbd "M-h") nil) ; mark-paragraph
- (global-set-key (kbd "M-i") nil) ; tab-to-tab-stop
- (global-set-key (kbd "M-j") nil) ; default-indent-new-line
- (global-set-key (kbd "M-k") nil) ; kill-sentence
- (global-set-key (kbd "M-l") nil) ; downcase-word
- (global-set-key (kbd "M-m") nil) ; back-to-indentation
- (global-set-key (kbd "M-o") nil) ; facemenu-keymap
- (global-set-key (kbd "M-q") nil) ; fill-paragraph
- (global-set-key (kbd "M-r") nil) ; move-to-window-line-top-bottom
- (global-set-key (kbd "M-s") nil) ; Prefix Command
- (global-set-key (kbd "M-t") nil) ; transpose-words
- (global-set-key (kbd "M-u") nil) ; upcase-word
- (global-set-key (kbd "M-v") nil) ; scroll-down-command
- (global-set-key (kbd "M-w") nil) ; kill-ring-save
- ;; (global-set-key (kbd "M-x") nil) ; execute-extended-command
- ;; (global-set-key (kbd "M-y") nil) ; yank-pop
- (global-set-key (kbd "M-z") nil) ; zap-to-char
- (global-set-key (kbd "M-{") nil) ; backward-paragraph
- (global-set-key (kbd "M-|") nil) ; shell-command-on-region
- (global-set-key (kbd "M-}") nil) ; forward-paragraph
- (global-set-key (kbd "M-~") nil) ; not-modified
- (global-set-key (kbd "M-DEL") nil) ; backward-kill-word
- )
-
-(when xah-fly-use-control-key
-
- (global-set-key (kbd "C-") #'xah-next-user-buffer)
- (global-set-key (kbd "C-S-") #'xah-previous-user-buffer)
-
- (global-set-key (kbd "C-S-") #'xah-previous-emacs-buffer)
- (global-set-key (kbd "C-S-") #'xah-next-emacs-buffer)
-
- (global-set-key (kbd "C-") #'xah-previous-user-buffer)
- (global-set-key (kbd "C-") #'xah-next-user-buffer)
-
- ;; (global-set-key (kbd "C-1") nil)
- (global-set-key (kbd "C-2") #'pop-global-mark)
- (global-set-key (kbd "C-3") #'previous-error)
- (global-set-key (kbd "C-4") #'next-error)
- (global-set-key (kbd "C-5") #'xah-previous-emacs-buffer)
- (global-set-key (kbd "C-6") #'xah-next-emacs-buffer)
- (global-set-key (kbd "C-7") #'xah-previous-user-buffer)
- (global-set-key (kbd "C-8") #'xah-next-user-buffer)
- (global-set-key (kbd "C-9") #'xah-page-up)
- (global-set-key (kbd "C-0") #'xah-page-down)
-
- (global-set-key (kbd "C--") #'text-scale-decrease)
- (global-set-key (kbd "C-=") #'text-scale-increase)
-
- (global-set-key (kbd "C-SPC") #'xah-fly-command-mode-activate)
-
- (global-set-key (kbd "C-S-n") #'make-frame-command)
- (global-set-key (kbd "C-S-s") #'write-file)
- (global-set-key (kbd "C-S-t") #'xah-open-last-closed)
-
- ;; (global-set-key (kbd "C-@") nil)
-
- (global-set-key (kbd "C-a") #'mark-whole-buffer)
- (global-set-key (kbd "C-b") nil)
- ;; (global-set-key (kbd "C-c") nil)
- (global-set-key (kbd "C-d") nil)
- (global-set-key (kbd "C-e") nil)
- (global-set-key (kbd "C-f") nil)
- ;; (global-set-key (kbd "C-g") nil) ; cancel
- ;; (global-set-key (kbd "C-h") nil) ; help
- ;; (global-set-key (kbd "C-i") nil) ; tab
- ;; (global-set-key (kbd "C-j") nil) ; newline
- (global-set-key (kbd "C-k") nil)
- (global-set-key (kbd "C-l") nil)
- ;; (global-set-key (kbd "C-m") nil) ; newline
- (global-set-key (kbd "C-n") #'xah-new-empty-buffer)
- (global-set-key (kbd "C-o") #'find-file)
- (global-set-key (kbd "C-p") nil)
- ;; (global-set-key (kbd "C-q") nil) ; quoted-insert
- ;; (global-set-key (kbd "C-r") nil)
- (global-set-key (kbd "C-s") #'save-buffer)
- (global-set-key (kbd "C-t") #'hippie-expand)
- ;; (global-set-key (kbd "C-u") nil) ; universal-argument
- (global-set-key (kbd "C-v") #'yank)
- (global-set-key (kbd "C-w") #'xah-close-current-buffer)
- (global-set-key (kbd "C-x") nil) ; c-x map
- (global-set-key (kbd "C-y") #'undo-redo) ; emacs 28
- (global-set-key (kbd "C-z") #'undo)
- ;;
- )
-
- (global-set-key (kbd "") 'xah-fly-leader-key-map)
-
-;; HHHH------------------------------
-
-(when (< emacs-major-version 28)
- (defalias 'execute-extended-command-for-buffer #'execute-extended-command))
-
-;; HHHH------------------------------
-;;;; misc
-
-;; the following have keys in gnu emacs, but i decided not to give them a key, because either they are rarely used (say, 95% of emacs users use them less than once a month ), or there is a more efficient command/workflow with key in xah-fly-keys
-
-;; C-x $ → set-selective-display
-;; C-x * → calc-dispatch
-;; C-x - → shrink-window-if-larger-than-buffer
-;; C-x . → set-fill-prefix
-;; C-x 4 . → find-tag-other-window
-;; C-x 4 0 → kill-buffer-and-window
-;; C-x 4 C-o → display-buffer
-;; C-x 4 a → add-change-log-entry-other-window
-;; C-x 4 b → switch-to-buffer-other-window
-;; C-x 4 c → clone-indirect-buffer-other-window
-;; C-x 4 d → dired-other-window
-;; C-x 4 f → find-file-other-window
-;; C-x 4 m → compose-mail-other-window
-;; C-x 4 r → find-file-read-only-other-window
-;; C-x 5 . xref-find-definitions-other-frame
-;; C-x 5 1 delete-other-frames
-;; C-x 5 5 other-frame-prefix
-;; C-x 5 C-o display-buffer-other-frame
-;; C-x 5 b switch-to-buffer-other-frame
-;; C-x 5 c clone-frame
-;; C-x 5 d dired-other-frame
-;; C-x 5 f find-file-other-frame
-;; C-x 5 m compose-mail-other-frame
-;; C-x 5 p project-other-frame-command
-;; C-x 5 r find-file-read-only-other-frame
-;; C-x 5 u undelete-frame
-;; C-x 6 2 → 2C-two-columns
-;; C-x 6 b → 2C-associate-buffer
-;; C-x 6 s → 2C-split
-;; C-x ; → comment-set-column
-;; C-x < → scroll-left
-;; C-x = → what-cursor-position, use describe-char instead
-;; C-x > → scroll-right
-;; C-x C-d → list-directory
-;; C-x C-l → downcase-region
-;; C-x C-n → set-goal-column
-;; C-x C-o → delete-blank-lines
-;; C-x C-p → mark-page
-;; C-x C-r → find-file-read-only
-;; C-x C-t → transpose-lines
-;; C-x C-u → upcase-region
-;; C-x C-v → find-alternate-file
-;; C-x C-z → suspend-frame
-;; C-x DEL → backward-kill-sentence
-;; C-x ESC → Prefix Command
-;; C-x [ → backward-page
-;; C-x ] → forward-page
-;; C-x f → set-fill-column
-;; C-x i → insert-file
-;; C-x k → kill-buffer
-;; C-x l → count-lines-page
-;; C-x m → compose-mail
-;; C-x n g goto-line-relative
-;; C-x n p narrow-to-page
-;; C-x r M bookmark-set-no-overwrite
-;; C-x r M-w copy-rectangle-as-kill
-;; C-x r SPC point-to-register
-;; C-x r f frameset-to-register
-;; C-x r j jump-to-register
-;; C-x r w window-configuration-to-register
-;; C-x { → shrink-window-horizontally
-;; C-x } → enlarge-window-horizontally
-
-;; HHHH------------------------------
-
-(defvar xah-fly-insert-state-p t "non-nil means insertion mode is on.")
-
-(defun xah-fly--update-key-map ()
- (setq xah-fly-key-map (if xah-fly-insert-state-p
- xah-fly-insert-map
- xah-fly-command-map)))
-
-(defun xah-fly-keys-set-layout (Layout)
- "Set a keyboard layout.
-Argument must be one of the key name in `xah-fly-layout-diagrams'
-Created: 2021-05-19
-Version: 2024-05-23"
- (interactive
- (list
- (completing-read
- "Choose a layout: "
- (seq-sort 'string< (hash-table-keys xah-fly-layout-diagrams))
- nil t)))
- (let ((xold xah-fly-key-current-layout)
- (xkeydiagram (gethash Layout xah-fly-layout-diagrams)))
- (when (not xkeydiagram)
- (user-error
- "xah-fly-keys-set-layout error: layout must be one of string:\n%s"
- (mapconcat 'identity (hash-table-keys xah-fly-layout-diagrams) "\n")))
- (setq xah-fly-key-current-layout Layout)
- (setq
- xah-fly--key-convert-table
- (xah-fly-create-key-conv-table
- (gethash "dvorak" xah-fly-layout-diagrams)
- xkeydiagram))
- (when (not (equal xold Layout)) (xah-fly-define-keys))))
-
-(defun xah-fly-space-key ()
- "Switch to command mode if the char before cursor is a space.
-experimental
-Version: 2018-05-07"
- (interactive)
- (if (eq (char-before ) 32)
- (xah-fly-command-mode-activate)
- (insert " ")))
-
-(defun xah-fly-command-mode-init ()
- "Set command mode keys.
-Version: 2022-07-06"
- (interactive)
- (setq xah-fly-insert-state-p nil)
- (xah-fly--update-key-map)
- (when xah-fly--deactivate-command-mode-func
- (funcall xah-fly--deactivate-command-mode-func))
- (setq xah-fly--deactivate-command-mode-func
- (set-transient-map xah-fly-command-map (lambda () t)))
- (modify-all-frames-parameters (list (cons 'cursor-type 'box)))
- ;; (set-face-background 'cursor "red")
- (setq mode-line-front-space xah-fly-command-mode-indicator)
- (force-mode-line-update))
-
-(defun xah-fly-insert-mode-init (&optional no-indication)
- "Enter insertion mode."
- (interactive)
- (setq xah-fly-insert-state-p t)
- (xah-fly--update-key-map)
- (funcall xah-fly--deactivate-command-mode-func)
- (unless no-indication
- (modify-all-frames-parameters '((cursor-type . bar)))
- ;; (set-face-background 'cursor "black")
- (setq mode-line-front-space xah-fly-insert-mode-indicator))
- (force-mode-line-update))
-
-(defun xah-fly-mode-toggle ()
- "Switch between {insertion, command} modes."
- (interactive)
- (if xah-fly-insert-state-p
- (xah-fly-command-mode-activate)
- (xah-fly-insert-mode-activate)))
-
-(defun xah-fly-save-buffer-if-file ()
- "Save current buffer if it is a file."
- (interactive)
- (when buffer-file-name
- (save-buffer)))
-
-(defun xah-fly-command-mode-activate ()
- "Activate command mode and run `xah-fly-command-mode-activate-hook'
-Version: 2017-07-07"
- (interactive)
- (xah-fly-command-mode-init)
- (run-hooks 'xah-fly-command-mode-activate-hook))
-
-(defun xah-fly-command-mode-activate-no-hook ()
- "Activate command mode. Does not run `xah-fly-command-mode-activate-hook'
-Version: 2017-07-07"
- (interactive)
- (xah-fly-command-mode-init))
-
-(defun xah-fly-insert-mode-activate ()
- "Activate insertion mode.
-Version: 2017-07-07"
- (interactive)
- (xah-fly-insert-mode-init)
- (run-hooks 'xah-fly-insert-mode-activate-hook))
-
-(defun xah-fly-insert-mode-activate-newline ()
- "Activate insertion mode, insert newline below."
- (interactive)
- (xah-fly-insert-mode-activate)
- (open-line 1))
-
-(defun xah-fly-insert-mode-activate-space-before ()
- "Insert a space, then activate insertion mode."
- (interactive)
- (insert " ")
- (xah-fly-insert-mode-activate))
-
-(defun xah-fly-insert-mode-activate-space-after ()
- "Insert a space, then activate insertion mode."
- (interactive)
- (insert " ")
- (xah-fly-insert-mode-activate)
- (left-char))
-
-;; HHHH------------------------------
-
-;;;###autoload
-(define-minor-mode xah-fly-keys
- "A modal keybinding set, like vim, but based on ergonomic
- principles, like Dvorak layout.
-
-URL `http://xahlee.info/emacs/misc/xah-fly-keys.html'"
- :global t
- :lighter " xflykeys"
- :keymap xah-fly-insert-map
- (delete-selection-mode 1)
- (setq shift-select-mode nil)
-
- (if xah-fly-keys
- ;; Construction:
- (progn
- (add-hook 'minibuffer-setup-hook 'xah-fly-insert-mode-activate)
- (add-hook 'minibuffer-exit-hook 'xah-fly-command-mode-activate)
- (add-hook 'isearch-mode-end-hook 'xah-fly-command-mode-activate)
- (xah-fly-command-mode-activate))
- (progn
- ;; Teardown:
- (remove-hook 'minibuffer-setup-hook 'xah-fly-insert-mode-activate)
- (remove-hook 'minibuffer-exit-hook 'xah-fly-command-mode-activate)
- (remove-hook 'isearch-mode-end-hook 'xah-fly-command-mode-activate)
- (xah-fly-insert-mode-init :no-indication)
- (setq mode-line-front-space '(:eval (if (display-graphic-p) " " "-")))
-
- ;;
- )))
-
-(provide 'xah-fly-keys)
-
-;;; xah-fly-keys.el ends here
|