Some Excerpts From My Emacs Config - 2: Functions

Some functions and mode enhancements from my .emacs

Page content

In his comment on Irreal’s post Some Configuration To Solve Common Problems, gregbognar noted that some of my configuration is seriously outdated. In some sense, he is absolutely correct – I’ve been collecting Emacs settings/tweaks since 2012, and keeping them unmodified for 12+ years.

But on the other hand, it demonstrates how stable and powerful Emacs is – everything is still working! If something works, don’t fix it – I’ve since tried to apply this rule wherever possible.

Here are a few functions/enhancements I found helpful.

dired-mode enhancements

Function: Calculate the total size of all marked files

The custom dired-get-size function calculates the total size of all marked files in the dired buffer and displays it in the echo area. Files in the dired buffer can be marked with m key and unmarked with u key.

The current version only works on systems with the /usr/bin/du system utility, which actually comprise 100% of the (non-Windows) systems – borrowed from oremacs.com.

(defun dired-get-size ()
  "Display file size in dired."
  (interactive)
  (let ((files (dired-get-marked-files)))
    (with-temp-buffer
      (apply 'call-process "/usr/bin/du" nil t nil "-sch" files)
      (message
       "Size of all marked files: %s"
       (progn
         (re-search-backward "\\(^[ 0-9.,]+[A-Za-z]+\\).*total$")
         (match-string 1))))))

In my config, dired-get-size is bound to z key in the dired-mode.

;; https://oremacs.com/2015/01/12/dired-file-size/
(define-key dired-mode-map "z" #'dired-get-size)

The result of pressing the `z` key in dired.

Some other dired-mode enhancements

Move to the parent directory

It reuses the current dired buffer for opening the parent directory (oremacs.com) instead of creating a new buffer. Bounded to the a key in dired-mode.

;; Move to the parent directory.
(define-key dired-mode-map "a"
  (lambda ()
    (interactive)
    (find-alternate-file "..")))

Run eshell in the current dired directory

Bounded to the ` back-tick key in dired-mode.

;; Run eshell.
(define-key dired-mode-map "`"
  (lambda ()
    (interactive)
    (eshell)))

Date and time stamps

Inserting the date and/or time stamps at the current cursor position. You can bind these functions to any key chords you prefer or call the corresponding function with M-x.

(defun my/time-stamp ()
  "Insert full date/time stamp as 2024-11-29 10:41 +0100 CET"
  (interactive)
  (insert (format-time-string "%Y-%m-%d %R %z %Z")))

(defun my/time-stamp-short ()
  "Insert short date/time stamp as 2024-11-29 10:41"
  (interactive)
  (insert (format-time-string "%Y-%m-%d %R")))

(defun my/date-stamp ()
  "Insert date stamp as 2024-11-29"
  (interactive)
  (insert (format-time-string "%Y-%m-%d")))

Some editing tweaks

Inserting a new line

Insert a new line, indent it, and move the cursor there. This behavior is different then the typical function bound to Enter which may be open-line or newline-and-indent. When you call them with the cursor between ^ (beginning of line) and $ (end of line), the contents of the line to the right of it will be moved to the newly inserted line. This function will not do that. Instead, the current line is left alone, a new line is inserted, indented, and the cursor is moved there. Borrowed from emacsredux.

(defun smart-open-line ()
  "Insert a new line, indent it, and move the cursor there."
  (interactive)
  (move-end-of-line nil)
  (newline-and-indent))

(global-set-key (kbd "<C-return>") #'smart-open-line)

I have bound it globally to Ctrl-EnterC-return in the Emacs notation – so it should work in any mode.

Smart beginning of line

Move point to first non-whitespace character or beginning-of-line.

(defun smart-beginning-of-line ()
  "Move point to first non-whitespace character or `beginning-of-line`."
  (interactive)
  (let ((oldpos (point)))
    (back-to-indentation)
    (and (= oldpos (point))
         (beginning-of-line))))

(global-set-key (kbd "C-a") #'smart-beginning-of-line)

I’ve rebound the default Ctrl-AC-a in the Emacs notation – to move to first non-whitespace character of a line instead of first column.

Killing a word at point

Deleting the whole word at the cursor position.

(defun kill-whole-word ()
  "Kill the current word at point."
  (interactive)
  (backward-word)
  (kill-word 1))

(define-key global-map (kbd "<M-DEL>") #'kill-whole-word)

I’ve rebound it to Alt-deleteM-DEL in the Emacs notation.

Nuke all buffers

Kill all buffers, leaving *scratch* only.

(defun nuke-all-buffers ()
  "Kill all buffers, leaving *scratch* only."
  (interactive)
  (mapc
   (lambda (buffer)
     (kill-buffer buffer))
   (buffer-list))
  (delete-other-windows))

To be continued. Happy emacsing!