-
-
Notifications
You must be signed in to change notification settings - Fork 79
/
dired-avfs.el
130 lines (101 loc) · 4.56 KB
/
dired-avfs.el
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
;;; dired-avfs.el --- AVFS support for dired
;; Copyright (C) 2014 Matus Goljer
;; Author: Matus Goljer <[email protected]>
;; Maintainer: Matus Goljer <[email protected]>
;; Keywords: files
;; Version: 0.0.1
;; Created: 14th February 2014
;; Package-Requires: ((dash "2.5.0") (dired-hacks-utils "0.0.1") (emacs "24"))
;; URL: https://github.com/Fuco1/dired-hacks
;; 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 <http://www.gnu.org/licenses/>.
;;; Commentary:
;; Adds AVFS (http://avf.sourceforge.net/) support for seamless archive
;; browsing. This extension therefore depends on the presence of `avfsd'
;; on your system. In debian-derived distributions you can usually do
;;
;; apt-get install avfs
;;
;; `avfs' is probably also available for Mac OS. You're out of luck on
;; Windows, sorry.
;; Once the daemon is installed, run it with `mountavfs' and everything
;; "Should Just Work^TM".
;; See https://github.com/Fuco1/dired-hacks for the entire collection.
;;; Code:
(require 'dired-hacks-utils)
(require 'dash)
(defgroup dired-avfs ()
"AVFS support for dired."
:group 'dired-hacks
:prefix "dired-avfs-")
(defcustom dired-avfs-root "~/.avfs"
"Root where the avfs virtual filesystem is mounted."
:type 'directory
:group 'dired-avfs)
(defcustom dired-avfs-archives
'("zip" "rar" "tar" "tar.gz" "tgz" "tar.bz2" "tb2" "tbz2" "tar.xz" "txz" "tar.zst" "7z")
"Archives that are automagically opened via avfs."
:type '(repeat string)
:group 'dired-avfs)
(defcustom dired-avfs-hide-root t
"If non-nil, hide the avfs root in dired listing."
:type 'boolean
:group 'dired-avfs)
(defcustom dired-avfs-ignore-commands nil
"Do not open a file via avfs if it was opened using this command.
For example, this allows the user to open files via avfs from
dired, but not from `find-file'."
:type '(repeat function)
:group 'dired-avfs)
(defcustom dired-avfs-file-size-threshold 100
"Ask before opening files if their size exceeds this setting.
The value is in megabytes."
:type 'number
:group 'dired-avfs)
(defun dired-avfs--archive-filename (filename)
"Transform FILENAME into corresponding avfs filename."
(file-truename (concat dired-avfs-root (file-truename filename) "#")))
(defun dired-avfs--archive-p (filename)
"Non-nil if FILENAME should be opened in avfs."
(let ((extensions (concat "\\." (regexp-opt dired-avfs-archives) "\\'")))
(string-match-p extensions filename)))
(defun dired-avfs--open (filename)
"Open FILENAME as avfs filename."
(find-file (dired-avfs--archive-filename filename)))
(defun dired-avfs--hide-root ()
"Remove the avfs root prefix from the dired header."
(save-excursion
(when dired-avfs-hide-root
(goto-char (point-min))
(when (search-forward (file-truename dired-avfs-root) nil t)
(let ((inhibit-read-only t))
(put-text-property (match-beginning 0) (match-end 0) 'invisible t))))))
(add-hook 'dired-after-readin-hook 'dired-avfs--hide-root)
(defun dired-avfs-open ()
"Open file at point using avfs."
(interactive)
(dired-avfs--open (dired-file-name-at-point)))
(defadvice find-file-noselect (before fix-avfs-arguments activate)
"Change target filename to avfs-compatible filename.
If the target is archive that can be handled via avfs,
automagically change the filename to the location of virtual
directory representing this archive."
(when (and (not (memq this-command dired-avfs-ignore-commands))
(or (not (featurep 'tramp))
(not (tramp-tramp-file-p (ad-get-arg 0))))
(dired-avfs--archive-p (ad-get-arg 0))
(if (> (nth 7 (file-attributes (ad-get-arg 0))) (* dired-avfs-file-size-threshold 1048576))
(y-or-n-p (format "Size of this file exceeds `dired-avfs-file-size-threshold' (%d MB), extracting the information might take very long time. Do you want to continue?"
dired-avfs-file-size-threshold))
t))
(ad-set-arg 0 (dired-avfs--archive-filename (ad-get-arg 0)))))
(provide 'dired-avfs)
;;; dired-avfs.el ends here