PageRenderTime 48ms CodeModel.GetById 19ms RepoModel.GetById 0ms app.codeStats 0ms

/old-archive/modes/expand.el

https://github.com/emacsmirror/ohio-archive
Emacs Lisp | 266 lines | 156 code | 24 blank | 86 comment | 4 complexity | 886a4ae36111b784f212866567f17158 MD5 | raw file
  1. ;; expand.el --- minor mode to make abbreviations more usable.
  2. ;;
  3. ;; Copyright (C) 1995, Frederic Lepied <fred@sugix.frmug.fr.net>
  4. ;;
  5. ;; Author: Frederic Lepied <fred@sugix.frmug.fr.net>
  6. ;; Version: $Id: expand.el,v 1.3 1995/02/25 21:39:54 fred Exp $
  7. ;; Keywords: abbrev
  8. ;;
  9. ;; LCD Archive Entry:
  10. ;; expand|Frederic Lepied|fred@sugix.frmug.fr.net|
  11. ;; A minor mode to make abbreviations more usable.|
  12. ;; 25-Feb-1995|1.3|~/modes/expand.el.gz|
  13. ;;
  14. ;; This file is NOT part of GNU Emacs but the same permissions apply.
  15. ;;
  16. ;; GNU Emacs is free software; you can redistribute it and/or modify
  17. ;; it under the terms of the GNU General Public License as published
  18. ;; by the Free Software Foundation; either version 2, or (at your
  19. ;; option) any later version.
  20. ;;
  21. ;; GNU Emacs is distributed in the hope that it will be useful, but
  22. ;; WITHOUT ANY WARRANTY; without even the implied warranty of
  23. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  24. ;; General Public License for more details.
  25. ;;
  26. ;; You should have received a copy of the GNU General Public License
  27. ;; along with GNU Emacs; see the file COPYING. If not, write to the
  28. ;; Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
  29. ;; This program is free software; you can redistribute it and/or
  30. ;; modify it under the terms of the GNU General Public License as
  31. ;; published by the Free Software Foundation; either version 2 of the
  32. ;; License, or (at your option) any later version.
  33. ;;
  34. ;; Purpose of this package:
  35. ;; 1. Make abbreviations more usable.
  36. ;; 2. Expand abbreviations only when they are at the end of a line.
  37. ;; 3. Position the cursor after expansion to a place specified by advance.
  38. ;; 4. Indent the expanded region.
  39. ;; 5. If a list of points as been provided with the abbreviation definition,
  40. ;; the functions expand-jump-to-previous-mark and expand-jump-to-next-mark
  41. ;; moved from mark to mark.
  42. ;;
  43. ;; Installation:
  44. ;; * store this file somewhere in your load-path and byte compile it.
  45. ;; * put (require 'expand) in your .emacs or in site-start.el or generate
  46. ;; autoloads.
  47. ;; * and according to the mode install your expansion table.
  48. ;;
  49. ;; For example for c-mode, you could declare your abbrev table with :
  50. ;;
  51. ;; (defconst c-expand-list
  52. ;; '(("if" "if () {\n \n} else {\n \n}" (5 10 21))
  53. ;; ("uns" "unsigned ")
  54. ;; ("for" "for(;;) {\n\n}" (5 6 7 11))
  55. ;; ("switch" "switch () {\n\n}" (9 13))
  56. ;; ("case" "case :\n\nbreak;\n" (6 8 16))
  57. ;; ("do" "do {\n\n} while ();" (6 16))
  58. ;; ("while" "while () {\n\n}" (8 12))
  59. ;; ("default" "default:\n\nbreak;" 10)
  60. ;; ("main" "int\nmain(int argc, char * argv[])\n{\n\n}\n" 37))
  61. ;; "Expansions for C mode")
  62. ;;
  63. ;; (expand-add-abbrevs c-mode-abbrev-table c-expand-list)
  64. ;;
  65. ;; and enter expand-mode with the following hook :
  66. ;;
  67. ;; (add-hook 'c-mode-hook (function (lambda() (expand-mode))))
  68. ;;
  69. ;; you can also bind jump functions to some keys :
  70. ;;
  71. ;; (define-key expand-map '[C-tab] 'expand-jump-to-next-mark)
  72. ;; (define-key expand-map '[C-S-tab] 'expand-jump-to-previous-mark)
  73. ;;
  74. ;; Commentaries:
  75. ;; Has been tested under emacs 19.28 and XEmacs 19.11.
  76. ;; Many thanks to Heddy Boubaker <boubaker@cenatls.cena.dgac.fr>.
  77. ;; Please send me a word to give me your feeling about this mode or
  78. ;; to explain me how you use it (your expansions table for example).
  79. ;; expand is not a replacement for abbrev it is just a layer above it.
  80. ;; You could always declare your abbreviations with define-abbrev to have
  81. ;; the abbrev behavior with expand-mode.
  82. (defvar expand-mode nil
  83. "Status variable for expand-mode")
  84. (make-variable-buffer-local 'expand-mode)
  85. ;;;###autoload
  86. (defun expand-mode(&optional arg)
  87. "Toggle expand mode.
  88. With argument ARG, turn expand mode on if ARG is positive.
  89. In expand mode, inserting an abbreviation at the end of a line
  90. causes it to expand and be replaced by its expansion."
  91. (interactive "P")
  92. (setq expand-mode (if (null arg) (not expand-mode)
  93. (> (prefix-numeric-value arg) 0)))
  94. (if expand-mode
  95. (setq abbrev-mode nil)))
  96. ;;;###autoload
  97. (defvar expand-map (make-sparse-keymap)
  98. "key map used in expand-mode.")
  99. (define-key expand-map " " 'expand)
  100. (or (assq 'expand-mode minor-mode-alist)
  101. (setq minor-mode-alist (cons (list 'expand-mode " Expand")
  102. minor-mode-alist)))
  103. (or (assq 'expand-mode minor-mode-map-alist)
  104. (setq minor-mode-map-alist (cons (cons 'expand-mode expand-map)
  105. minor-mode-map-alist)))
  106. ;;;###autoload
  107. (defun expand-add-abbrevs (table abbrevs)
  108. "Add a list of abbrev to the table.
  109. Each abbrev description entry has the following format :
  110. (abbrev expansion arg)
  111. where
  112. abbrev is the abbreviation to replace.
  113. expansion is the replacement string or a function which will make
  114. the expansion. For example you could use the DMacros package to generate such functions.
  115. arg is an optional element which can be a number or a list of
  116. numbers. If arg is a number, the cursor will be placed at arg chars
  117. from the beginning of the expanded text. If expansion is a list of
  118. numbers the cursor will be placed according to the first number of the
  119. list from the beginning of the expanded text and marks will be placed
  120. and you will be able to visit them cyclicaly with the functions
  121. expand-jump-to-previous-mark and expand-jump-to-next-mark. If arg is
  122. omitted, the cursor will be placed at the end of the expanded text."
  123. (if (null abbrevs)
  124. table
  125. (expand-add-abbrev table (nth 0 (car abbrevs)) (nth 1 (car abbrevs))
  126. (nth 2 (car abbrevs)))
  127. (expand-add-abbrevs table (cdr abbrevs))))
  128. (defvar expand-list nil "Temporary variable used by expand-mode.")
  129. (defvar expand-pos nil
  130. "If non nil, stores a vector containing markers to positions defined by the last expansion.
  131. This variable is local to a buffer.")
  132. (make-variable-buffer-local 'expand-pos)
  133. (defvar expand-index 0
  134. "Index of the last marker used in expand-pos.
  135. This variable is local to a buffer.")
  136. (make-variable-buffer-local 'expand-index)
  137. (defvar expand-point nil
  138. "Beginning of the expanded region.
  139. This variable is local to a buffer.")
  140. (make-variable-buffer-local 'expand-point)
  141. (defun expand-add-abbrev (table abbrev expansion arg)
  142. "Add one abbreviation and provide the hook to move to the specified
  143. position"
  144. (let* ((string-exp (if (and (symbolp expansion) (fboundp expansion))
  145. nil
  146. expansion))
  147. (position (if (and arg string-exp)
  148. (if (listp arg)
  149. (- (length expansion) (1- (car arg)))
  150. (- (length expansion) (1- arg)))
  151. 0)))
  152. (define-abbrev
  153. table
  154. abbrev
  155. (or string-exp "")
  156. (if string-exp
  157. (if (and (listp arg)
  158. (not (null arg)))
  159. (` (lambda()
  160. (expand-build-list (, (length string-exp)) '(, arg))
  161. (setq expand-point (point))
  162. (backward-char (, position))))
  163. (` (lambda()
  164. (setq expand-point (point))
  165. (backward-char (, position)))))
  166. expansion))))
  167. ;;;###autoload
  168. (defun expand()
  169. "Do the expansion job if we are at the end of a line or insert space"
  170. (interactive)
  171. (or (if (or (eolp)
  172. (abbrev-not-expand (previous-word)))
  173. (let ((p (point)))
  174. (when (expand-abbrev)
  175. (if (not expand-point)
  176. t
  177. (if (vectorp expand-list)
  178. (expand-build-marks expand-point))
  179. (indent-region p expand-point nil)
  180. t
  181. ))))
  182. (insert " "))
  183. (setq expand-point nil))
  184. (defun abbrev-not-expand(word)
  185. "Test if an abbrev as a hook"
  186. (or
  187. (and (intern-soft word local-abbrev-table)
  188. (not (symbol-function (intern-soft word local-abbrev-table))))
  189. (and (intern-soft word local-abbrev-table)
  190. (not (symbol-function (intern-soft word local-abbrev-table))))))
  191. (defun previous-word ()
  192. "Return the previous word"
  193. (save-excursion
  194. (let ((p (point)))
  195. (backward-word 1)
  196. (buffer-substring p (point)))))
  197. (defun expand-jump-to-previous-mark()
  198. "Move the cursor to previous mark created by the expansion"
  199. (interactive)
  200. (when expand-pos
  201. (setq expand-index (1- expand-index))
  202. (if (< expand-index 0)
  203. (setq expand-index (1- (length expand-pos))))
  204. (goto-char (aref expand-pos expand-index))))
  205. (defun expand-jump-to-next-mark()
  206. "Move the cursor to next mark created by the expansion"
  207. (interactive)
  208. (when expand-pos
  209. (setq expand-index (1+ expand-index))
  210. (if (>= expand-index (length expand-pos))
  211. (setq expand-index 0))
  212. (goto-char (aref expand-pos expand-index))))
  213. (defun expand-build-list (len l)
  214. "Build a vector of offset positions from the list of positions"
  215. (expand-clear-markers)
  216. (setq expand-list (vconcat l))
  217. (let ((i 0))
  218. (while (< i (length expand-list))
  219. (aset expand-list i (- len (1- (aref expand-list i))))
  220. (setq i (1+ i))))
  221. )
  222. (defun expand-build-marks (p)
  223. "Transform the offsets vector into a marker vector"
  224. (when expand-list
  225. (setq expand-index 0)
  226. (setq expand-pos (make-vector (length expand-list) nil))
  227. (let ((i (1- (length expand-list))))
  228. (while (>= i 0)
  229. (aset expand-pos i (copy-marker (- p (aref expand-list i))))
  230. (setq i (1- i))))
  231. (setq expand-list nil)))
  232. (defun expand-clear-markers ()
  233. "Make the markers point nowhere"
  234. (when expand-pos
  235. (let ((i (1- (length expand-pos))))
  236. (while (>= i 0)
  237. (set-marker (aref expand-pos i) nil)
  238. (setq i (1- i))))
  239. (setq expand-pos nil)))
  240. (provide 'expand)
  241. ;; end of expand.el