- N
- ,
- % means ,
- $
- .
- offsets
- +
- -
- ^ means -
- ;
- 'r
- /RE/
- ?RE?
- //
- ??
- ranges based off of regexes
- g//
- mutiline "command-list"
- a, i and c support
- g/old/s//new/ applies s/old/new/ on all matching lines with no error reported
- std::regex is apparently superslow... try passing the compile flag, or find a snappier regex library (like the one on FreeBSD, that one's BSD licensed)
- G//
- v//
- V//
- g, v, G, V no-regex shortcuts (can't cope with lack of tail)
- s///
- s///g
- s///N (replace only Nth match)
- s///p
- s///gp
- s///Np
- s
- s/re/fmt (= s/re/fmt/p)
- s/re/ (special case, where previous fmt is kept and p is implied)
- .,.p
- .,.l
- print specials chars in inverted mode
- .,.pn
- .,.n
- zN
- zNn
- zn (use stored N)
- =
-
Interactive write string prints UTF16 so that conhost shows unicode properlyprint out UTF8 correctly - read utf8 correctly on console
- u, see design document
- validate commands
- g//s//
- m
- d
- i
- t
- r
- a
- c
- j
- s//
- x
- e
- multilevel undo. Requires a simple-ish change, i.e. the undo reg points to a dummy line which points to the previous undo subhead, size is 8, and the text is a pointer to the undo command:
Linking a new undo command links the new subhead to the previous subhead and creates the new undo command line + additional lines. Invoking undo "pops" the subhead and points the global undo register to the previous subhead.
undo: pPrevUndo 8 pUndoCmd1 ... pPrevUndo: 0 8 pUndoCmd0 ; e.g. last available undo ... pUndoCmd1: pLines 4 "1,3c" pLines: 0 2 "hi" pUndoCmd0: pLines0 2 "1d" pLines0: 0 2 "ho" ...
- validate commands
- P
- H
- h
- .,.#
-
% means$ means default filename in shell commands (since the chars for env vars are swapped, might as well swap them back to avoid too much aprsing; $ doesn't mean too much on windows; I'll maybe add an escape char in the future to support reading silly device names or alternate data streams)
- k
Insert mode:
- Ni
- test inserted text preserves registers correctly
- Na
- test registers get clobbered by c
Line transfer, register update:
- j
- jSEPARATOR join lines using SEPARATOR (extension)
- .,.m.
- move preserves registers
- .,.t.
Cut buffer, register update:
- cut buffer
- .,.c
- .,.d
- test registers get clobbered by d
- .,.y
- .x
- test x preserves registers like i
- swap file: see design document
- On w/W, buffer is cleared and re-initialized with current cut buffer
- on clean exit, delete file
- Use MapViewOfFile and CreateFileMapping instead of CRT file I/O because I/O is through the roof. CreateFileMapping can be used to grow the swap file as needed (say,
4k -> 8k -> ... 2**27 -> 2 * 2**27 -> 3 * 2**27 ...
;2**27
should be 100MB or so). MapViewOfFile should be done chunked, because UnmapViewOfFile will schedule changed pages for commit (async) which would keep it pretty fresh. In this implementation, the "no I/O can be performed" scenario can cause it to work with swapfile backed memory (i.e. normal memory) while keeping the same API. Might work on this once I have more test coverage, since the slow CRTIO implementation at least works for now. See remapper – it's much, much faster now
- rewrite swap file to be a giant linked list + a bunch of registers
- large file support (i.e. use getfpos and setfpos and update header to be 64bit) – it's sort-of there, but uses a whole lotta disk space
- NullImpl
- In-memory impl based on MappedImpl (but without an explicit file)
- command line flags:
-
--slow-swap[=dir]
to useFileImpl
-
--no-swap
to useMemoryImpl
-
--swap[=dir]
to useMappedImpl
-
JAKED_DEFAULT_SWAP_DIRECTORY
-
--recover=file
, but I probably need to align the two formats first
-
-
fix the gremlines that happen when I invoke echo and read the output, it really seems like my end is reading "correctly", but I still haven't figured out where the garbage buffer overflow bleed comes from... (mb2wcs was not null terminated)
-
r [F]
- be able to read test\OctrlChars.txt; right now it fails at ^Z (windows EOT? can that even be parsed?) this might be a non-issue, although it would be nice to be able to read everything. Need to check if real ed can read ^D or something like that. I think it's because I'm using strings and fgetc or something like that, I think after switching to use pascal strings, and drastically change the way input handling is done (i.e. fgetc -> ReadFile) we'll see improvements, but that's a big task
-
e [F]
-
E [F]
-
f FILE
-
.,.w
-
.,.W
-
q
-
Q
-
^V literal input – It's done, but it works poorly. Might revisit this one in the future
-
handle
CTRL_C
andCTRL_BRK
elegantly -
dump swapfile to a readable filehave a recovery file if console's closed;or callcalls_exit
which theoretically won't purge the tmp file? or was that__exit
? or_quick_exit
? mehquick_exit(127)
Shell versions:
- r !sh
f !shf is used in the shell command line, and it's not in the spec either- e !sh
- e! and E! set dirty flag
- w !sh
- N,M!sh, N,M!! (extension to filter text through external command)
- ! (execute some command and output a '!')
- !! (repeat last shell command)
- refactor common code (processing !!, the sink and the emitter)
- refactor string processing – done, implemented swapfile.
- refactor it again to use a byte array (required for multi-level undo support without reimagining the swapfile format) –we got pointers now, woot!
- scripting behaviour (cancel on error if !isatty)
- test that e&q cowardly refuse to exit
- utf8 with BOM
- command line argument for P
- arg:
-s
(suppress diagnostics) - start with empty file
- jaked
--help-h
- jaked
--version-V
- some nice html documentation, like
ed
's man page - read windows-native UTF16 files (
rutf16 somefile?
) - don't crash if file can't be read
- the debug build (used to run external tests) should read a timeout from an env var to kill itself if the test takes too long
- add a command line flag for recovery
Big topics:
- Shell escapes
- Command line arguments
- Undo
- Multilevel undo -- the back-end support is there, I just have to go over all commands and use an extra indirect line reference to keep track of th undo stack
Other small topics remain, but ed
is usable even if those topics are open.