remacs

Rust ❤️ Emacs
授权协议 GPL-3.0 License
开发语言 C/C++
所属分类 应用工具、 文档/文本编辑
软件类型 开源软件
地区 不详
投 递 者 暨承平
操作系统 跨平台
开源组织
适用人群 未知
 软件概览

Rust ❤️ Emacs

This project isn't maintained anymore. If you are looking for a rust based emacs fork, you can take a look at emacs-ng. However this fork is not about replacing the C code base, but to provide additional features using the rich ecosystem of rust.

A community-driven port of Emacs to Rust.

Table of Contents

Why Emacs?

Emacs will change how you think about programming.

Emacs is totally introspectable. You can always find out 'whatcode runs when I press this button?'.

Emacs is an incremental programming environment. There's noedit-compile-run cycle. There isn't even an edit-run cycle. You canexecute snippets of code and gradually turn them into a finishedproject. There's no distinction between your editor and yourinterpreter.

Emacs is a mutable environment. You can set variables, tweakfunctions with advice, or redefine entire functions. Nothing isoff-limits.

Emacs provides functionality without applications. Rather thanseparate applications, functionality is all integrated into your Emacsinstance. Amazingly, this works. Ever wanted to use the same snippettool for writing C++ classes as well as emails?

Emacs is full of incredible software concepts that haven't hit themainstream yet. For example:

  • Many platforms have a single item clipboard. Emacs has an infiniteclipboard.
  • If you undo a change, and then continue editing, you can't redo theoriginal change. Emacs allows undoing to any historical state, evenallowing tree-based exploration of history.
  • Emacs supports a reverse variable search: you can find variableswith a given value.
  • You can perform structural editing of code, allowing you to makechanges without breaking syntax. This works for lisps (paredit) andnon-lisps (smartparens).
  • Many applications use a modal GUI: for example, you can't do otheredits during a find-and-replace operation. Emacs providesrecursive editing that allow you to suspend what you'recurrently doing, perform other edits, then continue the originaltask.

Emacs has a documentation culture. Emacs includes a usage manual,a lisp programming manual, pervasive docstrings and even aninteractive tutorial.

Emacs has a broad ecosystem. If you want to edit code in aniche language, there's probably an Emacs package for it.

Emacs doesn't have a monopoly on good ideas, and there are other greattools out there. Nonetheless, we believe the Emacs learning curve paysoff.

Why Rust?

Rust is a great alternative to C.

Rust has a fantastic learning curve. The documentation is superb,and the community is very helpful if you get stuck.

Rust has excellent tooling. The compiler makes great suggestions,the unit test framework is good, and rustfmt helps ensure formattingis beautiful and consistent.

The Rust packaging story is excellent. It's easy to reusethe great libraries available, and just as easy to factor out code forthe benefit of others. We can replace entire C files in Emacs withwell-maintained Rust libraries.

Code written in Rust easily interoperates with C. This means wecan port to Rust incrementally, and having a working Emacs at eachstep of the process.

Rust provides many compile-time checks, making it much easier to writefast, correct code (even when using multithreading). This also makesit much easier for newcomers to contribute.

Give it a try. We think you'll like it.

Why A Fork?

Emacs is a widely used tool with a long history, broad platformsupport and strong backward compatibility requirements. The core teamis understandably cautious in making far-reaching changes.

Forking is a longstanding tradition in the Emacs community for tryingdifferent approaches. Notable Emacs forks include XEmacs,Guile Emacs,and emacs-jit.

There have also been separate elisp implementations, such asDeuce,JEmacs andEl Compilador.

By forking, we can explore new development approaches. We canuse a pull request workflow with integrated CI.

We can drop legacy platforms and compilers. Remacs will never runon MS-DOS, and that's OK.

There's a difference between the idea of Emacs and the currentimplementation of Emacs. Forking allows us to explore being evenmore Emacs-y.

Getting Started

Requirements

  1. You will needRust installed.The file rust-toolchain indicates the version that gets installed.This happens automatically, so don't override the toolchain manually.IMPORTANT: Whenever the toolchain updates, you have to reinstallrustfmt manually.

  2. You will need a C compiler and toolchain. On Linux, you can dosomething like:

     apt install build-essential automake clang libclang-dev
    

    On macOS, you'll need Xcode.

  3. Linux:

     apt install texinfo libjpeg-dev libtiff-dev \
       libgif-dev libxpm-dev libgtk-3-dev gnutls-dev \
       libncurses5-dev libxml2-dev libxt-dev
    

    macOS:

     brew install gnutls texinfo autoconf
    

    To use the installed version of makeinfo instead of the built-in(/usr/bin/makeinfo) one, you'll need to make sure /usr/local/opt/texinfo/binis before /usr/bin in PATH.Mojave install libxml2 headers with: open /Library/Developer/CommandLineTools/Packages/macOS_SDK_headers_for_macOS_10.14.pkg

Dockerized development environment

If you don't want to bother with the above setup you can use theprovided Docker environment. Make sure you havedocker 1.12+ anddocker-compose 1.8+ available.

To spin up the environment run

docker-compose up -d

The first time you run this command, Docker will build the image. Afterthat any subsequent startups will happen in less than a second. Ifthis command fails because of needing absolute paths, make sure to setthe PWD environment variable before calling the command like so:

PWD=$(pwd) docker-compose up -d

The working directory with remacs will be mounted under the same pathin the container so editing the files on your host machine willautomatically be reflected inside the container. To build remacs usethe steps from Building Remacs prefixed withdocker-compose exec remacs, this will ensure the commands areexecuted inside the container.

Building Remacs

$ ./autogen.sh
$ ./configure --enable-rust-debug
$ make

For a release build, don't pass --enable-rust-debug.

The Makefile obeys cargo's RUSTFLAGS variable and additional optionscan be passed to cargo with CARGO_FLAGS.

For example:

$ make CARGO_FLAGS="-vv" RUSTFLAGS="-Zunstable-options --cfg MARKER_DEBUG"

Running Remacs

You can now run your shiny new Remacs build!

# Using -q to ignore your .emacs.d, so Remacs starts up quickly.
# RUST_BACKTRACE is optional, but useful if your instance crashes.
$ RUST_BACKTRACE=1 src/remacs -q

Design Goals

Compatibility: Remacs should not break existing elisp code, andideally provide the same FFI too.

Leverage Rust itself: Remacs should make best use of Rust toensure code is robust and performant.

Leverage the Rust ecosystem: Remacs should use existing Rustcrates wherever possible, and create new, separate crates where ourcode could benefit others.

Great docs: Emacs has excellent documentation, Remacs should be nodifferent.

Progress

At this point we focus on porting lisp functions from C to Rust.Currently there are 642 functions in Rust and 823 in C (May 2019).

We have a progress section in our wikiand there's also a list of long-term goalsunder projects.

Porting Elisp Primitive Functions

The first thing to look at is the C implementation for the atanfunction. It takes an optional second argument, which makes itinteresting. The complicated mathematical bits, on the other hand, arehandled by the standard library. This allows us to focus on theporting process without getting distracted by the math.

The Lisp values we are given as arguments are tagged pointers; in thiscase they are pointers to doubles. The code has to check the tag andfollow the pointer to retrieve the real values. Note that this codeinvokes a C macro (called DEFUN) that reduces some of theboilerplate. The macro declares a static variable called Satan thatholds the metadata the Lisp compiler will need in order tosuccessfully call this function, such as the docstring and the pointerto the Fatan function, which is what the C implementation is named:

DEFUN ("atan", Fatan, Satan, 1, 2, 0,
       doc: /* Return the inverse tangent of the arguments.
If only one argument Y is given, return the inverse tangent of Y.
If two arguments Y and X are given, return the inverse tangent of Y
divided by X, i.e. the angle in radians between the vector (X, Y)
and the x-axis.  */)
  (Lisp_Object y, Lisp_Object x)
{
  double d = extract_float (y);
  if (NILP (x))
    d = atan (d);
  else
    {
      double d2 = extract_float (x);
      d = atan2 (d, d2);
    }
  return make_float (d);
}

extract_float checks the tag (signalling an "invalid argument" errorif it's not the tag for a double), and returns the actualvalue. NILP checks to see if the tag indicates that this is a nullvalue, indicating that the user didn't supply a second argument atall.

Next take a look at the current Rust implementation. It must also takean optional argument, and it also invokes a (Rust) macro to reduce theboilerplate of declaring the static data for the function. However, italso takes care of all of the type conversions and checks that we needto do in order to handle the arguments and return value:

/// Return the inverse tangent of the arguments.
/// If only one argument Y is given, return the inverse tangent of Y.
/// If two arguments Y and X are given, return the inverse tangent of Y
/// divided by X, i.e. the angle in radians between the vector (X, Y)
/// and the x-axis
#[lisp_fn(min = "1")]
pub fn atan(y: EmacsDouble, x: Option<EmacsDouble>) -> EmacsDouble {
    match x {
        None => y.atan(),
        Some(x) => y.atan2(x)
    }
}

You can see that we don't have to check to see if our arguments are ofthe correct type, the code generated by the lisp_fn macro does thisfor us. We also asked for the second argument to be anOption<EmacsDouble>. This is the Rust type for a value which iseither a valid double or isn't specified at all. We use a matchstatement to handle both cases.

This code is so much better that it's hard to believe just how simplethe implementation of the macro is. It just calls .into() on thearguments and the return value; the compiler does the rest when itdispatches this method call to the correct implementation.

Contributing

Pull requests welcome, no copyright assignment required. This project is under theRust code of conduct.

There's lots to do! We keep a list oflow hanging fruithere so you can easily choose one. You can find information in thePorting cookbookor ask for help in our Gitter channel.

 相关资料
  • Reply 是一个电子邮件 App ,使用 Material Design 组件和 Material Theming 来创建品牌化的通讯体验。 该项目旨在发布一个基于 Reply Material Design Case Study in Flutter 完美像素体验的演示项目。主要聚焦于 UI 层面,包括动画、布局和页面转换等。 用来展示 Flutter 作为一个 UI 框架的强大功能。

  • 问题内容: 在emacs中,当我键入: 它的标签如下: 我宁愿不这样做,而只是像其他行继续一样对齐参数。我如何配置它不这样做? 问题答案: 这来自Emacs CC模式的信息手册,该手册在Windows上使用GNU Emacs 23.1: 开始构建缩进不正确的Java类。就您而言,正是您在上面输入的内容。 将光标移到缩进不正确的行的开头。在您的情况下,为“字符串二){”。 点击Cc Cs()询问Em

  • 本文向大家介绍emacs Prelude,包括了emacs Prelude的使用技巧和注意事项,需要的朋友参考一下 示例 Prelude是另一种流行的入门工具包。它具有对各种开箱即用的编程语言的良好支持,尤其是clojure。在* nix系统上,可以使用以下命令进行安装:            

  • 本文向大家介绍emacs-live,包括了emacs-live的使用技巧和注意事项,需要的朋友参考一下 示例 emacs-live是另一种流行的emacs入门套件,另外还重点关注使用泛音进行的现场音乐编码。 您可以通过两种方式安装它: 在* nix(例如Linux,OSX等)系统上,在命令行上运行以下命令: bash <(curl -fksSL https://raw.github.com/ove

  • 本文向大家介绍emacs 使用Cask进行自动包装管理,包括了emacs 使用Cask进行自动包装管理的使用技巧和注意事项,需要的朋友参考一下 示例 Cask是一个项目管理工具,也可以用于轻松管理本地emacs配置。 安装桶很容易。您可以在命令行上运行以下命令: 或者,如果您使用的是Mac,则可以使用进行安装homebrew: 安装后,您将创建一个Cask文件。木桶文件列出了应包含在您的配置中的所

  • 本文向大家介绍emacs 退出Emacs,包括了emacs 退出Emacs的使用技巧和注意事项,需要的朋友参考一下 示例 您可以使用以下快捷键退出Emacs: C-x C-c 哪里C是control关键。 挂起Emacs 您可以使用以下按键绑定来挂起Emacs: C-z 它使您回到外壳。如果要恢复emacs会话,请fg在终端中输入。

  • 本文向大家介绍emacs 文件处理,包括了emacs 文件处理的使用技巧和注意事项,需要的朋友参考一下 示例 用相同的文件名重新保存打开的文件(保存): C-x C-s 写为filename(另存为): C-x C-wfilename 新文件名将在迷你缓冲区中提示。   创建新文件或加载现有文件(新建/加载): C-x C-ffilename 这里的助记符为f表示文件。系统将提示您在迷你缓冲区中输

  • 本文向大家介绍emacs 中止当前命令,包括了emacs 中止当前命令的使用技巧和注意事项,需要的朋友参考一下 示例 通常,您会进入一种状态,其中正在进行部分键入的命令序列,但是您想中止它。您可以使用以下任一键绑定中止它: C-g EscEscEsc