Posts Tagged emacs
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'."
(set (make-local-variable 'minibuffer-default-add-function)
;; Get a command name at point in the original buffer
;; to propose it after M-n.
(let ((def (with-current-buffer
(and (commandp (function-called-at-point))
(format "%S" (function-called-at-point)))))
(all (sort (minibuffer-default-add-completions)
(lambda (a b) (string< a b)))))
(cons def (delete def 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.
((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)))
(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: ".
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
I needed something to speed up my work when I have few windows, I was looking at switch-window.el, but it kind of silly that the content of the window disappear. So I’ve written this simple 2 functions which act similar to my other sollution Faster buffer bookmarking in Emacs. But you mark window to which you want to jump.
It set Keyboard C-c C-0 for mark and C-C C-<1-9> to jump.
(setq window-alist '())
(defun mark-window (number)
"Give current window a number to select it later using `switch-to-number-window'"
(interactive "nNumber Your Window: ")
(let ((pair (assoc number window-alist))
(setf (cdr pair) window)
(add-to-list 'window-alist (cons number window)))))
(defun switch-to-number-window (number)
"Jump to the window marked with a `mark-window' function"
(interactive "nNumber Your Window: ")
(let ((pair (assoc number window-alist)))
(select-window (cdr pair))
(message "Invalid Number"))))
;; create 9 keyboard shortcuts using closure (forced using lexical-let)
(dolist (i (map #'1+ (range 9)))
(global-set-key (read-kbd-macro (concat "C-c C-"
(lexical-let ((i i))
(global-set-key (kbd "C-c C-0") 'mark-window)
It use range helper function (same as in python)
(defun range (n &optional list)
"function return list of numbers from 1 to n"
(if (eq n 0)
(let ((n (- n 1)))
(range n (cons n list)))))
EDIT: I just found windmove commands which are much better.
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))
(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)))
(if (or (null last-time-pair)
(> (float-time (time-subtract current-time
(async-exec-command "mpg123 -q /home/kuba/Pobrane/beep-6.mp3"))
(if (null last-time-pair)
(setf (cdr buffer-alist-pair)
(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)
(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))
(if success (lambda (process str)
(if (string= str "finished\n")
(let ((content (buffer-string)))
(funcall success content)))))
(lambda (proces str)
(concat "execute: " command)))
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)
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
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
Every buffer will have they own bookmarks.