Emacs is an incredibly feature rich editor. You can do just about anything you would ever want to do and much more. Unfortunately the power and flexibility of Emacs can be a bit unfriendly and cumbersome at times. I seem to rediscover this fact every 2-3 weeks and I usually customize Emacs in some way to make things easier for me.
My latest discovery is the complicated bookmarking system. Setting a bookmark in Emacs involves moving to the line in the file you want to bookmark, typing C-x r m and then giving the bookmark a unique name. To find the bookmark later, you type C-x r b and then type the unique name you gave the bookmark. This bookmarking system is very flexible but can difficult to work with.
I’ve used Visual Studio in the past and I became quite fond of its simple bookmarking system. You simply type Ctrl-F2 to set a bookmark and F2 to cycle between bookmarks. Shift-F2 cycles bookmarks in reverse. It is such a brain dead system. No need to remember bookmark names. No tiresome keystrokes to type.
Since Emacs is *the* programmable text editor, I was able to extend the existing bookmarking system to emulate the Visual Studio style bookmarks. Now I have a “dumbed down” bookmarking system that is quick and easy to use.
Here’s the code I wrote to make it happen:
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Easy bookmarks management
;;
;; Author: Anthony Fairchild
;;
;;;; Keymaping examples
;; (global-set-key [(control f2)] 'af-bookmark-toggle )
;; (global-set-key [f2] 'af-bookmark-cycle-forward )
;; (global-set-key [(shift f2)] 'af-bookmark-cycle-reverse )
;; (global-set-key [(control shift f2)] 'af-bookmark-clear-all )
;; Include common lisp stuff
(require 'cl)
(require 'bookmark)
(defvar af-current-bookmark nil)
(defun af-bookmark-make-name ()
"makes a bookmark name from the buffer name and cursor position"
(concat (buffer-name (current-buffer))
" - " (number-to-string (point))))
(defun af-bookmark-toggle ()
"remove a bookmark if it exists, create one if it doesnt exist"
(interactive)
(let ((bm-name (af-bookmark-make-name)))
(if (bookmark-get-bookmark bm-name)
(progn (bookmark-delete bm-name)
(message "bookmark removed"))
(progn (bookmark-set bm-name)
(setf af-current-bookmark bm-name)
(message "bookmark set")))))
(defun af-bookmark-cycle (i)
"Cycle through bookmarks by i. 'i' should be 1 or -1"
(if bookmark-alist
(progn (unless af-current-bookmark
(setf af-current-bookmark (first (first bookmark-alist))))
(let ((cur-bm (assoc af-current-bookmark bookmark-alist)))
(setf af-current-bookmark
(if cur-bm
(first (nth (mod (+ i (position cur-bm bookmark-alist))
(length bookmark-alist))
bookmark-alist))
(first (first bookmark-alist))))
(bookmark-jump af-current-bookmark)
;; Update the position and name of the bookmark. We
;; only need to do this when the bookmark has changed
;; position, but lets go ahead and do it all the time
;; anyway.
(bookmark-set-position af-current-bookmark (point))
(let ((new-name (af-bookmark-make-name)))
(bookmark-set-name af-current-bookmark new-name)
(setf af-current-bookmark new-name))))
(message "There are no bookmarks set!")))
(defun af-bookmark-cycle-forward () "find the next bookmark in the bookmark-alist" (interactive) (af-bookmark-cycle 1))
(defun af-bookmark-cycle-reverse () "find the next bookmark in the bookmark-alist" (interactive) (af-bookmark-cycle -1)) (defun af-bookmark-clear-all() "clears all bookmarks" (interactive) (setf bookmark-alist nil))
Posted by anthonyf