From 970947c80b98d00d0b54aee6d56e73d3c4688c7b Mon Sep 17 00:00:00 2001 From: Sean O'Rourke Date: Sat, 10 May 2008 14:16:04 -0700 Subject: [PATCH] Fix bugs, add list-author functionality. --- ChangeLog | 11 ++++++ lib/Sepia/CPAN.pm | 27 ++++++++++---- sepia-cpan.el | 106 ++++++++++++++++++++++++++++++++++-------------------- 3 files changed, 99 insertions(+), 45 deletions(-) diff --git a/ChangeLog b/ChangeLog index cfd969b..6120991 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,14 @@ +2008-05-10 Sean O'Rourke + + * sepia-cpan.el (sepia-cpan-list, sepia-cpan-make-buffer) + (sepia-cpan-search): added list-by-author, refactored. + (sepia-cpan-readme): insert temp file rather than passing as + string. + + * lib/Sepia/CPAN.pm (ls): new function to list author's modules. + * lib/Sepia/Debug.pm (repl_finish): mostly-working, by adding 0x10 + to $^P and looking at sub's last line. + 2008-01-10 Sean O'Rourke * lib/Sepia.pm (columnate): true -> defined diff --git a/lib/Sepia/CPAN.pm b/lib/Sepia/CPAN.pm index f289e92..5d6a3ff 100644 --- a/lib/Sepia/CPAN.pm +++ b/lib/Sepia/CPAN.pm @@ -1,5 +1,5 @@ package Sepia::CPAN; -use CPAN; +use CPAN (); use LWP::Simple; sub init @@ -14,6 +14,15 @@ sub list grep $_->inst_file, CPAN::Shell->expand('Module', shift || '/./'); } +sub ls +{ + my $want = shift; + grep { + # XXX: key to test in this order, because inst_file is slow. + $_->userid eq $want && $_->inst_file + } CPAN::Shell->expand('Module', '/./') +} + sub interesting_parts { my $mod = shift; @@ -30,6 +39,7 @@ sub readme { my $dist = CPAN::Shell->expand('Module', shift); return unless $dist; + my $wantfile = shift; $dist = $dist->cpan_file; # my ($dist) = $self->id; my ($sans, $suffix) = $dist =~ /(.+)\.(tgz|tar[\._-]gz|tar\.Z|zip)$/; @@ -38,11 +48,16 @@ sub readme $CPAN::Config->{keep_source_where}, "authors", "id", split(/\//,"$sans.readme")); $local_file = CPAN::FTP->localize("authors/id/$sans.readme", $local_wanted); - local (*IN, $/); - open IN, $local_wanted; - my $ret = ; - close IN; - $ret; + ## Return filename rather than contents to avoid Elisp reader issues... + if ($wantfile) { + $local_file; + } else { + local (*IN, $/); + open IN, $local_wanted; + my $ret = ; + close IN; + $ret; + } } sub perldoc diff --git a/sepia-cpan.el b/sepia-cpan.el index db4fef0..d09dfb8 100644 --- a/sepia-cpan.el +++ b/sepia-cpan.el @@ -5,6 +5,7 @@ ("d" . sepia-cpan-doc) ("i" . sepia-cpan-install) ("b" . sepia-cpan-browse) + ("q" . bury-buffer) ("?" . sepia-cpan-readme))) ;;;###autoload @@ -18,7 +19,8 @@ "Display the README file for MOD." (interactive "sModule: ") (with-current-buffer (get-buffer-create "*sepia-cpan-readme*") - (insert (sepia-call "Sepia::CPAN::readme" 'list-context mod)) + (insert-file-contents + (sepia-call "Sepia::CPAN::readme" 'scalar-context mod 1)) (pop-to-buffer (current-buffer)))) ;;;###autoload @@ -29,10 +31,16 @@ (sepia-call "Sepia::CPAN::install" 'void-context mod))) ;;;###autoload -(defun sepia-cpan-list (pattern) +(defun sepia-cpan-do-search (pattern) "Return a list modules matching PATTERN." ;; (interactive "sPattern (regexp): ") - (sepia-eval (format "map { Sepia::CPAN::interesting_parts $_ } Sepia::CPAN::list('/%s/')" pattern) + (sepia-eval (format "do { require Sepia::CPAN; map { Sepia::CPAN::interesting_parts $_ } Sepia::CPAN::list('/%s/') }" pattern) + 'list-context)) + +(defun sepia-cpan-do-list (pattern) + "Return a list modules matching PATTERN." + ;; (interactive "sPattern (regexp): ") + (sepia-eval (format "do { require Sepia::CPAN; map { Sepia::CPAN::interesting_parts $_ } Sepia::CPAN::ls('%s') }" (upcase pattern)) 'list-context)) (defun sepia-cpan-button (button) @@ -65,9 +73,14 @@ (define-derived-mode sepia-cpan-mode view-mode "CPAN" "Major mode for CPAN browsing.") -;;;###autoload -(defun sepia-cpan-search (pat) - (interactive "sPattern (regexp): ") +(defun string-repeat (s n) + "Repeat S N times." + (let ((ret "")) + (dotimes (i n) + (setq ret (concat ret s))) + ret)) + +(defun sepia-cpan-make-buffer (title mods fields names) (switch-to-buffer "*sepia-cpan*") (sepia-cpan-mode) (setq buffer-read-only nil) @@ -75,40 +88,55 @@ (erase-buffer)) (remove-overlays) (insert (format "\ -CPAN modules matching /%s/ - [r]eadme, [d]ocumentation, [i]nstall, [s]earch - -" pat)) - (let ((mods (sepia-cpan-list pat)) - (fields - '("id" "fullname" "inst_version" "cpan_version" "cpan_file")) - lengths fmt) - (when mods - (dolist (mod mods) - (setcdr (assoc "cpan_file" mod) - (replace-regexp-in-string "^.*/" "" - (cdr (assoc "cpan_file" mod))))) - (setq lengths - (mapcar - (lambda (f) - (+ 2 (apply #'max (mapcar - (lambda (x) - (length (format "%s" (cdr (assoc f x))))) - mods)))) - fields)) - (setq fmt - (concat (mapconcat (lambda (x) (format "%%-%ds" x)) lengths "") - "\n")) - (insert (format fmt "Module" "Author" "Inst." "CPAN" "Distribution")) - (insert (format fmt "------" "------" "-----" "----" "------------")) - (dolist (mod mods) - (let ((beg (point))) - (insert - (apply #'format fmt - (mapcar (lambda (x) (cdr (assoc x mod))) fields))) - (make-button beg (+ beg (length (cdr (assoc "id" mod)))) - :type 'sepia-cpan))))) +%s + [r]eadme, [d]ocumentation, [i]nstall, [s]earch, [l]ist, [q]uit + +" title)) + (when mods + (dolist (mod mods) + (setcdr (assoc "cpan_file" mod) + (replace-regexp-in-string "^.*/" "" + (cdr (assoc "cpan_file" mod))))) + (setq lengths + (mapcar + (lambda (f) + (+ 2 (apply #'max (mapcar + (lambda (x) + (length (format "%s" (cdr (assoc f x))))) + mods)))) + fields)) + (setq fmt + (concat (mapconcat (lambda (x) (format "%%-%ds" x)) lengths "") + "\n")) + (insert (apply 'format fmt names)) + (insert (apply 'format fmt + (mapcar (lambda (x) (string-repeat "-" (length x))) names))) + (dolist (mod mods) + (let ((beg (point))) + (insert + (apply #'format fmt + (mapcar (lambda (x) (or (cdr (assoc x mod)) "-")) fields))) + (make-button beg (+ beg (length (cdr (assoc "id" mod)))) + :type 'sepia-cpan)))) (setq buffer-read-only t truncate-lines t)) +;;;###autoload +(defun sepia-cpan-list (name) + (interactive "sAuthor: ") + (sepia-cpan-make-buffer + (concat "CPAN modules by " name) + (sepia-cpan-do-list name) + '("id" "inst_version" "cpan_version" "cpan_file") + '("Module" "Inst." "CPAN" "Distribution"))) + +;;;###autoload +(defun sepia-cpan-search (pat) + (interactive "sPattern (regexp): ") + (sepia-cpan-make-buffer + (concat "CPAN modules matching /" pat "/") + (sepia-cpan-do-search pat) + '("id" "fullname" "inst_version" "cpan_version" "cpan_file") + '("Module" "Author" "Inst." "CPAN" "Distribution"))) + (provide 'sepia-cpan) -- 2.11.4.GIT