Suppose how nice it would be to use #region directive when writing javascript code.
Javascript is becoming more and more complicated, and it is hard to scroll up and down every time we want to find needed function name and see what parameters it accepts.
I was so tired with this scrolling that started to search some alternative small IDE-s or highlighting text editors which would allow me to use collapsible regions in js files, but in this case I would lose javascript intellisense in VS 2008. I even thought about creating my own text editor plug-in for VS, but again - what about intellisense.
Earlier or later, I found one nice solution to the problem on Microsoft forums. Yes - it's so simple. The solution uses simple macros which parses current document and creates collapsible regions for
//#region
//#endregion
pairs.
So simple :)
Thanks to the author!
And because I don't not find it to be easily detectable in the internet, I decided to blog this.
Just do the following steps to support //#region directive:
1) Open Macro explorer:
2) Create new macro:
3) Name it "OutlineRegions":
4) Click "Edit" macro and paste the following VB code into it:
Option Strict Off Option Explicit Off Imports System Imports EnvDTE Imports EnvDTE80 Imports System.Diagnostics Imports System.Collections Public Module JsMacros Sub OutlineRegions() Dim selection As EnvDTE.TextSelection = DTE.ActiveDocument.Selection Const REGION_START As String = "//#region" Const REGION_END As String = "//#endregion" selection.SelectAll() Dim text As String = selection.Text selection.StartOfDocument(True) Dim startIndex As Integer Dim endIndex As Integer Dim lastIndex As Integer = 0 Dim startRegions As Stack = New Stack() Do startIndex = text.IndexOf(REGION_START, lastIndex) endIndex = text.IndexOf(REGION_END, lastIndex) If startIndex = -1 AndAlso endIndex = -1 Then Exit Do End If If startIndex <> -1 AndAlso startIndex < endIndex Then startRegions.Push(startIndex) lastIndex = startIndex + 1 Else ' Outline region ... selection.MoveToLineAndOffset(CalcLineNumber(text, CInt(startRegions.Pop())), 1) selection.MoveToLineAndOffset(CalcLineNumber(text, endIndex) + 1, 1, True) selection.OutlineSection() lastIndex = endIndex + 1 End If Loop selection.StartOfDocument() End Sub Private Function CalcLineNumber(ByVal text As String, ByVal index As Integer) Dim lineNumber As Integer = 1 Dim i As Integer = 0 While i < index If text.Chars(i) = vbCr Then lineNumber += 1 i += 1 End If i += 1 End While Return lineNumber End Function End Module
5) Save the macro and close the editor.
6) Now let's assign shortcut to the macro. Go to Tools->Options->Environment->Keyboard and search for your macro in "show commands containing" textbox:
7) now in textbox under the "Press shortcut keys" you can enter the desired shortcut. I use Ctrl+M+E. I don't know why - I just entered it first time and use it now :)
That's it, now if you write the following javascript code:
/// <reference name="MicrosoftAjax.debug.js" /> /// <reference name="MicrosoftAjaxTimer.debug.js" /> /// <reference name="MicrosoftAjaxWebForms.debug.js" /> // KWB.BaseWizard class constructor //#region Type.registerNamespace("KWB"); KWB.BaseWizard = function(field) { // call base constructor KWB.BaseWizard.initializeBase(this); this._state = null; } //#endregion // KWB.BaseWizard Class Body //#region KWB.BaseWizard.prototype = { // Sys.Component Overrides //#region dispose : function () { this._state = null; this._stateField = null; this.lastClicked = null; Sys.Application.remove_load(this.appLoad); KWB.BaseWizard.callBaseMethod(this, 'dispose'); }, initialize : function() { KWB.BaseWizard.callBaseMethod(this, 'initialize'); }, //#endregion // Properties //#region get_state : function() { return this._state; }, set_state : function(value) { this._state = value; }, //#endregion // Methods //#region getNext : function(current) { /// <summary> /// Override. Called when 'next' is called. Determines next frame to display /// </summary> /// <param name="current">current SelectedIndex</param> return current + 1; }, getPrevious : function(current) { /// <summary> /// Override. Called when 'previous' is called. Determines previous frame to display /// </summary> /// <param name="current">current SelectedIndex</param> return current - 1; }, finish : function() { /// <summary> /// Override. Called when 'finish' is pressed /// </summary> return true; }, //#endregion // Event handlers //#region nextClick : function() { //TODO: add contents later } //#endregion }; KWB.BaseWizard.registerClass('KWB.BaseWizard', Sys.Component); //#endregion // WizardStepType enumeration //#region KWB.WSType = function(){}; KWB.WSType.prototype = { Server : 1, Client : 2, Service : 4 } KWB.WSType.registerEnum("KWB.WSType", false); //#endregion if(typeof(Sys) !== "undefined")Sys.Application.notifyScriptLoaded();
Now click Ctrl+M+E and you will see:
Veeery handy !
This is possible in VS because actually you can outline and collapse any selection you like manually, this work in most editors for VS.
If you are interested about that shortcuts see Text Manipulation Shortcut Keys, Visual C# Scheme . The shortcuts starting with Ctrl+M are the ones that manipulate test outlining and toggling.
Check out my previous post related to js files in AJAX scenario, and see how we can remove unnecessary white spaces and comment blocks from them for use in production:
Auto generate release scripts for web application using T4 template
Hope this helps.