Yi is a text editor written and extensible in Haskell. The goal of Yi is to provide a flexible, powerful and correct editor core dynamically scriptable in Haskell.
- Yi is an haskell interpreter. Very much like emacs is a Lisp interpreter, this makes really easy to dynamically hack, experiment and modify Yi. All tools and goodies written in haskell are also readily available from the editor. This is implemented by binding to the GHC api.
- Frontends. Yi can use either gtk2hs or vty as frontends, so users can choose their favourite interface.
- "Emulation modes". The primary emulation modes for Yi are vim and emacs. Keybindings for vi, mg and nano and other are also provided. Other editor interfaces can be written by the user to extend Yi.
The long term goal of the project is to make Yi the editor of choice for the haskell hacker.
The main short term goal is to maximize Yi's Fun Factor. This includes:
- improve hackability (and therefore architecture)
- add cool features
former Yi homepage: http://www.cse.unsw.edu.au/~dons/yi.html
2 Get Yi
Stable release on Hackage:
- (NOTE: the 0.2 release does not work with recent versions of GHC/libraries, and is not supported at all. Please use the darcs repo version instead.)
darcs get --partial http://code.haskell.org/yi/
We try to keep the repository in a clean and buildable state, so it's "testable". If you have Darcs installed and a GHC 6.8.x installation, this is a better choice.
3 Screenshots (0.3)
(Recent items first)
- 'sdist' functionality
- Haddocked API
- Reverse incremental search
- "rope-like" structure for buffer (eg. for reading/editing huge log files)
- Experimental Cocoa frontend (OS X)
- More functionality of emacs/vim implemented
- Andy wrote a nice Yi tutorial: http://nobugs.org/developer/yi/index.html
- Yi is now hosted on code.haskell.org/yi
- Further simplify build process
- Simplify creation of keybindings; More powerful combinators.
- Tons of fixes
- Support for templates
- Syntax hilight modes for Cabal & C++
- GHC 6.8 support (and Yi is ever easier to build)
- word completion infrastructure
- vim: more window commands implemented
- Very important architectural cleanups (07:07, 15 July 2007 (UTC)):
- Buffer implementation is purely functional
- IO monad is only found at the toplevel (buffer-only and editor-only actions do not rely on IO)
- Window management is frontend independent
- Factored indent-code across keymaps
- All dependency cycles removed (makes for an easier understanding of the code)
- C-code removed from Yi
- Dynamic selection of frontend
- Cleaned up the multiple package mess
- Console buffer (old news)
- Common buffer backend (across all frontends) (15:08, 2 June 2007 (UTC))
- Overlays (thanks Ben Moseley)
- per-buffer extensible state (11:44, 28 May 2007 (UTC))
- Synchronous keymaps: the behaviour of the keymap (ie. the underlying parser) can depend on the editor state.
- Full-dynamic Yi
- it's now possible to change any part of the Yi codebase and see the result with a mere 'M-x reconfigE' (take that, Steve Yegge :))
- Yi is now hosted on darcs.haskell.org/yi
- Dired mode (thanks Ben Moseley)
- Yi 0.2 released!
- Buffer-specific code is now contained in BufferM monad
- Multiple marks per buffer
- All keymaps use a unified mechanism! (and are therefore potentially composable)
- Miniwindows for vty frontend
- Miniwindows for GTK frontend
- Basic support for query-replace (emacs)
- Rudimentary support for indentation
- Syntax highlighting in GTK frontend
- Completion for file names
- Incremental search (emacs)
- Completion for M-x, and buffer switch.
- History for emacs mode minibuffer
- New commands and keybindings can be defined easily and dynamically
- Yi is an haskell interpreter!
- Possibility to run editor actions interactively (similar to emacs M-x)
- Configuration is just a haskell module exporting (yiMain :: Action)
- Possibility to evaluate haskell expressions interactively.
- New, unified way to define Keybindings
- Vty frontend supports Haskell (lexical) syntax highlighting (thanks Stefan O'Rear)
- GTK frontend works in Win32
- GTK frontend (in addition of Vty frontend) (requires gtk>=0.9.10.4)
- Linewrap support
- Bugfixes in scrolling
- Lots of simplifications in the cursor management
- Keymaps can now process typed events instead of Chars (no extra decode step)
- Yi.Debug added for debugging
- Vty frontend replaces Curses frontend
Check/report bug reports here: Google Code: yi-editor
- On Mac OS X if you get an error message similar to this:
yi: can't load .so/.DLL for: gthread-2.0 (dlopen(libgthread-2.0.dylib, 10): image not found)
- then your dynamic library search path variable is probably not set correctly. You can set it (in bash) using:
- (Adjust the specific path to your system. You can find the right location using locate libgthread)
- ByteString problems: Yi as of 27 January 2008 cannot use the most recent ByteString library (because of the regexp libraries) which is 0.9.0.4 - it needs a version like 0.9 or 0.9.0.1. You may have the correct ByteString library installed, but still see an error like:
Couldn't match expected type
against inferred type `B.ByteString'
In the second argument of `renderBS', namely `(B.pack str)'
In the expression: renderBS (styleToAttr sty) (B.pack str)
In the definition of `withStyle':
withStyle sty str = renderBS (styleToAttr sty) (B.pack str)
- This is because versions of ByteString often aren't compatible, and in this case, the VTY library was compiled with a different version.
6 How to Configure Yi
You can find configuration file examples in the 'examples/' directory, or online at http://code.haskell.org/yi/examples/.
A good way to start is to copy YiConfig.hs in your ~/.yi directory (create it if needed), and hack as needed.
To run the GTK frontend:
- version > 0.2: use the "-f gtk" option
- version 0.2: install and expose the yi-gtk package
Get the repo here:
darcs get --partial http://code.haskell.org/yi/
Work on whatever you please, patches are always welcome. :)
Otherwise, see the complete list of open issues here: http://code.google.com/p/yi-editor/issues/list
(Note you can start working on all issues in New/Accepted state, regardless of the owner of the issue. -- just send an email to the list with your plan)
Post your questions and follow up on the mailing list: http://groups.google.com/group/yi-devel
Some other pending tasks are described below.
7.1 Write access policy
One does not need write access to the repository to contribute. Use "darcs send" to send your patches to the Yi development mailing list; someone else can apply them.
Write access can however be granted, with the following disclaimer:
- All people with write access can apply patches without prior approval. If one thinks a patch would be controversial, it might be a good idea to discuss it on the list though.
- Try to not break the build. (By Murphy's law, if you do so it will happen at the most annoying moment...) So, always try to build before pushing patches. Bypassing Darcs's test build to record a patch indicates you should further improve your patch.
- I can at any time rollback a patch for whatever reason. This however should not upset the author of the patch. Most contributions are welcome, so a patch revert normally would only mean that a detail or two need to be worked out. (eg. it breaks an important feature in some configuration, etc.)
8 Yi ideas
This section is meant to gather ideas people have for Yi.
Coming from an Emacs background, I think a few things are essential, mainly the introspection capabilities of Emacs.
8.1.1 Emacs goodness
The following are things I like about Emacs, as an extensible environment, and miss in Yi:
- Really good online documentation
- Emacs can tell you a lot about a function or variable with a keypress--- the current value, where it is declared, and a hypertext formation string
- All (good) apps allow users to extend, through, e.g., hooks --- a list of functions that are run before/after some event (like saving a file)
8.1.2 Emacs badness
So, why replace it?:
- Dynamically scoped, Dynamically typed, ugly, old. 'Nuff said
- What's a Parser?
- A lot of apps in emacs do stuff with text, usually text that is in some language. There is no standard parser (like, e.g. parsec), so a lot of it is ugly handwritten spaghetti. This also means that adding analysis tools isn't really done (or done nicely).
- ELisp again
- Haskell is a lot cleaner to write, especially because of the large number of libraries.
(See also WhyDoesElispSuck on the Emacs wiki.)
8.1.3 Emacs maybeness (?)
Some things that are sometimes bad, sometimes good:
- Everything is a buffer
- Makes some sense, but sometimes doesn't. It is nice to have uniform key bindings do the right thing (e.g., C-Space sets the mark, and the region can then be used, e.g. to delete a sequence of emails in Wl) Sometimes, however, you just want some sort of GUI widget.
- OTOH, having the minibuffer be a special kind of buffer is a good idea.
- It is possible to associate arbitrary properties with symbols. This means you can annotate a symbol and then use that information at a later date
- good things
- modal key editing
- light weight - fast startup
8.3 Be yourself
Take some ideas from emacs, some from vi, but don't stick them all together without a single core philosophy. Otherwise, you'll end up with an editor that looks like it was thrown together. Some people come from an emacs background, some from vi, some from elsewhere, and ALL of them will want yi to behave like their regular editor. The best way to do this is to have a single person make all the decisions on behaviour.
- An extension to GHCi to support documentation of symbols.
- This seems to be (reasonably) straightforward, as GHCi already has :info. It would mean hacking the type environment (what about values?) to add documentation information. The main problem would seem to be populating this --- maybe hack haddock to produce something from the library docs? I assume that using package GHC uses the parent RTS (package GHC seems to be the way to go, but more investigation is required --- don?)
- Views on data
- Rather than just editing a file, you would open a view onto the file, i.e. there is no longer a 1-1 correspondence between buffers and files. Why? Well, for aggregate buffers (i.e., editing multiple files in the one view), or for multiple views of a file (e.g. AST and source-level). There would be some primitive ops for editing a buffer (insertChar, delete, etc.), which would then call update functions on anything observing that file.
- Remote attach so I can work from home, but still use a remote machine
- Like Emacs's server?
- Haddock documentation
- (no brainer), maybe associate with .hi files for binaries.
- A class
PromptingRead) which allows the user to
invoke a function similar to M-x in Emacs, but without requiring (interactive)
- This means that given
f :: String -> Int -> Action,
(makeInteractive f) :: Actionwould prompt the user for a String then an Int and run the corresponding action.
- Maybe a class
YiShow, which all config items must be a member of? This is to emulate describe-variable
- Support for collaborative editing. This would be very good for #haskell work, and the text editor Gobby and its Obby protocol seem to provide a candidate way of doing things.
- Per mode/file/buffer/whatever Monads, or reload/recompile? Or some hybrid? How does this interact with the documentation aspects? Do we want to have separate sorts of symbols a la emacs (describe-function, describe-variable), or is everything a function? I would think that configuration info doesn't change that frequently --- is this globally true though?
- We can probably use a GHCi-like "let". Rebinding a function would then be synonym to assign a variable, thereby achieve unification between functions and variables.
- Also possible: use something similar to the GHCi debugger to "tune" the behavior of some functions.
- Interface to the runtime
- The scheduler, docs, etc.
- Introspection of e.g. what processes are running.
- There are already libraries in Haskell for processes, but they don't give Yi any extra information --- we really want a layer on top.
Sjw 09:15, 2 June 2006 (UTC)