#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma IndependentModule = AlignComments #pragma version=0.8 // Inspired by the Code Prettify snipped from Tony Withers // https://www.wavemetrics.com/user/chozo // To align comments in the selected code use: // Left-aligned: cmd-7 (Mac), ctrl-7 (Windows) // Right-aligned: cmd-8 (Mac), ctrl-8 (Windows) // Dial in your procedure window settings here: // You can find the default tab size under Procedure->Document Settings... StrConstant FontName = "Courier New" Constant FontSize = 11 Constant DefaultTab = 20 // in points Menu "Edit" "Align Comments in Clipboard Code (Right)", /Q, PutScrapText AlignComments#AlignComments(GetScrapText()) "Align Comments in Selected Code (Left)/7", /Q, AlignCommentsInSelection(1) "Align Comments in Selected Code (Right)/8", /Q, AlignCommentsInSelection(0) End Function AlignCommentsInSelection(Variable LeftOrRight) String strScrap = GetScrapText() DoIgorMenu "Edit" "Copy" PutScrapText AlignComments#AlignComments(GetScrapText(),AligntoLeft=LeftOrRight) DoIgorMenu "Edit" "Paste" PutScrapText strScrap // leave clipboard state unchanged End // For setting a determined tab position of all selected comments // Execute from the commandline as AlignComments#toTabPos(desiredPos) Function toTabPos(Variable TabPos) // for aligning all comments to a certain tab position DisplayProcedure/W=$StringFromList(0,WinList("*", ";","WIN:128")) // bring to front String strScrap = GetScrapText() DoIgorMenu "Edit" "Copy" PutScrapText AlignComments#AlignComments(GetScrapText(),TabPos=TabPos) DoIgorMenu "Edit" "Paste" PutScrapText strScrap End // The optional variable TabPos lets you choose a fixed offset (in tab widths) for all comments. // For example, TabPos = 30 will position all comments at 30 tabs, if possible Function/S AlignComments(String strText, [Variable TabPos, Variable AlignToLeft]) Variable LorR = 0 if(!ParamIsDefault(AlignToLeft)) LorR = AlignToLeft endif Variable fsPix = FontSize * ScreenResolution/72 // font size in pix Variable TabPix = floor(DefaultTab * ScreenResolution/72) // tab width in pix strText = ReplaceString(" //", strText, "//") // get rid of a space character in front of the comments Wave/T wText = ListToTextWave(strText, "\r") Variable endsWithReturn = (cmpstr(strText[strlen(strText)-1], "\r") == 0) Variable entries = numpnts(wText) wText += SelectString(p<(entries-1) || endsWithReturn, "", "\r") Make/D/FREE/N=(entries) CodeSize = 0 // saves the code size in 'tab widths' Make/T/FREE/N=(entries) CodeOnly, CommentOnly Variable i,j, bytes = 0, strSize = 0 String strLine = "", strCode = "" for (i = 0; i < entries; i += 1) strLine = wText[i] bytes = strsearch(strLine, "//",Inf,1) // is there a comment? if(bytes > 1) strCode = strLine[0,bytes-1] if(GrepString(strCode, "\S")) // line contains non-whitespace CodeOnly[i] = strCode // just the code CommentOnly[i] = strLine[bytes,inf] // just the comment // Below code calculates the line length in units of 'tab length' // Multiplication by TabPix would give the length in pix. Wave/T wTabList = ListToTextWave(strCode, "\t") // split code line by tabs for (j = 0; j < DimSize(wTabList,0); j += 1) strCode = wTabList[j] if (strlen(strCode) > 0) // tab only or code? strSize = FontSizeStringWidth(FontName,fsPix,0,strCode,"") // get the length of all characters if (mod(strSize,TabPix) < 0.05) // does this have roughly the size of a certain no. of tabs? strSize = ceil(strSize/TabPix + 1) // a full tab length is added else strSize = ceil(strSize/TabPix) // this will add a fractional tab length endif CodeSize[i] += strSize else CodeSize[i] += 1 // if it's just a tab then add one tab length endif endfor if (cmpstr(strCode[strlen(strCode)-1], "\t") == 0) // no tab in last entry => not aligned to the next tab position CodeSize[i] -= 1 endif endif endif endfor Variable AlignDistance = 0 // how many tabs define the new alignment if(!ParamIsDefault(TabPos)) AlignDistance = TabPos else Extract/Free CodeSize,SizeVals,CodeSize!=0 AlignDistance = LorR == 1 ? max(WaveMin(SizeVals),AlignDistance) : max(WaveMax(SizeVals),AlignDistance) endif CodeSize = CodeSize[p] > 0 ? AlignDistance - CodeSize[p] : 0 // how many tabs to add or subtract for (i = 0; i < entries; i += 1) String newTabs = "" if(abs(CodeSize[i]) > 0) for (j = 0; j < abs(CodeSize[i]); j += 1) if (CodeSize[i] < 0) CodeOnly[i] = RemoveEnding(CodeOnly[i],"\t") else newTabs += "\t" endif endfor wText[i] = CodeOnly[i] + newTabs + CommentOnly[i] endif endfor wfprintf strText, "%s", wText return strText End