Back in the day, when I was a team lead, I did more than my fair share of code reviews. What made the process relatively painless (at least for me, the reviewer) was a handy elisp function that made citing code from within emacs a breeze. I'd mark a region, hit a keystroke, and I was ready to paste the discussion-worthy code into an e-mail message. Having this function was like having a spell checker in your code editor; a seemingly superfluous feature, until you realize that you're utterly dependent on it.
Unfortunately, somewhere over the years I've lost this magic bit emacs code. Surely there's a whole package dedicated to citing code, but for the life of me, I couldn't find it. And so when I needed to review someone's code yesterday (something I apparently haven't done in years), I rewrote this function.
Now, I can set a region in emacs and type M-x code-review-region and poof! the code is annotated with the file name I grabbed it from, the line number, and a bit of ASCII art to show the item as being quoted. For example, I just ran this function on some utility PHP code:
+---[web/shared/lib/util.php:25] | function dev_env() { | return strtolower(g($_SERVER, 'SERVER_NAME')) == 'localhost'; | } +---
And here's the elisp function. Happy code reviewing!
(defun code-review-region (beg end) (interactive "r") (let* ((text (chomp (buffer-substring-no-properties beg end))) (line-number (line-number-at-pos)) (file (buffer-file-name)) (path (replace-regexp-in-string "^.*branches/" "" (replace-regexp-in-string "^.*trunk/" "" file)))) (with-temp-buffer (insert text) (goto-char (point-min)) (while (re-search-forward "^" nil t) (replace-match "| " nil nil)) (goto-char (point-min)) (insert (format "+---[%s:%s]\n" path line-number)) (goto-char (point-max)) (insert "\n+---\n") (kill-region (point-min) (point-max)))))
If you have boxquote.el installed, you could use box-quote-region and boxquote-title to make the box around the code you're quoting :-)
ReplyDeleteAhhhh yes, boxquote.el! That's almost certainly the original package that inspired me, but I couldn't recall. Thanks!
ReplyDeleteIf you use `region-binding-mode`, it would go perfect with such a function. You simply select a region and and hit a key binding to execute this command. I have a similar function inspired from a Stackoverflow answer ( https://github.com/kaushalmodi/.emacs.d/tree/3c01a24d5c2e85d3cb00e3543b304849e9918e67/setup-files/setup-editing.el#L224 ). Using `region- binding-mode`, I simply select a region of code I want to share and hit `c` or `C-u c` to copy the code with non-unicode or unicode characters to form the code border.
ReplyDeleteWhere is your chomp function coming from?
ReplyDeleteD'oh. Here you go:
ReplyDelete(defun chomp (str)
"Chomp leading and tailing whitespace from STR."
(replace-regexp-in-string (rx (or (: bos (* (any " \t\n")))
(: (* (any " \t\n")) eos)))
""
str))
Nice! Very similar to how I do it, but I often stay in Emacs and do some more reviewing and commenting there, so I setup a special buffer for that. I don't do the fancy box thing, but perhaps I should add it :)
ReplyDeleteHere is the main part of my code review review stuff:
https://gist.github.com/mathiasdahl/56b9ae8ce0f39c43f209
Mathias - thanks for sharing!
ReplyDelete