e
文件大小: unknow
源码售价: 5 个金币 积分规则     积分充值
资源说明:A text editor.
Overview
========

This is the source code for e, a text editor. It's implemented using C++ and
JavaScript (via Google's [V8](http://code.google.com/p/v8/)).

A key feature is that *all* editor functionality is written in JavaScript which
can be extended and customized by the user, without the need to recompile the
binary. There is *zero* editor logic hard coded in C++. There is *zero* editor
logic hard coded in JavaScript. Everything is completely extensible.

How well does it work?
----------------------

It doesn't work very well. There are a lot of rough edges. In theory you can use
it for editing, and it's possible to save buffers. But it's missing a lot of
features that other editors have.

Currently work is being done to make vi mode more functional. Implementing most
of the classic BSD vi functionality (i.e. without vim extensions) is definitely
within sight at this point, and would make the editor a lot more usable.

The project is not yet self-hosting (I'm editing the code in Emacs).

Why JavaScript?
---------------

Love it or hate it, one of the things that makes Emacs a really, really great
editor is that it's not written in C or C++, it's written in elisp. Only the
lowest-level I/O bits are written in C, and exported to elisp code.

This makes Emacs really extensible. The author of e normally uses Emacs, and
runs it using viper-mode, a minor mode that makes Emacs behave like vi. That's
pretty crazy -- using Emacs, you can pretend like you're using vi, but also tap
into this huge millions-of-lines-of-code Emacs elisp ecosystem. The fact that
you can completely customize Emacs down to the lowest level of keyboard handling
to tack on a brand new editing system -- and have it still be fast -- shows the
power of this approach.

That said, if you've written much elisp you know it's not a very good
language. It's very antiquated, and very complicated (and I'm not just saying
that because it's a Lisp -- it's antiquated and complicated compared to pretty
much every other Lisp implementation in wide use today). Elisp also has the
problem that it doesn't have a state-of-the-art bytecode interpreter. This can
make elisp rather slow, particularly when loading new files and while garbage
collections are running.

Editors like [vim](http://www.vim.org/) feel fast and have great editing
capabilities, but are hard to customize. If you've ever tried to really dive
into [vimscript](http://vimdoc.sourceforge.net/htmldoc/usr_41.html) or its
Python bindings you'll recognize that the scripting features feel tacked on and
clunky.

JavaScript solves all (or nearly all of these problems). It's really easy (and
fun!) to use. Tons of people already know how to read, write, and debug
JavaScript. And there are a
[number](https://developer.mozilla.org/en/SpiderMonkey) of
[great](http://www.webkit.org/projects/javascript/index.html) open source
[implementations](http://trac.webkit.org/wiki/SquirrelFish). This project uses
[Google's V8](http://code.google.com/apis/v8/intro.html) implementation of
JavaScript.

The goal of e is to keep the amount of C/C++ code to a minimum, and try to
provide a super-fast ultra-customizable text editor using JavaScript. Out of the
box it will probably look and feel like a lot like [vim](http://www.vim.org/).

Why this project? Why not use Node.js?
--------------------------------------

I think Node.js is a great project. It has I/O capabilities, and there's at
least one curses binding floating around, so there's no reason you couldn't
write the same thing using node.

The main answer is I wanted a project to expand my C++ skills, hence this
project. That said, I think there are some other advantages to a separate V8
embedding for an editor:

* After compiling, you get a real bona-fide binary; you can copy it around on
  different machines if they have the right shared libraries built.
* It's easy to statically link things, creating a stand-alone binary; this makes
  it even easier to copy around and install on different machines.
* The I/O model is a lot simpler (mostly due to doing synchronous I/O).
* You can still do asynchronous I/O if you want; as a matter of fact, behind the
  scenes e is using boost::asio to process keypresses asynchronously (to allow
  various timers to run in the background). Look at the implementation of
  `CursesWindow::Loop` if you want to learn more about this.

What does it look like?
-----------------------

Here's a screenshot. It's not very exciting.

![](http://github.com/eklitzke/e/raw/master/static/hello_from_e.png)

Help! How do I quit?
--------------------

Ctrl-C will always exit the editor.

How do I save files? How do I open new buffers?
-----------------------------------------------

You can save a file with Ctrl-S. There's currently no way to open a new buffer.

How can I customize/configure the editor?
-----------------------------------------

The best way to do this is to add JavaScript code to `~/.e.js`. The way the
editor starts up is that by default it will do the following (in the order
listed):

* load `js/core.js` for an unoptimized build, or the equivalent "bundled"
  JavaScript in an optimized build (see the "Bundled Javascript" section below
  for details).
* load any scripts passed on the command line with `-s` or `--script`
* load `~/.e.js`

Because you can use the `require()` method to include other scripts, you can
structure your own customizations however you like (e.g. by splitting them out
into multiple files).

In general most of the core event loop uses the same
[event](https://developer.mozilla.org/en/DOM/element.addEventListener)
[listener](http://www.w3.org/TR/DOM-Level-2-Events/events.html) pattern as
browsers, which makes it easy to extend/customize behavior in a non-intrusive
way. The various events and listeners that you can use are not well documented,
however.

Javascript API
==============

When running `make`, documentation will be generated at `docs/jsdoc.html`. This
will happen every time the `e` binary is successfully compiled.

Code Layout
===========

C++ code all lives in the `src` directory. The C++ code all passes the checks by
`third_party/cpplint.py` (which you should install as a git hook if you're
hacking on the editor).

JavaScript code (well, ECMAScript really) lives in the `js/` directory.

Third party code, regardless of language or origin, is in the `third_party/`
directory. This also includes some third party "data", such as the terminfo
capabilities file.

Building
========

Read on to get the appropriate instructions for your operating system.

Dependencies
------------

The following are dependencies that *must* be satisified to build the editor:

* [boost](http://www.boost.org/), including the
  [boost::asio](http://www.boost.org/libs/asio) and
  [boost::program_options](http://www.boost.org/libs/program_options) components
* [ncurses](http://www.gnu.org/software/ncurses/) (you probably already have
  this; other curses implementations might work too)
* [V8](http://code.google.com/p/v8/) (built as a shared library)

The following dependencies are optional:

* [libunwind](http://www.nongnu.org/libunwind/)
* [liblzma](http://tukaani.org/xz/) (only needed if you want to build the
  optimized `opt` binary)
* *ncursesw* (the unicode version of curses)
* [tcmalloc](http://goog-perftools.sourceforge.net/doc/tcmalloc.html)

Many of these "optional" dependencies are controlled by `USE_` defines in
`e.gyp`; if you're having problems with an optional dependency, you may find it
useful to take a look at `e.gyp` and tweak it according to your needs.

Bundled Javascript
------------------

For a normal editor build, there will be no "bundled" JavaScript. Instead what
happens is the editor will look for a file named `js/core.js` and load that as
the first script.

For an optimized editor build (i.e. the `opt` binary), the core JavaScript code
will be bundled into the binary. This is done by the script
`scripts/gen_bundled_core.py`. This script will attempt to recursively expand
any `requires()` statements seen in the file `js/core.js`, until it has a single
string representing all of the JavaScript code that might be needed while
running the editor. This JavaScript is then "pre-compiled" by
`scripts/precompile.cc` which uses the public V8 pre-compilation methods, and
additionally compressed using LZMA.

The pre-compilation data and the LZMA compressed core scripts are written out to
`src/bundled_core.h` and `src/bundled_core.cc` and end up included in the final
executable. When the executable starts up, it will decompress the LZMA data and
load the core script.

If you're running an optimized build, and don't want to run the editor with the
bundled JavaScript, invoke it as

    e --debug 

This will implicitly skip loading any bundled javascript, and force `js/core.js`
to be the first JavaScript file loaded, just like in the unoptimized build. The
`--debug` flag is actually a shortcut for, and identical to, running the editor
as

    e --skip-core -s js/core.js

In the future the meaning of `--debug` may expand to give more debugging
information, but that's unlikely to happen until the editor is out of alpha
stage.

Building on Linux
-----------------

You'll need [GYP](http://code.google.com/p/gyp/) installed. You ought to then be
able to simply run `make` to build the project. Internally, this will create a
directory called `build` with a generated `Makefile` from GYP, and then invoking
`make` in the future will run any necessary build scripts and then do a
recursive make using that file. (Note: the file generated by GYP is
`build/Makefile`, the root-level `Makefile` is different.)

To have GYP build your auto-generated `Makefile`, just run `./configure`. This
script will correctly invoke GYP for the project, and report errors if it fails
to run GYP.

If you have any build problems while running `make`, you might want to try
invoking `make` as

    make V=1

which sets verbose build output. This will help you hunt down the exact
compiler/linker errors.

Building on Ubuntu
------------------

Building on Ubuntu, both 11.10 (Oneiric) and 12.04 (Precise), is supported. For
both releases you need to install the following packages:

    sudo apt-get install binutils-gold build-essential git gyp libboost-dev \
      libboost-program-options-dev libboost-system-dev liblzma-dev \
      libncurses5-dev libncursesw5-dev libtcmalloc-minimal0 libunwind7-dev \
      libv8-dev pkg-config python-lzma python-jinja2

Then you will need to set up a `tcmalloc.so` symlink:

    sudo ln -s /usr/lib/libtcmalloc_minimal.so.0 /usr/lib/libtcmalloc.so

After that you should be good to go.

Building on Fedora
------------------

Pretty much the same as Ubuntu, with slightly different packages (not listed
here; inquire if you need assistance). You will also need to manually create a
`tcmalloc.so` symlink, as with Ubuntu. Unfortunately, Ubuntu and Fedora version
the tcmalloc .so files differently, so there's not a straightforward way to
handle this setup automatically.

Building on Mac OS X
--------------------

This should be pretty similar to building on Linux, except that before it will
work someone needs to modify `e.gyp`. It's probably just a matter of instructing
GYP to correctly link things.

Building on Windows
-------------------

This is unlikely to work. There are a fair number of Unix-isms in the code
(although nothing too nasty, they should be fixable by using various Boost
interfaces).

Probably the more difficult thing about this would be getting a working curses
implementation. There seem to be a couple out there but who knows how well they
work.

本源码包内暂不包含可直接显示的源代码文件,请下载源码包。