6

Some of my projects are organised in way that the there isn't one make file at the top route of the project (git/svn/...) folder but I have several small Makefiles in subfolders of the project. Normally I use Projectile to save only files related to my current project and call the main Makefile but this doesn't work if the Makefiles are more distributed in the project.

I would like to have a function that saves all open/unsaved files from the current folder and it's subfolder and then run the Makefile in the current folder.

(defun max/save-compile-current-folder ()
    (interactive)
    (max/save-current-and-subfolder-files ...)
    (compile t))

I currently don't know how to write the function max/save-current-and-subfolder-files. I would appreciate any hints how to write this function or links to libraries that already implement it.

Malabarba
  • 22,878
  • 6
  • 78
  • 163
kain88
  • 825
  • 7
  • 19
  • I would be astonished if Icicles couldn't do that... – mbork Dec 11 '14 at 08:59
  • Also, you might want to write a function firing `save-some-buffers` with a suitable second argument. See the docstring for details. – mbork Dec 11 '14 at 09:02

2 Answers2

4

I just added this feature to helm-make. Give it a go and let me know if it works as you wanted, you just need to set the custom:

(setq helm-make-do-save t)

Here's the code that does it:

(when helm-make-do-save
  (let* ((regex (format "^%s" (regexp-quote default-directory)))
         (buffers
          (cl-remove-if-not
           (lambda (b)
             (let ((name (buffer-file-name b)))
               (and name
                    (string-match regex (expand-file-name name)))))
           (buffer-list))))
    (mapc
     (lambda (b)
       (with-current-buffer b
         (save-buffer)))
     buffers))) 
abo-abo
  • 13,943
  • 1
  • 29
  • 43
  • awesome it works great thank you. This is also a good reason to start to get into helm. – kain88 Dec 09 '14 at 10:00
  • Note that this won't save files in the same directory tree but accessed through symbolic links, which is probably desirable here. Also, take care to protect metacharacters when you build a regexp. – Gilles 'SO- stop being evil' Dec 11 '14 at 01:21
2

The simple thing would be to save everything with C-u C-x s (mnemonic: C-x s is a slightly awkward modification of C-x C-s which is the normal save command). The computer takes less time to save everything than you'd lose worrying what not to save. This runs the command save-some-buffers. With no prefix argument, you'll be prompted whether to save each modified buffer.

If you really want to save only some files, you can write a function that only saves files based on your chosen criteria.

(defun save-buffers-in-directory-tree (directory)
  "Save buffers that are visiting a file in the current directory and its children."
  (interactive (list default-directory))
  (setq directory (file-name-as-directory (file-truename directory)))
  (mapc (lambda (buffer)
          (let ((filename (buffer-file-name buffer)))
            (when (and (buffer-modified-p buffer) filename)
              (setq filename (file-truename filename))
              (when (string-prefix-p directory filename)
                (with-current-buffer buffer
                  (save-buffer))))))
        (buffer-list)))