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.

177 lines
4.8 KiB

  1. ;;; zoutline.el --- Simple outline library. -*- lexical-binding: t -*-
  2. ;; Copyright (C) 2016 Oleh Krehel
  3. ;; Author: Oleh Krehel <ohwoeowho@gmail.com>
  4. ;; URL: https://github.com/abo-abo/zoutline
  5. ;; Package-Version: 0.2.0
  6. ;; Package-Commit: 63756846f8540b6faf89d885438186e4fe1c7d8a
  7. ;; Version: 0.2.0
  8. ;; Keywords: outline
  9. ;; This file is not part of GNU Emacs
  10. ;; This file 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, or (at your option)
  13. ;; 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. ;; For a full copy of the GNU General Public License
  19. ;; see <http://www.gnu.org/licenses/>.
  20. (require 'outline)
  21. (defun zo-up (arg)
  22. "Move ARG times up by outline."
  23. (interactive "p")
  24. (let ((i 0)
  25. out)
  26. (ignore-errors
  27. (while (<= (cl-incf i) arg)
  28. (outline-backward-same-level 1)
  29. t
  30. (setq out t)))
  31. out))
  32. (defun zo-down (arg)
  33. "Move ARG times down by outline.
  34. Return the amount of times moved.
  35. Return nil if moved 0 times."
  36. (interactive "p")
  37. (unless (bolp)
  38. (outline-back-to-heading))
  39. (let ((pt 0)
  40. (i 0)
  41. (outline-ok t))
  42. (while (and outline-ok
  43. (<= (cl-incf i) arg)
  44. (> (point) pt))
  45. (setq pt (point))
  46. (condition-case nil
  47. (outline-forward-same-level 1)
  48. (error (setq outline-ok nil))))
  49. (cl-decf i)
  50. (unless (= 0 i)
  51. i)))
  52. (defvar zo-lvl-re [nil
  53. "\n\\* "
  54. "\n\\*\\{2\\} "
  55. "\n\\*\\{3\\} "
  56. "\n\\*\\{4\\} "
  57. "\n\\*\\{5\\} "
  58. "\n\\*\\{6\\} "
  59. "\n\\*\\{7\\} "])
  60. (declare-function reveal-post-command "reveal")
  61. (defun zo-down-visible (&optional arg)
  62. "Move ARG times down by outline."
  63. (interactive "p")
  64. (setq arg (or arg 1))
  65. (let ((lvl (funcall outline-level))
  66. res)
  67. (if (= lvl 1)
  68. (setq res (re-search-forward (aref zo-lvl-re lvl) nil t arg))
  69. (let ((end (save-excursion
  70. (or (re-search-forward (aref zo-lvl-re (1- lvl)) nil t)
  71. (point-max)))))
  72. (when (setq res (re-search-forward (aref zo-lvl-re lvl) end t arg))
  73. (reveal-post-command))))
  74. (when res
  75. (beginning-of-line)
  76. (point))))
  77. (defun zo-left (arg)
  78. (outline-up-heading arg))
  79. (defun zo-right-once ()
  80. (let ((pt (point))
  81. (lvl-1 (funcall outline-level))
  82. lvl-2)
  83. (if (and (outline-next-heading)
  84. (setq lvl-2 (funcall outline-level))
  85. (> lvl-2 lvl-1))
  86. 1
  87. (goto-char pt)
  88. nil)))
  89. (defun zo-right (arg)
  90. "Try to move right ARG times.
  91. Return the actual amount of times moved.
  92. Return nil if moved 0 times."
  93. (let ((i 0))
  94. (while (and (< i arg)
  95. (zo-right-once))
  96. (cl-incf i))
  97. (unless (= i 0)
  98. i)))
  99. (defun zo-add-outline-title ()
  100. (save-excursion
  101. (outline-previous-visible-heading 1)
  102. (if (looking-at (concat outline-regexp " ?:$"))
  103. (match-string-no-properties 0)
  104. (let ((outline-comment
  105. (progn
  106. (string-match "\\(.*\\)\\(?:[\\](\\)\\|\\([\\]\\*\\+\\)" outline-regexp)
  107. (match-string-no-properties 1 outline-regexp))))
  108. (concat outline-comment (make-string (1+ (funcall outline-level)) ?*) " :")))))
  109. (defun zo-insert-outline-below ()
  110. (interactive)
  111. "Add an unnamed notebook outline at point."
  112. (cond
  113. ((and (bolp) (eolp)))
  114. ((outline-next-visible-heading 1)
  115. (insert "\n\n")
  116. (backward-char 2))
  117. (t
  118. (goto-char (point-max))
  119. (unless (bolp)
  120. (insert "\n"))))
  121. (let ((start (point))
  122. (title (zo-add-outline-title)))
  123. (skip-chars-backward "\n")
  124. (delete-region (point) start)
  125. (insert "\n\n" title "\n")
  126. (let ((inhibit-message t))
  127. (save-buffer))))
  128. (defun zo-end-of-subtree ()
  129. "Goto to the end of a subtree."
  130. (outline-back-to-heading t)
  131. (let ((first t)
  132. (level (funcall outline-level)))
  133. (while (and (not (eobp))
  134. (or first (> (funcall outline-level) level)))
  135. (setq first nil)
  136. (outline-next-heading)))
  137. (point))
  138. (defun zo-bnd-subtree ()
  139. "Return a cons of heading end and subtree end."
  140. (save-excursion
  141. (condition-case nil
  142. (progn
  143. (outline-back-to-heading)
  144. (cons
  145. (save-excursion
  146. (outline-end-of-heading)
  147. (point))
  148. (save-excursion
  149. (zo-end-of-subtree)
  150. (when (bolp)
  151. (backward-char))
  152. (point))))
  153. (error
  154. (cons (point-min) (point-max))))))
  155. (provide 'zoutline)
  156. ;;; zoutline.el ends here