@@ -12,8 +12,8 @@ function isPasteAction (handlerId: string, payload: unknown): payload is PastePa
1212}
1313
1414export function lockCodeWithoutDecoration (
15- editor : monaco . editor . IStandaloneCodeEditor ,
16- decorations : string [ ] ,
15+ editor : monaco . editor . ICodeEditor ,
16+ decorationFilter : ( decoration : monaco . editor . IModelDecoration ) => boolean ,
1717 allowChangeFromSources : string [ ] = [ ] ,
1818 errorMessage ?: string
1919) : monaco . IDisposable {
@@ -30,8 +30,14 @@ export function lockCodeWithoutDecoration (
3030 function canEditRange ( range : monaco . IRange ) {
3131 const model = editor . getModel ( )
3232 if ( model != null ) {
33- const editableRanges = decorations . map ( decoration => model . getDecorationRange ( decoration ) )
34- return editableRanges . some ( editableRange => editableRange ?. containsRange ( range ) ?? false )
33+ const editableRanges = model
34+ . getAllDecorations ( )
35+ . filter ( decorationFilter )
36+ . map ( ( decoration ) => decoration . range )
37+ if ( editableRanges . length === 0 ) {
38+ return true
39+ }
40+ return editableRanges . some ( ( editableRange ) => editableRange . containsRange ( range ) )
3541 }
3642 return false
3743 }
@@ -52,7 +58,13 @@ export function lockCodeWithoutDecoration (
5258 const originalTrigger = editor . trigger
5359 editor . trigger = function ( source , handlerId , payload ) {
5460 // Try to transform whole file pasting into a paste in the editable area only
55- const lastEditableRange = decorations . length > 0 ? editor . getModel ( ) ?. getDecorationRange ( decorations [ decorations . length - 1 ] ! ) : null
61+ const editableRanges = editor
62+ . getModel ( ) !
63+ . getAllDecorations ( )
64+ . filter ( decorationFilter )
65+ . map ( ( decoration ) => decoration . range )
66+ const lastEditableRange =
67+ editableRanges . length > 0 ? editableRanges [ editableRanges . length - 1 ] : undefined
5668 if ( isPasteAction ( handlerId , payload ) && lastEditableRange != null ) {
5769 const selections = editor . getSelections ( )
5870 const model = editor . getModel ( ) !
@@ -63,10 +75,12 @@ export function lockCodeWithoutDecoration (
6375 if ( wholeFileSelected ) {
6476 const currentEditorValue = editor . getValue ( )
6577 const before = model . getOffsetAt ( lastEditableRange . getStartPosition ( ) )
66- const after = currentEditorValue . length - model . getOffsetAt ( lastEditableRange . getEndPosition ( ) )
78+ const after =
79+ currentEditorValue . length - model . getOffsetAt ( lastEditableRange . getEndPosition ( ) )
6780 if (
6881 currentEditorValue . slice ( 0 , before ) === payload . text . slice ( 0 , before ) &&
69- currentEditorValue . slice ( currentEditorValue . length - after ) === payload . text . slice ( payload . text . length - after )
82+ currentEditorValue . slice ( currentEditorValue . length - after ) ===
83+ payload . text . slice ( payload . text . length - after )
7084 ) {
7185 editor . setSelection ( lastEditableRange )
7286 const newPayload : PastePayload = {
@@ -81,7 +95,7 @@ export function lockCodeWithoutDecoration (
8195
8296 if ( [ 'type' , 'paste' , 'cut' ] . includes ( handlerId ) ) {
8397 const selections = editor . getSelections ( )
84- if ( selections != null && selections . some ( range => ! canEditRange ( range ) ) ) {
98+ if ( selections != null && selections . some ( ( range ) => ! canEditRange ( range ) ) ) {
8599 displayLockedCodeError ( editor . getPosition ( ) ! )
86100 return
87101 }
@@ -107,16 +121,23 @@ export function lockCodeWithoutDecoration (
107121 if ( model == null ) {
108122 return
109123 }
110- const originalApplyEdit : ( operations : monaco . editor . IIdentifiedSingleEditOperation [ ] , computeUndoEdits ?: boolean ) => void = model . applyEdits
111- model . applyEdits = ( ( operations : monaco . editor . IIdentifiedSingleEditOperation [ ] , computeUndoEdits ?: boolean ) => {
124+ const originalApplyEdit : (
125+ operations : monaco . editor . IIdentifiedSingleEditOperation [ ] ,
126+ computeUndoEdits ?: boolean
127+ ) => void = model . applyEdits
128+ model . applyEdits = ( (
129+ operations : monaco . editor . IIdentifiedSingleEditOperation [ ] ,
130+ computeUndoEdits ?: boolean
131+ ) => {
112132 if ( currentEditSource != null && allowChangeFromSources . includes ( currentEditSource ) ) {
113133 return originalApplyEdit . call ( model , operations , computeUndoEdits ! )
114134 }
115- const filteredOperations = operations
116- . filter ( operation => canEditRange ( operation . range ) )
135+ const filteredOperations = operations . filter ( ( operation ) => canEditRange ( operation . range ) )
117136 if ( filteredOperations . length === 0 && operations . length > 0 ) {
118137 const firstRange = operations [ 0 ] ! . range
119- displayLockedCodeError ( new monaco . Position ( firstRange . startLineNumber , firstRange . startColumn ) )
138+ displayLockedCodeError (
139+ new monaco . Position ( firstRange . startLineNumber , firstRange . startColumn )
140+ )
120141 }
121142 return originalApplyEdit . call ( model , filteredOperations , computeUndoEdits ! )
122143 } ) as typeof model . applyEdits
@@ -160,13 +181,22 @@ export function lockCodeWithoutDecoration (
160181 return disposableStore
161182}
162183
163- export function hideCodeWithoutDecoration ( editor : monaco . editor . IStandaloneCodeEditor , decorations : string [ ] ) : monaco . IDisposable {
184+ export function hideCodeWithoutDecoration ( editor : monaco . editor . ICodeEditor , decorationFilter : ( decoration : monaco . editor . IModelDecoration ) => boolean ) : monaco . IDisposable {
164185 let otherHiddenAreas : monaco . IRange [ ] = editor . _getViewModel ( ) ?. getHiddenAreas ( ) ?? [ ]
165186 function getHiddenAreas ( ) {
166- const model = editor . getModel ( ) !
187+ const model = editor . getModel ( )
188+ if ( model == null ) {
189+ return [ ]
190+ }
191+
192+ const decorations = model . getAllDecorations ( )
193+ . filter ( decorationFilter )
194+ if ( decorations . length === 0 ) {
195+ return otherHiddenAreas
196+ }
167197
168198 const ranges = decorations
169- . map ( decoration => model . getDecorationRange ( decoration ) ! )
199+ . map ( decoration => decoration . range )
170200 . sort ( ( a , b ) => a . startLineNumber - b . startLineNumber )
171201 // merge ranges
172202 . reduce < monaco . Range [ ] > ( ( acc , range ) => {
@@ -218,6 +248,14 @@ export function hideCodeWithoutDecoration (editor: monaco.editor.IStandaloneCode
218248 }
219249
220250 const disposableStore = new DisposableStore ( )
251+
252+ disposableStore . add ( editor . onDidChangeModel ( ( ) => {
253+ otherHiddenAreas = editor . _getViewModel ( ) ?. getHiddenAreas ( ) ?? [ ]
254+ updateHiddenAreas ( )
255+ } ) )
256+ disposableStore . add ( editor . onDidChangeModelDecorations ( ( ) => {
257+ updateHiddenAreas ( )
258+ } ) )
221259 updateHiddenAreas ( )
222260
223261 disposableStore . add ( {
0 commit comments