Quality of Life
Changes to core behaviour to make life better.
Preamble
;;; quality_of_life.el --- Cunene: My emacs configuration. -*- lexical-binding: t -*- ;; Author: Marco Craveiro <marco_craveiro@gmail.com> URL: ;; https://github.com/mcraveiro/prelude Version: 0.0.3 Keywords: convenience ;; This file is not part of GNU Emacs. ;;; Commentary: ;; General editor configuration ;;; License: ;; This program is free software; you can redistribute it and/or ;; modify it under the terms of the GNU General Public License ;; as published by the Free Software Foundation; either version 3 ;; of the License, or (at your option) any later version. ;; ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; ;; You should have received a copy of the GNU General Public License ;; along with GNU Emacs; see the file COPYING. If not, write to the ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, ;; Boston, MA 02110-1301, USA. ;;; Code:
Garbage collection
Improvements to default GC. Links:
(setq-default gc-cons-threshold (* 8 1024 1024)) ; Bump up garbage collection threshold.
Garbage-collect on focus-out, Emacs should feel snappier overall.
(add-function :after after-focus-change-function (defun cunene/garbage-collect-maybe () (unless (frame-focus-state) (garbage-collect))))
Better Defaults
Here are what I consider better defaults as per my own experience.
(require 'image-mode) (setq-default ad-redefinition-action 'accept ; Silence warnings for redefinition require-final-newline t ; Newline at end of file auto-save-list-file-prefix nil ; Prevent tracking for auto-saves cursor-in-non-selected-windows nil ; Hide the cursor in inactive windows custom-unlispify-menu-entries nil ; Prefer kebab-case for titles custom-unlispify-tag-names nil ; Prefer kebab-case for symbols delete-by-moving-to-trash t ; Delete files to trash fill-column 80 ; Set width for automatic line breaks help-window-select t ; Focus new help windows when opened indent-tabs-mode nil ; Stop using tabs to indent inhibit-startup-screen t ; Disable start-up screen initial-scratch-message "" ; Empty the initial *scratch* buffer mouse-yank-at-point t ; Yank at point rather than pointer read-process-output-max (* 1024 1024) ; Increase read size per process recenter-positions '(5 top bottom) ; Set re-centering positions scroll-conservatively 101 ; Avoid recentering when scrolling far scroll-margin 2 ; Add a margin when scrolling vertically select-enable-clipboard t ; Merge system's and Emacs' clipboard sentence-end-double-space nil ; Use a single space after dots show-help-function nil ; Disable help text everywhere tab-always-indent 'complete ; Tab indents first then tries completions warning-minimum-level :error ; Skip warning buffers window-combination-resize t ; Resize windows proportionally vc-follow-symlinks t ; Follow symlinks without asking image-auto-resize nil ; Do not resize images automatically make-pointer-invisible nil ; Do not make mouse invisible x-stretch-cursor t) ; Stretch cursor to the glyph width (blink-cursor-mode 0) ; Prefer a still cursor (fset 'yes-or-no-p 'y-or-n-p) ; Replace yes/no prompts with y/n (global-subword-mode 1) ; Iterate through CamelCase words (put 'downcase-region 'disabled nil) ; Enable downcase-region (put 'upcase-region 'disabled nil) ; Enable upcase-region (set-default-coding-systems 'utf-8) ; Default to utf-8 encoding (set-terminal-coding-system 'utf-8) (set-keyboard-coding-system 'utf-8) (prefer-coding-system 'utf-8) (column-number-mode t) ; Display column numbers (line-number-mode t) ; Display line numbers (size-indication-mode t) ; Display size indicator ;; enable narrowing commands (put 'narrow-to-region 'disabled nil) (put 'narrow-to-page 'disabled nil) (put 'narrow-to-defun 'disabled nil) ;; enabled change region case commands (put 'upcase-region 'disabled nil) (put 'downcase-region 'disabled nil) ;; enable erase-buffer command (put 'erase-buffer 'disabled nil) ;; repeat pop mark command without the need for C-u (setq set-mark-command-repeat-pop t) (setq image-auto-resize 0.7)
Text Size
;; Font size (global-set-key (kbd "C-+") 'text-scale-increase) (global-set-key (kbd "C--") 'text-scale-decrease)
Buffers
Identification
(require 'uniquify) (setq uniquify-buffer-name-style 'reverse) (setq uniquify-separator " • ") (setq uniquify-after-kill-buffer-p t) (setq uniquify-ignore-buffers-re "^\\*")
Killing
;; Do not ask to kill a buffer. (global-set-key (kbd "C-x k") 'kill-this-buffer) (setq use-short-answers t) (defun cunene/diff-buffer-with-associated-file () "View the differences between BUFFER and its associated file. This requires the external program diff to be in your variable `exec-path'. Returns nil if no differences found, t otherwise." (interactive) (let ((buf-filename buffer-file-name) (buffer (current-buffer))) (unless buf-filename (error "Buffer %s has no associated file" buffer)) (let ((diff-buf (get-buffer-create (concat "*Assoc file diff: " (buffer-name) "*")))) (with-current-buffer diff-buf (setq buffer-read-only nil) (erase-buffer)) (let ((tempfile (make-temp-file "buffer-to-file-diff-"))) (unwind-protect (progn (with-current-buffer buffer (write-region (point-min) (point-max) tempfile nil 'nomessage)) (if (zerop (apply #'call-process "diff" nil diff-buf nil (append (when (and (boundp 'ediff-custom-diff-options) (stringp ediff-custom-diff-options)) (list ediff-custom-diff-options)) (list buf-filename tempfile)))) (progn (message "No differences found") nil) (progn (with-current-buffer diff-buf (goto-char (point-min)) (if (fboundp 'diff-mode) (diff-mode) (fundamental-mode))) (display-buffer diff-buf) t))) (when (file-exists-p tempfile) (delete-file tempfile))))))) (global-set-key (kbd "C-c C-=") 'cunene/diff-buffer-with-associated-file) ;; tidy up diffs when closing the file (defun cunene/kill-associated-diff-buf () "Kill the diff buffer when the file is killed." (let ((buf (get-buffer (concat "*Assoc file diff: " (buffer-name) "*")))) (when (bufferp buf) (kill-buffer buf)))) (add-hook 'kill-buffer-hook 'cunene/kill-associated-diff-buf) (defun cunene/de-context-kill (arg) "Show differences when killing buffer. ARG is true, always kill." (interactive "p") (if (and (buffer-modified-p) buffer-file-name (not (string-match "\\*.*\\*" (buffer-name))) ;; erc buffers will be automatically saved (not (eq major-mode 'erc-mode)) (= 1 arg)) (let ((differences 't)) (when (file-exists-p buffer-file-name) (setq differences (cunene/diff-buffer-with-associated-file))) (if (y-or-n-p (format "Buffer %s modified; Kill anyway? " buffer-file-name)) (progn (set-buffer-modified-p nil) (kill-buffer (current-buffer))))) (if (and (boundp 'gnuserv-minor-mode) gnuserv-minor-mode) (gnuserv-edit) (set-buffer-modified-p nil) (kill-buffer (current-buffer))))) (global-set-key (kbd "C-x k") 'cunene/de-context-kill)
Saving
super-save | https://github.com/bbatsov/super-save |
Super-save auto-saves your buffers, when certain events happen - e.g. you switch between buffers, an Emacs frame loses focus, etc. You can think of it as both something that augments and replaces the standard auto-save-mode.
(use-package super-save :config (add-to-list 'super-save-triggers 'ace-window 'select-window) (super-save-mode +1)) ;; revert buffers automatically when underlying files are changed externally (global-auto-revert-mode t)
Themes
Doom One |
https://github.com/hlissner/emacs-doom-themes |
(use-package doom-themes :config (setq doom-themes-enable-bold t ; if nil, bold is universally disabled doom-themes-enable-italic t) ; if nil, italics is universally disabled (load-theme 'doom-dark+ t) ;; Enable flashing mode-line on errors (doom-themes-visual-bell-config) ;; Corrects (and improves) org-mode's native fontification. (doom-themes-org-config))
Doom modeline.
Links:
(use-package all-the-icons) (use-package all-the-icons-dired) (use-package all-the-icons-completion) (use-package all-the-icons-ibuffer) (use-package all-the-icons-nerd-fonts) (add-hook 'dired-mode-hook 'all-the-icons-dired-mode) (use-package doom-modeline :hook (after-init . doom-modeline-mode) :config (setq doom-modeline-buffer-file-name-style 'buffer-name) (setq doom-modeline-major-mode-icon t) ;; Whether display the buffer encoding. (setq doom-modeline-buffer-encoding nil))
Modeline
diminish |
https://github.com/emacsmirror/diminish |
hide-mode-line |
https://github.com/hlissner/emacs-hide-mode-line |
(use-package diminish) (use-package hide-mode-line)
Whitespace
;; Give details about white space usage (require 'whitespace) (autoload 'whitespace-toggle-options "whitespace" "Toggle local `whitespace-mode' options." t) ;; limit line length (setq whitespace-line-column 80) ;; What to highlight (setq whitespace-style '(face tabs trailing lines-tail space-before-tab empty space-after-tab tab-mark)) ;; Indicate if empty lines exist at end of the buffer (set-default 'indicate-empty-lines t) ;; do not use global mode whitespace (global-whitespace-mode 0) (setq whitespace-global-modes nil) ;; Show whitespaces on these modes (add-hook 'sh-mode-hook 'whitespace-mode) (add-hook 'snippet-mode-hook 'whitespace-mode) (add-hook 'tex-mode-hook 'whitespace-mode) (add-hook 'sql-mode-hook 'whitespace-mode) (add-hook 'ruby-mode-hook 'whitespace-mode) (add-hook 'diff-mode-hook 'whitespace-mode) (add-hook 'csharp-ts-mode-hook 'whitespace-mode) (add-hook 'c-mode-common-hook 'whitespace-mode) (add-hook 'cmake-mode-hook 'whitespace-mode) (add-hook 'emacs-lisp-mode-hook 'whitespace-mode) (add-hook 'dos-mode-hook 'whitespace-mode) (add-hook 'org-mode-hook 'whitespace-mode) (add-hook 'js-mode-hook 'whitespace-mode) (add-hook 'js2-mode-hook 'whitespace-mode) ;; do not clean whitespace on windows. (if (not (eq window-system 'w32)) (add-hook 'before-save-hook 'delete-trailing-whitespace)) ;; ;; Tabs ;; (defun cunene/untabify-buffer () "Remove tabs from buffer." (interactive) (untabify (point-min) (point-max))) (defun cunene/build-tab-stop-list (width) "Create a tab stop list. WIDTH is the size of the list." (let ((num-tab-stops (/ 80 width)) (counter 1) (ls nil)) (while (<= counter num-tab-stops) (setq ls (cons (* width counter) ls)) (setq counter (1+ counter))) (nreverse ls))) ;; Spaces only for indentation (set-default 'indent-tabs-mode nil) ;; Tab size (setq tab-width 4) (setq standard-indent 4) (setq tab-stop-list (cunene/build-tab-stop-list tab-width)) (setq tab-stop-list (cunene/build-tab-stop-list tab-width))
Exiting
Links:
(require 'cl-lib) (defadvice save-buffers-kill-emacs (around no-query-kill-emacs activate) "Prevent annoying \"Active processes exist\" query when you quit Emacs." (cl-letf (((symbol-function #'process-list) (lambda ()))) ad-do-it)) ;; confirm exit (global-set-key (kbd "C-x C-c") #'(lambda () (interactive) (if (y-or-n-p-with-timeout "Do you really want to exit Emacs ?" 4 nil) (save-buffers-kill-emacs)))) (defun cunene/ask-before-closing-frame () "Close only if y was pressed." (interactive) (if (y-or-n-p (format "Do you really want to close this frame?")) (delete-frame) (message "Canceled frame close"))) (global-set-key (kbd "C-x 5 0") 'cunene/ask-before-closing-frame)
Dashboard
emacs-dashboard | https://github.com/emacs-dashboard/emacs-dashboard |
(use-package dashboard :config (dashboard-setup-startup-hook) (setq dashboard-set-heading-icons t) (setq dashboard-startup-banner 'logo) (setq dashboard-set-file-icons t) (setq dashboard-set-init-info t) (setq dashboard-items '((recents . 10) (bookmarks . 5) (projects . 5) (agenda . 5)))) ;; Remap Open Dashboard ;; From https://github.com/emacs-dashboard/emacs-dashboard/issues/236 (require 'dashboard) (defun cunene/new-dashboard () "Jump to the dashboard buffer, if doesn't exists create one." (interactive) (switch-to-buffer dashboard-buffer-name) (dashboard-mode) (dashboard-insert-startupify-lists) (dashboard-refresh-buffer)) (global-set-key (kbd "<f8>") 'cunene/new-dashboard)
Utilities
thingatpt | https://www.emacswiki.org/emacs/ThingAtPoint |
Assorted utility functions for which we could not yet establish a good category.
(use-package crux :bind ( ("C-S-d" . crux-duplicate-current-line-or-region) ;; Move to beginning of line between head of line and head of text ("C-a" . crux-move-beginning-of-line) ("C-c r" . crux-rename-file-and-buffer) ("C-c D" . crux-delete-file-and-buffer)) :config (crux-with-region-or-line kill-region)) (use-package uuid :load-path cunene/vendor-packages) (require 'uuid) (defun cunene/uuid-insert() "Insert a guid." (interactive) (insert (upcase (uuid-string)))) ;; VS Code has a great feature where you can just copy a filename to the ;; clipboard. (defun cunene/copy-file-name-to-clipboard () "Copy the current buffer file name to the clipboard." (interactive) (let ((filename (if (equal major-mode 'dired-mode) default-directory (buffer-file-name)))) (when filename (kill-new filename) (message "Copied buffer file name '%s' to the clipboard." filename)))) (defun cunene/toggle-scroll(&optional arg) "Toggle both horizontal and vertical scroll bars. ARG to set the direction." (interactive) (toggle-horizontal-scroll-bar arg) (toggle-scroll-bar arg)) (defun cunene/flush-blank-lines (start end) "Remove blank lines. START and END mark the region." (interactive "r") (flush-lines "^\\s-*$" start end)) ;; operations on thing at point. (require 'thingatpt) (defun cunene/to-excel-date (date) "Convert DATE to an excel date. Example date: 2024-03-01." (let* ((excel-epoch (encode-time '(0 0 0 1 1 1900))) (excel-days (floor (- (float-time (date-to-time date)) (float-time excel-epoch)) 86400))) (+ excel-days 2) )) (defun cunene/open-directory-on-windows-explorer() "Open Windows Explorer on the current directory." (interactive) (if (eq system-type 'windows-nt) (start-process "EXPLORER" nil "explorer" ".") (message "Command only available on Windows.")))
Editing
iedit | https://github.com/victorhge/iedit |
This package includes Emacs minor modes (iedit-mode and iedit-rectangle-mode) based on a API library (iedit-lib) and allows you to alter one occurrence of some text in a buffer (possibly narrowed) or region, and simultaneously have other occurrences changed in the same way, with visual feedback as you type.
(use-package iedit :ensure t :bind ("C-:" . iedit-mode))
Region
drag-stuff |
https://github.com/rejeep/drag-stuff.el |
volatile-highlights |
https://github.com/k-talo/volatile-highlights.el |
(use-package drag-stuff :bind (:map drag-stuff-mode-map ("<C-s-up>" . drag-stuff-up) ("<C-s-down>" . drag-stuff-down) ("<C-s-left>" . drag-stuff-left) ("<C-s-right>" . drag-stuff-right)) :diminish drag-stuff-mode :config (drag-stuff-global-mode t)) (use-package expand-region :bind ("C-=" . er/expand-region)) ;; Replace region when inserting text (delete-selection-mode 1) ;; brings visual feedback to some operations by highlighting portions relating ;; to the operations. (use-package volatile-highlights :diminish volatile-highlights-mode :config (volatile-highlights-mode t)) ;; note - this should be after volatile-highlights is required ;; add the ability to cut the current line, without marking it (require 'rect) ;; WSL only. As per this post: ;; https://www.fredgruber.org/post/wsl_emacs_clipboard/ ;; (defun cunene/wsl-copy-clip(&rest _args) "Write the region to a file and then copy it to the Windows clipboard." (setq mytemp (make-temp-file "winclip")) (write-region (current-kill 0 t) nil mytemp) (shell-command (concat "clip.exe<" mytemp)) (delete-file mytemp)) ;; (advice-add 'kill-new :after #'cunene/wsl-copy-clip) (defun cunene/wsl-copy-selected-text (start end) (interactive "r") (if (use-region-p) (let ((text (buffer-substring-no-properties start end))) (shell-command (concat "echo '" text "' | clip.exe")))))
Mark
jump-tree |
https://github.com/yangwen0228/jump-tree |
(use-package jump-tree :init (global-jump-tree-mode))
Strings
(defun cunene/toggle-quotes () "Toggle single quoted string to double or vice versa. Flip the internal quotes as well. Best to run on the first character of the string." (interactive) (save-excursion (re-search-backward "[\"']") (let* ((start (point)) (old-c (char-after start)) new-c) (setq new-c (cl-case old-c (?\" "'") (?\' "\""))) (setq old-c (char-to-string old-c)) (delete-char 1) (insert new-c) (re-search-forward old-c) (backward-char 1) (let ((end (point))) (delete-char 1) (insert new-c) (replace-string new-c old-c nil (1+ start) end))))) (defun cunene/backslash-slash-toggle () "Replace backslash/slash in the current region or line. If the current line contains more backslash char than slashes, then replace them to slashes, else replace slashes to backslashes. If there's a text selection, work on the selected text." (interactive) (let (li bds) (setq bds (if (region-active-p) (cons (region-beginning) (region-end)) (bounds-of-thing-at-point 'line))) (setq li (buffer-substring-no-properties (car bds) (cdr bds))) (if (> (count 47 li) (count 92 li)) (progn (replace-string "/" "\\" nil (car bds) (cdr bds))) (progn (replace-string "\\" "/" nil (car bds) (cdr bds)))))) (defun cunene/space-to-underscore-region (start end) "Replace space by underscore in region. START and END mark the region." (interactive "r") (save-restriction (narrow-to-region start end) (goto-char (point-min)) (while (search-forward " " nil t) (replace-match "_")))) (defun cunene/underscore-to-space-region (start end) "Replace underscore by space in region. START and END mark the region." (interactive "r") (save-restriction (narrow-to-region start end) (goto-char (point-min)) (while (search-forward "_" nil t) (replace-match " ")))) (defun cunene/replace-underscore-space-toggle () "Replace underscore/space in the current region or line. If the current line contains more _ char than space, then replace them to space, else replace space to _. If there's a text selection, work on the selected text." (interactive) (let (li bds) (setq bds (if (region-active-p) (cons (region-beginning) (region-end)) (bounds-of-thing-at-point 'line))) (setq li (buffer-substring-no-properties (car bds) (cdr bds))) (if (> (count 32 li) (count 95 li)) (progn (replace-string " " "_" nil (car bds) (cdr bds))) (progn (replace-string "_" " " nil (car bds) (cdr bds)))))) (defun cunene/cycle-hyphen-underscore-space () "Cyclically replace underscore, space, hypen chars. Acts in current line or text selection. When called repeatedly, this command cycles the { , _, -} characters." (interactive) ;; this function sets a property 「'state」. Possible values are 0 ;; to length of charList. (let (mainText charList p1 p2 currentState nextState changeFrom changeTo startedWithRegion-p ) (if (region-active-p) (progn (setq startedWithRegion-p t ) (setq p1 (region-beginning)) (setq p2 (region-end)) ) (progn (setq startedWithRegion-p nil ) (setq p1 (line-beginning-position)) (setq p2 (line-end-position)) ) ) (setq charList (list " " "_" "-" )) (setq currentState (if (get 'cunene/cycle-hyphen-underscore-space 'state) (get 'cunene/cycle-hyphen-underscore-space 'state) 0)) (setq nextState (% (+ currentState (length charList) 1) (length charList))) (setq changeFrom (nth currentState charList)) (setq changeTo (nth nextState charList)) (setq mainText (replace-regexp-in-string changeFrom changeTo (buffer-substring-no-properties p1 p2))) (delete-region p1 p2) (insert mainText) (put 'cunene/cycle-hyphen-underscore-space 'state nextState) (when startedWithRegion-p (goto-char p2) (set-mark p1) (setq deactivate-mark nil)))) (global-set-key (kbd "C-c C--") 'cunene/cycle-hyphen-underscore-space) (defun cunene/string-inflection-cycle-auto () "Switch by major-mode." (interactive) (cond ((eq major-mode 'emacs-lisp-mode) (string-inflection-all-cycle)) ((eq major-mode 'java-mode) (string-inflection-java-style-cycle)) ((eq major-mode 'ruby-mode) (string-inflection-ruby-style-cycle)) (t ;; default (string-inflection-all-cycle)))) (use-package string-inflection :config (global-set-key (kbd "C-M-j") 'cunene/string-inflection-cycle-auto))
Filling
From Sacha Chua's config.
(defun cunene/unfill-paragraph (&optional region) "Take a multi-line paragraph and make it into a single line of text. REGION to fill or unfill." (interactive (progn (barf-if-buffer-read-only) (list t))) (let ((fill-column (point-max))) (fill-paragraph nil region))) (bind-key "M-Q" 'cunene/unfill-paragraph) (defun cunene/fill-or-unfill-paragraph (&optional unfill region) "Fill paragraph (or REGION). With the prefix argument UNFILL, unfill it instead." (interactive (progn (barf-if-buffer-read-only) (list (if current-prefix-arg 'unfill) t))) (let ((fill-column (if unfill (point-max) fill-column))) (fill-paragraph nil region))) (bind-key "M-q" 'cunene/fill-or-unfill-paragraph) (remove-hook 'text-mode-hook #'turn-on-auto-fill) (add-hook 'text-mode-hook 'turn-on-visual-line-mode) (global-so-long-mode 1)
History
(require 'saveplace) (setq save-place-file (cunene/cache-concat "saveplace/places")) (save-place-mode 1) ;; Persist history over Emacs restarts. Vertico sorts by history position. (use-package savehist :init (savehist-mode +1) :config (setq history-length t) (setq history-delete-duplicates t) (setq savehist-save-minibuffer-history 1) (setq savehist-autosave-interval 60) (setq savehist-additional-variables '(kill-ring search-ring regexp-search-ring)) (setq savehist-file (cunene/cache-concat "savehist/history")))
Help
Links:
(use-package helpful :config (setq helpful-switch-buffer-function #'cunene/helpful-switch-to-buffer) (defun cunene/helpful-switch-to-buffer (buffer-or-name) "Switch to helpful BUFFER-OR-NAME. The logic is simple, if we are currently in the helpful buffer, reuse it's window, otherwise create new one." (if (eq major-mode 'helpful-mode) (switch-to-buffer buffer-or-name) (pop-to-buffer buffer-or-name))) :bind (("C-h f" . helpful-callable) ("C-h v" . helpful-variable) ("C-h k" . helpful-key) ("C-c C-d" . helpful-at-point) ("C-h C" . helpful-command)))
Prettify
Sources:
(defun cunene/configure-prettify-symbols-alist () "List of pretty symbols." (push '("[ ]" . "☐" ) prettify-symbols-alist) (push '("[X]" . "☑" ) prettify-symbols-alist) (push '("[-]" . "❍" ) prettify-symbols-alist) (push '("#+BEGIN_QUOTE" . "“") prettify-symbols-alist) (push '("#+END_QUOTE" . "”") prettify-symbols-alist) (push '("#+begin_quote" . "“") prettify-symbols-alist) (push '("#+end_quote" . "”") prettify-symbols-alist) (push '("#+BEGIN_SRC" . "»") prettify-symbols-alist) (push '("#+END_SRC" . "«") prettify-symbols-alist) (push '("#+begin_src" . "»") prettify-symbols-alist) (push '("#+end_src" . "«") prettify-symbols-alist) (prettify-symbols-mode)) (add-hook 'org-mode-hook 'cunene/configure-prettify-symbols-alist) (defun cunene/prog-mode-configure-prettify-symbols-alist () "Set prettify symbols alist." (setq prettify-symbols-alist '(("lambda" . "λ") ("->" . "→") ("->>" . "↠") ("=>" . "⇒") ("map" . "↦") ("/=" . "≠") ("!=" . "≠") ("==" . "≡") ("<=" . "≤") (">=" . "≥") ("=<<" . "=≪") (">>=" . "≫=") ("<=<" . "↢") (">=>" . "↣") ("&&" . "∧") ("||" . "∨") ("not" . "¬"))) (prettify-symbols-mode)) (add-hook 'prog-mode-hook 'cunene/prog-mode-configure-prettify-symbols-alist)
Processes
;; Example: (is-process-running "myprocess") (defun cunene/is-process-running (process-name) "Check if a system process named PROCESS-NAME is running." (let* ((process-list-command (if (eq system-type 'windows-nt) "pslist" "ps aux")) (pipeline (concat process-list-command "| grep -v grep |" (format "grep -c '%s'" process-name))) (output (shell-command-to-string pipeline))) (not (zerop (string-to-number (string-trim output))))))
Postamble
;;; quality_of_life.el ends here