Commits

seanmcl committed 102aedc

toggle-env/set-env prompts. Issue #85

Comments (0)

Files changed (10)

elisp/omake/omake-custom.el

 ;; (setq Omake.create-dedicated-frame t)
 ;; (setq Omake.create-dedicated-frame nil)
 
+(defcustom Omake.prompt-when-setting-environment-variable-for-a-project-that-is-building t
+  "t iff you want a prompt"
+  :group 'omake
+  :type 'boolean)
+;; (setq Omake.prompt-when-setting-environment-variable-for-a-project-that-is-building nil)
+
 (provide 'omake-custom)

elisp/omake/omake-env.el

    (LIMIT_SUBDIRS_FOR_SPEED (Omake.Env.limit-subdirs-for-speed env))
    (t (error "Omake.Env.value: Impossible: %s" var))))
 
-(defun Omake.Env.set (id)
-  (when (or (not (Omake.Model.has id))
-            (Omake.Model.dead-p (Omake.Model.get id))
-            (Emacs.y-or-n-p
-             (format
-              "\
+(defun Omake.Env.set (id &key toggle)
+  (let ((model (Omake.Model.get id)))
+    (when (or (not model)
+              (Omake.Model.dead-p model)
+              (not Omake.prompt-when-setting-environment-variable-for-a-project-that-is-building)
+              (Emacs.y-or-n-p
+               (format
+                "\
 Currently building:
   %s
 Changes to variables will only take effect after restarting OMake.  Proceed? "
-              (Omake.Model.compilation-dir (Omake.Model.get id)))))
-    ;; Set the variable on the server
-    (let ((var (Omake.Env.completing-read))
-          (value (Omake.Env.completing-read-value)))
-      (Omake.Server.setenv id var value))))
+                (Omake.Project.compilation-dir (Omake.Model.project model)))))
+      ;; Set the variable on the server
+      (let* ((var (Omake.Env.completing-read))
+             (val (if toggle
+                      (Omake.Env.not (Omake.Env.get id var))
+                    (Omake.Env.completing-read-value))))
+        (Omake.Server.setenv id var val)
+        (message "%s set to %s" var val)))))
 
 (defun Omake.Env.get (id &optional var)
   (let ((var (if var var (Omake.Env.completing-read))))
    (t (error "Omake.Env.not error"))))
 ;; (Omake.Env.not "true")
 
-(defun Omake.Env.toggle (id)
-  (let* ((var (Omake.Env.completing-read))
-         (val (Omake.Env.get id var))
-         (val (Omake.Env.not val)))
-    (Omake.Server.setenv id var val)
-    (message "%s set to %s" var val)))
+(defun Omake.Env.var-to-string (var val new-val)
+  (let ((val (if (equal val new-val) val
+               (format "%s (on next compilation: %s)" val new-val))))
+    (Omake.Model.verbose-line var val)))
 
-(defun Omake.Env.to-string (env)
+(defun Omake.Env.to-string (env new-env)
   (assert (Omake.Env.is env))
+  (assert (Omake.Env.is new-env))
   (concat
-   (Omake.Model.verbose-line
+   (Omake.Env.var-to-string
     "VERSION_UTIL_SUPPORT"
-    (Omake.Env.version-util-support env))
-   (Omake.Model.verbose-line
+    (Omake.Env.version-util-support env)
+    (Omake.Env.version-util-support new-env))
+   (Omake.Env.var-to-string
     "LINK_EXECUTABLES"
-    (Omake.Env.link-executables env))
-   (Omake.Model.verbose-line
+    (Omake.Env.link-executables env)
+    (Omake.Env.link-executables new-env))
+   (Omake.Env.var-to-string
     "X_LIBRARY_INLINING"
-    (Omake.Env.x-library-inlining env))
-   (Omake.Model.verbose-line
+    (Omake.Env.x-library-inlining env)
+    (Omake.Env.x-library-inlining new-env))
+   (Omake.Env.var-to-string
     "LIMIT_SUBDIRS_FOR_SPEED"
-    (Omake.Env.limit-subdirs-for-speed env))))
+    (Omake.Env.limit-subdirs-for-speed env)
+    (Omake.Env.limit-subdirs-for-speed new-env))))
 
 (provide 'omake-env)

elisp/omake/omake-error.el

   "The fullpath of a file"
   (assert (Omake.Error.is e))
   (let* ((id (Omake.Error.id e))
-         (model (Omake.Model.get id))
-         (root (Omake.Model.omakeroot-dir model))
+         (project (Omake.Project.find id))
+         (root (Omake.Project.omakeroot-dir project))
          (relpath (Omake.Error.relpath e))
          (file (Omake.Error.file e)))
   (format "%s/%s/%s" root relpath file)))

elisp/omake/omake-interface.el

   (assert (or (null id) (Omake.Id.is id)))
   (let* ((id (if id id (Omake.Id.current)))
          (model (Omake.Model.get id))
+         (project (Omake.Model.project model))
          (result (Omake.Model.result model))
          (status (Omake.Model.status model))
-         (comp-dir (Omake.Model.compilation-dir model))
+         (comp-dir (Omake.Project.compilation-dir project))
          (current-file (buffer-file-name)))
     (if (Omake.Result.failure-p result)
         (message "There is problem with omake.")
         (message "The server is running. Kill it with M-x Omake.shutdown before changing programs.")
       (setq Omake.Server.program p))))
 
-(defun Omake.setenv ()
-  (interactive)
-  (let ((id (Omake.Id.current)))
-    (Omake.Env.set id)))
-
 (defun Omake.getenv ()
   (interactive)
   (let ((id (Omake.Id.current)))
     (Omake.Env.get id)))
 
+(defun Omake.setenv ()
+  (interactive)
+  (let ((id (Omake.Id.current)))
+    (Omake.Env.set id :toggle nil)))
+
 (defun Omake.toggle-env ()
   (interactive)
   (let ((id (Omake.Id.current)))
-    (Omake.Env.toggle id)))
+    (Omake.Env.set id :toggle t)))
 
 ;;----------------------------------------------------------------------------;;
 ;; Buffers                                                                    ;;

elisp/omake/omake-model.el

    (:constructor nil)
    (:constructor
     Omake.Model
-    (project &aux
-             (_ (assert (Omake.Project.is project)))
-             (id (Omake.Project.id project))
-             (_ (when (Omake.Model.has id) (error "A model for %s already exists" id)))
-             (comp-dir (Omake.Project.compilation-dir project)))))
-  (project nil :read-only t)
+    (id &aux
+             (_ (assert (Omake.Id.is id)))
+             (_ (when (Omake.Model.has id) (error "A model for %s already exists" id))))))
+  (id nil :read-only t)
   (spinner (Omake.Spinner.create))
   (verbose nil)
   (progress-bar '(0 . 0))
   (result (Omake.Result.Ring (Omake.Ring.empty)))
   (error-msg nil))
 
-(defun Omake.Model.id (m)
-  (Omake.Project.id (Omake.Model.project m)))
-
-(defun Omake.Model.compilation-dir (m)
-  (Omake.Project.compilation-dir (Omake.Model.project m)))
-
-(defun Omake.Model.omakeroot-dir (m)
-  (Omake.Project.omakeroot-dir (Omake.Model.project m)))
-
-(defun Omake.Model.env (m)
-  (Omake.Project.env (Omake.Model.project m)))
-
-(defun Omake.Model.command (m)
-  (Omake.Project.command (Omake.Model.project m)))
+(defun Omake.Model.project (m)
+  (Omake.Project.find (Omake.Model.id m)))
 
 (defun Omake.Model.status-buffer (m)
   (Omake.Buffer.get 'status (Omake.Model.project m)))
   "Create an Emacs view of the ocaml project."
   (assert (Omake.Project.is p))
   (let* ((id (Omake.Project.id p))
-         (model (Omake.Model p)))
+         (model (Omake.Model id)))
     (when (Omake.Model.has id)
       (error "Model already exists: %s" (Omake.Id.to-string id)))
     (puthash id model Omake.Model.table)))
     (Emacs.protect-from-quit
       (let* ((model (Omake.Model.get id))
              (project (Omake.Model.project model))
-             (dir (Omake.Model.omakeroot-dir model)))
+             (dir (Omake.Project.omakeroot-dir project)))
         ;; Critical section
         (Omake.Buffer.kill 'status project t)
         (Omake.Buffer.kill 'raw project)
 
 (defun Omake.Model.to-string (model)
   (assert (Omake.Model.is model))
-  (let* ((project (Omake.Model.project model))
+  (let* ((id (Omake.Model.id model))
+         (project (Omake.Project.find id))
          ;; model state
          (status (Omake.Model.status model))
          (successful (Omake.Model.done model))
          (verbose (Omake.Model.verbose model))
          (error-msg (Omake.Model.error-msg model))
          ;; project
-         (root (Omake.Model.omakeroot-dir model))
+         (root (Omake.Project.omakeroot-dir project))
          (root (Omake.Model.verbose-line "Project dir" root))
          ;; compilation
          (comp (Omake.Project.compilation-dir-relpath project))
          (comp (Omake.Model.verbose-line "Compilation dir" comp))
          ;; command
-         (command (Omake.Model.command model))
+         (command (Omake.Project.command project))
          (command (Omake.Model.verbose-line "Command" command))
          ;; env
-         (env (Omake.Env.to-string (Omake.Model.env model)))
+         (env (Omake.Env.to-string
+               (Omake.Project.env project)
+               (Omake.Project.new-env project)))
          ;; last line
          (last-line (Omake.Model.last-line model))
          (last-line (String.truncate last-line 63))

elisp/omake/omake-project.el

    (:constructor nil)
    (:constructor
     Omake.Project.create
-    (&key id compilation-dir omakeroot-dir env command num-watchers &aux
+    (&key id compilation-dir omakeroot-dir command num-watchers env new-env &aux
         (_ (assert (stringp id)))
         (_ (assert (numberp num-watchers)))
         (_ (assert (Omake.Path.ok compilation-dir)))
         (_ (assert (Omake.Path.ok omakeroot-dir)))
+        (_ (assert (stringp command)))
         (_ (assert (Omake.Env.is env)))
-        (_ (assert (stringp command)))
+        (_ (assert (Omake.Env.is new-env)))
         (id (Omake.Id.of-path id)))))
   (id nil :read-only t)
   (compilation-dir nil :read-only t)
   (omakeroot-dir nil :read-only t)
   (env nil :read-only t)
+  (new-env nil :read-only t)
   (command nil :read-only t)
   (num-watchers nil :read-only t))
 
                     (ids (Omake.Id.to-string id)))
                (unless (List.find (lambda (p1) (equal id (Omake.Project.id p1))) ps)
                  (message "The project for %s was killed.  Removing the view." ids)
-                 (Omake.Model.kill id))))))
+                 (Omake.Model.kill id)))))
+          (update-new-env
+           (lambda () )))
       (mapc (lambda (m) (funcall remove-old-model ps m)) (Omake.Model.models))
       (setq Omake.Project.list ps)
-      (Omake.Project.create-buffer :display nil))))
+      (Omake.Project.create-buffer :display nil)
+      (Omake.Model.show-all))))
 
 (provide 'omake-project)

ocaml/omake/env.mli

 val var_to_string : var -> string
 val var_of_string : string -> var
 
-type t ={
+type t = {
   version_util_support : bool;
   link_executables : bool;
   x_library_inlining : bool;

ocaml/omake/project.ml

   compilation_dir : path;
   omakeroot_dir : path;
   env : Env.t;
+  mutable new_env : Env.t;
   command : Omake_command.t;
   log_writer : Writer.t;
   pid : Pid.t;
       (* set the environment *)
       Env.get id >>= fun env ->
       Env.set_env env;
+      let new_env = env in
       (* start omake *)
       let t = Fd.with_file_descr fd (fun omake_writer_descr ->
         let pid = ref None in
         ; compilation_dir
         ; omakeroot_dir
         ; env
+        ; new_env
         ; command
         ; log_writer
         ; pid
       :omakeroot-dir %s
       :command %s
       :num-watchers %d
-      :env %s)"
+      :env %s
+      :new-env %s)"
     (String.quote (Id.to_string t.id))
     (String.quote t.compilation_dir)
     (String.quote t.omakeroot_dir)
     (String.quote (Omake_command.to_string t.command))
     (num_watching t)
     (Env.to_elisp t.env)
+    (Env.to_elisp t.new_env)

ocaml/omake/project.mli

 
 type t = {
   id : Id.t;
-  (* where compilation started *)
+  (* Where compilation started *)
   compilation_dir : path;
-  (* full path to Omakeroot dir *)
+  (* Full path to Omakeroot dir *)
   omakeroot_dir : path;
-  (* the environment when the build started *)
+  (* The environment when the build started *)
   env : Env.t;
+  (* The environment for the next build. *)
+  mutable new_env : Env.t;
   (* Command to run omake *)
   command : Omake_command.t;
   (* Writer to the log file for debugging *)

ocaml/omake/query.ml

       let res = if b then "'true" else "'false" in
       Emacs.Sync.send writer "%s" res
     | Set_project_env (id, x, b) ->
-      Env.set id x b >>| fun () ->
-      Log.printf "Server: %s set to %b" (Env.var_to_string x) b
+      let p = Projects.get_exn id in
+      Env.set id x b >>= fun () ->
+      Log.printf "Server: %s set to %b" (Env.var_to_string x) b;
+      Env.get id >>= fun env ->
+      p.Project.new_env <- env;
+      Projects.update_all ()
     | Running -> Deferred.unit
     | Kill_when_unwatched ->
       Writer.writef writer "%s\n" (Elisp.bool (Config.kill_when_unwatched ()));