GitHub Next Logo

Code Brushes

Can editing code feel more tactile, like painting with Photoshop brushes? We added a toolbox of brushes to our Visual Studio Code extension that can modify your code.

What's it for?
Updating code with machine learning
Stage
Usable prototype
Who made it?
Share

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 our Copilot Labs Visual Studio Code extension 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) {
  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: 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 (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) {
  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;
    -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>
    <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 the Copilot Labs brushes toolbox, which is available for anyone with a Copilot license. 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.