Skip to content
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

Add rustfmt.toml #572

Open
wants to merge 7 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
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
20 changes: 13 additions & 7 deletions ui/frontend/Icon.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,20 +36,26 @@ export const MoreOptionsActiveIcon = () => (
</svg>
);

// M.D. 'settings',
export const ConfigIcon = () => (
<svg className="icon" height="15" viewBox="0 0 24 24" width="15" opacity="0.5" xmlns="http://www.w3.org/2000/svg">
const createConfigIcon = (size: string) => () => (
<svg className="icon" height={size} viewBox="0 0 24 24" width={size} opacity="0.5" xmlns="http://www.w3.org/2000/svg">
<path d="M19.43 12.98c.04-.32.07-.64.07-.98s-.03-.66-.07-.98l2.11-1.65c.19-.15.24-.42.12-.64l-2-3.46c-.12-.22-.39-.3-.61-.22l-2.49 1c-.52-.4-1.08-.73-1.69-.98l-.38-2.65C14.46 2.18 14.25 2 14 2h-4c-.25 0-.46.18-.49.42l-.38 2.65c-.61.25-1.17.59-1.69.98l-2.49-1c-.23-.09-.49 0-.61.22l-2 3.46c-.13.22-.07.49.12.64l2.11 1.65c-.04.32-.07.65-.07.98s.03.66.07.98l-2.11 1.65c-.19.15-.24.42-.12.64l2 3.46c.12.22.39.3.61.22l2.49-1c.52.4 1.08.73 1.69.98l.38 2.65c.03.24.24.42.49.42h4c.25 0 .46-.18.49-.42l.38-2.65c.61-.25 1.17-.59 1.69-.98l2.49 1c.23.09.49 0 .61-.22l2-3.46c.12-.22.07-.49-.12-.64l-2.11-1.65zM12 15.5c-1.93 0-3.5-1.57-3.5-3.5s1.57-3.5 3.5-3.5 3.5 1.57 3.5 3.5-1.57 3.5-3.5 3.5z" />
</svg>
);
)

// M.D. 'help_outline'
export const HelpIcon = () => (
<svg className="icon" height="18" viewBox="0 0 24 24" width="18" opacity="0.5" xmlns="http://www.w3.org/2000/svg">
// M.D. 'settings',
export const ConfigIcon = createConfigIcon('15');
export const RustfmtTomlIcon = createConfigIcon('30');

const createHelpIcon = (size: string) => () => (
<svg className="icon" height={size} viewBox="0 0 24 24" width={size} opacity="0.5" xmlns="http://www.w3.org/2000/svg">
<path d="M11 18h2v-2h-2v2zm1-16C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm0 18c-4.41 0-8-3.59-8-8s3.59-8 8-8 8 3.59 8 8-3.59 8-8 8zm0-14c-2.21 0-4 1.79-4 4h2c0-1.1.9-2 2-2s2 .9 2 2c0 2-3 1.75-3 5h2c0-2.25 3-2.5 3-5 0-2.21-1.79-4-4-4z" />
</svg>
);

// M.D. 'help_outline'
export const HelpIcon = createHelpIcon('18');
export const RustfmtModalHelpIcon = createHelpIcon('24');

export const CheckmarkIcon = () => (
<svg className="icon icon--checkmark" height="18" viewBox="2 2 22 22" width="18" opacity="0.5" xmlns="http://www.w3.org/2000/svg">
<path d="M9 16.17L4.83 12l-1.42 1.41L9 19 21 7l-1.41-1.41z" />
Expand Down
7 changes: 7 additions & 0 deletions ui/frontend/Playground.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,24 @@ import Editor from './Editor';
import Header from './Header';
import Notifications from './Notifications';
import Output from './Output';
import RustfmtTomlModal from './RustfmtTomlModal';
import * as selectors from './selectors';
import State from './state';

const Playground: React.SFC = () => {
const showNotifications = useSelector(selectors.anyNotificationsToShowSelector);
const showRustfmtTomlModal = useSelector((state: State) => state.rustfmt.show);
const focus = useSelector((state: State) => state.output.meta.focus);
const splitOrientation = useSelector((state: State) => state.configuration.orientation);

const outputFocused = focus ? 'playground-output-focused' : '';
const splitClass = 'playground-split';
const orientation = splitClass + '-' + splitOrientation;

const rustfmtModal = showRustfmtTomlModal
? <RustfmtTomlModal />
: null

return (
<div>
<div className="playground">
Expand All @@ -33,6 +39,7 @@ const Playground: React.SFC = () => {
</div>
</div>
{showNotifications && <Notifications />}
{rustfmtModal}
</div>
);
};
Expand Down
62 changes: 62 additions & 0 deletions ui/frontend/RustfmtTomlModal.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
import React, { useCallback } from 'react';
import { useSelector, useDispatch } from 'react-redux';

import { Rnd } from 'react-rnd';

import * as actions from './actions';
import { Close as CloseIcon, RustfmtModalHelpIcon } from './Icon';

import TomlEditor from './TomlEditor';
import State from './state';

const ModalDefaultWidth = 320;
const ModalDefaultHeight = 200;
const DefaultState = {
x: (window.innerWidth / 2) - ModalDefaultWidth,
y: (window.innerHeight / 2) - ModalDefaultHeight,
width: ModalDefaultWidth,
height: ModalDefaultHeight,
};

const RustfmtTomlModal: React.SFC = () => {
const toml = useSelector((state: State) => state.rustfmt.toml);
const dispatch = useDispatch();

const onEditRustfmt = useCallback((c) => dispatch(actions.editRustfmtToml(c)), [dispatch]);
const formatDialog = useCallback(() => {
dispatch(actions.toggleRustfmtTomlModalShow());
}, [dispatch]);

const Close = <button className="button-menu-item" title="Close Dialog" onClick={formatDialog}>
<CloseIcon />
</button>

return (
<Rnd
className="rustfmt-modal"
default={DefaultState}
cancel=".toml-input-area"
>
<div className="backbone">
<div className="toml-header">
<div className="toml-header-label">rustfmt.toml</div>
<div className="icon-areas">
<HelpIcon />
{Close}
</div>
</div>
<TomlEditor
toml={toml}
onEditCode={onEditRustfmt} />
</div>
</Rnd>
);
};

const HelpIcon: React.SFC = () => (
<a title="View help" href="https://rust-lang.github.io/rustfmt">
<RustfmtModalHelpIcon />
</a>
);

export default RustfmtTomlModal;
30 changes: 30 additions & 0 deletions ui/frontend/TomlEditor.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import React from 'react';

type TomlEditorProps = {
toml: string;
onEditCode: (_: string) => any;
}

class TomlEditor extends React.PureComponent<TomlEditorProps> {
private _editor: HTMLTextAreaElement;

private onChange = e => this.props.onEditCode(e.target.value);
private trackEditor = component => this._editor = component;

public render() {
return (
<textarea
ref={this.trackEditor}
className="toml-input-area"
name="toml-input-area"
autoCapitalize="none"
autoComplete="off"
autoCorrect="off"
spellCheck={false}
value={this.props.toml}
onChange={this.onChange} />
);
}
}

export default TomlEditor;
23 changes: 17 additions & 6 deletions ui/frontend/ToolsMenu.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import React, { useCallback } from 'react';
import { useDispatch, useSelector } from 'react-redux';

import { RustfmtTomlIcon } from './Icon';
import ButtonMenuItem from './ButtonMenuItem';
import MenuGroup from './MenuGroup';

Expand Down Expand Up @@ -32,15 +33,25 @@ const ToolsMenu: React.SFC<ToolsMenuProps> = props => {
dispatch(actions.performFormat());
props.close();
}, [dispatch, props]);
const formatDialog = useCallback(() => {
dispatch(actions.toggleRustfmtTomlModalShow());
}, [dispatch]);

return (
<MenuGroup title="Tools">
<ButtonMenuItem
name="Rustfmt"
onClick={format}>
<div>Format this code with Rustfmt.</div>
<div className="tools-menu__aside">{rustfmtVersion} ({rustfmtVersionDetails})</div>
</ButtonMenuItem>
<div className="menu-item-wrapper">
<ButtonMenuItem
name="Rustfmt"
onClick={format}>
<div>Format this code with Rustfmt.</div>
<div className="tools-menu__aside">{rustfmtVersion} ({rustfmtVersionDetails})</div>
</ButtonMenuItem>

<div className="menu-right" onClick={formatDialog}>
<RustfmtTomlIcon />
</div>
</div>

<ButtonMenuItem
name="Clippy"
onClick={clippy}>
Expand Down
11 changes: 11 additions & 0 deletions ui/frontend/actions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,8 @@ export enum ActionType {
CompileWasmSucceeded = 'COMPILE_WASM_SUCCEEDED',
CompileWasmFailed = 'COMPILE_WASM_FAILED',
EditCode = 'EDIT_CODE',
EditRustfmtToml = 'EDIT_RUSTFMT_TOML',
ToggleRustfmtTomlModalShow = 'TOGGLE_RUSTFMT_TOML_MODAL_SHOW',
AddMainFunction = 'ADD_MAIN_FUNCTION',
EnableFeatureGate = 'ENABLE_FEATURE_GATE',
GotoPosition = 'GOTO_POSITION',
Expand Down Expand Up @@ -415,6 +417,12 @@ export const performCompileToNightlyWasm =
export const editCode = (code: string) =>
createAction(ActionType.EditCode, { code });

export const editRustfmtToml = (code: string) =>
createAction(ActionType.EditRustfmtToml, { code });

export const toggleRustfmtTomlModalShow = () =>
createAction(ActionType.ToggleRustfmtTomlModalShow);

export const addMainFunction = () =>
createAction(ActionType.AddMainFunction);

Expand All @@ -429,6 +437,7 @@ const requestFormat = () =>

interface FormatRequestBody {
code: string;
rustfmtToml: string;
edition: string;
}

Expand Down Expand Up @@ -750,6 +759,8 @@ export type Action =
| ReturnType<typeof receiveCompileWasmSuccess>
| ReturnType<typeof receiveCompileWasmFailure>
| ReturnType<typeof editCode>
| ReturnType<typeof editRustfmtToml>
| ReturnType<typeof toggleRustfmtTomlModalShow>
| ReturnType<typeof addMainFunction>
| ReturnType<typeof enableFeatureGate>
| ReturnType<typeof gotoPosition>
Expand Down
52 changes: 52 additions & 0 deletions ui/frontend/index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -627,13 +627,33 @@ $header-transition: 0.2s ease-in-out;
}

.menu-item {
width: 100%;
margin-bottom: 1em;

&:last-child {
margin-bottom: 0;
}
}

.menu-item-wrapper {
display: flex;
width: 100%;
margin-bottom: 1em;
}

.menu-right {
display: flex;
align-items: center;
border-left: solid $header-main-border 2px;

svg {
cursor: pointer;
&:hover {
color: $header-tint;
}
}
}

@mixin menu-item-title {
font-size: 13px;
font-weight: 600;
Expand Down Expand Up @@ -894,3 +914,35 @@ $header-transition: 0.2s ease-in-out;
cursor: pointer;
}
}

.rustfmt-modal {
border: 4px solid $border-color;
z-index: 10;

.backbone {
height: 100%;
}

.toml-header {
display: flex;
justify-content: space-between;
line-height: 30px;
background-color: $background;

.toml-header-label {
margin-left: 4px;
}

.icon-areas {
display: flex;
padding: 4px;
}
}

.toml-input-area {
width: 100%;
height: calc(100% - 30px);
resize: none;
border: none;
}
}
1 change: 1 addition & 0 deletions ui/frontend/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"react-portal": "^4.1.4",
"react-prism": "^4.0.0",
"react-redux": "^7.0.0",
"react-rnd": "^10.1.4",
"redux": "^4.0.0",
"redux-thunk": "^2.1.0",
"regenerator-runtime": "^0.13.2",
Expand Down
2 changes: 2 additions & 0 deletions ui/frontend/reducers/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import notifications from './notifications';
import output from './output';
import page from './page';
import position from './position';
import rustfmt from './rustfmt';
import versions from './versions';

const playgroundApp = combineReducers({
Expand All @@ -19,6 +20,7 @@ const playgroundApp = combineReducers({
output,
page,
position,
rustfmt,
versions,
});

Expand Down
26 changes: 26 additions & 0 deletions ui/frontend/reducers/rustfmt.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { Action, ActionType } from '../actions';

const DEFAULT: State = {
show: false,
toml: '',
}

export type State = {
show: boolean;
toml: string;
};

export default function code(state = DEFAULT, action: Action): State {
switch (action.type) {
case ActionType.EditRustfmtToml:
return {
...state, toml: action.code,
};
case ActionType.ToggleRustfmtTomlModalShow:
return {
...state, show: !state.show,
};
default:
return state;
}
}
4 changes: 3 additions & 1 deletion ui/frontend/selectors/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { State } from '../reducers';
import { Backtrace, Channel, Edition, PrimaryActionAuto, PrimaryActionCore } from '../types';

const codeSelector = (state: State) => state.code;
const rustfmtSelector = (state: State) => state.rustfmt.toml;

const HAS_TESTS_RE = /^\s*#\s*\[\s*test\s*([^"]*)]/m;
export const hasTestsSelector = createSelector(codeSelector, code => !!code.match(HAS_TESTS_RE));
Expand Down Expand Up @@ -274,6 +275,7 @@ export const clippyRequestSelector = createSelector(

export const formatRequestSelector = createSelector(
codeSelector,
rustfmtSelector,
editionSelector,
(code, edition) => ({ code, edition }),
(code, rustfmtToml, edition) => ({ code, edition, rustfmtToml }),
);
Loading