Announcing cpan.el

The Cat's Eye Nebula, one of the first planetary nebulae discovered, also has one of the most complex forms known to this kind of nebula. Eleven rings, or shells, of gas make up the Cat's Eye. Credit: NASA, ESA, HEIC, and The Hubble Heritage Team (STScI/AURA) Acknowledgment: R. Corradi (Isaac Newton Group of Telescopes, Spain) and Z. Tsvetanov (NASA) The Hubble Space Telescope is a project of international cooperation between NASA and the European Space Agency. NASA's Goddard Space Flight Center manages the telescope. The Space Telescope Science Institute conducts Hubble science operations. Goddard is responsible for HST project management, including mission and science operations, servicing missions, and all associated development activities.

The CPAN shell is just another shell, so why not drive it from Emacs?

If you write Perl code in Emacs, you may have wondered why we don’t have a simple mode for driving the CPAN shell (at least I couldn’t find one!).

Well, I finally stopped wondering. It wasn’t that hard to rip out the sh-specific parts of shell.el and make a new mode for the CPAN shell.

Here’s the code:

https://github.com/rmloveland/cpan-el

It’s easy to load up and drive from Emacs:

(add-to-list 'load-path (expand-file-name "/path/to/cpan-el/"))
(setq cpan-file-name "cpan")

(require 'cpan)

To run it, type M-x cpan.

There aren’t too any bells and whistles yet (completion, etc.), but you it’s pretty small so feel free to hack away.

(Image courtesy NASA Goddard Photo and Video under Creative Commons License.)

Advertisements

Emacs Compilation Mode Regexp for Perl 6

Emacs Compilation Mode Regexp for Perl 6

Stick this in your .emacs if you want Perl 6 support in Emacs’ compilation mode:

  (add-to-list 'compilation-error-regexp-alist 'perl6-stack-trace)
  (add-to-list 'compilation-error-regexp-alist-alist
               '(perl6-stack-trace .
                                   ("at \\([A-Za-z-_]+\\(\.p[l6m]\\)?\\):\\([[:digit:]]+\\)"
                                    1 3)))

I don’t know if this would be a good addition to perl6-mode, or if compilation mode regexps are supposed to live elsewhere.

If you like this sort of thing, see also: flycheck-perl6.

Driving the Scsh disassembler from Geiser

(Note: This post refers to functionality provided by geiser-scsh.)

Most Scheme 48 and scsh programmers are familiar with the \,dis command. It allows you to disassemble Scheme code (a procedure or continuation) into the “assembly” understood by the Scheme 48 virtual machine. Here’s an example using scsh’s fork/pipe procedure:

> ,dis fork/pipe
fork/pipe
  0 (protocol 0 +)
  4 (make-env 1)
  7 (global fork)
 10 (push-local0 1)
 13 (push)
 14 (global really-fork/pipe)
 17 (call 2)

This is pretty cool. However, I thought it would be even better if Geiser could run the disassembler on a region of Scheme code, and pop open the disassembler output in a new buffer. Geiser already supports similar functionality for macro-expansion via GEISER-EXPAND-REGION. There’s no reason why it shouldn’t do the same for the disassembler. So that’s what I taught it to do – in this screenshot I’m disassembling the LETREC expression:

../img/scsh-disassembler.png

(I have to admit I was inspired to work on this by my jealousy of the disassembler functionality available to Common Lispers via the SLIME-DISASSEMBLE-{DEFINITION,SYMBOL} commands in SLIME.)

How it Works

Here’s how it works:

  • Highlight a region of Scheme (scsh) code in a buffer
  • Call ‘M-x geiser-scsh-disassemble-region‘ (a.k.a., ‘C-c RET C-d‘).
  • Emacs sends the Scheme code to the running scsh process for disassembly via a newly exported Geiser macro, GE:DISASSEMBLE. This macro wraps the code in a LAMBDA before sending it to the disassembler to work around the fact that the S48 DISASSEMBLE procedure won’t accept arbitrary Scheme expressions such as (+ 1 1). (Wrapping expressions in LAMBDA like this is not ideal for reasons I’ll explain below.)

Future Work

This implementation is a proof of concept – don’t believe in it. Think of it as a prototype of how this functionality could work if built into Geiser proper. Here are some of the issues with it from an implementation perspective:

  • It doesn’t use the correct Geiser protocols for sending Scheme code to evaluate, instead just piping in raw strings. This was expedient because of the way s48/scsh use non-reader-friendly strings like {#Uncategorized} as the final lines of output for procedures whose outputs are not defined by the standard. I think this can be fixed by coming up with a better implementation of the Geiser code evaluation protocols (in scsh/geiser/evaluation.scm) so that they handle all of the weird cases in S48 output.
  • Related to the previous point, I’m doing some ugly regex stuff on the stringified output of the disassembler to make it nicer before piping it into the temp buffer.
  • This functionality should really be added to Geiser itself, via the GEISER-DEBUG-* namespace. Then it would be forced to address both of the above points. Right now it’s just an ugly little hack in geiser-scsh.el. In principle, with the right infrastructure in GEISER-DEBUG-*, there’s nothing preventing a Guile or Racket implementation (here’s the Guile disassembler in action – you can see that it’s not so different from S48):
    scheme@(guile-user)> (define (foo n) (expt n n))
    scheme@(guile-user)> ,x foo
    Disassembly of #<procedure foo (n)>:
    
       0    (assert-nargs-ee/locals 1)      ;; 1 arg, 0 locals
       2    (toplevel-ref 1)                ;; `expt'
       4    (local-ref 0)                   ;; `n'
       6    (local-ref 0)                   ;; `n'
       8    (tail-call 2)                                         at (unknown file):5:16
    
    • The disassembler, like the macro-expansion functionality, should be able to work recursively. That is, in places where the S48 assembly makes procedure calls like (global ge:really-fork/pipe) (as it does in our first example way at the top of this post), you should be able to ask for the disassembled output of GE:REALLY-FORK/PIPE as well, all the way down to the core primitives. Currently, there are cases where you still need to call \,dis <PROCEDURE> at the command prompt. I think this limitation is created by the way we wrap the expression in a LAMBDA before sending it to the disassembler. A better design is needed, one that (for example) calls PROCEDURE? on the proposed input, and then decides whether the expression needs to be wrapped in a LAMBDA before going to the disassembler.

Best. Markdown. Writing. Setup. Ever.

../img/markdown-emacs-compilation.png

When writing in a source format such as Markdown, it’s nice to be able to see your changes show up automatically in the output. One of my favorite ways to work is to have Emacs and Firefox open side by side (as shown above). Whenever I save my Markdown file, I want Emacs to automatically build a new HTML file from it, and I want Firefox to automatically refresh to show the latest changes.

Once you have this set up, all you have to do is write and save, write and save.

As it happens, fellow Redditor goodevilgenius was looking to accomplish just this workflow. I originally posted this answer on Reddit, but I’m reposting it here in the hope that it will help some kindly internet stranger someday.

I have this exact use case. I use compile-on-save mode and the Firefox Auto Reload extension.

So in a Markdown buffer (once you’ve installed compile-on-save mode):

M-x compile-on-save-mode RET
M-x compile RET markdown current-file.md > /tmp/current-file.html
Open current-file.html in Firefox.
Write stuff and save. Emacs will auto-compile the Markdown, and Firefox will instantly auto-reload the HTML file.

With Emacs and Firefox open side-by-side, I find it pretty easy to enter a “flow” state, since all you have to do is write and save the file. Hope that helps!

The Emacs-savvy reader will note that this workflow isn’t confined to Markdown. For example, compile-on-save mode could kick off an XML doc build (or any other computation you like, for that matter).

Scsh Manual Available in Texinfo Format

../img/shells.jpg

I am pleased to announce that, many years later, the famous Scsh Reference Manual has been converted to Texinfo. You can get your very own copy here: https://github.com/rmloveland/scsh-manual-texinfo.

This conversion represents quite a bit of work. Although I would have liked to do the conversion with a program, there was just too much of an impedance mismatch between the original LaTeX sources and Texinfo. Something tells me that’s why this conversion hasn’t happened until now. Whatever the reason, I’m glad to finally collect some internet cool points, even if it is almost twenty years later.

In the course of the conversion, I uncovered a number of small spelling, grammatical, and usage issues, which have now been fixed. To be clear: this is no criticism of the original authors. Several of them appear to be non-native English speakers. Their English is miles better than my German!

The resulting manual builds very nicely into HTML, PDF, or Info files. The PDF in particular is nice, since you get beautiful, clickable links everywhere! And the Info files are quite easy to install in your local Emacs.

Speaking of Emacs, if you like hacking Scsh from Emacs, try my geiser-scsh setup. Better yet, help me hack on it!

(Image courtesy steeljam under CC-BY-NC-ND license.)

Geiser and Scsh are Talking

../img/fractal-cheetah.jpg

In this post I’d like to announce an early version of scsh 1 support for Geiser 2. There’s plenty left to do, but enough of Geiser is working that you can write scsh with real completions provided by scsh itself! What’s more, if you want to you can hack on the Geiser support from the inside. :-}

Working features include:

  • Symbol and module completion
  • Module imports (mostly)
  • view macroexpansions in buffer
  • Talking to Geiser over its async protocol (the foundation of everything else)

Some features aren’t there yet:

  • Jumping to procedure definition in source
  • Show callers/callees of a procedure
  • Jumping to module source
  • Jumping to documentation for the thing at point (I’ve only gotten this to work sporadically for some reason)

Getting the Code

You can get the code here:

https://github.com/rmloveland/geiser-scsh

See the README and TODO.org files in the repo for more detailed information about project goals and what works and what doesn’t. Feel free to open issues on Github for any broken things (there are plenty).

You can also get a copy of the scsh manual in Texinfo here – please let me know if you can get the Geiser doc commands working with it, so far I haven’t had much success:

https://github.com/rmloveland/scsh-manual-texinfo

Getting Started

There are a few setup quirks:

  • First, set Emacs’ geiser-scheme-dir variable to wherever you’re working from; here’s what I do:
    (setq geiser-scheme-dir (expand-file-name "~/Code/geiser-scsh/scheme/"))  
    
  • Second, go ahead and load up geiser-scsh.el from the git repo.
  • Next, hop into Customize via M-x customize-group ENTER geiser ENTER, and set the following:
    Custom Variable Value Note
    Geiser Repl Skip Version Check P on You must set this, or else Emacs throws you into the debugger. This is a bug I need to fix.
    Geiser Active Implementations scsh
    Geiser Default Implementation scsh I do this since I’m mostly working in scsh, but it shouldn’t be necessary.

    (Note that you’ll need to set geiser-scheme-dir back to its original value if you want to go back to using Guile or Racket.)

At this point, you should be able to do M-x run-scsh and enjoy your scsh hacking with nice completions and whatnot. If you’re going to hack on the Geiser support, do a C-u M-x geiser-show-logs; a buffer will open where you can listen to scsh and Emacs talking. And of course, the source is your friend. :-}

(Image courtesy RayMorris1 under CC-BY-NC-ND license.)

Edwin Support for External Schemes

I’m pleased to announce an alpha release of support for using Edwin to interact with external Schemes. This is similar to the way Emacs can interact with REPLs from languages other than Emacs Lisp.

The code is available at http://github.com/rmloveland/edwin-external-scheme. The repository contains two Edwin modes, “External Scheme mode” and “External Scheme REPL mode”.

Usage

“External Scheme REPL mode” allows you to interact with an external Scheme REPL’s process from Edwin in the same way you would interact with a shell using `#\M-x shell’. Load the file `external-scheme-repl.scm’ and enter the command `#\M-x external-scheme-repl’. You’ll be asked to enter the name of the external Scheme you’d like to run, and away you go.

External Scheme mode inherits from Edwin’s Scheme mode for all of its formatting and editing commands, but provides its own commands for sending expressions to a running external Scheme REPL, if one exists.

Load the file `external-scheme-mode.scm’ and enter the command `#\M-x external-scheme-mode’ in a buffer containing Scheme code that you want to send to the external Scheme. Right now you can run only one external Scheme REPL, so be sure that the code you’re sending is going to be understood by that Scheme. It’s a simple matter of programming to extend this to multiple external Scheme buffers if you care to.

Caveats

Right now you may run only one external Scheme REPL at a time. Any Scheme buffers in External Scheme mode will send their eval’d code to that REPL.

Finally, note that files containing Scheme code are automatically opened by Edwin in its own Scheme mode, no matter what Scheme they’re written in, so you’ll need to do `#\M-x external-scheme-mode’.

Motivation

Finally, why bother? Isn’t MIT Scheme good enough? The answer is yes: it’s great. However, I often write scripts using Scheme Shell due to its tight integration with UNIX and excellent process notation. I could already write these programs in Emacs, but Edwin is my preferred editor.