buffer-layers.el 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. ;;; buffer-layers.el --- Layered Buffers for Buffer Management
  2. ;; Copyright (C) 2016 Samuel Flint
  3. ;; Author: Samuel W. Flint <swflint@flintfam.org>
  4. ;; Version: 1.0
  5. ;; Package-Requires: (cl)
  6. ;; Keywords: buffer-management
  7. ;; URL: http://github.com/swflint/buffer-layers
  8. ;;; Commentary:
  9. ;;
  10. ;;; Code:
  11. (require 'cl)
  12. (defvar *buffer-layers* nil
  13. "List of all defined buffer layers.")
  14. (defvar *buffer-layers-applied* nil
  15. "List of applied buffer-layers.")
  16. (defun buffer-layer--applier-name (name)
  17. "Generate name to apply a buffer layer based on NAME."
  18. (intern (format "apply-buffer-layer-%s" name)))
  19. (defun buffer-layer--remover-name (name)
  20. "Generate name to remove a buffer layer based on NAME."
  21. (intern (format "remove-buffer-layer-%s" name)))
  22. (defun buffer-layer--buffer-list-name (name)
  23. "Generate name to contain buffer layer buffer list based on NAME."
  24. (intern (format "*buffer-layer-%s-buffers*" name)))
  25. (cl-defmacro define-buffer-layer (name &key files run-on-apply run-on-remove buffer-to-select)
  26. "Define a buffer layer named NAME, taking FILES, RUN-ON-APPLY, RUN-ON-REMOVE and BUFFER-TO-SELECT as keyword arguments."
  27. (let ((applier (buffer-layer--applier-name name))
  28. (remover (buffer-layer--remover-name name))
  29. (buffers-list (buffer-layer--buffer-list-name name))
  30. (files-list (cons 'list
  31. (when (not (null files))
  32. (mapcar #'(lambda (name)
  33. (format "%s" name)) files)))))
  34. `(progn
  35. (add-to-list '*buffer-layers* ',name)
  36. (defvar ,buffers-list nil)
  37. (defun ,applier ()
  38. ,(format "Apply buffer-layer %s." name)
  39. (interactive)
  40. (mapcar #'(lambda (file)
  41. (add-to-list ',buffers-list (find-file file)))
  42. ,files-list)
  43. ,@run-on-apply
  44. (when (not (null ,buffer-to-select))
  45. (switch-to-buffer ,buffer-to-select))
  46. (add-to-list '*buffer-layers-applied* ',name)
  47. (message "Applied Buffer Layer %s" ',name))
  48. (defun ,remover ()
  49. ,(format "Remove buffer-layer %s." name)
  50. (interactive)
  51. (mapc #'(lambda (buffer)
  52. (when (buffer-live-p buffer)
  53. (with-current-buffer buffer
  54. (save-buffer)
  55. (kill-buffer))))
  56. ,buffers-list)
  57. ,@run-on-remove
  58. (setq ,buffers-list nil)
  59. (setq *buffer-layers-applied* (delq ',name *buffer-layers-applied*))
  60. (message "Removed Buffer Layer %s" ',name))
  61. (setq current-buffer-applier ',applier)
  62. (list ',applier ',remover))))
  63. (defun load-buffer-layer (name-or-path load-it-p)
  64. "Load a buffer named NAME-OR-PATH, and if a file, apply if LOAD-IT-P is true."
  65. (interactive (list (completing-read "Buffer Layer Name or Path: " (remove-if #'(lambda (layer)
  66. (member layer *buffer-layers-applied*))
  67. *buffer-layers*))
  68. nil))
  69. (if (functionp (buffer-layer--applier-name name-or-path))
  70. (funcall (buffer-layer--applier-name name-or-path))
  71. (load name-or-path)
  72. (when load-it-p
  73. (funcall current-buffer-applier))))
  74. (defun unload-buffer-layer (name)
  75. "Unload Buffer Layer named NAME."
  76. (interactive (list (completing-read "Buffer Layer Name: " *buffer-layers-applied*)))
  77. (funcall (buffer-layer--remover-name name)))
  78. (defun unload-all-buffer-layers ()
  79. "Unload all loaded buffer layers."
  80. (interactive)
  81. (dolist (buffer-layer *buffer-layers-applied*)
  82. (unload-buffer-layer buffer-layer)))
  83. (defvar buffer-layer-map (make-keymap)
  84. "Keymap for buffer-layer commands.")
  85. (define-key buffer-layer-map (kbd "l") #'load-buffer-layer)
  86. (define-key buffer-layer-map (kbd "u") #'unload-buffer-layer)
  87. (define-key buffer-layer-map (kbd "U") #'unload-all-buffer-layers)
  88. (global-set-key (kbd "C-x L") buffer-layer-map)
  89. (add-hook 'kill-emacs-hook #'unload-all-buffer-layers)
  90. (provide 'buffer-layers)
  91. ;;; buffer-layers.el ends here