Scott Hanselman

Change Considered Harmful? - The New Visual Studio Look and Feel

February 24, '12 Comments [58] Posted in Musings
Sponsored By

DISCLAIMER: This is my opinion. I don't work for the Visual Studio Team. If you write an article about this and quote me as "The Principal Program Manager for Something Major" then you are a silly person.

Metro All ThingsThe next version of Visual Studio is being worked on and the Beta is coming out soon that we'll all get to download. The Visual Studio design team put a post out today called "Introducing the New Developer Experience" and many of the comments are negative. Some folks are freaking out about the colors and the icons.

Because the first blog post from Visual Studio was on the new look and feel (and because everyone is Metro-styling everything) the public perception is that no work has been happening except the icons and colors have changed.

This is my blog, not hosted, run, organized or written by anyone but me. My post, my blog, my opinions. My initial reaction to the redesign was who moved my cheese? Why are we making everything gray? But I've been running this for a few weeks and I have some perspective even though I'm not on the Visual Studio team (I work on the web team).

There's basically three issues here as I see it.

  • First, the new look of Visual Studio.
  • Second, look side, what actual new features are in the new Visual Studio.
  • Last, what this new look means to Windows applications and app design in general

The New Look

It's dramatic. It's initially gray. There is a light theme and a dark theme. Here's the VS11 next to VS10. It's still Visual Studio, so that's something, but the skin has changed.

dev10anddev11

The dark theme in Visual Studio 11 looks a lot like my current Text Editor of Choice (and the new hotness everyone is talking about) Sublime Text 2. Here are the two side by side. They are pretty similar. There's only so many ways you can make a minimal UI with a text editor, line numbers, a find dialog and a scrollbar. I actually blogged about simplifying your Visual Studio 2010 a while back. Just turn the toolbars off. You don't need them. In fact, the Web Team (the team I'm on) has a simplified Code View that we've had available since VS 2010.

See how Visual Studio looks very different below than it does above? It's customizable so you can get a number of weird looks. I also blogged about how to change your themes and make VS 2010 look like 2008 here. Also, did you know about http://studiostyl.es? It's a growing list of themes for Visual Studio. There's hundreds. I called some out in my Visual Studio Programmer Theme Gallery.

VS11 with Dark Theme next to Sublime Text 2

In VS10, today, you can switch your IDE to Web Development (Code Only) from Tools | Export Settings | Reset and you'll get this dialog.  That will hide all your tools windows, and extra stuff in the Visual Studio you already have. This feature has been there for years because folks asked for it. This is the same list that you are offered the very first time you launch Visual Studio. It's a nice way to "tidy up" Visual Studio today. Of course you can change the colors and generally mess about as you like.

Pick a Code View

Here's VS11 and VS10 next to each other. VS11 shows a preview of images if you hover over it.

image

Personally, I don't like the ALL CAPS much. I'm sure they have heard that feedback from a lot of people. That's just one man's opinion but I'm not too worried about it. I know the Visual Studio design team is collecting everyone's on their blog and I encourage you to comment there so they see it.

The colorful Visual Studio icons were changed to glyphs. Glyphs are apparently a designer term for icons that are not colorful. You can see a lot of glyphs at http://thenounproject.com and I used a lot in my recent Windows Phone 7 application. We're used to seeing glyphs in Windows already, like in the "tray" by the clock. (Yes I know it's not called The Tray.)

I'd like a little color in my icons, but I don't think they all need to be full color. Just include a splash so I can tell them apart. For example, here's my copy of Adobe Audition next to Photoshop, both from my same machine. Notice that there's some color in important buttons in Audition and very very minimal color in Photoshop, but mostly grays. There's still room for splashes of color in black and white glyph style icons. The idea is to make the icon get out of the way, but also be "scannable" so that I can remember not only where it is, but if it moves still scan and get to it quickly.

In Photoshop I'm editing color photos and in Audition I'm editing a colorful waveform. In both editors the UI is getting out of the way of the thing I'm editing. I like the idea of my editor being less important than the thing I'm editing.

Photoshop and Audition side by side

New Features

Searching for Features in VS11There are a pile of non-UI/UX features in Visual Studio 11 that are broad and systemic changes that aren't just changing colors. I’m finding it easier to locate the commands and options I need due to the new search features and toolbar reductions I mentioned above.  I find myself exploring relationships in my code with the new Solution Explorer without having to switch tool windows like I use to. I also find that unlike in the past when the files I needed to focus on kept getting crowded out by lots of open stuff I didn’t need now I keep looking up at my open tabs and seeing only the stuff I care about. It's hard to express this without spending hours inside the IDE. There's bug fixes, speed fixes and memory fixes.

Non-theme-related work that the UX guys are doing cleans up the UI and improve it's functionality without removing features. When you consider only the more commonly used toolbars (Standard, Debug, Text Editor, Work Item Tracking, Test Tools), they've removed 60% of the clutter and globally there's 35% fewer commands in the toolbar in VS11, but all the features are still available. The stuff that has value is up front and easier to find and the obscure stuff I can search for with one hotkey. Don't let talk of icon colors (or lack of) detract from actual thought that's been put into a developer's (in my case, a web developer's) daily workflow.

Solution Explorer and Class View are one

My team (the angle brackets folks) has talked about the features and fixes in ASP.NET, IIS and related tech on videos and tutorials up on http://asp.net/vnext and will keep updating that mini-site. All the editors have been updated with features like goto definition in JavaScript, color pictures and vendor prefixes and piles more. All added features, but done in a clean way that gives you useful functionality without adding more windows and widgets.

CSS Color Picker

You'll get your hands on the Beta very soon. It's not too late to get or give feedback. All the teams are listening and I'm making sure that your voice (and mine) are going to the right people. To dismiss all the CLR work, the BCL work, the speed and meory footprint work over some icons is premature. Does it work?

Is this Metro-style?

As far as the design, I think that there's a lot more interesting work going on in Windows application design now in everyone's applications. No, not everything is or has to be "Metro-style." It does need to be thoughtfully designed, though. We've seen that in phones and on desktops. We're starting to see applications with design at their heart.

Zune and iTunes

Office 15 Preview Image from The VergeI'm enjoying seeing what's coming next. There's a lot of interesting conversations around the web right now about what all design thought means for Windows, for Office, and for applications in general. Ars Technica has an interesting blurb that talks about an "elegant fusion of ribbon and Metro."

Is Visual Studio a metro-style application now? No. Is Zune or Sublime or iTunes or Photoshop? Of course not. I think the larger more interesting discussion is an increased use of whitespace, of design languages, of "content over chrome," of fewer lines, fewer wasted pixels and clearer spaces, of form meeting function. For now, Visual Studio is Beta, and it will look likely different when it's released. But it is being designed.

The Verge has some screenshots of some early builds of Office 15 and how it might look. I like our they to use color purposefully within the design. It's early to pass judgment on any of these applications, but I think I understand what all these designers are trying to accomplish. They don't (and I don't) want color and bling and flash in the outside application chrome if it doesn't provide information about my content. It's like what Tufte says, make those pixels work for you. Sure, one can blindly "Metro-style all things" but I would rather think of it as a applying design principles like clean lines, appropriate use of whitespace and focus on the the content (in this case, code). This beta is a step in that direction. I'm sure it will improve as feedback comes in.

VS and Me

There's style and there's functionality. So far I've been very happy with the functionality of VS11 and have been writing all my code in it. It opens VS2010 projects without converting and I can round-trip between VS11 and VS10SP1. I can create and target .NET 4.5 apps as well as.NET 2.0 apps. So far VS11 has been faster on my machines than VS10, and since I have more than one processor, I get multi-processor builds automatically.  The editor is fast and the builds are fast.

Target .NET 2.0 apps

It's far too early to panic. Sure, my cheese has been moved, but I can always change the colors or toolbars. I just want a faster, cleaner, more productive system that focuses on the code.

My advice to you? Go follow the updates on the Visual Studio blog. Keep adding your comments, and check out their new Visual Studio posts each day including the one they just posted today about the Solution Explorer hub. But above all, download it on launch day, use it for a while and see what you think.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Supporting high-dpi pixel-dense "Retina" Displays like iPhones or the iPad 3 with CSS or IMG

February 21, '12 Comments [14] Posted in Blogging | HTML5
Sponsored By

I'm loving responsive design and am slowly updating all my websites to support mobile browsers as well as tablets. Currently Hanselman.com (this site), Hanselminutes.com (my weekly podcast), SpeakingHacks.com (a video I sell on how to be a better presenter) as well as LostPhoneScreen.com (where I sell my Windows Phone 7 application.)

All of this "mobilization" has stemmed from my frustration with other folks' sites that look lousy on my phone. It's SO frustrating to reach a site that could take 10 minutes and make its mobile experience 100% better.

Now that I've updated my main sites I'm tidying up a few things that continue to bug me. On my iPhone 4S with a DPI of 326 dpi, the logo on my site and a few other graphics look lousy. Why?

Well, for example, the image for the logo is a PNG that is literally 100px by 100px. This is a foreground image (not a CSS background image on an elements, yes, people still use those) and it has its height and width both set to 100px. The size of the image and the img tag are both really 100x100.

A blurry image on a Retina Display

You can see that not only is the logo blurry but the search magnifying glass and social icons are as well. That's because the browser has scaled up the images to manage the super high-res display of this device. Better that they scale it up than make it too tiny. The overall size of all the other elements on the page are scaled up as well so the fonts and form elements like the dropdown are crystal clear.

There's a few ways to fix this.

Support (High DPI) Retina Display with CSS Background Images

Since I am already using CSS Media Queries to change my site's CSS for smaller screens like this already:

@media screen and (max-width:720px)
{

}

I can certainly do the same and detect high resolution displays. It's not just the iPhone. A lot of the newer Nokias and HTCs have displays over 200dpi.

I could create a media query like this:

@media screen and (min-device-pixel-ratio: 2) {

}

Or do conditional inclusion like this (or -webkit-min-device-pixel-ratio):

Do your testing and be aware you likely need to use both the webkit prefix and one without:

only screen and (-webkit-min-device-pixel-ratio : 2),
only screen and (min-device-pixel-ratio : 2) {
}

You may decide that 1.5 is a better ratio for you.

The WebKit folks are thinking about this and I could use background-size like this:

div {
background: url(logo-low.png);
background: url(logo-high.png) 0px 0px / 100px 100px;
}

Handling Foreground Images (with the IMG tag)

Ideally I should be using SVG (Scalable Vector Graphics) for my images like the magnifying glass and they'll scale everywhere. Until that day (and until I'm willing to redo all my images), I can take advantage of the way the IMG tag has always worked. We know that nothing is sadder than a small image that has been scaled up by incorrect width= and height= tags.

Since my image is only 4k, I decided to make a high-res 200x200 image and mark the width and height attributes to 100px. Stated differently, I'm sending more pixels than needed and scaling them down. The result is that it looks clear on high res displays and the same as it did before on regular displays. Here is a screenshot with the retina Logo file.

A super clear image on a Retina Display

It is true that I'm sending more data than I need to here. I am sending a 4kb image when the 100x100 original is 2kb. I can solve this by  swichign to a background image and using the conditional CSS options outlined above.

In this case it's a reasonable tradeoff and I'm happy with the result. It's a good solution for small images like this. For the social images I will likely want to sprite them and create both regular and "@2x.png" versions of the sprite.

Small, Medium, Large, FullSized

The problem isn't just with high-res images, it's also that we want to send the minimum number of bytes across the 3G wire while still offering the mobile user the chance to download the full sized images if they want.

I really wish that LowSrc still worked. I was talking to Jeremy Keith about this last week and he mentioned he just blogged the same thing! This was how we did things when we were all still on dialup. (And as Jeremy points out, we also often used ALL CAPS and omitted quotes! ;) )

my logo

It seems that LOWSRC just died, however. Ironically LOWSRC only works in OLD browsers. This is a shame as it was/is useful.

Mat at AListApart mentions another side of this idea using a fullsrc attribute, except with data- for HTML5 compliance with an idea from Scott Jehl.

It's unfortunate that there isn't a clear and comprehensive technique yet to handle both the low-res, fullsrc and highdpi solution. Today you can achieve them all with some CSS3 and some jQuery/JavaScript.

A correct image tag should take into consideration:

  • Connection speed (detected as well as user-overridden)
  • Screen DPI (pixel density)
  • Responsive design image resizing

I think a solution clearly needs to be baked into HTML5 with a solution like the ones that Mat Marquis outlines. The question before us is do we update the IMG tag or are we talking about a new tag?

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

It's 2012 and your kids have an iPhone - Do you know where they are? I do.

February 11, '12 Comments [30] Posted in Mobile | Musings
Sponsored By

Google Map Pin tells me your locationThe strangest thing just happened. I'm sitting here in a hotel in New Zealand and my phone pops up an alert from a push-to-talk voice chat application I recently installed called Voxer. It's a voicemail from a tween (a child perhaps not quite 13 - in-between) teasing me about my name. "Scott Hanselman - Who would name their kid Scott HanselAndGretal man. *giggle*" Harmless stuff, of course, but weird and random. No idea who this is.

The name wasn't familiar but there was a little icon next to the voicemail in the Voxer app. Perhaps you've seen it before. It was a little red pin.

I clicked, and the young person's exact location popped up. They were sitting in a public library, likely after school. Because the application is an iPhone app and tied into their identity, the app shows their full name, not an alias. Literally a light 20 seconds (not minutes, mind you) of Googling and I find their Google Plus profile and Twitter. Google Plus promotes even more "information leakage" with it's "Places Lived" feature. This showed the last three cities the young person lived in. One of them was Portland. Since I live in Portland that seemed too coincidental. I searched for people I know on Facebook with the same last name who lived in Portland. Turns out I'm Facebook-friends with this young person's dad, although both have long since moved out of town. I messaged him and he was appreciative, relieved it was me and not a stranger, and is dealing with his child.

What's the moral here friends? Let me break it down for you:

  • More apps leak your exact location than you realize.

    • These apps often ask you once, and then broadcast your location multiple times a day. I'm looking at you Facebook, Twitter, GroupMe, Voxer and Foursquare. I doubt anyone, including this young person, would ever guess that this little voice chat program would give up his address. If adults don't noticed this stuff, how is a teenager (or younger) supposed to?
    • Folks at Voxer - You need to make location services OFF by default.
  • Your kids have no idea. Yet.

    • They may be social this and savvy that, but honestly, they don't realize how much info they are leaking. Take a moment today and talk to them about it.

    • You've had the Drugs Talk, the Sex Talk, now have the Location Services Talk.

    • You can turn off Location Services on a per apps basis, and you can also turn on Restrictions on your phone so that only some apps (Find my Friends, for example) can access the GPS while others (Twitter, Voxer, etc) can't.

  • Have a Location Services policy for your family

    • As stupid as teens often are, they are smart when armed with information. Explain the situation, show them the control they have and apply your family policy.

Hope this helps your kids. Spread the word.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

The Web is the new Terminal: Are you using the Web's Keyboard Shortcuts and Hotkeys?

February 2, '12 Comments [45] Posted in HTML5
Sponsored By

My gmail looks like a terminal if you squint

A V100 Terminal - Creative Commons via blakespot on FlickrNUI is OUI, Dear Reader. About eight years ago I blogged about "text mode" and said (if I may be silly and quote myself):

"I’m just saying that my Tab,Tab,Tab,Enter will beat your Click,Tab,Alt-F,O,Click,Double-Click, more often than not." - Me

I like to look at the computer systems of the businesses that I visit on a regular but spaced apart basis over the course of years. You know these businesses - your dentist, your eye doctor, the car shop that changes your oil, perhaps your bank or finance person. You see them every 3 to 6 months, or perhaps over a many years.

At my automotive shop, I watch them move from:

  • Keyboard heavy, very fast
    • VT100 Dumb Terminal
    • Windows running a VT100 Dumb Terminal Emulator
    • Netscape with Java running a VT100 Dumb Terminal plugin
  • Mouse heavy, very slow
    • Ugly gray HTML application in Netscape
    • Pretty AJAXy HTML application in Firefox
  • Keyboard heavy, very fast
    • Very terminal-like AJAXY HTML application in Firefox
    • ???

Tab, Tab, Enter is just the start. I propose that the interaction model for this "timeline" looks like somewhat like this.

Bell curve showing Mouse and Keyboard on Y Axis and Time on X axis. Curve shows most sites use mice. We need more using keyboards.

If you are an airline counter customer service person, you're going to want to touch the mouse as little as possible. Every keystroke counts, in fact, and this is one of the reason that every airline counter system I've ever seen is either a terminal itself or a browser window into a terminal. The interaction model for an airline workers apps needs to be terse and crisp and keyboard based because they are using it all day.

When Web Sites start to become Web Applications that are used every day they have to have keyboard shortcuts. More and more if you app doesn't have them you're going to limit your audience.

All my favorite web applications use keyboard shortcuts, and you'll notice that they are coalescing around a few common patterns:

  • J, K to move up and down
  • Enter to select or expand
  • G + some letter to Navigate (Goto)
  • / for Search
  • ? for keyboard help

There are two kinds of hotkeys on the web, though. There are "accesskeys" which have been in HTML since forever, then there's "hotkeys" that are application specific and often done with JavaScript bindings or jQuery plugins like jquery.hotkeys. Implementing these takes virutally no effort and can pay off hugely with your most discerning customers. Logical hotkeys can also turn beginners into enthusiasts.

<gratuitous bold="true">There is literally no reason to not implement keyboard hot-keys in your web application other than you've likely forgotten it's important.</gratuitous>

Access Keys

Implementing accesskey requires only the will and some thought.

<label for="homePhone">Home phone:</label>
<input name="HomePhone" type="text" maxlength="20" id="homePhone" accesskey="H" title="Home phone" class="text-box" />

Here we've made "ALT-H" go to the Home text box. Do you want awesome and automatic "KeyTips" to appear when the user presses ALT? Use the lovely KeyTips jQuery plugin (on NuGet also).

KeyTips for accesskeys as a jQuery plugin

Access Keys are very easy to setup and now give your 8-hours-a-day data entry user a huge gift and keeps their hands off the mouse. Make sure you do some user experience testing - even if only with yourself - and do some standard tasks with your web application and count both keystrokes and mouse touches.

Hot Keys

Slightly more complicated is adding Hot Keys via JavaScript but only slightly. John Resig's jQuery.Hotkeys is a simple plugin that lets you add and remove keyboard handlers for events in any browser supported combination.

// e.g. replace '$' sign with 'EUR'
$('input.foo').bind('keyup', '$', function(){
this.value = this.value.replace('$', 'EUR');
});

You can bind with selectors so that keys are captured on specific inputs, like the replace/expand example above, or you can bind (and unbind to the document with optional modifiers:

$(document).bind('keydown', 'ctrl+g', myfunc);

Sushant Bhatia has a great blog post (coincidentally written within minutes of mine, great minds think alike!) that talks about the importance of keyboard UX and how hotkeys are always preferable over tab, tab, tab.

Example Web Applications with Awesome Keyboard support

Here's some of the best examples I (and you, thanks Dear Reader for helping!) could find of great Keyboard support in Web Applications.

Twitter

I use these Twitter keyboard shortcuts all the time. You don't need to learn them all. Just use . for refresh, / for search and G-R for replies and you're already ahead of the pack.

Gmail

Gmail really gets credit for proving, in my opinion, that hotkeys on the web can be done elegantly and "just work." It may take a day or two but once you learn how to triage your email with just your keyboard you'll be surprised how fast you can get in and out and back to work.

I use J and K to navigate, X to select then # to delete or E to archive. Bam, bam, bam.

Gmail Hotkeys

Hotmail

Hotmail? Yes, while Hotmail drops the box by not including a help popup for the ? button, Hotmail not only supports their own keyboard shortcuts, but also familiar shortcuts from Gmail and Yahoo.

Windows Live Hotmail Hotkeys and Keyboard shortcuts

GitHub

Another example of a site you may be on for hours if it's part of your work. Github also supports ? for help and gives lots of shortcuts. Theirs are also J and K (which have meant up and down for folks familiar with vi and *nix editors) for moving up and down as well as X for toggling selection like Gmail, C for great, and / for search. You see how a pattern is developing on its own?

Some GitHub keyboard shortcuts

There doesn't appear to be a Help page with the list of Github keyboard shortcuts so for now, go over there, login and press ? to explore the complete list.

Jira Bug Tracker

Jira from Atlassian is a popular bug tracker with this same keyboard model. Every web application needs to include a web popup like this when ? is pressed.

Some Jira shortcuts

Remember The Milk

Remember The Milk is a web-based todo application with lots of mobile versions as well. However, they are best known by their web application which was very innovative when it first came out.

In fact, they were the first web application I ever used that actively marketed their application as being keyboard friendly. I love that we're at a time in the web where that is possible.

Remember The Milk has an extensive list of keyboad shortcuts

Asana

Asana is a team-focused shared todo list for projects and project management. They are super-focused on keyboard support and use it in all their promotional video AND think it is so important that they keep on the screen all the time! Classy.

Asana's Keyboard shortcuts are front and center

And they have LOTS, very logical and organized.

image

Trello

Trello's up and coming project management board software also leans heavily on hotkeys.

image

YouTrack

YouTrack from JetBrains says this about itself: "YouTrack is a keyboard-centric application and provides enough keyboard support to let you forget about using the mouse in most cases." Sassy!

Personally, I'm moving away from the Ctrl-Alt-This and That and prefer simpler hotkeys like these for YouTrack.

A subset of YouTrack Hotkeys

And as this isn't an exhaustive list but rather a long list to make a point, how about DuckDuckGo.

DuckDuckGo

The little search engine that could, DuckDuckGo includes keyboard shortcuts not just to move around search results but also another unusual keyboard-centric feature they called !Bang.

I keep DuckDuckGo.com as my home page. If I want to search them, I search. If I want to search Bing I type "hanselman b!" or Google with "hanselman g!" or hundreds of other sites like "hanselman image!" or even super specific site searches like "hanselman csharp!"

Now THAT'S keyboard friendly.

image

Conclusion

Like it or not, there's a standard brewing on the web. Not only should you have accesskey support (should have done this years ago) but also extensive keyboard shortcuts if you expect your users to spend serious time with your application.

At the very least, I think it's fair to say that these are de facto standard shortcuts now on the web and you should think about what that means for your application:

  • J, K to move up and down
  • Enter to select or expand
  • G + some letter to Navigate (Goto)
  • / for Search
  • ? for keyboard help

Good shortcuts mean happy and engaged users.

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Prompts and Directories - Even Better Git (and Mercurial) with PowerShell

February 1, '12 Comments [36] Posted in Open Source | PowerShell
Sponsored By

posh-git with custom directoryI love PowerShell and spent years and years working with it since it first came out. I've actually got 15 or so pages of PowerShell posts on this blog going way back.

PowerShell is insanely powerful. I would even go so far as to say it was (is) ahead of its time. PowerShell is totally dynamic and is almost like having JavaScript at the command line, but even more thoughtfully designed. I appreciate folks that love their bash shells and what not, but PowerShell can do some wonderful things.

A long time ago (2009) Mark Embling blogged about a nice prompt with TabExpansion that he'd made to make working with PowerShell and Git (his favorite source control system) nicer. Later, Jeremy Skinner added TabExpansion for common commands. A little while later Keith Dahlby started with their code (with their blessing) and posh-git was born. Expanding even more, Jeremy later created posh-hg (for Mercurial, my favorite source control system).

All of these are currently in use in various forms. Just recently (days ago, even) while I was trying figure out how to get these two separate but similar PowerShell scripts to live together when Keith created a small shared function that makes sharing prompts easier.

I think that Git Bash on Windows needs to go away. It's just not useful to say that a Windows user has to run Bash in order to use Git. PowerShell with Git (or your favorite VCS) is demonstrably better for Windows folks. I also feel that the installation for posh-git, while it uses PsGet (think NuGet for PowerShell, which is INSANELY awesome), just could be easier.

I happened to be tweeting about this and ended up doing a Skype+Join.me 3-way pair programming session with Keith and Paul Betts to explore some ideas on the topic. While a customized prompt is cool, I wouldn't rest until we'd modified "dir/ls" to show source control status. I'm not talking about a PowerShell Provider, I'm talking about extending the View for the result of a dir (get-childitem and a FileInfo) itself.

I want to be able to take a fresh machine and fresh PowerShell installation, invoke one PsGet command and get Git and Hg (and whoever else) integration with PowerShell, a new prompt AND new (yet to be written at this point) directory listing support.

We did some pairing as I sat in a pub and drove while Keith and Paul told me I was a lousy typist. We got a nice prototype working and I went home. After the kids went to sleep I was asking questions on a mailing list and ended up getting an answer from James Brundage, noted PowerShell expert. I'd met James at a Nerd Dinner in Seattle once and gave him a book. He was kind enough to do a screen sharing session with me and refactor my directory spike (and some of posh-git) into a more useful form. It's still a spike, but Keith and I are going to merge all three of them (posh-git, posh-hg and my VCS dir stuff) into one usable and easy to install module. I'm sure we'll both blog about it when it's cleaner. I'm hoping we'll get it all integrated into a single install line:

(new-object Net.WebClient).DownloadString("http://psget.net/GetPsGet.ps1") | iex
install-module posh-git

Here's the general idea that encapsulates a number of these ideas. Rather than scripts that are plugged into your PowerShell $profile, we'll have a module or two like this.

C:\Users\Scott\Documents\WindowsPowerShell\Modules
$ dir

Mode LastWriteTime Length Name
---- ------------- ------ ----
d---- 1/31/2012 10:37 PM Posh-Git
d---- 1/31/2012 10:37 PM Posh-GitDir
d---- 1/31/2012 12:27 AM PsGet

The Posh-Git folder is the Posh-Git source as it is, as a module and imported in your profile like this.

Import-Module Posh-Git
Import-Module Posh-GitDir

Posh-GitDir is my extension module that will change dir/ls/get-childitem and add a Git Status column. I've added extra columns with file information before in PowerShell, except in a cheesy way and I never actually overrode dir directly.

First, we'll make a post-gitdir.Types.ps1xml that adds the new ScriptProperty that pulls details for each file out of a $GitStatus variable that's added each time the prompt is drawn.

<?xml version="1.0" encoding="utf-8" ?>
<Types>
<Type>
<Name>System.IO.FileInfo</Name>
<Members>
<ScriptProperty>
<Name>Git</Name>
<GetScriptBlock>
$retVal = ""
if ($GitStatus.Index.Added -contains $this.Name) { $retVal += "+" } `
elseif ($GitStatus.Index.Modified -contains $this.Name) { $retVal += "~" } `
elseif ($GitStatus.Index.Unmerged -contains $this.Name) { $retVal += "!" } `
else { $retVal += " " }

$retVal += " "

if ($GitStatus.Working.Added -contains $this.Name) { $retVal += "+" } `
elseif ($GitStatus.Working.Modified -contains $this.Name) { $retVal += "~" } `
elseif ($GitStatus.Working.Unmerged -contains $this.Name) { $retVal += "!" } `
else { $retVal += " " }

$retVal
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
<Type>
<Name>System.IO.DirectoryInfo</Name>
<Members>
<ScriptProperty>
<Name>Git</Name>
<GetScriptBlock>
""
</GetScriptBlock>
</ScriptProperty>
</Members>
</Type>
</Types>

This adds the Git column to the output as a ScriptProperty, but doesn't change the default view.

$ dir | get-member

TypeName: Get-ChildItem

Name MemberType Definition
---- ---------- ----------
Mode CodeProperty System.String Mode{get=Mode;}
Create Method System.Void Create(System.Security.AccessControl.DirectorySecurity director...
CreateObjRef Method System.Runtime.Remoting.ObjRef CreateObjRef(type requestedType)
...snip...
BaseName ScriptProperty System.Object BaseName {get=$this.Name;}
Git ScriptProperty System.Object Git {get="";}

I'd have to always select manually, which is tedious.

$ dir | select Name, Git

Name Git
---- ---
CommandType.cs ~
Connection.cs ~
ConnectionExtensions.cs ~
ConnectionManager.cs +
ConnectionScope.cs +
GuidConnectionIdFactory.cs ~

We want to change the dir "view" itself.  We have to copy the default view for a directory at: "C:\Windows\system32\WindowsPowerShell\v1.0\FileSystem.format.ps1xml" and add our new column.

<?xml version="1.0" encoding="utf-16"?>
<Configuration>
<ViewDefinitions>
<View>
<Name>Dir-Git</Name>
<ViewSelectedBy>
<TypeName>Dir-Git</TypeName>
</ViewSelectedBy>
<TableControl>
<TableHeaders>
<TableColumnHeader>
<Label>Git</Label>
<Width>4</Width>
<Alignment>left</Alignment>
</TableColumnHeader>
...snip...
</TableHeaders>
<TableRowEntries>
<TableRowEntry>
<Wrap/>
<TableColumnItems>
<TableColumnItem>
<PropertyName>Git</PropertyName>
</TableColumnItem>
...snip...
</TableColumnItems>
</TableRowEntry>
</TableRowEntries>
</TableControl>
</View>
</ViewDefinitions>
</Configuration>

For the design, I want the Indexed and Working files in two columns, showing Added+, Modified~ and Unmerged! files like this. Deleted files won't show up cause they aren't there.

$ dir #snipped out directories and files for clarity

Mode Git LastWriteTime Length Name
---- --- ------------- ------ ----
d---- 1/31/2012 5:14 PM Configuration
d---- 1/31/2012 5:14 PM Hosting
-a--- + 1/31/2012 5:14 PM 2170 ConnectionManager.cs
-a--- + 1/31/2012 5:14 PM 402 ConnectionScope.cs
-a--- ~ 1/31/2012 5:14 PM 280 GuidConnectionIdFactory.cs
-a--- 1/31/2012 5:14 PM 273 IConnection.cs
-a--- ~ 1/31/2012 5:14 PM 165 IConnectionIdFactory.cs
-a--- + 1/31/2012 5:14 PM 304 IConnectionManager.cs
-a--- 1/31/2012 5:14 PM 118 packages.config
-a--- ~ 1/31/2012 5:14 PM 8296 PersistentConnection.cs
-a--- + 1/31/2012 5:14 PM 1118 PersistentConnectionFactory.cs
-a--- 1/31/2012 5:14 PM 623 PersistentResponse.cs
-a--- ~ 1/31/2012 5:14 PM 1288 SignalCommand.cs
-a--- ~ 1/31/2012 5:14 PM 7386 SignalR.csproj
-a--- 1/31/2012 5:14 PM 23076 TaskAsyncHelper.cs
C:\Users\Scott\Desktop\github\SignalR\SignalR [master +1 ~0 -0 | +10 ~58 -11 !]

We import these modules in our $profile.

Import-Module Posh-Git
Import-Module Posh-GitDir

The posh-git module adds the custom prompt (if you haven't changed yours) with a new function called Write-VcsStatus that is shared between Hg and Git (and any other systems that want to play with us). It only adds the prompt if the user hasn't already customized their prompt. If they have, they'll need to incorporate Write-VcsStatus themselves.

$defaultPromptHash = "HEYStcKFSSj9jrfqnb9f+A=="

$md5 = [Security.Cryptography.MD5]::Create()
$thePrompt = [Text.Encoding]::Unicode.GetBytes((Get-Command prompt | Select-Object -ExpandProperty Definition))
$thePromptHash = [Convert]::ToBase64String($md5.ComputeHash($thePrompt))

if ($thePromptHash -eq $defaultPromptHash) #using the default prompt?
{
#recommend our own
function prompt(){
# Reset color, which can be messed up by Enable-GitColors
$Host.UI.RawUI.ForegroundColor = $GitPromptSettings.DefaultForegroundColor

Write-Host($pwd) -nonewline -foregroundcolor white

Write-VcsStatus

Write-Host ""
return "$ "
}
}
else {
Write-Debug "Make sure your prompt includes a called to Write-VcsStatus!"
}

The craziness that James Brundage came up with to override dir/ls/get-childitem was this. He said he'll do a complete tutorial on his blog with technical details for the generic case.

. ([ScriptBlock]::Create("
function Get-ChildItem {
$([Management.Automation.ProxyCommand]::GetCmdletBindingAttribute((Get-Command Get-ChildItem -CommandType Cmdlet)))
param(
$([Management.Automation.ProxyCommand]::GetParamBlock((Get-Command Get-ChildItem -CommandType Cmdlet)))
)

process {
Microsoft.PowerShell.Management\Get-ChildItem @psBoundParameters |
ForEach-Object {
`$null = `$_.pstypenames.Insert(0, 'Dir-Git')
`$_
}
}
}
"))

Tie it all up with a .psd1 file that has the list of Scripts, Types, Formats and the Module.

@{
ModuleVersion="1.0.0.0"
Author="Scott Hanselman"
Description="Posh-GitDir"
CompanyName="Hanselman and Friends"
RequiredModules="Posh-Git"
ScriptsToProcess="prompt.ps1"
TypesToProcess="posh-gitdir.Types.ps1xml"
FormatsToProcess="posh-gitdir.Format.ps1xml"
ModuleToProcess="posh-gitdir.psm1"
}

To recap, this new module requires the posh-git module, it ands our new "Dir-Git" type, adds the Git ScriptProperty in Types, and shows how to Format it, and overrides get-childitem in the psm1. If you didn't want to override dir proper, maybe you could make a dir-git or dir-hg.

Next steps are for us to integrate them into one module, bring in an inproc library to access the source info (rather than regex'ing the output of git status and hg status) which would speed it up 10x I'm sure, as well as better NuGet support.

In this screenshot you can see posh-git and posh-hg living together. The first directory is a hg repo with a 1 file not in control. The second directory is a git repo with 1 file added in the Index, 10 new added in working, 58 modified, and 11 deleted.

PowerShell with Git and Hg

Keith and Jeremy have done some amazing work. Open Source, baby. I'm looking forward to pairing with them in coming days and buttoning this up. I've been a hardcore Tortoise (Tortoise-Hg, Tortoise-SVN, Tortoise-Git) source control user, but the addition of PowerShell is shaking my faith in a good way. At leat to the point that I think it's worth my spare time to see this through.

Thoughts?

Related Links

About Scott

Scott Hanselman is a former professor, former Chief Architect in finance, now speaker, consultant, father, diabetic, and Microsoft employee. He is a failed stand-up comic, a cornrower, and a book author.

facebook twitter subscribe
About   Newsletter
Sponsored By
Hosting By
Dedicated Windows Server Hosting by SherWeb

Disclaimer: The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.