;;; init-kbd-func.el --- functions for keybindings -*- lexical-binding: t -*- ;;; Commentary: ;;; Code: (defun open-init-file() "Open user's init.el file in ~/.emacs.d ." (interactive) (find-file "~/.emacs.d/init.el")) (when *is-windows* (defun restart-emacs () "Restart emacs (for Windows)" (interactive) (save-some-buffers) (w32-shell-execute "open" "runemacs.exe") (kill-emacs))) (defun disable-truncate-lines () (toggle-truncate-lines 1)) (defun my-jinx-smart-toggle () "Toggle jinx-mode smartly. Disable jinx-mode if it's enable and global-jinx-mode is disable , otherwise toggle global-jinx-mode." (interactive) (unless (featurep 'jinx) (require 'jinx)) (let ((local-on (bound-and-true-p jinx-mode)) (global-on (bound-and-true-p global-jinx-mode))) (cond ((and local-on (not global-on)) (message "disable jinx-mode in current buffer") (jinx-mode -1)) (t (if global-on (progn (message "disable global-jinx-mode") (global-jinx-mode -1)) (progn (message "enable global-jinx-mode") (global-jinx-mode 1))))))) (defun popper-toggle-type-delete-other-window() "Toggle type of popper window and delete other window." (interactive) (popper-toggle-type) (delete-other-windows)) (defun consult-directory-externally (file) "Open FILE externally using the default application of the system." (interactive "fOpen externally: ") (if (and (eq system-type 'windows-nt) (fboundp 'w32-shell-execute)) (shell-command-to-string (encode-coding-string (replace-regexp-in-string "/" "\\\\" (format "explorer.exe %s" (file-name-directory (expand-file-name file)))) 'gbk)) (call-process (pcase system-type ('darwin "open") ('cygwin "cygstart") (_ "xdg-open")) nil 0 nil (file-name-directory (expand-file-name file))))) (defun my-open-current-directory () "Open current directory in default file explorer." (interactive) (consult-directory-externally default-directory)) (defun consult-fd-home () "Search for all files in home folder use fd." (interactive) (let ((consult-fd-args "fd -H -I -i -c never --full-path") (default-directory "~/")) (consult-fd))) (defun org-cycle-parent-subtree() "Cycle parent org subtree." (interactive) (if (org-at-heading-p) (progn (org-up-heading 1) (org-cycle)) (org-back-to-heading) (org-cycle))) (defun my-denote-journal-path-to-existing-entry (&optional date interval) "Return the path of current denote journal if it exists, otherwise return nil." (require 'denote-journal) (let* ((internal-date (denote-journal--date-in-interval-p (or date (current-time)) interval)) (files (denote-journal--get-entry internal-date interval))) (if files (denote-journal-select-file-prompt files)))) (defun my-denote-journal-open-entry () "Open current denote-journal entry." (interactive) (if (my-denote-journal-path-to-existing-entry) (find-file (my-denote-journal-path-to-existing-entry)) (message "No journal for today yet"))) (defun my-denote-open-metanote () "Open denote metanote in `~/org/my-org-note/20260508T220745==metanote--all-my-metanotes__org.org'" (interactive) (find-file (concat org-directory "/20260508T220745==metanote--all-my-metanotes__org.org"))) (defun my-denote-find-file () "Find file use denote-file-prompt." (interactive) (let ((denote-excluded-files-regexp "=journal\\|=archive")) (find-file (denote-file-prompt)))) (defun my-denote-find-backlink-with-location () "Like `denote-find-backlink-with-location' but with consult preview." (interactive) (when-let* ((current-file buffer-file-name) (id (or (denote-retrieve-filename-identifier current-file) (user-error "The current file does not have a Denote identifier"))) (files (denote-directory-files nil :omit-current :text-only)) (fetcher (lambda () (xref-matches-in-files id files)))) (consult-xref fetcher nil))) (defun my-denote-org-find-backlink-for-heading-with-location () "Like `denote-org-backlinks-for-heading' but with consult preview." (interactive) (unless (featurep 'denote-org) (require 'denote-org)) (when-let* ((heading-id (or (denote-org--get-file-id-and-heading-id-or-context) (user-error "The current file does not have a denote identifier"))) (files (denote-directory-files nil :omit-current :text-only)) (fetcher (lambda () (xref-matches-in-files heading-id files)))) (consult-xref fetcher nil))) (defun my-org-table-align-all () "Ajust all table in current buffer." (interactive) (save-excursion (goto-char (point-min)) (org-table-map-tables 'org-table-align t))) (defun org-align-description-list () "Ajust all `::' in active region. " (interactive) (align-regexp (region-beginning) (region-end) "\\(\\s-*\\)::" 1 1 nil)) (defun my-blog-publish (&optional directory) "Publish blog , git add/commit/push , generate commit message." (interactive) (let* ((blog-dir (or directory (if *is-windows* "h:/emacs/hugo/this-is-my-blog/" "~/org/hugo/this-is-my-blog/"))) (timestamp (format-time-string "%Y-%m-%d %H:%M:%S")) (default-directory blog-dir)) (message "Adding files...") (eshell-command "git add .") (message "Committing: %s" timestamp) (eshell-command (format "git commit -m \"Update: %s\"" timestamp)) (message "Pushing to remote...") (let ((exit-code (eshell-command "git push"))) (if (eq exit-code t) (message "Push may have failed or nothing to push, check *Messages* buffer for details") (message "Push successfully %s" timestamp))))) (defun my-blog-preview () "Save and preview blog." (interactive) (save-buffer) (let ((default-directory (if *is-windows* "h:/emacs/hugo/this-is-my-blog/" "~/org/hugo/this-is-my-blog/"))) (start-process "hugo-server" "*hugo-server*" "hugo" "server" "-D" "--bind" "0.0.0.0" "--port" "1313") (sleep-for 2) (browse-url "http://localhost:1313"))) (defun my-note-push () "Git add/commit/push notes in `~/org/my-org-note/', generate commit message." (interactive) (my-blog-publish "~/org/my-org-note/")) (defun my-org-tree-slide-start () "Start `org-tree-slide'." (interactive) (when (eq major-mode 'org-mode) (setq-local header-line-format nil mode-line-format nil cursor-type 'hbar olivetti-body-width 100) (blink-cursor-mode -1) (cnfonts-increase-fontsize 3) (hl-line-mode 'toggle) (read-only-mode 1) (jinx-mode -1) (org-tree-slide-mode 1))) (defun my-org-tree-slide-stop () "Stop `org-tree-slide'." (interactive) (when (and (eq major-mode 'org-mode) (memq 'org-tree-slide-mode local-minor-modes)) (org-mode-restart) (blink-cursor-mode 1) (cnfonts-decrease-fontsize 3) (hl-line-mode 1) (read-only-mode -1) (jinx-mode 1) (org-tree-slide-mode -1))) (defun my-dired-next-line() "Move to forward line in dired buffer" (interactive) (forward-line 1) (dired-move-to-filename)) (defun my-dirvish-layout-toggle () "Toggle layout using first recipe in `dirvish-layout-recipes' instead of fallback." (interactive) (let ((dv (dirvish-curr))) (unless dv (user-error "Not a dirvish buffer")) (unless (dv-curr-layout dv) (setf (dv-ff-layout dv) (car dirvish-layout-recipes))) (dirvish-layout-toggle))) (defun my-magit-toggle-parent-section () "Toggle parent magit section." (interactive) (magit-section-up) (magit-section-toggle (magit-section-at))) (defun my-persp-remove-marked-ibuffers () "Remove marked buffers from perspective." (interactive) (let ((buffers (ibuffer-get-marked-buffers))) (dolist (buf buffers) (persp-remove-buffer buf)))) (defun my-persp-add-marked-ibuffers (persp-name) "Add marked buffers to perspective." (interactive (list (completing-read "Perspective: " (persp-names) nil nil))) (let ((buffers (ibuffer-get-marked-buffers))) (persp-switch persp-name) (dolist (buf buffers) (persp-add-buffer buf)))) (defun my-persp-set-marked-ibuffers (persp-name) "Set marked buffers to perspective." (interactive (list (completing-read "Perspective: " (persp-names) nil nil))) (let ((buffers (ibuffer-get-marked-buffers))) (persp-switch persp-name) (dolist (buf buffers) (persp-set-buffer buf)))) (defun my-gptel-agent-project () "Run `gptel-agent' in current project's root (by run it with prefix argument)." (interactive) (let ((current-prefix-arg '-)) (call-interactively 'gptel-agent))) (defun my-opencode () "Run `opencode' in project root." (interactive) (let ((default-directory (project-root (project-current t)))) (opencode))) (defun my-consult-ripgrep-project () "Run `consult-ripgrep' in current project's root." (interactive) (when-let* ((proj (project-current t))) (consult-ripgrep (project-root proj)))) (defun consult-colors-emacs (color) "Show a list of all supported colors for a particular frame. You can insert the name (default), or insert or kill the hexadecimal or RGB value of the selected COLOR." (interactive (list (consult--read (list-colors-duplicates (defined-colors)) :prompt "Emacs color: " :require-match t :category 'color :history '(:input consult-colors-history)))) (insert color)) (defun fix-theme-colors () "Fix invalid color name in theme files." (interactive) (load-file (expand-file-name "~/.emacs.d/lisp/fix-theme-colors.el"))) (when *is-linux* (defun reboot () "Execute loginctl reboot command." (interactive) (eshell-command "loginctl reboot")) (defun poweroff () "Execute loginctl poweroff command" (interactive) (eshell-command "loginctl poweroff")) (defun suspend () "Execute loginctl suspend command" (interactive) (eshell-command "loginctl suspend")) (defun my-desktop-init () "Launch something for linux desktop." (interactive) (unless (zerop (shell-command "pgrep -x mihomo")) (start-process-shell-command "mihomo" nil "mihomo -d ~/.config/mihomo/")) (start-process-shell-command "xrandr-refresh" nil "xrandr --output DP-4 --mode 2560x1440 --rate 165.00") (start-process-shell-command "xinput" nil "xinput set-prop 12 'libinput Accel Speed' -0.45")) (defun restart-fcitx5 () "Kill and restart fcitx5, to fix random issues in exwm." (interactive) (if (zerop (shell-command "pgrep fcitx5")) (progn (eshell-command "pkill fcitx5") (eshell-command "fcitx5 -d")) (eshell-command "fcitx5 -d")))) (provide 'init-kbd-func) ;;; init-kbd-func.el ends here