@@ -672,6 +672,7 @@ export interface IEnvironmentalOptions {
672672 readonly fontInfo : FontInfo ;
673673 readonly extraEditorClassName : string ;
674674 readonly isDominatedByLongLines : boolean ;
675+ readonly maxLineNumber : number ;
675676 readonly lineNumbersDigitCount : number ;
676677 readonly emptySelectionClipboard : boolean ;
677678 readonly pixelRatio : number ;
@@ -1685,6 +1686,14 @@ export interface EditorLayoutInfo {
16851686 * The width of the minimap
16861687 */
16871688 readonly minimapWidth : number ;
1689+ readonly minimapHeightIsEditorHeight : boolean ;
1690+ readonly minimapIsSampling : boolean ;
1691+ readonly minimapScale : number ;
1692+ readonly minimapLineHeight : number ;
1693+ readonly minimapCanvasInnerWidth : number ;
1694+ readonly minimapCanvasInnerHeight : number ;
1695+ readonly minimapCanvasOuterWidth : number ;
1696+ readonly minimapCanvasOuterHeight : number ;
16881697
16891698 /**
16901699 * Minimap render type
@@ -1718,6 +1727,7 @@ export interface EditorLayoutInfoComputerEnv {
17181727 outerWidth : number ;
17191728 outerHeight : number ;
17201729 lineHeight : number ;
1730+ maxLineNumber : number ;
17211731 lineNumbersDigitCount : number ;
17221732 typicalHalfwidthCharacterWidth : number ;
17231733 maxDigitWidth : number ;
@@ -1741,13 +1751,28 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption<EditorOption.
17411751 outerWidth : env . outerWidth ,
17421752 outerHeight : env . outerHeight ,
17431753 lineHeight : env . fontInfo . lineHeight ,
1754+ maxLineNumber : env . maxLineNumber ,
17441755 lineNumbersDigitCount : env . lineNumbersDigitCount ,
17451756 typicalHalfwidthCharacterWidth : env . fontInfo . typicalHalfwidthCharacterWidth ,
17461757 maxDigitWidth : env . fontInfo . maxDigitWidth ,
17471758 pixelRatio : env . pixelRatio
17481759 } ) ;
17491760 }
17501761
1762+ public static computeContainedMinimapLineCount ( input : {
1763+ modelLineCount : number ;
1764+ scrollBeyondLastLine : boolean ;
1765+ height : number ;
1766+ lineHeight : number ;
1767+ pixelRatio : number ;
1768+ } ) : { typicalViewportLineCount : number ; extraLinesBeyondLastLine : number ; desiredRatio : number ; minimapLineCount : number ; } {
1769+ const typicalViewportLineCount = input . height / input . lineHeight ;
1770+ const extraLinesBeyondLastLine = input . scrollBeyondLastLine ? ( typicalViewportLineCount - 1 ) : 0 ;
1771+ const desiredRatio = ( input . modelLineCount + extraLinesBeyondLastLine ) / ( input . pixelRatio * input . height ) ;
1772+ const minimapLineCount = Math . floor ( input . modelLineCount / desiredRatio ) ;
1773+ return { typicalViewportLineCount, extraLinesBeyondLastLine, desiredRatio, minimapLineCount } ;
1774+ }
1775+
17511776 public static computeLayout ( options : IComputedEditorOptions , env : EditorLayoutInfoComputerEnv ) : EditorLayoutInfo {
17521777 const outerWidth = env . outerWidth | 0 ;
17531778 const outerHeight = env . outerHeight | 0 ;
@@ -1760,12 +1785,14 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption<EditorOption.
17601785 const showGlyphMargin = options . get ( EditorOption . glyphMargin ) ;
17611786 const showLineNumbers = ( options . get ( EditorOption . lineNumbers ) . renderType !== RenderLineNumbersType . Off ) ;
17621787 const lineNumbersMinChars = options . get ( EditorOption . lineNumbersMinChars ) | 0 ;
1788+ const scrollBeyondLastLine = options . get ( EditorOption . scrollBeyondLastLine ) ;
17631789 const minimap = options . get ( EditorOption . minimap ) ;
17641790 const minimapEnabled = minimap . enabled ;
17651791 const minimapSide = minimap . side ;
17661792 const minimapRenderCharacters = minimap . renderCharacters ;
1767- const minimapScale = ( pixelRatio >= 2 ? Math . round ( minimap . scale * 2 ) : minimap . scale ) ;
1793+ let minimapScale = ( pixelRatio >= 2 ? Math . round ( minimap . scale * 2 ) : minimap . scale ) ;
17681794 const minimapMaxColumn = minimap . maxColumn | 0 ;
1795+ const minimapMode = minimap . mode ;
17691796
17701797 const scrollbar = options . get ( EditorOption . scrollbar ) ;
17711798 const verticalScrollbarWidth = scrollbar . verticalScrollbarSize | 0 ;
@@ -1805,19 +1832,65 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption<EditorOption.
18051832
18061833 const remainingWidth = outerWidth - glyphMarginWidth - lineNumbersWidth - lineDecorationsWidth ;
18071834
1835+ const baseCharHeight = minimapRenderCharacters ? 2 : 3 ;
18081836 let renderMinimap : RenderMinimap ;
18091837 let minimapLeft : number ;
18101838 let minimapWidth : number ;
1839+ let minimapCanvasInnerWidth : number ;
1840+ let minimapCanvasInnerHeight = Math . floor ( pixelRatio * outerHeight ) ;
1841+ let minimapCanvasOuterWidth : number ;
1842+ const minimapCanvasOuterHeight = minimapCanvasInnerHeight / pixelRatio ;
1843+ let minimapHeightIsEditorHeight = false ;
1844+ let minimapIsSampling = false ;
1845+ let minimapLineHeight = baseCharHeight * minimapScale ;
18111846 let contentWidth : number ;
18121847 if ( ! minimapEnabled ) {
18131848 minimapLeft = 0 ;
18141849 minimapWidth = 0 ;
1850+ minimapCanvasInnerWidth = 0 ;
1851+ minimapCanvasOuterWidth = 0 ;
1852+ minimapLineHeight = 1 ;
18151853 renderMinimap = RenderMinimap . None ;
18161854 contentWidth = remainingWidth ;
18171855 } else {
1818- // The minimapScale is also the pixel width of each character. Adjust
1819- // for the pixel ratio of the screen.
1820- const minimapCharWidth = minimapScale / pixelRatio ;
1856+ let minimapCharWidth = minimapScale / pixelRatio ;
1857+ let minimapWidthMultiplier : number = 1 ;
1858+
1859+ if ( minimapMode === 'cover' || minimapMode === 'contain' ) {
1860+ const modelLineCount = env . maxLineNumber ;
1861+ const { typicalViewportLineCount, extraLinesBeyondLastLine, desiredRatio, minimapLineCount } = EditorLayoutInfoComputer . computeContainedMinimapLineCount ( {
1862+ modelLineCount : modelLineCount ,
1863+ scrollBeyondLastLine : scrollBeyondLastLine ,
1864+ height : outerHeight ,
1865+ lineHeight : lineHeight ,
1866+ pixelRatio : pixelRatio
1867+ } ) ;
1868+ // ratio is intentionally not part of the layout to avoid the layout changing all the time
1869+ // when doing sampling
1870+ const ratio = modelLineCount / minimapLineCount ;
1871+
1872+ if ( ratio > 1 ) {
1873+ minimapHeightIsEditorHeight = true ;
1874+ minimapIsSampling = true ;
1875+ minimapScale = 1 ;
1876+ minimapLineHeight = 1 ;
1877+ minimapCharWidth = minimapScale / pixelRatio ;
1878+ } else {
1879+ const effectiveMinimapHeight = Math . ceil ( ( modelLineCount + extraLinesBeyondLastLine ) * minimapLineHeight ) ;
1880+ if ( minimapMode === 'cover' || effectiveMinimapHeight > minimapCanvasInnerHeight ) {
1881+ minimapHeightIsEditorHeight = true ;
1882+ const configuredFontScale = minimapScale ;
1883+ minimapLineHeight = Math . min ( lineHeight * pixelRatio , Math . max ( 1 , Math . floor ( 1 / desiredRatio ) ) ) ;
1884+ minimapScale = Math . min ( configuredFontScale + 1 , Math . max ( 1 , Math . floor ( minimapLineHeight / baseCharHeight ) ) ) ;
1885+ if ( minimapScale > configuredFontScale ) {
1886+ minimapWidthMultiplier = Math . min ( 2 , minimapScale / configuredFontScale ) ;
1887+ }
1888+ minimapCharWidth = minimapScale / pixelRatio / minimapWidthMultiplier ;
1889+ minimapCanvasInnerHeight = Math . ceil ( ( Math . max ( typicalViewportLineCount , modelLineCount + extraLinesBeyondLastLine ) ) * minimapLineHeight ) ;
1890+ }
1891+ }
1892+ }
1893+
18211894 renderMinimap = minimapRenderCharacters ? RenderMinimap . Text : RenderMinimap . Blocks ;
18221895
18231896 // Given:
@@ -1849,6 +1922,10 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption<EditorOption.
18491922 } else {
18501923 minimapLeft = outerWidth - minimapWidth - verticalScrollbarWidth ;
18511924 }
1925+
1926+ minimapCanvasInnerWidth = Math . floor ( pixelRatio * minimapWidth ) ;
1927+ minimapCanvasOuterWidth = minimapCanvasInnerWidth / pixelRatio ;
1928+ minimapCanvasInnerWidth = Math . floor ( minimapCanvasInnerWidth * minimapWidthMultiplier ) ;
18521929 }
18531930
18541931 // (leaving 2px for the cursor to have space after the last character)
@@ -1875,6 +1952,14 @@ export class EditorLayoutInfoComputer extends ComputedEditorOption<EditorOption.
18751952 renderMinimap : renderMinimap ,
18761953 minimapLeft : minimapLeft ,
18771954 minimapWidth : minimapWidth ,
1955+ minimapHeightIsEditorHeight : minimapHeightIsEditorHeight ,
1956+ minimapIsSampling : minimapIsSampling ,
1957+ minimapScale : minimapScale ,
1958+ minimapLineHeight : minimapLineHeight ,
1959+ minimapCanvasInnerWidth : minimapCanvasInnerWidth ,
1960+ minimapCanvasInnerHeight : minimapCanvasInnerHeight ,
1961+ minimapCanvasOuterWidth : minimapCanvasOuterWidth ,
1962+ minimapCanvasOuterHeight : minimapCanvasOuterHeight ,
18781963
18791964 viewportColumn : viewportColumn ,
18801965
@@ -1975,6 +2060,11 @@ export interface IEditorMinimapOptions {
19752060 * Defaults to 'right'.
19762061 */
19772062 side ?: 'right' | 'left' ;
2063+ /**
2064+ * Control the minimap rendering mode.
2065+ * Defaults to 'actual'.
2066+ */
2067+ mode ?: 'actual' | 'cover' | 'contain' ;
19782068 /**
19792069 * Control the rendering of the minimap slider.
19802070 * Defaults to 'mouseover'.
@@ -1990,7 +2080,6 @@ export interface IEditorMinimapOptions {
19902080 * Defaults to 120.
19912081 */
19922082 maxColumn ?: number ;
1993-
19942083 /**
19952084 * Relative size of the font in the minimap. Defaults to 1.
19962085 */
@@ -2004,6 +2093,7 @@ class EditorMinimap extends BaseEditorOption<EditorOption.minimap, EditorMinimap
20042093 constructor ( ) {
20052094 const defaults : EditorMinimapOptions = {
20062095 enabled : true ,
2096+ mode : 'actual' ,
20072097 side : 'right' ,
20082098 showSlider : 'mouseover' ,
20092099 renderCharacters : true ,
@@ -2018,6 +2108,17 @@ class EditorMinimap extends BaseEditorOption<EditorOption.minimap, EditorMinimap
20182108 default : defaults . enabled ,
20192109 description : nls . localize ( 'minimap.enabled' , "Controls whether the minimap is shown." )
20202110 } ,
2111+ 'editor.minimap.mode' : {
2112+ type : 'string' ,
2113+ enum : [ 'actual' , 'cover' , 'contain' ] ,
2114+ enumDescriptions : [
2115+ nls . localize ( 'minimap.mode.actual' , "The minimap will be displayed in its original size, so it might be higher than the editor." ) ,
2116+ nls . localize ( 'minimap.mode.cover' , "The minimap will always have the height of the editor and will stretch or shrink as necessary." ) ,
2117+ nls . localize ( 'minimap.mode.contain' , "The minimap will shrink as necessary to never be higher than the editor." ) ,
2118+ ] ,
2119+ default : defaults . mode ,
2120+ description : nls . localize ( 'minimap.mode' , "Controls the rendering mode of the minimap." )
2121+ } ,
20212122 'editor.minimap.side' : {
20222123 type : 'string' ,
20232124 enum : [ 'left' , 'right' ] ,
@@ -2046,7 +2147,7 @@ class EditorMinimap extends BaseEditorOption<EditorOption.minimap, EditorMinimap
20462147 type : 'number' ,
20472148 default : defaults . maxColumn ,
20482149 description : nls . localize ( 'minimap.maxColumn' , "Limit the width of the minimap to render at most a certain number of columns." )
2049- } ,
2150+ }
20502151 }
20512152 ) ;
20522153 }
@@ -2058,6 +2159,7 @@ class EditorMinimap extends BaseEditorOption<EditorOption.minimap, EditorMinimap
20582159 const input = _input as IEditorMinimapOptions ;
20592160 return {
20602161 enabled : EditorBooleanOption . boolean ( input . enabled , this . defaultValue . enabled ) ,
2162+ mode : EditorStringEnumOption . stringSet < 'actual' | 'cover' | 'contain' > ( input . mode , this . defaultValue . mode , [ 'actual' , 'cover' , 'contain' ] ) ,
20612163 side : EditorStringEnumOption . stringSet < 'right' | 'left' > ( input . side , this . defaultValue . side , [ 'right' , 'left' ] ) ,
20622164 showSlider : EditorStringEnumOption . stringSet < 'always' | 'mouseover' > ( input . showSlider , this . defaultValue . showSlider , [ 'always' , 'mouseover' ] ) ,
20632165 renderCharacters : EditorBooleanOption . boolean ( input . renderCharacters , this . defaultValue . renderCharacters ) ,
0 commit comments