Terminal.appのウィンドウを横方向の間隔でグループ化してグリッドにそろえるスクリプト
このエントリの続き。このままではまだ使いにくいので、もっと賢くしていかないとなあ。
on createOverlappingPair(_first, _second, _xRange) script OverlappingPair property FirstWindowIndex : _first property SecondWindowIndex : _second property xRange : _xRange to theOtherOneOf(theItem) if theItem = SecondWindowIndex then return FirstWindowIndex else return SecondWindowIndex end if end theOtherOneOf end script return OverlappingPair end createOverlappingPair on calculateOverlappingXRange(theBounds, theBoundsOfAnother) if the item 1 of theBounds > the item 3 of theBoundsOfAnother then return (the item 3 of theBoundsOfAnother) - (the item 1 of theBounds) else if the item 3 of theBounds < the item 1 of theBoundsOfAnother then return (the item 3 of theBounds) - (the item 1 of theBoundsOfAnother) else if the item 1 of theBounds < the item 3 of theBoundsOfAnother and the item 3 of theBounds > the item 3 of theBoundsOfAnother then return (the item 3 of theBoundsOfAnother) - (the item 1 of theBounds) else if the item 3 of theBounds > the item 1 of theBoundsOfAnother and the item 3 of theBoundsOfAnother > the item 3 of theBounds then return (the item 3 of theBounds) - (the item 1 of theBoundsOfAnother) end if return 0 end calculateOverlappingXRange on abs(theValue) if theValue < 0 then return -theValue else return theValue end if end abs tell application "Finder" to set theWorkspaceBounds to the bounds of the window of the desktop tell application "Terminal" set theWindows to {} set theBoundsList to {} set theNumberOfWindows to (the count of the window) - 1 if theNumberOfWindows ≤ 1 then return repeat with theWindow in the windows if the index of theWindow > theNumberOfWindows ¬ then exit repeat set theWindows to theWindows & {theWindow} set theBounds to the bounds of theWindow set theBoundsList to theBoundsList & {theBounds} end repeat set theOverlappingPairs to {} set theNearestNeighborXRangeList to {} set theWindowGroups to {} set theWindowGroupIndices to {} set theOverlappingXRange to 0 repeat with theIndex from 1 to (the count of theBoundsList) set theMaximumOverlappingXRange to 0 set theBounds to the item (theIndex) of theBoundsList repeat with theAnotherIndex from 1 to the count of theBoundsList if theIndex is not theAnotherIndex then set theBoundsOfAnother to the item (theAnotherIndex) of theBoundsList set theOverlappingXRange to ¬ me's calculateOverlappingXRange(theBounds, theBoundsOfAnother) if theMaximumOverlappingXRange = 0 or ¬ theOverlappingXRange > theMaximumOverlappingXRange then set theMaximumOverlappingXRange to theOverlappingXRange end if set theOverlappingPairs to theOverlappingPairs & {¬ me's createOverlappingPair(theIndex, theAnotherIndex, theOverlappingXRange)} end if end repeat set theWindowGroups to theWindowGroups & {{}} set theWindowGroupIndices to theWindowGroupIndices & {0} repeat until (the count of theNearestNeighborXRangeList) ≥ theIndex set theNearestNeighborXRangeList to theNearestNeighborXRangeList & {null} end repeat set the item (theIndex) of theNearestNeighborXRangeList to theMaximumOverlappingXRange end repeat set theRealNumberOfWindowGroups to 0 set theAverageWidthOfTheWindow to 0 repeat with theIndex from 1 to the count of theBoundsList set unpaired to true set theBounds to the item (theIndex) of theBoundsList set theNearestNeighborXRange to the item (theIndex) of theNearestNeighborXRangeList set theWidthOfTheWindow to the (item 3 of theBounds) - the (item 1 of theBounds) set theAverageWidthOfTheWindow to theAverageWidthOfTheWindow + theWidthOfTheWindow if theNearestNeighborXRange > theWidthOfTheWindow / 1.5 then repeat with thePair in theOverlappingPairs if thePair's FirstWindowIndex = theIndex then if (me's abs((thePair's xRange) - theNearestNeighborXRange)) / (me's abs(theNearestNeighborXRange / theWidthOfTheWindow)) < theNearestNeighborXRange / 2 then set theIndexOfTheOther to thePair's theOtherOneOf(theIndex) set theWindowGroupIndex to the item (theIndexOfTheOther) of theWindowGroupIndices if theWindowGroupIndex is not theIndex then if theWindowGroupIndex is not 0 then set the item (theWindowGroupIndex) of theWindowGroups to the item (theWindowGroupIndex) of theWindowGroups & {theIndex} set the item (theIndex) of the theWindowGroupIndices to theWindowGroupIndex else set the item (theIndexOfTheOther) of theWindowGroups to the item (theIndexOfTheOther) of theWindowGroups & {theIndexOfTheOther, theIndex} set the item (theIndex) of the theWindowGroupIndices to theIndexOfTheOther set theRealNumberOfWindowGroups to theRealNumberOfWindowGroups + 1 end if end if set unpaired to false end if end if end repeat end if if unpaired then set the item (theIndex) of theWindowGroups to the item (theIndex) of theWindowGroups & {theIndex} set the item (theIndex) of the theWindowGroupIndices to theIndex set theRealNumberOfWindowGroups to theRealNumberOfWindowGroups + 1 end if end repeat set theAverageWidthOfTheWindow to theAverageWidthOfTheWindow / the (count of theBoundsList) set theGridWidth to (the (item 3 of theWorkspaceBounds) - the (item 1 of theWorkspaceBounds) - theAverageWidthOfTheWindow) / theRealNumberOfWindowGroups repeat with theGroup in theWindowGroups if the (count of theGroup) > 0 then set theBounds to the item (the first item of theGroup) of theBoundsList set theWidthOfTheWindow to the (item 3 of theBounds) - (the item 1 of theBounds) set theGridIndex to (((the item 1 of theBounds) - (the item 1 of theWorkspaceBounds)) + theGridWidth / 2 - 1) div theGridWidth repeat with theWindowIndex in theGroup set theWindow to the item (theWindowIndex) of theWindows set thePosition to the position of theWindow set the item 1 of thePosition to theGridWidth * theGridIndex + the (item 1 of theWorkspaceBounds) set the position of theWindow to thePosition end repeat end if end repeat end tell