Skip to content

Commit

Permalink
wip: code-block formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
ifiokjr committed Jul 18, 2019
1 parent f4fb7fe commit a5a659a
Show file tree
Hide file tree
Showing 8 changed files with 89 additions and 41 deletions.
1 change: 0 additions & 1 deletion @remirror/extension-code-block/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,6 @@
"@types/react-syntax-highlighter": "^10.2.1",
"@types/refractor": "^2.8.0",
"emotion": "^10.0.14",
"prettier": "^1.18.2",
"prosemirror-commands": "^1.0.8",
"prosemirror-inputrules": "^1.0.4",
"prosemirror-keymap": "^1.0.1",
Expand Down
18 changes: 11 additions & 7 deletions @remirror/extension-code-block/src/code-block-extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,17 @@ import refractor from 'refractor/core';
import { CodeBlockComponent } from './code-block-component';
import createCodeBlockPlugin from './code-block-plugin';
import { CodeBlockExtensionCommands, CodeBlockExtensionOptions } from './code-block-types';
import { getLanguage, updateNodeAttrs } from './code-block-utils';
import { formatCodeBlockFactory, getLanguage, updateNodeAttrs } from './code-block-utils';
import { syntaxTheme, SyntaxTheme } from './themes';

export const codeBlockDefaultOptions: CodeBlockExtensionOptions = {
SSRComponent: CodeBlockComponent,
supportedLanguages: [],
syntaxTheme: 'atomDark' as SyntaxTheme,
defaultLanguage: 'markup',
formatter: () => false,
};

export class CodeBlockExtension extends NodeExtension<
CodeBlockExtensionOptions,
CodeBlockExtensionCommands,
Expand All @@ -37,12 +45,7 @@ export class CodeBlockExtension extends NodeExtension<
* Provide the default options for this extension
*/
get defaultOptions() {
return {
SSRComponent: CodeBlockComponent,
supportedLanguages: [],
syntaxTheme: 'atomDark' as SyntaxTheme,
defaultLanguage: 'markup',
};
return codeBlockDefaultOptions;
}

/**
Expand Down Expand Up @@ -121,6 +124,7 @@ export class CodeBlockExtension extends NodeExtension<
toggleBlockItem({ type, toggleType: schema.nodes.paragraph, attrs }),
createCodeBlock: (attrs?: Attrs) => setBlockType(type, attrs),
updateCodeBlock: updateNodeAttrs(type),
formatCodeBlock: formatCodeBlockFactory(type, this.options.formatter),
};
}

Expand Down
47 changes: 46 additions & 1 deletion @remirror/extension-code-block/src/code-block-types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ export interface CodeBlockExtensionOptions extends NodeExtensionOptions {
*/
syntaxTheme?: SyntaxTheme | false;

/**
* Provide a formatter which can format the provided source code.
*
* @returns an object when formatting was successful and false when the code could not be formatted (a noop).
*/
formatter?: CodeBlockFormatter;

/**
* A handler called whenever any code block in the document has changed.
*
Expand All @@ -68,11 +75,49 @@ export interface CodeBlockExtensionOptions extends NodeExtensionOptions {
onHover?(params: any): void;
}

export type CodeBlockFormatter = (params: FormatterParams) => FormatterReturn | false;

export interface FormatterParams {
/**
* The code to be formatted
*/
source: string;

/**
* Specify where the cursor is. This option cannot be used with rangeStart and rangeEnd.
* This allows the command to both formats the code, and translates a cursor position from unformatted code to formatted code.
*/
cursorOffset: number;

/**
* The language of the code block. Should be used to determine whether the formatter can support the transformation.
*
* Possible languages are available here https://github.com/wooorm/refractor/tree/716fe904c37cd7ebfde53ac5157e7d6c323a3986/lang
*/
language: string;
}

export interface FormatterReturn {
/**
* The transformed source.
*/
output: string;

/**
* The new cursor position after formatting
*/
cursorOffset: number;
}

export interface CodeBlockAttrs extends Attrs {
/**
* The language attribute
*/
language: string;
}

export type CodeBlockExtensionCommands = 'toggleCodeBlock' | 'updateCodeBlock' | 'createCodeBlock';
export type CodeBlockExtensionCommands =
| 'toggleCodeBlock'
| 'updateCodeBlock'
| 'createCodeBlock'
| 'formatCodeBlock';
26 changes: 24 additions & 2 deletions @remirror/extension-code-block/src/code-block-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import {
} from '@remirror/core';
import { Decoration } from 'prosemirror-view';
import refractor, { RefractorNode, RefractorSyntax } from 'refractor/core';
import { CodeBlockAttrs } from './code-block-types';
import { CodeBlockAttrs, CodeBlockFormatter } from './code-block-types';

// Refractor languages
import clike from 'refractor/lang/clike';
Expand Down Expand Up @@ -65,6 +65,7 @@ function parseRefractorNodes(
*/
export const createDecorations = (blocks: NodeWithPosition[], skipLast: boolean) => {
const decorations: Decoration[] = [];

blocks.forEach(block => {
const positionedRefractorNodes = getPositionedRefractorNodes(block);
const lastBlockLength = skipLast ? positionedRefractorNodes.length - 1 : positionedRefractorNodes.length;
Expand Down Expand Up @@ -143,7 +144,7 @@ export const getNodeInformationFromState = (state: EditorState): NodeInformation
/**
* Updates the node attrs.
*
* Is used to update the language for the codeBlock.
* This is used to update the language for the codeBlock.
*/
export const updateNodeAttrs = (type: NodeType) => (attrs?: Attrs): CommandFunction => (
{ tr, selection },
Expand All @@ -170,6 +171,27 @@ export const updateNodeAttrs = (type: NodeType) => (attrs?: Attrs): CommandFunct
return true;
};

export const formatCodeBlockFactory = (
_type: NodeType,
formatter: CodeBlockFormatter,
) => (): CommandFunction => state => {
// Check if block is type is active, if not return false

// Get the `language`, `source` and `cursorOffset` for the block
// For cursor position it might be okay to just use the current position.
const format = formatter({ source: '', language: '', cursorOffset: state.selection.from });
if (!format) {
return false;
}

// const { cursorOffset, output } = format;

// Replace the node content with the transformed text.

// Set the new selection
return true;
};

/**
* Check that the attributes exist and are valid for the codeBlock updateAttrs.
*/
Expand Down
21 changes: 0 additions & 21 deletions @remirror/extension-code-block/src/prettier/index.ts

This file was deleted.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -151,6 +151,7 @@
"npm-run-all": "4.1.5",
"p-series": "^2.1.0",
"prettier": "1.18.2",
"@types/prettier": "1.16.4",
"prettier-package-json": "2.1.0",
"prosemirror-test-builder": "1.0.1",
"puppeteer": "1.18.1",
Expand Down
9 changes: 1 addition & 8 deletions packages/jest-remirror/src/jsdom-polyfills.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,14 +69,7 @@ export const jsdomExtras = () => {
return;
}

document.getSelection = () => {
return {
addRange: _ => {},
removeAllRanges: () => {},
} as Selection;
};

window.getSelection = () => {
document.getSelection = window.getSelection = () => {
return {
addRange: _ => {},
removeAllRanges: () => {},
Expand Down
7 changes: 6 additions & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3411,6 +3411,11 @@
resolved "https://registry.yarnpkg.com/@types/orderedmap/-/orderedmap-1.0.0.tgz#807455a192bba52cbbb4517044bc82bdbfa8c596"
integrity sha512-dxKo80TqYx3YtBipHwA/SdFmMMyLCnP+5mkEqN0eMjcTBzHkiiX0ES118DsjDBjvD+zeSsSU9jULTZ+frog+Gw==

"@types/prettier@1.16.4":
version "1.16.4"
resolved "https://registry.yarnpkg.com/@types/prettier/-/prettier-1.16.4.tgz#5e5e97702cb68498aaba7349b941648daaf2385c"
integrity sha512-MG7ExKBo7AQ5UrL1awyYLNinNM/kyXgE4iP4Ul9fB+T7n768Z5Xem8IZeP6Bna0xze8gkDly49Rgge2HOEw4xA==

"@types/prismjs@*", "@types/prismjs@^1.16.0":
version "1.16.0"
resolved "https://registry.yarnpkg.com/@types/prismjs/-/prismjs-1.16.0.tgz#4328c9f65698e59f4feade8f4e5d928c748fd643"
Expand Down Expand Up @@ -16204,7 +16209,7 @@ prettier-package-json@2.1.0:
sort-object-keys "^1.1.2"
sort-order "^1.0.1"

prettier@1.18.2, prettier@^1.17.0, prettier@^1.18.2:
prettier@1.18.2, prettier@^1.17.0:
version "1.18.2"
resolved "https://registry.yarnpkg.com/prettier/-/prettier-1.18.2.tgz#6823e7c5900017b4bd3acf46fe9ac4b4d7bda9ea"
integrity sha512-OeHeMc0JhFE9idD4ZdtNibzY0+TPHSpSSb9h8FqtP+YnoZZ1sl8Vc9b1sasjfymH3SonAF4QcA2+mzHPhMvIiw==
Expand Down

0 comments on commit a5a659a

Please sign in to comment.