#pragma TextEncoding = "UTF-8" #pragma rtGlobals=3 // Use modern global access method and strict wave access. #pragma version=0.5 // Inspired by the Code Prettify snipped from Tony Withers // https://www.wavemetrics.com/user/chozo // To align comments in the selected code use: cmd-6 (Mac), ctrl-6 (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", /Q, PutScrapText AlignComments(GetScrapText()) "Align Comments in Selected Code/6", /Q, AlignCommentsInSelection() End Function AlignCommentsInSelection() String strScrap = GetScrapText() DoIgorMenu "Edit" "Copy" PutScrapText AlignComments(GetScrapText()) DoIgorMenu "Edit" "Paste" PutScrapText strScrap // leave clipboard state unchanged End // The optional variable minTabs lets you choose a minimal offset (in tab widths) for all comments. // For example, minTabs = 30 will position all comments at 30 tabs Function/S AlignComments(String strText, [Variable minTabs]) Variable AlignTo = 0 if(!ParamIsDefault(minTabs)) AlignTo = minTabs endif Variable fsPix = FontSize * ScreenResolution/72 // font size in pix Variable TabPix = floor(DefaultTab * ScreenResolution/72) // tab width in pix 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 // the following 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 AlignTo = max(WaveMax(CodeSize),AlignTo) // how many tabs define the new alignment CodeSize = CodeSize[p] > 0 ? AlignTo - CodeSize[p] : 0 // how many tabs to add for (i = 0; i < entries; i += 1) String newTabs = "" if(CodeSize[i] > 0) for (j = 0; j < CodeSize[i]; j += 1) newTabs += "\t" endfor wText[i] = CodeOnly[i] + newTabs + CommentOnly[i] endif endfor wfprintf strText, "%s", wText return strText End