04 Apr 2016
I've been getting more and more organized in tracking my tasks and
time with Org-mode. Still using the usual suspects, of course: GTD and
Pomodoro, I'm just getting more diligent with them than in the
previous years.
So today I wanted to prettify the good old
org-agenda-view-mode-dispatch
, which is bound to v in
org-agenda-mode
. Currently, it's just a boring static message
and
read-char
combination. Why not do it with a
hydra instead?
Here's the current full code, that uses the newly extended doc syntax:
(define-key org-agenda-mode-map
"v" 'hydra-org-agenda-view/body)
(defun org-agenda-cts ()
(let ((args (get-text-property
(min (1- (point-max)) (point))
'org-last-args)))
(nth 2 args)))
(defhydra hydra-org-agenda-view (:hint none)
"
_d_: ?d? day _g_: time grid=?g? _a_: arch-trees
_w_: ?w? week _[_: inactive _A_: arch-files
_t_: ?t? fortnight _f_: follow=?f? _r_: report=?r?
_m_: ?m? month _e_: entry =?e? _D_: diary=?D?
_y_: ?y? year _q_: quit _L__l__c_: ?l?"
("SPC" org-agenda-reset-view)
("d" org-agenda-day-view
(if (eq 'day (org-agenda-cts))
"[x]" "[ ]"))
("w" org-agenda-week-view
(if (eq 'week (org-agenda-cts))
"[x]" "[ ]"))
("t" org-agenda-fortnight-view
(if (eq 'fortnight (org-agenda-cts))
"[x]" "[ ]"))
("m" org-agenda-month-view
(if (eq 'month (org-agenda-cts)) "[x]" "[ ]"))
("y" org-agenda-year-view
(if (eq 'year (org-agenda-cts)) "[x]" "[ ]"))
("l" org-agenda-log-mode
(format "% -3S" org-agenda-show-log))
("L" (org-agenda-log-mode '(4)))
("c" (org-agenda-log-mode 'clockcheck))
("f" org-agenda-follow-mode
(format "% -3S" org-agenda-follow-mode))
("a" org-agenda-archives-mode)
("A" (org-agenda-archives-mode 'files))
("r" org-agenda-clockreport-mode
(format "% -3S" org-agenda-clockreport-mode))
("e" org-agenda-entry-text-mode
(format "% -3S" org-agenda-entry-text-mode))
("g" org-agenda-toggle-time-grid
(format "% -3S" org-agenda-use-time-grid))
("D" org-agenda-toggle-diary
(format "% -3S" org-agenda-include-diary))
("!" org-agenda-toggle-deadlines)
("["
(let ((org-agenda-include-inactive-timestamps t))
(org-agenda-check-type t 'timeline 'agenda)
(org-agenda-redo)))
("q" (message "Abort") :exit t))
And here's how it looks like in action, I simply pressed v while in the agenda:
Since many functions that org-agenda-view-mode-dispatch
calls are
toggles, it makes sense for hydra-org-agenda-view
to display the
status of these toggles.
And it's actually convenient to toggle a whole lot of things at once,
and the default red hydra keys really come in handy here.
Quick explanation of the syntax
Each head of a hydra looks like:
(key cmd &optional doc &rest plist)
The fairly new bit that I'm using here is the ability to use a sexp
instead of a plain string in the doc
part. This sexp will be
evaluated each time the doc is re-displayed. This means that it can
represent a changing variable, for instance the state of a minor mode
or a variable.
And here's the best part: the doc of each head can be quoted in the
hydra's docstring by using the corresponding key, e.g. ?g?
. This
allows to have very complex docstrings while keeping them easily
aligned in a tabular format.
Here is only the hydra's docstring, copied from the above code:
_d_: ?d? day _g_: time grid=?g? _a_: arch-trees
_w_: ?w? week _[_: inactive _A_: arch-files
_t_: ?t? fortnight _f_: follow=?f? _r_: report=?r?
_m_: ?m? month _e_: entry =?e? _D_: diary=?D?
_y_: ?y? year _q_: quit _L__l__c_: ?l?
Doesn't that look simple?
16 Mar 2016
I'd like to highlight the new command counsel-linux-app
that I
recently added to the counsel
package:
This command looks through your /usr/share/applications/*.desktop
and offers to launch them, just like the launcher that you normally
get when you press the super key. My current system is Ubuntu, and the
launcher here is really horrible, so I'm glad to have a much faster
and reliable replacement.
Here's another screenshot, I open the keyboard settings quite often:
24 Feb 2016
Here's a code snippet I've found long ago on the internet (the source
seems to be no longer accessible), that has proven valuable time and
time again:
;;;###autoload
(defun ora-dired-rsync (dest)
(interactive
(list
(expand-file-name
(read-file-name
"Rsync to:"
(dired-dwim-target-directory)))))
;; store all selected files into "files" list
(let ((files (dired-get-marked-files
nil current-prefix-arg))
;; the rsync command
(tmtxt/rsync-command
"rsync -arvz --progress "))
;; add all selected file names as arguments
;; to the rsync command
(dolist (file files)
(setq tmtxt/rsync-command
(concat tmtxt/rsync-command
(shell-quote-argument file)
" ")))
;; append the destination
(setq tmtxt/rsync-command
(concat tmtxt/rsync-command
(shell-quote-argument dest)))
;; run the async shell command
(async-shell-command tmtxt/rsync-command "*rsync*")
;; finally, switch to that window
(other-window 1)))
(define-key dired-mode-map "Y" 'ora-dired-rsync)
Lets you copy huge files and directories without Emacs freezing up and
with convenient progress bar updates. That is all.
Thanks to tmtxt
, the mysterious hacker-person from whom the snippet
likely originated . Good luck with getting your blog back up.
15 Feb 2016
Many experienced Emacs users are aware of ffap
command:
Find FILENAME, guessing a default from text around point.
If ffap-url-regexp
is not nil, the FILENAME may also be an URL.
It's a great way to open an link, if you plan things in advance. But
for me it was usually C-x C-f (annoyed grunt) C-g M-x
ffap RET.
Now, thanks to counsel-find-file,
it's C-x C-f (anticipated annoyance, followed by a sigh of
relief) M-n.
With Ivy completion, M-n calls ivy-next-history-element
,
which tries to
predict the history element
in case you've reached history's edge. The prediction usually simply
inserts thing-at-point into the minibuffer. My favorite applications
of this are:
- C-s M-n -
swiper
thing-at-point, to get the occurrences
of the current symbol in the current file.
- C-c j M-n -
counsel-git-grep
thing-at-point, to get the
mentions within the current project.
- C-c g M-n -
counsel-git
thing-at-point to open a file
to which the current symbol links.
One thing I've recently added is the \_<...\_>
wrapper for when
major-mode
derives from prog-mode
. Since the \_<
regex matches
the symbol start, and \_>
matches the symbol end, there's no chance
of getting partial matches. You can call undo
or press
M-n again in case the symbol bounds aren't useful.
Finally, C-x C-f M-n can be used to open URLs. Recently,
I've added functionality to counsel-find-file
that allows me to also
visit Github issues by simply pointing at the plain issue number,
e.g. #123
in either a version-controlled file or in a Magit buffer.
The command will query:
$ git remote get-url origin
and fill in all the details. So I no longer bother with
bug-reference-url-format
and bug-reference-mode
- now it's all
automatic.
It's also possible to make it work for places other than Github, for
instance this code (already included in
counsel) makes it work for the Emacs Git
repository:
(defun counsel-emacs-url-p ()
"Return a Debbugs issue URL at point."
(when (and (looking-at "#[0-9]+")
(or
(eq (vc-backend (buffer-file-name)) 'Git)
(memq major-mode '(magit-commit-mode))))
(let ((url (match-string-no-properties 0))
(origin (shell-command-to-string
"git remote get-url origin")))
(when (string-match "git.sv.gnu.org:/srv/git/emacs.git"
origin)
(format "http://debbugs.gnu.org/cgi/bugreport.cgi?bug=%s"
(substring url 1))))))
(add-to-list 'ivy-ffap-url-functions 'counsel-emacs-url-p)
23 Jan 2016
This release consists of 77 commits done over the course of the last 7
months by me and many
contributors. Similarly
to the 0.3.0
release, the release notes are in
Changelog.org.
You can read them either at
github or
inside Emacs.
Big thanks to all contributors.
Highlights
A lot of new code is just straight upgrades, you don't need to do
anything extra to use them. Below, I'll describe the other part of the
new code, which is new commands and custom vars.
avy-goto-char-timer
This command now allows as many characters as you like, which makes it
similar to a isearch
+ avy-isearch
combination. As you type, you
get an isearch
-like highlight, then after a short delay you
automatically get the avy
selection.
Switch the action midway from goto to kill/mark/copy
This is similar to the cool feature of
ace-window that
allows you to switch the action after you get the avy prompt.
For example, suppose you have:
(global-set-key (kbd "M-t") 'avy-goto-word-1)
Here's what you can do now to a word that starts with a "w" and is
select-able with "a":
- To jump there: M-t w a.
- To copy the word instead of jumping to it: M-t w na
- To mark the word after jumping to it: M-t w ma.
- To kill the word after jumping to it: M-t w xa.
You can customize avy-dispatch-alist
to modify these actions, and
also ensure that it plays nicely with your avy-keys
, if you
customized them. By default, it works fine, since avy-keys
is '(?a
?s ?d ?f ?g ?h ?j ?k ?l)
and the keys on avy-dispatch-alist
are
'(?x ?m ?n)
.
avy-pop-mark
This command reverses avy-push-mark
which most of avy commands call.
It has its own history and works across multiple windows and frames.
I'm using it currently as an upgrade to my old (set-mark-command 4)
lambda:
(global-set-key (kbd "M-p") 'avy-pop-mark)
Here's a line to make avy-pop-mark
work also for swiper
:
(advice-add 'swiper :before 'avy-push-mark)