mode-local.el 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783
  1. ;;; mode-local.el --- Support for mode local facilities
  2. ;;
  3. ;; Copyright (C) 2004-2005, 2007-2012 Free Software Foundation, Inc.
  4. ;;
  5. ;; Author: David Ponce <david@dponce.com>
  6. ;; Maintainer: David Ponce <david@dponce.com>
  7. ;; Created: 27 Apr 2004
  8. ;; Keywords: syntax
  9. ;; This file is part of GNU Emacs.
  10. ;; GNU Emacs 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. ;; GNU Emacs 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 GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
  20. ;;; Commentary:
  21. ;;
  22. ;; Each major mode will want to support a specific set of behaviors.
  23. ;; Usually generic behaviors that need just a little bit of local
  24. ;; specifics.
  25. ;;
  26. ;; This library permits the setting of override functions for tasks of
  27. ;; that nature, and also provides reasonable defaults.
  28. ;;
  29. ;; There are buffer local variables, and frame local variables.
  30. ;; This library gives the illusion of mode specific variables.
  31. ;;
  32. ;; You should use a mode-local variable or override to allow extension
  33. ;; only if you expect a mode author to provide that extension. If a
  34. ;; user might wish to customize a given variable or function then
  35. ;; the existing customization mechanism should be used.
  36. ;; To Do:
  37. ;; Allow customization of a variable for a specific mode?
  38. ;;
  39. ;; Add macro for defining the '-default' functionality.
  40. ;;; Code:
  41. (eval-when-compile (require 'cl))
  42. ;;; Misc utilities
  43. ;;
  44. (defun mode-local-map-file-buffers (function &optional predicate buffers)
  45. "Run FUNCTION on every file buffer found.
  46. FUNCTION does not have arguments; when it is entered `current-buffer'
  47. is the currently selected file buffer.
  48. If optional argument PREDICATE is non nil, only select file buffers
  49. for which the function PREDICATE returns non-nil.
  50. If optional argument BUFFERS is non-nil, it is a list of buffers to
  51. walk through. It defaults to `buffer-list'."
  52. (dolist (b (or buffers (buffer-list)))
  53. (and (buffer-live-p b) (buffer-file-name b)
  54. (with-current-buffer b
  55. (when (or (not predicate) (funcall predicate))
  56. (funcall function))))))
  57. (defsubst get-mode-local-parent (mode)
  58. "Return the mode parent of the major mode MODE.
  59. Return nil if MODE has no parent."
  60. (or (get mode 'mode-local-parent)
  61. (get mode 'derived-mode-parent)))
  62. ;; FIXME doc (and function name) seems wrong.
  63. ;; Return a list of MODE and all its parent modes, if any.
  64. ;; Lists parent modes first.
  65. (defun mode-local-equivalent-mode-p (mode)
  66. "Is the major-mode in the current buffer equivalent to a mode in MODES."
  67. (let ((modes nil))
  68. (while mode
  69. (setq modes (cons mode modes)
  70. mode (get-mode-local-parent mode)))
  71. modes))
  72. (defun mode-local-map-mode-buffers (function modes)
  73. "Run FUNCTION on every file buffer with major mode in MODES.
  74. MODES can be a symbol or a list of symbols.
  75. FUNCTION does not have arguments."
  76. (or (listp modes) (setq modes (list modes)))
  77. (mode-local-map-file-buffers
  78. function #'(lambda ()
  79. (let ((mm (mode-local-equivalent-mode-p major-mode))
  80. (ans nil))
  81. (while (and (not ans) mm)
  82. (setq ans (memq (car mm) modes)
  83. mm (cdr mm)) )
  84. ans))))
  85. ;;; Hook machinery
  86. ;;
  87. (defvar mode-local-init-hook nil
  88. "Hook run after a new file buffer is created.
  89. The current buffer is the newly created file buffer.")
  90. (defvar mode-local-changed-mode-buffers nil
  91. "List of buffers whose `major-mode' has changed recently.")
  92. (defvar mode-local--init-mode nil)
  93. (defsubst mode-local-initialized-p ()
  94. "Return non-nil if mode local is initialized in current buffer.
  95. That is, if the current `major-mode' is equal to the major mode for
  96. which mode local bindings have been activated."
  97. (eq mode-local--init-mode major-mode))
  98. (defun mode-local-post-major-mode-change ()
  99. "Initialize mode-local facilities.
  100. This is run from `find-file-hook', and from `post-command-hook'
  101. after changing the major mode."
  102. (remove-hook 'post-command-hook 'mode-local-post-major-mode-change nil)
  103. (let ((buffers mode-local-changed-mode-buffers))
  104. (setq mode-local-changed-mode-buffers nil)
  105. (mode-local-map-file-buffers
  106. (lambda ()
  107. ;; Make sure variables are set up for this mode.
  108. (activate-mode-local-bindings)
  109. (run-hooks 'mode-local-init-hook))
  110. (lambda ()
  111. (not (mode-local-initialized-p)))
  112. buffers)))
  113. (defun mode-local-on-major-mode-change ()
  114. "Function called in `change-major-mode-hook'."
  115. (add-to-list 'mode-local-changed-mode-buffers (current-buffer))
  116. (add-hook 'post-command-hook 'mode-local-post-major-mode-change t nil))
  117. ;;; Mode lineage
  118. ;;
  119. (defsubst set-mode-local-parent (mode parent)
  120. "Set parent of major mode MODE to PARENT mode.
  121. To work properly, this function should be called after PARENT mode
  122. local variables have been defined."
  123. (put mode 'mode-local-parent parent)
  124. ;; Refresh mode bindings to get mode local variables inherited from
  125. ;; PARENT. To work properly, the following should be called after
  126. ;; PARENT mode local variables have been defined.
  127. (mode-local-map-mode-buffers #'activate-mode-local-bindings mode))
  128. (defmacro define-child-mode (mode parent &optional docstring)
  129. "Make major mode MODE inherit behavior from PARENT mode.
  130. DOCSTRING is optional and not used.
  131. To work properly, this should be put after PARENT mode local variables
  132. definition."
  133. `(set-mode-local-parent ',mode ',parent))
  134. (defun mode-local-use-bindings-p (this-mode desired-mode)
  135. "Return non-nil if THIS-MODE can use bindings of DESIRED-MODE."
  136. (let ((ans nil))
  137. (while (and (not ans) this-mode)
  138. (setq ans (eq this-mode desired-mode))
  139. (setq this-mode (get-mode-local-parent this-mode)))
  140. ans))
  141. ;;; Core bindings API
  142. ;;
  143. (defvar mode-local-symbol-table nil
  144. "Buffer local mode bindings.
  145. These symbols provide a hook for a `major-mode' to specify specific
  146. behaviors. Use the function `mode-local-bind' to define new bindings.")
  147. (make-variable-buffer-local 'mode-local-symbol-table)
  148. (defvar mode-local-active-mode nil
  149. "Major mode in which bindings are active.")
  150. (defsubst new-mode-local-bindings ()
  151. "Return a new empty mode bindings symbol table."
  152. (make-vector 13 0))
  153. (defun mode-local-bind (bindings &optional plist mode)
  154. "Define BINDINGS in the specified environment.
  155. BINDINGS is a list of (VARIABLE . VALUE).
  156. Optional argument PLIST is a property list each VARIABLE symbol will
  157. be set to. The following properties have special meaning:
  158. - `constant-flag' if non-nil, prevent to rebind variables.
  159. - `mode-variable-flag' if non-nil, define mode variables.
  160. - `override-flag' if non-nil, define override functions.
  161. The `override-flag' and `mode-variable-flag' properties are mutually
  162. exclusive.
  163. If optional argument MODE is non-nil, it must be a major mode symbol.
  164. BINDINGS will be defined globally for this major mode. If MODE is
  165. nil, BINDINGS will be defined locally in the current buffer, in
  166. variable `mode-local-symbol-table'. The later should be done in MODE
  167. hook."
  168. ;; Check plist consistency
  169. (and (plist-get plist 'mode-variable-flag)
  170. (plist-get plist 'override-flag)
  171. (error "Bindings can't be both overrides and mode variables"))
  172. (let (table variable varname value binding)
  173. (if mode
  174. (progn
  175. ;; Install in given MODE symbol table. Create a new one if
  176. ;; needed.
  177. (setq table (or (get mode 'mode-local-symbol-table)
  178. (new-mode-local-bindings)))
  179. (put mode 'mode-local-symbol-table table))
  180. ;; Fail if trying to bind mode variables in local context!
  181. (if (plist-get plist 'mode-variable-flag)
  182. (error "Mode required to bind mode variables"))
  183. ;; Install in buffer local symbol table. Create a new one if
  184. ;; needed.
  185. (setq table (or mode-local-symbol-table
  186. (setq mode-local-symbol-table
  187. (new-mode-local-bindings)))))
  188. (while bindings
  189. (setq binding (car bindings)
  190. bindings (cdr bindings)
  191. varname (symbol-name (car binding))
  192. value (cdr binding))
  193. (if (setq variable (intern-soft varname table))
  194. ;; Binding already exists
  195. ;; Check rebind consistency
  196. (cond
  197. ((equal (symbol-value variable) value)
  198. ;; Just ignore rebind with the same value.
  199. )
  200. ((get variable 'constant-flag)
  201. (error "Can't change the value of constant `%s'"
  202. variable))
  203. ((and (get variable 'mode-variable-flag)
  204. (plist-get plist 'override-flag))
  205. (error "Can't rebind override `%s' as a mode variable"
  206. variable))
  207. ((and (get variable 'override-flag)
  208. (plist-get plist 'mode-variable-flag))
  209. (error "Can't rebind mode variable `%s' as an override"
  210. variable))
  211. (t
  212. ;; Merge plist and assign new value
  213. (setplist variable (append plist (symbol-plist variable)))
  214. (set variable value)))
  215. ;; New binding
  216. (setq variable (intern varname table))
  217. ;; Set new plist and assign initial value
  218. (setplist variable plist)
  219. (set variable value)))
  220. ;; Return the symbol table used
  221. table))
  222. (defsubst mode-local-symbol (symbol &optional mode)
  223. "Return the mode local symbol bound with SYMBOL's name.
  224. Return nil if the mode local symbol doesn't exist.
  225. If optional argument MODE is nil, lookup first into locally bound
  226. symbols, then in those bound in current `major-mode' and its parents.
  227. If MODE is non-nil, lookup into symbols bound in that major mode and
  228. its parents."
  229. (let ((name (symbol-name symbol)) bind)
  230. (or mode
  231. (setq mode mode-local-active-mode)
  232. (setq mode major-mode
  233. bind (and mode-local-symbol-table
  234. (intern-soft name mode-local-symbol-table))))
  235. (while (and mode (not bind))
  236. (or (and (get mode 'mode-local-symbol-table)
  237. (setq bind (intern-soft
  238. name (get mode 'mode-local-symbol-table))))
  239. (setq mode (get-mode-local-parent mode))))
  240. bind))
  241. (defsubst mode-local-symbol-value (symbol &optional mode property)
  242. "Return the value of the mode local symbol bound with SYMBOL's name.
  243. If optional argument MODE is non-nil, restrict lookup to that mode and
  244. its parents (see the function `mode-local-symbol' for more details).
  245. If optional argument PROPERTY is non-nil the mode local symbol must
  246. have that property set. Return nil if the symbol doesn't exist, or
  247. doesn't have PROPERTY set."
  248. (and (setq symbol (mode-local-symbol symbol mode))
  249. (or (not property) (get symbol property))
  250. (symbol-value symbol)))
  251. ;;; Mode local variables
  252. ;;
  253. (defun activate-mode-local-bindings (&optional mode)
  254. "Activate variables defined locally in MODE and its parents.
  255. That is, copy mode local bindings into corresponding buffer local
  256. variables.
  257. If MODE is not specified it defaults to current `major-mode'.
  258. Return the alist of buffer-local variables that have been changed.
  259. Elements are (SYMBOL . PREVIOUS-VALUE), describing one variable."
  260. ;; Hack -
  261. ;; do not do this if we are inside set-auto-mode as we may be in
  262. ;; an initialization race condition.
  263. (if (or (and (featurep 'emacs) (boundp 'keep-mode-if-same))
  264. (and (featurep 'xemacs) (boundp 'just-from-file-name)))
  265. ;; We are inside set-auto-mode, as this is an argument that is
  266. ;; vaguely unique.
  267. ;; This will make sure that when everything is over, this will get
  268. ;; called and we won't be under set-auto-mode anymore.
  269. (mode-local-on-major-mode-change)
  270. ;; Do the normal thing.
  271. (let (modes table old-locals)
  272. (unless mode
  273. (set (make-local-variable 'mode-local--init-mode) major-mode)
  274. (setq mode major-mode))
  275. ;; Get MODE's parents & MODE in the right order.
  276. (while mode
  277. (setq modes (cons mode modes)
  278. mode (get-mode-local-parent mode)))
  279. ;; Activate mode bindings following parent modes order.
  280. (dolist (mode modes)
  281. (when (setq table (get mode 'mode-local-symbol-table))
  282. (mapatoms
  283. #'(lambda (var)
  284. (when (get var 'mode-variable-flag)
  285. (let ((v (intern (symbol-name var))))
  286. ;; Save the current buffer-local value of the
  287. ;; mode-local variable.
  288. (and (local-variable-p v (current-buffer))
  289. (push (cons v (symbol-value v)) old-locals))
  290. (set (make-local-variable v) (symbol-value var)))))
  291. table)))
  292. old-locals)))
  293. (defun deactivate-mode-local-bindings (&optional mode)
  294. "Deactivate variables defined locally in MODE and its parents.
  295. That is, kill buffer local variables set from the corresponding mode
  296. local bindings.
  297. If MODE is not specified it defaults to current `major-mode'."
  298. (unless mode
  299. (kill-local-variable 'mode-local--init-mode)
  300. (setq mode major-mode))
  301. (let (table)
  302. (while mode
  303. (when (setq table (get mode 'mode-local-symbol-table))
  304. (mapatoms
  305. #'(lambda (var)
  306. (when (get var 'mode-variable-flag)
  307. (kill-local-variable (intern (symbol-name var)))))
  308. table))
  309. (setq mode (get-mode-local-parent mode)))))
  310. (defmacro with-mode-local-symbol (mode &rest body)
  311. "With the local bindings of MODE symbol, evaluate BODY.
  312. The current mode bindings are saved, BODY is evaluated, and the saved
  313. bindings are restored, even in case of an abnormal exit.
  314. Value is what BODY returns.
  315. This is like `with-mode-local', except that MODE's value is used.
  316. To use the symbol MODE (quoted), use `with-mode-local'."
  317. (let ((old-mode (make-symbol "mode"))
  318. (old-locals (make-symbol "old-locals"))
  319. (new-mode (make-symbol "new-mode"))
  320. (local (make-symbol "local")))
  321. `(let ((,old-mode mode-local-active-mode)
  322. (,old-locals nil)
  323. (,new-mode ,mode)
  324. )
  325. (unwind-protect
  326. (progn
  327. (deactivate-mode-local-bindings ,old-mode)
  328. (setq mode-local-active-mode ,new-mode)
  329. ;; Save the previous value of buffer-local variables
  330. ;; changed by `activate-mode-local-bindings'.
  331. (setq ,old-locals (activate-mode-local-bindings ,new-mode))
  332. ,@body)
  333. (deactivate-mode-local-bindings ,new-mode)
  334. ;; Restore the previous value of buffer-local variables.
  335. (dolist (,local ,old-locals)
  336. (set (car ,local) (cdr ,local)))
  337. ;; Restore the mode local variables.
  338. (setq mode-local-active-mode ,old-mode)
  339. (activate-mode-local-bindings ,old-mode)))))
  340. (put 'with-mode-local-symbol 'lisp-indent-function 1)
  341. (defmacro with-mode-local (mode &rest body)
  342. "With the local bindings of MODE, evaluate BODY.
  343. The current mode bindings are saved, BODY is evaluated, and the saved
  344. bindings are restored, even in case of an abnormal exit.
  345. Value is what BODY returns.
  346. This is like `with-mode-local-symbol', except that MODE is quoted
  347. and is not evaluated."
  348. `(with-mode-local-symbol ',mode ,@body))
  349. (put 'with-mode-local 'lisp-indent-function 1)
  350. (defsubst mode-local-value (mode sym)
  351. "Return the value of the MODE local variable SYM."
  352. (or mode (error "Missing major mode symbol"))
  353. (mode-local-symbol-value sym mode 'mode-variable-flag))
  354. (defmacro setq-mode-local (mode &rest args)
  355. "Assign new values to variables local in MODE.
  356. MODE must be a major mode symbol.
  357. ARGS is a list (SYM VAL SYM VAL ...).
  358. The symbols SYM are variables; they are literal (not evaluated).
  359. The values VAL are expressions; they are evaluated.
  360. Set each SYM to the value of its VAL, locally in buffers already in
  361. MODE, or in buffers switched to that mode.
  362. Return the value of the last VAL."
  363. (when args
  364. (let (i ll bl sl tmp sym val)
  365. (setq i 0)
  366. (while args
  367. (setq tmp (make-symbol (format "tmp%d" i))
  368. i (1+ i)
  369. sym (car args)
  370. val (cadr args)
  371. ll (cons (list tmp val) ll)
  372. bl (cons `(cons ',sym ,tmp) bl)
  373. sl (cons `(set (make-local-variable ',sym) ,tmp) sl)
  374. args (cddr args)))
  375. `(let* ,(nreverse ll)
  376. ;; Save mode bindings
  377. (mode-local-bind (list ,@bl) '(mode-variable-flag t) ',mode)
  378. ;; Assign to local variables in all existing buffers in MODE
  379. (mode-local-map-mode-buffers #'(lambda () ,@sl) ',mode)
  380. ;; Return the last value
  381. ,tmp)
  382. )))
  383. (defmacro defvar-mode-local (mode sym val &optional docstring)
  384. "Define MODE local variable SYM with value VAL.
  385. DOCSTRING is optional."
  386. `(progn
  387. (setq-mode-local ,mode ,sym ,val)
  388. (put (mode-local-symbol ',sym ',mode)
  389. 'variable-documentation ,docstring)
  390. ',sym))
  391. (put 'defvar-mode-local 'lisp-indent-function 'defun)
  392. (defmacro defconst-mode-local (mode sym val &optional docstring)
  393. "Define MODE local constant SYM with value VAL.
  394. DOCSTRING is optional."
  395. (let ((tmp (make-symbol "tmp")))
  396. `(let (,tmp)
  397. (setq-mode-local ,mode ,sym ,val)
  398. (setq ,tmp (mode-local-symbol ',sym ',mode))
  399. (put ,tmp 'constant-flag t)
  400. (put ,tmp 'variable-documentation ,docstring)
  401. ',sym)))
  402. (put 'defconst-mode-local 'lisp-indent-function 'defun)
  403. ;;; Function overloading
  404. ;;
  405. (defun make-obsolete-overload (old new when)
  406. "Mark OLD overload as obsoleted by NEW overload.
  407. WHEN is a string describing the first release where it was made obsolete."
  408. (put old 'overload-obsoleted-by new)
  409. (put old 'overload-obsoleted-since when)
  410. (put old 'mode-local-overload t)
  411. (put new 'overload-obsolete old))
  412. (defsubst overload-obsoleted-by (overload)
  413. "Get the overload symbol obsoleted by OVERLOAD.
  414. Return the obsolete symbol or nil if not found."
  415. (get overload 'overload-obsolete))
  416. (defsubst overload-that-obsolete (overload)
  417. "Return the overload symbol that obsoletes OVERLOAD.
  418. Return the symbol found or nil if OVERLOAD is not obsolete."
  419. (get overload 'overload-obsoleted-by))
  420. (defsubst fetch-overload (overload)
  421. "Return the current OVERLOAD function, or nil if not found.
  422. First, lookup for OVERLOAD into locally bound mode local symbols, then
  423. in those bound in current `major-mode' and its parents."
  424. (or (mode-local-symbol-value overload nil 'override-flag)
  425. ;; If an obsolete overload symbol exists, try it.
  426. (and (overload-obsoleted-by overload)
  427. (mode-local-symbol-value
  428. (overload-obsoleted-by overload) nil 'override-flag))))
  429. (defun mode-local--override (name args body)
  430. "Return the form that handles overloading of function NAME.
  431. ARGS are the arguments to the function.
  432. BODY is code that would be run when there is no override defined. The
  433. default is to call the function `NAME-default' with the appropriate
  434. arguments.
  435. See also the function `define-overload'."
  436. (let* ((default (intern (format "%s-default" name)))
  437. (overargs (delq '&rest (delq '&optional (copy-sequence args))))
  438. (override (make-symbol "override")))
  439. `(let ((,override (fetch-overload ',name)))
  440. (if ,override
  441. (funcall ,override ,@overargs)
  442. ,@(or body `((,default ,@overargs)))))
  443. ))
  444. (defun mode-local--expand-overrides (name args body)
  445. "Expand override forms that overload function NAME.
  446. ARGS are the arguments to the function NAME.
  447. BODY is code where override forms are searched for expansion.
  448. Return result of expansion, or BODY if no expansion occurred.
  449. See also the function `define-overload'."
  450. (let ((forms body)
  451. (ditto t)
  452. form xbody)
  453. (while forms
  454. (setq form (car forms))
  455. (cond
  456. ((atom form))
  457. ((eq (car form) :override)
  458. (setq form (mode-local--override name args (cdr form))))
  459. ((eq (car form) :override-with-args)
  460. (setq form (mode-local--override name (cadr form) (cddr form))))
  461. ((setq form (mode-local--expand-overrides name args form))))
  462. (setq ditto (and ditto (eq (car forms) form))
  463. xbody (cons form xbody)
  464. forms (cdr forms)))
  465. (if ditto body (nreverse xbody))))
  466. (defun mode-local--overload-body (name args body)
  467. "Return the code that implements overloading of function NAME.
  468. ARGS are the arguments to the function NAME.
  469. BODY specifies the overload code.
  470. See also the function `define-overload'."
  471. (let ((result (mode-local--expand-overrides name args body)))
  472. (if (eq body result)
  473. (list (mode-local--override name args body))
  474. result)))
  475. (defmacro define-overloadable-function (name args docstring &rest body)
  476. "Define a new function, as with `defun', which can be overloaded.
  477. NAME is the name of the function to create.
  478. ARGS are the arguments to the function.
  479. DOCSTRING is a documentation string to describe the function. The
  480. docstring will automatically have details about its overload symbol
  481. appended to the end.
  482. BODY is code that would be run when there is no override defined. The
  483. default is to call the function `NAME-default' with the appropriate
  484. arguments.
  485. BODY can also include an override form that specifies which part of
  486. BODY is specifically overridden. This permits to specify common code
  487. run for both default and overridden implementations.
  488. An override form is one of:
  489. 1. (:override [OVERBODY])
  490. 2. (:override-with-args OVERARGS [OVERBODY])
  491. OVERBODY is the code that would be run when there is no override
  492. defined. The default is to call the function `NAME-default' with the
  493. appropriate arguments deduced from ARGS.
  494. OVERARGS is a list of arguments passed to the override and
  495. `NAME-default' function, in place of those deduced from ARGS."
  496. `(eval-and-compile
  497. (defun ,name ,args
  498. ,docstring
  499. ,@(mode-local--overload-body name args body))
  500. (put ',name 'mode-local-overload t)))
  501. (put :override-with-args 'lisp-indent-function 1)
  502. (defalias 'define-overload 'define-overloadable-function)
  503. (defsubst function-overload-p (symbol)
  504. "Return non-nil if SYMBOL is a function which can be overloaded."
  505. (and symbol (symbolp symbol) (get symbol 'mode-local-overload)))
  506. (defmacro define-mode-local-override
  507. (name mode args docstring &rest body)
  508. "Define a mode specific override of the function overload NAME.
  509. Has meaning only if NAME has been created with `define-overload'.
  510. MODE is the major mode this override is being defined for.
  511. ARGS are the function arguments, which should match those of the same
  512. named function created with `define-overload'.
  513. DOCSTRING is the documentation string.
  514. BODY is the implementation of this function."
  515. (let ((newname (intern (format "%s-%s" name mode))))
  516. `(progn
  517. (eval-and-compile
  518. (defun ,newname ,args
  519. ,(format "%s\n\nOverride %s in `%s' buffers."
  520. docstring name mode)
  521. ;; The body for this implementation
  522. ,@body)
  523. ;; For find-func to locate the definition of NEWNAME.
  524. (put ',newname 'definition-name ',name))
  525. (mode-local-bind '((,name . ,newname))
  526. '(override-flag t)
  527. ',mode))
  528. ))
  529. ;;; Read/Query Support
  530. (defun mode-local-read-function (prompt &optional initial hist default)
  531. "Interactively read in the name of a mode-local function.
  532. PROMPT, INITIAL, HIST, and DEFAULT are the same as for `completing-read'."
  533. (completing-read prompt obarray 'function-overload-p t initial hist default))
  534. ;;; Help support
  535. ;;
  536. (defun overload-docstring-extension (overload)
  537. "Return the doc string that augments the description of OVERLOAD."
  538. (let ((doc "\n\This function can be overloaded\
  539. with `define-mode-local-override'.")
  540. (sym (overload-obsoleted-by overload)))
  541. (when sym
  542. (setq doc (format "%s\nIt has made the overload `%s' obsolete since %s."
  543. doc sym (get sym 'overload-obsoleted-since))))
  544. (setq sym (overload-that-obsolete overload))
  545. (when sym
  546. (setq doc (format "%s\nThis overload is obsolete since %s;\nUse `%s' instead."
  547. doc (get overload 'overload-obsoleted-since) sym)))
  548. doc))
  549. (defun mode-local-augment-function-help (symbol)
  550. "Augment the *Help* buffer for SYMBOL.
  551. SYMBOL is a function that can be overridden."
  552. (with-current-buffer "*Help*"
  553. (pop-to-buffer (current-buffer))
  554. (goto-char (point-min))
  555. (unless (re-search-forward "^$" nil t)
  556. (goto-char (point-max))
  557. (beginning-of-line)
  558. (forward-line -1))
  559. (let ((inhibit-read-only t))
  560. (insert (overload-docstring-extension symbol) "\n")
  561. ;; NOTE TO SELF:
  562. ;; LIST ALL LOADED OVERRIDES FOR SYMBOL HERE
  563. )))
  564. ;; Help for mode-local bindings.
  565. (defun mode-local-print-binding (symbol)
  566. "Print the SYMBOL binding."
  567. (let ((value (symbol-value symbol)))
  568. (princ (format "\n `%s' value is\n " symbol))
  569. (if (and value (symbolp value))
  570. (princ (format "`%s'" value))
  571. (let ((pt (point)))
  572. (pp value)
  573. (save-excursion
  574. (goto-char pt)
  575. (indent-sexp))))
  576. (or (bolp) (princ "\n"))))
  577. (defun mode-local-print-bindings (table)
  578. "Print bindings in TABLE."
  579. (let (us ;; List of unspecified symbols
  580. mc ;; List of mode local constants
  581. mv ;; List of mode local variables
  582. ov ;; List of overloaded functions
  583. fo ;; List of final overloaded functions
  584. )
  585. ;; Order symbols by type
  586. (mapatoms
  587. #'(lambda (s)
  588. (add-to-list (cond
  589. ((get s 'mode-variable-flag)
  590. (if (get s 'constant-flag) 'mc 'mv))
  591. ((get s 'override-flag)
  592. (if (get s 'constant-flag) 'fo 'ov))
  593. ('us))
  594. s))
  595. table)
  596. ;; Print symbols by type
  597. (when us
  598. (princ "\n !! Unspecified symbols\n")
  599. (mapc 'mode-local-print-binding us))
  600. (when mc
  601. (princ "\n ** Mode local constants\n")
  602. (mapc 'mode-local-print-binding mc))
  603. (when mv
  604. (princ "\n ** Mode local variables\n")
  605. (mapc 'mode-local-print-binding mv))
  606. (when fo
  607. (princ "\n ** Final overloaded functions\n")
  608. (mapc 'mode-local-print-binding fo))
  609. (when ov
  610. (princ "\n ** Overloaded functions\n")
  611. (mapc 'mode-local-print-binding ov))
  612. ))
  613. (defun mode-local-describe-bindings-2 (buffer-or-mode)
  614. "Display mode local bindings active in BUFFER-OR-MODE."
  615. (let (table mode)
  616. (princ "Mode local bindings active in ")
  617. (cond
  618. ((bufferp buffer-or-mode)
  619. (with-current-buffer buffer-or-mode
  620. (setq table mode-local-symbol-table
  621. mode major-mode))
  622. (princ (format "%S\n" buffer-or-mode))
  623. )
  624. ((symbolp buffer-or-mode)
  625. (setq mode buffer-or-mode)
  626. (princ (format "`%s'\n" buffer-or-mode))
  627. )
  628. ((signal 'wrong-type-argument
  629. (list 'buffer-or-mode buffer-or-mode))))
  630. (when table
  631. (princ "\n- Buffer local\n")
  632. (mode-local-print-bindings table))
  633. (while mode
  634. (setq table (get mode 'mode-local-symbol-table))
  635. (when table
  636. (princ (format "\n- From `%s'\n" mode))
  637. (mode-local-print-bindings table))
  638. (setq mode (get-mode-local-parent mode)))))
  639. (defun mode-local-describe-bindings-1 (buffer-or-mode &optional interactive-p)
  640. "Display mode local bindings active in BUFFER-OR-MODE.
  641. Optional argument INTERACTIVE-P is non-nil if the calling command was
  642. invoked interactively."
  643. (if (fboundp 'with-displaying-help-buffer)
  644. ;; XEmacs
  645. (with-displaying-help-buffer
  646. #'(lambda ()
  647. (with-current-buffer standard-output
  648. (mode-local-describe-bindings-2 buffer-or-mode)
  649. (when (fboundp 'frob-help-extents)
  650. (goto-char (point-min))
  651. (frob-help-extents standard-output)))))
  652. ;; GNU Emacs
  653. (when (fboundp 'help-setup-xref)
  654. (help-setup-xref
  655. (list 'mode-local-describe-bindings-1 buffer-or-mode)
  656. interactive-p))
  657. (with-output-to-temp-buffer (help-buffer) ; "*Help*"
  658. (with-current-buffer standard-output
  659. (mode-local-describe-bindings-2 buffer-or-mode)))))
  660. (defun describe-mode-local-bindings (buffer)
  661. "Display mode local bindings active in BUFFER."
  662. (interactive "b")
  663. (when (setq buffer (get-buffer buffer))
  664. (mode-local-describe-bindings-1 buffer (called-interactively-p 'any))))
  665. (defun describe-mode-local-bindings-in-mode (mode)
  666. "Display mode local bindings active in MODE hierarchy."
  667. (interactive
  668. (list (completing-read
  669. "Mode: " obarray
  670. #'(lambda (s) (get s 'mode-local-symbol-table))
  671. t (symbol-name major-mode))))
  672. (when (setq mode (intern-soft mode))
  673. (mode-local-describe-bindings-1 mode (called-interactively-p 'any))))
  674. ;; ;;; find-func support (Emacs 21.4, or perhaps 22.1)
  675. ;; ;;
  676. ;; (condition-case nil
  677. ;; ;; Try to get find-func so we can modify it.
  678. ;; (require 'find-func)
  679. ;; (error nil))
  680. ;; (when (boundp 'find-function-regexp)
  681. ;; (unless (string-match "ine-overload" find-function-regexp)
  682. ;; (if (string-match "(def\\\\(" find-function-regexp)
  683. ;; (let ((end (match-end 0))
  684. ;; )
  685. ;; (setq find-function-regexp
  686. ;; (concat (substring find-function-regexp 0 end)
  687. ;; "ine-overload\\|ine-mode-local-override\\|"
  688. ;; "ine-child-mode\\|"
  689. ;; (substring find-function-regexp end)))))))
  690. ;;; edebug support
  691. ;;
  692. (defun mode-local-setup-edebug-specs ()
  693. "Define edebug specification for mode local macros."
  694. (def-edebug-spec setq-mode-local
  695. (symbolp &rest symbolp form))
  696. (def-edebug-spec defvar-mode-local
  697. (&define symbolp name def-form [ &optional stringp ] ))
  698. (def-edebug-spec defconst-mode-local
  699. defvar-mode-local)
  700. (def-edebug-spec define-overload
  701. (&define name lambda-list stringp def-body))
  702. (def-edebug-spec define-overloadable-function
  703. (&define name lambda-list stringp def-body))
  704. (def-edebug-spec define-mode-local-override
  705. (&define name symbolp lambda-list stringp def-body)))
  706. (add-hook 'edebug-setup-hook 'mode-local-setup-edebug-specs)
  707. (add-hook 'find-file-hook 'mode-local-post-major-mode-change)
  708. (add-hook 'change-major-mode-hook 'mode-local-on-major-mode-change)
  709. (provide 'mode-local)
  710. ;;; mode-local.el ends here