Some of these exist, and all are possible without threads.

Non-blocking save on network drives; Non-blocking autosave

This requires a memcpy and the aio_* functions. When a save is requested, you make a copy of the buffer in memory (so that what ends up on disk is what the buffer looked like exactly when the save was requested), then you stream this data to disk with aio_write (perhaps making the write atomic by doing a synchronous rename after all the data is on disk). This would probably take no more than a few hours to implement, and most of the complexity is simple to handle with atomic writes and aio_cancel. I think the biggest problem is handling the "userspace" semantics; after-save hooks expect to run after the data is on disk but before the user has changed the buffer in any way. What do you do about this?

(I've done this before. I have an Emacs mode at work that saves to a special centralized database in addition to the local disk at every modification. We just queue the write in before-save hook and tell some other process to read the data from a temp file that we create. It works perfectly, even on Windows!)

Rebuilding tag tables in the background

This is easy and eproject already does it. You run etags in a background process and when it's done, point Emacs at the new tags tables. Since the tags tables don't do anything until a lookup is requested, this is completely asynchronous.

Try it today:

https://github.com/jrockway/eproject/blob/master/contrib/epr...

Loading and fontifying large files in the background (i.e. concurrent fontification, not just jit-lock)

This you can't do unless you can guarantee that matchers are bounded and generate correct results no matter what the boundaries are. I don't know of any programming mode that could be made to meet this invariant easily; consider the case:

/* this code is bad:
int i = 0; */

If we had two threads fontifying this block, and the bounds were set to thread 1 = line 1, thread 2 = line 2, the results are going to be wrong. The first line will be treated as a comment and the second line will look like a normal variable declaration because getting the correct syntax information requires analyzing the entire first line. Any language with multiline constructs (string literals, preprocessor directives, comments, etc.) will have this problem, thus making parallelization Not Easy. If font-locking is slow, profile it and fix the algorithm, but don't expect speedups for free. Parsing programs that are invalid (as most are while being typed; you type characters, not tokens) and guessing what the user "means" is hard.

Concurrent url fetching and downloads (e.g. updating el-get without blocking).

Fork curl or wget. Display the result when done. Or, implement HTTP from scratch; network IO is already nonblocking.

Concurrent spellcheck

This is already implemented this way; a pipe is opened to aspell and words are piped to aspell as necessary. If parsing the results is too expensive and you don't care about interactivity, wait for bigger batches of data back from aspell. All IO to other processes is asynchronous and can be made synchronous with special calls like accept-process-output.

Fast scrolling in large buffers (especially complex XML files opened in nxml-mode)

How will threads solve this problem?