| @@ -153,6 +153,7 @@ found, otherwise returns nil." | |||||
| ilookup | ilookup | ||||
| pasteboard | pasteboard | ||||
| awk-preview | awk-preview | ||||
| recently | |||||
| )) | )) | ||||
| @@ -708,6 +709,9 @@ found, otherwise returns nil." | |||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | ||||
| ;; file handling | ;; file handling | ||||
| (when (safe-require-or-eval 'recently) | |||||
| (recently-mode 1)) | |||||
| (when (safe-require-or-eval 'editorconfig) | (when (safe-require-or-eval 'editorconfig) | ||||
| ;; (set-variable 'editorconfig-get-properties-function | ;; (set-variable 'editorconfig-get-properties-function | ||||
| ;; 'editorconfig-core-get-properties-hash) | ;; 'editorconfig-core-get-properties-hash) | ||||
| @@ -1812,243 +1816,6 @@ and search from projectile root (if projectile is available)." | |||||
| (editorconfig-auto-apply-mode 1) | (editorconfig-auto-apply-mode 1) | ||||
| ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; | |||||
| ;; recently | |||||
| (defgroup recently nil | |||||
| "Recently visited files" | |||||
| :tag "Recently" | |||||
| :prefix "recently-" | |||||
| :group 'tools) | |||||
| (defcustom recently-file | |||||
| (concat user-emacs-directory | |||||
| "recently.el") | |||||
| "Recently file." | |||||
| :type 'string | |||||
| :group 'recently) | |||||
| (defcustom recently-max | |||||
| 100 | |||||
| "Recently list max length." | |||||
| :type 'int | |||||
| :group 'recently) | |||||
| (defcustom recently-excludes | |||||
| '() | |||||
| "List of regexps for filenames excluded from the recent list." | |||||
| :type '(repeat string) | |||||
| :group 'recently) | |||||
| (add-to-list 'recently-excludes | |||||
| (eval-when-compile (rx "/COMMIT_EDITMSG" eot))) | |||||
| (defvar recently-list | |||||
| '() | |||||
| "Recently list.") | |||||
| (defvar recently-file-mtime | |||||
| nil | |||||
| "Modified time of file when last read file.") | |||||
| (defun recently-write () | |||||
| "Write to file." | |||||
| ;; Failsafe to avoid purging all existing entries | |||||
| (cl-assert recently-list) | |||||
| (with-temp-buffer | |||||
| (prin1 recently-list | |||||
| (current-buffer)) | |||||
| (write-region (point-min) | |||||
| (point-max) | |||||
| recently-file))) | |||||
| (defun recently-read () | |||||
| "Read file." | |||||
| (when (file-readable-p recently-file) | |||||
| (with-temp-buffer | |||||
| (insert-file-contents recently-file) | |||||
| (goto-char (point-min)) | |||||
| (setq recently-list | |||||
| (read (current-buffer)))) | |||||
| (setq recently-file-mtime | |||||
| (nth 5 | |||||
| (file-attributes recently-file))))) | |||||
| (defun recently-reload () | |||||
| "Reload file and update `recently-list' value. | |||||
| This function does nothing when there is no update to `recently-file' since last | |||||
| read." | |||||
| (when (and (file-readable-p recently-file) | |||||
| (not (equal recently-file-mtime | |||||
| (nth 5 | |||||
| (file-attributes recently-file))))) | |||||
| (recently-read) | |||||
| (cl-assert (equal recently-file-mtime | |||||
| (nth 5 | |||||
| (file-attributes recently-file)))))) | |||||
| (defun recently-add (path) | |||||
| "Add PATH to list." | |||||
| (cl-assert (string= path | |||||
| (expand-file-name path))) | |||||
| (when (cl-loop for re in recently-excludes | |||||
| if (string-match re path) return nil | |||||
| finally return t) | |||||
| (recently-reload) | |||||
| (let* ((l (cl-copy-list recently-list)) | |||||
| (l (delete path | |||||
| l)) | |||||
| (l (cl-loop for e in l | |||||
| unless (file-in-directory-p path e) | |||||
| collect e)) | |||||
| (l (cons path | |||||
| l)) | |||||
| (l (recently--truncate l | |||||
| recently-max))) | |||||
| (unless (equal recently-list | |||||
| l) | |||||
| (setq recently-list l) | |||||
| (recently-write) | |||||
| (setq recently-file-mtime | |||||
| (nth 5 | |||||
| (file-attributes recently-file))))))) | |||||
| (defun recently--truncate (list len) | |||||
| "Truncate LIST to LEN." | |||||
| (if (> (length list) | |||||
| len) | |||||
| (cl-subseq list | |||||
| 0 | |||||
| len) | |||||
| list)) | |||||
| (defun recently-find-file-hook () | |||||
| "Add current file." | |||||
| (when buffer-file-name | |||||
| (recently-add buffer-file-name))) | |||||
| (defun recently-dired-mode-hook () | |||||
| "Add current directory." | |||||
| (recently-add (expand-file-name default-directory))) | |||||
| (add-hook 'find-file-hook | |||||
| 'recently-find-file-hook) | |||||
| (add-hook 'dired-mode-hook | |||||
| 'recently-dired-mode-hook) | |||||
| ;;;;;;;;;;;;;;;; | |||||
| ;; recently-show | |||||
| (defvar recently-show-window-configuration nil | |||||
| "Used for internal") | |||||
| (defvar recently-show-abbreviate t | |||||
| "Non-nil means use `abbreviate-file-name' when listing recently opened files.") | |||||
| ;;;###autoload | |||||
| (defun recently-show (&optional buffer-name) | |||||
| "Show simplified list of recently opened files. | |||||
| If optional argument BUFFER-NAME is non-nil, it is a buffer name to | |||||
| use for the buffer. It defaults to \"*recetf-show*\"." | |||||
| ;; If optional argument FILES is non-nil, it is a list of recently-opened | |||||
| ;; files to choose from. It defaults to the whole recent list. | |||||
| (interactive) | |||||
| (let ((bf (recently-show--create-buffer-tabulated buffer-name))) | |||||
| (if bf | |||||
| (progn | |||||
| (setq recently-show-window-configuration (current-window-configuration)) | |||||
| (pop-to-buffer bf)) | |||||
| (message "No recent file!")))) | |||||
| (defun recently-show--create-buffer-tabulated (&optional buffer-name) | |||||
| "Create buffer listing recently files." | |||||
| (let ((bname (or buffer-name | |||||
| "*Recently*"))) | |||||
| (when (get-buffer bname) | |||||
| (kill-buffer bname)) | |||||
| (with-current-buffer (get-buffer-create bname) | |||||
| ;; (setq tabulated-list-sort-key (cons "Name" nil)) | |||||
| (recently-show--set-tabulated-list-mode-variables) | |||||
| (recently-show-tabulated-mode) | |||||
| (current-buffer)))) | |||||
| (defun recently-show--set-tabulated-list-mode-variables () | |||||
| "Set variables for `tabulated-list-mode'." | |||||
| (recently-reload) | |||||
| (setq tabulated-list-entries | |||||
| (mapcar (lambda (f) | |||||
| (list f | |||||
| (vector (file-name-nondirectory f) | |||||
| (if recently-show-abbreviate | |||||
| (abbreviate-file-name f) | |||||
| f)))) | |||||
| recently-list | |||||
| )) | |||||
| (let ((max | |||||
| (apply 'max | |||||
| (mapcar (lambda (l) | |||||
| (length (elt (cadr l) 0))) | |||||
| tabulated-list-entries)))) | |||||
| (setq tabulated-list-format | |||||
| `[("Name" | |||||
| ,(min max | |||||
| 30) | |||||
| t) | |||||
| ("Full Path" 0 t)]))) | |||||
| (defun recently-show-tabulated-find-file () | |||||
| "Find file at point." | |||||
| (interactive) | |||||
| (let ((f (tabulated-list-get-id))) | |||||
| (cl-assert f nil "No entry at point") | |||||
| (recently-show-tabulated-close) | |||||
| (find-file f))) | |||||
| (defun recently-show-tabulated-view-file () | |||||
| "View file at point." | |||||
| (interactive) | |||||
| (let ((f (tabulated-list-get-id))) | |||||
| (cl-assert f nil "No entry at point") | |||||
| (recently-show-tabulated-close) | |||||
| (view-file f))) | |||||
| (defun recently-show-tabulated-dired() | |||||
| "Open dired buffer of directory at point." | |||||
| (interactive) | |||||
| (let ((f (tabulated-list-get-id))) | |||||
| (cl-assert f nil "No entry at point") | |||||
| (recently-show-tabulated-close) | |||||
| (dired (if (file-directory-p f) | |||||
| f | |||||
| (or (file-name-directory f) | |||||
| "."))))) | |||||
| (defvar recently-show-tabulated-mode-map | |||||
| (let ((map (make-sparse-keymap))) | |||||
| (suppress-keymap map) | |||||
| (define-key map (kbd "C-m") 'recently-show-tabulated-find-file) | |||||
| (define-key map "v" 'recently-show-tabulated-view-file) | |||||
| (define-key map "@" 'recently-show-tabulated-dired) | |||||
| (define-key map (kbd "C-g") 'recently-show-tabulated-close) | |||||
| (define-key map "/" 'isearch-forward) | |||||
| map)) | |||||
| (define-derived-mode recently-show-tabulated-mode tabulated-list-mode "Recently-Show" | |||||
| "Major mode for browsing recently opened files and directories." | |||||
| (setq tabulated-list-padding 2) | |||||
| (add-hook 'tabulated-list-revert-hook | |||||
| 'recently-show--set-tabulated-list-mode-variables | |||||
| nil | |||||
| t) | |||||
| (tabulated-list-init-header) | |||||
| (tabulated-list-print nil nil)) | |||||
| (defun recently-show-tabulated-close () | |||||
| "Close recently-show window." | |||||
| (interactive) | |||||
| (kill-buffer (current-buffer)) | |||||
| (set-window-configuration recently-show-window-configuration)) | |||||
| (define-key ctl-x-map (kbd "C-r") 'recently-show) | (define-key ctl-x-map (kbd "C-r") 'recently-show) | ||||