Klimi's new dotfiles with stow.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

106 lines
3.9 KiB

5 years ago
  1. ;;; yapfify.el --- (automatically) format python buffers using YAPF.
  2. ;; Copyright (C) 2016 Joris Engbers
  3. ;; Author: Joris Engbers <info@jorisengbers.nl>
  4. ;; Homepage: https://github.com/JorisE/yapfify
  5. ;; Version: 0.0.6
  6. ;; Package-Version: 20180830.733
  7. ;; Package-Requires: ()
  8. ;; This file is free software; you can redistribute it and/or modify
  9. ;; it under the terms of the GNU General Public License as published
  10. ;; by the Free Software Foundation; either version 3, or (at your
  11. ;; option) any later version.
  12. ;;
  13. ;; This file is distributed in the hope that it will be useful,
  14. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. ;; GNU General Public License for more details.
  17. ;;
  18. ;; For a full copy of the GNU General Public License
  19. ;; see <http://www.gnu.org/licenses/>.
  20. ;;; Commentary:
  21. ;;
  22. ;; Yapfify uses yapf to format a Python buffer. It can be called explicitly on a
  23. ;; certain buffer, but more conveniently, a minor-mode 'yapf-mode' is provided
  24. ;; that turns on automatically running YAPF on a buffer before saving.
  25. ;;
  26. ;; Installation:
  27. ;;
  28. ;; Add yapfify.el to your load-path.
  29. ;;
  30. ;; To automatically format all Python buffers before saving, add the function
  31. ;; yapf-mode to python-mode-hook:
  32. ;;
  33. ;; (add-hook 'python-mode-hook 'yapf-mode)
  34. ;;
  35. ;;; Code:
  36. (require 'cl)
  37. (defun yapfify-call-bin (input-buffer output-buffer start-line end-line)
  38. "Call process yapf on INPUT-BUFFER saving the output to OUTPUT-BUFFER.
  39. Return the exit code. START-LINE and END-LINE specify region to
  40. format."
  41. (with-current-buffer input-buffer
  42. (call-process-region (point-min) (point-max) "yapf" nil output-buffer nil "-l" (concat (number-to-string start-line) "-" (number-to-string end-line)))))
  43. (defun get-buffer-string (buffer)
  44. "Return the contents of BUFFER."
  45. (with-current-buffer buffer
  46. (buffer-string)))
  47. ;;;###autoload
  48. (defun yapfify-region (beginning end)
  49. "Try to yapfify the current region.
  50. If yapf exits with an error, the output will be shown in a help-window."
  51. (interactive "r")
  52. (let* ((original-buffer (current-buffer))
  53. (original-point (point)) ; Because we are replacing text, save-excursion does not always work.
  54. (buffer-windows (get-buffer-window-list original-buffer nil t))
  55. (original-window-pos (mapcar 'window-start buffer-windows))
  56. (start-line (line-number-at-pos beginning))
  57. (end-line (line-number-at-pos (if (or (= (char-before end) 10)
  58. (= (char-before end) 13))
  59. (- end 1)
  60. end)))
  61. (tmpbuf (generate-new-buffer "*yapfify*"))
  62. (exit-code (yapfify-call-bin original-buffer tmpbuf start-line end-line)))
  63. (deactivate-mark)
  64. ;; There are three exit-codes defined for YAPF:
  65. ;; 0: Exit with success (change or no change on yapf >=0.11)
  66. ;; 1: Exit with error
  67. ;; 2: Exit with success and change (Backward compatibility)
  68. ;; anything else would be very unexpected.
  69. (cond ((or (eq exit-code 0) (eq exit-code 2))
  70. (with-current-buffer tmpbuf
  71. (copy-to-buffer original-buffer (point-min) (point-max))))
  72. ((eq exit-code 1)
  73. (error "Yapf failed, see %s buffer for details" (buffer-name tmpbuf))))
  74. ;; Clean up tmpbuf
  75. (kill-buffer tmpbuf)
  76. ;; restore window to similar state
  77. (goto-char original-point)
  78. (mapcar* 'set-window-start buffer-windows original-window-pos)))
  79. ;;;###autoload
  80. (defun yapfify-buffer ()
  81. "Yapfify whole buffer."
  82. (interactive)
  83. (yapfify-region (point-min) (point-max)))
  84. ;;;###autoload
  85. (define-minor-mode yapf-mode
  86. "Automatically run YAPF before saving."
  87. :lighter " YAPF"
  88. (if yapf-mode
  89. (add-hook 'before-save-hook 'yapfify-buffer nil t)
  90. (remove-hook 'before-save-hook 'yapfify-buffer t)))
  91. (provide 'yapfify)
  92. ;;; yapfify.el ends here