home

Using bookmarks to quickly navigate in PowerShell

31 Jan 2013

There are a few folders that I spend a lot of time and it is surprisingly slow to type cd c:\path\to\my\project many times a day. I solved this by creating a module that allows me to bookmark directories and navigate to them using aliases. Simply put, I can shorten the previous command to g project.

Usage looks like this:

Set-Bookmark <name> <path>
Get-Bookmark # to list all
Get-Bookmark <name>
Remove-Bookmark <name>
Clear-Bookmarks
Invoke-Bookmark <name>

I alias Invoke-Bookmark as g for speed.

All you have to do is import the module in your profile and initialize your bookmarks.

# Microsoft.PowerShell_profile.ps1

Import-Module bookmarks.psm1
Set-Alias g Invoke-Bookmark

Set-Bookmark project c:\path\to\my\project

Here is the module. Happy bookmarking!

# bookmarks.psm1
# Exports: Set-Bookmark, Get-Bookmark, Remove-Bookmark, Clear-Bookmarks, Invoke-Bookmark

# holds hash of bookmarked locations
$_bookmarks = @{}

function Get-Bookmark() {
  Write-Output ($_bookmarks.GetEnumerator() | sort Name)
}

function Remove-Bookmark($key) {
<#
.SYNOPSIS
  Removes the bookmark with the given key.
#>
  if ($_bookmarks.keys -contains $key) {
    $_bookmarks.remove($key)
  }
}

function Clear-Bookmarks() {
<#
.SYNOPSIS
  Clears all bookmarks.
#>
  $_bookmarks.Clear()
}

function Set-Bookmark($key, $location) {
<#
.SYNOPSIS
  Bookmarks the given location or the current location (Get-Location).
#>
  # bookmark the current location if a specific path wasn't specified
  if ($location -eq $null) {
    $location = (Get-Location).Path
  }

  # make sure we haven't already bookmarked this location (no need to clutter things)
  if ($_bookmarks.values -contains $location) {
    Write-Warning ("Already bookmarked as: " + ($_bookmarks.keys | where { $_bookmarks[$_] -eq $location }))
    return
  }

  # if no specific key was specified then auto-set the key to the next bookmark number
  if ($key -eq $null) {
    $existingNumbers = ($_bookmarks.keys | Sort-Object -Descending | where { $_ -is [int] })
    if ($existingNumbers.length -gt 0) {
      $key = $existingNumbers[0] + 1
    }
    else {
      $key = 1
    }
  }

  $_bookmarks[$key] = $location
}

function Invoke-Bookmark($key) {
<#
.SYNOPSIS
  Goes to the location specified by the given bookmark.
#>
  if ([string]::IsNullOrEmpty($key)) {
    Get-Bookmark
    return
  }

  if ($_bookmarks.keys -contains $key) {
    Push-Location $_bookmarks[$key]
  }
  else {
    Write-Warning "No bookmark set for the key: $key"
  }
}

Export-ModuleMember Get-Bookmark, Remove-Bookmark, Clear-Bookmarks, Set-Bookmark, Invoke-Bookmark
blog comments powered by Disqus