From mboxrd@z Thu Jan 1 00:00:00 1970 From: Eric Schulte Subject: Re: layout org-babel menu WAS: About org-babel menu Date: Tue, 10 Apr 2012 21:40:39 -0400 Message-ID: <87pqbfhwq0.fsf@gmx.com> References: <87d388lo8f.fsf@gmail.com> <87pqc8acwy.fsf@gmx.com> <4F67458D.5090904@gmail.com> <87mx71mymu.fsf@gnu.org> <4F7D6125.40309@gmail.com> <87pqbm8i0t.fsf@gmx.com> <87bon4pm03.fsf@gmx.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([208.118.235.92]:57791) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SHoQb-0004Gw-G6 for emacs-orgmode@gnu.org; Tue, 10 Apr 2012 23:41:07 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SHoQX-0000xT-VO for emacs-orgmode@gnu.org; Tue, 10 Apr 2012 23:41:05 -0400 Received: from mailout-us.gmx.com ([74.208.5.67]:56519 helo=mailout-us.mail.com) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1SHoQX-0000xF-ME for emacs-orgmode@gnu.org; Tue, 10 Apr 2012 23:41:01 -0400 List-Id: "General discussions about Org-mode." List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org Sender: emacs-orgmode-bounces+geo-emacs-orgmode=m.gmane.org@gnu.org To: "Thomas S. Dye" Cc: FengShu , emacs-orgmode@gnu.org --=-=-= Content-Type: text/plain tsd@tsdye.com (Thomas S. Dye) writes: > Eric Schulte writes: > >> Torsten Wagner writes: >> >>> Hi, >>> >>> for me the biggest "trouble" with babel is to remember the possible >>> keywords in the header for different languages. >>> There were a lot of ongoing syntax change which did not make it easier >>> for me to remember all this. >>> Thus a menu which is organised by languages offering all possible >>> settings for each language would be very helpful. >>> | >>> Python >>> | | >>> | export - code - result - both - none >>> | | >>> | tangle - no - yes- filename >>> | | >>> | result - value - output >>> | | >>> | ... >>> | >>> ... >>> >>> Not sure how effectual this would be in a main menu. It would be >>> definitely awesome in a context menu >>> >>> That would be (copied from worg) [*] indicates cursor position >>> >>> #+NAME: factorial >>> #+BEGIN_SRC haskell [*] :results silent :exports code :var n=0 >>> >>> a context menu would appear presenting all possible header arguments for haskell >>> >>> #+NAME: factorial >>> #+BEGIN_SRC haskell :results [*] :exports code :var n=0 >>> >>> a context menu presenting all possible values for the header argument >>> :results in haskell >>> I guess that together with the possibility to call this menu by >>> keyboard strokes or alternatively show the same infos in the >>> minibuffer would be a great win for babel and it would make many >>> questions here on the list unnecessary. >>> Furthermore, any change or extension in the syntax for a certain >>> language would be directly reflected to the end-user. E.g., If I >>> suddenly see the menu entry :exports 3dprint, I would be curious and >>> check it out on worg and the manual ;) >>> >>> Totti >>> >> >> Hi, >> >> I've put together a first pass at such support for interactive header >> argument look up. Please evaluate this elisp code [1] in your *scratch* >> buffer, then in an Org-mode buffer insert a code block like the >> following with the point at [*], and press tab. >> >> #+begin_src R :[*] >> :foo >> #+end_src >> >> You should see an auto-completion list showing which header arguments >> are available and (for those with known arguments) which arguments may >> be specified. This includes language specific header arguments, i.e., >> the R code block above suggests about twice as many possible header >> arguments as an elisp block. Note this "expand on tab after :" behavior >> is active on "#+headers:" lines as well. >> >> This makes use of the `org-babel-common-header-args-w-values' variable >> which holds header argument names and completions, as well as the >> org-babel-header-arg-names:lang variables. >> >> Does this seem like a good interface? >> >> Is it missing any important functionality? >> >> Best, >> >> Footnotes: >> [1] >> ;; Add support for completing-read insertion of header arguments after ":" >> (defun org-babel-header-arg-expand () >> "Call `org-babel-enter-header-arg-w-completion' in appropriate contexts." >> (when (and (= (char-before) ?\:) (org-babel-where-is-src-block-head)) >> (org-babel-enter-header-arg-w-completion (match-string 2)))) >> >> (defun org-babel-enter-header-arg-w-completion (&optional lang) >> "Insert header argument appropriate for LANG with completion." >> (let* ((lang-headers-var (intern (concat "org-babel-header-arg-names:" lang))) >> (lang-headers (when (boundp lang-headers-var) >> (mapcar #'symbol-name (eval lang-headers-var)))) >> (headers (append (mapcar #'symbol-name org-babel-header-arg-names) >> lang-headers)) >> (header (org-completing-read "Header Arg: " headers)) >> (args (cdr (assoc (intern header) >> org-babel-common-header-args-w-values))) >> (arg (when (and args (listp args)) >> (org-completing-read >> (format "%s: " header) >> (mapcar #'symbol-name (car args)))))) >> (insert (concat header " " (or arg ""))) >> (cons header arg))) >> >> (add-hook 'org-tab-first-hook 'org-babel-header-arg-expand) > > Hi Eric, > > This is potentially much nicer than a function template. I tried > filling out an R source code block's header arguments, but I couldn't > find a way to get :results output graphics, which I use frequently for > ggplot2 graphics. With TAB I could see type arguments, but not > collection or handling arguments. Is there some way to cycle through > the various completion lists? > > All the best, > Tom Hi Tom, Currently language specific arguments for header arguments are not stored in any elisp variables so there is no way to provide this information to the auto completion function. I'm adding a new suite of language-specific variables which may be customized by each language to provide information on language-specific header-argument arguments. I've just put together this new code into a patch. I'm not currently able to run the test suite without massive failures (with or without this patch), so I'm just attaching the patch here rather than pushing it up directly. If it works well on other people's systems I think it should be committed. After this is applied the language-specific header argument variables will need to be fleshed out. For example see the value of the `org-babel-header-args:R' which includes the "graphics" results option. The arguments of these variables will override the arguments of specific headers in the global `org-babel-common-header-args-w-values' variable. Best, --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-code-block-languages-may-specify-their-own-headers-a.patch >From ff3d974ff4d0aa93d3c241709557f6858ebf284f Mon Sep 17 00:00:00 2001 From: Eric Schulte Date: Tue, 10 Apr 2012 19:03:37 -0400 Subject: [PATCH] code-block languages may specify their own headers and values * lisp/ob-R.el (org-babel-header-args:R): Adding values. * lisp/ob-clojure.el (org-babel-header-args:clojure): Adding values. * lisp/ob-lisp.el (org-babel-header-args:lisp): Adding values. * lisp/ob-sql.el (org-babel-header-args:sql): Adding values. * lisp/ob-sqlite.el (org-babel-header-args:sqlite): Adding values. * lisp/ob.el (org-babel-combine-header-arg-lists): Combine lists of arguments and values. (org-babel-insert-header-arg): Use new combined header argument lists. (org-babel-header-arg-expand): Add support for completing-read insertion of header arguments after ":" (org-babel-enter-header-arg-w-completion): Completing read insertion of header arguments (org-tab-first-hook): Adding header argument completion. (org-babel-params-from-properties): Combining header argument lists. * testing/lisp/test-ob.el (ob-test/org-babel-combine-header-arg-lists): Test the new header argument combination functionality. --- lisp/ob-R.el | 29 +++++++++++++++++++--- lisp/ob-clojure.el | 2 +- lisp/ob-lisp.el | 2 +- lisp/ob-sql.el | 5 ++-- lisp/ob-sqlite.el | 14 +++++++++-- lisp/ob.el | 62 +++++++++++++++++++++++++++++++++++++---------- testing/lisp/test-ob.el | 18 ++++++++++++++ 7 files changed, 109 insertions(+), 23 deletions(-) diff --git a/lisp/ob-R.el b/lisp/ob-R.el index 49a8a85..9538dc4 100644 --- a/lisp/ob-R.el +++ b/lisp/ob-R.el @@ -40,10 +40,31 @@ (declare-function ess-eval-buffer "ext:ess-inf" (vis)) (declare-function org-number-sequence "org-compat" (from &optional to inc)) -(defconst org-babel-header-arg-names:R - '(width height bg units pointsize antialias quality compression - res type family title fonts version paper encoding - pagecentre colormodel useDingbats horizontal) +(defconst org-babel-header-args:R + '((width . :any) + (height . :any) + (bg . :any) + (units . :any) + (pointsize . :any) + (antialias . :any) + (quality . :any) + (compression . :any) + (res . :any) + (type . :any) + (family . :any) + (title . :any) + (fonts . :any) + (version . :any) + (paper . :any) + (encoding . :any) + (pagecentre . :any) + (colormodel . :any) + (useDingbats . :any) + (horizontal . :any) + (results . ((file list vector table scalar verbatim) + (raw org html latex code pp wrap) + (replace silent append prepend) + (output value graphics)))) "R-specific header arguments.") (defvar org-babel-default-header-args:R '()) diff --git a/lisp/ob-clojure.el b/lisp/ob-clojure.el index 69d3db8..f389404 100644 --- a/lisp/ob-clojure.el +++ b/lisp/ob-clojure.el @@ -45,7 +45,7 @@ (add-to-list 'org-babel-tangle-lang-exts '("clojure" . "clj")) (defvar org-babel-default-header-args:clojure '()) -(defvar org-babel-header-arg-names:clojure '(package)) +(defvar org-babel-header-args:clojure '((package . :any))) (defun org-babel-expand-body:clojure (body params) "Expand BODY according to PARAMS, return the expanded body." diff --git a/lisp/ob-lisp.el b/lisp/ob-lisp.el index 8fb6721..89dbe24 100644 --- a/lisp/ob-lisp.el +++ b/lisp/ob-lisp.el @@ -41,7 +41,7 @@ (add-to-list 'org-babel-tangle-lang-exts '("lisp" . "lisp")) (defvar org-babel-default-header-args:lisp '()) -(defvar org-babel-header-arg-names:lisp '(package)) +(defvar org-babel-header-args:lisp '((package . :any))) (defcustom org-babel-lisp-dir-fmt "(let ((*default-pathname-defaults* #P%S)) %%s)" diff --git a/lisp/ob-sql.el b/lisp/ob-sql.el index 20fbad3..e3f6edd 100644 --- a/lisp/ob-sql.el +++ b/lisp/ob-sql.el @@ -51,8 +51,9 @@ (defvar org-babel-default-header-args:sql '()) -(defvar org-babel-header-arg-names:sql - '(engine out-file)) +(defvar org-babel-header-args:sql + '((engine . :any) + (out-file . :any))) (defun org-babel-expand-body:sql (body params) "Expand BODY according to the values of PARAMS." diff --git a/lisp/ob-sqlite.el b/lisp/ob-sqlite.el index 84d6bb2..2106072 100644 --- a/lisp/ob-sqlite.el +++ b/lisp/ob-sqlite.el @@ -37,8 +37,18 @@ (defvar org-babel-default-header-args:sqlite '()) -(defvar org-babel-header-arg-names:sqlite - '(db header echo bail csv column html line list separator nullvalue) +(defvar org-babel-header-args:sqlite + '((db . :any) + (header . :any) + (echo . :any) + (bail . :any) + (csv . :any) + (column . :any) + (html . :any) + (line . :any) + (list . :any) + (separator . :any) + (nullvalue . :any)) "Sqlite specific header args.") (defun org-babel-expand-body:sqlite (body params) diff --git a/lisp/ob.el b/lisp/ob.el index 726245c..df401b0 100644 --- a/lisp/ob.el +++ b/lisp/ob.el @@ -622,6 +622,19 @@ arguments and pop open the results in a preview buffer." (mmin (in (1- i) j) (in i (1- j)) (in (1- i) (1- j))))))) (in l1 l2)))) +(defun org-babel-combine-header-arg-lists (original &rest others) + "Combine a number of lists of header argument names and arguments." + (let ((results (copy-sequence original))) + (dolist (new-list others) + (dolist (arg-pair new-list) + (let ((header (car arg-pair)) + (args (cdr arg-pair))) + (setq results + (cons arg-pair (org-remove-if + (lambda (pair) (equal header (car pair))) + results)))))) + results)) + ;;;###autoload (defun org-babel-check-src-block () "Check for misspelled header arguments in the current code block." @@ -649,12 +662,10 @@ arguments and pop open the results in a preview buffer." "Insert a header argument selecting from lists of common args and values." (interactive) (let* ((lang (car (org-babel-get-src-block-info 'light))) - (lang-headers (intern (concat "org-babel-header-arg-names:" lang))) - (headers (append (if (boundp lang-headers) - (mapcar (lambda (h) (cons h :any)) - (eval lang-headers)) - nil) - org-babel-common-header-args-w-values)) + (lang-headers (intern (concat "org-babel-header-args:" lang))) + (headers (org-babel-combine-header-arg-lists + org-babel-common-header-args-w-values + (if (boundp lang-headers) (eval lang-headers) nil))) (arg (org-icompleting-read "Header Arg: " (mapcar @@ -679,6 +690,30 @@ arguments and pop open the results in a preview buffer." ""))) vals "")))))))) +;; Add support for completing-read insertion of header arguments after ":" +(defun org-babel-header-arg-expand () + "Call `org-babel-enter-header-arg-w-completion' in appropriate contexts." + (when (and (= (char-before) ?\:) (org-babel-where-is-src-block-head)) + (org-babel-enter-header-arg-w-completion (match-string 2)))) + +(defun org-babel-enter-header-arg-w-completion (&optional lang) + "Insert header argument appropriate for LANG with completion." + (let* ((lang-headers-var (intern (concat "org-babel-header-args:" lang))) + (lang-headers (when (boundp lang-headers-var) (eval lang-headers-var))) + (headers-w-values (org-babel-combine-header-arg-lists + org-babel-common-header-args-w-values lang-headers)) + (headers (mapcar #'symbol-name (mapcar #'car headers-w-values))) + (header (org-completing-read "Header Arg: " headers)) + (args (cdr (assoc (intern header) headers-w-values))) + (arg (when (and args (listp args)) + (org-completing-read + (format "%s: " header) + (mapcar #'symbol-name (apply #'append args)))))) + (insert (concat header " " (or arg ""))) + (cons header arg))) + +(add-hook 'org-tab-first-hook 'org-babel-header-arg-expand) + ;;;###autoload (defun org-babel-load-in-session (&optional arg info) "Load the body of the current source-code block. @@ -1153,13 +1188,14 @@ may be specified in the properties of the current outline entry." (cons (intern (concat ":" header-arg)) (org-babel-read val)))) (mapcar - 'symbol-name - (append - org-babel-header-arg-names - (progn - (setq sym (intern (concat "org-babel-header-arg-names:" - lang))) - (and (boundp sym) (eval sym))))))))))) + #'symbol-name + (mapcar + #'car + (org-babel-combine-header-arg-lists + org-babel-common-header-args-w-values + (progn + (setq sym (intern (concat "org-babel-header-args:" lang))) + (and (boundp sym) (eval sym)))))))))))) (defvar org-src-preserve-indentation) (defun org-babel-parse-src-block-match () diff --git a/testing/lisp/test-ob.el b/testing/lisp/test-ob.el index 4dac696..5cf689a 100644 --- a/testing/lisp/test-ob.el +++ b/testing/lisp/test-ob.el @@ -87,6 +87,24 @@ '((:session . "none") (:results . "replace") (:exports . "results")) org-babel-default-inline-header-args))) +(ert-deftest ob-test/org-babel-combine-header-arg-lists () + (let ((results (org-babel-combine-header-arg-lists + '((foo . :any) + (bar) + (baz . ((foo bar) (baz))) + (qux . ((foo bar baz qux))) + (quux . ((foo bar)))) + '((bar) + (baz . ((baz))) + (quux . :any))))) + (dolist (pair '((foo . :any) + (bar) + (baz . ((baz))) + (quux . :any) + (qux . ((foo bar baz qux))))) + (should (equal (cdr pair) + (cdr (assoc (car pair) results))))))) + ;;; ob-get-src-block-info (ert-deftest test-org-babel/get-src-block-info-language () (org-test-at-marker nil org-test-file-ob-anchor -- 1.7.10 --=-=-= Content-Type: text/plain -- Eric Schulte http://cs.unm.edu/~eschulte/ --=-=-=--