+++ title = "Emacs and Org-mode" author = ["Elia el Lazkani"] date = 2020-08-22T21:00:00+02:00 lastmod = 2021-06-28T00:01:50+02:00 tags = ["emacs", "org-mode", "configuration"] categories = ["text-editors"] draft = false +++ I have recently found out, late I know, that the _VSCode_ distribution of the so called _Code - OSS_ is exactly that; a distribution. Let me make it clear, the _VSCode_ binaries you download from **Microsoft** has an upstream the **GitHub repository** named [VSCode](https://github.com/Microsoft/vscode) but in fact is not exactly the same code. **Microsoft** has already added a few gifts for you, including **telemetry**, not cool huh ?! Well, they tell you this in the documentation, urrrmmm [somewhere](https://github.com/microsoft/vscode/wiki/Differences-between-the-repository-and-Visual-Studio-Code). At the same time, I was giving _Jupyter Notebook_ a try. I worked on my previous post in it before writing down the final result as a blog post. But at the back of my mind, there was always [Org-mode](https://orgmode.org/). Putting one and one together, you've guessed it. I have moved to **Emacs**... again... for the umm I can't remember time. But this time, it is different ! I hope... ## Back story {#back-story} I was using _Jupyter Notebooks_ as a way to write down notes. Organize things. I had a work around the _output_ and was able to clean it. But let's face it, it might work but it is designed more towards other goals. I want to write notes and the best way to work with notes is to keep in the text, literally. I found a _VSCode_ extension that can handle _Org-mode_ in some capacity (I haven't tested it) so I decided to switch to _Emacs_ and keep the extention as a backup. ## Emacs Distribution of Doom {#emacs-distribution-of-doom} Haha ! Very funny, I know. I went with [Doom](https://github.com/hlissner/emacs-doom-themes). Why? You may ask. I don't really have a good answer for you except the following. - I didn't want to start from scratch, I wanted something with batteries included. - At the same time, I've tried _Doom_ before and I like how it does things. It is logical to me while at the same time very configurable. - I was able to get up and running very quickly. Granted, my needs are few. - I got _Python_ and _Golang_ auto-completion and _evil_ mode. I'm good to go ! Now let's dig down to my main focus here. Sure I switched editors but it was for a reason; **Org-mode**. ## Org-mode Configuration {#org-mode-configuration} I will be talking about two different configuartion options here. I am new to emacs so I will try to explain everything. The two options are related to the difference between a _vanilla_ configuration and _Doom_'s version of the configuration. The differences are minor but they are worth talking about. ### New Org File {#new-org-file} If you've used _Org-mode_ before and created _org files_, you already know that you need to set a few values at the top of the file. These include the _title_, _author_, _description_ and a different other values to change setting and/or behavior. It is a bit of a manual labor to write these few lines at the beginning of every file. I wanted to automate that. So I got inspiration from [shakthimaan](https://gitlab.com/shakthimaan/operation-blue-moon). I used his method to create a small `define-skeleton` for a header. It looks something like this. ```emacs-lisp (define-skeleton generate-new-header-org "Prompt for title, description and tags" nil '(setq title (skeleton-read "Title: ")) '(setq author (skeleton-read "Author: ")) '(setq description (skeleton-read "Description: ")) '(setq tags (skeleton-read "tags: ")) "#+TITLE: " title \n "#+AUTHOR: " author \n "#+DESCRIPTION: " description \n "#+TAGS: " tags \n ) ``` You can use this later with `M-x` + `genrate-new-header-org`.

Note

`M-x` is the **Meta** key and **x** combination. Your **Meta** key can differ between the **Alt** on _Linux_ and **Command** on _Mac OS X_. `M-x` will open a prompt for you to write in. Write the name you gave the skeleton, in this case it is `generate-new-header-org` and then hit the _Return_.
### New Task {#new-task} [shakthimaan](https://gitlab.com/shakthimaan/operation-blue-moon) already created something for this. It looks like the following. ```emacs-lisp ;; Create a new skeleton to generate a new =Task= (define-skeleton insert-org-entry "Prompt for task, estimate and category" nil '(setq task (skeleton-read "Task: ")) '(setq estimate (skeleton-read "Estimate: ")) '(setq owner (skeleton-read "Owner: ")) '(setq category (skeleton-read "Category: ")) '(setq timestamp (format-time-string "%s")) "** " task \n ":PROPERTIES:" \n ":ESTIMATED: " estimate \n ":ACTUAL:" \n ":OWNER: " owner \n ":ID: " category "." timestamp \n ":TASKID: " category "." timestamp \n ":END:") ``` This can also be used like the one above with `M-x` + `insert-org-entry`. ### Doom specific configuration {#doom-specific-configuration} Whatever defined so far should work if you just add it to your configuration but if you use _Doom_ it would a nice touch to integrate it with the workflow. In `~/.doom.d/config.el`, wrap the previous definitions with `(after! org)`. It's a nice touch to add these skeletons after _Org-mode_ has loaded. ```emacs-lisp (after! org ;; Create a skeleton to generate header org (define-skeleton generate-new-header-org "Prompt for title, description and tags" nil '(setq title (skeleton-read "Title: ")) '(setq author (skeleton-read "Author: ")) '(setq description (skeleton-read "Description: ")) '(setq tags (skeleton-read "tags: ")) "#+TITLE: " title \n "#+AUTHOR: " author \n "#+DESCRIPTION: " description \n "#+TAGS: " tags \n) ;; Create a new skeleton to generate a new =Task= (define-skeleton insert-org-entry "Prompt for task, estimate and category" nil '(setq task (skeleton-read "Task: ")) '(setq estimate (skeleton-read "Estimate: ")) '(setq owner (skeleton-read "Owner: ")) '(setq category (skeleton-read "Category: ")) '(setq timestamp (format-time-string "%s")) "** " task \n ":PROPERTIES:" \n ":ESTIMATED: " estimate \n ":ACTUAL:" \n ":OWNER: " owner \n ":ID: " category "." timestamp \n ":TASKID: " category "." timestamp \n ":END:") ) ```

warning

If you modify any file in `~/.doom.d/`, do not forget to run `doom sync` and `doom doctor` to update and check your configuration respectively.
### Final touches {#final-touches} I wanted to add it to the menu system that comes with _Doom_ so I included the following in my `(after! ...)` block. ```emacs-lisp ;; Add keybindings with the leader menu for everything above (map! :map org-mode-map (:leader (:prefix ("m", "+") :n :desc "Generate New Header Org" "G" 'generate-new-header-org :n :desc "New Task Entry" "N" 'insert-org-entry )) ) ``` Making the final configuration look like the following. ```emacs-lisp (after! org ;; Create a skeleton to generate header org (define-skeleton generate-new-header-org "Prompt for title, description and tags" nil '(setq title (skeleton-read "Title: ")) '(setq author (skeleton-read "Author: ")) '(setq description (skeleton-read "Description: ")) '(setq tags (skeleton-read "tags: ")) "#+TITLE: " title \n "#+AUTHOR: " author \n "#+DESCRIPTION: " description \n "#+TAGS: " tags \n) ;; Create a new skeleton to generate a new =Task= (define-skeleton insert-org-entry "Prompt for task, estimate and category" nil '(setq task (skeleton-read "Task: ")) '(setq estimate (skeleton-read "Estimate: ")) '(setq owner (skeleton-read "Owner: ")) '(setq category (skeleton-read "Category: ")) '(setq timestamp (format-time-string "%s")) "** " task \n ":PROPERTIES:" \n ":ESTIMATED: " estimate \n ":ACTUAL:" \n ":OWNER: " owner \n ":ID: " category "." timestamp \n ":TASKID: " category "." timestamp \n ":END:") (map! (:when (featurep! :lang org) (:map org-mode-map (:localleader :n :desc "Generate New Header Org" "G" 'generate-new-header-org :n :desc "New Task Entry" "N" 'insert-org-entry )) )) ) ``` ## What do I do now ? {#what-do-i-do-now} You might be asking yourself at this point, what does this all mean ? What do I do with this ? Where do I go ? Well here's the thing. You find yourself wanting to create a new _org file_. You do so in emacs and follow it with `M-x` + `generate-new-header-org` (or `SPC m G` in **Doom**). _Emacs_ will ask you a few questions in the bottom left corner and once you answer then, your header should be all set. You can follow that with `M-x` + `insert-org-entry` (or `SPC m N`) to generate a task. This will also ask you for input in the bottom left corner. ## Conclusion {#conclusion} This should help me pick up the usage of _Org-mode_ faster. It is also a good idea if you've already configured your _Emacs_ to read all your _org file_ for a wider **agenda** view.