#+BEGIN_COMMENT .. title: Emacs and Org-mode .. date: 2020-08-22 .. slug: emacs-and-org-mode .. updated: 2020-08-30 .. status: published .. tags: emacs, org-mode, configuration, .. category: text-editors .. authors: Elia el Lazkani .. description: I ditched VSCode and moved back to Emacs... You heard me ! .. type: text #+END_COMMENT 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 [[https://github.com/Microsoft/vscode][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 [[https://github.com/microsoft/vscode/wiki/Differences-between-the-repository-and-Visual-Studio-Code][somewhere]]. 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 [[https://orgmode.org/][Org-mode]]. 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... {{{TEASER_END}}} * 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 Haha ! Very funny, I know. I went with [[https://github.com/hlissner/emacs-doom-themes][Doom]]. 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 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 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 [[https://gitlab.com/shakthimaan/operation-blue-moon][shakthimaan]]. I used his method to create a small =define-skeleton= for a header. It looks something like this. #+BEGIN_SRC 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 ) #+END_SRC You can use this later with =M-x= + =genrate-new-header-org=. #+BEGIN_EXPORT html

Note

#+END_EXPORT =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/. #+BEGIN_EXPORT html
#+END_EXPORT ** New Task [[https://gitlab.com/shakthimaan/operation-blue-moon][shakthimaan]] already created something for this. It looks like the following. #+BEGIN_SRC 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:") #+END_SRC This can also be used like the one above with =M-x= + =insert-org-entry=. ** 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. #+BEGIN_SRC 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:") ) #+END_SRC #+BEGIN_EXPORT html

warning

#+END_EXPORT 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. #+BEGIN_EXPORT html
#+END_EXPORT ** Final touches I wanted to add it to the menu system that comes with /Doom/ so I included the following in my =(after! ...)= block. #+BEGIN_SRC 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 )) ) #+END_SRC Making the final configuration look like the following. #+BEGIN_SRC 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 )) )) ) #+END_SRC * 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 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.