Skip to content

Latest commit

 

History

History
203 lines (154 loc) · 7.69 KB

org-command-centre.org

File metadata and controls

203 lines (154 loc) · 7.69 KB

org-mode command centre

1 Changes

  • Apr 22 2017: initial version
Status:Work in progress
Location:https://github.com/perweij/org-command-centre

2 Background

Working as a programmer also entails tasks such as managing remote files and processes in test environments, running numerous scripts and tools to solve everyday problems and perform tasks, and monitoring resources such as diskspace, certificate expiration dates etc on numerous machines.

When my professional journey started two decades ago, I used the most naive of approaches. Where sequences of commands were needed, I entered them into scripts and placed somewhere. This worked as long as I could handle these problems:

  1. remembering that the scripts existed (even after months of doing other stuff)
  2. remembering how the scripts worked
  3. remembering where I had placed the scripts, especially the latest version in case I used the copies of the scripts on several servers.

Later on, I found less naive ways of doing things. Managing scripts in a version control system eliminated problem 3. Writing man-pages, or other kinds of documents could lessen problem 2 - even though it also added the complexity of more files.

20 years later I still write scripts for bigger tasks, but for most cases I use another, arguably superior way of managing everyday life at work. It solves all three problems listed above, at least for me. The solution works like this:

  • I have a single org-document as a central command and information centre. I have bound the opening of the document to function key F12, to make it globally accessible, and it is automatically loaded as a start screen for GNU Emacs. Having all information and commands collected in one easily searched org-document lessens the risk of forgetting routines and commands, solving problem 1.
  • I have moved the contents of my many small scripts into the org-file structure. The relocated script contents are still executable thanks to org-babel. This solves problem 3.
  • I have placed documentation immediately next to each section of org-babel code. This is in the great tradition of literate programming, an idea presented by Donald Knuth. Placing information about how to run commands right next to the code is efficient as you do not need separate documents, and it is as easy to update the instructions as the code itself. This solves problem 2.

3 Purpose

I will try to share a couple of recipes here, for how to solve some typical programmer tasks in the manner described above.

Staying true to the principles of literate programming, this very document is also the executable code. You can find the document’s source here.

4 Setup

I strongly suggest you use the latest stable version of GNU Emacs to avoid problems with unsupported functions in these recipies.

If you are unfamiliar with org-babel, you could start by reading the recommended links at the end of this document. I will try to provide enough information here to get beginners started. You will want to add your programming languages of choice to your org configuration (or just stick it into your org-file directly). Here is a decent, basic configuration of org-babel:

;; So you can follow org-links with Enter (as well as C-l C-o)
(setq org-return-follows-link t)

;; fontify local blocks
(setq org-confirm-babel-evaluate nil
      org-src-fontify-natively t
      org-src-tab-acts-natively t)

;; list some of your languages
(org-babel-do-load-languages
 'org-babel-load-languages
 '((sh         . t)
   (js         . t)
   (emacs-lisp . t)
   (perl       . t)
   (python     . t)))

5 Usage

A core function of org-babel is executing code blocks. A core function of org is org links. A code block is executed by placing the cursor on a code block and pressing C-c C-c. An org link is followed by placing the cursor on it and pressing C-l C-o. If you are reading this document in GNU Emacs, and have enabled the emacs-lisp programming language in your configuration, you could try the example below, evaluating the s-expression (emacs-version):

; #+name: startup        ; to get complete block syntax in HTML publishing
; #+begin_src emacs-lisp
 (emacs-version)
; #+end_src

Executing the code block will insert the program’s output right below the block, like this:

Giving each code block a name is smart for two reasons. First it makes it easier to remember what it does, and second it enables you to call this block from other blocks, and use its output programmatically, like a function.

In this example, the code block simply places the output after the code block as text. There are many other useful ways to direct and format the output.

6 Recipes

<<recipe_custom>>

6.1 Adding settings and help functions to an org-babel document

You can keep settings and helper functions in the document and make use of them in your codeblocks, for example settings such as your remote user account name, key directories etc, and helper functions to start certain external processes that are often used.

  • Add a new section to your org-document, for example
; * Document customisations and settings
; #+name: startup
; #+begin_src emacs-lisp
 
 ;; settings
 (defvar remoteuser "thedude")
 
 ;; helpers
 (defun pw/remote-tail-f (directory file)
  (interactive)
  (and (switch-to-buffer directory t nil))
       (cd directory)
       (async-shell-command (concat "tail -n 2000 -f " file) directory))

; #+end_src
  • Add the following line to the top of your org-document:
# -*- eval: (progn (org-babel-goto-named-src-block "startup")(setq org-confirm-elisp-link-function 'y-or-n-p)(org-babel-execute-src-block)) ; -*-

Each time you open this document, GNU Emacs will ask for permission to evaluate the code in the first line - press y. That line will in turn locate and execute the code you placed in the customisation code block.

6.1.1 Usage

As you can add just about any clever code to a startup codeblock, there is of course an infinite number of ways you could use it. Here is a simple example of using the function defined above in an org-link:

Connect with [[elisp:(pw/remote-tail-f (concat "/" remoteuser "@fsf.freedom.org:/var/log") "hello.log")][tail hello.log]].

<<anchor_links>>

7 External links