Feeds:
Posts
Comments

Archive for the ‘Emacs’ Category

Org Mode

The wonderful Org mode has deservedly been getting a lot of [word] press recently. This is a really great tutorial. There is a nice customization guide at orgmode.org. endperform talks about using it for time tracking and remembering useful tricks. Emacs-fu has an article on generating html with org-mode. ByteBaker talks about using it to organise papers he downloaded and to make a wiki.

My Emacs Posts

I’ve started a series about a light-weight alternative to dired mode. Part two, which will remember locations you have visited previously is on the way.

A quick mention of longlines-mode got a comment about visual-line-mode which is the replacement in Emacs 23 onwards. I’ve switched over and it does seem better. longlines-mode was fairly reliable, but occasionally it would forget that it was supposed to be wrapping words and I would need to disable it and enable it.

Other Emacs Posts

alieniloquent talks about using advice to disable other window is you use the universal prefix (C-u). Nice trick.

Aneesh Kumar has post on switching from vim to emacs, or actually viper. As I use vim a lot, I’ve tried viper in the past but I always found that it made accessing various emacs commands harder (or maybe just different) than it is in vanilla emacs so I always switched back.

Armin Sadeghi says that his two favourite editors are SlickEdit and Emacs.

The big difference between SlickEdit and Emacs is that SlickEdit is commercial software and Emacs is open source.

If that is the big difference, why not just use Emacs?

Read Full Post »

For many of the tasks I have to do day to day, I have a default tool. If I want to edit some text I’ll use Emacs; if I want to write an application slowly that runs quickly I’ll use C++; if I want to write an application quickly that runs slowly I’ll use Perl. And if I have to look after a hundred different configuration files for a hundred different users I’ll write a web interface so they can maintain the files themselves.

Ultimately, with any web app I write, anything complex is entered through a <textarea>. However, I often think that a sufficiently restricted emacs would give the users a nicer experience. If it was for me, I would just add the necessary functionality to dired. However, for a non-IT person, the dired interface is not reasonable.

So, a little experiment – can I make something emacs-based that a non-IT person would be happy to use?

File Selector Design Outline

What I envisage is a file selector that remembers the files that a user has opened before (fairly standard selector functionality right?). When a file is selected it provides a simplified view of the configuration file to the user. When they select save, it will save the full complex configuration file in all its glory.

I can also enforce some policies such as every save will check-in to source code control. Then if my editor doesn’t work correctly or the user does something they didn’t want to do, I can retrieve an earlier, working version.

File Selector Implementation

I had better give the user some defaults to click on to start with. Fortunately the configuration files are stored in two main areas: /data/sales and /data/admin.

(require 'button)
(require 'derived)

(defconst file-editor-default-dirs
  (mapcar (lambda (e) (concat "/data" (symbol-name e)))
          '(sales admin)))

I don’t want to display any files or directories that the users should not be looking in so I exclude them with a regex.

(defvar file-editor-exclude-file-regex "^RCS\\|^#\\|\\.back$\\|~$")

Each line in the file selector will be a button which enters the directory or opens the file respectively. I’ve mentioned emacs buttons previously).

(define-button-type 'open-dir
  'action 'file-editor-open-dir
  'follow-link t
  'help-echo "Open Directory")

(define-button-type 'open-file
  'action 'file-editor-open-file
  'follow-link t
  'help-echo "Open Configuration File")

The configuration files are based on xml. I want to redefine some of the keys, such as C-s for save and C-f for search so I derive a major mode from xml-mode.

(define-derived-mode file-editor-mode xml-mode "File Editor"
  "Major mode for editing configuration files.
Special commands:
\\{file-editor-mode-map}")

(if file-editor-mode-map
    nil
  (setq file-editor-mode-map (make-sparse-keymap))
  (define-key file-editor-mode-map (kbd "C-f") 'isearch-forward)
  (define-key file-editor-mode-map (kbd "C-o") 'file-editor-file-selector)
  (define-key file-editor-mode-map (kbd "C-s") 'file-editor-save-file))

The directory buttons and file buttons call file-editor-open-dir and file-editor-open-file respectively.

(defun file-editor-open-dir (button)
  (let ((parent (button-get button 'parent))
        (dir (button-get button 'dir)))
    (file-editor-dir-list
     (format "%s%s" (if parent (concat parent "/") "") dir))))

(defun file-editor-open-file (button)
  (let ((parent (button-get button 'parent))
        (file (button-get button 'file)))
    (find-file (concat parent "/" file))
    (file-editor-mode)
    (longlines-mode 1)))

When the file selector is first opened, it displays some default directories. Later on I’ll extend this to display files that have been opened recently.

(defun file-editor-insert-opendir-button (parent dir)
  (insert-text-button (format "[%s]" dir)
                      :type 'open-dir 'parent parent 'dir dir)
  (insert "\n"))

(defun file-editor-default-dirs ()
  (let ((buffer (get-buffer-create "*file-editor-dir-list*")))
    (with-current-buffer buffer
      (progn
        (erase-buffer)
        (insert "*** Default File List ***\n\n")
        (dolist (dir file-editor-default-dirs)
          (file-editor-insert-opendir-button nil dir))))))

I keep the file selector buffer read-only and therefore need to set inhibit-read-only to t whenever I write to it. I can then get all the files and directories within the current directory using directory-files-and-attributes.

I skip all the files beginning with a period. A string is a type of array so I can just compare against the first character using aref. I suspect it is more efficient than using a regex (surely it must be?) but I haven’t measured.

I list all of the directories prior to the files.

(defun file-editor-dir-list (parent)
  (let ((buffer (get-buffer-create "*file-editor-dir-list*")))
    (with-current-buffer buffer
      (let ((inhibit-read-only t) files dirs)
        (setq parent (expand-file-name parent))
        (erase-buffer)

        (dolist (vec (directory-files-and-attributes parent))
          (let ((filename (car vec))
                (is-directory (cadr vec)))
            (unless (or (eq (aref filename 0) ?.)
                        (string-match file-editor-exclude-file-regex filename))
              (if is-directory
                  (push filename dirs)
                (push filename files)))))

        (insert (format "Current Directory: %s\n\n" parent))
        (file-editor-insert-opendir-button parent "..")

        (dolist (dir (reverse dirs))
          (file-editor-insert-opendir-button parent dir))

        (dolist (file (reverse files))
          (insert-text-button file 'parent parent 'file file
                              :type 'open-file)
          (insert "\n"))

        (toggle-read-only 1)))))

file-editor-file-selector opens either the default files/directories or the buffer which should contain the last visited location.

(defun file-editor-file-selector ()
  (interactive)
  (let ((buffer (get-buffer "*file-editor-dir-list*")))
    (if buffer (switch-to-buffer buffer) (file-editor-default-dirs))))

(file-editor-file-selector)

Okay that is probably enough for one post. Obviously I have a fair amount of functionality left to implement. What do you guys think? Am I crazy to even consider using emacs over <textarea>? Let me know in the comments.

Read Full Post »

longlines-mode

Alex Bennee mentions the excellent longlines-mode in a recent post. I learnt something new – that it can highlight hard returns using (longlines-show-hard-newlines). Thanks Alex.

What is so good about it when you can wrap a paragraph at any time using M-q (fill-paragraph)? It wraps a paragraph in realtime as you are editing it, just like a word processor. And not only that, it uses soft newlines. If you cut and paste it, the result is not wrapped which is generally what you want.

I use longlines-mode a lot when I’m not editing source code. One thing I do is dump text in a scratch buffer (created with C-x b *random-name* <RET>) and then I press C-c C-l. Now I can look at two or more parts of the text at the same time using C-x 2 and related functions.

(defun set-longlines-mode ()
  (interactive)
  (text-mode)
  (longlines-mode 1))

(global-set-key (kbd "C-c C-l") 'set-longlines-mode)

Just as Alex does, I use longlines-mode for writing my blog posts. However, I write most of my blog posts using muse so I add it to the muse-mode-hook.

(defun muse-minor-modes ()
  (longlines-mode 1)
  (font-lock-mode 0))

(add-hook 'muse-mode-hook 'muse-minor-modes)

Read Full Post »

HowTo Disable indent-tabs-mode

It sounds like this guy is having problems with emacs automatically converting spaces to tabs. I can sympathise – it took me a while to figure out how to disable indent-tabs-mode correctly.

My post also received a comment asking how to add a tabs if you have disabled indent-tabs-mode. If you need a single tab, use C-q <TAB> (quoted-insert). Otherwise, if you need to enter many tabs you can enable M-x eval-expression <RET>(setq indent-tabs-mode t)<RET> or bind tab to (self-insert-command).

Working With Multiple Databases

To much wailing and nashing of teeth, several weeks ago I introduced my emacs db mode. I have made an extension for quickly and easily switching between multiple databases using ido. It also serves as a nice tutorial for adding custom sections to the mode-line.

Always Prompting Before Exiting Emacs

Nilesh has a post about prompting before exiting to avoid accidents. Now, I occasionally want a prompt – I often get a prompt anyway as I have either processes or unsaved buffers. Occasionally I am caught out when I am sketching things out in scratch buffers (with, e.g. C-x b *stuff* <RET>).

Most functions that are called when emacs is exiting call (save-buffers-kill-emacs) which has a customizable variable you can set to control if and how emacs prompts when exiting. I like to timeout these type of prompts, just in case I was attempting to exit while the screen was off.

(setq confirm-kill-emacs
      (lambda (e) 
        (y-or-n-p-with-timeout
         "Really exit Emacs (automatically exits in 5 secs)? " 5 t)))

Emacs As A Windows Editor?

There was a strange thread in the Joel On Software forums. Someone wanted an alternative to Emacs on Windows with the following features:

  • macros
  • good windows integration
  • syntax highlighting for multiple file types
  • free as in beer

Why strange? Well, emacs has all of this and more. Keyboard macros are available with C-x ( and C-x ) or <f3> <f4> in more modern versions. In addition, Emacs 23 is extremely good-looking.

Setting cua-mode and recentf will get you most of the way to that authentic windows app experience.

(cua-mode t)
(recentf-mode t)

Remember to use the Emacs Win32 build.

Miscellaneous Tips

Here is a mention of the fantastic occur command.

Someone made a brief post (http://rydow.wordpress.com/2009/06/11/emacs-history-between-sessions) about savehist-mode although they couldn’t remember where they had seen the original. Along with many great Emacs hints, it was from Emacs-fu (it was in a comment by valvo).

Read Full Post »

One thing that very few code samples (for any language) touch upon is error handling. There are a number of reasons for this.

  • Error handling code is ugly
  • It can take up a significant amount of the code
  • It distracts from what the sample is trying to demonstrate

Robust code almost always needs error handling. How is it done in Emacs Lisp?

Try / Catch / Finally – The Error Handling Trinity

In Java, code that may throw an exception looks like this:

try {
    // Code that may throw
} catch (SomeType exception) {
    // Handler code for SomeType
} catch (Exception exception) {
    // Handler code for Exception
} finally {
    // Code to execute after // Code + the handler if any
}

The finally clause handles the clean-up and is always executed whether or not an exception is thrown.

How Emacs Lisp Does It

Emacs Lisp has an equivalent for each part – from throwing the exception, to catching it and handling clean-up. (error ...) throws the most basic exception (in emacs lisp, they are called signals). If you execute an error call without protecting it, emacs will enter the debugger.

unwind-protect

unwind-protect is the emacs way of implementing a finally clause. In the following code, when you exit from the debugger, hi will be inserted in the buffer.

(unwind-protect
    (error "hello")
  (insert "hi"))

condition-case

Try/Catch is spelled condition-case. There is one handler per signal we want to handle. All signals are derived from ‘error so catching error catches any remaining signals.

(condition-case var bodyform &rest handlers)

(unwind-protect
    (let (retval)
      (condition-case ex
          (setq retval (error "Hello"))
        ('error (message (format "Caught exception: [%s]" ex))))
        retval)
  (message "Cleaning up..."))

We can wrap this all in a macro. Adapt the following for your own use.

(defmacro safe-wrap (fn &rest clean-up)
  `(unwind-protect
       (let (retval)
         (condition-case ex
             (setq retval (progn ,fn))
           ('error
            (message (format "Caught exception: [%s]" ex))
            (setq retval (cons 'exception (list ex)))))
         retval)
     ,@clean-up))

Some Examples

(safe-wrap (error "Hello") (message "Unwinding..."))
Caught exception: [(error Hello)]
Unwinding...
(exception (error "Hello")) ;; return value

;; (safe-wrap (message "Hello") (message "Unwinding..."))
Hello
Unwinding...
"Hello" ;; return value

(safe-wrap (/ 1 0))
Caught exception: [(arith-error)]
(exception (arith-error)) ;; return value

If you liked this post, why not subscribe to my RSS feed.

Read Full Post »

I’ve written a new article about how to query multiple databases using db-mode. It demonstrates quickly selecting between multiple databases using ido and you may be surprised to learn that it using a mechanism very similar to my directory aliases. This is a follow-up to my page on emacs db mode.

Why Should You Be Interested?

If you need to work with multiple databases and you like using emacs then the page is especially for you. Go take a look! It also has a good example of using the emacs mode line, in this case to display which database you are currently connected to. And finally it is another example of using ido which if you haven’t tried yet, you really should.

About The Code

The code is designed to work with my own db-mode as that is what I use but it could be easily adapted for use with sql-mode using the enter-db function from one of my earlier posts.

The preamble would be something like this:

;; ...
(let ((sql-sybase-program "/usr/bin/isql")
      (sql-server db-server)
      (sql-database db-database)
      (sql-user db-user)
      (sql-password db-password))
;; ...

Ian Eure also has a post on working with multiple databases here. It uses a new buffer for each database which is probably preferable to killing the connection.

Read Full Post »

Useful Blog Comments

Nachopp demonstrates some emacs lisp that inserts a commonly used find command in a shell buffer. And Ian Eure has a great follow-up comment which demonstrates the more typical way of defining emacs lisp functions; talks about alternatives such as abbrev mode and yasnippet and finally mentions the best solution, the built-in rgrep.

Defining C++ styles

David Ha has a gallery of some of the built-in C++ styles. None of the styles suit me exactly so I have accreted a fair amount of C++ configuration code over the years. I must admit, I haven’t audited for ages so I’m not sure which bits are necessary and which are not.

(defconst *my-cc-style*
  '((c-basic-offset . 4)
    (c-comment-only-line-offset . 0)
    (c-hanging-braces-alist . ((brace-list-open)
                               (brace-entry-open)
                               (substatement-open after)
                               (block-close . c-snug-do-while)))
    (c-cleanup-list . (brace-else-brace))
    (c-offsets-alist . ((statement-block-intro . +)
                        (knr-argdecl-intro     . 0)
                        (substatement-open     . 0)
                        (substatement-label    . 0)
                        (innamespace           . 0)
                        (case-label            . +)
                        (statement-cont        . +)))))

(defun my-c-initialization-hook ()
  (define-key c-mode-base-map "\C-m" 'c-context-line-break)
  (define-key c-mode-base-map (kbd "RET") 'newline-and-indent)
  (define-key c-mode-base-map [f7] 'run-compile))

(add-hook 'c-initialization-hook 'my-c-initialization-hook)
(setq c-offsets-alist '((member-init-intro . ++)))

(c-add-style "PERSONAL" *my-cc-style*)

(defun my-c-mode-common-hook ()
  (c-set-style "PERSONAL")
  (setq tab-width 4
        indent-tabs-mode nil
        c-hungry-delete-key t)
  (c-toggle-auto-newline 1))

(add-hook 'c-mode-common-hook 'my-c-mode-common-hook)

The most useful commands for finding out which of the variables to set are C-c C-o (c-set-offset) and C-c C-s (c-show-syntactic-information)

This is kinda interesting where Ronnie Collinson (from the NotThinking blog)
removes the *compilation* buffer if the compile is successful. It isn’t something I personally would use as I like the feedback, but I wasn’t previously thinking about compilation-finish-functions and I have a few ideas of things I would like to run after a successful compile.

Perennial Emacs Blog Topics

There are a few perennial blog topics in the emacs world – I mentioned a smooth scrolling post in my links from 2009/17 and here is Da Zhang’s take (does anyone like the default behaviour by the way?). I included a link to a post on the incredibly useful mark ring in emacs-links-2009-09 and here is another from yesterday.

Proposed solutions – fix the smooth scrolling behaviour so it works nicely out of the box and… well, perhaps blogs are not a great way of educating the masses after all. Pity.

Read Full Post »

Some time ago, I wrote about doing batch processing of text with an external process running, e.g. Perl. Similarly, emacs-lisp has a lot of functionality for manipulating text.

The Problem

I have a file like this:

John James,Admin,other data,...
Dave Jones,Sales,...
Lisa Sims,IT,...
...

I want to convert it into the following1:

AND name IN ("Dave Jones", "John James", "Lisa Sims")
AND dept IN ("Admin", "IT", "Sales")

The Solution

First of all I need a helper function that converts lisp lists into a quoted comma-separated list.

(defun make-csv (seq)
  (mapconcat (lambda (e) (format "\"%s\"" e)) seq ", "))

And then I can iterate over the text with re-search-forward, collecting the matched strings. At the end, I’ll output the collected strings. in a sql clause fragment.

(defun process-lines (&optional begin end)
  (interactive "r")
  (goto-char begin)
  (let (names depts)
    (while (re-search-forward "\\([^,]+\\),\\([^\n,]+\\)" end t)
      (push (match-string 1) names)
      (push (match-string 2) depts)
      (next-line))
    (insert (format (concat "\n"
                            "AND name IN (%s)\n"
                            "AND dept IN (%s)\n")
                    (make-csv (sort names #'string-lessp))
                    (make-csv (sort depts #'string-lessp))))))

If you liked this post, why not subscribe to my RSS feed.


1. Okay, you got me, I don’t really want to convert it into this. But for the purpose of the example, this will do. Exercise for the reader – how can I convert it into sql that will efficiently extract just the lines I want?

Read Full Post »

When writing a muse file it always annoyed me when I have written (for example) a-really-long-variable somewhere else in the file and then when I type =a-rea and press M-/ it fails to expand.

The way to fix this behaviour is by setting dabbrev-abbrev-skip-leading-regexp

(setq dabbrev-abbrev-skip-leading-regexp "[=*]")

(Edit: fixed the first regex per Billy’s comment below. Thanks)

Okay, you think, this doesn’t affect me – I don’t use muse (why not?) How about if you’re writing some html/xml.

(setq dabbrev-abbrev-skip-leading-regexp "[^ ]*[<>=*]")

Now <strong>long-word- completes as you would expect.

There is also dabbrev-abbrev-char-regexp if you want even more control over what should be considered a match.

Also, I’m no longer using autocomplete as I find vanilla dabbrev nicer to use.

Read Full Post »

A little while ago we were talking about clients and servers. And I’ve finally got back to the interesting thing which is playing with emacs networking.

The comment from Gabriel nicely pointed out emacs’ low-level socket facilities.

(open-network-stream) which is synchronous and
(make-network-process) which can be asynchronous if the parameter is set. I haven’t been able to make the last one work, but check it out yourself.

So, er, I’m not 100% sure how to simulate a crappy internet connection. Maybe making my server pause 2 seconds between line reads will be sufficient.

sub process_request
{
    while () {
        s/\r?\n$//;
        print STDERR "Received [$_]\n";
        last if /quit/i;
        sleep 2;
    }
}

I’m also interested (or perhaps curious?) in when the connection is made and broken.

sub post_accept_hook
{
    print STDERR "Accepted new connection\n";
}

sub post_process_request_hook
{
    print STDERR "Client disconnected\n";
}

Did I mention I think Perl’s bad press is a little unfair?

So what I need now is a basic API for connecting, disconnecting and sending messages. make-network-process makes a process as you can probably infer from the name and for my purposes a single client is enough so I make a wrapper to get the current process. Layering in this way means I can add any error handling at the appropriate point later on. And also it should be fairly easy to generalise client-process to choose between different connections.

(defconst client-process-name "*client*")
(defsubst client-process () (get-process client-process-name))

For maximum asynchronicity we add a sentinel function that will be called back when the connection has completed, either successfully or unsuccessfully.

It turns out that a perl-style chomp function is really handy!

(defun chomp (str)
  (if (and (stringp str) (string-match "\r?\n$" str))
      (replace-match "" t nil str)
    str))

(defun client-notify-connect (&rest args)
  (message (format "Connection message [%s]" (mapcar #'chomp args))))

I added a fairly hacky (sit-for 1) after opening the client as otherwise I could send messages before it was ready due to the sentinel and nowait. Future versions will probably get the sentinel to set an "opened" variable which will determine whether the send message and close functions work.

(defun client-open (host port)
  (make-network-process :name client-process-name
                        :host host
                        :service port
                        :nowait t
                        :sentinel #'client-notify-connect)
  (sit-for 1))

Closing the connection is a simple matter of deleting the process. I confirmed this against my test perl server.

(defun client-close ()
  (delete-process (client-process)))
(defun client-send-string (str)
  (process-send-string (client-process) (concat str "\r\n")))

My test program simply sends 10 hello messages to the server at the same time as inserting 10 hellos in the buffer. The fact that the buffer insertions completed almost instantaneously whereas the server took around 20 seconds to display the messages indicates there is some degree of separation.

(progn
  (client-open 'local 8080)
  (dotimes (var 10)
    (client-send-string (format "Hello %s" var))
    (insert (format "Hello %s\n" var)))
  (client-close))

Next time I’ll look at setting up a filter to receive messages that the server sends back. Any questions or comments let me know.

If you liked this post, why not subscribe to my RSS feed.

Read Full Post »

« Newer Posts - Older Posts »

Follow

Get every new post delivered to your Inbox.