Skip to content

Instantly share code, notes, and snippets.

@abo-abo
Created November 7, 2013 21:55
Show Gist options
  • Save abo-abo/7362506 to your computer and use it in GitHub Desktop.
Save abo-abo/7362506 to your computer and use it in GitHub Desktop.
A small arguments alignment hack for C/C++-like languages.
(defun extract-argument-positions (str)
"Given a single line C/C++ string, return list of arguments in form:
\(start-position end-position string\) for each argument"
(let ((args (list))
(pos 0))
(while (string-match "\\(?: [^ (\n]+\\)\\(?:,[\n ]\\|)\\|,$\\|;$\\|[ ]+=[ ]+\\)" str pos)
(push (list (match-beginning 0)
(match-end 0)
(substring (match-string-no-properties 0 str) 0 -1))
args)
(setq pos (match-end 0)))
(reverse args)))
(defun selected-lines ()
"Returns list of pairs (beginning-of-line-position . string)
for each line selected"
(interactive)
(when (region-active-p)
(let ((start (save-excursion (goto-char (region-beginning))
(line-beginning-position)))
(end (save-excursion (goto-char (region-end)) (line-end-position)))
(lines nil)
tstr)
(goto-char start)
(while (< (point) end)
(setq tstr (buffer-substring-no-properties
(point)
(line-end-position)))
(unless (string= tstr "")
(push (cons (point) tstr)
lines))
(beginning-of-line 2))
lines)))
(defun c-align-function-arguments ()
"Aligns selected C/C++ arguments list with spaces"
(interactive)
(let ((lines (selected-lines)))
(when (> (length lines) 1)
(let* ((pts-begin (mapcar #'car lines))
(pts-arg-rel (mapcar (lambda (x)
(caar
(extract-argument-positions
(cdr x))))
lines))
(pt-arg-max (apply #'max pts-arg-rel)))
(cl-mapcar (lambda (b x)
(goto-char (+ b x))
(insert (make-string (- pt-arg-max x) ? )))
pts-begin
pts-arg-rel)))))
(defmacro define-key-regionp (keymap key command)
"In KEYMAP, define KEY as DEF.
DEF is called only when mark is active.
Otherwise, KEY is inserted."
`(define-key ,keymap ,key (lambda()(interactive)
(if (region-active-p)
(call-interactively ,command)
(if (eq major-mode 'org-mode)
(org-self-insert-command 1)
(self-insert-command 1))))))
(setq-default indent-tabs-mode nil)
(add-hook
'c-mode-common-hook
(lambda ()
(define-key-regionp c-mode-base-map "3" 'c-align-function-arguments)))
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment