John DeRosa: GNU Emacs for OS X is a Win

I’ve used Aquamacs for the past four years or so. It has its strong points.

But I’ve always been a little unhappy with its slow performance relative to native Emacs (I use a MacBook Pro), and its unique initialization and behaviors. I’m sure there are good reasons for every difference. But each difference, no matter how small, is a little more cognitive load. E.g., I never got used to M-x Info opening up in a new window somewhere on my screen…

Today, I decided to try Emacs for Mac OS X. Whoa! I love it! It’s Emacs, the whole Emacs, and nothing but the Emacs.  Win!

I even donated $50 to the project. So there!


Tagged: Emacs
-1:-- GNU Emacs for OS X is a Win (Post John)--L0--C0--November 20, 2014 06:23 PM

Grant Rettke: Don’t run mode hooks during org exports

binchen has a nice post about how to disable org mode hook execution during exports. It can be a surprise when you run in batch mode and your export breaks because of dependency failures. Oh yea, the major mode hooks run during export even though you personally are not opening a buffer, Emacs is doing so!

Here is his solution:

(defun is-buffer-file-temp ()
  (interactive)
  "If (buffer-file-name) is nil or a temp file or HTML file converted from org file"
  (let ((f (buffer-file-name))
        (rlt t))
    (if f
        (if (and (not (string-match temporary-file-directory f))
                 (not (file-exists-p (replace-regexp-in-string "\.html$" ".org" f))))
          (setq rlt nil)))
    rlt))

Interesting.

-1:-- Don’t run mode hooks during org exports (Post Grant)--L0--C0--November 20, 2014 04:28 PM

Irreal: The info-display-manual Command

The prolific Bozhidar Batsov has another nice Emacs tip. If you want to want to look up an Info manual and know its name you can use the info-display-manual command to go right to it. This probably doesn't save much time unless you give it a convenient key binding—Batsov recommends 【Ctrl+i】 but you can use whatever makes sense for your configuration. If you access the Info manuals from Emacs regularly, you should head over to Emacs Redux and check out his post.

-1:-- The info-display-manual Command (Post jcs)--L0--C0--November 20, 2014 12:41 PM

Chen Bin (redguardtoo): Export org file embedded with code snippets

I use Org-mode to record all my notes.

As a developer, I place code snippets from many programming languages into one org file.

The issue is when exporting the org file, major mode for each language will be loaded to render the code snippet.

It means the hooks of the major modes will be executed. Since I put lots of heavy weight setup things in those hooks, my exporting is extremely slow.

In order to solve the issue, I write a small function which will be called at the beginning of each major mode hook.

The function basically check whether the `(buffer-file-name)` is the temporary file created by Org-mode or the output HTML converted from org file. If answer is "YES", then code in major mode hook will not be executed.

(defun is-buffer-file-temp ()
  (interactive)
  "If (buffer-file-name) is nil or a temp file or HTML file converted from org file"
  (let ((f (buffer-file-name))
        (rlt t))
    (if f
        (if (and (not (string-match temporary-file-directory f))
                 (not (file-exists-p (replace-regexp-in-string "\.html$" ".org" f))))
          (setq rlt nil)))
    rlt))

Another tip is that exporting shell code will fail if `sh-mode` is loaded. So I use "bash" instead. Since there is no "bash-mode", exporting will be fine.

-1:-- Export org file embedded with code snippets (Post)--L0--C0--November 20, 2014 12:22 PM

Irreal: Emacs Rocks! Episode 15

After 19 months, Magnar Sveen is back with episode 15 of Emacs Rocks!. Emacsers everywhere will rejoice, I'm sure.

This episode is a demonstration of Pavel Kurnosov's restclient package. It's a very handy and simple way of exercising HTTP REST webservices. You can get results in text, JSON, XML, or even images. Watch Sveen's excellent video to get an idea of what you can do.

-1:-- Emacs Rocks! Episode 15 (Post jcs)--L0--C0--November 19, 2014 12:25 PM

Endless Parentheses: Emacs Rocks Again!

The emacs community received some fantastic news yesterday.

Magnar Sveen's blog, What the emacs.d?!, was the greatest inspiration behind Endless Parentheses, and these 5 extra minutes of content from him cheered up my entire day.

Comment on this.

-1:-- Emacs Rocks Again! (Post)--L0--C0--November 19, 2014 12:00 AM

Timo Geusch: The official GNU Emacs 24.4 build is available for Windows

Looks like the Windows build of Emacs 24.4 has been released to http://ftp.gnu.org/gnu/emacs/windows/ on November 15th. As usual, I appear to be a few days behind the times. Time to upgrade and see how it compares to the unofficial 64 bit builds I’ve been using recently. Top new feature in 24.4 for me so far […]

The post The official GNU Emacs 24.4 build is available for Windows appeared first on The Lone C++ Coder's Blog.

-1:-- The official GNU Emacs 24.4 build is available for Windows (Post Timo Geusch)--L0--C0--November 18, 2014 08:21 PM

sachachua: Emacs: Limiting Magit status to a directory

I’m probably using Git the wrong way. In addition to the nice neat repositories I have for various projects, I also sometimes have a big grab-bag repository that has random stuff in it, just so that I can locally version-control individual files without fussing about with Emacs’ numbered version systems. Sometimes I even remember to organize those files into directories.

When you have a Git repository that’s not one logical project but many little prototypes, using Magit status to work across the entire project can sometimes mean running into lots of distracting work in progress. I wanted a way to limit the scope of Magit status to a specific directory.

Here’s the experimental code I came up with:

      (defvar sacha/magit-limit-to-directory nil "Limit magit status to a specific directory.")
      (defun sacha/magit-status-in-directory (directory)
        "Displays magit status limited to DIRECTORY.
Uses the current `default-directory', or prompts for a directory
if called with a prefix argument. Sets `sacha/magit-limit-to-directory'
so that it's still active even after you stage a change. Very experimental."
        (interactive (list (expand-file-name
                            (if current-prefix-arg
                                (read-directory-name "Directory: ")
                              default-directory))))
        (setq sacha/magit-limit-to-directory directory)
        (magit-status directory))

      (defadvice magit-insert-untracked-files (around sacha activate)
        (if sacha/magit-limit-to-directory
            (magit-with-section (section untracked 'untracked "Untracked files:" t)
              (let ((files (cl-mapcan
                            (lambda (f)
                              (when (eq (aref f 0) ??) (list f)))
                            (magit-git-lines
                             "status" "--porcelain" "--" sacha/magit-limit-to-directory))))
                (if (not files)
                    (setq section nil)
                  (dolist (file files)
                    (setq file (magit-decode-git-path (substring file 3)))
                    (magit-with-section (section file file)
                      (insert "\t" file "\n")))
                  (insert "\n"))))
          ad-do-it))

      (defadvice magit-insert-unstaged-changes (around sacha activate)
        (if sacha/magit-limit-to-directory
            (let ((magit-current-diff-range (cons 'index 'working))
                  (magit-diff-options (copy-sequence magit-diff-options)))
              (magit-git-insert-section (unstaged "Unstaged changes:")
                  #'magit-wash-raw-diffs
                "diff-files"
                "--" sacha/magit-limit-to-directory
                ))
          ad-do-it))

      (defadvice magit-insert-staged-changes (around sacha activate)
        "Limit to `sacha/magit-limit-to-directory' if specified."
        (if sacha/magit-limit-to-directory
            (let ((no-commit (not (magit-git-success "log" "-1" "HEAD"))))
              (when (or no-commit (magit-anything-staged-p))
                (let ((magit-current-diff-range (cons "HEAD" 'index))
                      (base (if no-commit
                                (magit-git-string "mktree")
                              "HEAD"))
                      (magit-diff-options (append '("--cached") magit-diff-options)))
                  (magit-git-insert-section (staged "Staged changes:")
                      (apply-partially #'magit-wash-raw-diffs t)
                    "diff-index" "--cached" base "--" sacha/magit-limit-to-directory))))
          ad-do-it)))

Now I can bind C-x v C-d to sacha/magit-status-in-directory and get something that lets me focus on one directory tree at a time. You can see my config in context at http://sachachua.com/dotemacs#magit

It feels like I’m probably trying to do things the Wrong Way and I should probably just break things out into separate repositories. Even though I realized this early on, though, I ended up digging into how to implement it just for the sheer heck of seeing if Emacs would let me do it. =) I don’t know how often I’ll use this function, but it was a good excuse to learn more about the way Magit works.

It took me an hour to find my way around magit.el, but that’s more my fault than the code’s. At first I tried to override magit-diff-options, but I eventually remembered that the paths need to come at the end of the command line arguments. (I had a cold! My brain was fuzzy!) It was fun poking around, though. Looking forward to learning even more about Magit!

The post Emacs: Limiting Magit status to a directory appeared first on sacha chua :: living an awesome life.

-1:-- Emacs: Limiting Magit status to a directory (Post Sacha Chua)--L0--C0--November 18, 2014 01:00 PM

Grant Rettke: How to debug expanded elisp macros

This video reveals just how amazingly it easy it is to expand and debug macros in elisp using the macrostep package.

Via irreal.

-1:-- How to debug expanded elisp macros (Post Grant)--L0--C0--November 18, 2014 01:06 AM

Endless Parentheses: Inserting the kbd tag in interactively

It doesn't take a psychic to guess the <kbd> tag will be useful when writing about Emacs. When Jorge Navarro asked for the best way to do this, over at Emacs.SE, I thought I'd share the snippet I use.

This simple command will ask for a key sequence (just like C-h k would) and will insert it for you. If you want to write the sequence manually, just hit RET when prompted.

(define-key org-mode-map "\C-ck" #'endless/insert-key)
(defun endless/insert-key (key)
  "Ask for a key then insert its description.
Will work on both org-mode and any mode that accepts plain html."
  (interactive "kType key sequence: ")
  (let* ((is-org-mode (derived-mode-p 'org-mode))
         (tag (if is-org-mode
                  "@@html:<kbd>@@%s@@html:</kbd>@@"
                "<kbd>%s</kbd>")))
    (if (null (equal key "
"))
        (insert
         (format tag (help-key-description key nil)))
      (insert (format tag ""))
      (forward-char (if is-org-mode -15 -6)))))

It should work in both org-mode and markdown-mode.

Comment on this.

-1:-- Inserting the kbd tag in interactively (Post)--L0--C0--November 17, 2014 12:00 AM

Wilfred Hughes: Editing Julia code (with Emacs!)

I’m a big admirer of the Julia programming language: it’s a fast general-purpose language with a nice syntax, macros, and a decent package manager.

No respectable up-and-coming language should be without good editor support. I’ve been polishing the Emacs mode, and learnt a lot about the language. If you’re writing Julia code, or integrating an editor, this should be interesting to you.

Syntax highlighting

Syntax highlighting is hard, and it’s rather challenging in Julia. We’ll look at some corner cases of syntax highlighting in Julia, so I’ll show code snippets along with screenshots of how this code is currently highlighted in Emacs.

I’ve written a complete Julia syntax highlighting test file which exercises all the different syntactic features of the language. You can use this to test Julia support in your editor of choice.

Highlighting function calls

Julia supports two ways of declaring functions, which the docs describe as ‘basic’ and ‘terse’.

function f(x,y)
    x + y
end

f(x,y) = x + y

We want to highlight keywords (such as function and end) and to highlight function names (f in this example). This is pretty straightforward: we can write a regular expression that spots either the keyword function or a symbol followed by something roughly like (.*?) =.

We can also define functions in an explicit namespace. This is also straightforward, we just highlight the last symbol after the dot.

function Foo.bar(x, y)
    x + 1
end

A function definition may also include type variables. This isn’t too difficult to handle either, we just need to adjust our terse regular expression to step over the curly brackets.

elsize{T}(::AbstractArray{T}) = sizeof(T)

function elsize{T}(::AbstractArray{T})
    sizeof(T)
end

However, highlighting gets harder with nested brackets.

cell(dims::(Integer...)) = Array(Any, convert((Int...), dims))

At this point, our naive regular expression falls down. We need to count brackets, or write a crude parser. The Emacs editing mode doesn’t yet handle this case.

Macro usage

Highlighting macros is easy. There are some awkward syntactic edge cases but these don’t affect highlighting.

@hello_world! foo

Built-in functions

Julia has a lot of built-in functions. After some discussion, we felt that it wasn’t worth special-casing functions that are keywords in other languages, such as throw and error.

throw(foo)
error("foo", bar, "baz")

Strings and characters

Julia has a lovely syntax here, but it takes a little care to highlight correctly.

For characters, Julia uses single quotes, but it also supports ' as an operator. This gives very readable mathematical formulae.

# Characters
x = 'a'
y = '\u0'

# Not characters
a = b' + c'

Julia’s string syntax allows multi-line strings, triple-quoted strings, regular expression literals, byte array literals and (particularly nifty) version number literals.

x = "foo
bar"
x = """hello world"""
x = "hello $user"
x = r"foo.*"ismx
x = v"0.1"
x = b"DATA\xff\u2200"

We are handling most of this syntax in the Emacs mode, but it’s not perfect yet. I think we should highlight interpolated values in strings. See my test file for a full set of examples.

Comments

Julia’s comment syntax is also very nice. There are single-line and multi-line comments, and they support arbitrary nesting.

# I'm a comment.

#= I'm a 
multi-line comment. =#

#= I'm a #= nested =# comment. =#

Emacs makes it easy for us to support all this different variants, so we’ve supported this for a long time.

Type declarations

You can declare your own types in Julia.

type Foo
    x::Bar
end
immutable Foo
    x::Bar
end

abstract Foo <: Bar

This is mostly a case of knowing all the keywords for type declaration, so it’s straightforward.

The operator <: is particularly tricky. It is used in type declarations to declare subtypes, but it’s also used a boolean operator to see if one value is a subtype of another x <: y. I believe this is impossible to highlight correctly in all cases.

# I can't see how to highlight the first 'T' here.
same_type_numeric{T<:Number}(x::T, y::T) = true

We can cheat by having a full list of built-in types in our highlighting code, so we highlight most subtype declarations correctly.

Type annotations

Julia supports optional type annotations in functions and on variables. These are simple to highlight, but we need to get :: right before dealing with quoted symbols.

f(x::FooBar) = x

function foo()
    local x::Int8 = 5
    x
end

Variable declarations

Julia has a local keyword which lets you introduce local variable bindings. I’d love to highlight this correctly too.

global x = "hello world", y = 3

let x = 1
    x + 1
end

function foo()
    local x = 5
    x + 1
end

This requires parsing to handle correctly, so we don’t handle it yet. We can’t simply look for commas, as there may be arbitrary Julia expressions used.

# 'b' is not declared as a variable here.
global x = foo(a, b), y = 3

Colons and quoting

The hardest part of Julia’s syntax is :. There have also been users confused by this syntax.

# Quoted symbols
x = :foo
y = :function
foo[:baz]
[1 :foo]

# Not quoted symbols
foo[bar:end]
foo[bar:baz]
x = :123
for x=1:foo
    print(x)
end

I’ve opened a pull request that enables Emacs to handle the most common usages correctly, but this is very hard to get right in all cases.

Numbers

Finally, Julia has a really neat numeric syntax. It supports all the literals you could possibly want. It also lets you write 2x as a shorthand for 2 * x, which makes many equations in Julia much more similar to a maths textbook.

x = 0x123abcdef
x = 0o7
x = 0b1011
x = 2.5e-4

# Equivalent to '2 * x'
y = 2x

The Emacs mode currently doesn’t highlight these, but we probably should. Some Emacs modes highlight numbers, some don’t, but for a language with a focus on scientific computing, it would make sense to highlight numbers. It’s particularly helpful to help readers see that 2x is two separate symbols.

Conclusions

Julia’s syntax isn’t completely set in stone, but I doubt much of the syntax will change in ways that affect highlighting. The syntax favours readability over simple parsing (a great tradeoff), so writing a highlighter takes some careful thought.

Once you’ve got syntax highlighting working, it’s much easier to handle indentation. I think Emacs’ ability to indent Julia is pretty good (this blog post is plenty long enough without getting into indentation) and this is because it can fairly robustly identify block delimiters for highlighting.

Finally, it’s also desirable to have as-you-type syntax checking and linting. Flycheck will add support for this using Lint.jl as soon as Lint.jl/Julia performance is good enough to run on demand without a persistent process.

If you do encounter a bug with Emacs and Julia, there’s a ‘julia-mode’ issue label to track any bugs.

Happy hacking!

-1:-- Editing Julia code (with Emacs!) (Post Wilfred Hughes (me@wilfred.me.uk))--L0--C0--November 16, 2014 12:00 AM

Chen Bin (redguardtoo): How a programmer publish static HTML blog in Emacs

I can publish my blog in five seconds, by running only one Emacs command!

I will give you a minimum solution, then explain why and provide technical details.

Basic Emacs lisp programming knowledges are required.

Please note I'm NOT targeted at specific static site generator like Nikola or Jekyll.

Solution

Tested on Linux and OSX.

Requirements:

  • Org-mode bundled with Emacs 24.x
  • Nikola as the blog generator
  • FTP client ncftp
  • Latest org2nikola (v0.0.9+)
  • Insert below code into ~/.emacs
(defun org2nikola-after-hook-setup (title slug)
  (let ((url (concat "http://blog.yourdomain.net/posts/" slug ".html"))
        (nikola-dir (file-truename "~/projs/nikola-root"))
        (password "yourpassowrd")
        (username "yourusername")
        dir
        file
        lines
        rlt
        res
        cmd)
    (copy-yank-str title)
    (copy-yank-str url)
    (message "%s => kill-ring&clipboard" url)
    (setq rlt (shell-command-to-string (format "cd %s; nikola build" nikola-dir)))
    (setq lines (split-string rlt "\n"))
    (dolist (l lines)
      (when (string-match "output\\(.*/\\)*\\([^/]*\\)$" l)
        (setq dir (match-string 1 l))
        (setq file (match-string 2 l))
        (setq cmd (format "ncftpput -b -u %s -p %s ftp.yourdomain.net /blog%s %s/output%s%s"
                          username password dir nikola-dir dir file))
        (message "cmd=%s" cmd)
        (shell-command cmd)
        ))
    ))

(add-hook 'org2nikola-after-hook 'org2nikola-after-hook-setup)

You can write blog into org file, export and publicize it with command `M-x org2nikola-export-subtree`.

Why

I used Wordpress and Org2blog for a very long time. Then I turned to static blog generator because:

  • Wordpress is slow to load web page
  • I waste too much time to "manage" Wordpress (applying security patch, fighting with spam comment …)
  • As a programmer, I need publish code snippets. Wordpress is BAD at rendering code.

Yes, only wordpress sucks. For Org2blog, I can only say good things. Actually, this article is inspired purely by Puneeth Chaganti's excellent work on org2blog.

Technical Details

Generating HTML

As I said, Nikola is my blog generator which converts my org file into HTML.

But I prefer using Org-mode to do the HTML rendering. Nikola only need handle remaining minor book keeping stuff (creating RSS feed, for example).

It's because I want to minimize the dependency. I may switch to other blog generator in the future. But my web site always has the same look and feel because the HTML is generated by Org-mode.

I learned this trick from Org2blog.

If we only use org-mode to create HTML, then extracting code snippet is really easy. All we need is to use regular expression to extract the content between HTML tag "<pre>".

Actually I don't even bother doing the extraction. I just replace all the "<pre>" tag with my own tag because I assume the HTML produced by org-mode is stable.

Here is the Emacs lisp code I borrowed from Org2blog:

(defun org2nikola-replace-pre (html)
  "Replace pre blocks with sourcecode shortcode blocks.
shamelessly copied from org2blog/wp-replace-pre()"
  (save-excursion
    (let (pos code lang info params header code-start code-end html-attrs pre-class)
      (with-temp-buffer
        (insert html)
        (goto-char (point-min))
        (save-match-data
          (while (re-search-forward "<pre\\(.*?\\)>" nil t 1)

            ;; When the codeblock is a src_block
            (unless
                (save-match-data
                  (setq pre-class (match-string-no-properties 1))
                  (string-match "example" pre-class))
              ;; Replace the <pre...> text
              (setq lang (replace-regexp-in-string ".*src-\\([a-zA-Z0-9]+\\).*" "\\1" pre-class)  )

              (replace-match "")
              (setq code-start (point))

              ;; Go to end of code and remove </pre>
              (re-search-forward "</pre.*?>" nil t 1)
              (replace-match "")
              (setq code-end (point))
              (setq code (buffer-substring-no-properties code-start code-end))

              ;; Delete the code
              (delete-region code-start code-end)
              ;; Stripping out all the code highlighting done by htmlize
              (setq code (replace-regexp-in-string "<.*?>" "" code))
              ;; class linenums will add stripes which will destory the 3rd party skins
              (insert (concat "\n<pre class=\"prettyprint lang-"
                              (org2nikola-fix-unsupported-language lang)
                              "\">\n"
                              code
                              "</pre>\n"))
              )))

        ;; Get the new html!
        (setq html (buffer-substring-no-properties (point-min) (point-max))))
      ))
  html)

The code snippet inside "<pre>" tag could be rendered by 3rd party javascript library google-code-prettify or SyntaxHighlighter.

BTW, the last straw that push me away the Wordpress is its wrapper of SyntaxHighlighter. SyntaxHighlighter is a beautiful and user-friendly library. But the wrapper forces me to tweak the php code in terrible editor from Wordpress.

Create blog posts

Emacs creates HTML files and meta files. Things created by Emacs will be copied into Nikola's folder.

Nikola's duty is simple. Basically it only copy my stuff from its input folder to its output folder when I trigger "nikola build" command.

The "nikola build" command will also dump the list of files to be uploaded into stdout.

The build message dumped:

Scanning posts....done!
.  render_archive:output/2014/index.html
.  render_sources:output/posts/jump-to-the-positions-before-and-after-m-x-imenu.wp
.  render_posts:cache/posts/jump-to-the-positions-before-and-after-m-x-imenu.html
.  render_indexes:output/index.html
.  render_indexes:output/index-17.html
.  render_tags:output/categories/en.html
.  render_tags:output/categories/emacs.html
.  render_tags:output/assets/js/tag_cloud_data.json
.  render_tags:output/categories/emacs.xml
.  generate_rss:output/rss.xml
.  render_pages:output/posts/jump-to-the-positions-before-and-after-m-x-imenu.html
.  render_pages:output/posts/why-emacs-is-better-editor-part-two.html
.  render_tags:output/categories/en.xml

Only the files in sub-folder "output" need be uploaded.

Preprocess nikola output

It's all done by Emacs Lisp.

The final output contain lines like:

ncftpput -b -u yourname -p yourpassword ftp.yourdomain.net /blog/2014/ /home/yourname/nikola-root/output/2014/index.html

As you can see, each line is a ftp upload command we need execute in shell.

FTP upload

Ncftp is my choice of FTP client. It's solid and efficient.

Its command line tool "ncftpput" has a flag "-b". With the flag ncftpput will start a daemon at background and handles the ftp upload as a batch job submit. It means ftp connection will be reused and the user is not blocked by the upload operation. So the upload operation is extremely fast.

I use Emacs Lisp API `file-truename` to convert all relative path to absolute path to avoid any platform (OSX) issue.

BTW, you can `cat ~/.ncftp/spool/log` to check the FTP upload status.

Summary

The workflow is simple.

Emacs and third party JS libraries are responsible for the look and feel of my website.

Blog generator like Nikola is just a thin layer to relay the HTML files created by Emacs.

Ncftp will upload HTML files. It's the best FTP client which could be easily integrated into Emacs.

-1:-- How a programmer publish static HTML blog in Emacs (Post)--L0--C0--November 15, 2014 04:16 AM

Mickey Petersen: Emacs's switch to Git

After nearly ten months of hard work, Eric S Raymond (esr) has finished the transition from Bazaar to Git, and in the process cleaned up 29 years of ossified CVS references and other source control flotsam. ESR calls it “geologic strata” and he’s not even kidding. 29 years of continued development makes it unavoidable. If you haven’t been keeping up I suggest you read his article on the conversion.

The move to Git, I think, is a big one. Like it or not, but it won the source control fight. Bazaar lost (not that it ever had a chance of winning); Mercurial lost too (and it did have a chance of winning.) Git’s the right choice; it will significantly reduce the barrier to entry for new developers — well, you still need to sign over your code to the FSF, but it’s easier.

Lars Ingebrigtsen has written a great tutorial for newcomers interested in contributing to Emacs. I had no idea it was that easy to find and push bug fixes out. There’s a fancy Emacs package, debbugs, that makes it easy to do so (obviously.)

I hope the switch to git will renew interest in committing to Emacs.

-1:-- Emacs's switch to Git (Post)--L0--C0--November 14, 2014 09:55 AM

Emacs Redux: Quickly Open an Info Manual

Every Emacs user knows that Emacs ships with plenty of built-in documentation in the GNU info format (they don’t call it a self-documenting editor for no reason). Most Emacs users know how to access that built-in documentation with C-h i (M-x info) and some Emacs users even know that the Emacs manual can be opened directly with C-h r (M-x info-emacs-manual).

If you know the name of the manual you’re looking for, however, there’s a nice little-known alternative to using C-h i - the info-display-manual command. When you run it you’ll be prompted in the minibuffer for the name of the manual you’d like to view (manual name completion is available).

To give you a more concrete example of the command’s advantage over info let’s try to open the Emacs Lisp manual with both commands. With info you’ll have to type the following:

1
M-x info RET m elisp RET

And the alternative would be:

1
M-x info-emacs-manual RET elisp RET

If you like the command I’d suggest binding it to some keybinding:

1
(define-key 'help-command (kbd "C-i") 'info-display-manual)
-1:-- Quickly Open an Info Manual (Post)--L0--C0--November 13, 2014 01:25 PM

Emacs Redux: Emacs's Development has Migrated to Git

The long wait is over - Emacs’s development has finally migrated from bazaar to git.

Now you don’t have any excuses not to contribute to Emacs!

If you’re wondering where to start I’d suggest taking a look at this short article.

-1:-- Emacs's Development has Migrated to Git (Post)--L0--C0--November 13, 2014 01:19 PM

John DeRosa: Back to the Future

After my embarrassing post about anaconda, I’ve awakened a Jonesing for working again in Lisp. I think I’ll look for a project to contribute to — maybe start by fixing some minor bugs in an Emacs package, or something similar.


Tagged: Emacs, Lisp
-1:-- Back to the Future (Post John)--L0--C0--November 12, 2014 10:41 PM

sachachua: Emacs: Evaluating Javascript and CSS in Chrome using Skewer Mode

I build a lot of quick prototypes, using Javascript and CSS to build little tools on top of the Jive social business platform. Since Javascript syntax errors could prevent the proper loading of the overview page customization screen and require me to reset the overview page through the admin console, my previous Javascript workflow involved copying and pasting code into Google Chrome’s developer console. Most of the time, I used narrow-to-region to focus on just the specific script block or set of functions I was working on, and I used js2-mode to handle syntax highlighting and indentation. Once the Javascript was sorted out, I’d widen to get back to the full HTML, JS, and CSS file, using web-mode for indentation.

Copying code between Javascript buffers and the developer console was a bit of a hassle. I’d use C-x h (mark-whole-buffer) to select the buffer, then C-w to copy it, change over to the Chrome window (possibly wading through a number of tabs and windows to find the right one), find the developer console, click in it, paste the code, and run it. My first step was to define a custom function that copied the whole buffer:

(defun sacha/copy-buffer ()
  "Copy buffer contents to kill ring."
  (interactive)
  (kill-new (buffer-substring-no-properties (point-min) (point-max))))
(global-set-key (kbd "C-c w") 'sacha/copy-buffer)

I still had to find the Chrome window and paste the code in, though.

My CSS workflow had its own challenges. I used Inspect Elements to look at CSS properties, and then I modified them on the fly. When I was happy with the rules I added or changed, I wrote the corresponding CSS code in my local file. Because I often ended up modifying several elements, it was hard to remember all the changes I needed to make, apply different sets of changes, or apply the changes after reloading the page. I used Stylish to make some of my changes persistent, but that still involved going back and forth between screens.

Since I’ll continue to work on web development over the next year (at least!), I thought I’d invest some time into improving my workflow. I’d seen several demos of Skewer Mode for Emacs, and I’d even given it a try a few times before. I hadn’t integrated it into my workflow yet, but it looked like it was definitely worth a try. Skewer allows you to interact with Google Chrome from Emacs. You can send HTML, CSS, and Javascript fragments to your browser.

If you use the included Greasemonkey-compatible script, you can even use this interactive capability on any website. I used the Tampermonkey extension for Google Chrome to run the script. When I tried it on the site I was working on, though, the https/http mismatch resulted in a content security error. It turns out that you need to run chrome --allow-running-insecure-content in order to let Chrome inject HTTPS sites with the scripts from the local HTTP server that Skewer Mode runs inside Emacs. If you had other Chrome sessions open, you’ll want to close them before starting up Chrome with that option. Once I sorted that out, it was easy to run skewer-setup, open a JS file, and start sending code to my browser.

I quickly became a fan of how C-c C-k (skewer-load-buffer in JS, skewer-css-eval-buffer in CSS) let me send my buffer to my browser. I narrowed my buffer to the parts I was working on, wrote some tests using console.assert(...), and kept the console visible as I coded. I periodically loaded the buffer to check whether my tests passed. I also liked having a proper file identifier and correct line numbers for errors. (It’s amazing how small things matter!)

Then to top it all off, I wanted a function that would prepare the source code for easy pasting into an HTML widget:

<script type="text/javascript">
// filename
</script>

Since Emacs is Emacs, you can do that. =)

(defvar sacha/javascript-test-regexp (concat (regexp-quote "/** Testing **/") "\\(.*\n\\)*")
  "Regular expression matching testing-related code to remove.
See `sacha/copy-javascript-region-or-buffer'.")

(defun sacha/copy-javascript-region-or-buffer (beg end)
  "Copy the active region or the buffer, wrapping it in script tags.
Add a comment with the current filename and skip test-related
code. See `sacha/javascript-test-regexp' to change the way
test-related code is detected."
  (interactive "r")
  (unless (region-active-p)
    (setq beg (point-min) end (point-max)))
  (kill-new
   (concat
    "<script type=\"text/javascript\">\n"
    (if (buffer-file-name) (concat "// " (file-name-nondirectory (buffer-file-name)) "\n") "")
    (replace-regexp-in-string
     sacha/javascript-test-regexp
     ""
     (buffer-substring (point-min) (point-max))
     nil)
    "\n</script>")))

(define-key js2-mode-map (kbd "C-c w") 'sacha/copy-javascript-region-or-buffer)

So now I can fiddle around with Javascript and CSS, send it to my browser with C-c C-k, and then use C-c w to wrap the Javascript in script tags and prepare it for copying.

Emacs!

The post Emacs: Evaluating Javascript and CSS in Chrome using Skewer Mode appeared first on sacha chua :: living an awesome life.

-1:-- Emacs: Evaluating Javascript and CSS in Chrome using Skewer Mode (Post Sacha Chua)--L0--C0--November 11, 2014 01:00 PM

Alex Schroeder: Oddmuse Development

Magit is cool. It works on my Emacs on Windows, too. Git integration! The picture shows that it uses ASCII art to visualize and colorizes the branching and merging. This also shows that I shouldn’t be developing on multiple machines.

Tags: RSS RSS

-1:-- Oddmuse Development (Post)--L0--C0--November 11, 2014 10:25 AM

Bozhidar Batsov: The Road to CIDER 0.8

I’m planning to release the long overdue CIDER 0.8 at clojure/conj 2014. I’ll be giving a talk there that will be mostly about CIDER, so this seems like a pretty good idea to me.

I’d like to ask you to do a bit of extra testing to the current snapshot builds, so we can deliver a solid release (if we’re lucky – the most solid ever). Guess you should pay extra attention to the new features.

If you want to get some issue fixed in time for 0.8 you’d better get started right away.

Thanks in advance for your help!

-1:-- The Road to CIDER 0.8 (Post)--L0--C0--November 10, 2014 01:27 PM

Timo Geusch: Finally trying out a 64 bit Emacs on Windows

I’ve been using the official GNU distribution of Emacs for Windows for the last few years and am very happy with it. Well, usually I am very happy with it until someone sends me a 25GB log file I need to analyse and the 32 bit Emacs refuses to play when faced with the enormity […]

The post Finally trying out a 64 bit Emacs on Windows appeared first on The Lone C++ Coder's Blog.

-1:-- Finally trying out a 64 bit Emacs on Windows (Post Timo Geusch)--L0--C0--November 01, 2014 04:00 PM

Jorgen Schäfer: Elpy 1.6.0 released

I just released version 1.6.0 of Elpy, the Emacs Python Development Environment. This is a feature release.

Elpy is an Emacs package to bring powerful Python editing to Emacs. It combines a number of other packages, both written in Emacs Lisp as well as Python.

Quick Installation

Evaluate this:

(require 'package)
(add-to-list 'package-archives
'("elpy" .
"http://jorgenschaefer.github.io/packages/"))

Then run M-x package-install RET elpy RET.

Finally, run the following (and add them to your .emacs):

(package-initialize)
(elpy-enable)

Changes in 1.6.0

  • When point is on a line with a flymake error, Elpy will now show the error in the echo area.
  • The movement commands (C-<cursor>) have been reworked again. Going left and right will now move by indentation levels left of the current indentation, i.e. jump four spaces, and by words right of the current indentation. Going up and down will go to the previous or next line with the indentation level point is at, not the indentation the line has. Try it, it's more difficult to explain than to use.
  • Completion results are now sorted more sensibly, with single-underscore symbols at the end, and double-underscore symbols after normal symbols, but before single-underscore ones.
  • M-x elpy-config will now point out if there are newer versions available for packages used by Elpy.
  • M-x elpy-config will now warn if ~/.local/bin is not in PATH while there is no virtualenv active.
  • The M-x elpy-version command is back by popular demand.
  • RPC buffers used by Elpy are now hidden by default, having a space at the beginning of the name.
  • When the Rope library throws an error, Elpy will now also attempt to provide reproduction steps. This used to only happen for Jedi.
  • Various bug fixes.
-1:-- Elpy 1.6.0 released (Post Jorgen Schäfer (noreply@blogger.com))--L0--C0--October 31, 2014 04:56 PM

Mathias Dahl: Cake. Can have. Eat too.

A while ago, a friend of mine shared this informative article about why Atom (a new text editor by the Github team, it seems) cannot replace Vim. The author talks about the very useful composability property of Vi(m) and ends his article with this (do read the complete article though, especially if you are quite new to Vi(m)):
A new, shiny, modern editor could one-up Vim by fixing some (or hopefully all) of these issues. But before an editor can replace Vim, it needs to learn everything that 1976 has to teach — not just the lesson of Emacs, but also the lesson of vi.
Well, it might not be very "shiny", and "modern" is, I guess, very subjective, but there is already an editor that both have awesome extensibility and, optionally, strict modal behaviour with a "command" mode.

Which editor it is? Emacs, of course. Just fire up viper-mode, or pick one of the more modern Vi(m) emulation packages like Evil (here is a list of different emulation modes for Emacs) and you can now have your cake and eat it too.

Mmm. Cake.

-1:-- Cake. Can have. Eat too. (Post Mathias Dahl (noreply@blogger.com))--L0--C0--October 28, 2014 09:38 PM

Mathias Dahl: Keyboard activated favorites menu using "simple menu items"

Some time back I wanted to create a keyboard activated menu with one-key access to some favorite commands that I did not want to give one-key bindings in the global keymap and for which I do not want to type the names on the M-x prompt. I was going to write my own command to read the key for the favorite command. However, it turns out Emacs already had more or less what I wanted in the form of simple menu items.

I chose to use the "apps" key (on keyboards with two Windows keys, it's the key to the right of the right Windows key, with a little menu symbol on it) since I did not use that for anything in Emacs.

Here is how to try this little hack out (FYI the key/command combinations below are just examples and not the actual keys and commands I wanted to use):

(defvar my-favorties-map (make-sparse-keymap "Favorites"))

(define-key global-map (kbd "<apps>") my-favorties-map)

(define-key my-favorties-map (kbd "f") 
  (cons "Find file"
        'find-file))

(define-key my-favorties-map (kbd "s")
  (cons "Save current buffer"
        'save-buffer))

(define-key my-favorties-map (kbd "i")
  (cons "Kill buffer"
        'kill-buffer))

After evaluating the above, when typing the "apps" key, the following "menu" will be displayed in the echo minibuffer:

 Favorites: i = Kill buffer, Save current buffer, Find file

It does what I want, although it is a little bit peculiar in how it decides for what bindings it will show X = Command for, and not. Seems that if the name of the menu item/command begins with the same letter/key that is bound to the command, it will not show it.

So, there it is, an instant little text based menu for executing favorite commands.

Enjoy!

-1:-- Keyboard activated favorites menu using "simple menu items" (Post Mathias Dahl (noreply@blogger.com))--L0--C0--October 28, 2014 09:36 PM

Got Emacs?: Update your package search url as melpa.milkbox.net is now melpa.org

It's been a couple of days but the url has changed to melpa.org. You may need to change your .emacs file  from ("melpa" . "http://melpa.milkbox.net/packages/") to ("melpa" . "http://melpa.org/packages/")
-1:-- Update your package search url as melpa.milkbox.net is now melpa.org (Post sivaram (noreply@blogger.com))--L0--C0--October 26, 2014 02:09 AM

Sebastian Wiesner: Flycheck 0.21 released

I’ve just released Flycheck 0.21, the result of two months of work. It’s already on MELPA and Marmalade, so take a look at the release annoucement and the changelog, and update Flycheck with M-x list-packages RET U x.

Enjoy the new release, and many many thanks for your support!

-1:-- Flycheck 0.21 released (Post)--L0--C0--October 26, 2014 12:00 AM

Got Emacs?: Emacs 24.4 released

Well, here's the official release mail on Emacs 24.4.  The Windows versions aren't out yet but will turn up in a few days.
-1:-- Emacs 24.4 released (Post sivaram (noreply@blogger.com))--L0--C0--October 21, 2014 03:18 AM

Mickey Petersen: Four year anniversary and new website

Welcome to the new Mastering Emacs website. After four years (yes, four!) it’s time for a site refresh. The old site was never meant to last that long; it was a temporary theme hastily picked so I could start writing about Emacs. Back then there were fewer blogs and Emacs resources. We didn’t even have a package manager.

The old site did serve its purpose as a launchpad for my blogging adventures. But Apache/WordPress is slow out of the box, even with SuperCache. A slight breeze and the thing would fall over — and it did, every time it featured on HackerNews or high-traffic subreddits.

Eventually I moved to FastCGI and nginx to host WordPress, but as it’s not officially supported it was a major pain to get working. António P. P. Almeida’s wordpress-nginx made my life so much easier and the site so much faster.

Alas, it’s time to retire the old site. Over the years I came to a number of conclusions:

People don’t use tags I spent a good amount of time adding tags to every article I wrote, but almost no one ever really used them. Sure people did click on them, but overall the reading guide proved far more useful. My goal is to re-implement a “tag”-like system but around concepts (Shells, Dired, etc.) instead of tags.

Not enough categories I had categories like “For Beginners”, “Tutorials”, and so on. They worked OK, but I am of the opinion now that manually curating my content makes more sense. Automatic content generation’s fine but throwing articles into a two or three baskets is never good enough.

Spammers are getting smarter I had to ditch Akismet, a free anti-spam checker for WordPress, after several years of near-perfect operation. The spammers simply mimicked humans too much and the filter would trip up on real content. I eventually switched to manual approval but that’s a lot of work.

Encourage visitors to read other articles A lot of visitors would leave after reading a single article, even though I would often have several related articles. I tried some of the “Suggested Content” plugins but they were universally terrible — another mark against content automation.

Apache is a memory hog Yes, yes. I am sure you can tame Apache and make it into a lithe and agile webserver but my best efforts failed me. The second I switched to nginx the memory and CPU usage dropped like a rock. Not to mention that nginx is much easier to configure.

So what about the new site then? Well it’s custom written for the job, though I may one day open source the blog engine. I launched it Tuesday the 14th of October, and immediately my site got slammed by reddit, Twitter and Hackernews on the announcement of Emacs 24.4. Talk about baptism by fire! The site held up just fine though.

The stack is Python and Flask running PostgreSQL with nginx as a reverse proxy and uWSGI as the application server, and with memcached for page caching. It took about three weeks of casual coding to write it, including the harrowing experience of having to convert the old blog articles — but more on that in a bit.

I opted for Memcached over Redis as my needs were simple, and because nginx ships with memcached support meaning nginx could short-circuit the trip to my upstream application server should the need ever arise. For now it just goes to uWSGI which checks the cache and returns the cached copy. That’s actually more than quick enough to survive HackerNews, the most high-traffic site visits I’ve gotten.

The slowness comes from page generation and not querying the database (databases are fast, Python is not) so that’s where memcached comes in. I thought about using nginx’s own proxy cache mechanism but invalidating the cache when you add a new comment or when I edit a page is messy.

Converting the blog articles proved a greater challenge than you might think. First of all, I like reStructuredText so I wanted to write and edit my articles in rST and convert them automatically to HTML when I publish them.

Enter Pandoc, which is a fine tool for the job. But there’s a snag. The original WordPress format is pseudo-HTML, meaning blank lines signify new paragraphs. Converting that without spending too much time with a hand-rolled, one-off state machine to convert to “real HTML” (for Pandoc to convert to rST) involved some compromises and hand editing. (And no, wrapping text blocks in paragraph tags is not enough when you have <pre> tags with newlines and other tag flotsam.)

So that was painful.

Coming up with a new design proved a fun challenge as well. CSS has come a long way in four years and things like text-justified automatic hyphenation work great (unless you’re on Chrome, in which case it’s the dark ages for you) on both Firefox and IE. Drop caps, ligatures, kerning and old-style numerals also work well and is possible in CSS alone. I’m surprised how good HTML/CSS is at typesetting nowadays. The font is Cardo, an open source font inspired by Monotype’s Bembo, a font itself inspired by Aldus Manutius’ from the 1500s, which I originally wanted to use but it’s way, way, WAY too expensive for web font use. If you’re a Chrome user on Windows the font will look weird as Chrome does not see fit to grace your eyes with aliasing. Again, both Firefox and IE render properly.

I opted for larger font sizes than normal in the belief that: it’s not the 1990s any more, and big font sizes mean people won’t have to zoom in or squint their eyes. Or at least that’s what I always end up doing, and my vision’s perfectly fine. Apparently doing that was a mistake: the amount of vitriol I received from certain quarters of the internet for having large font sizes was… perplexing to say the least.

So I made the fonts smaller.

The site’s still undergoing changes and I plan on adding to it over time. I am particularly keen on getting people to explore my site and learn more about Emacs.

Here’s to another four years.

Mickey.

-1:-- Four year anniversary and new website (Post)--L0--C0--October 20, 2014 10:41 AM

Flickr tag 'emacs': スクリーンショット 2014-10-18 17.01.34

zatsu posted a photo:

スクリーンショット 2014-10-18 17.01.34

Emacs 25.0 on OS X 10.10 Yosemite

-1:-- スクリーンショット 2014-10-18 17.01.34 (Post zatsu (nobody@flickr.com))--L0--C0--October 18, 2014 08:02 AM

Phil Hagelberg: in which preconceptions are unavoidable

In my last post I introduced my latest project, a HyperCard clone I've been writing in the Racket programming language, which is a practical and accessible dialect of Scheme. I'd played around a bit with Racket before, but this was the first time I'd used it for anything nontrivial. Any time you come to an unfamiliar language, there's naturally a period of disorientation in which it can be frustrating to find your footing. Racket's similarity to Clojure (the language I'm currently most proficient in) means this shouldn't be as pronounced as it would be with many languages, but these are my subjective reactions to how it's gone implementing my first project. There are a number of gripes, but if I may offer a spoiler, in the end Racket provides satisfactory ways of addressing all of them that aren't obvious up-front, and brings valuable new perspectives to the table.


When I was getting started with Racket, I was pleased to see that it defaults to immutable data structures. Coming from a Clojure background, I'm used to using free-form maps for everything. Racket has hash tables which sound similar, so let's take a look at how they're used:

(define h #hash(('a . 123)
                ('b . 234)
                ('c . (+ 345 456))))

(h 'b)
; application: not a procedure;
;  expected a procedure that can be applied to arguments
;   given: '#hash((a . 123) (b . 234) (c . (+ 345 456)))
;   arguments...:
;    'b

What's going on here? Well, it looks like hash tables can't be called like functions. This has never made any sense to me, since immutable hash tables are actually more like mathematical functions than lambdas are. But whatever, we'll just use hash-ref instead; it's more verbose but should get the job done:

(hash-ref h 'b)

; hash-ref: no value found for key
;   key: 'b

It turns out Racket implicitly quotes everything inside the hash table. So OK, maybe that's a little nicer since you don't need to quote the symbol keys in the hash table:

(define h #hash((a . 123)
                (b . 234)
                (c . (+ 345 456))))

(hash-ref h 'b) ; -> 234
(hash-ref h 'c) ; -> '(+ 345 456)

Oh dear... that's less than ideal, especially compared to Clojure's simple (def h {:a 123 :b 234 :c (+ 345 456)} and (:c h) notation. But let's move on[1] since it turns out hash tables are not nearly as important as maps are in Clojure. It's more idiomatic to use structs if your fields are known up-front:

(struct abc (a b c))
(define s (abc 123 234 (+ 345 456)))

(abc-c s) ; -> 801
s ; -> #<abc>

So that's nice in that it avoids the implicit quoting; our regular evaluation rules work at least. But what's this at the end? Racket structs default to being opaque. This may have made sense years ago when you needed to protect your mutable fields, but now that immutability is the default, it just gets in the way. Luckily you can set the #:transparent option when defining structs, and this will likely become the default in the future.

One place where Racket has a clear advantage over Clojure is that you'll never get nil back from an accessor. Both in hash tables and structs, if a field doesn't exist, you'll get an error immediately rather than allowing bogus data to percolate through your call chain and blow up in an unrelated place. (Though of course with hash tables you can specify your own value for the "not found" case.) In any case, less "garbage in, garbage out" is a welcome change for me as a human who frequently makes mistakes.

What about updates, though? Mutable struct fields have setter functions auto-generated, but inexplicably the nondestructive equivalents for immutable fields are missing. Instead the struct-copy macro is recommended. Here we change the b field of an abc struct instance we've defined:

(define s2 (struct-copy abc s [b 987]))
(abc-b s2) ; -> 987

This works, though you have to repeat the struct type in the invocation. That's not so bad, but the bigger problem is that this is a macro. The field you wish to update must be known at compile time, which makes it awkward to use in the context of higher order functions.

At this point the post is surely sounding pretty whiny. While the out-of-the-box experience working with these data structures is not great, Racket gives you plenty of power to make things better. Probably the most comprehensive take on this I've seen is Rackjure, which gives you a lot of the creature comforts I've noted as missing above like nicer hash table syntax and data structures you can call like functions, as well as a few other niceties like a general-purpose equality predicate[2] and atomic swap for boxes.

In my initial exploration of Racket, I resisted the temptation to dive straight into Rackjure in order to give "raw Racket" a fair shakedown. Because of this, I've spent more time looking into structs and some of the options they provide. Racket has the notion of interfaces you can conform to in order to get generic functionality specialized to a certain struct type. Dictionaries are one of the interfaces it ships with out of the box, so you can use dict-ref, dict-set, etc with hash-tables and other built-in types that conform to this interface. Your typical structs won't work with it, but you can declare structs that implement it without too much fuss. I've done this with my fstruct macro:

(fstruct fabc (a b c)) ; define a struct type with three fields
(define fs (fabc 123 234 (+ 345 456)))

(dict-ref fs 'a) ; -> 123
(dict-set fs 'b 999) ; -> (fabc 123 234 801)
(dict-update fs 'c (λ (x) (- x 400))) ; -> (fabc 123 234 401)

One gotcha if you're used to Clojure is that dict-update is not variadic—if you provide a fourth argument it will be used as a "not found" value rather than as an argument to the updater function. (dict-update fs 'c - 400) won't work. However, unlike Clojure, Racket can do reverse partial application, so (rcurry - 400) does the job, which is nicer than spelling out the lambda form fully.

Another gotcha is that dict-update doesn't appear to have a nested equivalent. For instance; it would be nice to be able to pass an updater function and a "key path" to a specific value in a tree of dictionaries:

(define inner (fabc '(a b c) 0 0))
(define ht-nest `#hash((key1 . ,inner)
                       (key2 . #f)))
(define outer (fabc 0 ht-nest '(1 2 3)))

(define updated (dict-update-in outer '(b key1 a) append '(d e f)))

(dict-ref-in updated '(b key1 a)) ; -> '(a b c d e f)

So that is easy to add:

(define (dict-update-in d ks f . args)
  (if (empty? (rest ks))
      (dict-update d (first ks) (λ (x) (apply f x args)))
      (dict-set d (first ks) (apply dict-update-in
                                    (dict-ref d (first ks))
                                    (rest ks) f args))))

(define (dict-ref-in d ks)
  (if (empty? (rest ks))
      (dict-ref d (first ks))
      (dict-ref-in (dict-ref d (first ks)) (rest ks))))

The fstruct macro has one more trick up its sleeve. The structs it generates are applicable just like Clojure maps:

(define fs2 (fabc 123 (fabc 234 345 (fabc 987 654 321)) 0))

(fs2 'a) ; -> 123
(fs2 '(b b)) ; -> 345
(fs2 'c 9) ; -> (fabc 123 (fabc 234 345 (fabc 987 654 321)) 9)
(fs2 '(b c a) 0) ; -> (fabc 123 (fabc 234 345 (fabc 0 654 321)) 0)
(dict-update-in fs2 '(b b) + 555)
; -> (fabc 123 (fabc 234 900 (fabc 987 654 321)) 0)

They support nested lookups and setting out of the box, but of course for expressing updates that are a function of the old value to the new value you'll have to use dict-update or dict-update-in. My primary project at the moment has a deeply-nested state fstruct that contains hash-tables which contain fstructs, so being able to use a single dict-update-in which operates across multiple concrete types is very convenient.

Finally, while I prefer pure functions for as much of the logic as I can, the outer layer requires tracking state and changes to it. Racket provides the box type for this, which is equivalent to the atom of Clojure. Unfortunately while it provides the same compare-and-swap atomicity guarantees, it only exposes this via the low-level box-cas! function. Oh well, functional swap! which operates in terms of the old value is easy to implement on our own or steal from Rackjure:

(define (swap! box f . args)
  (let [(old (unbox box))]
    (or (box-cas! box old (apply f old args))
        (apply swap! box f args))))

(define b (box 56))

(box-cas! b 56 92) ; -> b now contains 92

(swap! b + 75) ; -> b now contains 167

The HyperCard clone I wrote about in my last post consists of a number of modes that define handlers that can update the state based on clicks. The handlers are all functions that take and return a state fstruct and are called via the swap! function. This allows the bulk of the code to be written in a pure fashion while keeping state change constrained to only two outer-layer mouse and key handler functions. The actual box containing the state never leaves the main module.

Racket has top-notch support for contracts that can describe the shape of data. In this case rather than attaching contracts to functions scattered all over the codebase, I attach them only to the box that contains the state struct, and any time there's a type bug it's usually immediately apparent what caused the trouble. For instance, I have a contract that states that the "corners" field of each button must be a list of four natural numbers, but I've made a change which causes one of them to be negative:

now: broke its contract
   promised: natural-number/c
   produced: -23
   in: the 3rd element of
       the corners field of
       an element of
       the buttons field of
       the values of
       the cards field of
       the stack field of
       the content of
       (box/c (struct/dc state
                         (card string?)
                         (stack (struct/dc stack ...))))

It's pretty clear here that I've made a miscalculation in the button coordinates. If you use DrRacket, the IDE that ships with Racket, you get a very slick visual trace leading you directly to the point at which the contract was violated. While it would be possible to gain more certainty about correctness at compile time by using Typed Racket, contracts let me define the shape of the data in a single place rather than annotating every function that handles state.

While I'd certainly be happy if Racket accomodated some of these functional programming idioms in a more streamlined way out of the box, it speaks volumes that I was able to make myself quite comfortable on my own only a week or two after beginning with the language[3]. It's interesting to note that all of the places in which Clojure has the edge[4] over Racket (with the conspicuous exception of equality) lie around succinctness and greater expressivity, while Racket's advantages are all around improved correctness and making mistakes easier to prevent and detect.


[1] It's possible to perform evaluation inside hash literal syntax by using backticks: `#hash((a . ,(+ 5 6 7)) does what you expect. It's better than nothing, but that's a lot of noise to express a simple concept. In practice, you don't really use the literal notation in programs; you just call the hash function.

[2] I've blogged about why egal is such a great equality predicate. Racket ships with a bewildering array of equality functions, but in functional code you really only need this one (sadly absent from the core language) for 98% of what you do.

[3] With one exception: Racket's macro system is rather intimidating coming from Clojure. Its additional complexity allows it to support some neat things, but so far I haven't gotten to the point where I'd understand why I'd want to do those kinds of things. In any case, I got help from Greg Hendershott to turn the fstruct macro into something properly hygenic.

[4] This ignores the advantages conferred by the respective implementations—Clojure has significantly better performance and access to libraries, while Racket's compiler/debugger/editor tools are much more polished, and its resource consumption is dramatically lower.

-1:-- in which preconceptions are unavoidable (Post Phil Hagelberg)--L0--C0--October 13, 2014 08:50 PM

肉山博客: Gnus:用 GPG 加密邮件

这周四(2014-10-09)在公司同事 Jack 的帮助下,成功地用 Gnus 发送了加密邮件。

1 流程

Gnus 自带对 GPG 的支持,所以一旦 Gnus 配置成功(见 2.2 ),给邮件加密很容易:

  • C-x m (compose-mail),开一封新邮件
  • C-c C-m C-e (mml-secure-message-sign-encrypt)

    这会在邮件开始处添加一个标签:

    <#secure method=pgpmime mode=signencrypt>
    

    解释一下 mode=signencrypt

    • sign :用发送者(你)的私钥签名,所以接收者知道邮件确实是你发的
    • encrypt :用接受者的公钥加密,所以邮件只有接受者能解密
  • 写完邮件, C-c C-c (message-send-and-exit) 发送

2 配置

2.1 用 GPG 生成公钥私钥,加载其他人的公钥

不赘述了,直接看 manual 就行,或着搜索相关教程。

2.2 配置 Gnus

我没有自己的邮件服务器,用的是谷歌的 Gmail。

Gnus 配置则基本是跟着陈斌兄的 Practical guide to use Gnus with Gmail 来的,简单实用。

3 我的公钥

http://wenshanren.org/wp-content/uploads/2014/05/wpid-PGP-wenshan2.asc

–—BEGIN PGP PUBLIC KEY BLOCK–—
Version: GnuPG v1

mQENBFNlPGEBCADALGQlcpOfWCKvaasalZWH+WZnY7LFBw4qaUbMHZtuh+3uyKm7
VadfPjcbKtko0pa7inY0CYPQ9oHaSZ0trimXdiMgf5693tmb733MZt72fc9sE7Xy
Iyq9v0QCEUwZsUFkac8qcWaZxIvx99/lro4NCStE/DCmM4BjpNanWcZMS2LDGGcT
mV35Qhl/0WT5JVZBM600iqbN8nsFPBdeu1t6F5/tFPf9QQXa9d3NLVc2gtCbYATi
7l4/2+EyTxHFYBxZfjHj5fViKlQyeDQBrg5hFh6jp0Zq+Hk4Kp6J1sRcgYecD8oq
gHI/wKELYs5XCrUdYv9DNxvwvZD3PeW8EjOFABEBAAG0LeS7u+aWh+WxsSAoUmVu
IFdlbnNoYW4pIDxyZW53czE5OTBAZ21haWwuY29tPokBNwQTAQIAIgUCU2U8YQIb
AwYLCQgHAwIGFQgCCQoLBBYCAwECHgECF4AACgkQnHGj7EtW25xOVAf1GDvgkaG4
ryNQE5qKwIdq7dMh7U+JLhLq+KHTiPuOyC5Plw98ik7zd+bhLJLaKWE3rhKwRXCY
ZJJcUYsARUG1TnRHBRRpHvL4rIPaQZK09wmomAV9/Qs4G1O3FSQUtMlgLeZwKMO4
zCV52odYqqZnM1+NuHDgkvCtd2Fe4sIQsYfRh+nnFqKTXFSfNKZvhuOnIyPuM6pc
1K7evjrfxfjPpc4L4Eh7EyeOK+1r9zUewk5Cr/ddJ40JqNganitatsEZaN5pteZt
pfEhxY0nztdgFfQE/u9tZzJC2z3DifjioWoG3epPOJucZ6YPHhUmEeGbZ+ESgmik
G5Nq+uyRCnotuQENBFNlPGEBCAD0bfWvErG4oThJ+GhW86eGFKGeAP4jUhugzO77
nuk3sbeImaOcNqn1nJANJ4iWeqImcKPPRN07FHFFbW4O63oZmrGDRq9vpwQyKogT
LDBpOZ7Sgu9qmTAI1ij2lpZK1U4dI+91XhvajzboTzWurTqe3jdGS41n9jq2jE2K
D9CG4Hf3ckpWYDXoWC2wAC1qYXhbX2u57pJIhUdfubAEkJnFJ73+B9nskSUG9pAh
eiBSyK1wPJWqgIZRmW5k9fBVJxwC520+ymU68jHK06I3U+/4gOogzMLVRjI14qdu
JSl47+jk2+O2kwqTKz6CaJ/Q+4Wu1XACVOGJz80KoQvlN/FTABEBAAGJAR8EGAEC
AAkFAlNlPGECGwwACgkQnHGj7EtW25zrnwgAuROa8bE/NTUmJ0wLrTJ5ZLgUqNC1
okVCcraQ4ce2rg0YxSoLvFLxYM/ZiVPUT2HLcm08z9yMqGLZLxo9FUJGJoUzN+JN
pE1Uo19lsUcjl1sGvHCZ20SnxY8dDdowLJTIyDvo/haiw35WBIfV1CL5yjt/KiM7
hI8VTJJasR1Z/+5XKOqxxJ/TdweZmOf7UkYDtuTCjp4+2M2gUQqsBPAVJOPyZgFF
ow3rxpQeDzH/Twx500q6hfcKEJKw0/v2rk+zhFPB1j98xRZ97eUw6hdt3g7JOSEl
g5WINq3Piv9KI61pjUedutg1Z7Nexil8vRP3Kir7W3BR98kLLKEpnAnT2Q==
=gPpa
–—END PGP PUBLIC KEY BLOCK–—

-1:-- Gnus:用 GPG 加密邮件 (Post Wenshan)--L0--C0--October 12, 2014 12:59 PM