README ¶
Gomacs - Go Powered Emacs!
Gomacs is an Emacs clone for the terminal. Unlike many other mini-Emacsen, it
has an embedded Lisp, powered by Glisp.
This puts it in the realm of true Emacs! It also supports syntax highlighting
for a wide array of languages; see the syntax-files/
directory.
If you find Gomacs useful, consider supporting me on Patreon - at just $2000 a month I can justify working on it full-time!
Closely follows the modified version of Kilo found in this tutorial in terms of the inner workings of the editor. Inspiration also comes from the suckless editor Sandy.
Installation
If your $GOPATH (or %GOPATH% under Windows) is set correctly, you should be able to run:
go get github.com/japanoise/gomacs
If you want to install gomacs systemwide, make sure you set your gopath and that this directory resides within it: here's an incantation that will do that on Linux if you're not sure how:
# Set gopath and create directories
export GOPATH="$HOME/go"
mkdir -pv "$GOPATH"
# Create directory for this repo to live
mkdir -pv "${GOPATH}/src/github.com/japanoise"
cd "${GOPATH}/src/github.com/japanoise"
# Clone the repo
git clone https://github.com/japanoise/gomacs
cd gomacs
The makefile includes install
which will install the program as gomacs
, and
also install-em
which will install it as em
- in case your fingers are used
to uemacs. Both come with corresponding uninstall
targets. The makefile also
accepts PREFIX
, DESTDIR
, MANDIR
, etc.
Usage
gomacs [options] file
Options
-s
- Disable syntax highlighting-d
- Enable dumping of crash logs-D
- Dump the keybindings to stdout and exit immediately. Used to generate the man page.
Keybindings
Gomacs uses the standard Emacs keybindings. Of course, not all are implemented yet - I'll try to keep this list up to date!
Basics
C-g
- Cancel an action/keybinding/whateverC-x C-c
- Save buffers and quitC-x C-s
- Save bufferC-_
- Undo (C-/
also works)C-x C-_
- Redo (C-x C-/
also works) - pressC-_
orC-/
again to redo more actionsC-z
- Suspend Gomacs (Linux only)M-x
- Run named command<f12>
- Panic key - quit emacs immediately without saving changes. Useful if Glisp falls down (which may happen if you do a lot of hacking on the editor's internals)
Getting help
<f1>
- QuickhelpC-h a
- Apropos - search for a named commandC-h b
- Show key bindingsC-h c
- Describe keybinding brieflyC-h m
- Show modes active in buffer
File operations
C-x C-f
- find fileC-x d
- find file using dired-modeC-x C-w
- write fileC-x C-v
- visit new file
View operations
C-x b
- switch bufferC-x k
- kill bufferC-x 2
- open a new windowC-x o
- switch to other windowC-x 0
- delete selected windowC-x 1
- maximise selected window (deleting the others)C-x 4 0
- delete selected window and current bufferC-x 4 C-f
- find file in other window (creating one if there's only one window)C-x 4 d
- use dired-mode to find file in other windowC-x 4 b
- switch buffer in other windowC-x 4 C-o
- display buffer in other window (keeping current window focused)C-l
- Centre view on current line
Cursor, navigation, search & replace
C-f
orRIGHT
- Move cursor forward one characterM-f
- Move cursor forward one wordC-b
orLEFT
- Move cursor backward one characterM-b
- Move cursor backward one wordC-p
orUP
- Move cursor to previous lineC-n
orDOWN
- Move cursor to next lineM-{
- Go backward a paragraphM-}
- Go forward a paragraphC-v
ornext
(Page Down) - Move cursor forward a screenM-v
orprior
(Page Up) - Move cursor backward a screenC-M-v
- Move cursor forward a screen in other windowC-M-z
- Move cursor backward a screen in other windowC-s
- Incremental searchM-%
- Query replaceM-x replace-string
- Replace all instances of a stringM-x query-replace-regexp
- Query replace matches of a regular expressionM-x replace-regexp
- Replace all matches of a regular expressionM-<
- Go to start of bufferM->
- Go to end of bufferM-g g
orM-g M-g
- Go to line (prompt)M-g c
- Go to char (prompt)C-x =
- Print location of cursor & information about the character at the cursor.C-x r t
- Replace rectangle with string
Deletion and Transposition
M-l
- Lowercase forward wordM-u
- Uppercase forward wordM-c
- Capitalize forward wordC-d
ordeletechar
- Delete forwardsbackspace
- Delete backwardsM-d
- Delete forward wordM-<backspace>
orM-D
(Meta-Shift-D) - delete backward word (M-<deletechar>
does not work due to a fault either in Termbox or my terminal. If it works in your terminal, feel free to bind it.)C-k
- Delete to end of lineM-z
- Zap (delete everything until) given characterM-q
- Fill paragraph or region (justify it to the width of the fill column)M-x fill-region
- Fill regionC-x f
- Set the fill columnC-t
- Transpose (swap) characters at pointM-t
- Transpose (swap) words at point
Region operations
C-@
- Set Mark (C-<space>
also works)C-x C-x
- Swap mark and cursor locationC-w
- Kill (cut) region between mark and cursorM-w
- Copy region between mark and cursorC-y
- Yank (paste) previously copied or killed regionC-x C-u
- Uppercase regionC-x C-l
- Lowercase regionC-x r M-w
- Copy rectangle to clipboardC-x r k
orC-x r C-w
- Kill rectangleC-x r y
- Yank rectangle
Registers
C-x r s
- Save region to registerC-x r i
- Insert saved region or rectangle from registerC-x r C-@
- Save position to registerC-x C-k x
- Save macro to registerC-x r j
- Jump to saved position or run saved macro from registerM-x view-register
- Describe a given registerC-x r r
- Save rectangle to register
Misc
C-x (
- Start recording a macroC-x )
- Stop recording a macroC-x e
- Stop recording a macro and execute it (repeat by pressinge
)C-j
- Insert a newline and indent the new rowC-q
- Interpret the next keystroke literally and insert it (so you can enter escape sequences)C-u
- Universal argumentC-x z
- Repeat previous command - pressz
to repeat againM-x tabify
- Convert spaces to tabs using the tabsize set in the optionsM-x untabify
- Convert tabs to spaces using the tabsize set in the optionsM-~
- Clear the 'modified' flag, as if the buffer was just saved.M-!
- Run shell command (add a universal argument to output to buffer)M-|
- Run shell command on region (add a universal argument to replace region with output)M-/
- Auto-complete
Customization
Emacs loads from ~/.gomacs.lisp on startup and executes the content of this file. Check out the Glisp documentation for information on how the language works! Some functions to get you started…
(emacsbindkey arg1 arg2..)
- Bind arg1 (in standard Emacs C-*/M-* notation, subsequent keypresses space seperated) to the Lisp function or named command arg2. arg1 must be a string; arg2 can be a function or a string. If arg2 is a function, any additional args will be used as its arguments when run.(emacsdefinecmd arg1 arg2..)
- Define a command with name arg1 that runs the function arg2 with any aditional arguments as its arguments. arg1 must be a string; arg2 must be a function.(setsofttab arg)
- Enable (true) or disable (false) the use of soft tabs (spaces for indentation). arg must be a boolean.(settabstop arg)
- Set the width of \t characters in cells. If using soft tabs, this also sets the number of spaces that will be inserted when you press the Tab key. arg must be an integer.(gettabstr)
- returns what the Tab key inserts, either "\t" or some number of spaces.(disablesyntax arg)
- Enable (false) or disable (true) syntax highlighting. arg must be a boolean.(addhook mode func)
- Add a hook functionfunc
to the major modemode
.mode
must be a string;func
must be a function.
Minor Modes
Each buffer has a number of minor modes activated. When a new buffer is opened,
the modes are copied from the "default" set. Modes are added to this set with
the lisp function (adddefaultmode <mode>)
and removed with the function
(remdefaultmode <mode>)
. They can be toggled with the command toggle-mode
,
and you can view the current buffer's activated modes with the show-modes
command. Here's what each mode does:
terminal-title-mode
- use an escape sequence to set the terminal title.line-number-mode
- display line numbers on the left edge of the buffer.auto-indent-mode
- copy indentation from previous line when inserting a newline.auto-fill-mode
- automatically fill (wrap) the current paragraph tofill-column
characters (default 80, change withC-x f
) when inserting a space.tilde-mode
- drawvi
-style blue tildes on lines outside the filexsel-jump-to-cursor-mode
- jump to the mouse cursor position before pasting from the X selection
Why?
I wanted an emacs to run in my terminal when Real Emacs wasn't an option. Other terminal based Emacsen are available, but they each have their problems:
- mg doesn't do unicode.
- uemacs is effectively unmaintained (except for a patch from Torvalds once every few years) and lacks undo.
- godit is good, but not hackable. Furthermore, while I appreciate the "religious" approach in principle, in practice I like being able to customize my editor.
- sandy is too suckless-y. They build good components, but their tools often lack completeness. Plus it doesn't really use Emacs bindings, but emacs-like bindings, ala bash or zsh's "emacs mode". It's also unmaintained.
Furthermore, apart from sandy, none of these editors support syntax highlighting.
Finally, and most importantly, it's a fun project I've always wanted to do ;)
Contributing
I welcome issues and pull requests. I'd love to have a partner or team to work on Gomacs with me.
Gomacs contributors should be (in rough order of importance):
- Kind and reasonable
- Competent with Golang or willing to learn
- Able and willing to chat with or contact me outside of GitHub
- Enthusiastic about improving Gomacs and/or the ersatz-emacs landscape
Credits
Thanks to ixtenu for a lot of code changes and getting me off my ass with this project.
Thanks to nsf for termbox and godit (from which the suspend code comes.)
Thanks to zyedidia and the rest of the micro team for the syntax highlighting code; see the LICENSE file for their full credits + copyright notice.