Merged in changes from CVS HEAD
[bpt/emacs.git] / lisp / progmodes / ada-prj.el
CommitLineData
3afbc435 1;;; ada-prj.el --- easy editing of project files for the ada-mode
d41832c5 2
ce20e709 3;; Copyright (C) 1998, 99, 2000-2003 Free Software Foundation, Inc.
d41832c5
GM
4
5;; Author: Emmanuel Briot <briot@gnat.com>
da1492a4 6;; Ada Core Technologies's version: $Revision: 1.13 $
d41832c5
GM
7;; Keywords: languages, ada, project file
8
874d7995 9;; This file is part of GNU Emacs.
d41832c5 10
2be7dabc 11;; GNU Emacs is free software; you can redistribute it and/or modify
d41832c5
GM
12;; it under the terms of the GNU General Public License as published by
13;; the Free Software Foundation; either version 2, or (at your option)
14;; any later version.
15
2be7dabc 16;; GNU Emacs is distributed in the hope that it will be useful,
d41832c5
GM
17;; but WITHOUT ANY WARRANTY; without even the implied warranty of
18;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19;; GNU General Public License for more details.
20
21;; You should have received a copy of the GNU General Public License
2be7dabc
GM
22;; along with GNU Emacs; see the file COPYING. If not, write to the
23;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
24;; Boston, MA 02111-1307, USA.
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
3afbc435 36;;; Code:
d41832c5
GM
37
38
39;; ----- Requirements -----------------------------------------------------
40
41(require 'cus-edit)
ce20e709 42(require 'ada-xref)
d41832c5 43
6f9a2614
JB
44(eval-when-compile
45 (require 'ada-mode))
46
d41832c5 47;; ----- Buffer local variables -------------------------------------------
d41832c5 48
c6fa13e3 49(defvar ada-prj-current-values nil
6f9a2614 50 "Hold the current value of the fields, This is a property list.")
c6fa13e3
GM
51(make-variable-buffer-local 'ada-prj-current-values)
52
53(defvar ada-prj-default-values nil
6f9a2614 54 "Hold the default value for the fields, This is a property list.")
c6fa13e3
GM
55(make-variable-buffer-local 'ada-prj-default-values)
56
57(defvar ada-prj-ada-buffer nil
58 "Indicates what Ada source file was being edited.")
59
da2a1edf
SM
60(defvar ada-old-cross-prefix nil
61 "The cross-prefix associated with the currently loaded runtime library.")
62
c6fa13e3
GM
63
64;; ----- Functions --------------------------------------------------------
65
66(defun ada-prj-new ()
67 "Open a new project file"
d41832c5 68 (interactive)
c6fa13e3 69 (let* ((prj
da2a1edf
SM
70 (if (and ada-prj-default-project-file
71 (not (string= ada-prj-default-project-file "")))
72 ada-prj-default-project-file
c6fa13e3
GM
73 "default.adp"))
74 (filename (read-file-name "Project file: "
75 (if prj "" nil)
76 nil
77 nil
78 prj)))
79 (if (not (string= (file-name-extension filename t) ".adp"))
80 (error "File name extension for project files must be .adp"))
a1506d29 81
c6fa13e3
GM
82 (ada-customize nil filename)))
83
84(defun ada-prj-edit ()
85 "Editing the project file associated with the current Ada buffer.
86If there is none, opens a new project file"
87 (interactive)
61c08d00
SM
88 (if ada-prj-default-project-file
89 (ada-customize)
90 (ada-prj-new)))
d41832c5 91
ce20e709 92(defun ada-prj-initialize-values (symbol ada-buffer filename)
c6fa13e3
GM
93 "Set SYMBOL to the property list of the project file FILENAME.
94If FILENAME is null, read the file associated with ADA-BUFFER. If no
95project file is found, returns the default values."
96
ce20e709
JB
97 (if (and filename
98 (not (string= filename ""))
99 (assoc filename ada-xref-project-files))
100 (set symbol (copy-sequence (cdr (assoc filename ada-xref-project-files))))
a1506d29 101
ce20e709
JB
102 ;; Set default values (except for the file name if this was given
103 ;; in the buffer
104 (ada-xref-set-default-prj-values symbol ada-buffer)
105 (if (and filename (not (string= filename "")))
106 (set symbol (plist-put (eval symbol) 'filename filename)))
107 ))
a1506d29 108
d41832c5 109
c6fa13e3
GM
110(defun ada-prj-save-specific-option (field)
111 "Returns the string to print in the project file to save FIELD.
112If the current value of FIELD is the default value, returns an empty string."
113 (if (string= (plist-get ada-prj-current-values field)
114 (plist-get ada-prj-default-values field))
115 ""
116 (concat (symbol-name field)
117 "=" (plist-get ada-prj-current-values field) "\n")))
d41832c5
GM
118
119(defun ada-prj-save ()
c6fa13e3 120 "Save the edited project file."
d41832c5 121 (interactive)
c6fa13e3
GM
122 (let ((file-name (plist-get ada-prj-current-values 'filename))
123 output)
124 (set 'output
125 (concat
126
127 ;; Save the fields that do not depend on the current buffer
128 ;; only if they are different from the default value
a1506d29 129
c6fa13e3
GM
130 (ada-prj-save-specific-option 'comp_opt)
131 (ada-prj-save-specific-option 'bind_opt)
132 (ada-prj-save-specific-option 'link_opt)
133 (ada-prj-save-specific-option 'gnatmake_opt)
da2a1edf 134 (ada-prj-save-specific-option 'gnatfind_opt)
c6fa13e3
GM
135 (ada-prj-save-specific-option 'cross_prefix)
136 (ada-prj-save-specific-option 'remote_machine)
c6fa13e3
GM
137 (ada-prj-save-specific-option 'debug_cmd)
138
139 ;; Always save the fields that depend on the current buffer
da2a1edf
SM
140 "main=" (plist-get ada-prj-current-values 'main) "\n"
141 "main_unit=" (plist-get ada-prj-current-values 'main_unit) "\n"
142 "build_dir=" (plist-get ada-prj-current-values 'build_dir) "\n"
143 (ada-prj-set-list "check_cmd"
144 (plist-get ada-prj-current-values 'check_cmd)) "\n"
145 (ada-prj-set-list "make_cmd"
146 (plist-get ada-prj-current-values 'make_cmd)) "\n"
147 (ada-prj-set-list "comp_cmd"
148 (plist-get ada-prj-current-values 'comp_cmd)) "\n"
149 (ada-prj-set-list "run_cmd"
150 (plist-get ada-prj-current-values 'run_cmd)) "\n"
c6fa13e3 151 (ada-prj-set-list "src_dir"
da2a1edf
SM
152 (plist-get ada-prj-current-values 'src_dir)
153 t) "\n"
c6fa13e3 154 (ada-prj-set-list "obj_dir"
da2a1edf
SM
155 (plist-get ada-prj-current-values 'obj_dir)
156 t) "\n"
157 (ada-prj-set-list "debug_pre_cmd"
158 (plist-get ada-prj-current-values 'debug_pre_cmd))
159 "\n"
160 (ada-prj-set-list "debug_post_cmd"
161 (plist-get ada-prj-current-values 'debug_post_cmd))
162 "\n"
c6fa13e3 163 ))
a1506d29 164
d41832c5
GM
165 (find-file file-name)
166 (erase-buffer)
167 (insert output)
168 (save-buffer)
169 ;; kill the project buffer
170 (kill-buffer nil)
171
172 ;; kill the editor buffer
173 (kill-buffer "*Customize Ada Mode*")
174
da2a1edf
SM
175 ;; automatically set the new project file as the active one
176 (set 'ada-prj-default-project-file file-name)
d41832c5 177
c6fa13e3
GM
178 ;; force Emacs to reread the project files
179 (ada-reread-prj-file file-name)
d41832c5
GM
180 )
181 )
182
c6fa13e3
GM
183(defun ada-prj-load-from-file (symbol)
184 "Load SYMBOL value from file. One item per line should be found in the file."
185 (save-excursion
186 (let ((file (read-file-name "File name: " nil nil t))
187 (buffer (current-buffer))
188 line
189 list)
190 (find-file file)
191 (widen)
192 (goto-char (point-min))
193 (while (not (eobp))
194 (set 'line (buffer-substring-no-properties
195 (point) (save-excursion (end-of-line) (point))))
196 (add-to-list 'list line)
197 (forward-line 1)
198 )
199 (kill-buffer nil)
200 (set-buffer buffer)
201 (set 'ada-prj-current-values
202 (plist-put ada-prj-current-values
203 symbol
204 (append (plist-get ada-prj-current-values symbol)
205 (reverse list))))
206 )
207 (ada-prj-display-page 2)
208 ))
209
210(defun ada-prj-subdirs-of (dir)
211 "Returns a list of all the subdirectories of dir, recursively."
212 (let ((subdirs (directory-files dir t "^[^.].*"))
213 (dirlist (list dir)))
214 (while subdirs
215 (if (file-directory-p (car subdirs))
216 (let ((sub (ada-prj-subdirs-of (car subdirs))))
217 (if sub
218 (set 'dirlist (append sub dirlist)))))
219 (set 'subdirs (cdr subdirs)))
220 dirlist))
221
222(defun ada-prj-load-directory (field &optional file-name)
223 "Append the content of FILE-NAME to FIELD in the current project file.
224If FILE-NAME is nil, ask the user for the name."
61c08d00
SM
225
226 ;; Do not use an external dialog for this, since it wouldn't allow
227 ;; the user to select a directory
228 (let ((use-dialog-box nil))
229 (unless file-name
230 (set 'file-name (read-file-name "Root directory: " nil nil t))))
c6fa13e3
GM
231
232 (set 'ada-prj-current-values
233 (plist-put ada-prj-current-values
234 field
235 (append (plist-get ada-prj-current-values field)
236 (reverse (ada-prj-subdirs-of
237 (expand-file-name file-name))))))
238 (ada-prj-display-page 2))
239
240(defun ada-prj-display-page (tab-num)
241 "Display one of the pages available in the notebook. TAB-NUM should have
242a value between 1 and the maximum number of pages.
243The current buffer must be the project editing buffer."
244
245 (let ((inhibit-read-only t))
246 (erase-buffer))
247
da2a1edf 248 ;; Widget support in Emacs 21 requires that we clear the buffer first
6f9a2614 249 (if (and (not (featurep 'xemacs)) (>= emacs-major-version 21))
da2a1edf
SM
250 (progn
251 (setq widget-field-new nil
252 widget-field-list nil)
253 (mapcar (lambda (x) (delete-overlay x)) (car (overlay-lists)))
254 (mapcar (lambda (x) (delete-overlay x)) (cdr (overlay-lists)))))
a1506d29 255
c6fa13e3 256 ;; Display the tabs
a1506d29 257
c6fa13e3 258 (widget-insert "\n Project and Editor configuration.\n
da2a1edf 259 ___________ ____________ ____________ ____________ ____________\n / ")
c6fa13e3
GM
260 (widget-create 'push-button :notify
261 (lambda (&rest dummy) (ada-prj-display-page 1)) "General")
262 (widget-insert " \\ / ")
263 (widget-create 'push-button :notify
264 (lambda (&rest dummy) (ada-prj-display-page 2)) "Paths")
265 (widget-insert " \\ / ")
266 (widget-create 'push-button :notify
267 (lambda (&rest dummy) (ada-prj-display-page 3)) "Switches")
268 (widget-insert " \\ / ")
269 (widget-create 'push-button :notify
270 (lambda (&rest dummy) (ada-prj-display-page 4)) "Ada Menu")
da2a1edf
SM
271 (widget-insert " \\ / ")
272 (widget-create 'push-button :notify
273 (lambda (&rest dummy) (ada-prj-display-page 5)) "Debugger")
c6fa13e3
GM
274 (widget-insert " \\\n")
275
276 ;; Display the currently selected page
a1506d29 277
c6fa13e3 278 (cond
a1506d29 279
c6fa13e3
GM
280 ;;
281 ;; First page (General)
282 ;;
283 ((= tab-num 1)
da2a1edf 284 (widget-insert "/ \\/______________\\/______________\\/______________\\/______________\\\n")
c6fa13e3
GM
285
286 (widget-insert "Project file name:\n")
287 (widget-insert (plist-get ada-prj-current-values 'filename))
288 (widget-insert "\n\n")
289; (ada-prj-field 'filename "Project file name"
290; "Enter the name and directory of the project
291; file. The name of the file should be the
292; name of the project itself. The extension
293; must be .adp")
294; (ada-prj-field 'casing "Casing Exceptions Dictionnaries"
295; "List of files that contain casing exception
296; dictionnaries. All these files contain one
297; identifier per line, with a special casing.
298; The first file has the highest priority."
299; t)
300 (ada-prj-field 'main "Executable file name"
301"Name of the executable generated when you
302compile your application. This should include
303the full directory name, using ${build_dir} if
304you wish.")
305 (ada-prj-field 'main_unit "File name of the main unit"
306"Name of the file to pass to the gnatmake command,
307and that will create the executable.
308This should not include any directory specification.")
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)
da2a1edf
SM
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)
da2a1edf
SM
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
da2a1edf
SM
402"All the fields below can use variable substitution The syntax is ${name},
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)
467 (ada-xref-set-default-prj-values
468 'ada-prj-current-values ada-prj-ada-buffer)
469 (ada-prj-display-page 1))
470 "Reset to Default Values")
471 (widget-insert " ")
472 (widget-create 'push-button :notify (lambda (&rest ignore) (kill-buffer nil))
473 "Cancel")
474 (widget-insert " ")
475 (widget-create 'push-button :notify (lambda (&rest ignore) (ada-prj-save))
476 "Save")
477 (widget-insert "\n\n")
478
479 (widget-setup)
480 (beginning-of-buffer)
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
61c08d00
SM
513 ;; Else start the interactive editor
514 (switch-to-buffer "*Customize Ada Mode*")
a1506d29 515
61c08d00 516 (ada-xref-set-default-prj-values 'ada-prj-default-values ada-buffer)
ce20e709
JB
517 (ada-prj-initialize-values 'ada-prj-current-values
518 ada-buffer
519 ada-prj-default-project-file)
a1506d29 520
61c08d00 521 (set (make-local-variable 'ada-prj-ada-buffer) ada-buffer)
a1506d29 522
61c08d00
SM
523 (use-local-map (copy-keymap custom-mode-map))
524 (local-set-key "\C-x\C-s" 'ada-prj-save)
a1506d29 525
61c08d00
SM
526 (make-local-variable 'widget-keymap)
527 (define-key widget-keymap "\C-x\C-s" 'ada-prj-save)
a1506d29 528
61c08d00
SM
529 (set (make-local-variable 'ada-old-cross-prefix)
530 (ada-xref-get-project-field 'cross-prefix))
a1506d29 531
61c08d00
SM
532 (ada-prj-display-page 1)
533 )))
d41832c5
GM
534
535;; ---------------- Utilities --------------------------------
536
da2a1edf
SM
537(defun ada-prj-set-list (string ada-list &optional is-directory)
538 "Join the strings in ADA-LIST into a single string.
539Each name is put on a separate line that begins with STRING.
540If IS-DIRECTORY is non-nil, each name is explicitly converted to a
541directory name."
542
543 (mapconcat (lambda (x) (concat string "="
544 (if is-directory
545 (file-name-as-directory x)
546 x)))
547 ada-list "\n"))
d41832c5 548
c6fa13e3 549
c6fa13e3
GM
550(defun ada-prj-field-modified (widget &rest dummy)
551 "Callback called each time the value of WIDGET is modified. Save the
552change in ada-prj-current-values so that selecting another page and coming
553back keeps the new value."
554 (set 'ada-prj-current-values
555 (plist-put ada-prj-current-values
da2a1edf 556 (widget-get widget ':prj-field)
c6fa13e3
GM
557 (widget-value widget))))
558
559(defun ada-prj-display-help (widget widget-modified event)
560 "An help button in WIDGET was clicked on. The parameters are so that
561this function can be used as :notify for the widget."
562 (let ((text (widget-get widget 'prj-help)))
563 (if event
564 ;; If we have a mouse-event, popup a menu
565 (widget-choose "Help"
566 (mapcar (lambda (a) (cons a t))
567 (split-string text "\n"))
568 event)
569 ;; Else display the help string just before the next group of
570 ;; variables
571 (momentary-string-display
572 (concat "*****Help*****\n" text "\n**************\n")
573 (save-excursion (forward-line) (beginning-of-line) (point)))
574 )))
575
576(defun ada-prj-show-value (widget widget-modified event)
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.
615If IS-LIST is non-nil, the field contains a list. Otherwise, it contains
616a single string.
617if IS-PATHS is true, some special buttons are added to load paths,...
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
ab5796a9 684;;; arch-tag: 65978c77-816e-49c6-896e-6905605d1b4c
3afbc435 685;;; ada-prj.el ends here