Giter Club home page Giter Club logo

align-spaces's Introduction

Align Spaces

Aligns certain operators by visually stretching the leading characters, this way you can have groups of aligned code, without having to deal with meaningless whitespace changes in your commits.

Got a suggestion or issue? Raise an issue on GitHub

Workspace Trust Support ✔

The default keybinding to toggle alignment is ctrl + shift + =.
The default keybinding to trigger manual alignment is ctrl + shift + \.

Config

Set "align-spaces.delay" to a number to wait a number of milliseconds before realigning on typing / document change, or set it to "off" and use the align-spaces.realign command to realign.
Set "align-spaces.skip-after-first-assignment": true to ignore any operators on a line after the first =. This can reduce some weird alignment scenarios. See here for details.

Features

// Aligns operators:
foo = bar;
foobar = baz;

foo = foo + bar;
foobar = foobar - baz;

// Ignores content in strings
foo = {
	foo: 'foobar foobar',
	foo: 'foo, bar',
	foo: '\'foo\', "", bar',
};

// Knows the difference between assignment, 'binary', and comparison:
foo = bar;
foobar = baz;
if (foobar === bar) {
	bar = fizzbuzz;
}

// Groups object assignments:
foo = new Foo();
foo.foo = bar;
foo.foobar = baz;

bar = new Bar();
bar.foobar = 'foobar';
bar.baz = foo;

foo.bar = bar;

// Ignores 'unary' operators (those that don't have a space after):
const dx = x * cos(theta) + -y * sin(theta);
const dy = x * sin(theta) + y * cos(theta);

// Does alright with commas:
// prettier-ignore
const matrix = [
	100, 50, 0,
	0, 1, 0,
	2000, 300, 64,
];

Will appear visually as

// Aligns operators:
foo    = bar;
foobar = baz;

foo    = foo    + bar;
foobar = foobar - baz;

// Ignores content in strings
foo = {
	foo: 'foobar foobar foobar',
	foo: 'foo, bar',
	foo: '\'foo\', "", bar',
}

// Knows the difference between assignment, 'binary', and comparison:
foo    = bar;
foobar = baz;
if (foobar === bar) {
	bar = fizzbuzz;
}

// Groups object assignments:
foo = new Foo();
foo.foo    = bar;
foo.foobar = baz;

bar = new Bar();
bar.foobar = 'foobar';
bar.baz    = foo;

foo.bar = bar;

// Ignores 'unary' operators (those that don't have a space after):
const dx = x * cos(theta) + -y * sin(theta);
const dy = x * sin(theta) + y  * cos(theta);

// Does alright with commas:
// prettier-ignore
const matrix = [
	100 , 50 , 0,
	0   , 1  , 0,
	2000, 300, 64,
];

This works by adjusting the width of the character.

Known Issues

  • Rectangular selections are borked

Release Notes

See CHANGELOG.md

align-spaces's People

Contributors

dependabot[bot] avatar oldstarchy avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

Forkers

dciborow

align-spaces's Issues

Tabs make things go very wide

When the decoration is applied to a tab, the width is (generally) 4x wider than it should be since the width is based on the character width.

`-` in `->` should be ignored

$model = new Model();
$model->bar = 'baz';
$otherModel->foobar = $model;

Bad

$model     = new Model();
$model     ->bar    = 'baz';
$otherModel->foobar = $model;

Good

$model = new Model();
$model->bar         = 'baz';
$otherModel->foobar = $model;

It may be desirable to align -> but i suspect only if the preceding expression is the same

futuristic feature checklist

I really like the concept and see massive potential but it needs some usability improvements. The core idea of the extension is text visualization, not a text editing, and to get rid of hard coded text alignment which is counter-productive. It should be some automatic intelligence for displaying text which does not modify the stored byte representation and does not mess with the version control system.

I am not expecting this to be implemented in near future but for anyone interested in futuristic features, I write this list:

  • context/language awareness, at least an optional black- or whitelist of languages or a filename pattern
  • cursor movement/selection based on screen coordinates and not (column, row) so that it freely moves through stretched spaces
    • not even clear if vscode is able to do that at the moment, given that this is quite elaborate to provide and untypical for text editors
    • the width of characters may be split appropriately by typing a new character at a position in between the stretched area
  • automatically adapt alignment of the currently connected group of lines when typing
  • consecutive lines grouped by indentation level and separated by lines without alignment. All lines within such a group are aligned to each other. Groups can be nested inside other groups and receive their own independent alignement but parent groups may continue after the child group.
    • slightly related, split off a subset of lines into a nested group, if those lines cause alignment of other lines which exceeds a configured maximum width
  • allow pattern specifications for where alignment is allowed and which characters may be stretched, ideally language-sensitive
  • stretched characters may be filled with spaces in copied text (and replaced by stretched characters when pasting it)
  • allow partner definitions of a symbol S which whitelists all symbols S' that S can be aligned to

There are technically two ways to implement character stretches (without thinking of current technology's constraints):

  1. transient spaces. These only exist in RAM or other volatile memory but are discarded whenever text is saved to non-volatile memory). The reason being that there are two interface points: one which automatically inserts transient spaces when reading data, one which doesn't. The first is for visual applications, the 2nd one for background applications where visually related information is just noise. Transient spaces would be the clean solution. The only difficult part is for OS maintainers to have a clear algorithm for inserting transient spaces during read operations.
  2. virtual coordinates. An overlay coordinate system in the text field for the cursor. These coordinates are purely based on visualization, not on actual character-based coordinates. I think, this is much harder to deal with for text editors because there are so many coordinate transformations involved all the time. It may create compatibility issues with other text fields/editors which implement the alignment differently or not at all.

Idea: more configuration of which characters are stretched

Maybe it's useful to have an option which restricts stretched characters to certain given characters with certain given preceding or following characters.

Example: it could be that only whitespace characters are regarded for stretching and maybe only those which immediately precede an operator (which is the default).

"align-spaces.stretch-text" : [" ", "\t"]
"align-spaces.when-before": ["//", "/*"]
"align-spaces.when-after": [",", ";", ":"]

I think, it also would be useful to ask in the VSCode community if it is possible to allow the cursor being maneuvred based on the screen coordinates (visualization) and not based on character column start/end.

Minor Edge Cases for Bicep

Love this tool! Trying it out with Azure Bicep. Works better than anything else out there, but a few edge cases that could be even better. Going to see what I can do.

Case 1

Raw

@description('VNET resource group name.')
param vnetResourceGroupName string
param vnetName string = 'HXVNET'
param p4SubnetName string = 'PublicSubnet0'
param p4NicName string = 'hxnic'
@description('Name of the public IP to assign for NIC')
param p4PublicIPName string = 'hxcorepip'

Current

image

Preferred

@description('VNET resource group name.')
param vnetResourceGroupName string
param vnetName              string = 'HXVNET'
param p4SubnetName          string = 'PublicSubnet0'
param p4NicName             string = 'hxnic'
@description('Name of the public IP to assign for NIC')
param p4PublicIPName        string = 'hxcorepip'

Case 2

Input

var p4CmdToRun = 'sudo /usr/local/bin/signal.sh >> /var/log/userdata.log 2>&1'
var vnetID = resourceId(vnetResourceGroupName, 'Microsoft.Network/virtualNetworks', vnetName)
var imageReferenceSource = {...
}
var planReferenceSource = {...
}

Current

image

Preferred

var p4CmdToRu            = 'sudo /usr/local/bin/signal.sh >> /var/log/userdata.log 2>&1'
var vnetID               = resourceId(vnetResourceGroupName, 'Microsoft.Network/virtualNetworks', vnetName)
var imageReferenceSource = {...
}
var planReferenceSource  = {...
}

Case 3

Raw

resource p4PublicIPName_resource 'Microsoft.Network/publicIPAddresses@2020-08-01' = {...
}

resource p4NicName_resource 'Microsoft.Network/networkInterfaces@2020-08-01' = {...
}

Current

image

Prefered

resource p4PublicIPName_resource 'Microsoft.Network/publicIPAddresses@2020-08-01' = {...
}

resource p4NicName_resource      'Microsoft.Network/networkInterfaces@2020-08-01' = {...
}

Performance impact when typing

I have a lot of extensions installed so I can't be sure, but I did some tests and it seems that having this extension enabled causes delays when typing on every keypress. More investigation is required, but disabling automatic alignment does seem to help.

align by first assignment operator (= :) each line

I think only the first = or : alignment is enough for each line

For example, the alignment of arrows or other operators will cause too many meaningless whitespace, because if variable names are very long, the whitespace will increase exponentially,there are many such examples.

In short, one is enough.

// expected
const f1      = (x) => x + 1
const f111111 = (x, y, z) => x + y + z

```javascript
// now
const f1      = (x)       => x + 1
const f111111 = (x, y, z) => x + y + z

Fix uncaught errors

VSCode reports that this extension is throwing uncaught errors (though I haven't noticed any functional problems). It's maybe to do with opening tabs that don't have normal text content.

Idea: align the keyword "from"

import a              from 'a'
import bb             from 'bb'
import ccc            from 'ccc'
import { d1, d2, d3 } from 'ddd'
import * as xxx       from 'xxx'

Don't align the last comma

If the last character in a line is a comma, don't align it with others as it makes selecting a line by mouse difficult

Conflicts with existing align spaces

Many formatters have their own alignment

Example:

type T struct {
	A   int
	AAA int
}

// '.' is real space
// ' ' is fake space

// '…' some real spaces with reduced width
// (cool way if it's possible to set width less than 1)

// raw
var _ = T{
	A:...100000000,
	AAA:.1000,
}

// current
var _ = T{
	A  :...100000000,
	AAA:.1000,
}

// reduced spaces (best way)
var _ = T{
	A  :…100000000,
	AAA:.1000,
}

// if … not supported (still much better than current)
var _ = T{
	A  :...100000000,
	AAA:.  1000,
}

// // same for spaces before ':'

Doesn't consider tab width

When working out how to align two things, if the number of leading tabs is different the width of the offset required is miscalculated.

Also, if two lines have different indentation they should probably not be grouped.

Language specific operators

I'd like to align <> with = in SQL, and < and > should probably be added along with the <= and >= operators, but doing so would almost definitely interfere with xml-type languages.

Ignore comments

Comments tend to contain text, text contains commas, commas in text don't need to be aligned.

@param and @return could be aligned, but multiline types would have to be considered.

/**
 * does some things, and some other things, and some more things
 * @param {{ foo: string; foobar: string; }} foo
 * @param {string} bar this, and that, are parameters
 * @param {Record<string, number>} baz
 */
function foo(foo, bar, baz) {}

Currently the comma in the first line things, will align with the comma in the doc for the bar parameter, which is bad.

Ideally, bar and baz should align after the type definitions, the comment and the @foo parameter should be ignored.

Allowed Languages

Add a config to define which languages should this extension be active on.

Recommend add a command/shortcut to align document

It was a great plugin, but I felt a little dizzy, like I was typing into a shaking computer.
So that I couldn't focus on the line I was editing.
I recommend adding an option to align document by a command/shortcut, rather than keystroke typing.

Operators should only align with similar operators

const foo = bar
    ? foobarbaz.foo === foobarbaz.bar
    : foobar !== bar

Current Behaviour

const foo             = bar
    ? foobarbaz.foo === foobarbaz.bar
    : foobar !=       = bar

Expected

const foo = bar
    ? foobarbaz.foo === foobarbaz.bar
    : foobar        !== bar

See also #4

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.