Index: An Incremental Blog
Newer: An Incremental Blog
Older: Recipe: rsync-in
[ Vlado Keselj | 2022-10-23..2023-11-01 ]

STIL Recipes: emacs

(STIL stands for Software That I Like, which is emacs in this case.)
I would like to record here some useful emacs functions, which I usually add to my ~/.emacs configuration file.

Before start, I prefer using Emacs in the terminal mode, and the following bash alias is useful to have in the .bashrc file:

alias em='emacs -nw'

Going back to the .emacs file, I do not use Emacs Lisp that often, so one item to aways remember is that the line comments start with a semi-colon (;):

; Line comment

I prefer not to have syntax highlighting:

(global-font-lock-mode 0)
and I like to see column numbers:
(column-number-mode t)

Macro repeat [f8]. Recording a macro is a useful feature of Emacs. We start recording with C-x ( and stop recording with C-x ). All operations between the start and stop are now recorded and can be repeated with C-x e. This key sequence actually calls the Emacs function call-last-kbd-macro and I find it useful to link it to one of the keyboard function keys, f8 in particular, in the following way:

(global-set-key [f8] 'call-last-kbd-macro)

Moving line up and down [Alt+Up] [Alt+Down]. It is frequently very useful to be able to easily move aline of text up or down in a text file. We a use shortcuts Alt+Up and Alt+Down (press Alt key and with arrow keys Up and Down move the line). This is achieved with the following Emacs set-up code:

;; Moving a line of text
(defun move-line (n)
  "Move the current line up or down by N lines."
  (interactive "p")
  (let ((col (current-column))
        start
	end)
    (beginning-of-line)
    (setq start (point))
    (end-of-line)
    (forward-char)
    (setq end (point))
    (let ((line-text (delete-and-extract-region start end)))
      (forward-line n)
      (insert line-text)
      ;; restore point to original column in moved line
      (forward-line -1)
      (forward-char col))))

(defun move-line-up (n)
  "Move the current line up by N lines."
    (interactive "p")
      (move-line (if (null n) -1 (- n))))

(defun move-line-down (n)
  "Move the current line down by N lines."
  (interactive "p")
  (move-line (if (null n) 1 n)))

; Alt-up Alt-down
(global-set-key (kbd "<A-up>") 'move-line-up)
(global-set-key (kbd "<A-down>") 'move-line-down)
(global-set-key (kbd "<M-up>") 'move-line-up)
(global-set-key (kbd "<M-down>") 'move-line-down)
; in tmux below is required
(global-set-key (kbd "ESC <up>") 'move-line-up)
(global-set-key (kbd "ESC <down>") 'move-line-down)

Save, recompile, and reopen [f5] [f6]. Emacs has nice compile and recompile functions, which I frequently use to compile programs but also to do all kinds of "executions" such as: any make recipes, compile and test run, script test run, web-site updates, and so on. The old IDEs such as Turbo Pascal, Microsoft Visual-something, and others used F5 keyboard hotkey to do "Run"; i.e., execute a progam. So, I wire f5 in a similar way:

; f5 used to recompile
(global-set-key [f5] (lambda () (interactive)
  (save-buffer)
    (if (fboundp 'recompile) (recompile)
        (compile (read-string "Compile command: " compile-command)))))
When we press f5 for the first time, it will prompt us to edit the compile command, and it will be used later for each new invocation of f5.

Frequently I need to save file, recompile and reopen it, especially when using Starfish:

; f6 = Recompile and re-open
(global-set-key [f6] 'recompile-and-reopen)
(setq reopen-after-compile nil) ; flag to activate re-open hook
(setq reopen-finish-added nil)  ; indicator that hook is added
(defun recompile-and-reopen ()
  "Save file, recompile, and re-open it"
  (interactive nil)
  (save-buffer (current-buffer))
  (setq fileName (buffer-file-name))
  (setq reopen-after-compile t)
  (if (not reopen-finish-added) (progn
      (add-hook 'compilation-finish-functions #'(lambda (buf str)
        (if (and reopen-after-compile (string-match "finished" str)) (progn
          ; I was trying to use here (revert-buffer t t) somehow
          ; but it causes infinite recursion.  Warning about updating
          ; file from disk is not removed yet.
          (delete-other-windows)
          (find-file fileName)
          (message "---------- File Compiled and Reopened ----------")
          (sleep-for 1) (message "")
	))
        (setq reopen-after-compile nil)
	))
        (setq reopen-finish-added t)
  ))

  (if (fboundp 'recompile) (recompile)
      (compile (read-string "Compile command: " compile-command)))
  (message "---------- DONE ----------")
  (sleep-for 1) (message "") )

created: 2022-10-23, last update: 2023-11-01, me comments

© 2022-2023 Vlado Keselj, last update: 01-Nov-2023