Personal emacs config
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.

113 lines
3.8 KiB

  1. ;;; shift-number.el --- Increase/decrease the number at point
  2. ;; Copyright © 2016 Alex Kost
  3. ;; Author: Alex Kost <alezost@gmail.com>
  4. ;; Created: 12 Apr 2016
  5. ;; Version: 0.1
  6. ;; Package-Version: 0.1
  7. ;; Package-Commit: ba3c1f2e6b01bf14aa1433c2a49098af1c025f7c
  8. ;; URL: https://github.com/alezost/shift-number.el
  9. ;; Keywords: convenience
  10. ;; This program is free software; you can redistribute it and/or modify
  11. ;; it under the terms of the GNU General Public License as published by
  12. ;; the Free Software Foundation, either version 3 of the License, or
  13. ;; (at your option) any later version.
  14. ;; This program is distributed in the hope that it will be useful,
  15. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. ;; GNU General Public License for more details.
  18. ;; You should have received a copy of the GNU General Public License
  19. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. ;;; Commentary:
  21. ;; Increase or decrease the number at point with `shift-number-up' and
  22. ;; `shift-number-down' commands.
  23. ;; To install the package manually, add the following to your init file:
  24. ;;
  25. ;; (add-to-list 'load-path "/path/to/shift-number-dir")
  26. ;; (autoload 'shift-number-up "shift-number" nil t)
  27. ;; (autoload 'shift-number-down "shift-number" nil t)
  28. ;; For more verbose description and a gif demonstration, see
  29. ;; <https://github.com/alezost/shift-number.el>.
  30. ;;; Code:
  31. (defgroup shift-number nil
  32. "Increase or decrease the number at point."
  33. :group 'convenience)
  34. (defcustom shift-number-regexp
  35. (rx (group (one-or-more num)))
  36. "Regexp for `shift-number' function.
  37. The first parenthesized expression must match the number."
  38. :type 'regexp
  39. :group 'shift-number)
  40. (defcustom shift-number-display-message nil
  41. "If non-nil, display a message after shifting the current number."
  42. :type 'boolean
  43. :group 'shift-number)
  44. (defun shift-number-in-regexp-p (regexp)
  45. "Return non-nil, if point is inside REGEXP on the current line."
  46. ;; The code originates from `org-at-regexp-p'.
  47. (save-excursion
  48. (let ((pos (point))
  49. (end (line-end-position))
  50. found exit)
  51. (beginning-of-line)
  52. (while (and (not (or exit found))
  53. (re-search-forward regexp end t))
  54. (cond
  55. ((> (match-beginning 0) pos)
  56. (setq exit t))
  57. ((>= (match-end 0) pos)
  58. (setq found t))))
  59. found)))
  60. (defun shift-number (n)
  61. "Change the number at point by N.
  62. If there is no number at point, search forward till the end of
  63. the current line and change it."
  64. ;; The whole number is removed and a new number is inserted in its
  65. ;; place, so `save-excursion' is not used, as it will put the point at
  66. ;; the beginning of the number. Instead, the point is saved and
  67. ;; restored later.
  68. (let ((old-pos (point)))
  69. (or (shift-number-in-regexp-p shift-number-regexp)
  70. (re-search-forward shift-number-regexp (line-end-position) t)
  71. (error "No number on the current line"))
  72. (let* ((beg (match-beginning 1))
  73. (end (match-end 1))
  74. (old-num (string-to-number
  75. (buffer-substring-no-properties beg end)))
  76. (new-num (+ old-num n)))
  77. (delete-region beg end)
  78. (insert (number-to-string new-num))
  79. (goto-char old-pos)
  80. (when shift-number-display-message
  81. (message "Number %d has been changed to number %d."
  82. old-num new-num)))))
  83. ;;;###autoload
  84. (defun shift-number-up (&optional arg)
  85. "Increase the number at point (or on the current line) by ARG."
  86. (interactive "p")
  87. (shift-number arg))
  88. ;;;###autoload
  89. (defun shift-number-down (&optional arg)
  90. "Decrease the number at point (or on the current line) by ARG."
  91. (interactive "p")
  92. (shift-number (- arg)))
  93. (provide 'shift-number)
  94. ;;; shift-number.el ends here