I won’t say much about report design since manipulating text in an EMACS buffer is a pretty standard activity for EMACS users, with plenty of web resources available as tutorials. A couple of suggestions – with your results as a list of rows, you can iterate over the rows and print directly into a new buffer prepared with a header. Alternatively you can extract fields from each row using:
Now fields can individually be manipulated. Note that tab is being used as the field delimiter. This was specified previously when we started up the database.
For a good discussion of the details of creating a major mode refer to Writing GNU EMACS Extensions by Bob Glickstein. The advantage of utilizing SQLITE within a major mode is that while you are in the SQLITE specific buffer, you can have SQLITE specific menu items and key chords that are in effect only while in that buffer. A mode also allows you a single point in your code to open and close the database and deal with any database housekeeping that is required. Our effort to abstract away the details of database interaction are also facilitated by a mode, as any database specific functions can be included in the mode. The commands for creating the mode along with helper functions and load statements can go into a file called sqlite-mode.el. My file also includes code for working with the widget library:
Define a hook variable and menu map. Add elements to the menu map. Note that each menu item is defined by a dotted pair, the car being the text in the menu and the cdr being an associated function. Often that function will launch a form to be used to enter data. A single example of form design is given below.
Define keybindings specific for SQLITE mode. I don’t define any unique SQLITE specific bindings because I need to use the widget keymap for my forms to be functional, so I copy-keymap the widget keymap.
1 2 3 4 5 6 7 8 9 10 11
(defvar sqlite-mode-map nil "Keybindings for sqlite mode")
(define-derived-mode sqlite-mode text-mode "sqlite" "Major mode using sqlite for tau antibodies. Special commands: \\{sqlite-mode-map}")
Load any libraries that need to be accessed during database manipulation. Here I load various forms and the report interface. provide allows me to require in my .emacs file.
Also in this file I would include any helper functions, such as sqlite-query and chomp described in an earlier post. Once the mode is defined, the command (sqlite-mode) can be used to invoke the mode, for example in a form buffer.
Scientists in their quest for truth often need to catalog and parse large amounts of data. Desktop databases are ideal for this purpose. A reputable package will contain a form and report designer, scripting language, database back end, and a method for interfacing with other software and equipment. Over the years I have experimented with many systems, including the RAD (Rapid Application Development) environment Superbase ( late 1980s early 90s), JAVA and a variety of object oriented databases (POET, ObjectStore and the JDO from Sun; late 90s early 2000s) and more recently Lisp and ObjectPrevalence. Though I quickly gained an appreciation of the LISP language working with Common Lisp, the limited number of libraries, poor documentation, small user base, and lack of a GUI did not meet all my requirements. Clojure promises to address many of these issues, but is still a work in progress. My experience with the JDEE (Java Development Environment for EMACS) familiarized me with EMACS Lisp. The only shortcoming of EMACS is the lack of a database. Enter SQLITE.
SQLITE is a a software library that implements a self-contained, serverless, zero-configuration, transactional SQL relational database engine. Installation and configuration are simple, and an included executable allows SQLITE to run as a process within EMACS. With the widget interface of EMACS, you have all you need to create, query and report data. Setup is as follows:
Download and unzip SQLITE into a directory. I used c:\program files\sqlite3. This path will need to be referred to as c:\progra~1\sqlite3 in your lisp code and any batch files. Be sure to also download the associated executable file, which provides about 27 “dot” utility commands. Test that the systems works by creating a table and populating with data. To get started, create a batch file that starts SQLITE with the database name of interest, which is passed to the executable as a parameter. To create the database named “mydb”, the contents of sqlite.bat would be:
1
c:\progra~1\sqlite\sqlite3.exe mydb
At the sqlite prompt both dot and SQL commands can be submitted. To retain a record of the commands used to create your database, place them in a plain text file and then use the .read command to read that file into SQLITE. Here are the contents of my “create-tables.txt” file:
To execute, read in create-tables.txt at the sqlite prompt:
1
sqlite> .read "create-tables.txt"
You can check that the table was created with the .schema command. Next insert a value. Either type it directly at the sqlite prompt, or read it from a file.
If you retrieve your row, you are all set to move on. Note that the assigned value of ab_id is NULL. Let the database assign the autoincrement field.
Connect SQLITE to EMACS
Interaction between SQLITE and EMACS is accomplished through comint. Use describe-function “comint-” to browse the various comint commands. We are interested in comint-redirect-send-command-to-process. Some of the comments in comint.el are also useful to read. Before examining comint directly, let’s consider how to abstract away the process of interacting with the database. Ultimately what I want is a single command that will send my SQL statement to SQLITE and return my result set. I would like the result set returned as a list of tuples (rows). Each tuple can then be processed into a list of fields. This is very convenient as Lisp works well with lists. My command will be sqlite-query, and its only argument will be sql-command. It will return a list of tuples.
First, lets set up a few variables
1 2 3 4 5 6 7
(defvar sqlite-program "c:/progra~1/sqlite/sqlite3.exe""Full path name of the SQLITE executable.")
(defvar sqlite-db "c:/temp/lisp-code/tutorial/mydb""Full path name of the SQLITE database.")
(defvar sqlite-process-buffer "*sqlite-process*""*Name of the SQLITE process buffer. This is where SQL commands are sent.")
(defvar sqlite-output-buffer "*sqlite-output-buffer*""Name of the buffer to which all SQLITE output is redirected.")
Next start up the SQLITE process. Send the SQLITE dot command “.mode tabs” so that fields are always tab delimitted. This is important later when fields must be extracted. Our database abstraction will return a list of rows, each row being a string with tab delimited fields. This string then needs to be parsed using split-string to extract fields as a list. More on that later.
Next we need to write our sqlite-query function. The function should perform the following activities:
Navigate to the output buffer.
Erase the contents of the output buffer, if any.
Send the sql-statement to SQLITE using the sqlite-process buffer
Switch back to the sqlite-output buffer and retrieve the results. One result row per line of the buffer. Extract each line as an element of the result list.
Bioinformatics and data analysis are mission critical activities at both large pharmaceutical and small biotech companies. Access to bioinformatic resources can vary, depending on project priority and financial resources. Even when forthcoming, bioinformatic resources can be difficult to take advantage of for many reasons. The impedance mismatch between programmer and scientist vocabulary can result in costly misunderstandings during software design. The lengthy requirements gathering, document writing, prototype roll out, evaluation, rewrite cycle adds cost and extends project time lines. The perceived need by programmers to work with the latest and greatest language and programming technology can add unnecessary complexity, expense, and time to a project.
Way back in the 1980s there was a competitive market for desktop database systems such as dBASE, FoxPro, Quattro Pro, FileMaker, and my favorite - Superbase. Self taught programmers using such packages could make short work of many data storage needs in a laboratory environment. Though much maligned by the professional programmers for their sometimes sloppy, undocumented spaghetti code, scientists were focused on getting the job done in the fastest most efficient manner possible. Desktop systems were efficient, incorporating table and form design as well as scripting in a single package. A scientist could focus on mastering the details of his discipline rather than memorizing commands and protocols for different languages and systems.
Microsoft effectively ended innovation in the desktop database market with its Access database monopoly. Though capable, Access is expensive and forces a commitment to a closed Windows based system. Although there are numerous open source desktop databases available, few integrate a form designer, report generator, and scripting language. These elements do exist separately, and a close approximation of a semi-integrated system would be the EMACS/ELISP/SQLITE system I review in this tutorial. Familiarity with such a system would allow the user to perform rapid application development. Efficiency and rapidity are important, as many programs will have a short half life in a rapidly changing research and development environment.
Donald Eastlake describes my software development attitude succinctly as he discusses a piece of software called the ITS system:
The ITS system is not the result of a human wave or crash effort. The system has been incrementally developed almost continuously since its inception. It is indeed true that large systems are never “finished”….
In general, the ITS system can be said to have been designer implemented and user designed. The problem of unrealistic software design is greatly diminished when the designer is the implementor. The implementors’ ease in programming and pride in the result is increased when he, in an essential sense, is the designer. Features are less likely to turn out to be of low utility if users are their designers and they are less likely to be difficult to use if their designers are their users.
User designed software eliminates the communication barrier between scientist and programmer, and puts control of time lines in the hands of the scientist.
Below are some configuration notes for your .emacs file. By default .emacs is found in your “c:/documents and settings/<*your-login-id*>/Application Data” folder. If you set a HOME system variable, .emacs will be found in the HOME directory.
Below are settings I have used over the years, not necessarily all at the same time. Pick and choose what you need.
Global settings
; For all buffers
(global-font-lock-mode 1)
(show-paren-mode t);show matching parentheses
(cua-enable-cua-keys t);allows me to use Windows shortcut keys. Must install cua-mode.el
(cua-mode t nil (cua-base))
(tool-bar-mode nil);I don't like tool bars
(transient-mark-mode t);highlight marked regions when selecting code
(global-set-key (kbd "<f12>") 'other-window)
(global-set-key (kbd "<f2>") 'switch-to-buffer)
(global-set-key (kbd "<f1>") 'find-file)
;Define a key to load and run your current project of interest file
(defun load-and-run-fave-file()
(interactive)
(load "my-favorite-file.el"))
(global-set-key (kbd "<f6>") 'load-and-run-fave-file)
Note that below I use F5 in R mode to evaluate a region. Whichever mode I am in, R or Lisp, F5 evaluates a region.
R
;;;; R Setup
(require 'ess-site)
(defun my-ess-mode ()
(interactive)
(cond ((string= "R" ess-dialect)
(message "my-r-mode")
;; customization for ESS[R] here
(define-key ess-mode-map '[f5] 'ess-eval-region-and-go))))
;and then hook this into the appropriate place:
(add-hook 'ess-mode-hook 'my-ess-mode)
SLIME
;; 1. Start the CL first with "M-x clisp-start" (or equivalent) from Emacs
;; 2. Start the SLIME connection with "M-x slime-connect RET RET RET" from Emacs
;for Common Lisp
;(defun clisp-start ()
; (interactive)
; (shell-command (concat "c:/clisp-2.43/full/lisp.exe" ;
; "-B c:/clisp-2.43/full/ "
; "-M c:/clisp-2.43/full/lispinit.mem "
; "-i c:/emacs-22.1/site-lisp/.slime.lisp "
; "-ansi -q&")))
;(defun sbcl-start ()
; (interactive)
; (shell-command (concat "c:/sbcl-1.0.13/sbcl.exe"
" --dynamic-space-size 64"
" --noinform")))
(defun sbcl-start ()
(interactive)
(shell-command "c:/sbcl-1.0.13/sbcl.exe --core c:/sbcl-1.0.13/sbcl.core --load c:/emacs-22.1/site-lisp/.slime.lisp &"))
(setq load-path (append (list "c:/emacs-22.1/site/slime-2.0")
load-path))
(require 'slime)
(add-hook 'lisp-mode-hook (lambda () (slime-mode t)))
(add-hook 'inferior-lisp-mode-hook (lambda () (inferior-slime-mode t)))
;; If you don't want eldoc-like behavior, comment out the following line
(slime-autodoc-mode)
;M-x run-lisp; M-x slime
(setq inferior-lisp-program "c:/sbcl-1.0.13/sbcl.exe --core c:/sbcl-1.0.13/sbcl.core --userinit c:/sbcl-1.0.13/sbcl-init2.lisp")
(require 'slime)
(slime-setup)
Clojure
(setq load-path (append (list "c:/emacs-22.3/site-lisp/slime-2009-06-28")
load-path))
(require 'slime)
(slime-setup)
(setq inferior-lisp-program
; Path to java implementation
(let* ((java-path "java")
; Extra command-line options
; to java.
(java-options "")
; Base directory to Clojure.
; Change this accordingly.
(clojure-path "c:/myclasses/classes/clojure/")
; The character between
; elements of your classpath.
(class-path-delimiter ";")
(class-path (mapconcat (lambda (s) s)
; Add other paths to this list
; if you want to have other
; things in your classpath.
(list (concat clojure-path "clojure.jar"))
class-path-delimiter)))
(concat java-path
" " java-options
" -cp " class-path
" clojure.lang.Repl")))
(require 'clojure-mode)
(setq auto-mode-alist
(cons '("\\.clj$" . clojure-mode)
auto-mode-alist))
JDEE
(setq defer-loading-jde t)
;;
(if defer-loading-jde
(progn
(autoload 'jde-mode "jde" "JDE mode." t)
(setq auto-mode-alist
(append
'(("\\.java\\'" . jde-mode))
auto-mode-alist)))
(require 'jde)
(load "jde-ant"))
;; Sets the basic indentation for Java source files
;; to two spaces.
(defun my-jde-mode-hook ()
(setq c-basic-offset 2)
( define-key jde-mode-map '[f5] 'jde-build) )
(add-hook 'jde-mode-hook 'my-jde-mode-hook)
(cond ((fboundp 'global-font-lock-mode)
;;Turn on font-lock in all modes that support it
(global-font-lock-mode t)
;;Maximum colors
(setq font-lock-maximum-decoration t)))
(jde-ant-args "-emacs")
(jde-ant-buildfile "c:\\classes\\prs500mngr\\bin\\build.xml")
(jde-ant-complete-target t)
(jde-ant-enable-find nil)
(jde-ant-home "c:\\classes\\org\\apache-ant-1.7.1")
(jde-ant-program "c:\\classes\\prs500mngr\\bin\\ant")
(jde-ant-read-buildfile t)
(jde-ant-read-target nil)
(jde-ant-working-directory "c:\\classes\\prs500mngr\\bin\\")
(setenv "ANT_HOME" "c:\\classes\\org\\apache-ant-1.7.1")
Installation instructions for the various programs I use with EMACS
WindowsXP
R
Download and install R from Cran. I am using version 2.11.1. Sequence manipulation algorithms require the seqinr package v2.0-9 to be installed in R. Launch the gui and select Packages/Install Packages… Select a Cran mirror, then select the package “seqinr”. Packages can also be installed from the command line, once you have R running in EMACS. Use the comand:
This allows me to use F5 to evaluate a region whether I am in R or Lisp. I also define the following function key shortcuts to streamline the loading of different files of interest. If you decide not to define these keys, you will need to load the files manually using the command “M-x my-favorite-file”.
If ess is not finding R, check your PATH variable and make sure the R executable is listed.
Clustalw2
Install clustalw2 which performs the sequence alignments. Download the clustalw-2.0.11-win.msi file and allow it to install in c:\Program Files.
Package.el
Try to use Melpa stable only. At least for Clojure compatibility, MELPA unstable introduces bugs.
update MELPA packages (note capital U)
1
M-x package-list-packages U x
1
M-x package-refresh-contents
Init.el
I switched from ~/.emacs to ~/.emacs.d/init.el Furthermore I want all of .emacs.d to be in my ~/syncd directory for easy cloud backup. I need to change the properties of the launch icon to redirect to ~/syncd/.emacs.d/init.el and set the user-emacs-directory variable early in init.el
Properties of the launch icon can only be modified by root so sudo edit /usr/share/applications/GNU Emacs 25 (GUI)
#nautilus navigate to /usr/share/applications/GNU Emacs 25 (GUI) and chage properties to: /usr/bin/emacs25 %F -q –load “/home/mbc/syncd/.emacs.d/init.el”
%F allows multiple files as arguments.
The first line in init.el is (setq user-emacs-directory “/home/mbc/syncd/.emacs.d/“)
11/01/2019
Working with emacs26
#nautilus navigate to /usr/share/applications/emacs.desktop and change the line to: Exec=/usr/bin/emacs %F -q -load /home/mbc/syncd/.emacs.d/init.el
Useful Packages
eldoc: provides method documentation
company: auto completes
ido: provides selection lists e.g. for navigating directories
Principles of Population Genetics, first edition, was the text for Genetics 705 / Plant Science 705 graduate course at State U. I took this course back in 1983 to satisfy requirements for the Master of Science degree in Genetics. Being an early version of the book, there are few of the molecular biology and genomics distractions present in the more recent versions.
Owncloud will not back up certain files, such as those beginning with underscores. Ftpbox is a hack that allows me to back up all files manually, using batch files. A better option is rsync. Osync for bidirectional sync.