From mboxrd@z Thu Jan 1 00:00:00 1970 From: tsd@tsdye.com (Thomas S. Dye) Subject: Re: layout org-babel menu WAS: About org-babel menu Date: Wed, 11 Apr 2012 10:12:06 -1000 Message-ID: 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> <87iph64bev.fsf@gmx.com> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Return-path: Received: from eggs.gnu.org ([208.118.235.92]:58804) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1SI3tu-0006sk-Jf for emacs-orgmode@gnu.org; Wed, 11 Apr 2012 16:12:28 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1SI3to-0004nh-9c for emacs-orgmode@gnu.org; Wed, 11 Apr 2012 16:12:22 -0400 Received: from oproxy9.bluehost.com ([69.89.24.6]:33976) by eggs.gnu.org with smtp (Exim 4.71) (envelope-from ) id 1SI3tn-0004n6-T2 for emacs-orgmode@gnu.org; Wed, 11 Apr 2012 16:12:16 -0400 In-Reply-To: <87iph64bev.fsf@gmx.com> (Eric Schulte's message of "Wed, 11 Apr 2012 09:59:20 -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: Eric Schulte Cc: FengShu , emacs-orgmode@gnu.org Eric Schulte writes: > 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, > > 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 > > >> >>> >>> 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, >>> >>> >>> >>> >>> Hi Eric, Sorry to hear the test suite isn't working for you currently. I know you've put a lot of work into it and have come to rely on it. It will be a few days before I find time to work with the autocompletion patch, but look forward to it and will get back to you with comments. All the best, Tom -- Thomas S. Dye http://www.tsdye.com