SiteMap Search ElispArea HowTo Glossary RecentChanges News Problems Suggestions

CheckBufferCompiled

Often the CompileCommand for CompilationMode is a build tool like Make that can confirm whether the build process needs to be run by comparing if source modification time is newer than the build target. Sometimes, there is no such tool available, or your Makefile’s dependencies are not written to avoid building or executing time-intensive tasks. And sometimes, you’re using ‘M-x compile’ to run something that isn’t even a build tool.

In these cases, why not have an Emacs interactive command that can tell you if the current buffer’s file modification time is newer than the time of the last executed compile command. That way, you know whether to run ‘M-x recompile’ in case you forgot if you had. This is a common scenario for someone who is multi-tasking.

The following hack uses the text date at the beginning of the *compilation* buffer for the comparison.

  (defun my-buffer-compiled-since-modified-p (buffer)
    "Is file modification for BUFFER newer than last compilation time?"
    (interactive (list (current-buffer)))
      (unless (bufferp (get-buffer "*compilation*"))
        (error "No file associated with buffer"))
      (let ((mtime (nth 5 (file-attributes (buffer-file-name buffer))))
            (compile-start
             (save-excursion
               (with-current-buffer (get-buffer "*compilation*")
                 (goto-char (point-min))
                 (search-forward "Compilation started at "
                                 nil 'noerror)
                 (apply 'encode-time
                        ;; Anything missing in the string,
                        (mapcar
                         (lambda (a)
                           (if (null (car a)) (cadr a) (car a)))
                         ((lambda (&rest args)
			    "Transpose list of ARGS into one list."
                            (mapcar
			     (lambda (n)
			       (delq nil
				     (mapcar
				      (lambda (arg) (nth n arg))
				      args)))
			     (let ((len (apply 'max
					       (mapcar 'length args))))
			       (number-sequence 0 (1- len)))))
                          (parse-time-string
                           (buffer-substring-no-properties
                            (point)
                            (progn
                              (forward-line 1)
                              (forward-char -1)
                              (point))))
                          ;; fold in from current time.
                          (decode-time))))))))
        (if (time-less-p compile-start mtime)
            (prog1 nil
              (if (buffer-modified-p)
                  (message "Not compiled since last save (modified)")
                (message "Not compiled since last save")))
          (prog1 t
              (if (buffer-modified-p)
                  (message "Compiled after last save (modified)")
                (message "Compiled after last save"))))))

Since this depends on the compilation and file buffer date be close in proximity, don’t expect the above to work when you are compiling extremely close to a midnight, a new calendar year or daylight savings.


CategoryProgrammerUtils CategoryModes