Repository navigation
Releases: YardQuit/donkey
Release list
donkey 1.17.3 — one answer to each question, and f leaves folded text alone
A bug fix release. The code was gone over for functions that answer
the same question with code of their own, and four such pairs had
drifted apart into bugs: Split's own copy of the wrap's pair lookup,
three ways of working out a V selection's lines, the cursors'
character count, and the first idle moment re-reading one option of
three. Each question now has one function, and donkey.el is 175
lines smaller for it. Folded text is now never changed by f.
Fixed -- you will notice these
V J d,V J y,M-wandC-u 2 V dover a selection ending on
an empty line left that line behind: on "a", an empty line and "b",
V J dkilled "a" and its newline only. The empty line is taken now.x,d,yandcat the cursors on an accented letter written
with a combining mark, or an emoji made of joined ones, took one code
point and left the rest at every cursor. They take the character
whole, as one cursor has since 1.17.2.- In a split, a delimiter beside an escaped quote took the escaped
quote off:f "ona \"foo" blefta \foo b. A split now wraps
exactly as a wrap key does, junk rows in the pair table included. - A pair, or a refused command, added with
add-to-listin your init
file took effect only afterM-x donkey-pair-refreshor
M-x donkey-refresh-suppressed-commands; the first idle moment
re-read only the wrap keys. It reads every option now. RETwith an Enter rule whose command is a lambda signaled
wrong-type-argument; it runs the lambda now.
Changed -- you will notice these
fleaves out matches inside a fold whateversearch-invisible
says. Withsearch-invisibleset totit used to hold them and
write into the fold. Folded text is changed byr randr q; with
r q, unfold first, so you can see each match you answer.C-u -1 m smarks the sentence before point, asC-u -1 m wmarks
the word before it; it used to mark the sentence at point. With
nothing before, it refuses and leaves point and the mark alone.
Fixed
m iandm alogged "Mark set" before saying what they selected.m iwith a pair-table row whose closing half is not a character
raised a raw error; it says the delimiter is unsupported.- Undoing a split did not count what it recorded against
undo-limit,
so a large split kept two full undo entries -- some 13 MB each at
850,000 places. The newer is now cut to the limit like any other.
Under the hood
- One function now answers each of: which pair a delimiter belongs to,
which kind of buffer this is, which cursor a state asks for, whether
a mode is on a list, which lines aVselection covers, how a split
deletes at every place, how its state is cleared, and howyand
dchoose what to act on. The Org agenda's own Enter handler is
gone: the agenda'sREThas been the agenda's own since 1.12.0.
Upgrading
Nothing to do. If you set search-invisible to t so that f would
reach into folds, use r r or r q there instead.
donkey 1.17.2 — edits where two features meet no longer change text you did not touch
A bug fix release. Every part of the package was gone over for what
happens where two features meet -- a fold under a line selection, an
input method or overwrite mode while typing at a split, read-only text
under an edit at many places, two clients of one daemon, a mistyped
setting -- and what turned up is fixed here, in sixty-two changes,
most of them in places that changed or lost text without saying so.
Fixed -- you will notice these
),]and"in overwrite mode withdonkey-pair-modeon: a
closer typed where two stood deleted the second, so)before the
))off(g(x))leftf(g(x), and an opener typed over text wrote
a closer that pushed the line along. Pairing now does nothing in
overwrite mode: a delimiter replaces the character under the cursor,
as in plain Emacs.V,J,Kon a folded Org or outline heading: a line selection
counted the lines hidden in the fold, soV K dfrom the heading
below a folded one deleted a hidden body line, andV don the
folded heading left its body under the heading above. A folded
heading and its body are now one line, askill-whole-linetakes
it, andm lbanks them together.A,a,x,d,con a folded heading:Atyped at the end of
the hidden body, andx/djoined or deleted hidden text where
Org's ownC-drefuses.Aandanow type at the end of the
heading, andx,dandcwith a count refuse over hidden text.t,T: a cursor could land on a line hidden in a fold, and typing
then went into the hidden text. They now pass over folded lines, as
jandkdo.O: the line it opened above was re-indented as well as the new
one, so a Makefile recipe lost its tab, a Python statement after a
block moved into the block, and an indented line in Text mode lost
its indentation. Only the new line is indented now, at the cursors
too.p: every press put the clipboard's text on the kill ring again, so
ythenp p pleft four identical kills,C-u 200 ppushed every
older kill off the ring, andM-yafterpfound the duplicate.
The clipboard's text goes on the ring once now.RETinhexl-mode: one press wrote a carriage-return byte over the
byte at point. Inpicture-modeit broke the line. It does nothing
in either now.RETon the blank line under a TODO heading toggled the heading, and
could add a CLOSED line. OnlyRETon the heading line itself
toggles it now.Con an Org source block's#+begin_srcor#+end_srcline
commented a line of code instead; it now refuses there, and a
selection comments exactly the lines of code it covers.x,d,y,con an accented letter written with a combining
mark, or an emoji built from several joined ones: they took one code
point and left the rest standing. A character drawn as one is taken
as one now, asC-dtakes it.Pover aVselection: the rectangle's last row was glued onto the
line after the selection. The rows now replace the selected lines as
lines of their own, aspreplaces them.C-x C-xin aVselection silently ended it, soythen lost the
last newline anddleft an empty line behind. It now trades the
selection's ends, asodoes in Vim, andC-SPCends it.m i,m aone level out (a second press, orC-u 2) picked the
sibling pair where a closer sat right before the inner opener:
m i { m iin\frac{a}{b}selecteda. They now find the pair
around.m I,m Afrom inside a string or comment refused, or picked the
parens inside a regexp string. They now mark the expression around
the string.m Wwith a count past the end of a list raised a scan error and
moved the cursor; it now marks what there is and stops, asm w
does.- In a split,
M-u,M-lorM-creaching past a place while writing
corrupted undo (ugave backa foo bar, with a second space) and
could delete text at the other places. They undo exactly now. - In a split,
revert-bufferwhile writing made the nextufail and
leave the buffer nearly empty. The revert now ends the writing with
undo whole. - In a split, an edit made from an indirect buffer (
C-x 4 c) while
writing could never be undone, and text typed into another place
from there was written over. Such an edit now ends the writing and
keeps its own undo. - In a split of thousands of places,
C-x C-sright after typing saved
a half-written file: 2,000 of 20,000 places. A save now writes every
place first. - In overwrite mode, writing at a split or at the cursors stopped after
one character at the first place. It now writes over every place. pat the cursors afterD,d,yorcleft the last cursor's
text empty pasted the whole kill at every cursor;V yat the
cursors on a last line with no final newline added a blank line to
the kill;V pat the cursors opened an empty line under every line.
Each cursor gets its own text back now, and lines stay lines.g h v j j t, the way to select two whole lines, made three cursors.
It makes two.C-u 2 g hat the cursors sent every cursor to its line's end; it
goes to each line's start.- An edit at the cursors that read-only text refused part of the way
left the cursors where the edit had moved them, and the next key
acted on that. They are left as they were. m l: a line typed, opened or pasted at the edge of a banked line
was banked with it, soyanddtook lines nobody banked.- Banks after
M-x text-mode,revert-bufferor an Org restart: the
highlight stayed,ycopied a single character, and nothing could
clear them. Banks survive a change of major mode now. d,pover several banks with read-only text on one of them deleted
some lines, killed all of them and spent the banks. Nothing changes
now when any part is refused.uin a mark run spent a press on a key that changed nothing, such
aswpast the last word.Mwith several clients of one daemon: presses on one client went
into the other client's run, and a run armed on a client that
closed stayed armed. Each run now hears only its own client, and
ends with it. A split ends with its client too.DELbetween the halves of a pair in Dired, a help buffer or any
read-only buffer ran DONKEY's pair delete and said "Buffer is
read-only". It is the mode's ownDELthere again.C-x C-qin a fundamental-mode or diff-mode buffer showed
DONKEY[S]whileh j k lsaid "Buffer is read-only". They work at
once now, and making the buffer writable again gives Normal state
back whole.SPC C-g,g C-g,m C-gin a help or other support buffer rang the
bell and stopped a keyboard macro; they quit quietly, as in Normal
state.- In a terminal, every change between Normal and Insert state paused
10 ms (i C-gtook 10.5 ms inemacs -nwandemacsclient -t), and
leaving Emacs left the shell with Insert state's bar cursor. The
pause is gone, and the terminal gets its own cursor shape back when
Emacs exits or is suspended, or a terminal frame closes. - With
donkey-setup-smartparens,C-gcould not leave a minibuffer
that had Smartparens on; it leaves it now.
Changed -- you will notice these
- In a split,
M-d,C-k,M-\,M-zandC-tat a place's edge
were repeated at the other places by count, whatever the text there:
M-dturnedc foo bazookaintoc fooooka. They are now repeated
only where the same text follows every place, and end the split,
saying so, everywhere else. Backspace andC-dbehave as before. fleaves out matches inside folded or otherwise invisible text, and
says how many: "Split: 2 places in the buffer (2 hidden matches left
out)".%fused to write into folds where nothing on screen showed
it. Withsearch-invisibleset totevery match is held, as
before.g handg linside a mark run ignore a count, so the selection's
ends never cross.C-u 0 g lused to flip the selection to a lone
newline. Outside a run both keys take a count as before.xwith a negative count over an accented letter takes the whole
letter, accent included. To remove only an accent, useDELin
Insert state.- A mark key that reaches nothing says so and leaves the mark alone:
C-u - 1 m won the first word said "Word marked" over an empty
selection, andm sorm pin a blank buffer refused only after
moving the mark.
Fixed
- PRIMARY after a rectangle: a middle-click pasted the rectangle's rows
as they were at the time of the click, so text typed there after the
rectangle ended -- a password -- was what the next middle-click
pasted. With DONKEY off it pasted the plain stretch between the
corners, and with rectangles live in two windows, the other one's
block. PRIMARY now keeps the block that was selected. - A split no longer keeps a copy of the text last written in its hidden
working buffers after it ends. - A dotted list in a mode or pair option --
'(comint-mode . Info-mode),
or a pair added withappendand no list round it -- madefind-file
fail, made(donkey-pair-mode 1)stop the rest of the init file, or
made every key typed in Insert state signal. Such a value now reads
as no list at all.donkey-position-ring-maxset to1.0e+INFno
longer switches position tracking off for the session. - An input method waiting for Insert state survives
revert-bufferand
a change of major mode. - With text scaled down, every visible row of a tall rectangle is
highlighted and every cursor oftandfis drawn. m vin right-to-left text takes the character under the cursor.- With the
pairing-packagewrap engine and onlydonkey-pair-mode
pairing, a delimiter over a selection put `(...
donkey 1.17.1 — a key taken out of Normal state no longer reaches the major mode
A bug fix release. A key in Normal state is now DONKEY's, one you
bound, or nothing: taking one of DONKEY's keys away with
keymap-unset used to hand it to whatever the major mode put there,
where it could type or run the mode's own command. The tutor stops
erasing itself on the first u, and shows its keys, its states and
the lines to practice on in colors of their own.
Fixed -- you will notice these
keymap-unseton a key ofdonkey-normal-mode-map: the key used to
fall through to the major mode, with or withoutREMOVE. Measured
over sixteen stock modes with every printable key,RETandDEL
unset:/typed inhtml-modeandnxml-mode,"typed in
texinfo-modeandlatex-mode, andRETandDELedited in all
sixteen. Now every printable key,SPC,RETand the delete keys
do nothing once taken away.TABand every key Normal state never
bound --C-x,C-c,M-x, the arrows -- reach Emacs as before.
The README gave the fall-through as the way to give a key back to
the buffer; its own example,;, gave nothing back in any stock
mode, and the section is now "Taking a key away".g,m,r,zandSPC: a sequence a major or minor mode bound
under one of those keys ran in Normal state, merged in under
DONKEY's own. Only DONKEY's keys and yours answer there now.uin the tutor: in a tutor just opened, oneuemptied the
buffer, because the lesson itself was on the undo list. Undo now
stops at the lesson as it opened.- The tutor wrote
RETandSPCas plain text beside keys drawn as
keys. They, theC-uof a count, and Backspace and Delete, which it
now namesDELand<delete>as Emacs does, are drawn as keys too.
Changed -- you will notice these
- The tutor colors the names of the states -- NORMAL, INSERT, SUPPORT,
and the modeline's DONKEY[N], DONKEY[I], DONKEY[S] and DONKEY[E] --
in the facedonkey-tutor-state, and marks each line to practice on
with---->, four dashes where there were three, in
donkey-tutor-arrow. The faces inheritfont-lock-keyword-faceand
font-lock-builtin-face; customize either to change it. A font with
arrow ligatures, Cascadia Code among them, draws--->as a double
dash and a short arrow, and---->as one arrow.
Upgrading
Nothing to do, unless you took a key out of donkey-normal-mode-map to
reach the major mode's command in Normal state: that key now does
nothing. Bind the command to the key in donkey-normal-mode-map, or,
for one mode only, remap DONKEY's command in that mode's own map, as
the README's "If a Key Is Not Doing What You Want" shows. A tutor
buffer already open keeps its old text until you kill it.
donkey 1.17.0 — t puts cursors down a column, and editing happens at every one
The split of 1.16.0 held every match of a regexp and typed at all of
them. This release gives it cursors: t puts a second cursor on the
line below, a selection of lines gets one on each, and from then on
the motions, the selections, the edits and the mark run happen at
every cursor at once, in Normal state, with the keys you already use.
It was built by using it on a book of 87,000 lines: ten thousand
cursors answer a key in a tenth to a fifth of a second, and a
keystroke typed at 850,000 places takes about ten milliseconds where
it took over a second.
Added
t(donkey-split-add-cursor) puts a cursor on the line below at the
same column; each press adds one more, a count adds that many, and a
negative count adds above.Tadds above,DELtakes back the cursor
added last, and=puts every cursor back under the real one after a
motion left them in different columns. Both keys rang the bell before.tover a selection puts a cursor on every line it covers:V j j j j tis five cursors at their lines' starts, and avselection or an
m vblock gives each line a cursor at point's column.- Every cursor then does what the real one does:
hlwbW
Bg hg lmove;v,Vand themobjects select;iaI
Actype, withC-gcoming back to the cursors rather than ending
them;dxDypdelete, kill, copy and paste and keep the
cursors; a delimiter wraps each selection and the same key takes the
pair off;Mis the mark run at every cursor,uandUstepping it;
m landm ubank and unbank each cursor's line;M-uM-lM-c
change case;oOopen a line at each cursor;>andCindent
and comment each line;.repeats;uandUundo and redo and keep
the cursors;fsearches each cursor's selection or line. Any other
key,jandkincluded, ends the cursors and does its ordinary job. - The kill ring at the cursors: what
d,Dandytake is one kill,
one line per cursor, andpgives each cursor its own line back when
the kill has as many lines as there are cursors, som w y, a move,
andpcopies each cursor's word to where that cursor went. - Three limits keep the cursors out of each other's way: a cursor never
leaves its own line, cursors that come to share a line become one, and
a command that fails at one cursor is undone at all of them. An edit
at the cursors is one undo step whatever their number. donkey-split-cursor-limit(10000) is the most cursorstmakes, and
it refuses past that and says so; set it higher, or tonilfor no
limit, or setdonkey-split-cursor-limit-askto be asked instead.
fhas no limit.fdraws a cursor at every match, where before it showed one, so
where each match will take the typing is no longer a guess.fwith the regexp typed with%in front,f %foo RET, searches
the whole buffer, whatever is selected; with nothing selected it
searched only the current line, and the%was part of the search.
A bank is left standing.\%or[%]at the start searches for a
percent sign.- Lesson 16 of the tutor teaches the cursors by exercise, and the README
has a section, "Undo history at scale", on what a step at thousands of
places costs and the three Emacs settings that keep more of them.
Changed -- you will notice these
m v c, change on a rectangle, used to ask for the replacement in the
minibuffer throughstring-rectangleand stay in Normal state. It now
empties the block on every row and puts a cursor on each, in Insert
state, so the text is typed on every row at once and can be edited as
it is typed;C-gcomes back to the cursors andC-gagain ends
them.RET, which used to end the prompt, now types a line break on
every row, som v cxRETthat gavexon each row givesx
and a new line on each;C-/takes the line break back on every row.
The block still goes tokilled-rectangle, wherePpastes it back,
and a row too short to reach the block is still padded out to its
column. A block one row high is a plain change, and one taller than
donkey-split-cursor-limitstill asks in the minibuffer.m won a dash, or on any symbol character with no word at it, used
to refuse with "No word at or before point". It now takes the word
ahead, or the one behind where nothing is ahead, as it does from a
space. A dash between two words still gives the word it touches, and
m bfollows.uafter a split: once the writing at the places ends, oneutakes
back everything typed there, at every place, andUputs it back.
1.16.0 took it back about twenty characters at a time, the way Emacs
groups typing.
Fixed
- The tutor's last section said DONKEY steps aside altogether in Dired,
Ibuffer and the tabulated lists, and that its letters win in the
read-only buffers it does not leave. Those have been support modes
since 1.12.0, wherehjkland the leader are DONKEY's and
every other key is the mode's; the tutor now says so, and names the
buffers DONKEY does leave: Magit, a rebase todo, Info, terminals and
REPLs. - The README had the two directions of a wrap key the wrong way round,
and the docstring ofdonkey-mark-innersaid the delimiter typed after
m idoes nothing: with what the pair holds selected the pair comes
off, and with the pair selected as well another goes on. - The Commentary at the top of
donkey.el, the package's long
description, still described DONKEY as it was before the mark run; it
now says what the README says.
Under the hood
- Typing at many places is written where a window can show it first and
the rest is swept in between keystrokes, and the writing, like each
verb, records one compact undo entry. Before, every keystroke at
850,000 places took over a second and recorded 27 MB of undo, which
Emacs discarded at the next collection with a warning. - A tall rectangle is highlighted only where a window could show it,
and its PRIMARY selection is claimed lazily and made only when a
program asks, so a motion over 87,000 rows no longer takes most of a
second.
Upgrading
Nothing to do, unless a regexp you give f starts with a percent
sign: write \% there now, since a leading % means the whole
buffer. t and T were unbound keys in Normal state, so no binding
of DONKEY's moves; if you had put something of your own on either, it
stays yours, and the commands are donkey-split-add-cursor and
donkey-split-add-cursor-above. DONKEY's startup report now names
such a key, with a line like "DONKEY: t is my-command now, was
donkey-split-add-cursor": that is the report noticing a key you have
taken, and setting donkey-report-binding-changes to nil turns it off.
If you work with thousands of cursors or places, the README's "Undo
history at scale" says which three undo- limits to raise so that more
than a step or two is kept.
donkey 1.16.0 — f edits every match at once
A feature release. f edits every match in a selection at once, and a
V selection hands Emacs's own C-w, M-w and C-x r s its whole
lines.
f asks for a regexp, holds every match in what you selected, and
waits: i types before every match, a after it, c empties it and
types in its place, d deletes it, and w or a delimiter wraps it.
What you type appears at every match as you type it, in ordinary
INSERT state, and C-g ends it keeping what you wrote.
It is DONKEY's own take on multiple cursors, and it works by mirroring
rather than by cursors: the place you type in is copied into the others
after each command, so nothing intercepts a command while you write and
INSERT state stays Emacs's own.
Added
f(donkey-split) — a key that rang the bell before. It
changes nothing by itself: it selects every match and waits for a
verb. A wrap leaves the split standing, so pairs nest and a verb can
still follow —f([awraps twice and then types after — and
the other verbs end it.- What
fsearches is what you selected: the current line when
nothing is, av,Vor%selection, the inside of anm vblock
(C-u ftakes each row's whole line), or banked lines, with av
selection made after banking searched exactly as selected. There is
no whole-buffer default; press%first. Opening the split spends
the bank, asyandddo. - Matches that differ —
[0-9]+over1,22and333holds
three different texts, andiandathen type at their edges, so
nothing is replaced. Case is decided the wayr rdecides it: a
regexp with no capital ignores case. DELandC-dat an edge — Backspace just before a match,C-d
just after it, and the indentationRETbrings with it are repeated
at every match. An edit anywhere else ends the split and says so.canddput one kill on the ring: one copy when the matches
agree, every match on a line of its own when they differ.- The report — a split that ends says what it did, "Split: typed
after 3 places", and the line stays in*Messages*. donkey-split-facecolors the matches while a split is open.- The tutor teaches the split in Lessons 14 and 15, by exercise:
the verbs, a selection, banked lines alone and with part of a line
selected, case, and the five regexp spellings Emacs does not share
with other tools.
Changed — you will notice these
C-w,M-w,C-x r son aVselection take its whole lines,
final newline included, asdandydo.C-wused to leave an
empty line behind, andM-wcopied the lines without their last
newline, so the paste ran into the line it landed on.M-s o
searches the same lines. Commands that read point and mark for
themselves still see the selection stop before its last newline —
M-x keep-linesleaves the last line out — and the README says how
to hand them whole lines.
Fixed — you will notice these
Min a daemon with two clients — a key on the second client
ended a mark run armed on the first but left its keys armed there for
good, so on that client its letters went on running mark commands in
every state: typingwowin INSERT state left a singleo. A run
now keeps to the terminal it started on.
Under the hood
- Every match's edit goes through Emacs's change hooks as a typed edit
does, so font-lock, the syntax cache and a language server see every
match change, not only the one you typed in. - A verb over many matches is one change: it happens at every match or
at none, and what it reports reaches the kill ring only once it has. - Only what changed is copied into the other matches, which keeps a key
at a thousand matches to about a millisecond and a half, and the undo
record to about a third of the size.
Upgrading
Nothing to do. f was a free key, so if you had bound it yourself your
binding still wins; DONKEY's startup report now names it — "f is ...
now, was donkey-split" — because the key is DONKEY's from this release.
donkey 1.15.0 — a delimiter closes itself as you type, if you ask it to
A feature release, and the feature is opt-in: nothing about your typing
changes until you turn it on.
DONKEY can close a delimiter while you type. Type { and you get {}
with the cursor between the halves; type the closing half where one
already stands and the cursor steps over it rather than doubling it.
It is off by default and stays off, because INSERT state is otherwise
entirely Emacs's — C-g is the only key DONKEY holds there — and a
package that changed how you type on upgrade would be taking a liberty.
The delimiters come from donkey-mark-pair-delimiters, the same table
m i selects from and the wrap keys use. A pair you add there is one
you can type as well as select and wrap, with no second list to keep in
step.
Added
donkey-pair-mode— a global minor mode, off by default. With it
on, an opening delimiter writes its closing half and leaves the
cursor between the two. The closing half, typed where that character
already stands, steps over it.DELbetween the halves of an empty
pair takes both, andDELanywhere else is still your major mode's.
A count types and pairs nothing, soC-u 3 (gives you three
brackets.donkey-pair-delimiters— how much of the table is used.safe,
the default, is the brackets and the quotes: eight of them.allis
every pair in the table: twenty-one. A list is exactly those
characters.nilleaves the mode on with nothing pairing.donkey-pair-safe-exclusions— whatsafeholds back. Thirteen
characters that are ordinary text far more often than they are
delimiters: the apostrophe in "don't", the colon in prose, the
less-than sign. Add to it when a pair you put in the table is one you
never want to type.donkey-pair-delimiter-exceptions— drop one delimiter in one
major mode. Ships with the quote, the backquote and the hash held
back in Lisp buffers, where#'is a function quote.donkey-pair-delimiter-inclusions— the opposite, and HTML is
what it is for. The less-than sign is punctuation in prose, which is
whysafeleaves it out, but almost every line of an HTML buffer
sits between one and its closer. One row namingsgml-modecovers
html-modeandmhtml-modeas well.donkey-pair-excluded-modes— turn the pairing off by major mode
while NORMAL state stays on.donkey-pair-stand-down— on by default, and it means DONKEY
does nothing wheresmartparens-modeis on. Set it to nil to pair
regardless.M-x donkey-pair-refresh— hand the delimiters to Emacs again
after a plainsetq.setoptneeds no help.
Where electric-pair-mode is on, Emacs keeps the job and DONKEY hands
it the delimiters instead of pairing anything itself, so a pair Emacs
had no way to know about — (?# . ?#) say — is one it pairs now.
M-x donkey-debug-platform names whoever has the job in the buffer you
ran it from, and how many delimiters pair there.
Fixed — you will notice these
C-h f— six commands showed a key reference as brackets round a
symbol, "press[donkey-refresh-wrap-keys]", rather than the key
itself. Four of the six are in the wrapping code and have read that
way since wrapping shipped. A lone backslash before the bracket is
dropped by the Lisp reader as an unknown escape, and neither the byte
compiler nor checkdoc reports it.
Under the hood
- Every option the typing hook reads is coerced where it is used rather
than trusted. A signal raised frompost-self-insert-hooktakes the
hook off for the session, so one mis-typed character in an init file
would have turned the pairing off silently and for good. A value of
the wrong shape is skipped now and your typing continues. - The delimiter prompt reads the pair table after the prompt rather
than before it, so a pair added while it waits is one it accepts. - The pairing hook runs ahead of the pairing packages and at most once
per press, because a package that writes its own closing half runs
the whole hook again with a character nobody typed. - The README's tables of what pairs where are read out of the file by
the test suite and checked against the running Emacs, so a table that
drifts from the code fails the build rather than misleading a reader.
Upgrading
Nothing to do. The mode is off until you turn it on:
(donkey-pair-mode 1)If you already use electric-pair-mode or Smartparens, turning it on
is still safe: DONKEY works out who should do the job and gets out of
the way. M-x donkey-debug-platform says who has it.
donkey 1.14.1 — a banked line no longer disappears under hl-line-mode
A bug fix release, from a report that banking looked broken in a
configuration with the current-line highlight turned on.
It was. m l puts a line aside and highlights it, and hl-line-mode
draws a band across the line point is on. Both are overlays, both
cover exactly the same whole line, and both sat at priority -50.
Emacs is explicit about that case: when two overlays share a priority
and neither is nested in the other, which one shows is not something
you may assume. So the bank you had just made was there or it was not,
decided by nothing either package controls — measured over 200 banks
in a stock Emacs, the band hid the bank 116 times, and in one real
configuration 55 times in 100.
Fixed — you will notice these
m l— a banked line shows its own highlight whenever
hl-line-modeorglobal-hl-line-modeis on. It used to show it
about half the time and show the current-line band the rest, with
nothing to tell you which run you were in; a line you had banked
simply looked unbanked. Nothing else about banking changed: the
keys, the counts, the messages, and whaty,dandpspend are
all as they were, and a line that is both banked and selected still
shows the selection.
Under the hood
- A bank now sits at overlay priority
-25, between the current-line
band at-50and the region. Two other highlights live in that band
and are drawn under a bank as a result: the current lineguddraws
while debugging, which is off unless you set
gud-highlight-current-line, and thenext-errormessage
highlight, which is transient. Everything else in stock Emacs sits
above a bank and is unaffected. - Two tests pin the new order: one that the band cannot hide a bank in
either creation order, one that a bank cannot hide the live
selection.
Upgrading
Nothing to do. No option, key or command changed.
donkey 1.14.0 — NORMAL state answers every printable key
This one came out of a question with no bug attached: in NORMAL state,
can you be sure what a key does? The answer was no, and the reason was
structural rather than a mistake. Suppression worked by remapping the
typing commands by name, and a name cannot reach a command that has
none — so thirty-two printable keys fell through to the major mode,
and what they did there depended on which buffer you were in.
The case that made it concrete: idlwave-mode binds & to an
anonymous command that inserts an ampersand. No list of names could
ever have caught it, however long the list grew.
Changed — you will notice these
- A key a major mode bound that DONKEY does not now does nothing
in NORMAL state, and saysis undefinedwhen you press it. This is
answered from under the keymap rather than from a list, so it holds
for every printable key, in every mode, including modes nobody has
installed. - To hand a key back to the buffer, unbind it — exactly as before,
(keymap-unset donkey-normal-mode-map ";"). That now works for any
printable key rather than only the ones DONKEY had bound. M-x donkey-debug-platformsays which kind of buffer the report
came from —Insert [S],Insert [E]orInsert [I]— and, where
something decided it, what decided it. In a Dired buffer it used to
sayState here: Insert, which is true and tells a bug report
nothing.
Under the hood
- The modeline asks which kind of buffer this is once and remembers
the answer, where it worked it out on every redisplay. Byte-compiled
in a Dired buffer the lighter goes from 1.50 µs to 0.38, and in a
graphical frame from 1.47 to 0.23. The letter and the cursor shape
come from that one answer now, so the two cannot disagree. - The test suite's docstrings are held to the package's own spelling
rules by a guard that renders them — a hundred and one lines were
wrong in a way that showed only in the rendered text, and nothing
had ever rendered them.
Upgrading
Nothing to do, unless you had come to rely on a major mode's key
reaching through NORMAL state in a buffer you write in. If you had,
name it and unbind it:
(with-eval-after-load 'donkey
(keymap-unset donkey-normal-mode-map "&")) ; & is the mode's againYour own bindings are untouched, including a prefix hung on a key
DONKEY does not bind — (keymap-set donkey-normal-mode-map "s d" ...)
works as it always did.
donkey 1.13.0 — speedbar navigates like Dired, and [S] and [E] get cursors of their own
speedbar joins the support modes with Dired's keys, and the two states
that are not NORMAL stop borrowing INSERT's cursor. The rest is the
documentation catching up with 1.12.0 — the install chapter is one
method instead of five, and the chapter on disagreeing with a section
had two examples that quietly took keys away from anyone who pasted
them.
Changed — you will notice these
hgoes up a directory andlopens the file or enters the
directory in a speedbar tree, the pair Dired has.Kkills the
buffer on the line, which is wherekwent when DONKEY took it.
jandkare plain line motion there: speedbar bindsnandp
directly instead of remappingnext-line, so nothing of its own
reachesj. What that costs is the description speedbar echoes as
you move and the cursor resting on the button glyph — no command
depends on either, andIstill asks for the description.lgoes to the member definition in anebrowsemember buffer,
which is whatRETdoes there. Forty-one sections ship now, and
twenty-six of them givehorla meaning.- The cursor in a support mode is a box, where it was INSERT's
bar. The keys in an[S]buffer are NORMAL state's —h j k lmove
and nothing you press becomes text — so it looks like NORMAL state
rather than like typing.donkey-cursor-supportis the option. donkey-cursor-excludedsets the cursor in an[E]buffer and
ships as the bar such a buffer already showed, so nothing changes
there unless you had setdonkey-cursor-insertyourself. The two
are independent options: an excluded buffer keeps the shipped bar
until you set this one to match yours.
Fixed — you will notice these
setopt donkey-support-modesno longer warns. The option
described its commands with a type that only matches what is loaded
at that moment, and the table names commands from forty packages, so
setting the option to anything — including back to its own shipped
value — printed a type warning at every start.- The README's examples for disagreeing with a section no longer
take keys away. A section answers with nothing from any later one,
so the Dired examples, which left outJandK, left
dired-goto-fileanddired-do-kill-lineswith no key at all for
anyone who pasted one. The agenda example that takesSPCback left
outhandlthe same way. - The
=key's row in the binding tables renders as a key again
on the repository page, and the test that checks those tables
against the keymap now reads that row, which it never could before.
Under the hood
- Installing from a clone is one
use-packageblock, which compiles
the file whenever it is newer than the.elcbeside it and says in
the echo area which copy it loaded. The by-hand, straight.el and
quelpa blocks are gone, along with a third copy of the compile
recipe. - What
SPCcosts a support mode was remeasured across all forty-one
sections rather than the thirty-one the text described: twenty-five
carry the pager pair, eight a line motion, three put something that
has another key, and four lose something with no other home, where
it said two. - The cursor a buffer asks for is memoized on every input to the
answer, because it is asked once per command. - 1,481 tests, up from 1,475.
Upgrading
Nothing to do. If you had set donkey-cursor-insert yourself and want
an excluded buffer to match it, set donkey-cursor-excluded to the
same shape. If you would rather tell all four states apart, give
donkey-cursor-support and donkey-cursor-excluded shapes of their
own.
donkey 1.12.0 — a program's buffer keeps its own keys, and DONKEY keeps four'ish
1.11.0 answered "NORMAL state owns the alphabet in a buffer a program
made" by stepping aside altogether: Dired, Ibuffer, Magit and the
tabulated lists went on donkey-excluded-modes, which gave the mode
its keys back and took h j k l with them. This release is the middle
that was missing, and it comes in two sizes. In a list or a viewer —
Dired, Ibuffer, Occur, the menus, twenty-one modes in all — DONKEY
holds five keys, h j k l and SPC, and the mode keeps its
whole alphabet. In the eighteen that are text to read — help, Man,
apropos, compilation — it holds about two dozen, because there is
nothing in those buffers to lose. The modeline says DONKEY[S] in
both, and thirty-nine modes ship a section.
Changed — you will notice these
jandkwalk the listing andlopens what is under the cursor
in Dired, Ibuffer and the tabulated lists. They came off
donkey-excluded-modesand are support modes instead, sod,m,
x,gand the rest of the mode's alphabet are exactly as they were
in 1.11.0, and the four motion keys work again.hgoes up a
directory in Dired.dno longer deletes inhelp-mode,Man-mode,occur-mode,
compilation-mode,grep-modeandorg-agenda-mode, and neither do
the other editing letters. NORMAL state used to be on in those, which
meant DONKEY owned the alphabet; they are support modes now. Nothing
was at risk — the buffers are read-only, so every editing key was
refused — but the mode's own keys were unreachable, and now they are
not.SPCis the leader in a support mode as well as in NORMAL state, and
it is the same keymap. Anything you have hung underSPCreaches
Dired, help, Man and the rest without being named a second time. The
mode's ownSPC, usuallyscroll-up-command, isC-vas it always
was, andS-SPCis untouched.gis a prefix in the eighteen modes that take the reading keys —
Man-mode,help-mode,apropos-mode,compilation-modeand the
rest — becauseg gandg ego there. Wheregwas
revert-bufferorrecompilethe section carries it onR.w,b,y,G, the mark run and?work in those eighteen —
about two dozen keys in all, against five in the other twenty-one.
They are buffers of text to read and copy, so the reading half of
NORMAL state is there and nothing that types is.C-gstill quits:
it delegates tokeyboard-quitwherever NORMAL state is off.lgoes to the error in a compilation buffer, into the entry in an
archive or a tar file, to the occurrence in an Occur buffer, and to
the reference in an Xref buffer. Twenty-four of the thirty-nine
sections givehorla meaning; where none does they are
backward-charandforward-char.
Added
donkey-support-modes, the table of sections. A section names the
mode, optionally a package, and the(CHARACTER . COMMAND)pairs
that say what a key means there. A mode matches by derivation as well
as by name, and the first section it matches answers, so write a
specific mode before the general one it derives from.donkey-support-mode-exceptions, for a buffer that looks like a
program's but is one you type in.occur-edit-modeis the case it
ships for.donkey-key-packages, a named list of sequences a section can ask
for in one word.proseis the only one that ships: the reading half
of NORMAL state, forty-five sequences.
Under the hood
- The rule that handed individual letters back to a major mode was
built, measured and then deleted. Every buffer it would have applied
to is a support mode, decided by its section, so it found nothing;
the options it introduced never appeared in a release. - Options read from
post-command-hookare coerced rather than
trusted, a section cannot name a command that types, and the two
caches that decide a buffer's state are keyed on the same inputs. - 1,475 tests, up from 1,426.
Upgrading
Nothing to do. If you put dired-mode, ibuffer-mode or
tabulated-list-mode on donkey-excluded-modes yourself, your setting
still wins and those buffers stay DONKEY[E]; remove them to get the
four motion keys back. Info-mode is still excluded, as it was in
1.11.0.