Skip navigation

Tag Archives: elisp

A probably ridiculous thing to do, I know, but in hope of getting valuable help for you elisp expert guys out there (I’m all ears) I’m going ahead to show the unusual path I followed to simply bind the org-cicle invoked with an argument 64 (C-u C-u C-u)

(This is also a litle probe of how magnanimously flexible the emacs lisp environment can actually be to allow us to record processes we want automated for later reuse)
Anyway:
1) I started to record the macro “C-(
2) made the call to org-cycle to reveal-all by previously pressing C-u three times “C-u C-u C-u M-x org-cycle
3) stopped recording macro “C-)
4) did “M-x kmacro-name-last-macro” (which provides the lambda form of the last created macro)
5) ran “M-x insert-kbd-macro
6) assigned a key binding to it (global-set-key(kbd “C-+”) ‘my-org-reveal-all)


(fset 'my-org-reveal-all
(lambda (&optional arg) "Keyboard macro." (interactive "p") (kmacro-exec-ring-item (quote ([21 21 21 134217816 111 114 103 45 99 121 99 108 101 return] 0 "%d")) arg)))

(global-set-key(kbd “C-+”) ‘my-org-reveal-all)

I just wanted to free a shortcut I had for “C-1” to let it behave the way it was meant with the command “digit-arguments”. This answer http://stackoverflow.com/questions/7549259/is-there-a-quick-way-to-unbind-keys-in-emacs came in handy.

(global-unset-key (kbd “C-1”))
(define-key global-map (kbd “C-1”) ‘digit-argument)

By the way (a little tip) you can go: C-<digit ARG) instead of the C-u method; say to move 11 characters back, “C-11 C-b” is quicker than “C-u 11 C-b”, one less hit!

Now that I’m getting fond of using a heredoc to insert mysql scripts into the bash shell, have put this into my emacs initialization file. The same shortcut (Control+Shift+f11) will conveniently write different parameters depending in which shell I’m sitting in.

UPDATE: seems that I spoke too soon. Asking about the present working directory, formerly “(let ((a (shell-command-to-string “pwd | tr -d ‘\\n'”)))”, didn’t actually work when having opened shells of different servers via Tramp.
The correction below (less elegant) depends on the shell buffer being created/renamed with an identifiable name -which could be the hostname or whatever consistent nomenclature we choose-.
Anyway, until figuring a better way, this does the job of inserting the right parameters into each shell:

(defun my-heredoc-sql-invocation-from-shell ()
"Insert the appropiate parameters to run a heredoc mysql query depending on which shell I'm in"
  (interactive)
  (let ((a (buffer-name (window-buffer (minibuffer-selected-window))))
        (b nil))
    (cond ((string-match "serverA" a) 
           (setq b "mysql -uroot mainDbToHitAt_A--password=`cat /etc/security/mysqlpassword` -t -vv <<\\!"))
          ((string-match "serverB" a) 
           (setq b "mysql -ualpha mainDbToHitAt_B --password=`cat /etc/security/mysqlpassword` -t -vv <<\\!"))
          ((string-match "serverC" a) 
           (setq b "mysql -uroot mainDbToHitAt_C  -t <<\\!")))
    (insert b)))

;; key shortcut to bind it to
(global-set-key (kbd "C-S-<f11>")  'my-heredoc-sql-invocation-from-shell)

In emacs you use the function “occur” to find all occurrences of a string (or regexp) in a buffer. The matching lines are listed in another buffer named “*Occur*”, and you can click them there to navigate to the corresponding lines in the original buffer. That is, buffer ‘*Occur*’ acts as a hypertext index to your buffer.

Here’s a little bit of elisp that I wrote inside the dot emacs (the configuration to customize stuff) to re-define occur (well it’s actually a sort of wrapper of the function since itself isn’t touched and you can still call it with M-x occur ).

As the code is already commented, I’ll put it here without much explanation.

(defun my-occur (&optional arg)
 "Make sure to always put occur in a vertical split, into a narrower buffer at the side.
I didn't like the default horizontal split, nor the way it messes up the arrangement of windows in the frame or 
the way in which the standard way uses a neighbor window."
  (interactive "P")
  (window-configuration-to-register ?y) ; store whatever frame configuratin we are currently in
  (occur (read-from-minibuffer "Regexp: "))
  (if (occur-check-existence)
      (progn
        (delete-other-windows)
        (split-window-horizontally)
        (enlarge-window-horizontally -10)
        (set-cursor-color "green")))
  (occur-procede-accordingly))


(defun occur-procede-accordingly ()
  "Switch to occur buffer or prevent opening of the occur window if no matches occured."
  (interactive "P")
  (if (not(get-buffer "*Occur*"))
      (message "There are no results.")
    (switch-to-buffer "*Occur*")))

(defun occur-check-existence()
  "Signal the existance of an occur buffer depending on the number of matches."
  (interactive)
  (if (not(get-buffer "*Occur*"))
      nil
    t))

(define-key global-map (kbd "C-S-o") 'my-occur)


(defun occur-mode-quit ()
  "Quit and close occur window. I want to press 'q' and leave things as they were before in regard of the split of windows in the frame.
This is the equivalent of pressing C-x 0 and reset windows in the frame, in whatever way they were,
plus jumping to the latest position of the cursor which might have been changed by using the links out
of any of the matches found in occur."
  (interactive)
  (switch-to-buffer "*Occur*")
  ;; in order to know where we put the cursor thay might have jumped from qoccur
  (other-window 1)                  ;; go to the main window
  (point-to-register ?1)            ;; store the latest cursor position
  (switch-to-buffer "*Occur*")      ;; go back to the occur window
  (kill-buffer "*Occur*")           ;; delete it
  (jump-to-register ?y)             ;; reset the original frame state
  (set-cursor-color "rgb:ff/fb/53") ;; reset cursor color
  (register-to-point ?1))           ;; re-position cursor


;; some key bindings defined below. Use "p" ans "n" as in dired mode (without Cntrl key) for previous and next line; just show occurrence without leaving the "occur" buffer; use RET to display the line of the given occurrence, instead of jumping to i,t which you do clicking instead;  also quit mode with Ctrl-g.
(define-key occur-mode-map (kbd "q") 'occur-mode-quit)
(define-key occur-mode-map (kbd "C-q") 'occur-mode-quit)
(define-key occur-mode-map (kbd "C-g") 'occur-mode-quit)
(define-key occur-mode-map (kbd "C-RET") 'occur-mode-goto-occurrence-other-window)
(define-key occur-mode-map (kbd "C-<up>") 'occur-mode-goto-occurrence-other-window)
(define-key occur-mode-map (kbd "RET") 'occur-mode-display-occurrence)
(define-key occur-mode-map (kbd "p") 'previous-line)
(define-key occur-mode-map (kbd "n") 'next-line)

The windows split capabilities of emacs is something I didn’t know before and became quite an important aspects of my editing work habits.

An emacs window is a viewport that looks into a buffer. The emacs screen begins by displaying a single window, but this screen space can later be divided among two or more windows. On the screen, the current window holds the cursor and views the current buffer.
A windows views one buffer at a time. Multiple windows can view one buffer, each window may view different parts of the same buffer, and each window carries its own value of Point. Any change to a buffer will be reflected in all the windows viewing that buffer.

Even with rudimentary knowledge of elisp I managed to hack a few functions to go into my dot file (the configuration file of the editor) to deal with them.

For instance, I depend a lot on this is one in my workflow as I happen to need several files open simultaneously, plus the shell, some folder in dired mode, etc. With it I can be sort of zooming in and out, maximizing any buffer and going back to the split as I please .

;; I want to be able to conmute between a split and a single window (sort of "C-x 1" for the one on focus)
(defun toggle-windows-split()
"Switch back and forth between one window and whatever split of windows we might have in the frame. The idea is to maximize the current buffer, while being able to go back to the previous split of windows in the frame simply by calling this command again."
(interactive)
(if (not(window-minibuffer-p (selected-window)))
(progn
(if (< 1 (count-windows))
(progn
(window-configuration-to-register ?u)
(delete-other-windows))
(jump-to-register ?u))))
(my-iswitchb-close))

Then, the convenient key binding:
(define-key global-map (kbd "C-`") 'toggle-windows-split)
(define-key global-map (kbd "C-~") 'toggle-windows-split)
(define-key global-map (kbd "C-|") 'toggle-windows-split) ; same key, on a spanish keyword mapping since I commute a lot between both

Below, a tweaking of the function other-window to go back and some key bindings to cycle through windows.

;; Window shifting. C-x-o lets us go forward a window (or several).
;; This one lets us go back one or more windows. From Glickstein.
(defun other-window-backward (&optional n)
"Select previous Nth window."
(interactive "P")
(other-window (- (prefix-numeric-value n))))

(define-key global-map (kbd “”) ‘other-window) ; [PgUp]
(define-key global-map (kbd “”) ‘other-window-backward) ; [PgDn]

(global-set-key [(control tab)] ‘other-window)
(global-set-key [(shift control tab)] ‘other-window-backward)

Also (stolen from someone else’s dot file) this is needed to shrink/expand windows without using the mouse.

(define-key global-map (kbd "C-M-<left>") 'shrink-window-horizontally)
(define-key global-map (kbd "C-M-<right>") 'enlarge-window-horizontally)
(define-key global-map (kbd "C-M-<top>") 'enlarge-window)
(define-key global-map (kbd "C-M-<down>") 'shrink-window)

Ah! I so wanted this in the tip of my fingers that felt really good writing the small elisp code to insert the find command I use the most in shell. See how the insertion bar also gets in place for conveniently start typing in between the quotes.

(set-register ?x "find . -type f -exec grep -i '' /dev/null {} + | awk '!/svn|htdocs/'")
(defalias 'x
(read-kbd-macro "M-x insert-register RET x C-u 30 M-x forward-char "))
(global-set-key [C-S-f10] 'x)

It’s now part of my .emacs file