diff --git a/.cirrus.yml b/.cirrus.yml
new file mode 100644
index 000000000..19bd97c70
--- /dev/null
+++ b/.cirrus.yml
@@ -0,0 +1,35 @@
+env:
+ CARGO_HOME: /tmp/cargo
+
+task:
+ matrix:
+ - install_cmake_script: apt-get update && apt-get install -y cmake
+ matrix:
+ - name: test (linux)
+ container:
+ image: rust:latest
+ cpu: 4
+ memory: 8G
+ - name: test (linux nightly)
+ allow_failures: true
+ container:
+ image: rustlang/rust:nightly
+ cpu: 4
+ memory: 8G
+ - osx_instance:
+ image: high-sierra-xcode-9.4
+ env:
+ PATH: $PATH:$CARGO_HOME/bin
+ install_cmake_script: brew install cmake
+ matrix:
+ - name: test (macOS)
+ install_rust_script: curl https://sh.rustup.rs -sSf | sh -s -- -y
+ - name: test (macOS nightly)
+ allow_failures: true
+ install_rust_script: curl https://sh.rustup.rs -sSf | sh -s -- -y --default-toolchain nightly
+ cargo_cache:
+ folder: $CARGO_HOME/registry
+ fingerprint_script: cat rust/Cargo.lock
+ build_script: cd rust && cargo build --verbose --all --jobs 4
+ test_script: cd rust && cargo test --verbose --all --jobs 4
+ before_cache_script: rm -rf $CARGO_HOME/registry/index
\ No newline at end of file
diff --git a/CONTRIBUTING.md b/.github/CONTRIBUTING.md
similarity index 98%
rename from CONTRIBUTING.md
rename to .github/CONTRIBUTING.md
index ae83ab777..a6595e5bb 100644
--- a/CONTRIBUTING.md
+++ b/.github/CONTRIBUTING.md
@@ -11,14 +11,17 @@ follow the [Code of Conduct](https://github.com/xi-editor/xi-editor/blob/master/
- [Improving and reviewing docs](#improving-and-reviewing-docs)
- [Reviewing and testing changes](#reviewing-and-testing-changes)
- [Proposing and making changes](#proposing-and-making-changes)
- - [Finding something to work on](#finding-something-to-work-on)
+ - [Finding something to work on](#finding-something-to-work-on)
- [Before you start](#before-you-start-work)
- [Before you open your PR](#before-you-open-your-pr)
- [Review process](#review-process)
+ - [After submitting your change](#after-submitting-your-change)
- [Getting more involved](#getting-more-involved)
## Getting started
+### Very first steps
+
Not sure where to start? If you haven't already, take a look at the
[docs](http://xi-editor.github.io/xi-editor/docs.html) to get a better
sense of the project. Read through some issues and some open PRs, to
diff --git a/.github/ISSUE_TEMPLATE.md b/.github/ISSUE_TEMPLATE.md
new file mode 100644
index 000000000..81d320a74
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE.md
@@ -0,0 +1,35 @@
+# Xi-Editor Issue Template
+- [ ] I have searched existing issues and could not find my issue.
+- [ ] I have studied the documentation.
+
+
+## Details
+
+_If your issue is a build or runtime error, please include the following:_
+- OS / platform (e.g. macOS 10.13.2)
+- rust compiler version (`rustc --version`) (we test against the latest
+ stable release)
+- rust compiler installation method (e.g. rustup, homebrew, source)
+- the frontend you're using, if applicable
+- the commit you're on, if building from source (`#3a2405b`)
+- a full backtrace or error message, if available
+
+## Expected vs Actual
+When describing an issue, it is very helpful to first describe expected behavior, followed by the actual functionality. See the following example:
+
+_Note that backticks can be used to escape code both inline and in blocks._
+
+
+ Expected `xi-core -v` to provide version.
+ ```
+ $ xi-core -v
+ xi-core 0.2.0
+ ```
+
+ Actual: xi-core skips printing out the version and starts taking input
+ ```
+ $ xi-core -v
+ <-------- xi-core waits on input there
+ ```
diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 000000000..f8356ab5c
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,42 @@
+
+## Summary
+Example: `Add a pull request template. This will make it easier for newcomers to contribute to the project with confidence.`
+
+
+
+
+## Related Issues
+Example: `Related to #1`
+
+
+Example: `closes #2`
+
+
+## Checklist
+Example:
+
+- [ ] Example check-list item
+- [x] Create a pull request template
+- [ ] make xi perfect
+
+## Review Checklist
+
+- [ ] I have responded to reviews and made changes where appropriate.
+- [ ] I have tested the code with `cargo test --all` / `./rust/run_all_checks`.
+- [ ] I have updated comments / documentation related to the changes I made.
+- [ ] I have rebased my PR branch onto xi-editor/master.
diff --git a/.travis.yml b/.travis.yml
index 730680f10..7840de071 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -8,11 +8,18 @@ rust:
os:
- linux
- osx
+ - windows
matrix:
allow_failures:
- rust: nightly
+ - os: windows
+# on windows, rustup installs the msvc toolchain by default so we need link.exe
+before_script:
+ - if [ "$TRAVIS_OS_NAME" = 'windows' ]; then choco install windows-sdk-10.0; fi
+
+# windows builds run in git bash so these (should) Just Work
cache:
directories:
- $HOME/.cargo
diff --git a/AUTHORS b/AUTHORS
index 2d4381725..0c781f69b 100644
--- a/AUTHORS
+++ b/AUTHORS
@@ -12,3 +12,5 @@ Pranjal Paliwal
Araz Abishov
Lê Viết Hoàng Dũng
Markus Ast
+Raph Levien
+Hilmar Gústafsson
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
deleted file mode 100644
index 61e8dd334..000000000
--- a/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,8 +0,0 @@
-_If your issue is a build or runtime error, please include the following:_
-- OS / platform (e.g. macOS 10.13.2)
-- rust compiler version (`rustc --version`) (we test against the latest
- stable release)
-- rust compiler installation method (e.g. rustup, homebrew, source)
-- the frontend you're using, if applicable
-- the commit you're on, if building from source (`#3a2405b`)
-- a full backtrace or error message, if available
diff --git a/README.md b/README.md
index 4db3d6e1a..edb5754a2 100644
--- a/README.md
+++ b/README.md
@@ -1,13 +1,15 @@
-The xi editor project is an attempt to build a high quality text editor,
+***Note:*** *This is repo contains only the editor core, which is not usable on its own. For editors based on it, check out the list in [Frontends](#frontends).*
+
+The xi-editor project is an attempt to build a high quality text editor,
using modern software engineering techniques. It is initially built for
Mac OS X, using Cocoa for the user interface. There are also frontends for
other operating systems available from third-party developers.
@@ -27,36 +29,40 @@ Goals include:
* ***Developer friendliness***. It should be easy to customize xi editor, whether
by adding plug-ins or hacking on the core.
-Please refer to the [November 2017 roadmap](https://github.com/google/xi-editor/issues/437)
-to learn more about planned features.
+**Learn more** with the creator of Xi, Raph Levien, in this [Recurse Center Localhost talk](https://www.recurse.com/events/localhost-raph-levien
+).
Screenshot (will need to be updated as syntax coloring and UI polish is added):
-![xi screenshot](/docs/docs/img/xi-mac-screenshot.png?raw=true)
+![xi-mac screenshot](/docs/docs/img/xi-mac-screenshot.png?raw=true)
+
## Getting started
This repository is the core only. You'll also need a front-end, from the list
below.
+
### Building the core
-Xi targets 'recent stable Rust'. We recommend installing via [rustup](https://www.rustup.rs).
+Xi-editor targets 'recent stable Rust'. We recommend installing via [rustup](https://www.rustup.rs).
The current minimum supported version is 1.28.
-To build the xi editor from the root directory of this repo:
+To build the xi-editor core from the root directory of this repo:
```
> cd rust
> cargo build
```
-Here are some other front-ends in various stages of development:
-* [xi-mac](https://github.com/google/xi-mac), the official macOS front-end.
+## Frontends
+
+Here are some front-ends in various stages of development:
-* [fuchsia/xi](https://fuchsia.googlesource.com/topaz/+/master/bin/xi/), a front-end in Flutter for Fuchsia,
-and might work on other Flutter targets.
+* [xi-mac](https://github.com/xi-editor/xi-mac), the official macOS front-end.
+
+* [fuchsia/xi](https://fuchsia.googlesource.com/topaz/+/master/bin/xi/), a front-end in Flutter for Fuchsia.
* [xi-gtk](https://github.com/eyelash/xi-gtk), a GTK+ front-end.
@@ -66,7 +72,7 @@ and might work on other Flutter targets.
* [gxi](https://github.com/bvinc/gxi), a GTK+ front-end written in Rust.
-* [xi-win](https://github.com/google/xi-win), an experimental Windows front-end written in Rust.
+* [xi-win](https://github.com/xi-editor/xi-win), an experimental Windows front-end written in Rust.
* [kod](https://github.com/linde12/kod), a terminal frontend written in Golang.
@@ -87,6 +93,7 @@ documentation at this point) on the protocol at
[frontend.md](https://xi-editor.github.io/xi-editor/docs/frontend-protocol.html). If you're working on a front-end, feel free to
send a PR to add it to the above list.
+
## Design decisions
Here are some of the design decisions, and motivation why they should
@@ -132,6 +139,7 @@ contribute to the above goals:
languages, and there are plenty of the libraries available for the other
ones.
+
## Current status
This is still a project in its early stages. The Mac build has basic editing
@@ -140,21 +148,24 @@ is still missing essentials such as auto-indent. At the moment, it’s expected
that its main community will be developers interested in hacking on a text
editor.
+
## Authors
-The main author is Raph Levien.
+The xi-editor project was started by Raph Levien but has since received
+contributions from a number of other people. See the [AUTHORS](AUTHORS)
+file for details.
+
+
+## License
+
+This project is licensed under the Apache 2 [license](LICENSE).
+
## Contributions
-We gladly accept contributions via GitHub pull requests, as long as the author
-has signed the Google Contributor License. Please see
-[CONTRIBUTING.md](CONTRIBUTING.md) for more details.
+We gladly accept contributions via GitHub pull requests. Please see
+[CONTRIBUTING.md](.github/CONTRIBUTING.md) for more details.
If you are interested in contributing but not sure where to start, there is
an active IRC channel at #xi on irc.mozilla.org. There is also a subreddit at
[/r/xi_editor](https://www.reddit.com/r/xi_editor/).
-
-### Disclaimer
-
-This is not an official Google product (experimental or otherwise), it
-is just code that happens to be owned by Google.
diff --git a/docs/contribute.md b/docs/contribute.md
index 82b881f3f..5998917d6 100644
--- a/docs/contribute.md
+++ b/docs/contribute.md
@@ -6,25 +6,220 @@ site_nav_category_order: 400
is_site_nav_category: true
---
-Want to contribute? Great! First, read this page (including the small print at the end).
+The xi-editor project is committed to fostering and preserving a
+diverse, welcoming community; all participants are expected to
+follow the [Code of Conduct](https://github.com/xi-editor/xi-editor/blob/master/CODE_OF_CONDUCT.md).
-### Before you contribute
-Before we can use your code, you must sign the [Google Individual Contributor License Agreement](https://developers.google.com/open-source/cla/individual?csw=1) (CLA), which you can do online. The CLA is necessary mainly because you own the copyright to your changes, even after your contribution becomes part of our codebase, so we need your permission to use and distribute your code. We also need to be sure of various other things—for instance that you'll tell us if you know that your code infringes on other people's patents. You don't have to sign the CLA until after you've submitted your code for review and a member has approved it, but you must do it before we can put your code into our codebase. Before you start working on a larger contribution, you should get in touch with us first through the issue tracker with your idea so that we can help out and possibly guide you. Coordinating up front makes it much easier to avoid frustration later on.
+- [Getting Started](#getting-started)
+ - [Very first steps](#very-first-steps)
+ - [Opening issues](#opening-issues)
+ - [Participating in discussions](#participating-in-discussions)
+ - [Improving and reviewing docs](#improving-and-reviewing-docs)
+ - [Reviewing and testing changes](#reviewing-and-testing-changes)
+- [Proposing and making changes](#proposing-and-making-changes)
+ - [Finding something to work on](#finding-something-to-work-on)
+ - [Before you start](#before-you-start-work)
+ - [Before you open your PR](#before-you-open-your-pr)
+ - [Review process](#review-process)
+ - [After submitting your change](#after-submitting-your-change)
+- [Getting more involved](#getting-more-involved)
-### Code reviews
-All submissions, including submissions by project members, require review. We use Github pull requests for this purpose.
+## Getting started
-After a demonstrated record of contribution and understanding of the code base, we grant collaborator access, at our discretion. Collaborators have write access, subject to the following rules:
+### Very first steps
-* Managing issues and merging trivial PR's (comments, doc fixes, etc) are fine.
-* A Google-employed project member should approve all nontrivial PR's by non-Googlers.
-* We wait for CI to be green, unless there is a really compelling reason.
-* If the PR author has commit privs, then they should merge after approval (this
- gives the author a chance to make last-minute fixes). Otherwise, the approver
- generally merges.
+Not sure where to start? If you haven't already, take a look at the
+[docs](http://xi-editor.github.io/xi-editor/docs.html) to get a better
+sense of the project. Read through some issues and some open PRs, to
+get a sense for the habits of existing contributors. Drop by the #xi
+channel on [irc.mozilla.org](https://mozilla.logbot.info/xi) to follow
+ongoing discussions or ask questions. Clone the repos you're
+interested in, and make sure you can build and run the tests. If you
+can't, open an issue, and someone will try to help. Once you're up and
+running, there are a a number of ways to participate:
-### Code of conduct
-We are committed to preserving and fostering a diverse, welcoming community. This project follows the [Fuchsia Code of Conduct](https://fuchsia.googlesource.com/docs/+/master/CODE_OF_CONDUCT.md).
+### Opening issues
-### The small print
-Contributions made by corporations are covered by a different agreement than the one above, the Software Grant and Corporate Contributor License Agreement.
+If you have a question or a feature request or think you've found a bug,
+please open an issue. When opening an issue, include any details that
+might be relevant: for a bug this might be the steps required to
+reproduce; for a feature request it might be a detailed explanation of
+the behaviour you are imagining, an outline of how it would be used,
+and/or examples of how this feature is used in other editors.
+
+#### Before you open an issue
+
+Before opening an issue, **try to identify where the issue belongs**.
+Is it a problem with the frontend or with core? The frontend is
+responsible for drawing windows and UI, and handling events; the core
+is responsible for most everything else. Issues with the frontend
+should be opened in that frontend's repository, and issues with
+core should be opened in the
+[xi-editor](https://github.com/xi-editor/xi-editor/issues) repo.
+
+Finally, before opening an issue, **use github's search bar** to make
+sure there isn't an existing (open or closed) issue for your particular
+problem.
+
+### Participating in discussions
+
+An _explicit_ goal of xi-editor is to be an educational resource.
+Everyone is encouraged to participate in discussion issues (issues with
+the 'discussion' or 'planning' labels), and we expect people
+participating in discussions to be respectful of the fact that we all
+have different backgrounds and levels of experience. Similarly, if
+something is confusing, feel free to ask for clarification! If you're
+confused, other people probably are as well.
+
+### Improving and reviewing docs
+
+If the docs are unclear or incomplete, please open an issue or a PR to
+improve them. This is an especially valuable form of feedback from new
+contributors, who are seeing things for the first time, and will be best
+positioned to identify areas that need improvement.
+
+### Reviewing and testing changes
+
+One of the best ways to get more familiar with the project is by reading
+other people's pull requests. If there's something in a commit that you
+don't understand, this is a great time to ask for clarification. Testing
+changes is also very helpful, especially for bug fixes or feature
+additions. Check out a change and try it out; does it work? Can you find
+edge cases? Manual testing is very valuable. For more information on
+reviews, see [code review process](#review-process).
+
+
+## Proposing and making changes
+
+### Finding something to work on
+
+If you're looking for something to work on, a good first step is to browse
+the [issues](https://github.com/xi-editor/xi-editor/issues). Specifically,
+issues that are labeled
+[help wanted](https://github.com/xi-editor/xi-editor/issues?q=is%3Aissue+is%3Aopen+label%3A%22help+wanted%22) and/or
+[easy](https://github.com/xi-editor/xi-editor/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy)
+are good places to start. If you can't find anything there, feel free to ask
+on IRC, or play around with the editor and try to identify something that
+_you_ think is missing.
+
+### Before you start work
+
+Before starting to work on an issue, consider the following:
+
+- _Is it a bugfix or small change?_ If you notice a small bug somewhere,
+ and you believe you have a fix, feel free to open a pull request directly.
+
+- _Is it a feature?_ If you have an idea for a new editor feature that is
+ along the lines of something that already exists (for instance, adding a
+ new command to reverse the letters in a selected region) _consider_
+ opening a short issue beforehand, describing the feature you have in mind.
+ Other contributors might be able to identify possible issues or
+ refinements. This isn't _necessary_, but it might end up saving you work,
+ and it means you will get to close an issue when your PR gets merged,
+ which feels good.
+
+- _Is it a major feature, affecting for instance the behaviour or appearance
+ of a frontend, or the API or architecture of core?_ Before working on a
+ large change, please open a discussion/proposal issue. This should describe
+ the problem you're trying to solve, and the approach you're considering;
+ think of this as a 'lite' version of Rust's
+ [RFC](https://github.com/rust-lang/rfcs) process.
+
+
+### Before you open your PR
+
+Before pressing the 'Create pull request' button,
+
+- _Run the tests_. It's easy to accidentally break something with even a small
+ change, so always run the tests locally before submitting (or updating) a PR.
+ You can run all checks locally with the `xi-editor/rust/run_all_checks`. script.
+
+- _Add a message for your reviewers_. When submitting a PR, take advantage
+ of the opportunity to include a message. Your goal here should be to help
+ your reviewers. Are there any parts of your change that you're uncertain
+ about? Are there any non-obvious explanations for some of your decisions?
+ If your change changes some behaviour, how might it be tested?
+
+- ***Be your own first reviewer***. On the page where you enter your message,
+ you have a final opportunity to see your PR _as it will be seen by your
+ reviewers_. This is a great opportunity to give it one last review, yourself.
+ Imagine that it is someone else's work, that you're reviewing: what comments
+ would you have? If you spot a typo or a problem, you can push an update in
+ place, without losing your PR message or other state.
+
+- _Add yourself to the AUTHORS file_. If this is your first substantive pull
+request in this repo, feel free to add yourself to the AUTHORS file.
+
+### Review process
+
+Every non-trivial pull request goes through review. Everyone is welcome to
+participate in review; review is an excellent time to ask questions about
+code or design decisions that you don't understand.
+
+All pull requests must be approved by an appropriate reviewer before they
+are merged. For bug fixes and smaller changes, this can be anyone who has
+commit rights to the repo in question; larger changes (changes which add a
+feature, or significantly change behaviour or API) should also be approved by
+a maintainer.
+
+Before being merged, a change must pass
+[CI](https://en.wikipedia.org/wiki/Continuous_integration).
+
+#### Responsibilites of the approving reviewer
+
+If you approve a change, it is expected that you:
+- understand what the change is trying to do, and how it is doing it
+- have manually built and tested the change, to verify it works as intended
+- believe the change generally matches the idioms, formatting rules,
+and overall coding style of the relevant repo
+- are ready and able to help resolve any problems that may be introduced by
+merging the change.
+
+If a PR is made by a contributor who has write access to the repo in question,
+they are responsible for merging/rebasing the PR after it has been approved;
+otherwise it will be merged by the reviewer.
+
+If a patch adds or modifies behaviour that is observable in the client,
+the reviewer should build the patch and verify that it works as expected.
+
+### After submitting your change
+
+You've done all this, and submitted your patch. What now?
+
+_Read other PRs_. If you're waiting for a review, it's likely that other
+pull requests are waiting for review as well. This can be a good time
+to go and take a look at what other work is happening in the project;
+and if another PR has review comments, it might provide a clue to the
+type of feedback you might expect.
+
+_Patience_. As a general goal, we try to respond to all pull requests
+within a few days, and to do preliminary review within a week, but we
+don't always succeed. If you've opened a PR and haven't heard from
+anyone, feel free to comment on it, or stop by the IRC channel, to ask
+if anyone has had a chance to take a look. It's very possible that it's
+been lost in the shuffle.
+
+## Getting more involved
+
+If you are participating in the xi-editor project, you may receive
+additional privileges:
+
+_Organization membership_: If you are regularly making contributions
+to a xi project, in any of the forms outlined above, we will be happy to
+add you to the xi-editor organization, which will give you the ability
+to do things like add labels to issues and view active projects.
+
+_Contributor_: If you are regularly making substantive contributions
+to a specific xi project, we will be happy to add you as a contributor
+to the repo in question. Contributors are encouraged to review and
+approve changes, respond to issues, and generally help to maintain
+the project in question.
+
+_Maintainer_: If you are making substantive contributions to multiple
+repos over an extended period, you are regularly reviewing the work of
+other contributors, and you are actively participating in planning and
+discussion, you may, (at the discretion of @raphlinus) be invited to
+take on the role of _maintainer_. Maintainers are responsible for
+coordinating the general direction of the project, resolving
+architectural questions, and doing the day to day work of moving the
+project forward.
diff --git a/docs/docs/frontend-protocol.md b/docs/docs/frontend-protocol.md
index 6d3780dfa..65a60d64f 100644
--- a/docs/docs/frontend-protocol.md
+++ b/docs/docs/frontend-protocol.md
@@ -73,9 +73,15 @@ note for `new_view`. Errors are not currently reported.
`set_theme {"theme_name": "InspiredGitHub"}`
-Requests that core change the theme. If the change succeeds the client
+Asks core to change the theme. If the change succeeds the client
will receive a `theme_changed` notification.
+### set_language
+`set_language {"view-id":"view-id-1", "language_id":"Rust"}`
+
+Asks core to change the language of the buffer associated with the `view_id`.
+If the change succeeds the client will receive a `language_changed` notification.
+
### modify_user_config
`modify_user_config { "domain": Domain, "changes": Object }`
@@ -117,13 +123,13 @@ multiple cursors and `chars` has the same number of lines as there are
cursors, one line will be inserted at each cursor, in order; otherwise the full
string will be inserted at each cursor.
-#### copy
+#### copy
`copy -> String|Null`
Copies the active selection, returning their contents or `Null` if the selection was empty.
-#### cut
+#### cut
`cut -> String|Null`
@@ -188,6 +194,13 @@ multi_line_select # adds a line to the selection
multi_word_select # adds a word to the selection
```
+#### goto_line
+
+`goto_line {"line": 1}`
+
+Sets the cursor to the beginning of the provided `line` and scrolls to
+this position.
+
#### Other movement and deletion commands
The following edit methods take no parameters, and have similar
@@ -212,6 +225,11 @@ scroll_page_up
page_up_and_modify_selection
scroll_page_down
page_down_and_modify_selection
+yank
+transpose
+select_all
+add_selection_above
+add_selection_below
```
#### Transformations
@@ -221,10 +239,48 @@ The following methods act by modifying the current selection.
```
uppercase
lowercase
+capitalize
indent
outdent
```
+#### Number Transformations
+
+The following methods work with a caret or multiple selections. If the beginning of a selection (or the caret) is within a positive or negative number, the number will be transformed accordingly:
+
+```
+increase_number
+decrease_number
+```
+
+#### Recording
+
+These methods allow manipulation and playback of event recordings.
+
+- If there is no currently active recording, start recording events under the provided name.
+- If there is no provided name, the current recording is saved.
+- If the name provided matches the current recording name, the current recording is saved.
+- If the name provided does not match the current recording name, the events for the current recording are dismissed.
+```
+toggle_recording {
+ "recording_name"?: string
+}
+```
+
+Execute a set of recorded events and modify the document state:
+```
+play_recording {
+ "recording_name": string
+}
+```
+
+Completely remove a specific recording:
+```
+clear_recording {
+ "recording_name": string
+}
+```
+
### Language Support Oriented features (in Edit Namespace)
#### Hover
@@ -293,6 +349,17 @@ Parameters `regex` and `whole_words` are optional and by default `false`.
Sets the current search query and options.
+#### multi_find
+
+This find command supports multiple search queries.
+
+`multi_find [{"id": 1, "chars": "a", "case_sensitive": false, "regex": false, "whole_words": true}]`
+Parameters `regex` and `whole_words` are optional and by default `false`. `id` is an optional parameter
+used to uniquely identify a search query. If left empty, the query is considered as a new query and
+the backend will generate a new ID.
+
+Sets the current search queries and options.
+
#### find_next and find_previous
`find_next {"wrap_around": true, "allow_same": false, "modify_selection": "set"}`
@@ -533,6 +600,17 @@ instance.
Notifies the client of the available themes.
+#### language_changed
+
+`language_changed {"view_id": "view-id-1", "language_id": "Rust"}`
+
+Notifies the client that the language used for syntax highlighting has been changed.
+
+#### available_languages
+
+`available_languages {"languages": ["Rust"]}`
+
+Notifies the client of the available languages.
#### config_changed
@@ -643,7 +721,9 @@ Removes a status item from the front end.
#### find_status
-`find_status {"view_id": "view-id-1", "queries": [{"chars": "a", "case_sensitive": false, "is_regex": false, "whole_words": true, "matches": 6}]}`
+Find supports multiple search queries.
+
+`find_status {"view_id": "view-id-1", "queries": [{"id": 1, "chars": "a", "case_sensitive": false, "is_regex": false, "whole_words": true, "matches": 6}]}`
Notifies the client about the current search queries and search options.
diff --git a/docs/docs/tracing.md b/docs/docs/tracing.md
new file mode 100644
index 000000000..d54abebb9
--- /dev/null
+++ b/docs/docs/tracing.md
@@ -0,0 +1,45 @@
+# Tracing
+
+To debug or find performance bottlenecks in xi, the crate `xi_trace` can be used to write a trace log.
+
+## Analyzing the Trace Log
+
+To write the trace log into a file in [xi-mac](https://github.com/xi-editor/xi-mac): Debug → Write Trace (F5)
+
+The create file can be opened and analyzed in Chrome in `about:tracing`.
+
+## Trace Methods
+
+All methods are available in [`xi_trace`](https://github.com/xi-editor/xi-editor/blob/master/rust/trace/src/lib.rs).
+
+### trace
+
+Sample without any payload.
+
+`xi_trace::trace("something happened", &["rpc", "response"]);`
+
+### trace_payload
+
+Sample with payload.
+
+`xi_trace::trace_payload("my event", &["rpc", "response"], json!({"key": "value"}));`
+
+### trace_block and trace_block_payload
+
+Duration sample.
+
+```
+let trace_guard = xi_trace::trace_block("something_expensive", &["rpc", "request"]);
+something_expensive();
+std::mem::drop(trace_guard); // finalize explicitly
+```
+
+### trace_closure and trace_closure_payload
+
+Duration sample that measures how long the closure took to execute.
+
+```
+xi_trace::trace_closure("something_else_expensive", &["rpc", "response"], || {
+ something_else_expensive(result);
+});
+```
diff --git a/rust/.gitignore b/rust/.gitignore
index 18ec10e71..103affc25 100644
--- a/rust/.gitignore
+++ b/rust/.gitignore
@@ -1,5 +1,6 @@
*/Cargo.lock
!/syntect-plugin/Cargo.lock
+/syntect-plugin/out
*.rs.bk
target
build
diff --git a/rust/Cargo.lock b/rust/Cargo.lock
index 207b9784c..3e51c0b28 100644
--- a/rust/Cargo.lock
+++ b/rust/Cargo.lock
@@ -5,23 +5,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "aho-corasick"
-version = "0.6.5"
+version = "0.6.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "argon2rs"
+version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "arrayref"
-version = "0.3.4"
+version = "0.3.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "arrayvec"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace"
+version = "0.3.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "backtrace-sys"
+version = "0.1.24"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "base64"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -30,8 +68,8 @@ name = "bincode"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -39,31 +77,35 @@ name = "bincode"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "bitflags"
-version = "0.4.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bitflags"
-version = "0.7.0"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "bitflags"
-version = "1.0.3"
+name = "blake2-rfc"
+version = "0.2.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
+ "constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "block-buffer"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -79,7 +121,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytecount"
-version = "0.3.1"
+version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"simd 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -87,51 +129,51 @@ dependencies = [
[[package]]
name = "byteorder"
-version = "1.2.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "bytes"
-version = "0.3.0"
+version = "1.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "bytes"
-version = "0.4.8"
+version = "0.4.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "cc"
-version = "1.0.17"
+version = "1.0.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "cfg-if"
-version = "0.1.4"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "chrono"
-version = "0.4.5"
+version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "cmake"
-version = "0.1.31"
+name = "cloudabi"
+version = "0.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "constant_time_eq"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "crc"
version = "1.8.1"
@@ -145,28 +187,27 @@ name = "crossbeam"
version = "0.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "crossbeam-utils"
+version = "0.5.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "digest"
-version = "0.7.4"
+version = "0.7.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "dtoa"
-version = "0.4.3"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "duct"
-version = "0.10.0"
+name = "dirs"
+version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "os_pipe 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "shared_child 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -177,6 +218,26 @@ dependencies = [
"num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "failure"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "failure_derive"
+version = "0.1.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
+ "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "fake-simd"
version = "0.1.2"
@@ -187,25 +248,25 @@ name = "fern"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "filetime"
-version = "0.1.15"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "flate2"
-version = "1.0.1"
+version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -222,7 +283,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -230,7 +291,7 @@ name = "fsevent-sys"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -238,7 +299,7 @@ name = "fuchsia-zircon"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -248,8 +309,8 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "gcc"
-version = "0.3.54"
+name = "futures"
+version = "0.1.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -265,17 +326,31 @@ name = "idna"
version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-normalization 0.1.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "inotify"
-version = "0.3.0"
+version = "0.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "inotify-sys"
+version = "0.1.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -283,13 +358,13 @@ name = "iovec"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "itoa"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -297,9 +372,9 @@ name = "jsonrpc-lite"
version = "0.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -316,57 +391,63 @@ name = "languageserver-types"
version = "0.41.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "lazy_static"
-version = "1.0.1"
+version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "lazycell"
-version = "0.6.0"
+version = "1.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "libc"
-version = "0.2.42"
+version = "0.2.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "log"
-version = "0.3.9"
+name = "lock_api"
+version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "log"
-version = "0.4.3"
+version = "0.4.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "matches"
-version = "0.1.6"
+version = "0.1.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "memchr"
-version = "2.0.1"
+version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -374,8 +455,8 @@ name = "miniz-sys"
version = "0.1.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -384,7 +465,7 @@ version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -392,31 +473,44 @@ name = "miniz_oxide_c_api"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
"crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "mio"
-version = "0.5.1"
+version = "0.6.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "mio-extras"
+version = "2.0.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "miow"
-version = "0.1.5"
+version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -430,48 +524,32 @@ name = "net2"
version = "0.2.33"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "nix"
-version = "0.5.1"
+name = "nodrop"
+version = "0.1.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "nix"
-version = "0.10.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
[[package]]
name = "notify"
-version = "4.0.3"
+version = "4.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
"fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -479,7 +557,7 @@ name = "num-integer"
version = "0.1.39"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -487,43 +565,70 @@ name = "num-traits"
version = "0.1.43"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "num-traits"
-version = "0.2.5"
+version = "0.2.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "num_cpus"
+version = "1.8.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "onig"
version = "3.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "onig_sys 68.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "onig_sys 68.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "onig_sys"
-version = "68.0.1"
+version = "68.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "duct 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)",
+ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "os_pipe"
-version = "0.6.1"
+name = "owning_ref"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parking_lot"
+version = "0.6.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "parking_lot_core"
+version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -533,7 +638,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "pkg-config"
-version = "0.3.11"
+version = "0.3.14"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -542,15 +647,15 @@ version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "proc-macro2"
-version = "0.4.6"
+version = "0.4.19"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -558,37 +663,65 @@ dependencies = [
[[package]]
name = "quote"
-version = "0.6.3"
+version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "rand"
-version = "0.4.2"
+version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "rand"
+version = "0.5.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "rand_core"
+version = "0.2.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "redox_syscall"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "redox_users"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "regex"
-version = "1.0.1"
+version = "1.0.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -598,7 +731,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "regex-syntax"
-version = "0.6.1"
+version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -609,9 +742,27 @@ name = "remove_dir_all"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "rustc-demangle"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "rustc_version"
+version = "0.2.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "ryu"
+version = "0.2.6"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "safemem"
version = "0.2.0"
@@ -619,43 +770,66 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "same-file"
-version = "1.0.2"
+version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
+[[package]]
+name = "scoped_threadpool"
+version = "0.1.9"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "scopeguard"
+version = "0.3.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "semver"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "semver-parser"
+version = "0.7.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
[[package]]
name = "serde"
-version = "1.0.69"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_derive"
-version = "1.0.69"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_json"
-version = "1.0.22"
+version = "1.0.31"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_test"
-version = "1.0.69"
+version = "1.0.79"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -665,37 +839,61 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)",
"byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "digest 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "shared_child"
-version = "0.3.2"
+name = "simd"
+version = "0.2.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "slab"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "smallvec"
+version = "0.6.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "simd"
-version = "0.2.2"
+name = "stable_deref_trait"
+version = "1.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
-name = "slab"
-version = "0.1.3"
+name = "syn"
+version = "0.14.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
[[package]]
name = "syn"
-version = "0.14.4"
+version = "0.15.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "synstructure"
+version = "0.9.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)",
+ "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -705,17 +903,17 @@ version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"onig 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)",
"regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -723,17 +921,16 @@ name = "tempdir"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
"remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "thread_local"
-version = "0.3.5"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -741,17 +938,52 @@ name = "time"
version = "0.1.40"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
"redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-executor"
+version = "0.1.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-io"
+version = "0.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
+name = "tokio-reactor"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)",
+ "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
+ "tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "toml"
-version = "0.4.6"
+version = "0.4.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -769,7 +1001,7 @@ name = "unicode-bidi"
version = "0.3.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -801,7 +1033,7 @@ version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -810,13 +1042,18 @@ name = "url_serde"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "utf8-ranges"
-version = "1.0.0"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
+[[package]]
+name = "version_check"
+version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
@@ -826,11 +1063,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "walkdir"
-version = "2.1.4"
+version = "2.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
@@ -840,7 +1078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "winapi"
-version = "0.3.5"
+version = "0.3.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -857,6 +1095,14 @@ name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
+[[package]]
+name = "winapi-util"
+version = "0.1.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
@@ -875,11 +1121,12 @@ dependencies = [
name = "xi-core"
version = "0.2.0"
dependencies = [
- "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
"fern 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-core-lib 0.2.0",
"xi-rpc 0.2.0",
]
@@ -888,17 +1135,18 @@ dependencies = [
name = "xi-core-lib"
version = "0.2.0"
dependencies = [
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "notify 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "notify 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-rope 0.2.0",
"xi-rpc 0.2.0",
"xi-trace 0.1.0",
@@ -910,14 +1158,14 @@ dependencies = [
name = "xi-lsp-lib"
version = "0.1.0"
dependencies = [
- "chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"fern 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
"jsonrpc-lite 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
"languageserver-types 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-core-lib 0.2.0",
"xi-plugin-lib 0.1.0",
@@ -930,14 +1178,14 @@ dependencies = [
name = "xi-plugin-lib"
version = "0.1.0"
dependencies = [
- "bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
"languageserver-types 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-core-lib 0.2.0",
"xi-rope 0.2.0",
"xi-rpc 0.2.0",
@@ -949,13 +1197,13 @@ dependencies = [
name = "xi-rope"
version = "0.2.0"
dependencies = [
- "bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_test 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_test 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -964,10 +1212,10 @@ name = "xi-rpc"
version = "0.2.0"
dependencies = [
"crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-trace 0.1.0",
]
@@ -975,8 +1223,8 @@ dependencies = [
name = "xi-sample-plugin"
version = "0.0.0"
dependencies = [
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-core-lib 0.2.0",
"xi-plugin-lib 0.1.0",
"xi-rope 0.2.0",
@@ -987,10 +1235,10 @@ dependencies = [
name = "xi-syntect-plugin"
version = "0.0.0"
dependencies = [
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
"syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "toml 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-core-lib 0.2.0",
"xi-plugin-lib 0.1.0",
"xi-rope 0.2.0",
@@ -1001,12 +1249,12 @@ dependencies = [
name = "xi-trace"
version = "0.1.0"
dependencies = [
- "lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)",
+ "log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1015,9 +1263,9 @@ name = "xi-trace-dump"
version = "0.1.0"
dependencies = [
"bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)",
"xi-trace 0.1.0",
]
@@ -1030,103 +1278,129 @@ name = "xml-rs"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
- "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum adler32 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "7e522997b529f05601e05166c07ed17789691f562762c7f3b987263d2dedee5c"
-"checksum aho-corasick 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f0ba20154ea1f47ce2793322f049c5646cc6d0fa9759d5f333f286e507bf8080"
-"checksum arrayref 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "0fd1479b7c29641adbd35ff3b5c293922d696a92f25c8c975da3e0acbc87258f"
+"checksum aho-corasick 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "68f56c7353e5a9547cbd76ed90f7bb5ffc3ba09d4ea9bd1d8c06c8b1142eeb5a"
+"checksum argon2rs 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3f67b0b6a86dae6e67ff4ca2b6201396074996379fba2b92ff649126f37cb392"
+"checksum arrayref 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0d382e583f07208808f6b1249e60848879ba3543f57c32277bf52d69c2f0f0ee"
+"checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
+"checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+"checksum backtrace-sys 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
"checksum base64 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7c4a342b450b268e1be8036311e2c613d7f8a7ed31214dff1cc3b60852a3168d"
"checksum bincode 0.9.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9a6301db0b49fb63551bc15b5ae348147101cdf323242b93ec7546d5002ff1af"
"checksum bincode 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f2fb9e29e72fd6bc12071533d5dc7664cb01480c59406f656d7ac25c7bd8ff7"
-"checksum bitflags 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8dead7461c1127cf637931a1e50934eb6eee8bff2f74433ac7909e9afcee04a3"
"checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
-"checksum bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d0c54bb8f454c567f21197eefcdbf5679d0bd99f2ddbe52e84c77061952e6789"
+"checksum bitflags 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "228047a76f468627ca71776ecdebd732a3423081fcf5125585bcd7c49886ce12"
+"checksum blake2-rfc 0.2.18 (registry+https://github.com/rust-lang/crates.io-index)" = "5d6d530bdd2d52966a6d03b7a964add7ae1a288d25214066fd4b600f0f796400"
"checksum block-buffer 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a076c298b9ecdb530ed9d967e74a6027d6a7478924520acddcddc24c1c8ab3ab"
"checksum build_const 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "39092a32794787acd8525ee150305ff051b0aa6cc2abaf193924f5ab05425f39"
"checksum byte-tools 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "560c32574a12a89ecd91f5e742165893f86e3ab98d21f8ea548658eb9eef5f40"
-"checksum bytecount 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "882585cd7ec84e902472df34a5e01891202db3bf62614e1f0afe459c1afcf744"
-"checksum byteorder 1.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "74c0b906e9446b0a2e4f760cdb3fa4b2c48cdc6db8766a845c54b6ff063fd2e9"
-"checksum bytes 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c129aff112dcc562970abb69e2508b40850dd24c274761bb50fb8a0067ba6c27"
-"checksum bytes 0.4.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7dd32989a66957d3f0cba6588f15d4281a733f4e9ffc43fcd2385f57d3bf99ff"
-"checksum cc 1.0.17 (registry+https://github.com/rust-lang/crates.io-index)" = "49ec142f5768efb5b7622aebc3fdbdbb8950a4b9ba996393cb76ef7466e8747d"
-"checksum cfg-if 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "efe5c877e17a9c717a0bf3613b2709f723202c4e4675cc8f12926ded29bcb17e"
-"checksum chrono 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e48d85528df61dc964aa43c5f6ca681a19cfa74939b2348d204bd08a981f2fb0"
-"checksum cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)" = "95470235c31c726d72bf2e1f421adc1e65b9d561bf5529612cbe1a72da1467b3"
+"checksum bytecount 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f861d9ce359f56dbcb6e0c2a1cb84e52ad732cadb57b806adeb3c7668caccbd8"
+"checksum byteorder 1.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "90492c5858dd7d2e78691cfb89f90d273a2800fc11d98f60786e5d87e2f83781"
+"checksum bytes 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)" = "0ce55bd354b095246fc34caf4e9e242f5297a7fd938b090cadfea6eee614aa62"
+"checksum cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)" = "f159dfd43363c4d08055a07703eb7a3406b0dac4d0584d96965a3262db3c9d16"
+"checksum cfg-if 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "0c4e7bb64a8ebb0d856483e1e682ea3422f883c5f5615a90d51a2c82fe87fdd3"
+"checksum chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "45912881121cb26fad7c38c17ba7daa18764771836b34fab7d3fbd93ed633878"
+"checksum cloudabi 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "ddfc5b9aa5d4507acaf872de71051dfd0e309860e88966e1051e462a077aac4f"
+"checksum constant_time_eq 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8ff012e225ce166d4422e0e78419d901719760f62ae2b7969ca6b564d1b54a9e"
"checksum crc 1.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d663548de7f5cca343f1e0a48d14dcfb0e9eb4e079ec58883b7251539fa10aeb"
"checksum crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "24ce9782d4d5c53674646a6a4c1863a21a8fc0cb649b3c94dfc16e45071dea19"
-"checksum digest 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)" = "3cae2388d706b52f2f2f9afe280f9d768be36544bd71d1b8120cb34ea6450b55"
-"checksum dtoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "6d301140eb411af13d3115f9a562c85cc6b541ade9dfa314132244aaee7489dd"
-"checksum duct 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "166298c17c5b4fe5997b962c2f22e887c7c5adc44308eb9103ce5b66af45a423"
+"checksum crossbeam-utils 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "677d453a17e8bd2b913fa38e8b9cf04bcdbb5be790aa294f2389661d72036015"
+"checksum digest 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "03b072242a8cbaf9c145665af9d250c59af3b958f83ed6824e13533cf76d5b90"
+"checksum dirs 1.0.4 (registry+https://github.com/rust-lang/crates.io-index)" = "88972de891f6118092b643d85a0b28e0678e0f948d7f879aa32f2d5aafe97d2a"
"checksum enum_primitive 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "be4551092f4d519593039259a9ed8daedf0da12e5109c5280338073eaeb81180"
+"checksum failure 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7efb22686e4a466b1ec1a15c2898f91fa9cb340452496dca654032de20ff95b9"
+"checksum failure_derive 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "946d0e98a50d9831f5d589038d2ca7f8f455b1c21028c0db0e84116a12696426"
"checksum fake-simd 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "e88a8acf291dafb59c2d96e8f59828f3838bb1a70398823ade51a84de6a6deed"
"checksum fern 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "57915fe00a83af935983eb2d00b0ecc62419c4741b28c207ecbf98fd4a1b94c8"
-"checksum filetime 0.1.15 (registry+https://github.com/rust-lang/crates.io-index)" = "714653f3e34871534de23771ac7b26e999651a0a228f47beb324dfdf1dd4b10f"
-"checksum flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9fac2277e84e5e858483756647a9d0aa8d9a2b7cba517fd84325a0aaa69a0909"
+"checksum filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "da4b9849e77b13195302c174324b5ba73eec9b236b24c221a61000daefb95c5f"
+"checksum flate2 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "37847f133aae7acf82bb9577ccd8bda241df836787642654286e79679826a54b"
"checksum fnv 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2fad85553e09a6f881f739c29f0b00b0f01357c743266d478b68951ce23285f3"
"checksum fsevent 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "c4bbbf71584aeed076100b5665ac14e3d85eeb31fdbb45fbd41ef9a682b5ec05"
"checksum fsevent-sys 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "1a772d36c338d07a032d5375a36f15f9a7043bf0cb8ce7cee658e037c6032874"
"checksum fuchsia-zircon 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "2e9763c69ebaae630ba35f74888db465e49e259ba1bc0eda7d06f4a067615d82"
"checksum fuchsia-zircon-sys 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3dcaa9ae7725d12cdb85b3ad99a434db70b468c09ded17e012d86b5c1010f7a7"
-"checksum gcc 0.3.54 (registry+https://github.com/rust-lang/crates.io-index)" = "5e33ec290da0d127825013597dbdfc28bee4964690c7ce1166cbc2a7bd08b1bb"
+"checksum futures 0.1.24 (registry+https://github.com/rust-lang/crates.io-index)" = "0c84b40c7e2de99ffd70602db314a7a8c26b2b3d830e6f7f7a142a8860ab3ca4"
"checksum generic-array 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ef25c5683767570c2bbd7deba372926a55eaae9982d7726ee2a1050239d45b9d"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"
-"checksum inotify 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "887fcc180136e77a85e6a6128579a719027b1bab9b1c38ea4444244fe262c20c"
+"checksum inotify 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40b54539f3910d6f84fbf9a643efd6e3aa6e4f001426c0329576128255994718"
+"checksum inotify-sys 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e74a1aa87c59aeff6ef2cc2fa62d41bc43f54952f55652656b18a02fd5e356c0"
"checksum iovec 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "dbe6e417e7d0975db6512b90796e8ce223145ac4e33c377e4a42882a0e88bb08"
-"checksum itoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "5adb58558dcd1d786b5f0bd15f3226ee23486e24b7b58304b60f64dc68e62606"
+"checksum itoa 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "1306f3464951f30e30d12373d31c79fbd52d236e5e896fd92f96ec7babbbe60b"
"checksum jsonrpc-lite 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a98d245f26984add78277a5306ca0cf774863d4eddb4912b31d94ee3fa1a22d4"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum languageserver-types 0.41.0 (registry+https://github.com/rust-lang/crates.io-index)" = "017cf5ade4be5ebeb06277ccd281c268dbd2e0801128d3992b4b4057f34dd432"
-"checksum lazy_static 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "e6412c5e2ad9584b0b8e979393122026cdd6d2a80b933f890dcd694ddbe73739"
-"checksum lazycell 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "a6f08839bc70ef4a3fe1d566d5350f519c5912ea86be0df1740a7d247c7fc0ef"
-"checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
-"checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
-"checksum log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "61bd98ae7f7b754bc53dca7d44b604f733c6bba044ea6f41bc8d89272d8161d2"
-"checksum matches 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "100aabe6b8ff4e4a7e32c1c13523379802df0772b82466207ac25b013f193376"
-"checksum memchr 2.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "796fba70e76612589ed2ce7f45282f5af869e0fdd7cc6199fa1aa1f1d591ba9d"
+"checksum lazy_static 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ca488b89a5657b0a2ecd45b95609b3e848cf1755da332a0da46e2b2b1cb371a7"
+"checksum lazycell 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ddba4c30a78328befecec92fc94970e53b3ae385827d28620f0f5bb2493081e0"
+"checksum libc 0.2.43 (registry+https://github.com/rust-lang/crates.io-index)" = "76e3a3ef172f1a0b9a9ff0dd1491ae5e6c948b94479a3021819ba7d860c8645d"
+"checksum lock_api 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "775751a3e69bde4df9b38dd00a1b5d6ac13791e4223d4a0506577f0dd27cfb7a"
+"checksum log 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d4fcce5fa49cc693c312001daf1d13411c4a5283796bac1084299ea3e567113f"
+"checksum matches 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "7ffc5c5338469d4d3ea17d269fa8ea3512ad247247c30bd2df69e68309ed0a08"
+"checksum memchr 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4b3629fe9fdbff6daa6c33b90f7c08355c1aca05a3d01fa8063b822fcf185f3b"
"checksum miniz-sys 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "609ce024854aeb19a0ef7567d348aaa5a746b32fb72e336df7fcc16869d7e2b4"
"checksum miniz_oxide 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba430291c9d6cedae28bcd2d49d1c32fc57d60cd49086646c5dd5673a870eb5"
"checksum miniz_oxide_c_api 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5a5b8234d6103ebfba71e29786da4608540f862de5ce980a1c94f86a40ca0d51"
-"checksum mio 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a637d1ca14eacae06296a008fa7ad955347e34efcb5891cfd8ba05491a37907e"
-"checksum miow 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "3e690c5df6b2f60acd45d56378981e827ff8295562fc8d34f573deb267a59cd1"
+"checksum mio 0.6.16 (registry+https://github.com/rust-lang/crates.io-index)" = "71646331f2619b1026cc302f87a2b8b648d5c6dd6937846a16cc8ce0f347f432"
+"checksum mio-extras 2.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "46e73a04c2fa6250b8d802134d56d554a9ec2922bf977777c805ea5def61ce40"
+"checksum miow 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "8c1f2f3b1cf331de6896aabf6e9d55dca90356cc9960cca7eaaf408a355ae919"
"checksum net2 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)" = "42550d9fb7b6684a6d404d9fa7250c2eb2646df731d1c06afc06dcee9e1bcf88"
-"checksum nix 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b7fd5681d13fda646462cfbd4e5f2051279a89a544d50eb98c365b507246839f"
-"checksum nix 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "bfb3ddedaa14746434a02041940495bf11325c22f6d36125d3bdd56090d50a79"
-"checksum notify 4.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "5c3812da3098f210a0bb440f9c008471a031aa4c1de07a264fdd75456c95a4eb"
+"checksum nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)" = "9a2228dca57108069a5262f2ed8bd2e82496d2e074a06d1ccc7ce1687b6ae0a2"
+"checksum notify 4.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "873ecfd8c174964ae30f401329d140142312c8e5590719cf1199d5f1717d8078"
"checksum num-integer 0.1.39 (registry+https://github.com/rust-lang/crates.io-index)" = "e83d528d2677f0518c570baf2b7abdcf0cd2d248860b68507bdcb3e91d4c0cea"
"checksum num-traits 0.1.43 (registry+https://github.com/rust-lang/crates.io-index)" = "92e5113e9fd4cc14ded8e499429f396a20f98c772a47cc8622a736e1ec843c31"
-"checksum num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "630de1ef5cc79d0cdd78b7e33b81f083cbfe90de0f4b2b2f07f905867c70e9fe"
+"checksum num-traits 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "0b3a5d7cc97d6d30d8b9bc8fa19bf45349ffe46241e8816f50f62f6d6aaabee1"
+"checksum num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c51a3322e4bca9d212ad9a158a02abc6934d005490c054a2778df73a70aa0a30"
"checksum onig 3.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "f5eeb268a4620c74ea5768c6d2ccd492d60a47a8754666b91a46bfc35cd4d1ba"
-"checksum onig_sys 68.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5c6be7c4f985508684e54f18dd37f71e66f3e1ad9318336a520d7e42f0d3ea8e"
-"checksum os_pipe 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "934868c3f86ed7a39ef63d88edeac5bd49a0c843192651900e9ce1178cbbf157"
+"checksum onig_sys 68.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "195ebddbb56740be48042ca117b8fb6e0d99fe392191a9362d82f5f69e510379"
+"checksum owning_ref 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "cdf84f41639e037b484f93433aa3897863b561ed65c6e59c7073d7c561710f37"
+"checksum parking_lot 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)" = "f0802bff09003b291ba756dc7e79313e51cc31667e94afbe847def490424cde5"
+"checksum parking_lot_core 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad7f7e6ebdc79edff6fdcb87a55b620174f7a989e3eb31b65231f4af57f00b8c"
"checksum percent-encoding 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "31010dd2e1ac33d5b46a5b413495239882813e0369f8ed8a5e266f173602f831"
-"checksum pkg-config 0.3.11 (registry+https://github.com/rust-lang/crates.io-index)" = "110d5ee3593dbb73f56294327fe5668bcc997897097cbc76b51e7aed3f52452f"
+"checksum pkg-config 0.3.14 (registry+https://github.com/rust-lang/crates.io-index)" = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
"checksum plist 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "c61ac2afed2856590ae79d6f358a24b85ece246d2aa134741a66d589519b7503"
-"checksum proc-macro2 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "effdb53b25cdad54f8f48843d67398f7ef2e14f12c1b4cb4effc549a6462a4d6"
-"checksum quote 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e44651a0dc4cdd99f71c83b561e221f714912d11af1a4dff0631f923d53af035"
-"checksum rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "eba5f8cb59cc50ed56be8880a5c7b496bfd9bd26394e176bc67884094145c2c5"
+"checksum proc-macro2 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "ffe022fb8c8bd254524b0b3305906c1921fa37a84a644e29079a9e62200c3901"
+"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
+"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
+"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
+"checksum rand_core 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "edecf0f94da5551fc9b492093e30b041a891657db7940ee221f9d2f66e82eef2"
"checksum redox_syscall 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "c214e91d3ecf43e9a4e41e578973adeb14b474f2bee858742d127af75a0112b1"
-"checksum regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "13c93d55961981ba9226a213b385216f83ab43bd6ac53ab16b2eeb47e337cf4e"
+"checksum redox_users 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "214a97e49be64fd2c86f568dd0cb2c757d2cc53de95b273b6ad0a1c908482f26"
+"checksum regex 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "2069749032ea3ec200ca51e4a31df41759190a88edca0d2d86ee8bedf7073341"
"checksum regex-syntax 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "8e931c58b93d86f080c734bfd2bce7dd0079ae2331235818133c8be7f422e20e"
-"checksum regex-syntax 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "05b06a75f5217880fc5e905952a42750bf44787e56a6c6d6852ed0992f5e1d54"
+"checksum regex-syntax 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "747ba3b235651f6e2f67dfa8bcdcd073ddb7c243cb21c442fc12395dfcac212d"
"checksum remove_dir_all 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "3488ba1b9a2084d38645c4c08276a1752dcbf2c7130d74f1569681ad5d2799c5"
+"checksum rustc-demangle 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "bcfe5b13211b4d78e5c2cadfebd7769197d95c639c35a50057eb4c05de811395"
+"checksum rustc_version 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "138e3e0acb6c9fb258b19b67cb8abd63c00679d2851805ea151465464fe9030a"
+"checksum ryu 0.2.6 (registry+https://github.com/rust-lang/crates.io-index)" = "7153dd96dade874ab973e098cb62fcdbb89a03682e46b144fd09550998d4a4a7"
"checksum safemem 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e27a8b19b835f7aea908818e871f5cc3a5a186550c30773be987e155e8163d8f"
-"checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
-"checksum serde 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)" = "210e5a3b159c566d7527e9b22e44be73f2e0fcc330bb78fef4dbccb56d2e74c8"
-"checksum serde_derive 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)" = "dd724d68017ae3a7e63600ee4b2fdb3cad2158ffd1821d44aff4580f63e2b593"
-"checksum serde_json 1.0.22 (registry+https://github.com/rust-lang/crates.io-index)" = "84b8035cabe9b35878adec8ac5fe03d5f6bc97ff6edd7ccb96b44c1276ba390e"
-"checksum serde_test 1.0.69 (registry+https://github.com/rust-lang/crates.io-index)" = "b908c52a09953a7a783ce4ec726d2ad7f4addc4e4d98d886669b47559962d6cb"
+"checksum same-file 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "10f7794e2fda7f594866840e95f5c5962e886e228e68b6505885811a94dd728c"
+"checksum scoped_threadpool 0.1.9 (registry+https://github.com/rust-lang/crates.io-index)" = "1d51f5df5af43ab3f1360b429fa5e0152ac5ce8c0bd6485cae490332e96846a8"
+"checksum scopeguard 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "94258f53601af11e6a49f722422f6e3425c52b06245a5cf9bc09908b174f5e27"
+"checksum semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1d7eb9ef2c18661902cc47e535f9bc51b78acd254da71d375c2f6720d9a40403"
+"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
+"checksum serde 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "84257ccd054dc351472528c8587b4de2dbf0dc0fe2e634030c1a90bfdacebaa9"
+"checksum serde_derive 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "31569d901045afbff7a9479f793177fe9259819aff10ab4f89ef69bbc5f567fe"
+"checksum serde_json 1.0.31 (registry+https://github.com/rust-lang/crates.io-index)" = "bb47a3d5c84320222f66d7db21157c4a7407755de41798f9b4c1c40593397b1a"
+"checksum serde_test 1.0.79 (registry+https://github.com/rust-lang/crates.io-index)" = "14d0315287db0b84cfbb1531eb21803fd1b17092e227e90d3afaed30cf03824e"
"checksum sha2 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9eb6be24e4c23a84d7184280d2722f7f2731fcdd4a9d886efbfe4413e4847ea0"
-"checksum shared_child 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "bcd5e483b3475af9bc2a35311c2f3bbf0bd98fde91410ab15a0d4ba3c3127b4e"
"checksum simd 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "ed3686dd9418ebcc3a26a0c0ae56deab0681e53fe899af91f5bbcee667ebffb1"
-"checksum slab 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d807fd58c4181bbabed77cb3b891ba9748241a552bcc5be698faaebefc54f46e"
-"checksum syn 0.14.4 (registry+https://github.com/rust-lang/crates.io-index)" = "2beff8ebc3658f07512a413866875adddd20f4fd47b2a4e6c9da65cd281baaea"
+"checksum slab 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5f9776d6b986f77b35c6cf846c11ad986ff128fe0b2b63a3628e3755e8d3102d"
+"checksum smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)" = "153ffa32fd170e9944f7e0838edf824a754ec4c1fc64746fcc9fe1f8fa602e5d"
+"checksum stable_deref_trait 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "dba1a27d3efae4351c8051072d619e3ade2820635c3958d826bfea39d59b54c8"
+"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
+"checksum syn 0.15.6 (registry+https://github.com/rust-lang/crates.io-index)" = "854b08a640fc8f54728fb95321e3ec485b365a97fe47609797c671addd1dde69"
+"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
"checksum syntect 2.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "dc8a6f0db88d4afc340522c20d260411e746b2225b257c6b238a75de9d7cec78"
"checksum tempdir 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "15f2b5fb00ccdf689e0149d1b1b3c03fead81c2b37735d812fa8bddbbf41b6d8"
-"checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
+"checksum thread_local 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c6b53e329000edc2b34dbe8545fd20e55a333362d0a321909685a19bd28c3f1b"
"checksum time 0.1.40 (registry+https://github.com/rust-lang/crates.io-index)" = "d825be0eb33fda1a7e68012d51e9c7f451dc1a69391e7fdc197060bb8c56667b"
-"checksum toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "a0263c6c02c4db6c8f7681f9fd35e90de799ebd4cfdeab77a38f4ff6b3d8c0d9"
+"checksum tokio-executor 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "84823b932d566bc3c6aa644df4ca36cb38593c50b7db06011fd4e12e31e4047e"
+"checksum tokio-io 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)" = "8d6cc2de7725863c86ac71b0b9068476fec50834f055a243558ef1655bbd34cb"
+"checksum tokio-reactor 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "4bfbaf9f260635649ec26b6fb4aded03887295ffcd999f6e43fd2c4758f758ea"
+"checksum toml 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "b7e7d59d55f36979a9dd86d71ae54657a5e9c7fdb4fa2212f4064e2d32f9dcda"
"checksum typenum 1.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "612d636f949607bdf9b123b4a6f6d966dedf3ff669f7f045890d3a4a73948169"
"checksum ucd-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd2be2d6639d0f8fe6cdda291ad456e23629558d466e2789d2c3e9892bda285d"
"checksum unicode-bidi 0.3.4 (registry+https://github.com/rust-lang/crates.io-index)" = "49f2bd0c6468a8230e1db229cff8029217cf623c767ea5d60bfbd42729ea54d5"
@@ -1136,13 +1410,15 @@ dependencies = [
"checksum unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "382810877fe448991dfc7f0dd6e3ae5d58088fd0ea5e35189655f84e6814fa56"
"checksum url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2a321979c09843d272956e73700d12c4e7d3d92b2ee112b31548aef0d4efc5a6"
"checksum url_serde 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "74e7d099f1ee52f823d4bdd60c93c3602043c728f5db3b97bdb548467f7bddea"
-"checksum utf8-ranges 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "662fab6525a98beff2921d7f61a39e7d59e0b425ebc7d0d9e66d316e55124122"
+"checksum utf8-ranges 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "fd70f467df6810094968e2fce0ee1bd0e87157aceb026a8c083bcf5e25b9efe4"
+"checksum version_check 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "914b1a6776c4c929a602fafd8bc742e06365d4bcbe48c30f9cca5824f70dc9dd"
"checksum void 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
-"checksum walkdir 2.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "63636bd0eb3d00ccb8b9036381b526efac53caf112b7783b730ab3f8e44da369"
+"checksum walkdir 2.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "af464bc7be7b785c7ac72e266a6b67c4c9070155606f51655a650a6686204e35"
"checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
-"checksum winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "773ef9dcc5f24b7d850d0ff101e542ff24c3b090a9768e03ff889fdef41f00fd"
+"checksum winapi 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "92c1eb33641e276cfa214a0522acad57be5c56b10cb348b3c5117db75f3ac4b0"
"checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
"checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
+"checksum winapi-util 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "afc5508759c5bf4285e61feb862b6083c8480aec864fa17a81fdec6f69b461ab"
"checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
"checksum ws2_32-sys 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d59cefebd0c892fa2dd6de581e937301d8552cb44489cdff035c6187cb63fa5e"
"checksum xml-rs 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c1cb601d29fe2c2ac60a2b2e5e293994d87a1f6fa9687a31a15270f909be9c2"
diff --git a/rust/Cargo.toml b/rust/Cargo.toml
index 018fa2bbf..4ff6f97eb 100644
--- a/rust/Cargo.toml
+++ b/rust/Cargo.toml
@@ -13,6 +13,7 @@ serde_json = "1.0"
chrono = "0.4.5"
fern = "0.5.6"
log = "0.4.3"
+dirs = "1.0.4"
[dependencies.xi-core-lib]
path = "core-lib"
diff --git a/rust/core-lib/Cargo.toml b/rust/core-lib/Cargo.toml
index 7560dd629..294333111 100644
--- a/rust/core-lib/Cargo.toml
+++ b/rust/core-lib/Cargo.toml
@@ -15,6 +15,7 @@ time = "0.1"
toml = "0.4"
notify = { optional = true, version = "4.0" }
regex = "1.0"
+memchr = "2.0.1"
xi-trace = { path = "../trace", version = "0.1.0" }
xi-trace-dump = { path = "../trace-dump", version = "0.1.0" }
diff --git a/rust/core-lib/assets/client_example.toml b/rust/core-lib/assets/client_example.toml
index 7c1d40030..f9998d01b 100644
--- a/rust/core-lib/assets/client_example.toml
+++ b/rust/core-lib/assets/client_example.toml
@@ -36,3 +36,6 @@ wrap_width = 0
# If true, wraps lines at the edge of the view. Overrides 'wrap_width'.
word_wrap = false
+
+# Detect tab and newline settings on file open
+autodetect_whitespace = true
diff --git a/rust/core-lib/assets/defaults.toml b/rust/core-lib/assets/defaults.toml
index fb61bf6d3..761fbffe5 100644
--- a/rust/core-lib/assets/defaults.toml
+++ b/rust/core-lib/assets/defaults.toml
@@ -24,3 +24,5 @@ scroll_past_end = false
wrap_width = 0
word_wrap = false
+
+autodetect_whitespace = true
diff --git a/rust/core-lib/src/backspace.rs b/rust/core-lib/src/backspace.rs
new file mode 100644
index 000000000..d8ca1486f
--- /dev/null
+++ b/rust/core-lib/src/backspace.rs
@@ -0,0 +1,213 @@
+// Copyright 2018 The xi-editor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Calc start of a backspace delete interval
+
+use view::View;
+
+use xi_rope::tree::Cursor;
+use xi_rope::rope::Rope;
+
+use config::BufferItems;
+use selection::SelRegion;
+use xi_unicode::*;
+
+pub fn offset_for_delete_backwards(view: &View, region: &SelRegion, text: &Rope, config: &BufferItems) -> usize {
+ if !region.is_caret() {
+ region.min()
+ } else {
+ // backspace deletes max(1, tab_size) contiguous spaces
+ let (_, c) = view.offset_to_line_col(&text, region.start);
+
+ let tab_off = c % config.tab_size;
+ let tab_size = config.tab_size;
+ let tab_size = if tab_off == 0 { tab_size } else { tab_off };
+ let tab_start = region.start.saturating_sub(tab_size);
+ let preceded_by_spaces = region.start > 0 &&
+ (tab_start..region.start).all(|i| text.byte_at(i) == b' ');
+ if preceded_by_spaces
+ && config.translate_tabs_to_spaces
+ && config.use_tab_stops {
+ tab_start
+ } else {
+ #[derive(PartialEq)]
+ enum State {
+ Start,
+ Lf,
+ BeforeKeycap,
+ BeforeVsAndKeycap,
+ BeforeEmojiModifier,
+ BeforeVSAndEmojiModifier,
+ BeforeVS,
+ BeforeEmoji,
+ BeforeZwj,
+ BeforeVSAndZWJ,
+ OddNumberedRIS,
+ EvenNumberedRIS,
+ InTagSequence,
+ Finished
+ };
+ let mut state = State::Start;
+ let mut tmp_offset = region.end;
+
+ let mut delete_code_point_count = 0;
+ let mut last_seen_vs_code_point_count = 0;
+
+ while state != State::Finished && tmp_offset > 0 {
+ let mut cursor = Cursor::new(&text, tmp_offset);
+ let code_point = cursor.prev_codepoint().unwrap_or('0');
+
+ tmp_offset = text.prev_codepoint_offset(tmp_offset).unwrap_or(0);
+
+ match state {
+ State::Start => {
+ delete_code_point_count = 1;
+ if code_point == '\n' {
+ state = State::Lf;
+ } else if is_variation_selector(code_point) {
+ state = State::BeforeVS;
+ } else if code_point.is_regional_indicator_symbol() {
+ state = State::OddNumberedRIS;
+ } else if code_point.is_emoji_modifier() {
+ state = State::BeforeEmojiModifier;
+ } else if code_point.is_emoji_combining_enclosing_keycap() {
+ state = State::BeforeKeycap;
+ } else if code_point.is_emoji() {
+ state = State::BeforeEmoji;
+ } else if code_point.is_emoji_cancel_tag() {
+ state = State::InTagSequence;
+ } else {
+ state = State::Finished;
+ }
+ }
+ State::Lf => {
+ if code_point == '\r' {
+ delete_code_point_count += 1;
+ }
+ state = State::Finished;
+ }
+ State::OddNumberedRIS => {
+ if code_point.is_regional_indicator_symbol() {
+ delete_code_point_count += 1;
+ state = State::EvenNumberedRIS
+ } else {
+ state = State::Finished
+ }
+ }
+ State::EvenNumberedRIS => {
+ if code_point.is_regional_indicator_symbol() {
+ delete_code_point_count -= 1;
+ state = State::OddNumberedRIS;
+ } else {
+ state = State::Finished;
+ }
+ }
+ State::BeforeKeycap => {
+ if is_variation_selector(code_point) {
+ last_seen_vs_code_point_count = 1;
+ state = State::BeforeVsAndKeycap;
+ } else {
+ if is_keycap_base(code_point) {
+ delete_code_point_count += 1;
+ }
+ state = State::Finished;
+ }
+ }
+ State::BeforeVsAndKeycap => {
+ if is_keycap_base(code_point) {
+ delete_code_point_count += last_seen_vs_code_point_count + 1;
+ }
+ state = State::Finished;
+ }
+ State::BeforeEmojiModifier => {
+ if is_variation_selector(code_point) {
+ last_seen_vs_code_point_count = 1;
+ state = State::BeforeVSAndEmojiModifier;
+ } else {
+ if code_point.is_emoji_modifier_base() {
+ delete_code_point_count += 1;
+ }
+ state = State::Finished;
+ }
+ }
+ State::BeforeVSAndEmojiModifier => {
+ if code_point.is_emoji_modifier_base() {
+ delete_code_point_count += last_seen_vs_code_point_count + 1;
+ }
+ state = State::Finished;
+ }
+ State::BeforeVS => {
+ if code_point.is_emoji() {
+ delete_code_point_count += 1;
+ state = State::BeforeEmoji;
+ } else {
+ if !is_variation_selector(code_point) { //TODO: UCharacter.getCombiningClass(codePoint) == 0
+ delete_code_point_count += 1;
+ }
+ state = State::Finished;
+ }
+ }
+ State::BeforeEmoji => {
+ if code_point.is_zwj() {
+ state = State::BeforeZwj;
+ } else {
+ state = State::Finished;
+ }
+ }
+ State::BeforeZwj => {
+ if code_point.is_emoji() {
+ delete_code_point_count += 2;
+ state = if code_point.is_emoji_modifier() { State::BeforeEmojiModifier } else { State::BeforeEmoji };
+ } else if is_variation_selector(code_point) {
+ last_seen_vs_code_point_count = 1;
+ state = State::BeforeVSAndZWJ;
+ } else {
+ state = State::Finished;
+ }
+ }
+ State::BeforeVSAndZWJ => {
+ if code_point.is_emoji() {
+ delete_code_point_count += last_seen_vs_code_point_count + 2;
+ last_seen_vs_code_point_count = 0;
+ state = State::BeforeEmoji;
+ } else {
+ state = State::Finished;
+ }
+ }
+ State::InTagSequence => {
+ if code_point.is_tag_spec_char() {
+ delete_code_point_count += 1;
+ } else if code_point.is_emoji() {
+ delete_code_point_count += 1;
+ state = State::Finished;
+ } else {
+ delete_code_point_count = 1;
+ state = State::Finished;
+ }
+ }
+ State::Finished => {
+ break;
+ }
+ }
+ }
+
+ let mut start = region.end;
+ while delete_code_point_count > 0 {
+ start = text.prev_codepoint_offset(start).unwrap_or(0);
+ delete_code_point_count -= 1;
+ }
+ start
+ }
+ }
+}
\ No newline at end of file
diff --git a/rust/core-lib/src/client.rs b/rust/core-lib/src/client.rs
index ab40964c5..3f2a9ee85 100644
--- a/rust/core-lib/src/client.rs
+++ b/rust/core-lib/src/client.rs
@@ -24,6 +24,7 @@ use config::Table;
use styles::ThemeSettings;
use plugins::rpc::ClientPluginInfo;
use plugins::Command;
+use syntax::LanguageId;
/// An interface to the frontend.
pub struct Client(RpcPeer);
@@ -71,6 +72,11 @@ impl Client {
&json!({"themes": theme_names}))
}
+ pub fn available_languages(&self, languages: Vec) {
+ self.0.send_rpc_notification("available_languages",
+ &json!({"languages": languages}))
+ }
+
pub fn theme_changed(&self, name: &str, theme: &ThemeSettings) {
self.0.send_rpc_notification("theme_changed",
&json!({
@@ -79,6 +85,14 @@ impl Client {
}));
}
+ pub fn language_changed(&self, view_id: ViewId, new_lang: &LanguageId) {
+ self.0.send_rpc_notification("language_changed",
+ &json!({
+ "view_id": view_id,
+ "language_id": new_lang,
+ }));
+ }
+
/// Notify the client that a plugin has started.
pub fn plugin_started(&self, view_id: ViewId, plugin: &str) {
self.0.send_rpc_notification("plugin_started",
diff --git a/rust/core-lib/src/config.rs b/rust/core-lib/src/config.rs
index daa20a777..8dfee8e8c 100644
--- a/rust/core-lib/src/config.rs
+++ b/rust/core-lib/src/config.rs
@@ -36,12 +36,17 @@ fn load_base_config() -> Table {
}
fn platform_overrides() -> Option
{
- #[cfg(target_os = "windows")]
- {
- let win_toml: &str = include_str!("../assets/windows.toml");
- return Some(load(win_toml))
+ if cfg!(test) {
+ // Exit early if we are in tests and never have platform overrides.
+ // This makes sure we have a stable test environment.
+ None
+ } else if cfg!(windows) {
+ let toml = include_str!("../assets/windows.toml");
+ Some(load(toml))
+ } else {
+ // All other platorms
+ None
}
- None
}
let base_toml: &str = include_str!("../assets/defaults.toml");
@@ -165,6 +170,7 @@ pub struct BufferItems {
pub scroll_past_end: bool,
pub wrap_width: usize,
pub word_wrap: bool,
+ pub autodetect_whitespace: bool,
}
pub type BufferConfig = Config;
@@ -301,13 +307,14 @@ impl ConfigManager {
/// Sets a specific language for the given buffer. This is used if the
/// user selects a specific language in the frontend, for instance.
- #[allow(dead_code)]
- pub(crate) fn override_language(&mut self, id: BufferId, new_lang: LanguageId) {
+ pub(crate) fn override_language(&mut self, id: BufferId, new_lang: LanguageId) -> Option
{
let has_changed = self.buffer_tags.get_mut(&id)
.map(|tag| tag.set_user(Some(new_lang)))
.expect("buffer must exist");
if has_changed {
- self.update_buffer_config(id);
+ self.update_buffer_config(id)
+ } else {
+ None
}
}
diff --git a/rust/core-lib/src/edit_types.rs b/rust/core-lib/src/edit_types.rs
index 21b44adea..72040adad 100644
--- a/rust/core-lib/src/edit_types.rs
+++ b/rust/core-lib/src/edit_types.rs
@@ -19,11 +19,12 @@
//! the editor or view as appropriate.
use movement::Movement;
-use rpc::{Position, GestureType, LineRange, EditNotification, MouseAction, SelectionModifier};
+use rpc::{Position, GestureType, LineRange, EditNotification, MouseAction, SelectionModifier, FindQuery};
use view::Size;
/// Events that only modify view state
+#[derive(Debug, PartialEq, Clone)]
pub(crate) enum ViewEvent {
Move(Movement),
ModifySelection(Movement),
@@ -36,6 +37,7 @@ pub(crate) enum ViewEvent {
Gesture { line: u64, col: u64, ty: GestureType },
GotoLine { line: u64 },
Find { chars: String, case_sensitive: bool, regex: bool, whole_words: bool },
+ MultiFind { queries: Vec },
FindNext { wrap_around: bool, allow_same: bool, modify_selection: SelectionModifier },
FindPrevious { wrap_around: bool, allow_same: bool, modify_selection: SelectionModifier },
FindAll,
@@ -48,6 +50,7 @@ pub(crate) enum ViewEvent {
}
/// Events that modify the buffer
+#[derive(Debug, PartialEq, Clone)]
pub(crate) enum BufferEvent {
Delete { movement: Movement, kill: bool },
Backspace,
@@ -56,6 +59,7 @@ pub(crate) enum BufferEvent {
Redo,
Uppercase,
Lowercase,
+ Capitalize,
Indent,
Outdent,
Insert(String),
@@ -66,9 +70,12 @@ pub(crate) enum BufferEvent {
ReplaceNext,
ReplaceAll,
DuplicateLine,
+ IncreaseNumber,
+ DecreaseNumber
}
/// An event that needs special handling
+#[derive(Debug, PartialEq, Clone)]
pub(crate) enum SpecialEvent {
DebugRewrap,
DebugWrapWidth,
@@ -76,8 +83,12 @@ pub(crate) enum SpecialEvent {
Resize(Size),
RequestLines(LineRange),
RequestHover { request_id: usize, position: Option },
+ ToggleRecording(Option),
+ PlayRecording(String),
+ ClearRecording(String),
}
+#[derive(Debug, PartialEq, Clone)]
pub(crate) enum EventDomain {
View(ViewEvent),
Buffer(BufferEvent),
@@ -167,8 +178,12 @@ impl From for EventDomain {
ViewEvent::ModifySelection(Movement::RightWord).into(),
MoveToBeginningOfParagraph =>
ViewEvent::Move(Movement::StartOfParagraph).into(),
+ MoveToBeginningOfParagraphAndModifySelection =>
+ ViewEvent::ModifySelection(Movement::StartOfParagraph).into(),
MoveToEndOfParagraph =>
ViewEvent::Move(Movement::EndOfParagraph).into(),
+ MoveToEndOfParagraphAndModifySelection =>
+ ViewEvent::ModifySelection(Movement::EndOfParagraph).into(),
MoveToLeftEndOfLine =>
ViewEvent::Move(Movement::LeftOfLine).into(),
MoveToLeftEndOfLineAndModifySelection =>
@@ -210,6 +225,8 @@ impl From for EventDomain {
Redo => BufferEvent::Redo.into(),
Find { chars, case_sensitive, regex, whole_words } =>
ViewEvent::Find { chars, case_sensitive, regex, whole_words }.into(),
+ MultiFind { queries } =>
+ ViewEvent::MultiFind { queries }.into(),
FindNext { wrap_around, allow_same, modify_selection } =>
ViewEvent::FindNext { wrap_around, allow_same, modify_selection }.into(),
FindPrevious { wrap_around, allow_same, modify_selection } =>
@@ -221,6 +238,7 @@ impl From for EventDomain {
CancelOperation => ViewEvent::Cancel.into(),
Uppercase => BufferEvent::Uppercase.into(),
Lowercase => BufferEvent::Lowercase.into(),
+ Capitalize => BufferEvent::Capitalize.into(),
Indent => BufferEvent::Indent.into(),
Outdent => BufferEvent::Outdent.into(),
HighlightFind { visible } => ViewEvent::HighlightFind { visible }.into(),
@@ -235,6 +253,11 @@ impl From for EventDomain {
SpecialEvent::RequestHover { request_id, position }.into(),
SelectionIntoLines => ViewEvent::SelectionIntoLines.into(),
DuplicateLine => BufferEvent::DuplicateLine.into(),
+ IncreaseNumber => BufferEvent::IncreaseNumber.into(),
+ DecreaseNumber => BufferEvent::DecreaseNumber.into(),
+ ToggleRecording { recording_name } => SpecialEvent::ToggleRecording(recording_name).into(),
+ PlayRecording { recording_name } => SpecialEvent::PlayRecording(recording_name).into(),
+ ClearRecording { recording_name } => SpecialEvent::ClearRecording(recording_name).into(),
}
}
}
diff --git a/rust/core-lib/src/editor.rs b/rust/core-lib/src/editor.rs
index faca195fe..06defaeae 100644
--- a/rust/core-lib/src/editor.rs
+++ b/rust/core-lib/src/editor.rs
@@ -23,7 +23,7 @@ use xi_rope::interval::Interval;
use xi_rope::delta::{self, Delta, Transformer};
use xi_rope::engine::{Engine, RevId, RevToken};
use xi_rope::spans::SpansBuilder;
-use xi_trace::trace_block;
+use xi_trace::{trace_block, trace_payload};
use xi_rope::tree::Cursor;
use config::BufferItems;
@@ -37,11 +37,13 @@ use selection::{Selection, SelRegion};
use styles::ThemeStyleMap;
use view::{View, Replace};
use rpc::SelectionModifier;
+use word_boundaries::WordCursor;
#[cfg(not(feature = "ledger"))]
pub struct SyncStore;
#[cfg(feature = "ledger")]
use fuchsia::sync::SyncStore;
+use backspace::offset_for_delete_backwards;
// TODO This could go much higher without issue but while developing it is
// better to keep it low to expose bugs in the GC during casual testing.
@@ -72,6 +74,7 @@ pub struct Editor {
undos: BTreeSet,
/// undo groups that are no longer live and should be gc'ed
gc_undos: BTreeSet,
+ force_undo_group: bool,
this_edit_type: EditType,
last_edit_type: EditType,
@@ -115,6 +118,7 @@ impl Editor {
cur_undo: 1,
undos: BTreeSet::new(),
gc_undos: BTreeSet::new(),
+ force_undo_group: false,
last_edit_type: EditType::Other,
this_edit_type: EditType::Other,
layers: Layers::default(),
@@ -162,6 +166,16 @@ impl Editor {
self.engine.get_head_rev_id())
}
+ /// Set whether or not edits are forced into the same undo group rather than being split by
+ /// their EditType.
+ ///
+ /// This is used for things such as recording playback, where you don't want the
+ /// individual events to be undoable, but instead the entire playback should be.
+ pub(crate) fn set_force_undo_group(&mut self, force_undo_group: bool) {
+ trace_payload("Editor::set_force_undo_group", &["core"], force_undo_group.to_string());
+ self.force_undo_group = force_undo_group;
+ }
+
/// Sets this Editor's contents to `text`, preserving undo state and cursor
/// position when possible.
pub fn reload(&mut self, text: Rope) {
@@ -209,14 +223,22 @@ impl Editor {
/// `commit_delta` call.
fn add_delta(&mut self, delta: Delta) {
let head_rev_id = self.engine.get_head_rev_id();
- let undo_group;
+ let undo_group = self.calculate_undo_group();
+ self.last_edit_type = self.this_edit_type;
+ let priority = 0x10000;
+ self.engine.edit_rev(priority, undo_group, head_rev_id.token(), delta);
+ self.text = self.engine.get_head().clone();
+ }
- if !self.this_edit_type.breaks_undo_group(self.last_edit_type)
- && !self.live_undos.is_empty()
- {
- undo_group = *self.live_undos.last().unwrap();
+ pub(crate) fn calculate_undo_group(&mut self) -> usize {
+ let has_undos = !self.live_undos.is_empty();
+ let force_undo_group = self.force_undo_group;
+ let is_unbroken_group = !self.this_edit_type.breaks_undo_group(self.last_edit_type);
+
+ if has_undos && (force_undo_group || is_unbroken_group) {
+ *self.live_undos.last().unwrap()
} else {
- undo_group = self.undo_group_id;
+ let undo_group = self.undo_group_id;
self.gc_undos.extend(&self.live_undos[self.cur_undo..]);
self.live_undos.truncate(self.cur_undo);
self.live_undos.push(undo_group);
@@ -226,11 +248,8 @@ impl Editor {
self.gc_undos.insert(self.live_undos.remove(0));
}
self.undo_group_id += 1;
+ undo_group
}
- self.last_edit_type = self.this_edit_type;
- let priority = 0x10000;
- self.engine.edit_rev(priority, undo_group, head_rev_id.token(), delta);
- self.text = self.engine.get_head().clone();
}
/// generates a delta from a plugin's response and applies it to the buffer.
@@ -276,6 +295,10 @@ impl Editor {
Some((delta, last_text, keep_selections))
}
+ pub(crate) fn delta_rev_head(&self, target_rev_id: RevToken) -> Delta {
+ self.engine.delta_rev_head(target_rev_id)
+ }
+
#[cfg(not(target_os = "fuchsia"))]
fn gc_undos(&mut self) {
if self.revs_in_flight == 0 && !self.gc_undos.is_empty() {
@@ -340,28 +363,7 @@ impl Editor {
// could be improved by implementing a "backspace" movement instead.
let mut builder = delta::Builder::new(self.text.len());
for region in view.sel_regions() {
- let start = if !region.is_caret() {
- region.min()
- } else {
- // backspace deletes max(1, tab_size) contiguous spaces
- let (_, c) = view.offset_to_line_col(&self.text, region.start);
-
- let tab_off = c % config.tab_size;
- let tab_size = config.tab_size;
- let tab_size = if tab_off == 0 { tab_size } else { tab_off };
- let tab_start = region.start.saturating_sub(tab_size);
- let preceded_by_spaces = region.start > 0 &&
- (tab_start..region.start).all(|i| self.text.byte_at(i) == b' ');
- if preceded_by_spaces
- && config.translate_tabs_to_spaces
- && config.use_tab_stops {
- tab_start
- } else {
- self.text.prev_grapheme_offset(region.end)
- .unwrap_or(region.end)
- }
- };
-
+ let start = offset_for_delete_backwards(&view, ®ion, &self.text, &config);
let iv = Interval::new_closed_open(start, region.max());
if !iv.is_empty() {
builder.delete(iv);
@@ -398,7 +400,7 @@ impl Editor {
if save {
let saved = self.extract_sel_regions(&deletions)
.unwrap_or_default();
- *kill_ring = saved.into();
+ *kill_ring = Rope::from(saved);
}
self.delete_sel_regions(&deletions);
}
@@ -420,16 +422,16 @@ impl Editor {
/// Extracts non-caret selection regions into a string,
/// joining multiple regions with newlines.
- fn extract_sel_regions(&self, sel_regions: &[SelRegion]) -> Option {
+ fn extract_sel_regions(&self, sel_regions: &[SelRegion]) -> Option> {
let mut saved = None;
for region in sel_regions {
if !region.is_caret() {
- let val = self.text.slice_to_string(region);
+ let val = self.text.slice_to_cow(region);
match saved {
None => saved = Some(val),
Some(ref mut s) => {
- s.push('\n');
- s.push_str(&val);
+ s.to_mut().push('\n');
+ s.to_mut().push_str(&val);
}
}
}
@@ -519,7 +521,7 @@ impl Editor {
let tab_offset = view.line_col_to_offset(&self.text, line,
tab_text.len());
let interval = Interval::new_closed_open(offset, tab_offset);
- let leading_slice = self.text.slice_to_string(interval.start()..interval.end());
+ let leading_slice = self.text.slice_to_cow(interval.start()..interval.end());
if leading_slice == tab_text {
builder.delete(interval);
} else if let Some(first_char_col) = leading_slice.find(|c: char| !c.is_whitespace()) {
@@ -571,7 +573,7 @@ impl Editor {
pub(crate) fn do_copy(&self, view: &View) -> Value {
if let Some(val) = self.extract_sel_regions(view.sel_regions()) {
- Value::String(val)
+ Value::String(val.into_owned())
} else {
Value::Null
}
@@ -615,18 +617,26 @@ impl Editor {
for ®ion in view.sel_regions() {
if region.is_caret() {
- let middle = region.end;
- let start = self.text.prev_grapheme_offset(middle).unwrap_or(0);
- // Note: this matches Sublime's behavior. Cocoa would swap last
+ let mut middle = region.end;
+ let mut start = self.text.prev_grapheme_offset(middle).unwrap_or(0);
+ let mut end = self.text.next_grapheme_offset(middle).unwrap_or(middle);
+
+ // Note: this matches Emac's behavior. It swaps last
// two characters of line if at end of line.
- if let Some(end) = self.text.next_grapheme_offset(middle) {
- if start >= last {
- let interval = Interval::new_closed_open(start, end);
- let swapped = self.text.slice_to_string(middle..end) +
- &self.text.slice_to_string(start..middle);
- builder.replace(interval, Rope::from(swapped));
- last = end;
+ if start >= last {
+ let end_line_offset = view.offset_of_line(&self.text, view.line_of_offset(&self.text, end));
+ if end == middle || end == end_line_offset {
+ middle = start;
+ start = self.text.prev_grapheme_offset(middle).unwrap_or(0);
+ end = middle.wrapping_add(1);
}
+
+ let interval = Interval::new_closed_open(start, end);
+ let before = self.text.slice_to_cow(start..middle);
+ let after = self.text.slice_to_cow(middle..end);
+ let swapped: String = [after, before].concat();
+ builder.replace(interval, Rope::from(swapped));
+ last = end;
}
} else if let Some(previous_selection) = optional_previous_selection {
let current_interval = self.sel_region_to_interval_and_rope(region);
@@ -675,7 +685,7 @@ impl Editor {
let mut builder = delta::Builder::new(self.text.len());
for region in view.sel_regions() {
- let selected_text = self.text.slice_to_string(region);
+ let selected_text = self.text.slice_to_cow(region);
let interval = Interval::new_closed_open(region.min(), region.max());
builder.replace(interval, Rope::from(transform_function(&selected_text)));
}
@@ -684,6 +694,84 @@ impl Editor {
self.add_delta(builder.build());
}
}
+
+ /// Changes the number(s) under the cursor(s) with the `transform_function`.
+ /// If there is a number next to or on the beginning of the region, then
+ /// this number will be replaced with the result of `transform_function` and
+ /// the cursor will be placed at the end of the number.
+ /// Some Examples with a increment `transform_function`:
+ ///
+ /// "|1234" -> "1235|"
+ /// "12|34" -> "1235|"
+ /// "-|12" -> "-11|"
+ /// "another number is 123|]" -> "another number is 124"
+ ///
+ /// This function also works fine with multiple regions.
+ fn change_number Option>(&mut self, view: &View,
+ transform_function: F) {
+ let mut builder = delta::Builder::new(self.text.len());
+ for region in view.sel_regions() {
+
+ let mut cursor = WordCursor::new(&self.text, region.end);
+ let (mut start, end) = cursor.select_word();
+
+ // if the word begins with '-', then it is a negative number
+ if start > 0 && self.text.byte_at(start - 1) == ('-' as u8) {
+ start -= 1;
+ }
+
+ let word = self.text.slice_to_cow(start..end);
+ if let Some(number) = word.parse::().ok().and_then(&transform_function) {
+ let interval = Interval::new_closed_open(start, end);
+ builder.replace(interval, Rope::from(number.to_string()));
+ }
+ }
+
+ if !builder.is_empty() {
+ self.this_edit_type = EditType::Other;
+ self.add_delta(builder.build());
+ }
+ }
+
+ // capitalization behaviour is similar to behaviour in XCode
+ fn capitalize_text(&mut self, view: &mut View) {
+ let mut builder = delta::Builder::new(self.text.len());
+ let mut final_selection = Selection::new();
+
+ for ®ion in view.sel_regions() {
+ final_selection.add_region(SelRegion::new(region.max(), region.max()));
+ let mut word_cursor = WordCursor::new(&self.text, region.min());
+
+ loop {
+ // capitalize each word in the current selection
+ let (start, end) = word_cursor.select_word();
+
+ if start < end {
+ let interval = Interval::new_closed_open(start, end);
+ let word = self.text.slice_to_cow(start..end);
+
+ // first letter is uppercase, remaining letters are lowercase
+ let (first_char, rest) = word.split_at(1);
+ let capitalized_text = [first_char.to_uppercase(), rest.to_lowercase()].concat();
+ builder.replace(interval, Rope::from(capitalized_text));
+ }
+
+ if word_cursor.next_boundary().is_none() || end > region.max() {
+ break;
+ }
+ }
+ }
+
+ if !builder.is_empty() {
+ self.this_edit_type = EditType::Other;
+ self.add_delta(builder.build());
+ }
+
+ // at the end of the transformation carets are located at the end of the words that were
+ // transformed last in the selections
+ view.collapse_selections(&self.text);
+ view.set_selection(&self.text, final_selection);
+ }
fn duplicate_line(&mut self, view: &View, config: &BufferItems) {
let mut builder = delta::Builder::new(self.text.len());
@@ -735,6 +823,7 @@ impl Editor {
Redo => self.do_redo(),
Uppercase => self.transform_text(view, |s| s.to_uppercase()),
Lowercase => self.transform_text(view, |s| s.to_lowercase()),
+ Capitalize => self.capitalize_text(view),
Indent => self.modify_indent(view, config, IndentDirection::In),
Outdent => self.modify_indent(view, config, IndentDirection::Out),
InsertNewline => self.insert_newline(view, config),
@@ -745,6 +834,8 @@ impl Editor {
ReplaceNext => self.replace(view, false),
ReplaceAll => self.replace(view, true),
DuplicateLine => self.duplicate_line(view, config),
+ IncreaseNumber => self.change_number(view, |s| s.checked_add(1)),
+ DecreaseNumber => self.change_number(view, |s| s.checked_sub(1)),
}
}
@@ -817,7 +908,7 @@ impl Editor {
end_off = text.prev_codepoint_offset(end_off + 1).unwrap();
}
- let chunk = text.slice_to_string(offset..end_off);
+ let chunk = text.slice_to_cow(offset..end_off).into_owned();
let first_line = text.line_of_offset(offset);
let first_line_offset = offset - text.offset_of_line(first_line);
diff --git a/rust/core-lib/src/event_context.rs b/rust/core-lib/src/event_context.rs
index e1abd17c3..cac64ed38 100644
--- a/rust/core-lib/src/event_context.rs
+++ b/rust/core-lib/src/event_context.rs
@@ -22,8 +22,10 @@ use std::time::{Duration, Instant};
use serde_json::{self, Value};
use xi_rope::Rope;
+use xi_rope::tree::Node;
+use xi_rope::delta::Delta;
use xi_rope::interval::Interval;
-use xi_rope::rope::LinesMetric;
+use xi_rope::rope::{LinesMetric, RopeInfo};
use xi_rpc::{RemoteError, Error as RpcError};
use xi_trace::trace_block;
@@ -39,6 +41,7 @@ use tabs::{BufferId, PluginId, ViewId, RENDER_VIEW_IDLE_MASK};
use editor::Editor;
use file::FileInfo;
use edit_types::{EventDomain, SpecialEvent};
+use recorder::Recorder;
use client::Client;
use plugins::Plugin;
use selection::SelRegion;
@@ -65,6 +68,7 @@ pub struct EventContext<'a> {
pub(crate) editor: &'a RefCell,
pub(crate) info: Option<&'a FileInfo>,
pub(crate) config: &'a BufferItems,
+ pub(crate) recorder: &'a RefCell,
pub(crate) language: LanguageId,
pub(crate) view: &'a RefCell,
pub(crate) siblings: Vec<&'a RefCell>,
@@ -104,19 +108,39 @@ impl<'a> EventContext<'a> {
}
pub(crate) fn do_edit(&mut self, cmd: EditNotification) {
- use self::EventDomain as E;
let event: EventDomain = cmd.into();
+
+ {
+ // Handle recording-- clone every non-toggle and play event into the recording buffer
+ let mut recorder = self.recorder.borrow_mut();
+ match (recorder.is_recording(), &event) {
+ (_, EventDomain::Special(SpecialEvent::ToggleRecording(recording_name))) => {
+ recorder.toggle_recording(recording_name.clone());
+ },
+ // Don't save special events
+ (true, EventDomain::Special(_)) =>
+ warn!("Special events cannot be recorded-- ignoring event {:?}", event),
+ (true, event) => recorder.record(event.clone().into()),
+ _ => {}
+ }
+ }
+
+ self.dispatch_event(event);
+ self.after_edit("core");
+ self.render_if_needed();
+ }
+
+ fn dispatch_event(&mut self, event: EventDomain) {
+ use self::EventDomain as E;
match event {
E::View(cmd) => {
- self.with_view(|view, text| view.do_edit(text, cmd));
- self.editor.borrow_mut().update_edit_type();
- },
+ self.with_view(|view, text| view.do_edit(text, cmd));
+ self.editor.borrow_mut().update_edit_type();
+ },
E::Buffer(cmd) => self.with_editor(
|ed, view, k_ring, conf| ed.do_edit(view, k_ring, conf, cmd)),
E::Special(cmd) => self.do_special(cmd),
}
- self.after_edit("core");
- self.render_if_needed();
}
fn do_special(&mut self, cmd: SpecialEvent) {
@@ -137,8 +161,42 @@ impl<'a> EventContext<'a> {
}),
SpecialEvent::RequestLines(LineRange { first, last }) =>
self.do_request_lines(first as usize, last as usize),
- SpecialEvent::RequestHover{ request_id, position } =>
- self.do_request_hover(request_id, position)
+ SpecialEvent::RequestHover { request_id, position } =>
+ self.do_request_hover(request_id, position),
+ SpecialEvent::ToggleRecording(_) => {}
+ SpecialEvent::PlayRecording(recording_name) => {
+ let recorder = self.recorder.borrow();
+
+ let starting_revision = self.editor.borrow_mut().get_head_rev_token();
+
+ // Don't group with the previous action
+ self.editor.borrow_mut().update_edit_type();
+ self.editor.borrow_mut().calculate_undo_group();
+
+ // No matter what, our entire block must belong to the same undo group
+ self.editor.borrow_mut().set_force_undo_group(true);
+ recorder.play(&recording_name, |event| {
+ self.dispatch_event(event.clone());
+
+ let mut editor = self.editor.borrow_mut();
+ let (delta, last_text, keep_sels) = match editor.commit_delta() {
+ Some(edit_info) => edit_info,
+ None => return,
+ };
+ self.update_views(&editor, &delta, &last_text, keep_sels);
+ });
+ self.editor.borrow_mut().set_force_undo_group(false);
+
+ // The action that follows the block must belong to a separate undo group
+ self.editor.borrow_mut().update_edit_type();
+
+ let delta = self.editor.borrow_mut().delta_rev_head(starting_revision);
+ self.update_plugins(&mut self.editor.borrow_mut(), delta, "core")
+ }
+ SpecialEvent::ClearRecording(recording_name) => {
+ let mut recorder = self.recorder.borrow_mut();
+ recorder.clear(&recording_name);
+ }
}
}
@@ -200,17 +258,37 @@ impl<'a> EventContext<'a> {
/// This only updates internal state; it does not update the client.
fn after_edit(&mut self, author: &str) {
let _t = trace_block("EventContext::after_edit", &["core"]);
+
let mut ed = self.editor.borrow_mut();
let (delta, last_text, keep_sels) = match ed.commit_delta() {
Some(edit_info) => edit_info,
None => return,
};
+
+ self.update_views(&ed, &delta, &last_text, keep_sels);
+ self.update_plugins(&mut ed, delta, author);
+
+ //if we have no plugins we always render immediately.
+ if !self.plugins.is_empty() {
+ let mut view = self.view.borrow_mut();
+ if !view.has_pending_render() {
+ let timeout = Instant::now() + RENDER_DELAY;
+ let view_id: usize = self.view_id.into();
+ let token = RENDER_VIEW_IDLE_MASK | view_id;
+ self.client.schedule_timer(timeout, token);
+ view.set_has_pending_render(true);
+ }
+ }
+ }
+
+ fn update_views(&self, ed: &Editor, delta: &Delta, last_text: &Node, keep_sels: bool) {
let mut width_cache = self.width_cache.borrow_mut();
let iter_views = iter::once(&self.view).chain(self.siblings.iter());
iter_views.for_each(|view| view.borrow_mut()
- .after_edit(ed.get_buffer(), &last_text, &delta,
- self.client, &mut width_cache, keep_sels));
+ .after_edit(ed.get_buffer(), last_text, delta, self.client, &mut width_cache, keep_sels));
+ }
+ fn update_plugins(&self, ed: &mut Editor, delta: Delta, author: &str) {
let new_len = delta.new_document_len();
let nb_lines = ed.get_buffer().measure::() + 1;
// don't send the actual delta if it is too large, by some heuristic
@@ -224,14 +302,14 @@ impl<'a> EventContext<'a> {
let edit_type_str = v.as_str().unwrap().to_string();
let update = PluginUpdate::new(
- self.view_id,
- ed.get_head_rev_token(),
- delta,
- new_len,
- nb_lines,
- Some(undo_group),
- edit_type_str,
- author.into());
+ self.view_id,
+ ed.get_head_rev_token(),
+ delta,
+ new_len,
+ nb_lines,
+ Some(undo_group),
+ edit_type_str,
+ author.into());
// we always increment and decrement regardless of whether we're
@@ -249,18 +327,6 @@ impl<'a> EventContext<'a> {
});
ed.dec_revs_in_flight();
ed.update_edit_type();
-
- //if we have no plugins we always render immediately.
- if !self.plugins.is_empty() {
- let mut view = self.view.borrow_mut();
- if !view.has_pending_render() {
- let timeout = Instant::now() + RENDER_DELAY;
- let view_id: usize = self.view_id.into();
- let token = RENDER_VIEW_IDLE_MASK | view_id;
- self.client.schedule_timer(timeout, token);
- view.set_has_pending_render(true);
- }
- }
}
/// Renders the view, if a render has not already been scheduled.
@@ -308,6 +374,7 @@ impl<'a> EventContext<'a> {
&available_plugins);
self.client.config_changed(self.view_id, config);
+ self.client.language_changed(self.view_id, &self.language);
self.update_wrap_state();
self.render()
}
@@ -343,6 +410,16 @@ impl<'a> EventContext<'a> {
self.render()
}
+ pub(crate) fn language_changed(
+ &mut self,
+ new_language_id: &LanguageId
+ ) {
+ self.language = new_language_id.clone();
+ self.client.language_changed(self.view_id, new_language_id);
+ self.plugins.iter()
+ .for_each(|plug| plug.language_changed(self.view_id, new_language_id));
+ }
+
pub(crate) fn reload(&mut self, text: Rope) {
//TODO: It would be nice if we could preserve the existing selections,
//but to do that correctly we would need to compute a real delta between
@@ -439,7 +516,7 @@ impl<'a> EventContext<'a> {
Err(err) => warn!("Hover Response from Client Error {:?}", err)
}
}
-
+
/// Gives the requested position in UTF-8 offset format to be sent to plugin
/// If position is `None`, it tries to get the current Caret Position and use
/// that instead
@@ -452,6 +529,7 @@ impl<'a> EventContext<'a> {
#[cfg(test)]
+#[cfg_attr(rustfmt, rustfmt_skip)]
mod tests {
use super::*;
use config::ConfigManager;
@@ -468,6 +546,7 @@ mod tests {
style_map: RefCell,
width_cache: RefCell,
config_manager: ConfigManager,
+ recorder: RefCell,
}
impl ContextHarness {
@@ -483,8 +562,9 @@ mod tests {
let kill_ring = RefCell::new(Rope::from(""));
let style_map = RefCell::new(ThemeStyleMap::new(None));
let width_cache = RefCell::new(WidthCache::new());
+ let recorder = RefCell::new(Recorder::new());
ContextHarness { view, editor, client, core_ref, kill_ring,
- style_map, width_cache, config_manager }
+ style_map, width_cache, config_manager, recorder }
}
/// Renders the text and selections. cursors are represented with
@@ -522,6 +602,7 @@ mod tests {
info: None,
siblings: Vec::new(),
plugins: Vec::new(),
+ recorder: &self.recorder,
client: &self.client,
kill_ring: &self.kill_ring,
style_map: &self.style_map,
@@ -558,6 +639,21 @@ mod tests {
lines.";
let harness = ContextHarness::new(initial_text);
let mut ctx = harness.make_context();
+
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 0, ty: PointSelect });
+ ctx.do_edit(EditNotification::MoveToEndOfParagraphAndModifySelection);
+ assert_eq!(harness.debug_render(),"\
+ [this is a string|]\n\
+ that has three\n\
+ lines." );
+
+ ctx.do_edit(EditNotification::MoveToEndOfParagraph);
+ ctx.do_edit(EditNotification::MoveToBeginningOfParagraphAndModifySelection);
+ assert_eq!(harness.debug_render(),"\
+ [|this is a string]\n\
+ that has three\n\
+ lines." );
+
ctx.do_edit(EditNotification::Gesture { line: 0, col: 0, ty: PointSelect });
assert_eq!(harness.debug_render(),"\
|this is a string\n\
@@ -657,6 +753,529 @@ mod tests {
lines|." );
}
+ #[test]
+ fn delete_combining_enclosing_keycaps_tests() {
+ use rpc::GestureType::*;
+
+ let initial_text = "1\u{E0101}\u{20E3}";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 8, ty: PointSelect });
+
+ assert_eq!(harness.debug_render(), "1\u{E0101}\u{20E3}|");
+
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // multiple COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "1\u{20E3}\u{20E3}".into() });
+ assert_eq!(harness.debug_render(), "1\u{20E3}\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{20E3}".into() });
+ assert_eq!(harness.debug_render(), "\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated multiple COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{20E3}\u{20E3}".into() });
+ assert_eq!(harness.debug_render(), "\u{20E3}\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+ }
+
+ #[test]
+ fn delete_variation_selector_tests() {
+ use rpc::GestureType::*;
+
+ let initial_text = "\u{FE0F}";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 3, ty: PointSelect });
+
+ assert_eq!(harness.debug_render(), "\u{FE0F}|");
+
+ // Isolated variation selector
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{E0100}".into() });
+ assert_eq!(harness.debug_render(), "\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated multiple variation selectors
+ ctx.do_edit(EditNotification::Insert { chars: "\u{FE0F}\u{FE0F}".into() });
+ assert_eq!(harness.debug_render(), "\u{FE0F}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{FE0F}\u{E0100}".into() });
+ assert_eq!(harness.debug_render(), "\u{FE0F}\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{E0100}\u{FE0F}".into() });
+ assert_eq!(harness.debug_render(), "\u{E0100}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{E0100}\u{E0100}".into() });
+ assert_eq!(harness.debug_render(), "\u{E0100}\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Multiple variation selectors
+ ctx.do_edit(EditNotification::Insert { chars: "#\u{FE0F}\u{FE0F}".into() });
+ assert_eq!(harness.debug_render(), "#\u{FE0F}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "#\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "#\u{FE0F}\u{E0100}".into() });
+ assert_eq!(harness.debug_render(), "#\u{FE0F}\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "#\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "#\u{E0100}\u{FE0F}".into() });
+ assert_eq!(harness.debug_render(), "#\u{E0100}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "#\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "#\u{E0100}\u{E0100}".into() });
+ assert_eq!(harness.debug_render(), "#\u{E0100}\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "#\u{E0100}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+ }
+
+ #[test]
+ fn delete_emoji_zwj_sequence_tests() {
+ use rpc::GestureType::*;
+ let initial_text = "\u{1F441}\u{200D}\u{1F5E8}";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}\u{1F5E8}|");
+
+ // U+200D is ZERO WIDTH JOINER.
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F441}\u{200D}\u{1F5E8}\u{FE0E}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}\u{1F5E8}\u{FE0E}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F469}\u{200D}\u{1F373}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F469}\u{200D}\u{1F373}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F487}\u{200D}\u{2640}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F487}\u{200D}\u{2640}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F487}\u{200D}\u{2640}\u{FE0F}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F487}\u{200D}\u{2640}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F468}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F48B}\u{200D}\u{1F468}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F468}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F48B}\u{200D}\u{1F468}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Emoji modifier can be appended to the first emoji.
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F469}\u{1F3FB}\u{200D}\u{1F4BC}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F469}\u{1F3FB}\u{200D}\u{1F4BC}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // End with ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F441}\u{200D}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F441}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Start with ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}\u{1F5E8}".into() });
+ assert_eq!(harness.debug_render(), "\u{200D}\u{1F5E8}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::Insert { chars: "\u{FE0E}\u{200D}\u{1F5E8}".into() });
+ assert_eq!(harness.debug_render(), "\u{FE0E}\u{200D}\u{1F5E8}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{FE0E}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{FE0E}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Multiple ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F441}\u{200D}\u{200D}\u{1F5E8}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}\u{200D}\u{1F5E8}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F441}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}".into() });
+ assert_eq!(harness.debug_render(), "\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated multiple ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}\u{200D}".into() });
+ assert_eq!(harness.debug_render(), "\u{200D}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+ }
+
+ #[test]
+ fn delete_flags_tests() {
+ use rpc::GestureType::*;
+ let initial_text = "\u{1F1FA}";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 4, ty: PointSelect });
+
+ // Isolated regional indicator symbol
+ assert_eq!(harness.debug_render(), "\u{1F1FA}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Odd numbered regional indicator symbols
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1FA}\u{1F1F8}\u{1F1FA}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F1FA}\u{1F1F8}\u{1F1FA}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F1FA}\u{1F1F8}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Incomplete sequence. (no tag_term: U+E007E)
+ ctx.do_edit(EditNotification::Insert { chars: "a\u{1F3F4}\u{E0067}b".into() });
+ assert_eq!(harness.debug_render(), "a\u{1F3F4}\u{E0067}b|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{1F3F4}\u{E0067}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{1F3F4}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a|");
+
+ // No tag_base
+ ctx.do_edit(EditNotification::Insert { chars: "\u{E0067}\u{E007F}b".into() });
+ assert_eq!(harness.debug_render(), "a\u{E0067}\u{E007F}b|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{E0067}\u{E007F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{E0067}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a|");
+
+ // Isolated tag chars
+ ctx.do_edit(EditNotification::Insert { chars: "\u{E0067}\u{E0067}b".into() });
+ assert_eq!(harness.debug_render(), "a\u{E0067}\u{E0067}b|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{E0067}\u{E0067}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{E0067}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a|");
+
+ // Isolated tab term.
+ ctx.do_edit(EditNotification::Insert { chars: "\u{E007F}\u{E007F}b".into() });
+ assert_eq!(harness.debug_render(), "a\u{E007F}\u{E007F}b|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{E007F}\u{E007F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{E007F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a|");
+
+ // Immediate tag_term after tag_base
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F3F4}\u{E007F}\u{1F3F4}\u{E007F}b".into() });
+ assert_eq!(harness.debug_render(), "a\u{1F3F4}\u{E007F}\u{1F3F4}\u{E007F}b|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{1F3F4}\u{E007F}\u{1F3F4}\u{E007F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a\u{1F3F4}\u{E007F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "a|");
+ }
+
+ #[test]
+ fn delete_emoji_modifier_tests() {
+ use rpc::GestureType::*;
+ let initial_text = "\u{1F466}\u{1F3FB}";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 8, ty: PointSelect });
+
+ // U+1F3FB is EMOJI MODIFIER FITZPATRICK TYPE-1-2.
+ assert_eq!(harness.debug_render(), "\u{1F466}\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F3FB}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Isolated multiple emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F3FB}\u{1F3FB}".into() });
+ assert_eq!(harness.debug_render(), "\u{1F3FB}\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Multiple emoji modifiers
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F466}\u{1F3FB}\u{1F3FB}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F466}\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+ }
+
+ #[test]
+ fn delete_mixed_edge_cases_tests() {
+ use rpc::GestureType::*;
+ let initial_text = "";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 7, ty: PointSelect });
+
+ // COMBINING ENCLOSING KEYCAP + variation selector
+ ctx.do_edit(EditNotification::Insert { chars: "1\u{20E3}\u{FE0F}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Variation selector + COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{2665}\u{FE0F}\u{20E3}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{2665}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // COMBINING ENCLOSING KEYCAP + ending with ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "1\u{20E3}\u{200D}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // COMBINING ENCLOSING KEYCAP + ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "1\u{20E3}\u{200D}\u{1F5E8}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1\u{20E3}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Start with ZERO WIDTH JOINER + COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}\u{20E3}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // ZERO WIDTH JOINER + COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F441}\u{200D}\u{20E3}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F441}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F441}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // COMBINING ENCLOSING KEYCAP + regional indicator symbol
+ ctx.do_edit(EditNotification::Insert { chars: "1\u{20E3}\u{1F1FA}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Regional indicator symbol + COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1FA}\u{20E3}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F1FA}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // COMBINING ENCLOSING KEYCAP + emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "1\u{20E3}\u{1F3FB}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "1\u{20E3}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Emoji modifier + COMBINING ENCLOSING KEYCAP
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F466}\u{1F3FB}\u{20E3}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1f466}\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Variation selector + end with ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{2665}\u{FE0F}\u{200D}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{2665}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Variation selector + ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F469}\u{200D}\u{2764}\u{FE0F}\u{200D}\u{1F469}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Start with ZERO WIDTH JOINER + variation selector
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}\u{FE0F}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // ZERO WIDTH JOINER + variation selector
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F469}\u{200D}\u{FE0F}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F469}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Variation selector + regional indicator symbol
+ ctx.do_edit(EditNotification::Insert { chars: "\u{2665}\u{FE0F}\u{1F1FA}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{2665}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Regional indicator symbol + variation selector
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1FA}\u{FE0F}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Variation selector + emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "\u{2665}\u{FE0F}\u{1F3FB}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{2665}\u{FE0F}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Emoji modifier + variation selector
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F466}\u{1F3FB}\u{FE0F}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F466}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Start withj ZERO WIDTH JOINER + regional indicator symbol
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}\u{1F1FA}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // ZERO WIDTH JOINER + Regional indicator symbol
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F469}\u{200D}\u{1F1FA}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F469}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F469}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Regional indicator symbol + end with ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1FA}\u{200D}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F1FA}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Regional indicator symbol + ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1FA}\u{200D}\u{1F469}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Start with ZERO WIDTH JOINER + emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "\u{200D}\u{1F3FB}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // ZERO WIDTH JOINER + emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F469}\u{200D}\u{1F3FB}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F469}\u{200D}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F469}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Emoji modifier + end with ZERO WIDTH JOINER
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F466}\u{1F3FB}\u{200D}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F466}\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Regional indicator symbol + Emoji modifier
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1FA}\u{1F3FB}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F1FA}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // Emoji modifier + regional indicator symbol
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F466}\u{1F3FB}\u{1F1FA}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F466}\u{1F3FB}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+
+ // RIS + LF
+ ctx.do_edit(EditNotification::Insert { chars: "\u{1F1E6}\u{000A}".into() });
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "\u{1F1E6}|");
+ ctx.do_edit(EditNotification::DeleteBackward);
+ assert_eq!(harness.debug_render(), "|");
+ }
#[test]
fn delete_tests() {
@@ -839,4 +1458,258 @@ mod tests {
that has three\n\
|lines." );
}
+
+ #[test]
+ fn number_change_tests() {
+ use rpc::GestureType::*;
+ let harness = ContextHarness::new("");
+ let mut ctx = harness.make_context();
+ // Single indent and outdent test
+ ctx.do_edit(EditNotification::Insert { chars: "1234".into() });
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "1235|");
+
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 2, ty: PointSelect });
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "1236|");
+
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "-42".into() });
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "-41|");
+
+ // Cursor is on the 3
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 336 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a 335| text example");
+
+ // Cursor is on of the 3
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a -336 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a -337| text example");
+
+ // Cursor is on the 't' of text
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a -336 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 15, ty: PointSelect });
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a -336 |text example");
+
+ // test multiple iterations
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 336 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a 339| text example");
+
+ // test changing number of chars
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 10 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a 9| text example");
+
+ // test going negative
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 0 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a -1| text example");
+
+ // test going positive
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a -1 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 12, ty: PointSelect });
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a 0| text example");
+
+ // if it begins in a region, nothing will happen
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 10 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 10, ty: PointSelect });
+ ctx.do_edit(EditNotification::MoveToEndOfDocumentAndModifySelection);
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a [10 text example|]");
+
+ // If a number just happens to be in a region, nothing will happen
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 10 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 5, ty: PointSelect });
+ ctx.do_edit(EditNotification::MoveToEndOfDocumentAndModifySelection);
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this [is a 10 text example|]");
+
+ // if it ends on a region, the number will be changed
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 10".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 0, ty: PointSelect });
+ ctx.do_edit(EditNotification::MoveToEndOfDocumentAndModifySelection);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "[this is a 11|]");
+
+ // if only a part of a number is in a region, the whole number will be changed
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "this is a 1000 text example".into() });
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 11, ty: PointSelect });
+ ctx.do_edit(EditNotification::MoveRightAndModifySelection);
+ ctx.do_edit(EditNotification::DecreaseNumber);
+ assert_eq!(harness.debug_render(), "this is a 999| text example");
+
+ // invalid numbers
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "10_000".into() });
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "10_000|");
+
+ // decimals are kinda accounted for (i.e. 4.55 becomes 4.56 (good), but 4.99 becomes 4.100 (bad)
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "4.55".into() });
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "4.56|");
+
+ // invalid numbers
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ ctx.do_edit(EditNotification::Insert { chars: "0xFF03".into() });
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "0xFF03|");
+
+ // Test multiple selections
+ ctx.do_edit(EditNotification::MoveToEndOfDocument);
+ ctx.do_edit(EditNotification::DeleteToBeginningOfLine);
+ let multi_text = "\
+ example 42 number\n\
+ example 90 number\n\
+ Done.";
+ ctx.do_edit(EditNotification::Insert { chars: multi_text.into() });
+ ctx.do_edit(EditNotification::Gesture { line: 1, col: 9, ty: PointSelect });
+ ctx.do_edit(EditNotification::AddSelectionAbove);
+ ctx.do_edit(EditNotification::IncreaseNumber);
+ assert_eq!(harness.debug_render(), "\
+ example 43| number\n\
+ example 91| number\n\
+ Done.");
+ }
+
+ #[test]
+ fn text_recording() {
+ use rpc::GestureType::*;
+ let initial_text = "";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+
+ let recording_name = String::new();
+
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 0, ty: PointSelect });
+ assert_eq!(harness.debug_render(), "|");
+
+ ctx.do_edit(EditNotification::ToggleRecording { recording_name: Some(recording_name.clone()) });
+
+ ctx.do_edit(EditNotification::Insert { chars: "Foo ".to_owned() });
+ ctx.do_edit(EditNotification::Insert { chars: "B".to_owned() });
+ ctx.do_edit(EditNotification::Insert { chars: "A".to_owned() });
+ ctx.do_edit(EditNotification::Insert { chars: "R".to_owned() });
+ assert_eq!(harness.debug_render(), "Foo BAR|");
+
+ ctx.do_edit(EditNotification::ToggleRecording { recording_name: Some(recording_name.clone())});
+ ctx.do_edit(EditNotification::Insert { chars: " ".to_owned() });
+
+ ctx.do_edit(EditNotification::PlayRecording { recording_name });
+ assert_eq!(harness.debug_render(), "Foo BAR Foo BAR|");
+ }
+
+ #[test]
+ fn movement_recording() {
+ use rpc::GestureType::*;
+ let initial_text = "\
+ this is a string\n\
+ that has about\n\
+ four really nice\n\
+ lines to see.";
+ let harness = ContextHarness::new(initial_text);
+ let mut ctx = harness.make_context();
+
+ let recording_name = String::new();
+
+ ctx.do_edit(EditNotification::Gesture { line: 0, col: 5, ty: PointSelect });
+ assert_eq!(harness.debug_render(),"\
+ this |is a string\n\
+ that has about\n\
+ four really nice\n\
+ lines to see." );
+
+ ctx.do_edit(EditNotification::ToggleRecording { recording_name: Some(recording_name.clone()) });
+
+ // Swap last word of the current line and the line below
+ ctx.do_edit(EditNotification::AddSelectionBelow);
+ ctx.do_edit(EditNotification::MoveToRightEndOfLine);
+ ctx.do_edit(EditNotification::MoveWordLeftAndModifySelection);
+ ctx.do_edit(EditNotification::Transpose);
+ ctx.do_edit(EditNotification::CancelOperation);
+ ctx.do_edit(EditNotification::MoveToRightEndOfLine);
+ assert_eq!(harness.debug_render(),"\
+ this is a about|\n\
+ that has string\n\
+ four really nice\n\
+ lines to see." );
+
+ ctx.do_edit(EditNotification::ToggleRecording { recording_name: Some(recording_name.clone())});
+
+ ctx.do_edit(EditNotification::Gesture { line: 2, col: 5, ty: PointSelect });
+ ctx.do_edit(EditNotification::PlayRecording { recording_name: recording_name.clone() });
+ assert_eq!(harness.debug_render(),"\
+ this is a about\n\
+ that has string\n\
+ four really see.|\n\
+ lines to nice" );
+
+ // Undo entire playback in a single command
+ ctx.do_edit(EditNotification::Undo);
+ assert_eq!(harness.debug_render(),"\
+ this is a about\n\
+ that has string\n\
+ four really nice|\n\
+ lines to see." );
+
+ // Make sure we can redo in a single command as well
+ ctx.do_edit(EditNotification::Redo);
+ assert_eq!(harness.debug_render(),"\
+ this is a about\n\
+ that has string\n\
+ four really see.|\n\
+ lines to nice" );
+
+ // We shouldn't be able to use cleared recordings
+ ctx.do_edit(EditNotification::Undo);
+ ctx.do_edit(EditNotification::Undo);
+ ctx.do_edit(EditNotification::ClearRecording { recording_name: recording_name.clone() });
+ ctx.do_edit(EditNotification::PlayRecording { recording_name });
+ assert_eq!(harness.debug_render(),"\
+ this is a string\n\
+ that has about\n\
+ four really nice|\n\
+ lines to see." );
+ }
}
diff --git a/rust/core-lib/src/find.rs b/rust/core-lib/src/find.rs
index 2192b4427..fc4c55bb7 100644
--- a/rust/core-lib/src/find.rs
+++ b/rust/core-lib/src/find.rs
@@ -31,6 +31,9 @@ const REGEX_SIZE_LIMIT: usize = 1000000;
/// Information about search queries and number of matches for find
#[derive(Serialize, Deserialize, Debug)]
pub struct FindStatus {
+ /// Identifier for the current search query.
+ id: usize,
+
/// The current search query.
chars: Option,
@@ -49,25 +52,26 @@ pub struct FindStatus {
/// Contains logic to search text
pub struct Find {
- // todo: link to search query so that search results can be correlated back to query
-
+ /// Uniquely identifies this search query.
+ id: usize,
/// The occurrences, which determine the highlights, have been updated.
hls_dirty: bool,
- /// The currently active search string
+ /// The currently active search string.
search_string: Option,
- /// The case matching setting for the currently active search
+ /// The case matching setting for the currently active search.
case_matching: CaseMatching,
- /// The search query should be considered as regular expression
+ /// The search query should be considered as regular expression.
regex: Option,
/// Query matches only whole words.
whole_words: bool,
- /// The set of all known find occurrences (highlights)
+ /// The set of all known find occurrences (highlights).
occurrences: Selection,
}
impl Find {
- pub fn new() -> Find {
+ pub fn new(id: usize) -> Find {
Find {
+ id: id,
hls_dirty: true,
search_string: None,
case_matching: CaseMatching::CaseInsensitive,
@@ -77,6 +81,10 @@ impl Find {
}
}
+ pub fn id(&self) -> usize {
+ self.id
+ }
+
pub fn occurrences(&self) -> &Selection {
&self.occurrences
}
@@ -88,6 +96,7 @@ impl Find {
pub fn find_status(&self, matches_only: bool) -> FindStatus {
if matches_only {
FindStatus {
+ id: self.id,
chars: None,
case_sensitive: None,
is_regex: None,
@@ -96,6 +105,7 @@ impl Find {
}
} else {
FindStatus {
+ id: self.id,
chars: self.search_string.clone(),
case_sensitive: Some(self.case_matching == CaseMatching::Exact),
is_regex: Some(self.regex.is_some()),
@@ -160,13 +170,13 @@ impl Find {
}
/// Set search parameters and executes the search.
- pub fn do_find(&mut self, text: &Rope, search_string: String, case_sensitive: bool,
+ pub fn do_find(&mut self, text: &Rope, search_string: &str, case_sensitive: bool,
is_regex: bool, whole_words: bool) {
if search_string.len() == 0 {
self.unset();
}
- self.set_find(&search_string, case_sensitive, is_regex, whole_words);
+ self.set_find(search_string, case_sensitive, is_regex, whole_words);
self.update_find(text, 0, text.len(), false);
}
diff --git a/rust/core-lib/src/lib.rs b/rust/core-lib/src/lib.rs
index b0c8a7bdb..a2adb7ee8 100644
--- a/rust/core-lib/src/lib.rs
+++ b/rust/core-lib/src/lib.rs
@@ -44,6 +44,7 @@ extern crate syntect;
extern crate toml;
#[cfg(feature = "notify")]
extern crate notify;
+extern crate memchr;
extern crate xi_rope;
extern crate xi_rpc;
@@ -64,67 +65,38 @@ mod ledger_includes {
#[cfg(feature = "ledger")]
use ledger_includes::*;
-/// Internal data structures and logic.
-///
-/// These internals are not part of the public API (for the purpose of binding to
-/// a front-end), but are exposed here, largely so they appear in documentation.
-#[path=""]
-pub mod internal {
- pub mod client;
- pub mod core;
- pub mod tabs;
- pub mod editor;
- pub mod edit_types;
- pub mod event_context;
- pub mod file;
- pub mod find;
- pub mod view;
- pub mod linewrap;
- pub mod plugins;
- #[cfg(feature = "ledger")]
- pub mod fuchsia;
- pub mod styles;
- pub mod word_boundaries;
- pub mod index_set;
- pub mod selection;
- pub mod movement;
- pub mod syntax;
- pub mod layers;
- pub mod config;
- #[cfg(feature = "notify")]
- pub mod watcher;
- pub mod line_cache_shadow;
- pub mod width_cache;
-}
+pub mod client;
+pub mod core;
+pub mod tabs;
+pub mod editor;
+pub mod edit_types;
+pub mod event_context;
+pub mod file;
+pub mod find;
+pub mod view;
+pub mod linewrap;
+pub mod plugins;
+#[cfg(feature = "ledger")]
+pub mod fuchsia;
+pub mod styles;
+pub mod word_boundaries;
+pub mod index_set;
+pub mod selection;
+pub mod movement;
+pub mod syntax;
+pub mod layers;
+pub mod config;
+pub mod recorder;
+#[cfg(feature = "notify")]
+pub mod watcher;
+pub mod line_cache_shadow;
+pub mod width_cache;
+pub mod whitespace;
+pub mod line_ending;
+pub mod backspace;
pub mod rpc;
-use internal::tabs;
-use internal::core;
-use internal::client;
-use internal::edit_types;
-use internal::editor;
-use internal::event_context;
-use internal::file;
-use internal::find;
-use internal::view;
-use internal::linewrap;
-use internal::plugins;
-use internal::styles;
-use internal::word_boundaries;
-use internal::index_set;
-use internal::selection;
-use internal::movement;
-use internal::syntax;
-use internal::layers;
-use internal::config;
-#[cfg(feature = "notify")]
-use internal::watcher;
-use internal::line_cache_shadow;
-use internal::width_cache;
-#[cfg(feature = "ledger")]
-use internal::fuchsia;
-
#[cfg(feature = "ledger")]
use apps_ledger_services_public::Ledger_Proxy;
diff --git a/rust/core-lib/src/line_ending.rs b/rust/core-lib/src/line_ending.rs
new file mode 100644
index 000000000..bdffb82e4
--- /dev/null
+++ b/rust/core-lib/src/line_ending.rs
@@ -0,0 +1,96 @@
+// Copyright 2018 The xi-editor Authors.
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+//! Utilities for detecting and working with line endings
+
+extern crate xi_rope;
+
+use xi_rope::Rope;
+use memchr::memchr2;
+
+/// An enumeration of valid line endings
+#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
+pub enum LineEnding {
+ CrLf, // DOS style, \r\n
+ Lf, // *nix style, \n
+}
+
+/// A struct representing a mixed line ending error.
+#[derive(Debug)]
+pub struct MixedLineEndingError;
+
+impl LineEnding {
+ /// Breaks a rope down into chunks, and checks each chunk for line endings
+ pub fn parse(rope: &Rope) -> Result