al-buffer.el 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. ;;; al-buffer.el --- Additional functionality for working with buffers
  2. ;; Copyright © 2013–2018 Alex Kost
  3. ;; This program is free software; you can redistribute it and/or modify
  4. ;; it under the terms of the GNU General Public License as published by
  5. ;; the Free Software Foundation, either version 3 of the License, or
  6. ;; (at your option) any later version.
  7. ;;
  8. ;; This program is distributed in the hope that it will be useful,
  9. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. ;; GNU General Public License for more details.
  12. ;;
  13. ;; You should have received a copy of the GNU General Public License
  14. ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
  15. ;;; Code:
  16. (defun al/kill-file-buffer (filename)
  17. "Kill the buffer visiting file FILENAME (a string).
  18. Return nil, if there is no such live buffer."
  19. (let ((buffer (get-file-buffer filename)))
  20. (if buffer (kill-buffer buffer))))
  21. (defun al/re-buffer-list (regexp)
  22. "Return a list of buffers which names match REGEXP."
  23. (let ((buffers))
  24. (dolist (buffer (buffer-list) buffers)
  25. (if (string-match-p regexp (buffer-name buffer))
  26. (setq buffers (cons buffer buffers))))))
  27. ;;;###autoload
  28. (defun al/buffer-file-name (&optional buffer)
  29. "Return file name without extension for BUFFER.
  30. If BUFFER is nil, use the current buffer.
  31. If BUFFER is not visiting a file, return BUFFER name."
  32. (let ((file (buffer-file-name buffer)))
  33. (file-name-sans-extension
  34. (if file
  35. (file-name-nondirectory file)
  36. (buffer-name buffer)))))
  37. ;;; Putting buffer info into kill ring
  38. (defun al/funcall-to-kill-ring (fun error-msg)
  39. "Call function FUN and put its result (string) into `kill-ring'.
  40. Also display result string in minibuffer.
  41. ERROR-MSG is a format string with one '%s' form, used as an error
  42. message for a case when FUN does not return a string."
  43. (let ((out (funcall fun)))
  44. (or (stringp out)
  45. (error error-msg out))
  46. (kill-new out)
  47. (message out)))
  48. ;;;###autoload
  49. (defun al/buffer-name-to-kill-ring ()
  50. "Put a name of the current buffer into `kill-ring'."
  51. (interactive)
  52. (al/funcall-to-kill-ring
  53. #'buffer-name "buffer-name has returned %s"))
  54. ;;;###autoload
  55. (defun al/file-name-to-kill-ring ()
  56. "Put a name of the file visited by the current buffer into `kill-ring'."
  57. (interactive)
  58. (al/funcall-to-kill-ring
  59. #'buffer-file-name "buffer-file-name has returned %s"))
  60. ;;;###autoload
  61. (defun al/major-mode-to-kill-ring ()
  62. "Put major mode name of the current buffer into `kill-ring'."
  63. (interactive)
  64. (al/funcall-to-kill-ring
  65. (lambda () (symbol-name major-mode)) "major-mode is %s"))
  66. ;;;###autoload
  67. (defun al/default-directory-to-kill-ring ()
  68. "Put `default-directory' into `kill-ring'."
  69. (interactive)
  70. (al/funcall-to-kill-ring
  71. (lambda () default-directory) "%s"))
  72. ;;; Switching to some buffers
  73. (require 'al-minibuffer)
  74. ;;;###autoload
  75. (defun al/display-buffer (buffer)
  76. "Switch to BUFFER, preferably reusing a window displaying this buffer."
  77. (pop-to-buffer buffer
  78. '((display-buffer-reuse-window
  79. display-buffer-same-window))))
  80. (defvar ivy-switch-buffer-map)
  81. (defvar ido-default-buffer-method)
  82. (declare-function ivy-read "ivy" t)
  83. (declare-function ido-buffer-internal "ido" t)
  84. ;;;###autoload
  85. (cl-defun al/switch-buffer (prompt &key buffers initial-input)
  86. "Switch to a buffer using `al/completing-read-engine'.
  87. Specifying BUFFERS is not supported by `ido' engine."
  88. (interactive (list "Switch to buffer: "))
  89. (cond
  90. ((and (eq 'ivy al/completing-read-engine)
  91. (require 'ivy nil t))
  92. ;; Disable flx match, as I prefer to sort buffers chronologically.
  93. (let (ivy--flx-featurep)
  94. (ivy-read prompt
  95. (or buffers (mapcar #'buffer-name (buffer-list)))
  96. :initial-input initial-input
  97. :matcher 'ivy--switch-buffer-matcher
  98. :preselect (unless initial-input
  99. (buffer-name (other-buffer (current-buffer))))
  100. :action 'ivy--switch-buffer-action
  101. :keymap ivy-switch-buffer-map
  102. :caller 'ivy-switch-buffer)))
  103. ((and (null buffers)
  104. (eq 'ido al/completing-read-engine)
  105. (require 'ido nil t))
  106. (ido-buffer-internal ido-default-buffer-method
  107. nil prompt nil initial-input))
  108. (t
  109. (completing-read-default prompt buffers nil nil initial-input))))
  110. (defun al/switch-to-buffer-or-funcall (buffer &optional function)
  111. "Switch to BUFFER or call FUNCTION.
  112. BUFFER can be nil, a string, a buffer object or a function
  113. returning one of those. If there is no such buffer, call
  114. FUNCTION if it is specified."
  115. (let* ((buffer (if (functionp buffer)
  116. (funcall buffer)
  117. buffer))
  118. (buffer (and buffer (get-buffer buffer))))
  119. (if buffer
  120. (switch-to-buffer buffer)
  121. (when function (funcall function)))))
  122. ;;;###autoload
  123. (defun al/switch-to-characters (&optional charset)
  124. "Switch to the buffer with unicode characters from CHARSET.
  125. If CHARSET is nil, use `unicode-bmp'. With prefix, use `unicode-smp'."
  126. (interactive
  127. (list (and current-prefix-arg 'unicode-smp)))
  128. (al/switch-to-buffer-or-funcall
  129. "*Character List*"
  130. (lambda () (list-charset-chars (or charset 'unicode-bmp)))))
  131. ;;;###autoload
  132. (defun al/switch-to-packages ()
  133. "Switch to the buffer with packages."
  134. (interactive)
  135. (al/switch-to-buffer-or-funcall
  136. "*Packages*" #'list-packages))
  137. (provide 'al-buffer)
  138. ;;; al-buffer.el ends here