The kill ring is a nice thing to have. Only the navigation is a bit to uncomfortable (I am refering to doing C-y again and again until the to desired element is found). So this is what I came up with to feel more ‚comfy‘:

(defun pre-process-kill-ring-element (element)
  (replace-regexp-in-string "^[[:space:]]+" ""
                            (replace-regexp-in-string "[[:space:]]+$" "" (substring-no-properties element))))
 
(defun preprocess-kill-ring ()
  (let ((result nil)
        (element nil))
    (dolist (element kill-ring)
      (progn
        (setq element (pre-process-kill-ring-element element))
        (when (not (or
                    (eq 0 (length element))
                    (string-match-p "[\r\n]+" element)))
          (setq result (cons element result)))))
    (reverse result)))
 
(defun browse-kill-ring ()
  (interactive)
  (insert (completing-read "Pick an element: "
                       (preprocess-kill-ring))))
 
(global-set-key (kbd "C-M-y") 'browse-kill-ring)

The Emacs built-in command (garbage-collect) gives detailed information about the data structures that currently consume memory. It is propably not the most usefull information but I wanted to collect the data and plot it. I started with writing functions to access the list returned from (garbage-collect):

(defsubst get-mem-conses (mi)
  (let ((data (nth 0 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-symbols (mi)
  (let ((data (nth 1 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-misc (mi)
  (let ((data (nth 2 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-string-header (mi)
  (let ((data (nth 3 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-string-bytes (mi)
  (let ((data (nth 4 mi)))
    (/ (* (nth 1 data) (nth 2 data)) (* 1024 1024.0))))
 
(defsubst get-mem-vector-header (mi)
  (let ((data (nth 5 mi)))
    (/ (* (nth 1 data) (nth 2 data)) (* 1024 1024.0))))
 
(defsubst get-mem-vector-slots (mi)
  (let ((data (nth 6 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-floats (mi)
  (let ((data (nth 7 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-intervals (mi)
  (let ((data (nth 8 mi)))
    (/ (* (nth 1 data) (+ (nth 2 data) (nth 3 data))) (* 1024 1024.0))))
 
(defsubst get-mem-buffers (mi)
  (let ((data (nth 9 mi)))
    (/ (* (nth 1 data) (nth 2 data)) (* 1024 1024.0))))

Then I had need for a function that will be called periodically. This function will call (garbage-collect) and store the data in the file-system:

(defun collector (filename)
  "Write memory data into file with FILENAME."
  (let ((mi (garbage-collect)))
    (with-temp-buffer
      (insert 
       (format "%f %f %f %f %f %f %f %f %f %f %f\r\n"
               (float-time)
               (get-mem-conses mi)
               (get-mem-symbols mi)
               (get-mem-misc mi)
               (get-mem-string-header mi)
               (get-mem-string-bytes mi)
               (get-mem-vector-header mi)
               (get-mem-vector-slots mi)
               (get-mem-floats mi)
               (get-mem-intervals mi)
               (get-mem-buffers mi)))
      (let ((message-log-max nil))
        (append-to-file (point-min) (point-max) filename)))))

Next I have need for a function that starts the collection process and one that stops it again:

(defvar collector-timer nil)
 
(defun start-collection (filename interval)
  (interactive "FEnter filename:\nMEnter interval: ")
  (setq collector-filename filename
        collector-timer (run-at-time
                         2
                         (string-to-number interval)
                         'collector filename)))
(defun stop-collection ()
  (interactive)
  (when (timerp collector-timer)
    (cancel-timer collector-timer)))

Finally the collected data should be plotted into a nice graph:

(defun plot-data (datafile imagefile)
  (interactive "FEnter data-filename: \nFEnter image-filename:")
  (let ((gnuplot (start-process "gnuplot" "*gnuplot*" "gnuplot")))
    (process-send-string gnuplot "set term png\n")
    (process-send-string gnuplot (format "set output \"%s\"\n" imagefile))
    (process-send-string gnuplot "set grid\n")
    (process-send-string gnuplot "set title \"Emacs memory consumption by category\"\n")
    (process-send-string gnuplot "set xlabel \"interval\"\n")
    (process-send-string gnuplot "set autoscale\n")
    (process-send-string gnuplot "set ylabel \"2^{20} bytes\"\n")
    (process-send-string gnuplot (format "plot \"%s\" using 2 title \"cons cells\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 3 title \"symbols\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 4 title \"\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 5 title \"string header\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 6 title \"string bytes\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 7 title \"vector header\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 8 title \"vector slots\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 9 title \"floats\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 10 title \"intervals\" with lines" datafile))
    (process-send-string gnuplot (format ", \"%s\" using 11 title \"buffers\" with lines\n" datafile))))

Turns out that my emacs usage was really calm in the time when I sampled the data 🙂 In fact I have entered some kilobytes of test data into the scratch buffer with two seconds between two samples:

I recently wanted to have some more information about which of the packages I am using contributes more time to the total (emacs-init-time) I use to keep my emacs init code in a single file and I manually divide the file into sections of related code. A section is opened by entering a carefully prepared comment string and ended by another one so that it looks like this:

;; [ an example section
(some emacs lisp)
(and some more)
;; ]

Starting from here I could alter my init file to write down time values from the stop-clock (And since I also need to know to which section the time value belongs – the section names). Therefore I invoked query-replace-regexp and query-replace to surround my sections with emacs lisp to collect the necessary information:

query replace regexp: ;; []] \(.*\) ➤ ;; [ \1[C-q C-j](add-to-list 'section-names "\1")
query replace: ;; ] ➤  (add-to-list 'init-runtime (get-internal-run-time))[C-q C-j];; ]

My example section would then look like this:

;; [ an example section
(add-to-list 'section-names "an example section")
(some emacs lisp)
(and some more)
(add-to-list 'init-runtime (get-internal-run-time))
;; ]

After the whole file is processed I end up with two lists (I called them section-names and init-runtime). These I then further-process. So I switched to an org-mode buffer and entered


#+NAME: perf_data_names
#+BEGIN_SRC emacs-lisp
(reverse section-names)
#+END_SRC

#+NAME: perf_data_times
#+BEGIN_SRC emacs-lisp
(progn
    (let ((bak-init-times init-runtime)
          (next nil)
          (result '()))
        (while bak-init-times
           (setq next (car bak-init-times))
           (setq bak-init-times (cdr bak-init-times))
           (add-to-list 'result (+ (nth 2 next)
                                   (* (nth 1 next) 1000000))))
      result))
#+END_SRC

#+BEGIN_SRC python :var sections=perf_data_names :var times=perf_data_times :results output
xtics="set xtics ("
numsections=len(sections)
for i, section in enumerate(sections):
    xtics = xtics +  "\"{0}\" {1}".format(section, i+1)
    if i<numsections-1:
      xtics = xtics + ", "
xtics+=")"      
print("set grid")
print(xtics)
print("plot \"-\" using 1:2 title "Stopclock times")
for i, time in enumerate(times):
    print("{0} {1}".format(i+1, time))
print("e")    
#+END_SRC

This results in a snippet of text that can be fed into gnuplot! Gnuplot kindly generates the following image:

It turns out that no one can really be blamed for beeing responsible and it must be taken into consideration that some of the loading may be deferred and is not subject to the analysis (No, I did not look up how exactly use-package is deferring package loading). Some sections take more time then others:

  • packages
  • s
  • global appearance
  • yasnippet
  • org mode
  • java mode
  • elpy python
  • magit

There are a couple of symbols the emacs‘ lisp interpreter gives special meaning to. Since for some reason these never made it into my long-term memory I collect them here for later reference. Quotes are copied from all over the internet (mostly from GNU Emacs Lisp reference). A reference is given in the last column.

Symbol Meaning Reference
# The sharp quote (or function quote, or simply #‘) is an abbreviation for the function form. It is essentially a version of quote (or ‚) which enables byte-compilation, but its actual usefulness has changed throughout the years. reference
` Backquote constructs allow you to quote a list, but selectively evaluate elements of that list. reference
: A symbol whose name starts with a colon (‘:’) is called a keyword symbol. These symbols automatically act as constants, and are normally used only by comparing an unknown symbol with a few specific alternatives. reference
, Unquotes expressions in backquote-constructs. reference
' Prevents its single argument from beeing evaluated reference
? Introduces a „character literal“ (eg ?a). Evaluates to the printed representation of the character. reference
,@ Splice an evaluated value into a list reference
; Introduces a comment. reference

There is a couple of packages for emacs that really have application character. Like for example:

  • https://www.emacswiki.org/emacs/Magit
  • https://www.emacswiki.org/emacs/EmacSpeak
  • https://www.emacswiki.org/emacs/GnusTutorial
  • https://github.com/skeeto/elfeed
  • https://emacswiki.org/emacs/Sunrise_Commander

And there are propably some more. Me personally – I did not adopt well to the „App in Emacs“ approach as I use none of the mentioned packages. It’s not a categorical decision, I just did not get used to it. My writings in Emacs Lisp have a much lesser extend: Recently I had need to copy files from one directory to the other and I just love to have this done with two directories showing up side by side as in well known „file commanders“. That said Emacs Lisp comes to the rescue!

(defun mp-dired-2pane-copy-over ()
  (interactive)
    (when (eq 2 (length (window-list)))
      (let ((other-directory nil)
            (file-to-copy (dired-get-filename)))
        (progn
          (other-window 1)
          (setq other-directory (dired-current-directory))
          (other-window 1)
          (copy-file file-to-copy other-directory)
          (other-window 1)
          (revert-buffer)
          (other-window 1)))))

I have customized my ibuffer-format to have the name column width set to 36. This is fine in 99% of the filenames showing up there. However I also have to access a couple of files that have a common prefix that is longer then 36 characters. This way the files cannot be distinguished in ibuffer… Since I am not willing to have the width set to even higher value I have added this little defun to my init.el to deal with the issue:

 
(defun mp/ibuffer-show-filename ()
  (interactive)
  (let ((buf (ibuffer-current-buffer))
        (lsoutput nil))
    (when (file-exists-p (buffer-file-name buf))
      (with-temp-buffer
        (let* ((filename (buffer-file-name buf))
               (default-directory (file-name-directory filename))
               (just-filename (file-name-nondirectory filename)))
          (call-process "/usr/bin/ls" nil t nil "-l" just-filename)
          (setq lsoutput (buffer-substring-no-properties (point-min) (- (point-max) 1))))))
    (message lsoutput)))
 
(define-key ibuffer-mode-map (kbd "f") 'mp/ibuffer-show-filename)

This way I can stick to my column width of 36 and whenever I have need to see the a longer filename I can just press f on the entry and see the name at the bottom of the screen.

Even though I am a long time Emacs user I only recently realized that I am really missing treeviews. There are numerous applications like getting an overview of a directory hierarchy  or structure of documents in xml format. It’s a nice thing to have and of course Emacs does not stand back and has something to offer:

To name a couple that immediatly show up. For the dyi people emacs brings an xml parser and a thing called „Tree-widget“ that allows for building of tree-views.  I gave these a try. And since the web does not seem to overflow with information about using tree widget I dump it here – hoping that other beginners might profit from it:

 

 
(setq xml "<post time=\"20050716234509\" id=\"010101\"><login><id>123</id></login><msg>A message.</msg><info>Information!</info></post>")
(setq xml-2 "<post><login><id>123</id></login><msg>Here is the message</msg><info>Information!</info></post>")
(setq xml-3 "<id>123</id>")
 
(setq root (with-temp-buffer
             (insert xml)
             (xml-parse-region (point-min) (point-max))))
 
(setq root-2 (with-temp-buffer
               (insert xml-2)
               (xml-parse-region (point-min) (point-max))))
 
(setq root-3 (with-temp-buffer
               (insert xml-3)
               (xml-parse-region (point-min) (point-max))))
 
(setq root-4 (with-current-buffer "some-more-complex.xml"
               (xml-parse-region (point-min) (point-max))))
 
(xml-node-children (car root-3))
 
(cdr (car (car (nthcdr 1 (car root)))))
 
(let* (
       (post (car root))
       (attrs (xml-node-attributes post)))
  attrs)
 
(require 'tree-widget)
 
(defun xml-to-tree-widget (xml)
  (interactive)
  (cond 
   ((stringp xml)
    (widget-convert 'item :tag xml))
   ((listp xml)
    (let ((attributes (xml-node-attributes xml))
          (attrib-widgets nil)
          (children (xml-node-children xml))
          (current-node))
      (progn
        (when attributes
          (setq attrib-widgets (mapcar (lambda (prop)
                                         (widget-convert 'item
                                                         :tag (format "%s=%s" (symbol-to-string (car prop)) (cdr prop))))
                                       attributes)))
        (setq current-node (widget-convert 'tree-widget 
                                           :tag (symbol-to-string (car xml))
                                           :args (append (if children 
                                                             (mapcar (lambda (node)
                                                                       (xml-to-tree-widget node))
                                                                     children)
                                                           nil)
                                                         attrib-widgets)))
        current-node ) ) ) ) )
 
(xml-to-tree-widget (car root))
 
(xml-to-tree-widget (car root-3))
 
(xml-to-tree-widget "text")
 
(defun test-tree-widget ()
  (interactive)
  (with-current-buffer (get-buffer-create "*tree-widget-test*")
    (erase-buffer)
    (setq-local my-tree-widget (widget-create (xml-to-tree-widget (car root-4))))
    (switch-to-buffer (current-buffer))))
 
;; This one will show the tree-widget in an empty buffer.
(test-tree-widget)

It’s not yet a piece of code that can be (use-package)ed or even (require)d 🙂 I entered the code in emacs and then „C-x C-e“ where necessary. When the initial xml data contains spaces (e.g. between a closing and the next opening tag) the resulting „tree“ contains empty lines, too.

An Emacs Gem is one of the many little tools/functions/modes that Emacs ships with and that turned out to be ‚extremely usefull‘ in a specific situation.

Introduction

If you ever want to compare two buffers line by line and are too lazy to fire up ediff or don’t use ediff at all you might end up with a google search for „Emacs scroll windows simultaniously“. The top results will then inform you that Emacs brings a solution for this task: scroll-all-mode.

scroll-all-mode

Scroll-all-mode does not need lots of explanation and if I am not mistaken the official Emacs Manual dedicates a single line of documentation (which in fact suffices):

Scroll All mode (M-x scroll-all-mode) is a global minor mode that causes scrolling commands and point motion commands to apply to every single window.

Every single window in the selected frame one might add – but that’s it. For a quick comparison it’s definetly a great tool and it comes with Emacs. No need for installation (it’s not a package). No need for a command-window (it’s not ediff).

Neotree is a package for emacs (available for example on elpa) that displays the directory tree in a themeable tree-buffer. It looks nice but I was looking for a feature that I was missing. A window configuration I frequently use looks like this:

+-------+------------------+
|A      |B                 |  A - neotree
|       |                  |  B - some file
|       |                  |
|       |                  |
|       |                  |
+-------+------------------+

Now I am expecting that when I change the buffer in window B I have neotree in window A also show the buffers file. So I rolled up my sleeves and entered following lines of Emacs Lisp into my init.el:

  (defun mp:neotree-updater ()
    "Hook run on buffer list update."
    (interactive)
    (when (eq 2 (length (window-list)))
      (let* ((wnd-0 (nth 0 (window-list)))
             (wnd-1 (nth 1 (window-list)))
             (buf-0 (window-buffer wnd-0))
             (buf-1 (window-buffer wnd-1))
             (neo-buf nil)
             (other-buf nil)
             (filename nil))
        (when (or (eq buf-0 neo-global--buffer)
                  (eq buf-1 neo-global--buffer))
          (progn
            (if (eq buf-0 neo-global--buffer)
                (setq neo-buf buf-0
                      other-buf buf-0)
              (setq neo-buf buf-1
                    other-buf buf-0))
            (setq filename (buffer-file-name other-buf))
            (when filename
            (progn
              (when (file-exists-p filename)
                (message (concat "New filename " filename))
                (setq mp:neotree-go-to-dir filename)))))))))
 
  (add-hook 'buffer-list-update-hook 'mp:neotree-updater)
 
  (defun mp:neotree ()
    (interactive)
    (if mp:neotree-go-to-dir
        (progn
          (neotree-find mp:neotree-go-to-dir)
          (setq mp:neotree-go-to-dir nil))
      (neotree)))

Not perfect, but this way I can bind mp:neotree to „C-c n“ and have neotree jump to the current file when I hit „C-c n“. Since the mp:neotree-updater function is called in buffer-list-update-hook I was running into several recursions until I realized I can set buffer-list-update-hook temporarily to nil and so came up with this function:

(defun mp:neotree-updater ()
    (when (eq 2 (length (window-list)))
      (let* ((wnd-0 (nth 0 (window-list)))
             (wnd-1 (nth 1 (window-list)))
             (buf-0 (window-buffer wnd-0))
             (buf-1 (window-buffer wnd-1))
             (neo-buf nil)
             (other-buf nil)
             (neo-wnd nil)
             (other-wnd nil)
             (filename nil)
             (neo-buffer (get-buffer " *NeoTree*")))
        (when (and neo-buffer
                   (or (eq buf-0 neo-buffer)
                       (eq buf-1 neo-buffer)))
          (progn
            (if (eq buf-0 neo-buffer)
                (setq neo-buf buf-0
                      other-buf buf-1
                      neo-wnd wnd-0
                      other-wnd wnd-1)
              (setq neo-buf buf-1
                    other-buf buf-0
                    neo-wnd wnd-1
                    other-wnd wnd-0))
            (when (not (eq wnd-0 neo-wnd))
              (progn
                (setq filename (buffer-file-name other-buf))
                (when (and filename
                           (file-exists-p filename))
                  (progn
                    (let ((buffer-list-update-hook nil))
                      (neotree-find filename)
                      (select-window other-wnd)))))))))))

I have to take care for the case when I actually want to „C-x o“ into the neotree window, otherwise point will always jump out of the window with (select-window other-wnd).

Writing Java sourcecode in Emacs is a rather hard task. Emacs does not usually support the developer with lots of context awareness (friendly put…). What does the unsatisfied developer do when he is in need for functionality? He codes his own solution! So I have just started work on „Emacs Java Coding Extension (version 0.0.1)“. The project is admittedly in a very early phase. But there is an ambitious roadmap and some lines of code already available. Fresh from the scratch buffer where I tried it out:

(defvar mp:ac-classpath-cache nil)
 
(defun mp:ac-classpath-init ()
  (setq mp:ac-classpath-cache (mp:read-classes-from-jar)))
 
(defvar ac-source-classpath
  '((prefix . "^import \\(.*\\)")
    (init . mp:ac-classpath-init)
    (candidates . mp:ac-classpath-cache)))
 
(defun mp:read-classes-from-jar ()
  (with-temp-buffer
    (call-process "/usr/bin/unzip" nil t nil "-l" "/home/map/opt/jdk1.8.0_101/jre/lib/rt.jar")
    (goto-char (point-min))
    (let ((end 0)
          (result '())
          (classname ""))
      (while (search-forward ".class" nil t nil)
        (end-of-line)
        (setq end (point))
        (beginning-of-line)
        (goto-char (+ (point) 30))
        (setq classname (substring 
                         (replace-regexp-in-string "/" "."
                                                   (buffer-substring-no-properties (point) end))
                         0 -6))
        (setq result (cons classname result))
        (forward-line 1)
        (beginning-of-line))
      result)))

Put together correctly the code supplies a auto-complete source that knows about classes from the java rt.jar file (or any other jar file, or with some modifications several jar files).