The Copilot Labs technical preview, which includes Code Brushes, ended on December 15th, 2023.
Learn more about why it was sunset.
Painting is a very visceral activity - you dip your paintbrush in a color and dab it onto your image. We wondered if we could make editing code feel just as tactile.
To explore this idea, we added a toolbox of brushes to Copilot Labs that can modify your code. Just select a few lines, choose your brush, and see your code update.
What can brushes do?
We’ve populated the toolbox with a few brushes that we find handy:
Make code more readable
Let’s say you were working on code with a function that’s hard to digest. What would it look like to “paint” that code with a brush that makes it easier to understand?
function ascending(a, b) {
return a == null || b == null ? NaN : a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;
}
function ascending(a, b) {
if (a == null || b == null) {
return NaN;
} else if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else if (a >= b) {
return 0;
} else {
return NaN;
}
}
function ascending(a, b) {
if (a == null || b == null) {
return NaN;
} else if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else if (a >= b) {
return 0;
} else {
return NaN;
}
}
Add types
Could adding types be as easy as clicking a button?
function ascending(a, b) {
if (a == null || b == null) {
return NaN;
} else if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else if (a >= b) {
return 0;
} else {
return NaN;
}
}
function ascending(a: number, b: number): number {
if (a == null || b == null) {
return NaN;
} else if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else if (a >= b) {
return 0;
} else {
return NaN;
}
}
function ascending(a: number, b: number): number {
if (a == null || b == null) {
return NaN;
} else if (a < b) {
return -1;
} else if (a > b) {
return 1;
} else if (a >= b) {
return 0;
} else {
return NaN;
}
}
Fix simple bugs
What if it were easy to fix simple bugs, like typos?
function bisectLeft(a, x, lo, hi) {
if (low == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (ascending(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
}
function bisectLeft(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (ascending(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
}
function bisectLeft(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (ascending(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
}
Add debugging statements
Or if those bugs are more complex, could a brush add debugging statements for you?
function bisectLeft(a, x, lo, hi) {
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
if (ascending(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
}
function bisectLeft(a, x, lo, hi) {
console.log("x = ", x, "lo = ", lo, "hi = ", hi);
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
console.log("x = ", x, "lo = ", lo, "hi = ", hi, "mid = ", mid);
if (ascending(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
}
function bisectLeft(a, x, lo, hi) {
console.log("x = ", x, "lo = ", lo, "hi = ", hi);
if (lo == null) lo = 0;
if (hi == null) hi = a.length;
while (lo < hi) {
var mid = lo + hi >>> 1;
console.log("x = ", x, "lo = ", lo, "hi = ", hi, "mid = ", mid);
if (ascending(a[mid], x) < 0) lo = mid + 1; else hi = mid;
}
return lo;
}
Make your code more robust
It works in my browser, what about yours? Make any code more robust with a click.
form {
border-radius: 10px;
}
form {
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
}
form {
border-radius: 10px;
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
}
And more!
You can also define your own custom brushes on the fly.
<form>
<div>name</div>
<input type="text" />
<div>email</div>
<input type="text" />
<div>add me to the mailing list</div>
<input type="checkbox" />
<button onclick="submitForm()">submit</button>
</form>
<form>
<div>
<label for="name">name</label>
<input id="name" type="text" />
</div>
<div>
<label for="email">email</label>
<input id="email" type="text" />
</div>
<div>
<label for="mailing">add me to the mailing list</label>
<input id="mailing" type="checkbox" />
</div>
<button onclick="submitForm()">submit</button>
</form>
<form>
<div>
<label for="name">name</label>
<input id="name" type="text" />
</div>
<div>
<label for="email">email</label>
<input id="email" type="text" />
</div>
<div>
<label for="mailing">add me to the mailing list</label>
<input id="mailing" type="checkbox" />
</div>
<button onclick="submitForm()">submit</button>
</form>
We’ve added these brushes, along with a few others, to Copilot Labs. This was a quick exploration, really just the tip of the iceberg! In the future, we’re interested in adding more useful brushes, as well as letting developers store their own custom brushes.
As we explore enhancing developers’ workflows with Machine Learning, we’re focused on how to empower developers, instead of automating them. This was one of many explorations we have in the works along those lines.
We would love to hear your thoughts and brush ideas! Give us a shout on Twitter.