Skip to content

Commit

Permalink
Initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
adamzapasnik committed Jan 25, 2021
1 parent e1640d8 commit b6961e6
Show file tree
Hide file tree
Showing 102 changed files with 6,141 additions and 2,374 deletions.
20 changes: 20 additions & 0 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"env": {
"node": true,
"es6": true,
"jest": true
},
"extends": ["eslint:recommended", "prettier"],
"plugins": ["prettier"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parserOptions": {
"ecmaVersion": 2018,
"sourceType": "module"
},
"rules": {
"prettier/prettier": ["error"]
}
}
11 changes: 11 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# To get started with Dependabot version updates, you'll need to specify which
# package ecosystems to update and where the package manifests are located.
# Please see the documentation for all configuration options:
# https://help.github.com/github/administering-a-repository/configuration-options-for-dependency-updates

version: 2
updates:
- package-ecosystem: 'npm'
directory: '/'
schedule:
interval: 'weekly'
55 changes: 55 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
name: CI

on:
push:
branches:
- master
pull_request:
branches:
- master


jobs:
format:
name: Format
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1

- name: Install OTP and Elixir
uses: actions/setup-elixir@v1
with:
otp-version: "22.3.4.1"
elixir-version: "1.10.3"

- run: mix compile --warnings-as-errors
- run: mix format --check-formatted

test:
name: Test
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1

- name: Install OTP and Elixir
uses: actions/setup-elixir@v1
with:
otp-version: "22.3.4.1"
elixir-version: "1.10.3"

- name: Install
run: |
yarn policies set-version
yarn install --frozen-lockfile
- name: Get yarn cache directory path
id: yarn-cache-dir-path
run: echo "::set-output name=dir::$(yarn cache dir)"

- uses: actions/cache@v1
id: yarn-cache # use this to check for `cache-hit` (`steps.yarn-cache.outputs.cache-hit != 'true'`)
with:
path: ${{ steps.yarn-cache-dir-path.outputs.dir }}
key: ${{ runner.os }}-yarn-${{ hashFiles('**/yarn.lock') }}
restore-keys: |
${{ runner.os }}-yarn-
5 changes: 4 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,5 @@
.DS_Store
node_modules/
node_modules/
.elixir_ls/
prettier_eex_formatter_release
.vscode/
4 changes: 4 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[submodule "prettier_eex_formatter"]
path = prettier_eex_formatter
url = [email protected]:adamzapasnik/prettier_eex_formatter.git
branch = master
4 changes: 4 additions & 0 deletions .prettierrc.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"singleQuote": true,
"printWidth": 120
}
1 change: 0 additions & 1 deletion .tool-versions

This file was deleted.

7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# Changelog

All notable changes to the prettier-plugin-eex will be documented in this file.

## v0.1.0 - 25 January 2021

Initial release
76 changes: 71 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,75 @@
figure out scripts and styles..
probably should use some string for that, eex1 or smth
# Prettier EEX Plugin

.leex
## How to install?

attributes
```sh
yarn add -D prettier prettier-plugin-eex
```

## Config options

if <% should work to check it>
* printWidth - used by Prettier directly
* eexMultilineNoParens - Array - used to format multiline expressions, provide which functions shouldn't wrap parens around arguments
* eexMultilineLineLength - Number - used to format multiline expressions

Example:

```js
{
"printWidth": 130,
"eexMultilineLineLength": 100,
"eexMultilineNoParens": [
"link",
"form_for"
]
}
```

## How to install in Phoenix project?

Add .prettierignore file with:

```plain
deps/
_build/
.elixir_ls
assets
priv
```

And .prettierrc.js

```js
module.exports = {
printWidth: 120,
};
```

```sh
cd assets
yarn add -D prettier prettier-plugin-eex
```

### How to use?

Add to `mix.exs` `aliases` and use as `mix prettier`

```elixir
defp aliases do
[...
prettier: "cmd ./assets/node_modules/.bin/prettier --check . --color"
]
end
```

### How to make it work with Prettier Visual Studio code extension?

It's important to add node modules path.

```json
"prettier.prettierPath": "./assets/node_modules"
```

## How to deal with bugs?

Your code wasn't formatted correctly or there was an error? Add the problematic file to .prettierignore and submit an Issue.
22 changes: 5 additions & 17 deletions jest.config.js
Original file line number Diff line number Diff line change
@@ -1,23 +1,11 @@
"use strict";
'use strict';
const ENABLE_CODE_COVERAGE = !!process.env.ENABLE_CODE_COVERAGE;

module.exports = {
setupFiles: ["<rootDir>/tests_config/run_spec.js"],
snapshotSerializers: [
"jest-snapshot-serializer-raw",
// "jest-snapshot-serializer-ansi",
],
testRegex: "jsfmt\\.spec\\.js$|__tests__/.*\\.js$",
setupFiles: ['<rootDir>/tests_config/run_spec.js'],
snapshotSerializers: ['jest-snapshot-serializer-raw'],
testRegex: 'jsfmt\\.spec\\.js$|__tests__/.*\\.js$',
collectCoverage: ENABLE_CODE_COVERAGE,
// collectCoverageFrom: ["src/**/*.js", "<rootDir>/src/**/*.js",
// "!<rootDir>/node_modules/",
// "!<rootDir>/tests_config/", "!<rootDir>/node_modules/"],
// coveragePathIgnorePatterns: [
// "<rootDir>/standalone.js",
// "<rootDir>/src/document/doc-debug.js",
// "<rootDir>/src/main/massage-ast.js",
// ],
// coverageReporters: ["text", "lcov"],
testEnvironment: "node",
testEnvironment: 'node',
transform: {},
};
94 changes: 94 additions & 0 deletions lib/eex/formatter.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
const { concat, indent, hardline, group } = require('prettier').doc.builders;
const { execSync } = require('child_process');
const path = require('path');

// TODO: add formatting option to format multiline by urself
// TODO: better naming please

const formatEex = (tokens, options = {}) => {
const collectedMultiLine = {};

tokens.forEach((token, index) => {
if (token.type !== 'text' && token.content.match(/\r?\n/)) {
collectedMultiLine[index] = true;
}
});

const outputMap = {};
const encodedCode = Object.keys(collectedMultiLine)
.sort()
.map((tokenIndex, index) => {
const matcher = tokens[tokenIndex].content.match(/<%(#=|%=|=|%|#)?([\S\s]*?)\s*%>/m);
const tag = matcher[1] || '';
const expression = matcher[2];
outputMap[index] = tokenIndex;
return Buffer.from(expression).toString('base64');
});

if (encodedCode.length) {
const { eexMultilineLineLength, eexMultilineNoParens } = options;
let eexFormatterOptions = `--line-length=${eexMultilineLineLength}`;
if (eexMultilineNoParens.length) {
eexFormatterOptions = eexFormatterOptions.concat(' --no-parens=${eexFormatterOptions.join(", ")}');
}

const binPath = path.join(__dirname, '..', '..', 'prettier_eex_formatter_release');
execSync(`${binPath} ${encodedCode.join(' ')} ${eexFormatterOptions}`, {
encoding: 'utf-8',
})
.trim()
.split('\n')
.forEach((encodedFormattedCode, index) => {
const tokenIndex = outputMap[index];
collectedMultiLine[tokenIndex] = Buffer.from(encodedFormattedCode, 'base64').toString();
});
}

return tokens
.map((token) => ({ ...token }))
.map((token, index) => {
if (token.type === 'text') return token;

const matcher = token.content.match(/<%(#=|%=|=|%|#)?([\S\s]*?)\s*%>/m);
const tag = matcher[1] || '';
const expression = matcher[2];
const ssq = expression.match(/^\s*\r?\n\s*\S/) ? hardline : ' ';
const exprr = '<%' + tag;

if (expression.match(/\r?\n/)) {
const formattedCode = collectedMultiLine[index];

let cursorPosition = 0;
let formattedExpression = [];

formattedCode.replace(/\r?\n/g, (match, offset) => {
if (cursorPosition !== offset) {
let string = formattedCode.slice(cursorPosition, offset);
if (formattedExpression.length && ssq === ' ') {
string = ' '.repeat(exprr.length + 1 - 2) + string;
}
formattedExpression.push(string);
}

formattedExpression.push(hardline);
cursorPosition = offset + match.length;
});

let string = formattedCode.slice(cursorPosition);
if (string.length && ssq === ' ') {
string = ' '.repeat(exprr.length + 1 - 2) + string;
}
formattedExpression.push(string);

token.content = group(concat([exprr, indent(concat([ssq, concat(formattedExpression)])), ssq, '%>']));
} else {
token.content = `${exprr} ${expression.trim()} %>`;
}

return token;
});
};

module.exports = {
formatEex,
};
Loading

0 comments on commit b6961e6

Please sign in to comment.