“The hardest bug I ever debugged in my life was a concurrency bug; the second hardest wasn’t even close (and thankfully, I didn’t try to solve it at the same time).” — John Wiegley, Emacs maintainer, on Emacs Lisp’s future, 09 October 2016
-1:-- Concurrency (Post William Denton)--L0--C0--October 12, 2016 01:03 AM
Charles-H. Schulz is not a developeralthough he is technically proficient. He describes himself as specializing in literature, history and philosophy. He's also an Emacs user. I find that interesting because I'm always fascinated with how people who aren't writing code use Emacs and how they took the unlikely step of getting started.
Schulz has a post in which he describes how he uses Emacs. It's easy to see him as a power user because he performs many" class="wp-smiley" style="height: 1em; max-height: 1em;" />or even most" class="wp-smiley" style="height: 1em; max-height: 1em;" />of his daily tasks in Emacs. That includes mu4e for email, blogging, IRC, file management, terminal, and, of course, Org mode. Like most of us he prefers to browse with a dedicated browser rather than, say, eww, and he doesn't like the available Emacs packages for RSS or Twitter. Still, he does an impressive number of his daily chores from within Emacs.
If this sort of thing interests you too, head on over to and take a look at his write-up.
Four Saturdays ago, on September 17, Emacs 25 was finally released. Almost two
years before that, I wrote a post predicting a few Big things to expect from
Emacs 25. Throughout the months since then, I’ve also been reporting interesting
new features as they arrived on the dev builds. Today, we compile a list of all
of those news posts, and review which predictions I actually got right.
News posts
For the convenience of those looking for actually practical information, I feel
we should start with a list of the posts. I must strive to be clear that this
is not a comprehensive list of new features. Not by a mile! If you want
everything, you can have a look at the news file that ships with Emacs,
/etc/NEWS, or you can read Mickey Petersen’s commented version.
The list below merely sums up most (not even all) of the features that piqued
my interest over the last couple of years.
If you’re short on time, I personally recommend checking out char-folding
search (1), archive priorities (17), and the comment-line command (4), which are all
features you might not realize are there. The round-quotes in Help buffers (2) and
the improved query-replace history (3) are also among my favorites, but you don’t
need to do anything special to see them in action.
Reviewing predictions
Now, for the indulgence of those looking for more than just practical
information. On the aforementioned post, I talked about 6 things I hoped to see
by the time Emacs 25 came out.
Moving the code base to git
This one even had a schedule date when I wrote
the post, so it obviously doesn’t count as a prediction. Still, I’m
extremely glad it happened as I would never have contributed myself if not
for this change.
Dynamic library loading
Now this is exciting. I originally wrote it was
“looking almost in shape for release”, but I have no idea what led me to
say that. This feature actually almost didn’t make it into release. It only
got merged to the emacs-25 branch more than one year later, after the
feature-freeze took place!
Nonetheless, it’s finally out and about, and I’m eager to see what comes
out of it. If you’re interested, it’s actually very easy to get started
(well… easy by C-coding standards). Aurélien Aptel has a super short
tutorial on how to write, compile, and use a dynamic module in Emacs.
Concurrency in Elisp
I’ll count this as a half point. We don’t have proper
concurrency in Elisp yet, and whether that’s something we want is still an
ongoing discussion. Still, most of the points in my rant have already been
addressed. The packages list does refresh asynchronously now (despite the
lack of concurrency), and several optimizations have been made which speed
up the actual rendering of the list.
A Better Package Menu
I shouldn’t have to say much here. The last 5 links on
list above are all improvements to the package menu. While there’s still
room for improvement, it’s quite ahead of where it was 2 years ago. Better
dependency management, asynchronous refreshing, and more filtering options
were all much needed improvements. Meanwhile, archive priorities are a nice
cherry to top of it all off.
A More Robust Customize Interface
Out of the two issues that led me to
write this point, one of them has been fixed (custom-theme-load-path is no
longer a defcustom). Still, I’m counting this as a miss. Over the last
couple of years I’ve seen other fundamental issues with the Customize
interface be reported, and there’s still quite a bit of work to be done here.
Namespaces
Well, OK. We still don’t have namespaces. Honestly, though, it
doesn’t bother me anymore. I’ve released two packages, Names and Nameless,
which are available on Elpa and help mitigate the the lack of namespaces. I
use Nameless for all my Elisp coding now and that’s the end of the story
for me.
Summarizing, even if we exclude the Git point (which wasn’t really a
prediction), it’s a 2½ out of 5 (or 3½ if we count namespaces). That’s a
pretty good outcome considering I had never even made a single contribution to
Emacs core when I wrote that post. I’d love to write another one of those, but
I’m not nearly as involved in the news as I was 2 years ago. Maybe in a couple
of months I’ll manage to catch up.
This is a really simple tip, but it saves a lot of dull work. In AUCTeX, you can mark some text and press C-c C-f C-e to put an \emph around it. Type C-c C-f C-h to see other options, divided into text and math modes. But wait, there’s more!
I recently needed to transpose a table in org-mode and spent a few minutes trying to come up with a keyboard macro to do it before it occurred to me that there might be a command to do this already. And of course there was: M-x org-table-transpose-table-at-point. Here it is in action:
It’s great when there’s a command that does exactly what you want!
The other day I wrote about undo-tree and wished for a video on how to use it. Mike Zamansky came to the rescue with a very nice video expanation of undo-tree. Really, this package is extraordinarily useful and it's nice to have an easy way to get started.
For me, at least, seeing the video helped illuminate some of the dark corners. Others, I know, would rather read an explanation and for them the nice commentary that I mentioned in the original blog post is the place to go. If you like to see things actually happening, you should definitely take a look at Zamansky's video. It's the 16th in a series of useful Emacs tutorials that he's done. They're all worth watching so take a look when you get a chance.
One interesting thing that Zamansky mentioned that I hadn't considered is that you really don't need redoalthough that is much improved with undo-treebecause you can simply use undo-tree-visualize (bound to Ctrl+xu) to move down the undo tree to redo as much as you like. That's a subtle but very useful point.
My advice is to watch Zamansky's video and then read the commentary (or vice versa if that makes more sense for you) and you should be able to start using undo-tree efficiently. It's definitely a package you want.
Does this image look familiar? I always found Emacs’ tendency to stuck buffer
text on the far left of a window quite annoying, particularly on large screens
where it doesn’t just look ugly but also forces you to keep your head twisted to
the left in order to follow the buffer text.
Luckily Visual Fill Column Mode comes to the rescue. The purpose of this
mode is actually to make buffer text wrap on the fill-column even in buffers
that don’t use hard wrapping and typically have Visual Line Mode active—hence
the name of this mode. By default it inherits Emacs’ left-wing tendency—which
I’d absolutely agree, politically, but it just doesn’t make for a nice UI.
However there’s a tiny flag that makes Visual Fill Column Mode center text. My
use package configuration looks as follows1:
(use-packagevisual-fill-column:ensuret:defert:bind(("C-c t v".visual-fill-column-mode)):init(dolist(hook'(visual-line-mode-hookprog-mode-hooktext-mode-hook))(add-hookhook#'visual-fill-column-mode)):config(setq-defaultvisual-fill-column-center-texttvisual-fill-column-fringes-outside-marginsnil))
The key is visual-fill-column-center-text which does, well, exactly what the
name says and beautifully centers buffer text:
visual-fill-column-fringes-outside-margins in turn moves the fringes to the
window borders far from the text. By default the option is on, keeping helpful
icons from Flycheck or diff-hl far away from the actual text, but I’d
like information close with the actual text.
Of course, as with many things UI-related in Emacs, the
implementation is a dirty hack: It extends the window margins to cover
the empty area of the buffer. As hacks are hacks there are a couple of issues;
for instance text scale adjustments go unnoticed at first: Visual Fill Column
has no chance to intercept text-scale-adjust or similar functions to recompute
the margins so the alignment will be somewhat off after changing the text scale
until the next redisplay.
But generally Visual Fill Column Mode works perfect, and is now the default for
all buffers in my Emacs, even if they don’t use visual-line-mode.
By the way, Visual Fill is a by-product of Writeroom Mode which is a very
nice mode for distracting-free writing where the whole UI of the buffer is
reduced, even more than Emacs’ normal UI. Take a look at it, too, if you like
the idea.
Note that in this form :defer t is technically redundant, because
:bind generally implies :defer t. I prefer an explicit :defer t
however, because I can never remember which forms imply :defer t. Also, a
decade of using Python code has really etched the Zen Of Python in my
mind— “Explicit is better than implicit”—so I always found the implicit
:defer t of use-package to be one of its less brilliant features. ↩
I’ve mentionedcrux before; it’s a package providing a set of general-purpose useful commands. One that I use all the time is crux-open-with, which opens the file currently being visited (or the file at the point in a dired buffer) using the system default application for that filetype. It works on Mac or Linux, by using the open or xdg-open commands respectively.
I bind the command to C-c o, using the following code (which also binds the previously mentionedcrux-move-beginning-of-line)
I still not fluent with Magit’s terminology and workflow. Probably because I’m not using git, in general, too often. When I do, and when I try to use Magit as the interface, I usually get confused by the wealth of options and switches, and resort to git in the terminal. Today I decided to give … Continue reading Magit – My Simple Workflow
My configuration results in an environment where you can only evaluate code within the document and never during export or tangling. That way it is easier to understand what happens when.
Code is only ever evaluated when you execute the document. The results of execution are stored within the document. That is my workflow.
Knitr in comparison does the opposite only evaluating code during export.
Here is the easiest way to make sense of what happens when resulting in what:
Key:
Columns
Activity: The actions that is being performed on the document
S : Source document modified?
T : Destination tangled-document modified?
W : Destination weaved-document modified?
C : Source-Block Evaluation occurred?
O : Org-Macro Expansion occurred?
Activity
S
T
W
C
O
Tangling
F
T
F
F
F
Evaluating
T
F
F
T
F
Weaving
F
F
T
F
T
Once you answer all of those questions you aren’t likely to have many surprises by your Org-Mode Literate Programming system.
I made a schoolboy error last week: I narrowed down a problem I was having with a program to one line and one setting … but then I didn’t read the documentation. It was Org mode in Emacs, and the variable was org-export-babel-evaluate. I set it to nil, and what happened wasn’t what I thought should happen, so I thought it was a bug, when actually it’s all set out in the docs. Lesson re-learned: RTFM.
Here’s what happened. At work I did a long report analyzing some aspects of the library’s presence in the university’s course management system. We made a box in Moodle that generates customized recommendations to students based on the course code: students see links to relevant research guides (for example poli sci students see a link to the poli sci research guide), to the course’s specific guide and/or reserves if they exist, and to the profile of the librarian who handles that subject. Turns out the links in the box don’t get many clickthroughs, but that’s something I’ll write up some other time.
A cat.
The thing is, doing the full analysis means looking at millions of lines of data from log files, then processing things in R and Ruby, generating charts, tables of numbers, the whole schmear. The way I have it set up, the Org file, which is full of source code blocks, can be fully reproducible research: when I export to PDF, every data file is read in and analyzed fresh, every table and chart are regenerated. That’s wonderful, and it’s one of the reasons I love Org—but it’s intensive, and it takes about five minutes to run on my personal machine, and usually crashes my slower work machine. (I asked for a new one.) And when I’m rewriting and editing and want to see how the changes look, I don’t need to regenerate all the data, I just want to turn what’s there into a PDF as is.
Because I didn’t want any of the code blocks evaluated, I set this in a file variable (it’s the first line in the Org file):
# -*- org-export-babel-evaluate: nil -*-
But when I exported the file to PDF, all of a sudden not only were the results of the code blocks in the PDF (as desired) but also the code that generated them. Instead of showing the results of a bit of Ruby, the Ruby was there too. Instead of just showing a chart, the R that made it was there too. Not what I wanted!
Another cat.
I spent about an hour narrowing this down and reported it as a possible bug to the Org mailing list. Very quickly Charles Berryreplied and gently corrected me, pointing me to the documentation (which I now notice contains a typo, which I’ll submit a real bug report for):
Switch controlling code evaluation during export.
When set to nil no code will be evaluated as part of the export
process and no header argumentss will be obeyed. When set to
‘inline-only’, only inline code blocks will be executed. Users
who wish to avoid evaluating code on export should use the header
argument ‘:eval never-export’.
It’s the “no header arguments will be obeyed” that was causing my trouble. I needed that “:eval never-export” thing, which isn’t managed like the org-export-babel-evaluate variable, but is a header argument, which I’d never used before (and had to search GitHub to find examples of). I put this near the start of the file and hit C-c C-c on the line to make Emacs know about it:
#+PROPERTY: header-args :eval never-export
Now when I export the file to PDF (C-c C-e l o) it just blasts the document as is into LaTeX and turns it into a PDF, no calculating done. For minor tweaks and copy editing, that’s just what I need. When I need to rerun some data analysis, I can remove the line to rerun everything fully and completely.
This is all a bit arcane, so I document this in the hopes it will save someone, perhaps just future me, a moment of trouble in some month or year to come.
So far I’ve used TextExpander for text snippets and, well, text expansion. One of my main uses-cases is character pairings. For example, when I type " I almost always enclose it with another ". But TextExpander is lacking in several ways: Performance – it takes a friction of a second for the expansion to happen, … Continue reading Electric Pair Mode In Emacs
In Emacs today, there’s no way to find all the callers of a function
or macro. Most Emacsers just grab their favourite text search tool.
Sadly, dumb text search knows nothing of syntax.
We can do better. It just wouldn’t be Emacs without a little fanatical
tool building. Let’s make this happen.
Parsing
Everyone know how to parse lisp, right? It’s just read.
It turns out that a homoiconic language is hard to parse when you want
to know where you found the code in the first place. In a language
with a separate AST, the AST type includes file positions. In
lisp, you just have… a list. No frills.
I briefly explored writing my own parser before coming to my
senses. Did you know the following is legal elisp?
;; Variables can start with numbers:(let((0x01));; And a backquote does not have to immediately precede the;; expression it's quoting:`;; foo(+,0x0))
Cripes.
Anyway, I totally ripped off was inspired by similar functionality
in el-search. read
moves point to the end of the expression read, and you can use
scan-sexps to find the beginning. Using this technique
recursively, you can find the position of every form in a file.
Analysing
OK, we’ve parsed our code, preserving positions. Which forms actually
look like function calls?
This requires a little thought. Here are some tricky examples:
;; Not references to `foo' as a function.(defunsome-func(foo))(lambda(foo))(let(foo))(let((foo)));; Calls to `foo'.(foo)(lambda(x)(foo))(let(x)(foo))(let((x(foo)))(foo))(funcall'foo);; Not necessarily a call, but definitely a reference to ;; the function `foo'.(a-func#'foo)
We can’t simply walk the list: (foo) may or may not be a function
call, depending on context. To model context, we build a ‘path’ that
describes the contextual position of the current form.
A path is just a list that shows the first element of all the
enclosing forms, plus our position within it. For example, given the
code (let (x) (bar) (setq x (foo))), we build a path ((setq . 2)
(let . 3)) when looking at the (foo).
This gives us enough context to recognise function calls in normal
code. “Aha!”, says the experienced lisper. “What about macros?”
Well, elisp-refs understands a few common macros. Most macros just
evaluate most of their arguments. This means we can just walk the
form and spot most function calls.
This isn’t perfect, but it works very well in practice. We also
provide an elisp-refs-symbol command that finds all references to a
symbol, regardless of its position in forms.
Performance
It turns out that Emacs has a ton of elisp. My current instance
has loaded three quarters of a million lines of code. Emacs actually
lazily loads files, so that’s only the functionality that I use!
So, uh, a little optimisation was needed. I wrote a benchmark script
and learnt how to make elisp fast.
Firstly, avoid doing work. elisp-refs needs to calculate form
positions, so users can jump to the file at the correct
location. However, if a form doesn’t contain any matches, we don’t
need to do this expensive calculation at all.
Secondly, find shortcuts. Emacs has a little-known variable
called read-with-symbol-positions. This variable reports all the
symbols read when parsing a form. If we’re looking for function calls
to some-func, and there’s no reference to the symbol some-func, we
can skip that form entirely.
Thirdly, use C functions. CS algorithms says that building a hash
map gives you fast lookup. In elisp-refs, we use assoc with small
alists, because C functions are fast and most lists weren’t big enough
to benefit from the O(1) lookup.
Fourthly, write impure functions. Elisp provides various ways to
preserve the state of the current buffer, particularly
save-excursion and with-current-buffer. This bookkeeping is
expensive, so elisp-refs just creates its own temporary buffers and
dirties them.
When all else fails, cheat. elisp-refs reports its progress, which
doesn’t make it faster, but it certainly feels like it.
Display
We have something that works, and we can search in all the code in in
the current Emacs instance in less than 10 seconds. How do we display
results?
first prototype, showing the matching forms in isolation
Initially, I just displayed each form in the results buffer. It turns
out that the context is useful, so added the rest of the matching lines
too. To avoid confusion, I underlined the section of the code that
matched the search.
second prototype, adding context and custom faces
The second prototype also had some custom faces for styling. This was
an improvement, but it forces all Emacs theme authors to add support
for the faces defined in our package.
It still didn’t work as well as I’d hoped. When I get stuck with UI,
I ask ‘what would magit do?’. I decided that magit would take
advantage of existing Emacs faces.
final UI, using normal syntax highlighting
The final version uses standard elisp highlighting, but highlights the
surrounding context as comments. This means it will match your
favourite colour scheme, and new users should find the UI familiar.
I added a few other flourishes too. You can see that results in the
second prototype were often very indented. The final version unindents
each result, to make the matches easier to read quickly.
Emacs has had suggesting keybindings for some time (according to git blame, about four years): if you M-x some command, and that command has a keybinding, it will show sth like You can run the command ‘find-file’ with C-x C-f for two seconds (by default). It is quite nice, non-intrusive and helpful. Emacs 25.1 took that to the next level.
Finally, Emacs 25.1 is released. The windows binaries would take some time to turn up. Hopefully the new TLS features would help in setting up mail connectivity easier to deal with.
-1:-- Emacs 25.1 released (Post sivaram (noreply@blogger.com))--L0--C0--September 18, 2016 02:32 AM
Today I decided to write a little bit of documentation for my most basic version of .emacs or init.el that I use. It gets me up to 80% or so of full productivity for basic text editing on a new installation.
At Affectv we use a wide range of editors: Sublime, Atom, Emacs, Pycharm, IntelliJ... Actually only two people use the same editor! As such, from time to time I see things in other people's editors that I would like to have as well. So, yesterday I decided to improve on some configuration settings on Spacemacs.
Click for multiple-cursors
I saw this on Jordi's Sublime, and it is much more comfortable than using more-like-this or similar helper functions, even if I need to use the trackpad to do so. After all, a multi-cursor edit (proper edit, not as a substitute for a macro) is rare enough that I can tolerate leaving the home row. Easy enough to configure thanks to Magnar Sveen.
Also from Sublime, I had this on my old emacs setup. As simple as adding minimap to the list of additional packages and configuring its property group. See animation below.
I have always loved how clean vim's folding works, and how Sublime has this nice folding. Then I found origami-mode and my emacs-life was complete. I tweaked a little the folding functions so that minimap was updated on fold (for some reason it is not, I guess minimap is tied to the "modified" hook or similar). I bound z and Z (and A-z which maps to æ in Colemak) to the basic fold operations.
For some reason just advising the functions with after didn't work, this is not great but does work. I left the Z bindings as they are, since I have not used them yet, and will probably delete them if I keep not using them.
Execution overlays in Ensime (Scala)
I saw this for Cider in the emacs church meeting from August, and heard @fommil (I think it was him) mention that it was coming to ensime. And indeed it was. And it's easy enough to use C-c C-v C-r (thing of it as extended command, eval, region to remember), given an open inferior Scala interpreter. Symbol prettify does not apply to overlays, so you need to customise the arrow used therein.
A Kanban board is a way to visualise your work and help you get more work done. You organise your work into tasks that need completeing and use the board to show the state of each card. Kanban encourages you to get work finished before starting new work.
The amazing Emacs Org-mode can be used to create a very fast and easy to use Kanban board that is with you where ever you are.
Update: Using Org-mode doesnt give me everything I want from a Kanban board, but it was an interesting exersice. For now, I am just sticking to my list view of a Kanban board.
Org-mode is built into Emacs / Spacemacs so there is no need to install any packages or layers for any of the following.
Designing a kanban board
The columns on your kanban board represent the state of work and represent your typical workflow. You can represent the states as the most generic todo, doing, done workflow, or anything more specific that adds value to how you manage work.
I have been using kanban for a while, so I am using a five stage workflow: planning, in progress, blocked, review, done
planning - work I’d like to do that needs organising so I can do it.
in progress - what I am currently working on. I try and keep this to a minimum so I get things done
blocked - things I’ve started working on but currently arent able to complete
review - work I have completed. Check if there are any follow on tasks or lessons learnt
done - things I have completed. Gives feeling of satisfaction
Create a new file by opening a new buffer M-x find-files and type in the new file name, ending in .org. Any files with a .org filename extension will automatically set the Emacs major mode to Org-mode.
I use a file called kanban.org for my kanban board.
Spacemacs
Emacs
SPC f f
C-x C-f
M-x spacemacs/helm-find-files
M-x find-files
Create a kanban board
Lets assume you created a file called kanban.org. Edit this file and create a table for the kanban board. You can start creating ths manually by typing | for the table layout or use M-x org-table-create and enter the number of columns and rows for the table. For example, to create for a table with 5 columns and 3 rows, you would speciify 5x3
Add the names of the kanban board in the first row of the table. If you did not use M-x org-table-create then add a header row with M-x org-table-insert-hline.
In my kanban board, this gives
Adding tasks to the kanban board
Each item on the board represents a task and we use the Org-mode interal link to jump from the board to the details of the task. To create a link of the same name as the task, simply type the name inside double square brakets [[]].
Moving the tasks across the board
Its easy enough to move the columns around with Alt - <arrow-keys> in org-mode, but there is not a single keybinding to move a cell.
To move the individual tasks between the columns use selective cut and paste:
Move the cursor to the cell you want to move and use C-c C-x C-w
Use TAB to move to the new cell
Paste/Yank the value into the new cell using C-c C-x C-y
However, simply moving the task does not update the Org-mode stage. As each task is a link, I can click on that link and I am taken to the task and can easily update the task stage to match the board.
It would be great if moving the tasks on the board updated the associated task stage and vice versa.
El Kanban - updating the board from task stage changes
I found the El Kanban package that will updated the kanban board based on the task org-mode stages. This uses the Org-mode table format directive that you run each time you want to update the board.
I installed this package and it did pull in my custom org-mode stages for the headers. Unfortunately it did not pull in the tasks to the board, so I will either need to fix the package or find another solution.
When I got started with Lua, everything about it seemed to be the
opposite of what I would like in a language, especially coming
from Racket, Clojure, OCaml, and Erlang. It's unabashedly
imperative, has nils everywhere, and lacks a macro system or any
kind of static analysis. But now after spending over a year with
it, I've developed a fondness for it, and the reasons are not what
I would have expected.
The most obvious strength of Lua is its relentless
simplicity. The small number of concepts you have to keep in your
head when writing Lua can really help you focus, and it picks just
the right concepts to build on[1]. For
instance, the module system is largely just constructed out of
tables and closures. What more do you need? It brings to mind the
simplicity of Scheme and its "perfection is achieved when there is
nothing left to remove" philosophy, but I believe Scheme's
insistence on lists as the fundamental data type actually does a
great disservice—fitting sequential data into an associative
data type is much more natural than going the other way around[2].
There are two advanced features which can be confusing:
metatables and coroutines. But when used judiciously, these can
allow you to overcome the limitations of normal tables and
functions in ways that feel seamless, like the
way itch.io
uses coroutines to hide the fact that many of its functions use
asynchronous I/O and avoids structuring everything around
callback soup.
But what you most often hear touted as Lua's appeal is actually
in its ease of embedding. Now obviously when people talk about
this they are usually referring to how seamless it is to add the
Lua runtime to a large C program and expose its functionality to
code that can be written by the end user. And this is huge;
empowering users to control your programs by doing their own
coding pays major dividends, and here again Lua's simplicity means
more users are likely to be able to take advantage of it. But even
though I don't write large C programs, I found that the ability to
embed Lua execution inside a Lua program is very
valuable.
This advantage is not at all intuitive if you haven't seen it, but one
distinguishing factor of Lua is that it allows sandboxed execution
contexts to be constructed trivially:
In these three lines the code loaded from the user_code
string will run with no access to any functions outside
the api table you provide. (In practice you would also
include a whitelist of pure functions for tables, strings, math,
etc.) But that's all it takes to allow user code to run inside
your own limited sandbox.
Now Lua lacks any notion of first-class interfaces. The idea of
passing a table in which must conform to a certain specified shape
of fields and functions is fully ad-hoc and must be communicated
entirely through documentation. And unfortunately it's somewhat
unusual for Lua programmers to specify which functions in a module
are for public consumption vs which are internal implementation
details. But first-class sandboxes as extension points actually
address many of the same problems as interfaces! Instead of saying
"you must provide an implementation of this interface that has
these fields and these functions" you can say "Provide your own
code here; you will have access to call only this limited subset
of functions which we've designated as a public API. The
implementation details aren't even visible to you."
Now this can break down badly when the sandbox doesn't
expose enough functionality to get the job done. This is why it's
important not to tack on "scriptability" as a checkbox you fulfill
at the end, but to embrace
internal
reprogrammability from the very start. If you use the same
methods to build the program in the first place as the end users
use to customize it, you force yourself to be honest and to give
the end users everything they need.
So from this perspective, we can agree that yes, Lua's imperative
nature and sloppy semantics (especially around nils) put it at a
disadvantage for large codebases vs languages that have the
advantage of immutability and/or intelligent type systems. But the
fact that it offers setfenv makes it uniquely suited
for constructing larger codebases out of small
codebases. This is the approach I take in my game
Bussard, where
I have four separate execution contexts, none of which have much
more than 3,000 lines of code in them. Each small codebase is
perfectly manageable on its own, and the interfaces between them
are concise and clearly-defined despite Lua lacking first-class
features for defining interfaces as we normally think of them.
[1] I have found that this simplicity also
makes it a great choice for teaching
programming, especially to younger kids who haven't reached
the developmental stages where they can appreciate the more
abstract, mathematical
approach espoused by Racket.
[2] I know this method has a bad reputation
because JavaScript and PHP do it very badly, but Lua shows it can
be done well. There is a bit of awkwardness around ambiguity
between array-like tables and key/value tables, but it is not
nearly as awkward as using alists.
Recently, I've been looking at
libigl. I
didn't manage to fully figure out their CMake build system for
tutorials: although each tutorial has a CMakeLists.txt, it's only
possible to build them all at once.
So I decided to replace CMakeLists.txt with a good-old Makefile;
how hard can it be? Concerning includes, not at all hard: the missing
files are found with counsel-locate and added to the include path.
But I had some trouble matching a missing ld dependency to a library
file. Fixed it with a bunch of googling and guesswork; I still wonder
if there's a better way. But in the process, I've found this useful
command:
readelf --syms libGL.so
which produces e.g.:
Symbol table '.dynsym' contains 2732 entries:
Num: Value Size Type Bind Vis Ndx Name
0: 0000000000000000 0 NOTYPE LOCAL DEFAULT UND
1: 000000000004faf0 0 SECTION LOCAL DEFAULT 8
2: 00000000000e8f20 0 FUNC GLOBAL DEFAULT 11 glGetIntegerui64i_vNV
3: 00000000000e13e0 0 FUNC GLOBAL DEFAULT 11 glGetMultiTexEnvfvEXT
4: 00000000000d7440 0 FUNC GLOBAL DEFAULT 11 glProgramUniform2uiv
5: 00000000000cfdc0 0 FUNC GLOBAL DEFAULT 11 glMultiTexCoord3sv
This is a pretty good representation of a binary file: in this
example, instead of one megabyte of gibberish I see a bit more than
2732 lines describing the functions this file uses and provides.
Viewing the symbol list automatically
I liked the above representation so much that I want to see it by
default. In Emacs, it's pretty easy to do with auto-mode-alist:
The idea is very simple: elf-mode is a toggle function that replaces
the buffer contents with the shell command output. It carefully uses
read-only-mode and set-buffer-modified-p so that the file will not
be overwritten by accident with the symbol names.
Using autoload to avoid overhead
As you might imagine, looking at binaries isn't really a common
task. Is it worth to be dragging this code around from now on, loading
it on each start? The answer is yes, of course. Since the actual cost
is negligible until the feature is used.
If you look above, elf-mode has an ;;;###autoload cookie before
it. The cookie results in this line in my loaddefs.el:
(autoload'elf-mode"modes/ora-elf"""tnil)
My init.el always loads loaddefs.el, but never loads ora-elf.el
where the function is defined. That file is only loaded when the
function elf-mode is called for the first time. The above autoload
statement simply instructs Emacs to load a particular file when
elf-mode needs to be called.
When you use the package manager, the autoloads file is generated and
loaded for you automatically:
Here, the package manager will always load ace-link-autoloads.el,
which instructs Emacs to load ace-link.el when one of the
;;;###autoload functions is called and ace-link.el isn't yet
loaded.
As an example of how useful delayed loading is: my 6000 line
config starts in 1.8 seconds.
About 40% of that time is spent on (package-initialize), which I
assume is the package manager loading all those *-autoloads.el files
that I have in my elpa/.
Outro
Let me know if there's interest to have elf-mode on MELPA. Also, if
anyone knows how to set mode automatically based on the first few
chars of the file (all binaries seem to start with ^?ELF), I'd like
to know that as well. Happy hacking!
The new racer-describe command actually renders the markdown in
rustdoc comments. Since we’re showing a separate buffer, we can render
the docs and throw away the markdown syntax. We can even convert
external hyperlinks to clickable links!
This is a really nice example of composing Emacs functionality. Since
we can easily highlight code snippets (it’s an editor!), we actually
apply syntax highlighting to inline code! Note how Vec and T are
highlighted as types in the above screenshot.
Whilst we don’t use *Help* buffers, we extend the same keymaps, so
all the relevant help shortcuts just work too.
We have hit a few teething issues in racer (namely
#594 and
#597) but it’s
changed the way I explore Rust APIs. It’s particularly useful for
learning functionality via examples, without worrying about
implementation:
I hope it will also encourage users to write great docstrings for
their own projects.
While this may be obvious, I was pretty dang pleased with myself when I managed to turn the Caps Lock key on my Windows 10 computer into an emacs friendly Hyper key. Here's what I did:
Step 1. Use AutoHotKey to trivially map the Caps Lock key to the Windows Menu key, or as AutoHotKey calls it, the AppsKey.
;; Add this to your standard AutoHotKey configuration
CapsLock::AppsKey
Step 2. Use this elisp code to capture the Menu key from within emacs and map it to the Hyper modifier: