.emacs.d

the most bloated Emacs config on this planet
git clone https://git.trogloxene.org/.emacs.d.git
Log | Files | Refs

init-kbd-func.el (10011B)


      1 ;;; init-kbd-func.el --- functions -*- lexical-binding: t -*-
      2 
      3 ;;; Commentary:
      4 
      5 ;;; Code:
      6 
      7 (defun my-open-init-file ()
      8   "Open user's init.el file."
      9   (interactive)
     10   (find-file user-init-file))
     11 
     12 (defun my-open-custom-file ()
     13   "Open user's `custom-file'."
     14   (interactive)
     15   (or (find-file custom-file)
     16       (user-error "No custom file")))
     17 
     18 (defun my-empty-line-p (&optional really-empty)
     19   (save-excursion
     20     (beginning-of-line)
     21     (looking-at-p (if really-empty
     22                       "$"
     23                     "[[:blank:]]*$"))))
     24 
     25 (defun my-electric-open-line-and-indent (n)
     26   "Insert N newlines and leave point before them.
     27 If there is a fill prefix and/or a `left-margin', insert them on the new
     28 line if the line would have been blank.  Reindent the line following the
     29 inserted newlines, if that line is blank, remove its indentation."
     30   (interactive "*p")
     31   (let* ((do-fill-prefix (and fill-prefix (bolp)))
     32          (do-left-margin (and (bolp) (> (current-left-margin) 0)))
     33          (loc (point-marker))
     34          (abbrev-mode nil))
     35     (newline n)
     36     (when (and (not do-left-margin)
     37                (not do-fill-prefix))
     38       (indent-according-to-mode)
     39       (when (my-empty-line-p)
     40         (delete-horizontal-space t)))
     41     (goto-char loc)
     42     (while (> n 0)
     43       (cond ((bolp)
     44              (if do-left-margin (indent-to (current-left-margin)))
     45              (if do-fill-prefix (insert-and-inherit fill-prefix))))
     46       (forward-line 1)
     47       (setq n (1- n)))
     48     (goto-char loc)
     49     (end-of-line)))
     50 
     51 (defun my-copy-function-name ()
     52   "Copy the function name return by `which-function'."
     53   (interactive)
     54   (if-let* ((func (which-function)))
     55       (progn (kill-new func)
     56              (message "Save `%s' to kill ring." func))
     57     (message "Cannot find the name of the current function.")))
     58 
     59 (defun my-copy-buffer-name ()
     60   "Copy the name of the current buffer."
     61   (interactive)
     62   (if-let* ((buf (buffer-name)))
     63       (progn (kill-new buf)
     64              (message "Save `%s' to kill ring." buf))
     65     (message "Cannot find the name of the  current buffer.")))
     66 
     67 (defun my-copy-file-path (arg)
     68   "Copy the path of the current file.
     69 With a prefix ARG, copy the expanded file path."
     70   (interactive "P")
     71   (if-let* ((path (buffer-file-name)))
     72       (progn
     73         (unless arg (setq path (abbreviate-file-name path)))
     74         (kill-new path)
     75         (message "Save `%s' to kill ring." path))
     76     (message "Cannot find the path of the current file.")))
     77 
     78 (defun my-count-words-region (start end &optional totals)
     79   "Count the number of words in the region.
     80 With prefix ARG, report for the entire buffer rather than the region."
     81   (interactive (if current-prefix-arg
     82                    (list nil nil current-prefix-arg)
     83                  (list (region-beginning) (region-end) nil)))
     84   (cl-letf (((symbol-function 'forward-word-strictly) #'forward-word))
     85     (if totals
     86         (message "%s" (count-words--buffer-format))
     87       (message "%s" (count-words--format
     88                      "Region" (region-beginning) (region-end))))))
     89 
     90 (defun my-bounds-of-next-thing (thing)
     91   "Return the bounds of THING at or after point."
     92   (or (bounds-of-thing-at-point thing)
     93       (save-excursion (ignore-errors (forward-thing thing 1)
     94                                      (forward-thing thing -1))
     95                       (bounds-of-thing-at-point thing))))
     96 
     97 (defun my-bounds-of-symbol-at-point-or-next-sexp ()
     98   (let* ((symbol (my-bounds-of-next-thing 'symbol))
     99          (sexp (my-bounds-of-next-thing 'sexp))
    100          (at-point-p (bounds-of-thing-at-point 'symbol)))
    101     (if at-point-p
    102         symbol
    103       sexp)))
    104 
    105 (defun my-mark-sexp-hack (fun &optional arg allow-extend)
    106   (if (and allow-extend
    107            (or (and (eq last-command this-command) (mark t))
    108                (and transient-mark-mode mark-active)))
    109       (funcall fun arg allow-extend)
    110     (let* ((bounds (or (my-bounds-of-symbol-at-point-or-next-sexp)
    111                        (bounds-of-thing-at-point 'sexp)))
    112            (pos (point))
    113            (beg (car bounds))
    114            (end (cdr bounds))
    115            (endp (equal (point) end)))
    116       (goto-char beg)
    117       (funcall fun arg allow-extend)
    118       (if endp (exchange-point-and-mark)))))
    119 (advice-add #'mark-sexp :around #'my-mark-sexp-hack)
    120 
    121 (defun my-mark-word-hack (&optional arg allow-extend)
    122   (unless (and allow-extend
    123                (or (and (eq last-command this-command) (mark t))
    124                    (region-active-p)))
    125     (when-let* ((beg (car (my-bounds-of-next-thing 'word))))
    126       (goto-char beg))))
    127 (advice-add #'mark-word :before #'my-mark-word-hack)
    128 
    129 ;; from Bozhidar Batsov's crux
    130 (defun my-kill-line-backwards ()
    131   "Kill line backwards and adjust the indentation."
    132   (interactive)
    133   (kill-line 0)
    134   (indent-according-to-mode))
    135 
    136 ;; from Bozhidar Batsov's crux
    137 (defun my-get-positions-of-line-or-region ()
    138   "Return positions (beg . end) of the current line or region."
    139   (let (beg end)
    140     (if (and mark-active (> (point) (mark)))
    141         (exchange-point-and-mark))
    142     (setq beg (line-beginning-position))
    143     (if mark-active
    144         (exchange-point-and-mark))
    145     (setq end (line-end-position))
    146     (cons beg end)))
    147 
    148 (defun my-duplicate-current-line-or-region (arg)
    149   "Duplicates the current line or region ARG times.
    150 If there's no region, the current line will be duplicated.  However, if
    151 there's a region, all lines that region covers will be duplicated."
    152   (interactive "p")
    153   (pcase-let* ((origin (point))
    154                (`(,beg . ,end) (my-get-positions-of-line-or-region))
    155                (region (buffer-substring-no-properties beg end)))
    156     (dotimes (_i arg)
    157       (goto-char end)
    158       (newline)
    159       (insert region)
    160       (setq end (point)))
    161     (goto-char (+ origin (* (length region) arg) arg))))
    162 
    163 (defun enable-truncate-lines ()
    164   (setq truncate-lines t))
    165 
    166 (defun my-eshell-input-from-history ()
    167   "Insert command from eshell input history."
    168   (interactive)
    169   (let ((history (ring-elements eshell-history-ring)))
    170     (insert
    171      (completing-read
    172       "Insert input from history: "
    173       history))))
    174 
    175 (defun query-replace-case-sensitive ()
    176   "Case-sensitive `query-replace'."
    177   (interactive)
    178   (let ((case-fold-search nil))
    179     (call-interactively #'query-replace)))
    180 
    181 (defun my-show-utc-time (&optional arg)
    182   "Display current UTC time in echo area."
    183   (interactive "P")
    184   (let ((time (format-time-string "%Y-%m-%d %H:%M UTC" nil t)))
    185     (if arg
    186         (progn (kill-new time) (message "Save `%s' to kill ring." time))
    187       (message time))))
    188 
    189 (defun my-back-to-indentation ()
    190   "Move point to the first non-whitespace character on this line."
    191   (interactive "^")
    192   (beginning-of-line 1)
    193   (when (looking-at "^ ?[-+]+")
    194     (goto-char (match-end 0)))
    195   (skip-syntax-forward " " (line-end-position))
    196   (backward-prefix-chars))
    197 
    198 (defun my-straight-package-dir (package)
    199   "Return the source directory of PACKAGE if it exist.
    200 PACKAGE is a string."
    201   (when-let* ((recipe
    202                (ignore-errors
    203                  (or (gethash package straight--recipe-cache)
    204                      (straight--convert-recipe (intern package)))))
    205               (local-repo (plist-get recipe :local-repo)))
    206     (straight--repos-dir local-repo)))
    207 
    208 (defun my-straight-packages-count ()
    209   "Count how many straight.el package are currently installed."
    210   (interactive)
    211   (if (called-interactively-p 'interactive)
    212       (message (format "%s packages installed" (hash-table-count straight--profile-cache)))
    213     (hash-table-count straight--profile-cache)))
    214 
    215 (defun my-insert-straight-packages ()
    216   "Insert straight.el packages."
    217   (interactive)
    218   (dolist (item (sort (hash-table-keys straight--profile-cache)))
    219     (insert (format "- %s\n" item))))
    220 
    221 (defun my-insert-raw-org-link (arg)
    222   "Insert the last link stored in `org-stored-links' in its raw form.
    223 When a prefix ARG, do not delete the links from `org-stored-links'."
    224   (interactive "P")
    225   (if-let* ((links (and (bound-and-true-p org-stored-links) org-stored-links))
    226             (link (if arg (caar links) (car (pop org-stored-links))))
    227             (unpropertized (substring-no-properties link)))
    228       (insert unpropertized)
    229     (message "No link to insert")))
    230 
    231 (defun org-cycle-parent-subtree()
    232   "Cycle parent org subtree."
    233   (interactive)
    234   (if (org-at-heading-p)
    235       (progn
    236         (org-up-heading 1)
    237         (org-cycle))
    238     (org-back-to-heading)
    239     (org-cycle)))
    240 
    241 (defun my-blog-find-file ()
    242   "Find blog file use denote-file-prompt."
    243   (interactive)
    244   (let* ((denote-directory my-blog-directory)
    245          (denote-prompts '(title keywords)))
    246     (call-interactively #'denote-open-or-create)))
    247 
    248 (defun my-blog-grep ()
    249   "Run `consult-grep' in `my-blog-directory'."
    250   (interactive)
    251   (consult-grep my-blog-directory))
    252 
    253 (defun my-org-table-align-all ()
    254   "Adjust all table in current buffer."
    255   (interactive)
    256   (org-table-map-tables 'org-table-align t))
    257 
    258 (defun my-org-align-description-list ()
    259   "Adjust all `::' in active region."
    260   (interactive)
    261   (align-regexp (region-beginning) (region-end) "\\(\\s-*\\)::" 1 1 nil))
    262 
    263 (defun my-push-with-timestamp (directory)
    264   "Git add/commit/push, generate commit message."
    265   (let ((timestamp (format-time-string "%Y-%m-%d %H:%M:%S"))
    266         (default-directory directory))
    267     (message "Adding files...")
    268     (eshell-command "git add .")
    269     (message "Committing: %s" timestamp)
    270     (eshell-command (format "git commit -m \"Update: %s\"" timestamp))
    271     (message "Pushing to remote...")
    272     (let ((exit-code (eshell-command "git push")))
    273       (if (eq exit-code t)
    274           (message "Push may have failed or nothing to push, check *Messages* buffer for details")
    275         (message "Push successfully %s" timestamp)))))
    276 
    277 (defun my-note-push ()
    278   "Git add/commit/push in 'my-org-directory'."
    279   (interactive)
    280   (my-push-with-timestamp my-org-directory))
    281 
    282 (defun my-org-publish ()
    283   "Git add/commit/push in `my-blog-directory'."
    284   (interactive)
    285   (my-push-with-timestamp my-blog-directory))
    286 (defalias 'my-blog-push (symbol-function #'my-org-publish))
    287 
    288 (provide 'init-kbd-func)
    289 ;;; init-kbd-func.el ends here