From: Andreas Gerler Date: Wed, 2 Mar 2016 13:51:18 +0000 (+0100) Subject: adding dired-narrow X-Git-Url: http://git.bundesbrandschatzamt.de/?a=commitdiff_plain;h=301c97d125be9e108e8d562a48acb0d028d49853;p=emacsconfig.git adding dired-narrow - bound to / in dired mode. --- diff --git a/bba.org b/bba.org index a672c182..2bcf666c 100644 --- a/bba.org +++ b/bba.org @@ -2218,6 +2218,8 @@ character before any spaces." (define-key bba/toggle "s" 'flyspell-mode) (define-key bba/toggle "v" 'visual-line-mode) (define-key bba/toggle "\S-w" 'which-function-mode) + + (define-key dired-mode-map "/" 'dired-narrow-regexp) #+END_SRC Toggle Whitespace mode on and off. Whitespace mode causes all hard diff --git a/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils-autoloads.el b/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils-autoloads.el new file mode 100644 index 00000000..62b29e58 --- /dev/null +++ b/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils-autoloads.el @@ -0,0 +1,16 @@ +;;; dired-hacks-utils-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil nil ("dired-hacks-utils.el") (22230 42873 811802 +;;;;;; 0)) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; dired-hacks-utils-autoloads.el ends here diff --git a/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils-pkg.el b/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils-pkg.el new file mode 100644 index 00000000..fbd53bde --- /dev/null +++ b/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils-pkg.el @@ -0,0 +1 @@ +(define-package "dired-hacks-utils" "20150819.948" "Utilities and helpers for dired-hacks collection" '((dash "2.5.0")) :keywords '("files")) diff --git a/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils.el b/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils.el new file mode 100644 index 00000000..1eafe499 --- /dev/null +++ b/elpa/dired-hacks-utils-20150819.948/dired-hacks-utils.el @@ -0,0 +1,205 @@ +;;; dired-hacks-utils.el --- Utilities and helpers for dired-hacks collection + +;; Copyright (C) 2014-2015 Matúš Goljer + +;; Author: Matúš Goljer +;; Maintainer: Matúš Goljer +;; Keywords: files +;; Package-Version: 20150819.948 +;; Version: 0.0.1 +;; Created: 14th February 2014 +;; Package-requires: ((dash "2.5.0")) + +;; This program is free software; you can redistribute it and/or modify +;; it under the terms of the GNU General Public License as published by +;; the Free Software Foundation, either version 3 of the License, or +;; (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; Utilities and helpers for `dired-hacks' collection of dired +;; improvements. + +;; This package also provides these interactive functions: +;; * `dired-hacks-next-file' - go to next file, skipping empty and non-file lines +;; * `dired-hacks-previous-file' - go to previous file, skipping empty +;; and non-file lines + +;; See https://github.com/Fuco1/dired-hacks for the entire collection + +;;; Code: + +(require 'dash) +(require 'dired) + +(defgroup dired-hacks () + "Collection of useful dired additions." + :group 'dired + :prefix "dired-hacks-") + +(defun dired-utils-get-filename (&optional localp) + "Like `dired-get-filename' but never signal an error." + (dired-get-filename localp t)) + +(defun dired-utils-get-all-files (&optional localp) + "Return all files in this dired buffer as a list. + +LOCALP has same semantics as in `dired-get-filename'." + (save-excursion + (goto-char (point-min)) + (let (r) + (while (= 0 (forward-line)) + (--when-let (dired-utils-get-filename localp) + (push it r))) + (nreverse r)))) + +(defconst dired-utils-file-attributes-keywords + '(:isdir :nlinks :uid :gid :atime :mtime :ctime :size :modes :gidchg :inode :devnum) + "List of keywords to map with `file-attributes'.") + +(defconst dired-utils-info-keywords + `(:name :issym :target ,@dired-utils-file-attributes-keywords) + "List of keywords available for `dired-utils-get-info'.") + +(defun dired-utils--get-keyword-info (keyword) + (let ((filename (dired-utils-get-filename))) + (cl-case keyword + (:name filename) + (:isdir (file-directory-p filename)) + (:issym (and (file-symlink-p filename) t)) + (:target (file-symlink-p filename)) + (t + (nth (-elem-index keyword dired-utils-file-attributes-keywords) + (file-attributes filename)))))) + +(defun dired-utils-get-info (&rest keywords) + "Query for info about the file at point. + +When querying for one attribute, its value is returned. When +querying for more than one, a list of results is returned. + +The available attributes are listed in +`dired-utils-info-keywords'." + (let ((attributes (mapcar 'dired-utils--get-keyword-info keywords))) + (if (> (length attributes) 1) + attributes + (car attributes)))) + +(defun dired-utils-goto-line (filename) + "Go to line describing FILENAME in listing. + +Should be absolute file name matched against +`dired-get-filename'." + (goto-char (point-min)) + (let (stop) + (while (and (not stop) + (= (forward-line) 0)) + (when (equal filename (dired-utils-get-filename)) + (setq stop t) + (dired-move-to-filename))) + stop)) + +(defun dired-utils-match-filename-regexp (filename alist) + "Match FILENAME against each car in ALIST and return first matched cons. + +Each car in ALIST is a regular expression. + +The matching is done using `string-match-p'." + (let (match) + (--each-while alist (not match) + (when (string-match-p (car it) filename) + (setq match it))) + match)) + +(defun dired-utils-match-filename-extension (filename alist) + "Match FILENAME against each car in ALIST and return first matched cons. + +Each car in ALIST is a string representing file extension +*without* the delimiting dot." + (let (done) + (--each-while alist (not done) + (when (string-match-p (concat "\\." (regexp-quote (car it)) "\\'") file) + (setq done it))) + done)) + + +;;; Predicates +(defun dired-utils-is-file-p () + "Return non-nil if the line at point is a file or a directory." + (dired-utils-get-filename 'no-dir)) + +(defun dired-utils-is-dir-p () + "Return non-nil if the line at point is a directory." + (--when-let (dired-utils-get-filename) + (file-directory-p it))) + + +;;; Interactive +;; TODO: add wrap-around option +(defun dired-hacks-next-file (&optional arg) + "Move point to the next file. + +Optional prefix ARG says how many lines to move; default is one +line." + (interactive "p") + (unless arg (setq arg 1)) + (if (< arg 0) + (dired-hacks-previous-file (- arg)) + (--dotimes arg + (forward-line) + (while (and (or (not (dired-utils-is-file-p)) + (get-text-property (point) 'invisible)) + (= (forward-line) 0)))) + (if (not (= (point) (point-max))) + (dired-move-to-filename) + (forward-line -1) + (dired-move-to-filename) + nil))) + +(defun dired-hacks-previous-file (&optional arg) + "Move point to the previous file. + +Optional prefix ARG says how many lines to move; default is one +line." + (interactive "p") + (unless arg (setq arg 1)) + (if (< arg 0) + (dired-hacks-next-file (- arg)) + (--dotimes arg + (forward-line -1) + (while (and (or (not (dired-utils-is-file-p)) + (get-text-property (point) 'invisible)) + (= (forward-line -1) 0)))) + (if (not (= (point) (point-min))) + (dired-move-to-filename) + (dired-hacks-next-file) + nil))) + +(defun dired-hacks-compare-files (file-a file-b) + "Test if two files FILE-A and FILE-B are the (probably) the same." + (interactive (let ((other-dir (dired-dwim-target-directory))) + (list (read-file-name "File A: " default-directory (car (dired-get-marked-files)) t) + (read-file-name "File B: " other-dir (with-current-buffer (cdr (assoc other-dir dired-buffers)) + (car (dired-get-marked-files))) t)))) + (let ((md5-a (with-temp-buffer + (shell-command (format "md5sum %s" file-a) (current-buffer)) + (buffer-string))) + (md5-b (with-temp-buffer + (shell-command (format "md5sum %s" file-b) (current-buffer)) + (buffer-string)))) + (message "%s%sFiles are %s." md5-a md5-b + (if (equal (car (split-string md5-a)) + (car (split-string md5-b))) + "probably the same" "different")))) + +(provide 'dired-hacks-utils) + +;;; dired-hacks-utils.el ends here diff --git a/elpa/dired-narrow-20160130.845/dired-narrow-autoloads.el b/elpa/dired-narrow-20160130.845/dired-narrow-autoloads.el new file mode 100644 index 00000000..03a2cc07 --- /dev/null +++ b/elpa/dired-narrow-20160130.845/dired-narrow-autoloads.el @@ -0,0 +1,42 @@ +;;; dired-narrow-autoloads.el --- automatically extracted autoloads +;; +;;; Code: +(add-to-list 'load-path (or (file-name-directory #$) (car load-path))) + +;;;### (autoloads nil "dired-narrow" "dired-narrow.el" (22230 42874 +;;;;;; 0 0)) +;;; Generated autoloads from dired-narrow.el + +(autoload 'dired-narrow-regexp "dired-narrow" "\ +Narrow a dired buffer to the files matching a regular expression. + +\(fn)" t nil) + +(autoload 'dired-narrow "dired-narrow" "\ +Narrow a dired buffer to the files matching a string. + +If the string contains spaces, then each word is matched against +the file name separately. To succeed, all of them have to match +but the order does not matter. + +For example \"foo bar\" matches filename \"bar-and-foo.el\". + +\(fn)" t nil) + +(autoload 'dired-narrow-fuzzy "dired-narrow" "\ +Narrow a dired buffer to the files matching a fuzzy string. + +A fuzzy string is constructed from the filter string by inserting +\".*\" between each letter. This is then matched as regular +expression against the file name. + +\(fn)" t nil) + +;;;*** + +;; Local Variables: +;; version-control: never +;; no-byte-compile: t +;; no-update-autoloads: t +;; End: +;;; dired-narrow-autoloads.el ends here diff --git a/elpa/dired-narrow-20160130.845/dired-narrow-pkg.el b/elpa/dired-narrow-20160130.845/dired-narrow-pkg.el new file mode 100644 index 00000000..a2e97269 --- /dev/null +++ b/elpa/dired-narrow-20160130.845/dired-narrow-pkg.el @@ -0,0 +1 @@ +(define-package "dired-narrow" "20160130.845" "Live-narrowing of search results for dired" '((dash "2.7.0") (dired-hacks-utils "0.0.1")) :keywords '("files")) diff --git a/elpa/dired-narrow-20160130.845/dired-narrow.el b/elpa/dired-narrow-20160130.845/dired-narrow.el new file mode 100644 index 00000000..d13c6fe8 --- /dev/null +++ b/elpa/dired-narrow-20160130.845/dired-narrow.el @@ -0,0 +1,290 @@ +;;; dired-narrow.el --- Live-narrowing of search results for dired + +;; Copyright (C) 2014-2015 Matúš Goljer + +;; Author: Matúš Goljer +;; Maintainer: Matúš Goljer +;; Version: 0.0.1 +;; Package-Version: 20160130.845 +;; Created: 14th February 2014 +;; Package-requires: ((dash "2.7.0") (dired-hacks-utils "0.0.1")) +;; Keywords: files + +;; This program is free software; you can redistribute it and/or +;; modify it under the terms of the GNU General Public License +;; as published by the Free Software Foundation; either version 3 +;; of the License, or (at your option) any later version. + +;; This program is distributed in the hope that it will be useful, +;; but WITHOUT ANY WARRANTY; without even the implied warranty of +;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +;; GNU General Public License for more details. + +;; You should have received a copy of the GNU General Public License +;; along with this program. If not, see . + +;;; Commentary: + +;; This package provides live filtering of files in dired buffers. In +;; general, after calling the respective narrowing function you type a +;; filter string into the minibuffer. After each change the changes +;; automatically reflect in the buffer. Typing C-g will cancel the +;; narrowing and restore the original view, typing RET will exit the +;; live filtering mode and leave the dired buffer in the narrowed +;; state. To bring it back to the original view, you can call +;; `revert-buffer' (usually bound to `g'). + +;; During the filtering process, several special functions are +;; available. You can customize the binding by changing +;; `dired-narrow-map'. + +;; * `dired-narrow-next-file' () - move the point to the next file +;; * `dired-narrow-previous-file' () - move the point to the +;; previous file +;; * `dired-narrow-enter-directory' () - descend into the +;; directory under point and immediately go back to narrowing mode + +;; You can customize what happens after exiting the live filtering +;; mode by customizing `dired-narrow-exit-action'. + +;; These narrowing functions are provided: + +;; * `dired-narrow' +;; * `dired-narrow-regexp' +;; * `dired-narrow-fuzzy' + +;; You can also create your own narrowing functions quite easily. To +;; define new narrowing function, use `dired-narrow--internal' and +;; pass it an apropriate filter. The filter should take one argument +;; which is the filter string from the minibuffer. It is then called +;; at each line that describes a file with point at the beginning of +;; the file name. If the filter returns nil, the file is removed from +;; the view. As an inspiration, look at the built-in functions +;; mentioned above. + +;; See https://github.com/Fuco1/dired-hacks for the entire collection. + +;;; Code: + +(require 'dash) +(require 'dired-hacks-utils) + +(require 'delsel) + +(defgroup dired-narrow () + "Live-narrowing of search results for dired." + :group 'dired-hacks + :prefix "dired-narrow-") + +(defvar dired-narrow-map + (let ((map (make-sparse-keymap))) + (define-key map (kbd "") 'dired-narrow-previous-file) + (define-key map (kbd "") 'dired-narrow-next-file) + (define-key map (kbd "") 'dired-narrow-enter-directory) + (define-key map (kbd "C-g") 'minibuffer-keyboard-quit) + (define-key map (kbd "RET") 'exit-minibuffer) + (define-key map (kbd "") 'exit-minibuffer) + map) + "Keymap used while `dired-narrow' is reading the pattern.") + +(defcustom dired-narrow-exit-action 'ignore + "Function to call after exiting minibuffer. + +Function takes no argument and is called with point over the file +we should act on." + :type '(choice (const :tag "Open file under point" dired-narrow-find-file) + (function :tag "Use custom function.")) + :group 'dired-narrow) + + +;; Utils + +;; this is `gnus-remove-text-with-property' +(defun dired-narrow--remove-text-with-property (prop) + "Delete all text in the current buffer with text property PROP." + (let ((start (point-min)) + end) + (unless (get-text-property start prop) + (setq start (next-single-property-change start prop))) + (while start + (setq end (text-property-any start (point-max) prop nil)) + (delete-region start (or end (point-max))) + (setq start (when end + (next-single-property-change start prop)))))) + +(defvar dired-narrow-filter-function 'identity + "Filter function used to filter the dired view.") + +(defvar dired-narrow--current-file nil + "Value of point just before exiting minibuffer.") + +(defun dired-narrow--update (filter) + "Make the files not matching the FILTER invisible." + (save-excursion + (goto-char (point-min)) + (let ((inhibit-read-only t)) + ;; TODO: we might want to call this only if the filter gets less + ;; specialized. + (dired-narrow--restore) + (while (dired-hacks-next-file) + (if (funcall dired-narrow-filter-function filter) + (when (fboundp 'dired-insert-set-properties) + (dired-insert-set-properties (line-beginning-position) (1+ (line-end-position)))) + (put-text-property (line-beginning-position) (1+ (line-end-position)) :dired-narrow t) + (put-text-property (line-beginning-position) (1+ (line-end-position)) 'invisible :dired-narrow))))) + (unless (dired-hacks-next-file) + (dired-hacks-previous-file)) + (unless (dired-utils-get-filename) + (dired-hacks-previous-file))) + +(defun dired-narrow--restore () + "Restore the invisible files of the current buffer." + (let ((inhibit-read-only t)) + (remove-text-properties (point-min) (point-max) '(invisible)) + (when (fboundp 'dired-insert-set-properties) + (dired-insert-set-properties (point-min) (point-max))))) + + +;; Live filtering + +(defvar dired-narrow-buffer nil + "Dired buffer we are currently filtering.") + +(defvar dired-narrow--minibuffer-content "" + "Content of the minibuffer during narrowing.") + +(defun dired-narrow--minibuffer-setup () + "Set up the minibuffer for live filtering." + (when dired-narrow-buffer + (add-hook 'post-command-hook 'dired-narrow--live-update nil :local))) + +(add-hook 'minibuffer-setup-hook 'dired-narrow--minibuffer-setup) + +(defun dired-narrow--live-update () + "Update the dired buffer based on the contents of the minibuffer." + (when dired-narrow-buffer + (let ((current-filter (minibuffer-contents-no-properties))) + (with-current-buffer dired-narrow-buffer + (unless (equal current-filter dired-narrow--minibuffer-content) + (dired-narrow--update current-filter)) + (setq dired-narrow--minibuffer-content current-filter) + (setq dired-narrow--current-file (dired-utils-get-filename)) + (set-window-point (get-buffer-window (current-buffer)) (point)))))) + +(defun dired-narrow--internal (filter-function) + "Narrow a dired buffer to the files matching a filter. + +The function FILTER-FUNCTION is called on each line: if it +returns non-nil, the line is kept, otherwise it is removed. The +function takes one argument, which is the current filter string +read from minibuffer." + (let ((dired-narrow-buffer (current-buffer)) + (dired-narrow-filter-function filter-function) + (disable-narrow nil)) + (unwind-protect + (progn + (dired-narrow-mode 1) + (add-to-invisibility-spec :dired-narrow) + (setq disable-narrow (read-from-minibuffer "Filter: " nil dired-narrow-map)) + (let ((inhibit-read-only t)) + (dired-narrow--remove-text-with-property :dired-narrow)) + ;; If the file no longer exists, we can't do anything, so + ;; set to nil + (unless (dired-utils-goto-line dired-narrow--current-file) + (setq dired-narrow--current-file nil))) + (with-current-buffer dired-narrow-buffer + (unless disable-narrow (dired-narrow-mode -1)) + (remove-from-invisibility-spec :dired-narrow) + (dired-narrow--restore)) + (when (and disable-narrow + dired-narrow--current-file + dired-narrow-exit-action) + (funcall dired-narrow-exit-action)) + (cond + ((equal disable-narrow "dired-narrow-enter-directory") + (dired-narrow--internal filter-function)))))) + + +;; Interactive + +(defun dired-narrow--regexp-filter (filter) + (re-search-forward filter (line-end-position) t)) + +;;;###autoload +(defun dired-narrow-regexp () + "Narrow a dired buffer to the files matching a regular expression." + (interactive) + (dired-narrow--internal 'dired-narrow--regexp-filter)) + +(defun dired-narrow--string-filter (filter) + (let ((words (split-string filter " "))) + (--all? (save-excursion (search-forward it (line-end-position) t)) words))) + +(defun dired-narrow-next-file () + "Move point to the next file." + (interactive) + (with-current-buffer dired-narrow-buffer + (dired-hacks-next-file))) + +(defun dired-narrow-previous-file () + "Move point to the previous file." + (interactive) + (with-current-buffer dired-narrow-buffer + (dired-hacks-previous-file))) + +(defun dired-narrow-find-file () + "Run `dired-find-file' or any remapped action on file under point." + (interactive) + (let ((function (or (command-remapping 'dired-find-file) + 'dired-find-file))) + (funcall function))) + +(defun dired-narrow-enter-directory () + "Descend into directory under point and initiate narrowing." + (interactive) + (let ((inhibit-read-only t)) + (erase-buffer) + (insert "dired-narrow-enter-directory")) + (exit-minibuffer)) + +;;;###autoload +(defun dired-narrow () + "Narrow a dired buffer to the files matching a string. + +If the string contains spaces, then each word is matched against +the file name separately. To succeed, all of them have to match +but the order does not matter. + +For example \"foo bar\" matches filename \"bar-and-foo.el\"." + (interactive) + (dired-narrow--internal 'dired-narrow--string-filter)) + +(defun dired-narrow--fuzzy-filter (filter) + (re-search-forward + (mapconcat 'regexp-quote + (mapcar 'char-to-string (string-to-list filter)) + ".*") + (line-end-position) t)) + +;;;###autoload +(defun dired-narrow-fuzzy () + "Narrow a dired buffer to the files matching a fuzzy string. + +A fuzzy string is constructed from the filter string by inserting +\".*\" between each letter. This is then matched as regular +expression against the file name." + (interactive) + (dired-narrow--internal 'dired-narrow--fuzzy-filter)) + +(define-minor-mode dired-narrow-mode + "Minor mode for indicating when narrowing is in progress." + :lighter " dired-narrow") + +(defun dired-narrow--disable-on-revert () + "Disable `dired-narrow-mode' after revert." + (dired-narrow-mode -1)) + +(add-hook 'dired-after-readin-hook 'dired-narrow--disable-on-revert) + +(provide 'dired-narrow) +;;; dired-narrow.el ends here diff --git a/elpa/dired-narrow-readme.txt b/elpa/dired-narrow-readme.txt new file mode 100644 index 00000000..5d03f72b --- /dev/null +++ b/elpa/dired-narrow-readme.txt @@ -0,0 +1,38 @@ +This package provides live filtering of files in dired buffers. In +general, after calling the respective narrowing function you type a +filter string into the minibuffer. After each change the changes +automatically reflect in the buffer. Typing C-g will cancel the +narrowing and restore the original view, typing RET will exit the +live filtering mode and leave the dired buffer in the narrowed +state. To bring it back to the original view, you can call +`revert-buffer' (usually bound to `g'). + +During the filtering process, several special functions are +available. You can customize the binding by changing +`dired-narrow-map'. + +* `dired-narrow-next-file' () - move the point to the next file +* `dired-narrow-previous-file' () - move the point to the + previous file +* `dired-narrow-enter-directory' () - descend into the + directory under point and immediately go back to narrowing mode + +You can customize what happens after exiting the live filtering +mode by customizing `dired-narrow-exit-action'. + +These narrowing functions are provided: + +* `dired-narrow' +* `dired-narrow-regexp' +* `dired-narrow-fuzzy' + +You can also create your own narrowing functions quite easily. To +define new narrowing function, use `dired-narrow--internal' and +pass it an apropriate filter. The filter should take one argument +which is the filter string from the minibuffer. It is then called +at each line that describes a file with point at the beginning of +the file name. If the filter returns nil, the file is removed from +the view. As an inspiration, look at the built-in functions +mentioned above. + +See https://github.com/Fuco1/dired-hacks for the entire collection.