Commits

seanmcl  committed 5072373 Merge
  • Participants
  • Parent commits e362159, f64f018

Comments (0)

Files changed (16)

File elisp/omake/omake-connection.el

 
 (defun Omake.Connection.open ()
   "A TCP connection is made to the server via the user's socket."
-  (message "Establishing a connection to the server.  This takes a couple of seconds.")
+  (message "Establishing a connection to the server.")
   (let* ((user (String.strip (shell-command-to-string "whoami")))
          (p (make-network-process
              :name "omake-server"

File 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)

File elisp/omake/omake-env.el

    (:constructor nil)
    (:constructor
     Omake.Env.create
-    (&key version-util-support link-executables
-          x-library-inlining limit-subdirs-for-speed
+    (&key version-util-support
+          link-executables
+          x-library-inlining
+          limit-subdirs-for-speed
+          four-point-zero
           &aux
           (_ (assert (Omake.Env.value-p version-util-support)))
           (_ (assert (Omake.Env.value-p link-executables)))
           (_ (assert (Omake.Env.value-p x-library-inlining)))
-          (_ (assert (Omake.Env.value-p limit-subdirs-for-speed))))))
+          (_ (assert (Omake.Env.value-p limit-subdirs-for-speed)))
+          (_ (assert (Omake.Env.value-p four-point-zero))))))
   (version-util-support    nil :read-only t)
   (link-executables        nil :read-only t)
   (x-library-inlining      nil :read-only t)
-  (limit-subdirs-for-speed nil :read-only t))
+  (limit-subdirs-for-speed nil :read-only t)
+  (four-point-zero         nil :read-only t))
 
 (defun Omake.Env.completing-read ()
   (let ((vars
-         '("VERSION_UTIL_SUPPORT" "LINK_EXECUTABLES"
-           "X_LIBRARY_INLINING" "LIMIT_SUBDIRS_FOR_SPEED")))
+         '("VERSION_UTIL_SUPPORT"
+           "LINK_EXECUTABLES"
+           "X_LIBRARY_INLINING"
+           "LIMIT_SUBDIRS_FOR_SPEED"
+           "FOUR_POINT_ZERO")))
     (intern (completing-read "Var: " vars nil t))))
 
 (defun Omake.Env.completing-read-value ()
    (X_LIBRARY_INLINING (Omake.Env.x-library-inlining env))
    (LINK_EXECUTABLES (Omake.Env.link-executables env))
    (LIMIT_SUBDIRS_FOR_SPEED (Omake.Env.limit-subdirs-for-speed env))
+   (FOUR_POINT_ZERO (Omake.Env.four-point-zero 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))
+   (Omake.Env.var-to-string
+    "FOUR_POINT_ZERO"
+    (Omake.Env.four-point-zero env)
+    (Omake.Env.four-point-zero new-env))))
 
 (provide 'omake-env)

File 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)))

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.")
           (when project
             (let* ((num-watchers (Omake.Project.num-watchers project))
                    (watch-msg
-                    (if (< 1 num-watchers) 
+                    (if (< 1 num-watchers)
                         "\nThis will affect other processes watching this project."
                       ""))
-                   (kill 
+                   (kill
                     (Emacs.y-or-n-p
                      (format "\
 OMake is already building:
                   (if read-command
                       (read-from-minibuffer "Command: " (concat config " "))
                     config)))
-            (message "Starting compilation.  This takes a couple seconds.")
+            (message "Starting compilation.")
             (Omake.Server.create-project
              :id id
              :omakeroot-dir root-dir
         (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                                                                    ;;

File 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))

File 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)

File elisp/omake/omake-server.el

   "Start the server.  Use nohup so closing this Emacs instance will not affect
 the running server."
   (Omake.Server.logf "Starting the server.")
-  (message "Starting the server.  This takes a couple of seconds.")
+  (message "Starting the server.")
   (let ((p
          (start-process
-          "Omake.Server.start" nil "nohup" Omake.Server.program
-          "server" "start"))
+          "Omake.Server.start" nil "sh" "-c"
+          (format "nohup %s server start > /dev/null" Omake.Server.program)))
         (i 0))
     (set-process-query-on-exit-flag p nil)
     (Emacs.protect-from-quit
-      ;; CR smclaughlin: this is a bad hack to get around a mysterious 
+      ;; CR smclaughlin: this is a bad hack to get around a mysterious
       ;; problem where (sleep-for N) doesn't sleep.  It must have something
       ;; to do with the fact that other processes get to run during a sleep
       ;; but not a loop, but I haven't been able to find the problem yet.

File elisp/omake/omake-version.el

 
 ;; Detect version changes
 
-(defconst Omake.pre-version 11
+(defconst Omake.pre-version 12
   "We use a version number to synchronize the elisp code the omake server
 To roll a new version of elisp that is incompatible with ocaml or vice
 versa, you must bump the version number.  This prevents old elisp code

File ocaml/omake/config.ml

 
 let write_default_file () =
   if not (has_config_file ()) then
-    (* CR sweeks: It would be nice to output a header line:
-
-         ;; -*-scheme-*-;
-
-       It would also be nice to use [Sexp.to_string_hum]. *)
-    Out_channel.write_all config_file ~data:(Sexp.to_string (sexp_of_t default))
+    Out_channel.write_lines config_file
+      [";; -*- scheme -*- ;;"; ""; Sexp.to_string_hum (sexp_of_t default) ]
 
 let init () =
   begin

File ocaml/omake/env.ml

 | LINK_EXECUTABLES
 | VERSION_UTIL_SUPPORT
 | LIMIT_SUBDIRS_FOR_SPEED
-  with sexp
+| FOUR_POINT_ZERO
+with sexp
 
 let var_to_string x = Sexp.to_string (sexp_of_var x)
 let var_of_string x = var_of_sexp (Sexp.of_string x)
   link_executables : bool;
   x_library_inlining : bool;
   limit_subdirs_for_speed : bool;
+  four_point_zero : bool;
 } with sexp, fields
 
 let value t = function
 | LINK_EXECUTABLES -> t.link_executables
 | VERSION_UTIL_SUPPORT -> t.version_util_support
 | LIMIT_SUBDIRS_FOR_SPEED -> t.limit_subdirs_for_speed
+| FOUR_POINT_ZERO -> t.four_point_zero
 
 let to_elisp t = sprintf "
       (Omake.Env.create
         :version-util-support %s
         :link-executables %s
         :x-library-inlining %s
-        :limit-subdirs-for-speed %s)"
+        :limit-subdirs-for-speed %s
+        :four-point-zero %s)"
   (Elisp.env_value t.version_util_support)
   (Elisp.env_value t.link_executables)
   (Elisp.env_value t.x_library_inlining)
   (Elisp.env_value t.limit_subdirs_for_speed)
+  (Elisp.env_value t.four_point_zero)
 
   (*** make sure all the env variables are set. ***)
 
     assure_set ~default:"true"  ~key:"LINK_EXECUTABLES"       ;
     assure_set ~default:"true"  ~key:"X_LIBRARY_INLINING"     ;
     assure_set ~default:"false" ~key:"LIMIT_SUBDIRS_FOR_SPEED";
+    assure_set ~default:"false" ~key:"FOUR_POINT_ZERO";
   end
 
   (* Save the variables in a file in ~/.omake-server/PROJ/env.sexp *)
     link_executables = get_bool_exn "LINK_EXECUTABLES";
     x_library_inlining = get_bool_exn "X_LIBRARY_INLINING";
     limit_subdirs_for_speed = get_bool_exn "LIMIT_SUBDIRS_FOR_SPEED";
+    four_point_zero = get_bool_exn "FOUR_POINT_ZERO";
   }
   in
   save id t >>| fun () ->
   | VERSION_UTIL_SUPPORT -> {t with version_util_support = b}
   | LINK_EXECUTABLES -> {t with link_executables = b}
   | LIMIT_SUBDIRS_FOR_SPEED -> {t with limit_subdirs_for_speed = b}
+  | FOUR_POINT_ZERO -> {t with four_point_zero = b}
   in
   save id t
 
-  (* Set the variables before starting the process. *)
+(* Set the variables before starting the process. *)
 let set_env t =
   begin
     Unix.putenv ~key:(var_to_string X_LIBRARY_INLINING) ~data:(string_of_bool t.x_library_inlining);
     Unix.putenv ~key:(var_to_string LINK_EXECUTABLES) ~data:(string_of_bool t.link_executables);
     Unix.putenv ~key:(var_to_string VERSION_UTIL_SUPPORT) ~data:(string_of_bool t.version_util_support);
     Unix.putenv ~key:(var_to_string LIMIT_SUBDIRS_FOR_SPEED) ~data:(string_of_bool t.limit_subdirs_for_speed);
+    Unix.putenv ~key:(var_to_string FOUR_POINT_ZERO) ~data:(string_of_bool t.four_point_zero);
   end

File ocaml/omake/env.mli

 | X_LIBRARY_INLINING
 | LINK_EXECUTABLES
 | VERSION_UTIL_SUPPORT
-| LIMIT_SUBDIRS_FOR_SPEED with sexp
+| LIMIT_SUBDIRS_FOR_SPEED
+| FOUR_POINT_ZERO
+with sexp
+
 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;
   limit_subdirs_for_speed : bool;
+  four_point_zero : bool;
 }
 
 val value : t -> var -> bool

File 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)

File 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 *)

File 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 ()));

File ocaml/omake/version.ml

 
 (* Use a version number to synchronize with the elisp code. *)
-let version = 11
+let version = 12