Skip to content

Add compiler suggestions and message themes. #267

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2018
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -30,7 +30,7 @@ It is possible that the built-in `Rust` package will cause conflicts with Rust E
## Features
### Go To Definition
### Cargo Build
Rust Enhanced has a custom build system tailored for running Cargo. It will display errors and warnings in line using Sublime's phantoms. It also supports a variety of configuration options to control how Cargo is run.
Rust Enhanced has a custom build system tailored for running Cargo. It will display errors and warnings in line using Sublime's phantoms (see [Messages](docs/messages.md) for settings to control how messages are displayed). It also supports a variety of configuration options to control how Cargo is run.

![testingrust](https://cloud.githubusercontent.com/assets/43198/22944409/7780ab9a-f2a5-11e6-87ea-0e253d6c40f6.png)

@@ -119,7 +119,7 @@ To customize the settings, use the command from the Sublime menu:
Additionally, you can customize settings per-project by adding settings to your `.sublime-project` file under the `"settings"` key.

## Development
Development is quite simple, just check out this project to your Sublime Text 3 packages folder, and switch to using this one.
Development is quite simple, just check out this project to your Sublime Text 3 packages folder, and switch to using this one.
Syntax definitions are defined in the `RustEnhanced.sublime-syntax` file.

## Credits
7 changes: 6 additions & 1 deletion RustEnhanced.sublime-settings
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@
// If true, will not display warning messages.
"rust_syntax_hide_warnings": false,

// Color of messages.
// Color of messages for "clear" theme.
// These use CSS colors. See
// https://www.sublimetext.com/docs/3/minihtml.html for more detail.
"rust_syntax_error_color": "var(--redish)",
@@ -46,6 +46,11 @@
// "none" - Do not place icons in the gutter.
"rust_gutter_style": "shape",

// Style for displaying inline messages. Can be:
// "clear" - Clear background with colors matching your color scheme.
// "solid" - Solid background color.
"rust_message_theme": "clear",

// If your cargo project has several build targets, it's possible to specify mapping of
// source code filenames to the target names to enable syntax checking.
// "projects": {
32 changes: 32 additions & 0 deletions cargo_build.py
Original file line number Diff line number Diff line change
@@ -3,6 +3,7 @@
import functools
import sublime
import sublime_plugin
import sys
from .rust import (rust_proc, rust_thread, opanel, util, messages,
cargo_settings, target_detect)
from .rust.cargo_config import *
@@ -486,3 +487,34 @@ def is_applicable(cls, settings):
def on_hover(self, point, hover_zone):
if util.get_setting('rust_phantom_style', 'normal') == 'popup':
messages.message_popup(self.view, point, hover_zone)


class RustAcceptSuggestedReplacement(sublime_plugin.TextCommand):

"""Used for suggested replacements issued by the compiler to apply the
suggested replacement.
"""

def run(self, edit, region, replacement):
region = sublime.Region(*region)
self.view.replace(edit, region, replacement)


def plugin_unloaded():
messages.clear_all_messages()
try:
from package_control import events
except ImportError:
return
package_name = __package__.split('.')[0]
if events.pre_upgrade(package_name):
# When upgrading the package, Sublime currently does not cleanly
# unload the `rust` Python package. This is a workaround to ensure
# that it gets completely unloaded so that when it upgrades it will
# load the new package. See
# https://github.com/SublimeTextIssues/Core/issues/2207
re_keys = [key for key in sys.modules if key.startswith(package_name + '.rust')]
for key in re_keys:
del sys.modules[key]
if package_name in sys.modules:
del sys.modules[package_name]
17 changes: 17 additions & 0 deletions changelog/2.11.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# Rust Enhanced 2.11.0

You must restart Sublime after installing this update.

## New Features
- Added `"rust_message_theme"` configuration setting for choosing different
styles of inline messages. Currently two options are available: "clear" and
"solid". See
https://github.com/rust-lang/rust-enhanced/blob/master/docs/build.md#general-settings
for examples.

- If the Rust compiler provides a suggestion on how to fix an error, the
inline messages now include a link that you can click to automatically apply
the suggestion.

## Syntax Updates
- Support u128/i128 integer suffix.
25 changes: 3 additions & 22 deletions docs/build.md
Original file line number Diff line number Diff line change
@@ -4,6 +4,9 @@ The Rust Enhanced build system provides an interface for running Cargo. It can
show inline warning and error messages. It also has a variety of ways of
configuring options for how Cargo is run.

See [Messages](messages.md) for settings to control how compiler messages are
displayed.

## Usage

When Sublime is set to use "Automatic" build system detection, it will choose
@@ -42,28 +45,6 @@ Document | <code>cargo&nbsp;doc</code> | Builds package documentation.
Clippy | <code>cargo&nbsp;clippy</code> | Runs [Clippy](https://github.com/Manishearth/rust-clippy). Clippy must be installed, and currently requires the nightly toolchain.
Script | <code>cargo&nbsp;script&nbsp;$path</code> | Runs [Cargo Script](https://github.com/DanielKeep/cargo-script). Cargo Script must be installed. This is an addon that allows you to run a Rust source file like a script (without a Cargo.toml manifest).

## General Settings

General settings (see [Settings](../README.md#settings)) for how messages are displayed are:

| Setting | Default | Description |
| :------ | :------ | :---------- |
| `rust_syntax_hide_warnings` | `false` | If true, will not display warning messages. |
| `rust_syntax_error_color` | `"var(--redish)"` | Color of error messages. |
| `rust_syntax_warning_color` | `"var(--yellowish)"` | Color of warning messages. |
| `rust_syntax_note_color` | `"var(--greenish)"` | Color of note messages. |
| `rust_syntax_help_color` | `"var(--bluish)"` | Color of help messages. |
| `rust_phantom_style` | `"normal"` | How to display inline messages. Either `normal`, `popup`, or `none`. |
| `rust_region_style` | `"outline"` | How to highlight messages. Either `outline` or `none`. |
| `rust_gutter_style` | `"shape"` | Type of icon to show in the gutter. Either `shape`, `circle`, or `none`. |

It also supports Sublime's build settings:

| Setting | Default | Description |
| :------ | :------ | :---------- |
| `show_errors_inline` | `true` | If true, messages are displayed in line using Sublime's phantoms. If false, messages are only displayed in the output panel. |
| `show_panel_on_build` | `true` | If true, an output panel is displayed at the bottom of the window showing the compiler output. |

## Cargo Settings

A variety of settings are available to customize how Cargo is run. These
Binary file added docs/img/messages_popup.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/region_style_none.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/region_style_outline.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/show_errors_inline_false.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/show_errors_inline_true.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/theme_clear.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/img/theme_solid.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions docs/messages.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Messages

There are a variety of ways to display Rust compiler messages. See
[Settings](../README.md#settings) for more details about how to configure
settings.

## Inline Phantoms vs Output Panel

The `show_errors_inline` setting controls whether or not errors are shown
inline with the code using Sublime's "phantoms". If it is `true`, it will
also display an abbreviated message in the output panel. If it is `false`,
messages will only be displayed in the output panel, using rustc's formatting.

### `show_errors_inline`

<table>
<tr>
<td><code>true</code></td>
<td><img src="img/show_errors_inline_true.png"></td>
</tr>
<tr>
<td><code>false</code></td>
<td><img src="img/show_errors_inline_false.png"></td>
</tr>
</table>

## Popup Phantom Style

Phantoms can be displayed inline with the code, or as a popup when the mouse
hovers over an error (either the gutter icon or the error outline). The
`rust_phantom_style` setting controls this behavior.

### `rust_phantom_style`

| Value | Description |
| :---- | :---------- |
| `normal` | Phantoms are displayed inline. |
| `popup` | Phantoms are displayed when the mouse hovers over an error. |
| `none` | Phantoms are not displayed. |

<img src="img/messages_popup.gif">

## Phantom Themes

The style of the phantom messages is controlled with the `rust_message_theme`
setting. Currently the following themes are available:

### `rust_message_theme`

<table>
<tr>
<td><code>clear</code></td>
<td><img src="img/theme_clear.png"></td>
</tr>
<tr>
<td><code>solid</code></td>
<td><img src="img/theme_solid.png"></td>
</tr>
</table>

### Clear Theme Colors

The `clear` theme is designed to integrate with your chosen Color Scheme. You
can customize the colors of the messages with the following settings.

| Setting | Default | Description |
| :------ | :------ | :---------- |
| `rust_syntax_error_color` | `"var(--redish)"` | Color of error messages. |
| `rust_syntax_warning_color` | `"var(--yellowish)"` | Color of warning messages. |
| `rust_syntax_note_color` | `"var(--greenish)"` | Color of note messages. |
| `rust_syntax_help_color` | `"var(--bluish)"` | Color of help messages. |


## Region Highlighting

The span of code for a compiler message is by default highlighted with an
outline.

### `rust_region_style`

| Value | Example | Description |
| :---- | :------ | :---------- |
| `outline` | <img src="img/region_style_outline.png"> | Regions are highlighted with an outline. |
| `none` | <img src="img/region_style_none.png"> | Regions are not highlighted. |

## Gutter Images

The gutter (beside the line numbers) will include an icon indicating the level
of the message. The styling of these icons is controlled with
`rust_gutter_style`.

### `rust_gutter_style`

| Value | Description |
| :---- | :---------- |
| `shape` | <img src="../images/gutter/shape-error.png"> <img src="../images/gutter/shape-warning.png"> <img src="../images/gutter/shape-note.png"> <img src="../images/gutter/shape-help.png"> |
| `circle` | <img src="../images/gutter/circle-error.png"> <img src="../images/gutter/circle-warning.png"> <img src="../images/gutter/circle-note.png"> <img src="../images/gutter/circle-help.png"> |
| `none` | Do not display icons. |

## Other Settings

A few other settings are available for controlling messages:

| Setting | Default | Description |
| :------ | :------ | :---------- |
| `show_panel_on_build` | `true` | If true, an output panel is displayed at the bottom of the window showing the compiler output. |
| `rust_syntax_hide_warnings` | `false` | If true, will not display warning messages. |
Binary file added images/gutter/circle-none.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/gutter/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/gutter/shape-none.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added images/gutter/[email protected]
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions messages.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"2.11.0": "changelog/2.11.0.md"
}
118 changes: 118 additions & 0 deletions rust/batch.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@
"""Classes used for aggregating messages that are on the same line."""


class MessageBatch:

"""Abstract base class for a set of messages that apply to the same line.

:ivar children: List of additional messages, may be empty.
:ivar hidden: Boolean if this message should be displayed.
"""

hidden = False

def __init__(self):
self.children = []

def __iter__(self):
"""Iterates over all messages in the batch."""
raise NotImplementedError()

def path(self):
"""Returns the file path of the batch."""
raise NotImplementedError()

def first(self):
"""Returns the first message of the batch."""
raise NotImplementedError()

def dismiss(self):
"""Permanently remove this message and all its children from the
view."""
raise NotImplementedError()

def _dismiss(self, window):
# There is a awkward problem with Sublime and
# add_regions/erase_regions. The regions are part of the undo stack,
# which means even after we erase them, they can come back from the
# dead if the user hits undo. We simply mark these as "hidden" to
# ensure that `clear_messages` can erase any of these zombie regions.
# See https://github.com/SublimeTextIssues/Core/issues/1121
# This is imperfect, since the user could do the following:
# 1) Build 2) Type some text 3) Clear Messages 4) Undo
# which will resurrect the regions without an easy way to remove them
# (user has to close and reopen the file). I don't know of any good
# workarounds.
for msg in self:
view = window.find_open_file(msg.path)
if view:
view.erase_regions(msg.region_key)
view.erase_phantoms(msg.region_key)


class PrimaryBatch(MessageBatch):

"""A batch of messages with the primary message.

:ivar primary_message: The primary message object.
:ivar child_batches: List of `ChildBatch` batches associated with this
batch.
:ivar child_links: List of `(url, text)` tuples for links to child batches
that are "far away".
"""

primary_message = None

def __init__(self, primary_message):
super(PrimaryBatch, self).__init__()
self.primary_message = primary_message
self.child_batches = []
self.child_links = []

def __iter__(self):
yield self.primary_message
for child in self.children:
yield child

def path(self):
return self.primary_message.path

def first(self):
return self.primary_message

def dismiss(self, window):
self.hidden = True
self._dismiss(window)
for batch in self.child_batches:
batch._dismiss(window)


class ChildBatch(MessageBatch):

"""A batch of messages that are associated with a primary message.

:ivar primary_batch: The `PrimaryBatch` this is associated with.
:ivar back_link: Tuple of `(url, text)` of the link to the primary batch
if it is "far away" (otherwise None).
"""

primary_batch = None
back_link = None

def __init__(self, primary_batch):
super(ChildBatch, self).__init__()
self.primary_batch = primary_batch

def __iter__(self):
for child in self.children:
yield child

def path(self):
return self.children[0].path

def first(self):
return self.children[0]

def dismiss(self, window):
self.hidden = True
self.primary_batch.dismiss(window)
Loading