PageRenderTime 27ms CodeModel.GetById 27ms RepoModel.GetById 1ms app.codeStats 0ms

/ecb/html-help/Programming-special-windows.html

https://github.com/shanbhardwaj/emacsonrails
HTML | 388 lines | 305 code | 83 blank | 0 comment | 0 complexity | a53bb3d2d452f400580b107aaf8c75e3 MD5 | raw file
  1. <html lang="en">
  2. <head>
  3. <title>ECB - the Emacs Code Browser</title>
  4. <meta http-equiv="Content-Type" content="text/html">
  5. <meta name=description content="ECB - the Emacs Code Browser">
  6. <meta name=generator content="makeinfo 4.2">
  7. <link href="http://www.gnu.org/software/texinfo/" rel=generator-home>
  8. </head>
  9. <body>
  10. <p>
  11. Node:<a name="Programming%20special%20windows">Programming special windows</a>,
  12. Next:<a rel=next accesskey=n href="Possible-layout-outlines.html#Possible%20layout-outlines">Possible layout-outlines</a>,
  13. Previous:<a rel=previous accesskey=p href="Programming-a-new-layout.html#Programming%20a%20new%20layout">Programming a new layout</a>,
  14. Up:<a rel=up accesskey=u href="The-layout-engine.html#The%20layout-engine">The layout-engine</a>
  15. <hr><br>
  16. <h4>All aspects of programming special windows</h4>
  17. <p>ECB offers a flexible programmable layout-engine for other packages to
  18. display their own contents and informations in special ECB-windows. An
  19. example could be a graphical debugger which offers a special window for
  20. displaying local variables and another special window for messages
  21. from the debugger-process (like JDEbug of JDEE<a rel=footnote href="#fn-1"><sup>1</sup></a>).
  22. <p>This section explains all aspects of programming new special windows,
  23. adding them to a new layout and synchronizing them with edit-window of
  24. ECB. This can be done best with an easy example which nevertheless
  25. covers all necessary aspects to be a good example and skeleton for
  26. complex tools (like a graphical debugger) which want to use the
  27. layout-engine of ECB do display their own information.
  28. <p><strong>IMPORTANT</strong>: See <a href="tree-buffer.html#tree-buffer">tree-buffer</a> for a full documentation of
  29. the library tree-buffer.el which can be used for programming a new
  30. special window as a tree!
  31. <p>Here comes the example:
  32. <h5>The outline of the example layout:</h5>
  33. <br><pre>-------------------------------------------------------
  34. |Bufferinfo for &lt;filename&gt;: |[prior] |
  35. |Type: file |[next] |
  36. |Size: 23456 | |
  37. |Modes: rw-rw-rw- | |
  38. |-----------------------------------------------------|
  39. | |
  40. | |
  41. | |
  42. | |
  43. | edit-window |
  44. | |
  45. | |
  46. | |
  47. | |
  48. -------------------------------------------------------
  49. | |
  50. | compilation-window |
  51. | |
  52. -------------------------------------------------------
  53. </pre>
  54. <h5>The description of the layout-contents</h5>
  55. <p>The top-left window always displays informations about the current
  56. buffer in the selected edit-window. This window demonstrates how
  57. autom. synchronizing a special window/buffer of a layout with current
  58. edit-window.
  59. <p>The top-right window contains an read-only "action-buffer" and
  60. offers two buttons which can be used with the middle mouse-button to
  61. scroll the edit-window. This is not very senseful but it demonstrates
  62. how to control the edit-window with actions performed in a special
  63. window/buffer of a layout.
  64. <p>(If you have not set a compilation-window in
  65. <code>ecb-compile-window-height</code> then the layout contains no persistent
  66. compilation window and the other windows get a little more place).
  67. <h5>The example code</h5>
  68. <p>Now let have us a look at the several parts of the Elisp-program
  69. needed to program this new example layout. ECB contains a library
  70. <code>ecb-examples.el</code> which contains the full working code of this
  71. example. To test this example and to play with it you can load this
  72. library into Emacs (with <code>load-library</code> for example) and then
  73. calling <code>ecb-change-layout</code> (bound to <kbd>C-c . lc</kbd>) and
  74. inserting "example-layout1" as layout-name. An alternative is
  75. calling <code>ecb-examples-activate</code> and
  76. <code>ecb-examples-deactivate</code>. For details see file
  77. <code>ecb-examples.el</code>.
  78. <p>The following steps only contain code-skeletons to demonstrate the
  79. principle. The full working code is available in
  80. <code>ecb-examples.el</code>.
  81. <h5>The bufferinfo buffer of the example</h5>
  82. <p>The name of the bufferinfo buffer:
  83. <br><pre>(defconst ecb-examples-bufferinfo-buffer-name " *ECB buffer info*")
  84. </pre>
  85. <p>Two helper functions for displaying infos in a special buffer:
  86. <br><pre>(defun ecb-examples-print-file-attributes (buffer filename)
  87. (ecb-with-readonly-buffer buffer
  88. (erase-buffer)
  89. (insert (format "Bufferinfo for %s:\n\n" filename))
  90. ;; insert with the function `file-attributes' some
  91. ;; informations about FILENAME.
  92. ))
  93. (defun ecb-examples-print-non-filebuffer (buffer buffer-name)
  94. (ecb-with-readonly-buffer buffer
  95. (erase-buffer)
  96. ;; analogous to `ecb-examples-print-file-attributes'
  97. ))
  98. </pre>
  99. <p>The main synchronizing function added to
  100. <code>ecb-current-buffer-sync-hook</code> for autom. evaluation by
  101. <code>ecb-current-buffer-sync</code> which runs dependent on the values of
  102. <code>ecb-window-sync</code> and <code>ecb-window-sync-delay</code>. This function
  103. synchronizes the bufferinfo buffer with the current buffer of the
  104. edit-window if that buffer has changed.
  105. <br><pre>(defun ecb-examples-bufferinfo-sync ()
  106. (ecb-do-if-buffer-visible-in-ecb-frame
  107. 'ecb-examples-bufferinfo-buffer-name
  108. ;; here we can be sure that the buffer with name
  109. ;; `ecb-examples-bufferinfo-buffer-name' is displayed in a
  110. ;; window of `ecb-frame'
  111. ;; The macro `ecb-do-if-buffer-visible-in-ecb-frame' locally
  112. ;; binds the variables visible-buffer and visible-window!! See
  113. ;; documentation of this macro!
  114. (let ((filename (buffer-file-name (current-buffer))))
  115. (if (and filename (file-readable-p filename))
  116. ;; real filebuffers
  117. ;; here we could add a smarter mechanism;
  118. ;; see ecb-examples.el
  119. (ecb-examples-print-file-attributes visible-buffer
  120. filename)
  121. ;; non file buffers like help-buffers etc...
  122. (setq ecb-examples-bufferinfo-last-file nil)
  123. (ecb-examples-print-non-filebuffer visible-buffer
  124. (buffer-name
  125. (current-buffer)))
  126. ))))
  127. </pre>
  128. <p>Two conveniance commands for the user:
  129. <br><pre>(defun ecb-maximize-bufferinfo-window ()
  130. "Maximize the bufferinfo-window.
  131. I.e. delete all other ECB-windows, so only one ECB-window and the
  132. edit-window\(s) are visible \(and maybe a compile-window). Works
  133. also if the ECB-analyse-window is not visible in current layout."
  134. (interactive)
  135. (ecb-display-one-ecb-buffer ecb-examples-bufferinfo-buffer-name))
  136. (defun ecb-goto-bufferinfo-window ()
  137. "Make the bufferinfo-window the current window."
  138. (interactive)
  139. (ecb-goto-ecb-window ecb-examples-bufferinfo-buffer-name))
  140. </pre>
  141. <p>The function which makes the bufferinfo-buffer dedicated to a window
  142. and registers the new special window/buffer at ECB.
  143. <br><pre>(defecb-window-dedicator ecb-examples-set-bufferinfo-buffer
  144. ecb-examples-bufferinfo-buffer-name
  145. "Set the buffer in the current window to the bufferinfo-buffer
  146. and make this window dedicated for this buffer."
  147. (switch-to-buffer (get-buffer-create
  148. ecb-examples-bufferinfo-buffer-name))
  149. (setq buffer-read-only t))
  150. </pre>
  151. <p>This is all what we need for the special bufferinfo buffer. We have
  152. demonstrated already three of the important functions/macros of the
  153. layout-engine API of ECB: <code>ecb-with-readonly-buffer</code>,
  154. <code>ecb-do-if-buffer-visible-in-ecb-frame</code> and
  155. <code>defecb-window-dedicator</code> (see <a href="The-layout-engine-API.html#The%20layout-engine%20API">The layout-engine API</a>.
  156. Especially the second macro is strongly recommended for programming
  157. good synchronizing functions which do not waste CPU!
  158. <h5>The action buffer of the example</h5>
  159. <p>The name of the action-buffer:
  160. <br><pre>(defconst ecb-examples-action-buffer-name " *ECB action buffer*")
  161. </pre>
  162. <p>Two helper functions for creating a readonly action-buffer with a
  163. special local key-map for the middle-mouse-button and two buttons
  164. [prior] and [next]:
  165. <br><pre>(defun ecb-examples-insert-text-in-action-buffer (text)
  166. (let ((p (point)))
  167. (insert text)
  168. (put-text-property p (+ p (length text)) 'mouse-face
  169. 'highlight)))
  170. (defun ecb-examples-action-buffer-create ()
  171. (save-excursion
  172. (if (get-buffer ecb-examples-action-buffer-name)
  173. (get-buffer ecb-examples-action-buffer-name)
  174. (set-buffer (get-buffer-create
  175. ecb-examples-action-buffer-name))
  176. ;; we setup a local key-map and bind middle-mouse-button
  177. ;; see ecb-examples.el for the full code
  178. ;; insert the action buttons [prior] and [next] and
  179. ;; make it read-only
  180. (ecb-with-readonly-buffer (current-buffer)
  181. (erase-buffer)
  182. (ecb-examples-insert-text-in-action-buffer "[prior]")
  183. ;; analogous for the [next] button
  184. )
  185. (current-buffer))))
  186. </pre>
  187. <p>The function which performs the actions in the action-buffer if
  188. clicked with the middle-mouse button onto a button [next] or [prior].
  189. <br><pre>(defun ecb-examples-action-buffer-clicked (e)
  190. (interactive "e")
  191. (mouse-set-point e)
  192. (let ((line (buffer-substring (ecb-line-beginning-pos)
  193. (ecb-line-end-pos))))
  194. (cond ((string-match "prior" line)
  195. (ecb-select-edit-window)
  196. (call-interactively 'scroll-down))
  197. ((string-match "next" line)
  198. ;; analogous for [next]
  199. ))))
  200. </pre>
  201. <p>Two conveniance-commands for the user:
  202. <br><pre>(defun ecb-maximize-action-window ()
  203. "Maximize the action-window.
  204. I.e. delete all other ECB-windows, so only one ECB-window and the
  205. edit-window\(s) are visible \(and maybe a compile-window). Works
  206. also if the ECB-analyse-window is not visible in current layout."
  207. (interactive)
  208. (ecb-display-one-ecb-buffer ecb-examples-action-buffer-name))
  209. (defun ecb-goto-action-window ()
  210. "Make the action-window the current window."
  211. (interactive)
  212. (ecb-goto-ecb-window ecb-examples-action-buffer-name))
  213. </pre>
  214. <p>The function which makes the action-buffer dedicated to a window and
  215. registers it at ECB.
  216. <br><pre>(defecb-window-dedicator ecb-examples-set-action-buffer
  217. (buffer-name (ecb-examples-action-buffer-create))
  218. "Set the buffer in the current window to the action-buffer
  219. and make this window dedicated for this buffer."
  220. (switch-to-buffer (buffer-name (ecb-examples-action-buffer-create))))
  221. </pre>
  222. <p>We do not need more code for the action buffer. All of the code is
  223. standard emacs-lisp which would also needed if used without ECB. You
  224. see that you can use any arbitrary code as second argument for
  225. <code>defecb-window-dedicator</code> as long it returns a buffer-name.
  226. <h5>Adding the bufferinfo- and action-buffer to a new layout</h5>
  227. <p>Now we add the bufferinfo- and the action-buffer to a new layout of
  228. type top with name "example-layout1":
  229. <br><pre>(ecb-layout-define "example-layout1" top
  230. ;; dedicating the bufferinfo window to the bufferinfo-buffer
  231. (ecb-examples-set-bufferinfo-buffer)
  232. ;; creating the action-window
  233. (ecb-split-hor 0.75)
  234. ;; dedicate the action window to the action-buffer
  235. (ecb-examples-set-action-buffer)
  236. ;; select the edit-window
  237. (select-window (next-window)))
  238. </pre>
  239. <p>This all what we need to define the new layout. See <a href="Programming-a-new-layout.html#Programming%20a%20new%20layout">Programming a new layout</a> for more details of the pure layout-programming task.
  240. <h5>Synchronizing the bufferinfo-buffer automatically</h5>
  241. <p>The last thing we have to do is to synchronize the bufferinfo-buffer
  242. with current edit-window. We do this by adding
  243. <code>ecb-examples-bufferinfo-sync</code> to the hook
  244. <code>ecb-current-buffer-sync-hook'</code> (The file <code>ecb-examples.el</code>
  245. shows a smarter mechanism for (de)activating the new layout and the
  246. synchronization but this works also very well).
  247. <br><pre>(add-hook 'ecb-current-buffer-sync-hook 'ecb-examples-bufferinfo-sync)
  248. </pre>
  249. <h5>Activating and deactivating new layouts</h5>
  250. <p>Because a set of new special windows integrated in a new layout is
  251. often just the GUI of a complete tool (like a graphical debugger) we
  252. demonstrate here the complete activation and deactivation of such a
  253. tool or at least of the tool-GUI. We decide that the GUI of our
  254. example "tool" needs a compile-window with height 5 lines and the
  255. height of the special windows "row" on top should be exactly 6 lines
  256. (normally width and height of the special windows should be a fraction
  257. of the frame, but here we use 6 lines<a rel=footnote href="#fn-2"><sup>2</sup></a>
  258. <p>Here comes the (de)activation code.
  259. <p>The code for saving and restoring the state before activation (the
  260. full code is available in <code>ecb-examples.el</code>:
  261. <br><pre>(defun ecb-examples-preactivation-state(action)
  262. (cond ((equal action 'save)
  263. ;; code for saving the state
  264. )
  265. ((equal action 'restore)
  266. ;; code for restoring the state
  267. )))
  268. </pre>
  269. <p>The following function activates the GUI of our example tool:
  270. <br><pre>(defun ecb-examples-activate ()
  271. (interactive)
  272. ;; activating the synchronization of the bufferinfo-window
  273. (add-hook 'ecb-current-buffer-sync-hook
  274. 'ecb-examples-bufferinfo-sync)
  275. ;; saving the state
  276. (ecb-examples-preactivation-state 'save)
  277. ;; switch to our preferred layout
  278. (setq ecb-windows-height 6)
  279. (setq ecb-compile-window-height 5)
  280. (ecb-layout-switch "example-layout1"))
  281. </pre>
  282. <p>This function deactivates the GUI of our example-tool and restores the
  283. state as before activation:
  284. <br><pre>(defun ecb-examples-deactivate ()
  285. (interactive)
  286. (remove-hook 'ecb-current-buffer-sync-hook
  287. 'ecb-examples-bufferinfo-sync)
  288. (ecb-examples-preactivation-state 'restore)
  289. (ecb-layout-switch ecb-layout-name))
  290. </pre>
  291. <p>Now we have all code for the new layout and the new layout-buffers.
  292. The example is ready for use; just load <code>ecb-examples.el</code> (s.a.).
  293. <hr><h4>Footnotes</h4>
  294. <ol type="1">
  295. <li><a name="fn-1"></a>
  296. <p>JDEE is
  297. available at
  298. <a href="http://jdee.sunsite.dk/">http://jdee.sunsite.dk/</a>
  299. </p>
  300. <li><a name="fn-2"></a>
  301. <p>You can change the code
  302. in the file <code>ecb-examples.el</code> to use a frame-fraction of 0.2
  303. instead of 6 hard lines, just try it!</p>
  304. </ol><hr>
  305. </body></html>