2022-06-20 Copying the current location

Continuing the trend of playing around with copying stuff from Emacs to the system clipboard, today I’d like to talk about a command I wrote a few days ago. When I chat with a team member about some piece of code we are working on, I often need to tell them where I’m looking. This means the file name and usually also the current line number. While it is very easy to get the current line number (although be careful with narrowing – the number displayed in the modeline only counts the lines in the visible portion of the buffer! Give line-number-at-pos a non-nil second argument to get the “real” line number), the filename is slightly tricky. On the one hand, just the filename (without the path) is sometimes not enough – it sometimes happens that a project contains two distinct files with the same name, just in different directories. (This is probably a bad practice and we usually avoid it, but it happens sometimes.) On the other hand, I don’t want to copy the full path (even if it is easy to get in Dired with dired-copy-filename-as-kill, bound to w by default, with a zero prefix argument) – no need to tell people the directory structure of my drive, down to /home/mbork/. What I need is the filename relative to the directory containing the .git subdirectory (which means the root directory of the current project).

Emacs Lisp to the rescue – it turns out that it took me less than 15 minutes to come up with this.

(defun current-location ()
  "Show the current location and put it into the kill ring.
Use the filename relative to the current VC root directory."
  (interactive)
  (let* ((file-name (file-relative-name buffer-file-name (vc-root-dir)))
	 (line-number (line-number-at-pos nil t))
	 (location (format "%s:%s" file-name line-number)))
    (kill-new location)
    (message location)))

It should be pretty self-explanatory, and if you do not know any of the functions involved, go check its docstring. Yet another testimony to Emacs’ flexibility – and easiness of extending it according to your needs.

(Just to remind you: if you want to learn Emacs Lisp and be able to write such little functions for yourself, best start with the late Robert J. Chassell’s excellent – and free! – An introduction to programming in Emacs Lisp. And if you want to learn more, either dive straight into GNU Emacs Lisp Reference Manual, or cough up a few bucks for my book, Hacking your way around in Emacs. As a teaser, let me just briefly mention that I will upload a small update of that book pretty soon, i.e., within the next few weeks!)

CategoryEnglish, CategoryBlog, CategoryEmacs