Browse Source

Merge commit 'jan/org-file-apps-ex'

Conflicts:
	lisp/ChangeLog
Carsten Dominik 15 years ago
parent
commit
4b475bcd11
2 changed files with 64 additions and 46 deletions
  1. 15 11
      lisp/ChangeLog
  2. 49 35
      lisp/org.el

+ 15 - 11
lisp/ChangeLog

@@ -1,3 +1,18 @@
+2010-04-10  Jan Böcker  <jan.boecker@jboecker.de>
+
+	* org.el (org-file-apps-entry-match-against-dlink-p): new function.
+	(org-file-apps-ex): remove variable.
+	(org-open-file): Integrate org-file-apps-ex functionality back
+	into org-file-apps, and decide whether to match a regexp against
+	the link or the filename using org-file-apps-entry-uses-grouping-p.
+
+2010-04-09  Jan Böcker  <jan.boecker@jboecker.de>
+
+	* org.el (org-file-apps-ex): new variable.
+	(org-open-file): Before considering org-file-apps, first match the
+	regexps from org-file-apps-ex against the whole link. See
+	docstring of org-file-apps-ex.
+
 2010-04-12  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org.el (org-export-latex-default-packages-alist): Remove
@@ -17,7 +32,6 @@
 	frames.
 	(org-export-latex-default-packages-alist): hyperref must be loaded
 	late.
-	(org-open-file): More care with the new matching for file links.
 
 2010-04-07  Carsten Dominik  <carsten.dominik@gmail.com>
 
@@ -302,16 +316,6 @@
 	(org-table-get, org-table-put, org-table-goto-line)
 	(org-table-current-line): New functions.
 
-2010-03-21  Jan Böcker  <jan.boecker@jboecker.de>
-
-	* org.el (org-open-file): Allow regular expressions in
-	org-file-apps to capture link parameters using groups.  In a
-	command string to be executed, the parameters can be referenced
-	using %1, %2, etc.  Lisp forms can access them using
-	(match-string n link).
-	(org-apps-regexp-alist): Adopt the created regexp, as this is now
-	matched against a file: link instead of the file name.
-
 2010-03-21  Carsten Dominik  <carsten.dominik@gmail.com>
 
 	* org-crypt.el (org-reveal-start-hook): Add a decryption function

+ 49 - 35
lisp/org.el

@@ -1463,10 +1463,9 @@ you can use this variable to set the application for a given file
 extension.  The entries in this list are cons cells where the car identifies
 files and the cdr the corresponding command.  Possible values for the
 file identifier are
- \"regex\"       Regular expression matched against the file: link.  For
-               backward compatibility, this can also be a string with only
-               alphanumeric characters, which is then interpreted as an
-               extension.
+ \"regex\"     Regular expression matched against the file name.  For backward
+               compatibility, this can also be a string with only alphanumeric
+               characters, which is then interpreted as an extension.
  `directory'   Matches a directory
  `remote'      Matches a remote file, accessible through tramp or efs.
                Remote files most likely should be visited through Emacs
@@ -1495,13 +1494,9 @@ Possible values for the command are:
                does define this command, but you can overrule/replace it
                here.
  string        A command to be executed by a shell; %s will be replaced
-               by the path to the file.  If the file identifier is a regex,
-               %n will be replaced by the match of the nth match group.
+               by the path to the file.
  sexp          A Lisp form which will be evaluated.  The file path will
-               be available in the Lisp variable `file', the link itself
-               in the Lisp variable `link'. If the file identifier is a regex,
-               the original match data will be restored, so subexpression
-               matches are accessible using (match-string n link).
+               be available in the Lisp variable `file'.
 For more examples, see the system specific constants
 `org-file-apps-defaults-macosx'
 `org-file-apps-defaults-windowsnt'
@@ -1523,6 +1518,8 @@ For more examples, see the system specific constants
 			(string :tag "Command")
 			(sexp :tag "Lisp form")))))
 
+
+
 (defgroup org-refile nil
   "Options concerning refiling entries in Org-mode."
   :tag "Org Refile"
@@ -9136,17 +9133,17 @@ With optional prefix argument IN-EMACS, Emacs will visit the file.
 With a double C-c C-u prefix arg, Org tries to avoid opening in Emacs
 and to use an external application to visit the file.
 
-Optional LINE specifies a line to go to, optional SEARCH a string to
-search for.  If LINE or SEARCH is given, but IN-EMACS is nil, it will
-be assumed that org-open-file was called to open a file: link, and the
-original link to match against org-file-apps will be reconstructed
-from PATH and whichever of LINE or SEARCH is given.
-
+Optional LINE specifies a line to go to, optional SEARCH a string
+to search for.  If LINE or SEARCH is given, the file will be
+opened in Emacs, unless an entry from org-file-apps that makes
+use of groups in a regexp matches.  
 If the file does not exist, an error is thrown."
   (let* ((file (if (equal path "")
 		   buffer-file-name
 		 (substitute-in-file-name (expand-file-name path))))
-	 (apps (append org-file-apps (org-default-apps)))
+	 (file-apps (append org-file-apps (org-default-apps)))
+	 (apps (remove-if 'org-file-apps-entry-match-against-dlink-p file-apps))
+	 (apps-dlink (remove-if-not 'org-file-apps-entry-match-against-dlink-p file-apps))
 	 (remp (and (assq 'remote apps) (org-file-remote-p file)))
 	 (dirp (if remp nil (file-directory-p file)))
 	 (file (if (and dirp org-open-directory-means-index-dot-org)
@@ -9178,21 +9175,19 @@ If the file does not exist, an error is thrown."
      (t
       (setq cmd (or (and remp (cdr (assoc 'remote apps)))
 		    (and dirp (cdr (assoc 'directory apps)))
-		    ;; if we find a match in org-file-apps, store the match
-		    ;; data for later
-		    (let* ((re-list1 (org-apps-regexp-alist apps nil))
-			   (re-list2 
-			    (if a-m-a-p
-				(org-apps-regexp-alist apps a-m-a-p)
-			      re-list1))
-			   (private-match
-			    (assoc-default dlink re-list1 'string-match))
-			   (general-match
-			    (assoc-default dfile re-list2 'string-match)))
-		      (if private-match
+		    ; first, try matching against apps-dlink
+		    ; if we get a match here, store the match data for later
+		    (let ((match (assoc-default dlink apps-dlink
+						'string-match)))
+		      (if match
 			  (progn (setq link-match-data (match-data))
-				 private-match)
-			general-match))
+				 match)
+			(progn (setq in-emacs (or in-emacs line search))
+			       nil))) ; if we have no match in apps-dlink,
+		                      ; always open the file in emacs if line or search
+		                      ; is given (for backwards compatibility)
+		    (assoc-default dfile (org-apps-regexp-alist apps a-m-a-p)
+				   'string-match)
 		    (cdr (assoc ext apps))
 		    (cdr (assoc t apps))))))
     (when (eq cmd 'system)
@@ -9222,6 +9217,7 @@ If the file does not exist, an error is thrown."
 		     (shell-quote-argument
 		      (convert-standard-filename file)))
 		   t t cmd)))
+
       ;; Replace "%1", "%2" etc. in command with group matches from regex
       (save-match-data
 	(let ((match-index 1)
@@ -9233,7 +9229,7 @@ If the file does not exist, an error is thrown."
 	      (while (string-match regex cmd)
 		(setq cmd (replace-match replace-with t t cmd))))
 	    (setq match-index (+ match-index 1)))))
-
+      
       (save-window-excursion
 	(start-process-shell-command cmd nil cmd)
 	(and (boundp 'org-wait) (numberp org-wait) (sit-for org-wait))
@@ -9248,13 +9244,32 @@ If the file does not exist, an error is thrown."
       (let ((file (convert-standard-filename file)))
 	(save-match-data
 	  (set-match-data link-match-data)
-	  (eval cmd))))
+	  (eval cmd))))	
      (t (funcall (cdr (assq 'file org-link-frame-setup)) file)))
     (and (org-mode-p) (eq old-mode 'org-mode)
 	 (or (not (equal old-buffer (current-buffer)))
 	     (not (equal old-pos (point))))
 	 (org-mark-ring-push old-pos old-buffer))))
 
+(defun org-file-apps-entry-match-against-dlink-p (entry)
+  "This function returns non-nil if `entry' uses a regular
+  expression which should be matched against the whole link by
+  org-open-file.
+
+ It assumes that is the case when the entry uses a regular
+ expression which has at least one grouping construct and the
+ action is either a lisp form or a command string containing
+ '%1', i.e. using at least one subexpression match as a
+ parameter."
+  (let ((selector (car entry))
+	(action (cdr entry)))
+    (if (stringp selector)
+	(and (> (regexp-opt-depth selector) 0)
+	     (or (and (stringp action)
+		      (string-match "%1" action))
+		 (consp action)))
+      nil)))
+
 (defun org-default-apps ()
   "Return the default applications for this operating system."
   (cond
@@ -9278,8 +9293,7 @@ be opened in Emacs."
 		       nil
 		     (if (string-match "\\W" (car x))
 			 x
-		       (cons (concat "\\." (car x) "\\(::.*\\)?\\'")
-			     (cdr x)))))
+		       (cons (concat "\\." (car x) "\\'") (cdr x)))))
 		 list))
    (if add-auto-mode
        (mapcar (lambda (x) (cons (car x) 'emacs)) auto-mode-alist))))