diff options
Diffstat (limited to 'content/emacs/org-babel.md')
-rw-r--r-- | content/emacs/org-babel.md | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/content/emacs/org-babel.md b/content/emacs/org-babel.md new file mode 100644 index 0000000..d6b5166 --- /dev/null +++ b/content/emacs/org-babel.md @@ -0,0 +1,177 @@ ++++ +title = "Executing code in Org files with Babel" +author = ["MichaĆ Sapka"] +date = 2024-02-07T21:23:00+01:00 +categories = ["emacs"] +draft = false +weight = 3006 +image_dir = "emacs" +image_max_width = 480 +primary_menu = "cool-emacs-appendix" +abstract = "A short introduction into the world if Org Babel" +aliases = ["/cool-emacs/org-babel/"] +[menu] + [menu.cool-emacs-appendix] + weight = 3006 + identifier = "executing-code-in-org-files-with-babel" ++++ + +**Abstract**: a very short introduction into the word of Org Babel. + +No other package seems to have had such huge impact on Emacs community as the introduction of Org Babel[^fn:1]. +It made folks not only love their Org Mode, but _live_ in it. + +In short: Babel allows for [literate programming](/emacs/literate-programing-in-emacs/) form within an Org document. + + +## Source code basics {#source-code-basics} + +Babel comes baked into any modern version of `Emacs`, so you've already got everything you need. +Open any `org` document, add the code to the document within source code blocks: + +```emacs-lisp +regular text + +#+BEGIN_SRC emacs-lisp +(+ 1 1) +#+END_SRC + +and more regular text +``` + +Now, move the pointer to with the blocks, tap `C-c C-c` and the code is evaluated. +The result will be appended just below the source code, in a `RESULT` block. + +You now know how to do literate programming in Emacs. +Create an Org document, add your narrative, add your source code and execute. +Simple, isn't it? + +By default, `Babel` allows only for execution of `emacs-lisp` mode, but it supports many more. +You can enable all supported via: + +```emacs-lisp +(org-babel-do-load-languages 'org-babel-load-languages + '((shell . t) + (js . t) + (emacs-lisp . t) + (clojure . t) + (python . t) + (ruby . t) + (dot . t) + (css . t) + (plantuml . t))) +``` + +There are even more provided as dedicated packages. + + +## Being faster {#being-faster} + +Typing `#+BEGIN_SRC` can become tedious pretty quick. +We can use the `org-tempo` package to make it much faster. + +```emacs-lisp +(require 'org-tempo) +(setq org-structure-template-alist + '(("s" . "src"))) +``` + +Now, we can create new block simply by taping `<s` and pressing tab. + +Org tempo supports many more blocks, you can refer to [the official manual](https://orgmode.org/manual/Structure-Templates.html). + + +## Joining the blocks together {#joining-the-blocks-together} + +In _strict_ Literate Programming sense, your _web/_ should not be where you execute code. +Instead, you should extract programmatic parts and run it separately - the process is called _tangling_. + +Babel bypasses this limitation with `noweb` mode, in which code blocks can reference each other. +First, you need to name your code blocks: + +```emacs-lisp +#+NAME: two +#+BEGIN_SRC emacs-lisp +(+ 1 1) +#+END_SRC +``` + +Then we can use it the result other code blocks + +```emacs-lisp +#+NAME: three +#+BEGIN_SRC emacs-lisp :noweb yes +(+ <<two>> 1) +#+END_SRC +``` + +Here, the `<<two>>` will be replaced with the result of block named `two`. +This makes the block `three` return the number `3`. + +This mode gives quite a lot more option. +You can read about them inside [manual](https://orgmode.org/manual/Noweb-Reference-Syntax.html). + + +## Running on remote machines {#running-on-remote-machines} + +To make it even _cooler_, Babel integrates with `Tramp` mode which allows for execution over ssh! +You can add a tramp-style header argument as `:dir` and the code will be executed over the established connection. + +```emacs-lisp +#+BEGIN_SRC shell :dir /user@host:~/ +rm -rf / +#+END_SRC +``` + +And boom - we've got a bomb. + + +## Babel as source for Emacs configuration {#babel-as-source-for-emacs-configuration} + +The most popular use case of Babel however is Emacs configuration. +You can have as many org files as you want, have the configuration inside `emacs-lisp` code blocks and use that as config. + + +### Loading files directly {#loading-files-directly} + +If your config isn't _very_ complicated, you can force Emacs to parse the files on boot. +To achieve that, add + +```emacs-lisp +(org-babel-load-file "~/.emacs.d/config.org") +``` + +To your `init.el`. + +What happens is, that Emacs will create a corresponding `config.el` (_tangle_) file and load it as a elisp file. +Just remember not to name your config as `init.org` as there will be naming conflict with `init.el`. + + +### Pre-tangling {#pre-tangling} + +If you don't want _tangling_ on boot time, but rather want to have it ready you can manually _org-babel-tangle_. +To achieve it, add a `tangle` header argument to all you code blocks: + +```emacs-lisp +#+BEGIN_SRC emacs-lisp :tangle ~/.emacs.d/init.el +(+ 1 1) +#+END_SRC +``` + +And then, after any changes of the file run `org-babel-tangle` and your `init.el` will be up-to-date. +This is the approach [Prot](https://protesilaos.com/codelog/2023-12-18-emacs-org-advanced-literate-conf/) uses, but his config consists of over _17_000_ [sic!] lines of org file, so your mileage may vary. + + +## Links {#links} + +If you are interested in the subject, you can look at much more details sources: + +- [Official website](https://orgmode.org/worg/org-contrib/babel/intro.html) +- [Literate devops](https://howardism.org/Technical/Emacs/literate-devops.html) on Howardism +- [Advanced literate configuration](https://protesilaos.com/codelog/2023-12-18-emacs-org-advanced-literate-conf/) on Prot's website. +- [Cheat sheet](https://org-babel.readthedocs.io/en/latest/) + +[^fn:1]: you may argue and say that `magit` had bigger impact. + I disagree. + Magit made using git nicer and easier, but it is still the old, old git. + Babel changed the way we use the edit code, the way we think and how we work. |