Add "Package:" file headers to denote built-in packages.
[bpt/emacs.git] / lisp / progmodes / ada-prj.el
CommitLineData
d759dcce 1;;; ada-prj.el --- GUI editing of project files for the ada-mode
d41832c5 2
4e643dd2 3;; Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
114f9c96 4;; 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
d41832c5
GM
5
6;; Author: Emmanuel Briot <briot@gnat.com>
d759dcce 7;; Maintainer: Stephen Leake <stephen_leake@stephe-leake.org>
d41832c5 8;; Keywords: languages, ada, project file
bd78fa1d 9;; Package: ada-mode
d41832c5 10
874d7995 11;; This file is part of GNU Emacs.
d41832c5 12
b1fc2b50 13;; GNU Emacs is free software: you can redistribute it and/or modify
d41832c5 14;; it under the terms of the GNU General Public License as published by
b1fc2b50
GM
15;; the Free Software Foundation, either version 3 of the License, or
16;; (at your option) any later version.
d41832c5 17
2be7dabc 18;; GNU Emacs is distributed in the hope that it will be useful,
d41832c5
GM
19;; but WITHOUT ANY WARRANTY; without even the implied warranty of
20;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21;; GNU General Public License for more details.
22
23;; You should have received a copy of the GNU General Public License
b1fc2b50 24;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>.
d41832c5 25
3afbc435
PJ
26;;; Commentary:
27
d41832c5
GM
28;;; This package provides a set of functions to easily edit the project
29;;; files used by the ada-mode.
c6fa13e3
GM
30;;; The only function publicly available here is `ada-customize'.
31;;; See the documentation of the Ada mode for more information on the project
32;;; files.
33;;; Internally, a project file is represented as a property list, with each
34;;; field of the project file matching one property of the list.
d41832c5 35
d759dcce
JB
36
37;;; History:
38;;
39
3afbc435 40;;; Code:
d41832c5
GM
41
42
43;; ----- Requirements -----------------------------------------------------
44
45(require 'cus-edit)
ce20e709 46(require 'ada-xref)
d41832c5 47
6f9a2614
JB
48(eval-when-compile
49 (require 'ada-mode))
50
d41832c5 51;; ----- Buffer local variables -------------------------------------------
d41832c5 52
c6fa13e3 53(defvar ada-prj-current-values nil
6f9a2614 54 "Hold the current value of the fields, This is a property list.")
c6fa13e3
GM
55(make-variable-buffer-local 'ada-prj-current-values)
56
57(defvar ada-prj-default-values nil
6f9a2614 58 "Hold the default value for the fields, This is a property list.")
c6fa13e3
GM
59(make-variable-buffer-local 'ada-prj-default-values)
60
61(defvar ada-prj-ada-buffer nil
62 "Indicates what Ada source file was being edited.")
63
da2a1edf
SM
64(defvar ada-old-cross-prefix nil
65 "The cross-prefix associated with the currently loaded runtime library.")
66
c6fa13e3
GM
67
68;; ----- Functions --------------------------------------------------------
69
70(defun ada-prj-new ()
d759dcce 71 "Open a new project file."
d41832c5 72 (interactive)
c6fa13e3 73 (let* ((prj
da2a1edf
SM
74 (if (and ada-prj-default-project-file
75 (not (string= ada-prj-default-project-file "")))
76 ada-prj-default-project-file
c6fa13e3
GM
77 "default.adp"))
78 (filename (read-file-name "Project file: "
79 (if prj "" nil)
80 nil
81 nil
82 prj)))
83 (if (not (string= (file-name-extension filename t) ".adp"))
84 (error "File name extension for project files must be .adp"))
a1506d29 85
c6fa13e3
GM
86 (ada-customize nil filename)))
87
88(defun ada-prj-edit ()
89 "Editing the project file associated with the current Ada buffer.
32b1a27f 90If there is none, opens a new project file."
c6fa13e3 91 (interactive)
61c08d00
SM
92 (if ada-prj-default-project-file
93 (ada-customize)
94 (ada-prj-new)))
d41832c5 95
ce20e709 96(defun ada-prj-initialize-values (symbol ada-buffer filename)
c6fa13e3 97 "Set SYMBOL to the property list of the project file FILENAME.
32b1a27f
JB
98If FILENAME is null, read the file associated with ADA-BUFFER.
99If no project file is found, return the default values."
d759dcce 100;; FIXME: rationalize arguments; make ada-buffer optional?
ce20e709
JB
101 (if (and filename
102 (not (string= filename ""))
103 (assoc filename ada-xref-project-files))
104 (set symbol (copy-sequence (cdr (assoc filename ada-xref-project-files))))
a1506d29 105
ce20e709
JB
106 ;; Set default values (except for the file name if this was given
107 ;; in the buffer
ff6d2a9e 108 (set symbol (ada-default-prj-properties))
ce20e709
JB
109 (if (and filename (not (string= filename "")))
110 (set symbol (plist-put (eval symbol) 'filename filename)))
111 ))
a1506d29 112
d41832c5 113
c6fa13e3 114(defun ada-prj-save-specific-option (field)
d759dcce 115 "Return the string to print in the project file to save FIELD.
32b1a27f 116If the current value of FIELD is the default value, return an empty string."
c6fa13e3
GM
117 (if (string= (plist-get ada-prj-current-values field)
118 (plist-get ada-prj-default-values field))
119 ""
120 (concat (symbol-name field)
121 "=" (plist-get ada-prj-current-values field) "\n")))
d41832c5
GM
122
123(defun ada-prj-save ()
c6fa13e3 124 "Save the edited project file."
d41832c5 125 (interactive)
d5875b25
JB
126 (let ((file-name (or (plist-get ada-prj-current-values 'filename)
127 (read-file-name "Save project as: ")))
c6fa13e3
GM
128 output)
129 (set 'output
130 (concat
131
132 ;; Save the fields that do not depend on the current buffer
133 ;; only if they are different from the default value
a1506d29 134
c6fa13e3
GM
135 (ada-prj-save-specific-option 'comp_opt)
136 (ada-prj-save-specific-option 'bind_opt)
137 (ada-prj-save-specific-option 'link_opt)
138 (ada-prj-save-specific-option 'gnatmake_opt)
da2a1edf 139 (ada-prj-save-specific-option 'gnatfind_opt)
c6fa13e3
GM
140 (ada-prj-save-specific-option 'cross_prefix)
141 (ada-prj-save-specific-option 'remote_machine)
c6fa13e3
GM
142 (ada-prj-save-specific-option 'debug_cmd)
143
144 ;; Always save the fields that depend on the current buffer
da2a1edf 145 "main=" (plist-get ada-prj-current-values 'main) "\n"
da2a1edf
SM
146 "build_dir=" (plist-get ada-prj-current-values 'build_dir) "\n"
147 (ada-prj-set-list "check_cmd"
148 (plist-get ada-prj-current-values 'check_cmd)) "\n"
149 (ada-prj-set-list "make_cmd"
150 (plist-get ada-prj-current-values 'make_cmd)) "\n"
151 (ada-prj-set-list "comp_cmd"
152 (plist-get ada-prj-current-values 'comp_cmd)) "\n"
153 (ada-prj-set-list "run_cmd"
154 (plist-get ada-prj-current-values 'run_cmd)) "\n"
c6fa13e3 155 (ada-prj-set-list "src_dir"
da2a1edf
SM
156 (plist-get ada-prj-current-values 'src_dir)
157 t) "\n"
c6fa13e3 158 (ada-prj-set-list "obj_dir"
da2a1edf
SM
159 (plist-get ada-prj-current-values 'obj_dir)
160 t) "\n"
161 (ada-prj-set-list "debug_pre_cmd"
162 (plist-get ada-prj-current-values 'debug_pre_cmd))
163 "\n"
164 (ada-prj-set-list "debug_post_cmd"
165 (plist-get ada-prj-current-values 'debug_post_cmd))
166 "\n"
c6fa13e3 167 ))
a1506d29 168
d41832c5
GM
169 (find-file file-name)
170 (erase-buffer)
171 (insert output)
172 (save-buffer)
173 ;; kill the project buffer
174 (kill-buffer nil)
175
176 ;; kill the editor buffer
d759dcce 177 (kill-buffer "*Edit Ada Mode Project*")
d41832c5 178
da2a1edf
SM
179 ;; automatically set the new project file as the active one
180 (set 'ada-prj-default-project-file file-name)
d41832c5 181
c6fa13e3
GM
182 ;; force Emacs to reread the project files
183 (ada-reread-prj-file file-name)
d41832c5
GM
184 )
185 )
186
c6fa13e3 187(defun ada-prj-load-from-file (symbol)
32b1a27f
JB
188 "Load SYMBOL value from file.
189One item per line should be found in the file."
c6fa13e3
GM
190 (save-excursion
191 (let ((file (read-file-name "File name: " nil nil t))
192 (buffer (current-buffer))
193 line
194 list)
195 (find-file file)
196 (widen)
197 (goto-char (point-min))
198 (while (not (eobp))
199 (set 'line (buffer-substring-no-properties
200 (point) (save-excursion (end-of-line) (point))))
201 (add-to-list 'list line)
202 (forward-line 1)
203 )
204 (kill-buffer nil)
205 (set-buffer buffer)
206 (set 'ada-prj-current-values
207 (plist-put ada-prj-current-values
208 symbol
209 (append (plist-get ada-prj-current-values symbol)
210 (reverse list))))
211 )
212 (ada-prj-display-page 2)
213 ))
214
215(defun ada-prj-subdirs-of (dir)
d759dcce 216 "Return a list of all the subdirectories of DIR, recursively."
c6fa13e3
GM
217 (let ((subdirs (directory-files dir t "^[^.].*"))
218 (dirlist (list dir)))
219 (while subdirs
220 (if (file-directory-p (car subdirs))
221 (let ((sub (ada-prj-subdirs-of (car subdirs))))
222 (if sub
223 (set 'dirlist (append sub dirlist)))))
224 (set 'subdirs (cdr subdirs)))
225 dirlist))
226
227(defun ada-prj-load-directory (field &optional file-name)
d759dcce 228 "Append to FIELD in the current project the subdirectories of FILE-NAME.
c6fa13e3 229If FILE-NAME is nil, ask the user for the name."
61c08d00
SM
230
231 ;; Do not use an external dialog for this, since it wouldn't allow
232 ;; the user to select a directory
233 (let ((use-dialog-box nil))
234 (unless file-name
235 (set 'file-name (read-file-name "Root directory: " nil nil t))))
c6fa13e3
GM
236
237 (set 'ada-prj-current-values
238 (plist-put ada-prj-current-values
239 field
240 (append (plist-get ada-prj-current-values field)
241 (reverse (ada-prj-subdirs-of
242 (expand-file-name file-name))))))
243 (ada-prj-display-page 2))
244
245(defun ada-prj-display-page (tab-num)
d759dcce 246 "Display page TAB-NUM in the notebook.
c6fa13e3
GM
247The current buffer must be the project editing buffer."
248
249 (let ((inhibit-read-only t))
250 (erase-buffer))
251
da2a1edf 252 ;; Widget support in Emacs 21 requires that we clear the buffer first
6f9a2614 253 (if (and (not (featurep 'xemacs)) (>= emacs-major-version 21))
da2a1edf
SM
254 (progn
255 (setq widget-field-new nil
256 widget-field-list nil)
88f43129
JB
257 (mapc (lambda (x) (delete-overlay x)) (car (overlay-lists)))
258 (mapc (lambda (x) (delete-overlay x)) (cdr (overlay-lists)))))
a1506d29 259
c6fa13e3 260 ;; Display the tabs
a1506d29 261
d759dcce 262 (widget-insert "\n Project configuration.\n
da2a1edf 263 ___________ ____________ ____________ ____________ ____________\n / ")
c6fa13e3
GM
264 (widget-create 'push-button :notify
265 (lambda (&rest dummy) (ada-prj-display-page 1)) "General")
266 (widget-insert " \\ / ")
267 (widget-create 'push-button :notify
268 (lambda (&rest dummy) (ada-prj-display-page 2)) "Paths")
269 (widget-insert " \\ / ")
270 (widget-create 'push-button :notify
271 (lambda (&rest dummy) (ada-prj-display-page 3)) "Switches")
272 (widget-insert " \\ / ")
273 (widget-create 'push-button :notify
274 (lambda (&rest dummy) (ada-prj-display-page 4)) "Ada Menu")
da2a1edf
SM
275 (widget-insert " \\ / ")
276 (widget-create 'push-button :notify
277 (lambda (&rest dummy) (ada-prj-display-page 5)) "Debugger")
c6fa13e3
GM
278 (widget-insert " \\\n")
279
280 ;; Display the currently selected page
a1506d29 281
c6fa13e3 282 (cond
a1506d29 283
c6fa13e3
GM
284 ;;
285 ;; First page (General)
286 ;;
287 ((= tab-num 1)
da2a1edf 288 (widget-insert "/ \\/______________\\/______________\\/______________\\/______________\\\n")
c6fa13e3
GM
289
290 (widget-insert "Project file name:\n")
291 (widget-insert (plist-get ada-prj-current-values 'filename))
292 (widget-insert "\n\n")
d5875b25
JB
293 (ada-prj-field 'casing "Casing Exceptions"
294"List of files that contain casing exception
295dictionaries. All these files contain one
296identifier per line, with a special casing.
297The first file has the highest priority."
298 t nil
299 (mapconcat (lambda(x)
300 (concat " " x))
301 (ada-xref-get-project-field 'casing)
302 "\n")
303 )
c6fa13e3
GM
304 (ada-prj-field 'main "Executable file name"
305"Name of the executable generated when you
306compile your application. This should include
307the full directory name, using ${build_dir} if
308you wish.")
c6fa13e3
GM
309 (ada-prj-field 'build_dir "Build directory"
310 "Reference directory for relative paths in
311src_dir and obj_dir below. This is also the directory
312where the compilation is done.")
313 (ada-prj-field 'remote_machine "Name of the remote machine (if any)"
314"If you want to remotely compile, debug and
315run your application, specify the name of a
316remote machine here. This capability requires
317the 'rsh' protocol on the remote machine.")
318 (ada-prj-field 'cross_prefix "Prefix used in for the cross tool chain"
319"When working on multiple cross targets, it is
320most convenient to specify the prefix of the
321tool chain here. For instance, on PowerPc
322vxworks, you would enter 'powerpc-wrs-vxworks-'.
323To use JGNAT, enter 'j'.")
324 )
d41832c5 325
a1506d29 326
c6fa13e3
GM
327 ;;
328 ;; Second page (Paths)
329 ;;
330 ((= tab-num 2)
da2a1edf
SM
331 (if (not (equal (plist-get ada-prj-current-values 'cross_prefix)
332 ada-old-cross-prefix))
333 (progn
334 (setq ada-old-cross-prefix
335 (plist-get ada-prj-current-values 'cross_prefix))
336 (ada-initialize-runtime-library ada-old-cross-prefix)))
337
a1506d29 338
da2a1edf 339 (widget-insert "/_____________\\/ \\/______________\\/______________\\/______________\\\n")
c6fa13e3
GM
340 (ada-prj-field 'src_dir "Source directories"
341"Enter the list of directories where your Ada
342sources can be found. These directories will be
343used for the cross-references and for the default
344compilation commands.
345Note that src_dir includes both the build directory
346and the standard runtime."
347 t t
348 (mapconcat (lambda(x)
d759dcce
JB
349 (concat " " x))
350 ada-xref-runtime-library-specs-path
351 "\n")
c6fa13e3
GM
352 )
353 (widget-insert "\n\n")
a1506d29 354
c6fa13e3
GM
355 (ada-prj-field 'obj_dir "Object directories"
356"Enter the list of directories where the GNAT
357library files (ALI files) can be found. These
358files are used for cross-references and by the
359gnatmake command.
360Note that obj_dir includes both the build directory
361and the standard runtime."
362 t t
363 (mapconcat (lambda(x)
d759dcce
JB
364 (concat " " x))
365 ada-xref-runtime-library-ali-path
366 "\n")
c6fa13e3
GM
367 )
368 (widget-insert "\n\n")
369 )
d41832c5 370
c6fa13e3
GM
371 ;;
372 ;; Third page (Switches)
373 ;;
374 ((= tab-num 3)
da2a1edf 375 (widget-insert "/_____________\\/______________\\/ \\/______________\\/______________\\\n")
c6fa13e3
GM
376 (ada-prj-field 'comp_opt "Switches for the compiler"
377"These switches are used in the default
378compilation commands, both for compiling a
379single file and rebuilding the whole project")
380 (ada-prj-field 'bind_opt "Switches for the binder"
381"These switches are used in the default build
382command and are passed to the binder")
383 (ada-prj-field 'link_opt "Switches for the linker"
384"These switches are used in the default build
385command and are passed to the linker")
386 (ada-prj-field 'gnatmake_opt "Switches for gnatmake"
387"These switches are used in the default gnatmake
a1506d29 388command.")
da2a1edf
SM
389 (ada-prj-field 'gnatfind_opt "Switches for gnatfind"
390"The command gnatfind is run every time the Ada/Goto/List_References menu.
391You should for instance add -a if you are working in an environment
392where most ALI files are write-protected, since otherwise they get
393ignored by gnatfind and you don't see the references within.")
c6fa13e3 394 )
d41832c5 395
c6fa13e3
GM
396 ;;
397 ;; Fourth page
398 ;;
399 ((= tab-num 4)
da2a1edf 400 (widget-insert "/_____________\\/______________\\/______________\\/ \\/______________\\\n")
c6fa13e3 401 (widget-insert
32b1a27f 402"All the fields below can use variable substitution. The syntax is ${name},
da2a1edf
SM
403where name is the name that appears after the Help buttons in this buffer. As
404a special case, ${current} is replaced with the name of the file currently
405edited, with directory name but no extension, whereas ${full_current} is
406replaced with the name of the current file with directory name and
407extension.\n")
c6fa13e3 408 (widget-insert
da2a1edf
SM
409"The environment variables ADA_INCLUDE_PATH and ADA_OBJECTS_PATH are set to
410${src_dir} and ${obj_dir} before running the compilation commands, so that you
411don't need to specify the -aI and -aO switches on the command line\n")
c6fa13e3 412 (widget-insert
da2a1edf
SM
413"You can reference any environment variable using the same ${...} syntax as
414above, and put the name of the variable between the quotes.\n\n")
c6fa13e3
GM
415 (ada-prj-field 'check_cmd
416 "Check syntax of a single file (menu Ada->Check File)"
417"This command is run to check the syntax and semantics of a file.
da2a1edf 418The file name is added at the end of this command." t)
c6fa13e3
GM
419 (ada-prj-field 'comp_cmd
420 "Compiling a single file (menu Ada->Compile File)"
421"This command is run when the recompilation
422of a single file is needed. The file name is
da2a1edf 423added at the end of this command." t)
c6fa13e3
GM
424 (ada-prj-field 'make_cmd "Rebuilding the whole project (menu Ada->Build)"
425"This command is run when you want to rebuild
426your whole application. It is never issues
427automatically and you will need to ask for it.
428If remote_machine has been set, this command
da2a1edf 429will be executed on the remote machine." t)
c6fa13e3
GM
430 (ada-prj-field 'run_cmd "Running the application (menu Ada->Run)"
431"This command specifies how to run the
432application, including any switch you need to
433specify. If remote_machine has been set, this
da2a1edf
SM
434command will be executed on the remote host." t)
435 )
436
437 ;;
438 ;; Fifth page
439 ;;
440 ((= tab-num 5)
441 (widget-insert "/_____________\\/______________\\/______________\\/______________\\/ \\\n")
442 (ada-prj-field 'debug_pre_cmd "Commands to execute before launching the
443debugger"
444"The following commands are executed one after the other before starting
445the debugger. These can be used to set up your environment." t)
a1506d29 446
c6fa13e3
GM
447 (ada-prj-field 'debug_cmd "Debugging the application"
448"Specifies how to debug the application, possibly
449remotely if remote_machine has been set. We
450recommend the following debuggers:
451 > gdb
da2a1edf 452 > gvd --tty
c6fa13e3 453 > ddd --tty -fullname -toolbar")
da2a1edf
SM
454
455 (ada-prj-field 'debug_post_cmd "Commands to execute in the debugger"
456"The following commands are executed one in the debugger once it has been
457started. These can be used to initialize the debugger, for instance to
458connect to the target when working with cross-environments" t)
c6fa13e3 459 )
a1506d29 460
c6fa13e3
GM
461 )
462
463
464 (widget-insert "______________________________________________________________________\n\n ")
465 (widget-create 'push-button
466 :notify (lambda (&rest ignore)
ff6d2a9e 467 (setq ada-prj-current-values (ada-default-prj-properties))
c6fa13e3
GM
468 (ada-prj-display-page 1))
469 "Reset to Default Values")
470 (widget-insert " ")
471 (widget-create 'push-button :notify (lambda (&rest ignore) (kill-buffer nil))
472 "Cancel")
473 (widget-insert " ")
474 (widget-create 'push-button :notify (lambda (&rest ignore) (ada-prj-save))
475 "Save")
476 (widget-insert "\n\n")
477
478 (widget-setup)
300ee850
RS
479 (with-no-warnings
480 (beginning-of-buffer))
c6fa13e3 481 )
d41832c5 482
d41832c5 483
c6fa13e3
GM
484(defun ada-customize (&optional new-file filename)
485 "Edit the project file associated with the current buffer.
486If there is none or NEW-FILE is non-nil, make a new one.
487If FILENAME is given, edit that file."
488 (interactive)
d41832c5 489
c6fa13e3
GM
490 (let ((ada-buffer (current-buffer))
491 (inhibit-read-only t))
d41832c5 492
61c08d00
SM
493 ;; We can only edit interactively the standard ada-mode project files. If
494 ;; the user is using other formats for the project file (through hooks in
495 ;; `ada-load-project-hook', we simply edit the file
a1506d29 496
61c08d00
SM
497 (if (and (not new-file)
498 (or ada-prj-default-project-file filename)
499 (string= (file-name-extension
500 (or filename ada-prj-default-project-file))
501 "gpr"))
502 (progn
503 (find-file ada-prj-default-project-file)
504 (add-hook 'after-save-hook 'ada-reread-prj-file t t)
505 )
da2a1edf 506
ce20e709
JB
507 (if filename
508 (ada-reread-prj-file filename)
509 (if (not (string= ada-prj-default-project-file ""))
510 (ada-reread-prj-file ada-prj-default-project-file)
511 (ada-reread-prj-file)))
512
d759dcce 513 (switch-to-buffer "*Edit Ada Mode Project*")
a1506d29 514
ce20e709
JB
515 (ada-prj-initialize-values 'ada-prj-current-values
516 ada-buffer
517 ada-prj-default-project-file)
a1506d29 518
61c08d00 519 (set (make-local-variable 'ada-prj-ada-buffer) ada-buffer)
a1506d29 520
61c08d00
SM
521 (use-local-map (copy-keymap custom-mode-map))
522 (local-set-key "\C-x\C-s" 'ada-prj-save)
a1506d29 523
61c08d00
SM
524 (make-local-variable 'widget-keymap)
525 (define-key widget-keymap "\C-x\C-s" 'ada-prj-save)
a1506d29 526
61c08d00
SM
527 (set (make-local-variable 'ada-old-cross-prefix)
528 (ada-xref-get-project-field 'cross-prefix))
a1506d29 529
61c08d00
SM
530 (ada-prj-display-page 1)
531 )))
d41832c5
GM
532
533;; ---------------- Utilities --------------------------------
534
da2a1edf 535(defun ada-prj-set-list (string ada-list &optional is-directory)
d759dcce
JB
536 "Prepend STRING to strings in ADA-LIST, return new-line separated string.
537If IS-DIRECTORY is non-nil, each element of ADA-LIST is explicitly
538converted to a directory name."
da2a1edf
SM
539
540 (mapconcat (lambda (x) (concat string "="
541 (if is-directory
542 (file-name-as-directory x)
543 x)))
d759dcce 544 ada-list "\n"))
d41832c5 545
c6fa13e3 546
c6fa13e3 547(defun ada-prj-field-modified (widget &rest dummy)
d759dcce
JB
548 "Callback for modification of WIDGET.
549Remaining args DUMMY are ignored.
550Save the change in `ada-prj-current-values' so that selecting
551another page and coming back keeps the new value."
c6fa13e3
GM
552 (set 'ada-prj-current-values
553 (plist-put ada-prj-current-values
da2a1edf 554 (widget-get widget ':prj-field)
c6fa13e3
GM
555 (widget-value widget))))
556
557(defun ada-prj-display-help (widget widget-modified event)
d759dcce
JB
558 "Callback for help button in WIDGET.
559Parameters WIDGET-MODIFIED, EVENT match :notify for the widget."
c6fa13e3
GM
560 (let ((text (widget-get widget 'prj-help)))
561 (if event
562 ;; If we have a mouse-event, popup a menu
563 (widget-choose "Help"
564 (mapcar (lambda (a) (cons a t))
565 (split-string text "\n"))
566 event)
567 ;; Else display the help string just before the next group of
568 ;; variables
569 (momentary-string-display
570 (concat "*****Help*****\n" text "\n**************\n")
571 (save-excursion (forward-line) (beginning-of-line) (point)))
572 )))
573
574(defun ada-prj-show-value (widget widget-modified event)
d759dcce
JB
575 "Show the current field value in WIDGET.
576Parameters WIDGET-MODIFIED, EVENT match :notify for the widget."
da2a1edf
SM
577 (let* ((field (widget-get widget ':prj-field))
578 (value (plist-get ada-prj-current-values field))
579 (inhibit-read-only t)
580 w)
c6fa13e3
GM
581
582 ;; If the other widget is already visible, delete it
583 (if (widget-get widget 'prj-other-widget)
584 (progn
585 (widget-delete (widget-get widget 'prj-other-widget))
586 (widget-put widget 'prj-other-widget nil)
da2a1edf 587 (widget-put widget ':prj-field field)
c6fa13e3
GM
588 (widget-default-value-set widget "Show Value")
589 )
590
591 ;; Else create it
592 (save-excursion
593 (mouse-set-point event)
594 (forward-line 1)
595 (beginning-of-line)
da2a1edf
SM
596 (setq w (widget-create 'editable-list
597 :entry-format "%i%d %v"
598 :notify 'ada-prj-field-modified
599 :help-echo (widget-get widget 'prj-help)
600 :value value
601 (list 'editable-field :keymap widget-keymap)))
602 (widget-put widget 'prj-other-widget w)
603 (widget-put w ':prj-field field)
604 (widget-put widget ':prj-field field)
c6fa13e3
GM
605 (widget-default-value-set widget "Hide Value")
606 )
607 )
608 (widget-setup)
609 ))
610
611(defun ada-prj-field (field text help-text &optional is-list is-paths after-text)
612 "Create a widget to edit FIELD in the current buffer.
613TEXT is a short explanation of what the field means, whereas HELP-TEXT
614is the text displayed when the user pressed the help button.
32b1a27f 615If IS-LIST is non-nil, the field contains a list. Otherwise, it contains
c6fa13e3 616a single string.
32b1a27f 617If IS-PATHS is true, some special buttons are added to load paths,...
c6fa13e3
GM
618AFTER-TEXT is inserted just after the widget."
619 (let ((value (plist-get ada-prj-current-values field))
620 (inhibit-read-only t)
621 widget)
622 (unless value
623 (set 'value
624 (if is-list '() "")))
625 (widget-insert text)
626 (widget-insert ":")
627 (move-to-column 54 t)
628 (widget-put (widget-create 'push-button
629 :notify 'ada-prj-display-help
630 "Help")
631 'prj-help
632 help-text)
633 (widget-insert (concat " (" (symbol-name field) ")\n"))
634 (if is-paths
635 (progn
636 (widget-create 'push-button
637 :notify
638 (list 'lambda '(&rest dummy) '(interactive)
639 (list 'ada-prj-load-from-file
640 (list 'quote field)))
641 "Load From File")
642 (widget-insert " ")
643 (widget-create 'push-button
644 :notify
645 (list 'lambda '(&rest dummy) '(interactive)
646 (list 'ada-prj-load-directory
647 (list 'quote field)))
648 "Load Recursive Directory")
649 (widget-insert "\n ${build_dir}\n")))
da2a1edf 650
c6fa13e3
GM
651 (set 'widget
652 (if is-list
653 (if (< (length value) 15)
654 (widget-create 'editable-list
655 :entry-format "%i%d %v"
656 :notify 'ada-prj-field-modified
657 :help-echo help-text
658 :value value
659 (list 'editable-field :keymap widget-keymap))
da2a1edf 660
c6fa13e3
GM
661 (let ((w (widget-create 'push-button
662 :notify 'ada-prj-show-value
663 "Show value")))
664 (widget-insert "\n")
c6fa13e3
GM
665 (widget-put w 'prj-help help-text)
666 (widget-put w 'prj-other-widget nil)
667 w)
668 )
669 (widget-create 'editable-field
670 :format "%v"
671 :notify 'ada-prj-field-modified
672 :help-echo help-text
673 :keymap widget-keymap
674 value)))
da2a1edf 675 (widget-put widget ':prj-field field)
c6fa13e3
GM
676 (if after-text
677 (widget-insert after-text))
678 (widget-insert "\n")
679 ))
d41832c5 680
d41832c5 681
d41832c5 682(provide 'ada-prj)
3afbc435 683
cbee283d 684;; arch-tag: 65978c77-816e-49c6-896e-6905605d1b4c
3afbc435 685;;; ada-prj.el ends here