Posts Tagged emacs
Mastering Emacs – Search inside minibufer
Posted by jcubic in Programming on September 23, 2012
This is by far best feature in Emacs that you can use interactive search inside Minibuffer. If you want to find a function that you don’t know exact name, I do this a lot – who will remember function names in Emacs, you can use:
C-h f C-s
And search for functions. How cool is that? Almost all functions that have completion inside minibuffer work with search like
- C-x b C-s – search for buffer to switch
- C-h <KEY> C-s – search for help
When I switch to Emacs 24, I found that M-x C-s don’t work. So you can’t search for interactive function to execute. But you can get it back. As describe by this Emacs Bug Ticket by putting this to you .emacs file.
(defun read-extended-command ()
"Read command name to invoke in `execute-extended-command'."
(minibuffer-with-setup-hook
(lambda ()
(set (make-local-variable 'minibuffer-default-add-function)
(lambda ()
;; Get a command name at point in the original buffer
;; to propose it after M-n.
(let ((def (with-current-buffer
(window-buffer (minibuffer-selected-window))
(and (commandp (function-called-at-point))
(format "%S" (function-called-at-point)))))
(all (sort (minibuffer-default-add-completions)
(lambda (a b) (string< a b)))))
(if def
(cons def (delete def all))
all)))))
;; Read a string, completing from and restricting to the set of
;; all defined commands. Don't provide any initial input.
;; Save the command read on the extended-command history list.
(completing-read
(concat (cond
((eq current-prefix-arg '-) "- ")
((and (consp current-prefix-arg)
(eq (car current-prefix-arg) 4)) "C-u ")
((and (consp current-prefix-arg)
(integerp (car current-prefix-arg)))
(format "%d " (car current-prefix-arg)))
((integerp current-prefix-arg)
(format "%d " current-prefix-arg)))
;; This isn't strictly correct if `execute-extended-command'
;; is bound to anything else (e.g. [menu]).
;; It could use (key-description (this-single-command-keys)),
;; but actually a prompt other than "M-x" would be confusing,
;; because "M-x" is a well-known prompt to read a command
;; and it serves as a shorthand for "Extended command: ".
"M-x ")
obarray 'commandp t nil 'extended-command-history)))
And tell me, why you will ever need Ido-mode
One note about that, when you use one interactive function inside another one you will need to call C-g twice to exit minibuffer
ERC notifications on channels where there was activity after some inactivity
Posted by jcubic in Programming on July 24, 2012
I need to monitor few IRC channels and I use Emacs so I write simple elisp function that I append to erc-insert-pre-hook and it notify me when there is some activity on those channels. I made this mainly because I what to know if someone visit #openclipart channel (because people where visiting ask question and leave after few minutes, there is no much activity on this channel)
(setq inactivity-buffer-alist '(("#openclipart" (inactivity . 900))
("#hackerrank" (inactivity . 900))
("#aiki" (inactivity . 900))))
(defun channel-activity (string &rest ignore)
"notification when there is activity on a erc channel after inactivity"
(let* ((buffer (buffer-name))
(buffer-alist-pair (assoc buffer inactivity-buffer-alist))
(buffer-alist (cdr buffer-alist-pair))
(current-time (current-time)))
(if (not (null buffer-alist))
(let ((last-time-pair (assoc 'last-time buffer-alist))
(inactivity (cdr (assoc 'inactivity buffer-alist))))
(if (not (and (string-match "^\\*\\*\\*" string)
(string-match "[freenode-info]" string)))
(progn
(if (or (null last-time-pair)
(> (float-time (time-subtract current-time
(cdr last-time-pair)))
inactivity))
(async-exec-command "mpg123 -q /home/kuba/Pobrane/beep-6.mp3"))
(if (null last-time-pair)
(setf (cdr buffer-alist-pair)
(append buffer-alist
(list (cons 'last-time current-time))))
(setf (cdr last-time-pair) current-time))))))))
(add-hook 'erc-insert-pre-hook 'channel-activity)
You can add your channels to inactivity-buffer-alist along with time of inactivity (in miliseconds)
The function I use for notification is play sound using (async-exec-command "mpg123 -q /home/kuba/Pobrane/beep-6.mp3") – normal shell command was stoping execution of Emacs for few seconds
The code for this function is as follow
(defun async-exec-command (command &rest success)
(interactive)
(let* ((buffer-name (generate-new-buffer-name "**shell**"))
(buffer (get-buffer-create buffer-name))
(process (apply #'start-process
(append (list buffer-name buffer)
(split-string command " ")))))
(lexical-let ((buffer buffer) (success (car success)) (command command))
(set-process-sentinel process
(if success (lambda (process str)
(if (string= str "finished\n")
(save-excursion
(set-buffer buffer)
(let ((content (buffer-string)))
(kill-buffer buffer)
(funcall success content)))))
(lambda (proces str)
(kill-buffer buffer)))))
(concat "execute: " command)))
Switching between buffers with the same major mode in Emacs
Posted by jcubic in Programming on January 26, 2012
Below are functions that can be used to switch to next or previus buffer in the same major mode
(defun buffer-same-mode (change-buffer-fun)
(let ((current-mode major-mode)
(next-mode nil))
(while (not (eq next-mode current-mode))
(funcall change-buffer-fun)
(setq next-mode major-mode))))
(defun previous-buffer-same-mode ()
(interactive)
(buffer-same-mode #'previous-buffer))
(defun next-buffer-same-mode ()
(interactive)
(buffer-same-mode #'next-buffer))
In my init file I have bind those functions to CTRL+TAB and CTRL+ALT+TAB which was not set by default.
(global-set-key [C-M-tab] 'previous-buffer-same-mode) (global-set-key [C-tab] 'next-buffer-same-mode)
Faster buffer bookmarking in Emacs
Posted by jcubic in Programming on January 25, 2012
I wanted to speed up jumping in the same buffer so I have written this bookmarking utility (Similar to built-in registers) and put it in my .emacs file.
(defvar bookmark-markers '())
(defun bookmark (bookmark)
"Store current position for this buffer in
bookmar-markers a-list"
(interactive "nBookmark: ")
(let* ((buffer (current-buffer))
(bookmarks
(let ((pair (assoc buffer bookmark-markers)))
(if (eq pair nil)
(let ((new-pair (cons buffer '())))
(progn
(setq bookmark-markers
(append bookmark-markers
(list new-pair)))
new-pair))
pair))))
(let ((pair (assoc bookmark bookmarks)))
(if (eq pair nil)
(setf (cdr bookmarks)
(append (cdr bookmarks)
(list (cons bookmark (point)))))
(setf (cdr pair) (point))))))
(defun jump-to-bookmark (bookmark)
"Jump to previously stored bookmark position"
(interactive "nJump To: ")
(let ((pair-bookmars (assoc (current-buffer) bookmark-markers)))
(if (not (eq pair-bookmars nil))
(let ((pair-point (assoc bookmark (cdr pair-bookmars))))
(if (not (eq pair-point nil))
(goto-char (cdr pair-point)))))))
(defun range (n &optional list)
"function return list of numbers from 1 to n"
(if (eq n 0)
list
(let ((n (- n 1)))
(range n (cons n list)))))
(dolist (i (range 9))
(global-set-key (read-kbd-macro (concat "C-c "
(number-to-string i)))
;; emacs lisp have no closures
(lexical-let ((i i))
(lambda ()
(interactive)
(jump-to-bookmark i)))))
(global-set-key (kbd "C-c 0") 'bookmark)
Above code define 2 functions bookmark bind to C-c 0 and function jump-to-bookmark this function create a bookmark, for currect position in a buffer, and assing it to the number (passed as argument or from minubuffer, if run interactively). You have 9 keyboard binding for keys from C-c 1 to C-c 9.
You can use it go to specific location and type C-c 0 1 RET go to another location and type C-c 0 2 RET and now you can jump to locations with C-c 1 or C-c 2.
Every buffer will have they own bookmarks.

