diff options
author | Vitalie Spinu <spinuvit@gmail.com> | 2018-08-30 17:21:18 +0200 |
---|---|---|
committer | Bozhidar Batsov <bozhidar.batsov@gmail.com> | 2018-09-08 22:25:50 +0300 |
commit | 55740ea8e973fb1fcb90c65b068a076ab2022171 (patch) | |
tree | eca5270de7efefed129148486a88c290f73be835 | |
parent | 8996e699ae7dd140a9f74219940e2e30ff213fd9 (diff) |
Open archive entries within AVFS directory
-rw-r--r-- | CHANGELOG.md | 3 | ||||
-rw-r--r-- | cider-common.el | 80 | ||||
-rw-r--r-- | doc/interactive_programming.md | 27 |
3 files changed, 70 insertions, 40 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index 50d974cd..97f9faab 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,10 +2,13 @@ ## master (unreleased) +* [#2430](https://github.com/clojure-emacs/cider/issues/2375) `cider-find-var` opens archive files inside [AVFS](http://avf.sourceforge.net) folders if AVFS is detected. + ## 0.18.0 (2018-09-02) ### New features +* Open archive files within AVFS direcotires if AVFS has been detected. * [#2375](https://github.com/clojure-emacs/cider/issues/2375): Move `cider-eval-toplevel-inside-comment-form` into clojure-mode as `clojure-toplevel-inside-comment-form` so `beginning-of-defun` is aware of comment forms. * Add new `cider-session-name-template` variable for flexible customization of cider session and REPL buffer names. * Bind `C-c M-r` to `cider-restart`. diff --git a/cider-common.el b/cider-common.el index 3bae267a..08414c63 100644 --- a/cider-common.el +++ b/cider-common.el @@ -286,10 +286,13 @@ If no local or remote file exists, return nil." (defun cider-find-file (url) "Return a buffer visiting the file URL if it exists, or nil otherwise. If URL has a scheme prefix, it must represent a fully-qualified file path -or an entry within a zip/jar archive. If URL doesn't contain a scheme -prefix and is an absolute path, it is treated as such. Finally, if URL is -relative, it is expanded within each of the open Clojure buffers till an -existing file ending with URL has been found." +or an entry within a zip/jar archive. If AVFS (archive virtual file +system; see online docs) is mounted the archive entry is opened inside the +AVFS directory, otherwise the entry is archived into a temporary read-only +buffer. If URL doesn't contain a scheme prefix and is an absolute path, it +is treated as such. Finally, if URL is relative, it is expanded within each +of the open Clojure buffers till an existing file ending with URL has been +found." (require 'arc-mode) (cond ((string-match "^file:\\(.+\\)" url) (when-let* ((file (cider--url-to-file (match-string 1 url))) @@ -297,42 +300,39 @@ existing file ending with URL has been found." (find-file-noselect path))) ((string-match "^\\(jar\\|zip\\):\\(file:.+\\)!/\\(.+\\)" url) (when-let* ((entry (match-string 3 url)) - (file (cider--url-to-file (match-string 2 url))) - (path (cider--file-path file)) - ;; It is used for targeting useless intermediate buffer. - ;; That buffer is made by (find-file path) below. - ;; It has the name which is the last part of the path. - (trash (replace-regexp-in-string "^/.+/" "" path)) - (name (format "%s:%s" path entry))) - (or (find-buffer-visiting name) - (if (tramp-tramp-file-p path) - (progn - ;; Use emacs built in archiving. - ;; This makes a list of files in archived Zip or Jar. - ;; That list buffer is useless after jumping to the - ;; buffer which has the real definition. - ;; It'll be removed by (kill-buffer trash) below. - (find-file path) - (goto-char (point-min)) - ;; Make sure the file path is followed by a newline to - ;; prevent eg. clj matching cljs. - (search-forward (concat entry "\n")) - ;; moves up to matching line - (forward-line -1) - (archive-extract) - ;; Remove useless buffer made by (find-file path) above. - (kill-buffer trash) - (current-buffer)) - ;; Use external zip program to just extract the single file - (with-current-buffer (generate-new-buffer - (file-name-nondirectory entry)) - (archive-zip-extract path entry) - (set-visited-file-name name) - (setq-local default-directory (file-name-directory path)) - (setq-local buffer-read-only t) - (set-buffer-modified-p nil) - (set-auto-mode) - (current-buffer)))))) + (file (cider--url-to-file (match-string 2 url))) + (path (cider--file-path file)) + (name (format "%s:%s" path entry)) + (avfs (format "%s%s#uzip/%s" + (expand-file-name (or (getenv "AVFSBASE") "~/.avfs/")) + path entry))) + (cond + ;; 1) use avfs + ((file-exists-p avfs) + (find-file-noselect avfs)) + ;; 2) already uncompressed + ((find-buffer-visiting name)) + ;; 3) on remotes use Emacs built-in archiving + ((tramp-tramp-file-p path) + (find-file path) + (goto-char (point-min)) + ;; anchor to eol to prevent eg. clj matching cljs. + (re-search-forward (concat entry "$")) + (let ((archive-buffer (current-buffer))) + (archive-extract) + (kill-buffer archive-buffer)) + (current-buffer)) + ;; 4) Use external zip program to extract a single file + (t + (with-current-buffer (generate-new-buffer + (file-name-nondirectory entry)) + (archive-zip-extract path entry) + (set-visited-file-name name) + (setq-local default-directory (file-name-directory path)) + (setq-local buffer-read-only t) + (set-buffer-modified-p nil) + (set-auto-mode) + (current-buffer)))))) (t (if-let* ((path (cider--file-path url))) (find-file-noselect path) (unless (file-name-absolute-p url) diff --git a/doc/interactive_programming.md b/doc/interactive_programming.md index 92906d01..20d2c9bb 100644 --- a/doc/interactive_programming.md +++ b/doc/interactive_programming.md @@ -90,4 +90,31 @@ Here's a list of `cider-mode`'s keybindings: ![CIDER which-key](images/cider-which-key.png) + +!!! Tip + + `cider-find-var` has built-in support for [AVFS](). AVFS is an a virtual + file system which allows seamless navigation within archives as if they were + normal directories. When AVFS is mounted, `cider-find-var` automatically + opens `jar` and `zip` files inside AVFS folder instead of attempting to + uncompressed the archive. + + On linux based systems AVFS comes through the distribution managers. For + example on Debian derivatives: + + `sudo apt-get install avfs` + + Once installed mount with `mountavfs` in a place where it could be started + automatically during the startup (`.bash_profile` would do). Or initialize the + `avfsd` daemon directly like this + + `/usr/bin/avfsd -o allow_root -o intr -o sync_read .avfs` + + [AVFS]() is not available on Windows but could be installed on MacOS with [some + effort](http://blog.breadncup.com/tag/sunrise-commander/). Some other uses of + [AVFS]() in Emacs include + [dired-avfs](https://github.com/Fuco1/dired-hacks#dired-avfs) and + [sunrise-commander](https://www.emacswiki.org/emacs/Sunrise_Commander_Tips#toc12). + [which-key]: https://github.com/justbur/emacs-which-key +[AVFS]: http://avf.sourceforge.net |