al-file-cmd.el 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158
  1. ;;; al-file-cmd.el --- Interactive commands for working with files
  2. ;; Copyright © 2012–2019 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. (require 'al-read)
  17. (declare-function counsel-find-file "counsel" t)
  18. ;;;###autoload
  19. (defun al/find-file (&optional dir)
  20. "Find file starting from DIR if it is non-nil.
  21. Call either `counsel-find-file' or `ido-find-file'."
  22. (interactive)
  23. (let ((default-directory (file-name-as-directory
  24. (or dir default-directory))))
  25. (if (fboundp 'counsel-find-file)
  26. (counsel-find-file)
  27. (ido-find-file))))
  28. ;;;###autoload
  29. (defun al/sudo-find-file (&optional arg)
  30. "Find current file or dired directory with root privileges.
  31. If ARG is nil use `find-alternate-file', otherwise - `find-file'."
  32. (interactive "P")
  33. (let ((file (or (and (eq major-mode 'dired-mode)
  34. dired-directory)
  35. buffer-file-name
  36. (error "Current buffer should visit a file or be in a dired-mode")))
  37. (window-start (window-start))
  38. (point (point))
  39. (mark (and mark-active (region-beginning))))
  40. (funcall (if arg #'find-file #'find-alternate-file)
  41. (format "/sudo::%s" file))
  42. (and mark (set-mark mark))
  43. (goto-char point)
  44. (set-window-start nil window-start)))
  45. (defvar al/ssh-default-user user-login-name
  46. "A default user name for `al/ssh-find-file'.
  47. Can be a string or a list of strings (names).")
  48. (defvar al/ssh-default-host "remote-host"
  49. "A default host name for `al/ssh-find-file'.
  50. Can be a string or a list of strings (hosts).")
  51. ;;;###autoload
  52. (defun al/ssh-find-file (&optional user host)
  53. "Find a file for a USER on a HOST using tramp ssh method.
  54. If USER and HOST are not specified, values from
  55. `al/ssh-default-user' and `al/ssh-default-host' will be used.
  56. Interactively with \\[universal-argument] prompt for a user name,
  57. with \\[universal-argument] \\[universal-argument] prompt for a default host as well."
  58. (interactive
  59. (list (and (or (equal current-prefix-arg '(4))
  60. (equal current-prefix-arg '(16)))
  61. (ido-completing-read "User: "
  62. (if (listp al/ssh-default-user)
  63. al/ssh-default-user
  64. (list al/ssh-default-user))))
  65. (and (equal current-prefix-arg '(16))
  66. (ido-completing-read "Host: "
  67. (if (listp al/ssh-default-host)
  68. al/ssh-default-host
  69. (list al/ssh-default-host))))))
  70. (or user (setq user (or (and (listp al/ssh-default-user)
  71. (car al/ssh-default-user))
  72. al/ssh-default-user)))
  73. (or host (setq host (or (and (listp al/ssh-default-host)
  74. (car al/ssh-default-host))
  75. al/ssh-default-host)))
  76. (with-current-buffer
  77. (find-file-noselect (format "/ssh:%s@%s:/" user host))
  78. (ido-find-file)))
  79. ;;; Files in PATH
  80. (defvar al/path-completions nil
  81. "List of names of executable files from PATH.")
  82. (defun al/refresh-path-completions ()
  83. "Refresh `al/path-completions'."
  84. (interactive)
  85. (let ((regexp (rx "." (zero-or-one ".") "/")))
  86. (setq al/path-completions
  87. (sort (locate-file-completion-table
  88. exec-path exec-suffixes ""
  89. (lambda (name)
  90. (not (string-match-p regexp name)))
  91. t)
  92. #'string<))))
  93. ;;;###autoload
  94. (defun al/find-file-in-path (file)
  95. "Edit executable FILE found in PATH environment variable."
  96. (interactive
  97. (progn
  98. (unless al/path-completions
  99. (al/refresh-path-completions))
  100. (list (completing-read "Find PATH file: "
  101. al/path-completions))))
  102. (let ((file (executable-find file)))
  103. (when file
  104. (find-file file))))
  105. ;;; Renaming files
  106. (declare-function dired-get-filename "dired" t)
  107. ;;;###autoload
  108. (defun al/replace-space-in-file-names (dir &optional recursive string)
  109. "Rename files in DIR by replacing space in their names with STRING.
  110. Rename DIR itself if needed. If recursive is non-nil, rename
  111. files in all sub-directories recursively. If STRING is nil, use
  112. '_'."
  113. (interactive
  114. (list (let* ((dir (and (derived-mode-p 'dired-mode)
  115. (dired-get-filename)))
  116. (dir (and (file-directory-p dir) dir)))
  117. (read-directory-name "Directory: " dir))
  118. (y-or-n-p "Recursively? ")
  119. (al/read-string "Replace space with: " nil nil "_")))
  120. (or string (setq string "_"))
  121. (let* ((regexp ".* .*")
  122. (dir (directory-file-name (expand-file-name dir)))
  123. (files (if recursive
  124. (directory-files-recursively dir regexp t)
  125. (directory-files dir t regexp t)))
  126. (files (if (string-match-p regexp dir)
  127. (append files (list dir))
  128. files)))
  129. (dolist (file files)
  130. (let* ((new-name (replace-regexp-in-string
  131. " " string (file-name-nondirectory file)))
  132. (new-file (expand-file-name new-name
  133. (file-name-directory file))))
  134. (message "Renaming '%s' to '%s'." file new-file)
  135. (rename-file file new-file)))))
  136. (provide 'al-file-cmd)
  137. ;;; al-file-cmd.el ends here