Content AND Presentation

(Note to English-speaking readers: the links entitled Komentarze na tej stronie lead to comment pages.)

2017-02-26 other-window-or-switch-buffer

Some time ago I decided to bind f6 to other-window. I lived happily with that binding, but then something struck me. My f6 key was completely useless when I had only one window in the current frame. What a waste! So, I decided to code this.

(defun other-window-or-switch-buffer ()
  "Call `other-window' if more than one window is visible, switch
to next buffer otherwise."
  (if (one-window-p)
	  (switch-to-buffer nil)
	(other-window 1)))

(global-set-key (kbd "<f6>") #'other-window-or-switch-buffer)

Now f6 cycles through my most recently used two buffers if I have only one window. (This partially supersedes my other command described here, so maybe I’ll bind C-z b without the prefix argument to something else – we’ll see.)

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2017-02-18 Using isearch-string on exit from isearch

Recently, I wanted my function, which asks the user for some string, use the isearch term as the default. That’s easy – the variable isearch-string holds the term searched (note that it may be a plain string or a regex!). The problem was, I wanted that to be the default only when I invoked my command from isearch (sort of what M-% does when called from within isearch). The way M-% does its magic when invoked during isearch is simple: in isearch-mode-map, that key is bound to isearch-query-replace and not the usual query-replace. I didn’t want anything like that, though: I wanted my command to be callable via M-x.

I thought about checking whether last-command was isearch-forward or isearch-backward and if yes, using isearch-string. The problem is, last-command is usually something else, like isearch-printing-char or anything else from isearch-mode-map.

I know about two ways of overcoming that. The hackery way is to apply this check: (string-match "^isearch-" (symbol-name last-command)). Slightly risky, but works due to the way Emacs functions are traditionally named.

Probably the cleaner way is to use isearch-mode-end-hook, to which I can add a function setting last-command to something like isearch:

(add-hook 'isearch-mode-end-hook (lambda () (setq last-command 'isearch)))

(Such command does not exist, but we can set last-command to whatever symbol we want!) Then we can check for that exact symbol in our command. The expression below evaluates to the input given by the user, which is equal to the last isearch term when isearch was the thing the user was doing when evaluating and s?he just pressed RET.

(let ((default (when (eq last-command 'isearch)
  (read-string (if default
		   (format "Your input [%s]: " default)
		 "Your input: ")
		   nil nil default))

I’m not sure whether this won’t break anything, but I don’t think so. Anyway, I’m starting using it; if anything breaks, I’ll update this post.

Thanks to Michael Heerdegen for his suggestion on the help-gnu-emacs list.

CategoryEnglish, CategoryBlog, CategoryEmacs

Comments on this page

2017-02-13 Sorting Org entries by most recent activity

As I mentioned a lot of times, I use Org-mode – and in particular, clocking – very heavily. Sometimes I have this Org entry with a lot of (clocked) subentries, and I’d like to see which ones of them I haven’t touched in a long time – and which ones I’ve been working recently.

I wanted to ask on the Org mailing list whether it was possible, but – taught by experience – I decided to check in the manual first. Unsurprisingly, the feature is (almost) already there. It’s called org-sort and is bound to C-c ^. You can invoke it on the “parent” entry and then choose the sorting order (it works differently on lists and tables, though). The one interesting here is T, which means “time”. The sorting key is the first active timestamp in the entry, and in case there are no active timestamps, the first inactive one. Since I usually don’t have active timestamps on things I clock, this is enough for me. In case this is a problem, org-sort also accepts an f (for function) and then asks for any Elisp function acting as a predicate; writing one treating active and inactive timestamps in the same way would most probably be very easy.

Interestingly enough, there is almost no need to write such a function. Deep in the Org-mode guts, in org-clock.el, there lies hidden a function called org-clock-get-last-clock-out-time. It’s almost never really used, but it does what we want. The only problem is that it returns a time value, i.e. not sth you can feed into org-sort. But this is easy to remedy:

(defun org-clock-get-last-clock-out-unix-time ()
  "Return the last clock-out time for the current sub-tree as
a Unix time."
  (time-to-seconds (org-clock-get-last-clock-out-time)))

Note also that lowercase letters in org-sort correspond to ascending order and uppercase ones to descending ones. It might also be interesting to know that org-sort is really kind of a “dispatcher”, calling org-table-sort-lines, org-sort-list or just org-sort-entries (depending on what the point is at).

CategoryEnglish, CategoryBlog, CategoryEmacs, CategoryOrgMode

Comments on this page


(Więcej means More in Polish; click it to see older entries.)

CategoryEnglish, CategoryBlog