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: Wed, 11 Apr 2012 09:59:20 -0400 Message-ID: <87iph64bev.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> <87pqbfhwq0.fsf@gmx.com> <4F853242.3020600@gmail.com> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="=-=-=" Return-path: Received: from eggs.gnu.org ([208.118.235.92]:58056) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SI04N-0000ye-Gk for emacs-orgmode@gnu.org; Wed, 11 Apr 2012 12:07:01 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SI04F-0005cN-FG for emacs-orgmode@gnu.org; Wed, 11 Apr 2012 12:06:55 -0400 Received: from mailout-us.gmx.com ([74.208.5.67]:39959) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1SI04F-0005cG-6q for emacs-orgmode@gnu.org; Wed, 11 Apr 2012 12:06:47 -0400 In-Reply-To: <4F853242.3020600@gmail.com> (Rainer M. Krug's message of "Wed, 11 Apr 2012 09:26:58 +0200") 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: R.M.Krug@gmail.com Cc: FengShu , emacs-orgmode@gnu.org, "Thomas S. Dye" --=-=-= Content-Type: text/plain Rainer M Krug writes: > On 11/04/12 03:40, Eric Schulte wrote: >> 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. > > Hi > > I applied the patch and it seems to be working when used on #+header: but on > #+src_begin R :[*] > #+end_src > > it folds the code block when tab is pressed at [*] > > No detailed further tests done. > > Cheers, > > Rainer > Thanks for checking this out. Please try this new attached version which move the header argument auto completion to the front of the org-tab-first-hook. Thanks, --=-=-= Content-Type: text/x-patch Content-Disposition: inline; filename=0001-code-block-languages-may-specify-their-own-headers-a.patch >From a450373c69f1556bf9838112587352c743097f5d 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/org.el (org-tab-first-hook): Adding header argument auto-completion to the tab hook. --- 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 | 60 +++++++++++++++++++++++++++++++++++++---------- lisp/org.el | 4 ++++ testing/lisp/test-ob.el | 18 ++++++++++++++ 8 files changed, 111 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..8a514ae 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,28 @@ 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))) + ;;;###autoload (defun org-babel-load-in-session (&optional arg info) "Load the body of the current source-code block. @@ -1153,13 +1186,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/lisp/org.el b/lisp/org.el index 170ddc9..96872ec 100644 --- a/lisp/org.el +++ b/lisp/org.el @@ -6793,6 +6793,10 @@ Optional arguments START and END can be used to limit the range." ;; org-tab-after-check-for-cycling-hook (add-hook 'org-tab-first-hook 'org-hide-block-toggle-maybe) + +;; should proceed the previous function in the `org-tab-first-hook' +(add-hook 'org-tab-first-hook 'org-babel-header-arg-expand) + ;; Remove overlays when changing major mode (add-hook 'org-mode-hook (lambda () (org-add-hook 'change-major-mode-hook 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 > >> >> 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, >> >> >> >> >> -- Eric Schulte http://cs.unm.edu/~eschulte/ --=-=-=--