Created
February 9, 2015 18:50
-
-
Save jordonbiondo/c03362772e024c5b5612 to your computer and use it in GitHub Desktop.
Magit, macro to define commands that change an unstaged hunk, with example.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| (defun jorbi-magit/-line-region-of-section-at-point () | |
| "If point is in a hunk return a list of info about the hunk. | |
| The info is like (expanded-file-name starting-line number-of-lines-show)" | |
| (let* ((section (magit-current-section)) | |
| (context-type (magit-section-context-type section))) | |
| (when (and (member 'hunk context-type)) | |
| (let* ((info | |
| (mapcar 'string-to-number | |
| (split-string | |
| (second (split-string | |
| (magit-section-info | |
| (magit-current-section)) | |
| "[ @]" t)) | |
| ","))) | |
| (start-line (car info)) | |
| (line-count (or (and (cdr info) (cadr info)) 1))) | |
| (let ((parent (magit-section-parent section))) | |
| (while (and parent | |
| (not (equal (magit-section-type parent) | |
| 'diff))) | |
| (setq magit-section-parent parent)) | |
| (list (expand-file-name (magit-section-info parent)) | |
| start-line | |
| line-count)))))) | |
| ;; use this macro to define unstaged hunk actions | |
| (defmacro define-magit-unstaged-hunk-action (name args &optional docstring &rest body) | |
| "NAME will be command that executes BODY in a way that has access to the beginning | |
| and end of the region shown by the unstaged magit hunk at point. | |
| The function will automatically open the hunks file, evaluated the body, and then | |
| save the file and refresh the magit status buffer. | |
| Args needs to be in the form (BEG END) where BEG and END are symbols that will be bound | |
| to the regions beginning and end respectively. | |
| In this example, the function `cleanup-this-hunk' is defined as a function | |
| that deletes the trailing whitespace in the current unstaged magit hunk: | |
| (define-magit-unstaged-hunk-action cleanup-this-hunk (beg end) | |
| \"Delete trailing whitespace in the current unstaged magit hunk.\" | |
| (delete-trailing-whitespace beg end)) | |
| \(fn NAME (BEG END) &optional DOCSTRING &rest BODY)" | |
| (declare (indent-defun) (doc-string 3)) | |
| (assert (and (= (length args) 2) | |
| (symbolp (car args)) | |
| (symbolp (cadr args))) nil "Invalid args format to `define-magit-unstaged-hunk-action', see doc.") | |
| (let ((docstring (if (car-safe docstring) "" docstring)) | |
| (body (append (and (car-safe docstring) (list docstring)) body)) | |
| (file-sym (make-symbol "a")) | |
| (start-line-sym (make-symbol "b")) | |
| (total-lines-sym (make-symbol "c")) | |
| (area-sym (make-symbol "d"))) | |
| `(defun ,name () | |
| ,docstring | |
| (interactive) | |
| (let ((,area-sym (jorbi-magit/-line-region-of-section-at-point))) | |
| (if (and ,area-sym (member 'unstaged (magit-section-context-type (magit-current-section)))) | |
| (destructuring-bind (,file-sym ,start-line-sym ,total-lines-sym) ,area-sym | |
| (save-some-buffers) | |
| (with-current-buffer (find-file-noselect ,file-sym) | |
| (save-excursion | |
| (let ((,(car args) (progn (goto-char (point-min)) | |
| (forward-line (1- ,start-line-sym)) | |
| (point-at-bol))) | |
| (,(cadr args) (progn (forward-line (1- ,total-lines-sym)) | |
| (point-at-eol)))) | |
| ,@body)) | |
| (save-buffer)) | |
| (magit-refresh)) | |
| (message "Cannot perform. Point is not on an unstaged hunk.")))))) | |
| ;; this defines a function: jorbi-magit/cleanup-this-hunk, when in a status buffer | |
| ;; you can put the point on an unstaged hunk and run this function and it will | |
| ;; delete the trailing whitespace in the file's region shown by the hunk, | |
| ;; save the changes and refresh that status buffer | |
| (define-magit-unstaged-hunk-action jorbi-magit/cleanup-this-hunk (beg end) | |
| "Delete trailing whitespace in the current unstaged magit hunk." | |
| (delete-trailing-whitespace beg end)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment