Открыть боковую панель
code
vscode
Коммиты
3d182cf0
Коммит
3d182cf0
создал
Ноя 12, 2025
по автору
Henning Dieterichs
Просмотр файлов
first version of NES long distance hints
владелец
9a4e259c
Изменения
23
Развернуть все
Скрыть пробелы
Построчно
Рядом
src/vs/base/browser/dom.ts
Просмотр файла @
3d182cf0
...
...
@@ -2507,7 +2507,43 @@ export abstract class ObserverNode<T extends HTMLOrSVGElement = HTMLOrSVGElement
this
.
keepUpdated
(
store
);
return
new
LiveElement
(
this
.
_element
,
store
);
}
private
_isHovered
:
IObservable
<
boolean
>
|
undefined
=
undefined
;
get
isHovered
():
IObservable
<
boolean
>
{
if
(
!
this
.
_isHovered
)
{
const
hovered
=
observableValue
<
boolean
>
(
'
hovered
'
,
false
);
this
.
_element
.
addEventListener
(
'
mouseenter
'
,
(
_e
)
=>
hovered
.
set
(
true
,
undefined
));
this
.
_element
.
addEventListener
(
'
mouseleave
'
,
(
_e
)
=>
hovered
.
set
(
false
,
undefined
));
this
.
_isHovered
=
hovered
;
}
return
this
.
_isHovered
;
}
private
_didMouseMoveDuringHover
:
IObservable
<
boolean
>
|
undefined
=
undefined
;
get
didMouseMoveDuringHover
():
IObservable
<
boolean
>
{
if
(
!
this
.
_didMouseMoveDuringHover
)
{
let
_hovering
=
false
;
const
hovered
=
observableValue
<
boolean
>
(
'
didMouseMoveDuringHover
'
,
false
);
this
.
_element
.
addEventListener
(
'
mouseenter
'
,
(
_e
)
=>
{
_hovering
=
true
;
});
this
.
_element
.
addEventListener
(
'
mousemove
'
,
(
_e
)
=>
{
if
(
_hovering
)
{
hovered
.
set
(
true
,
undefined
);
}
});
this
.
_element
.
addEventListener
(
'
mouseleave
'
,
(
_e
)
=>
{
_hovering
=
false
;
hovered
.
set
(
false
,
undefined
);
});
this
.
_didMouseMoveDuringHover
=
hovered
;
}
return
this
.
_didMouseMoveDuringHover
;
}
}
function
setClassName
(
domNode
:
HTMLOrSVGElement
,
className
:
string
)
{
if
(
isSVGElement
(
domNode
))
{
domNode
.
setAttribute
(
'
class
'
,
className
);
...
...
@@ -2515,6 +2551,7 @@ function setClassName(domNode: HTMLOrSVGElement, className: string) {
domNode
.
className
=
className
;
}
}
function
resolve
<
T
>
(
value
:
ValueOrList
<
T
>
,
reader
:
IReader
|
undefined
,
cb
:
(
val
:
T
)
=>
void
):
void
{
if
(
isObservable
(
value
))
{
cb
(
value
.
read
(
reader
));
...
...
@@ -2582,41 +2619,6 @@ export class ObserverNodeWithElement<T extends HTMLOrSVGElement = HTMLOrSVGEleme
public
get
element
()
{
return
this
.
_element
;
}
private
_isHovered
:
IObservable
<
boolean
>
|
undefined
=
undefined
;
get
isHovered
():
IObservable
<
boolean
>
{
if
(
!
this
.
_isHovered
)
{
const
hovered
=
observableValue
<
boolean
>
(
'
hovered
'
,
false
);
this
.
_element
.
addEventListener
(
'
mouseenter
'
,
(
_e
)
=>
hovered
.
set
(
true
,
undefined
));
this
.
_element
.
addEventListener
(
'
mouseleave
'
,
(
_e
)
=>
hovered
.
set
(
false
,
undefined
));
this
.
_isHovered
=
hovered
;
}
return
this
.
_isHovered
;
}
private
_didMouseMoveDuringHover
:
IObservable
<
boolean
>
|
undefined
=
undefined
;
get
didMouseMoveDuringHover
():
IObservable
<
boolean
>
{
if
(
!
this
.
_didMouseMoveDuringHover
)
{
let
_hovering
=
false
;
const
hovered
=
observableValue
<
boolean
>
(
'
didMouseMoveDuringHover
'
,
false
);
this
.
_element
.
addEventListener
(
'
mouseenter
'
,
(
_e
)
=>
{
_hovering
=
true
;
});
this
.
_element
.
addEventListener
(
'
mousemove
'
,
(
_e
)
=>
{
if
(
_hovering
)
{
hovered
.
set
(
true
,
undefined
);
}
});
this
.
_element
.
addEventListener
(
'
mouseleave
'
,
(
_e
)
=>
{
_hovering
=
false
;
hovered
.
set
(
false
,
undefined
);
});
this
.
_didMouseMoveDuringHover
=
hovered
;
}
return
this
.
_didMouseMoveDuringHover
;
}
}
function
setOrRemoveAttribute
(
element
:
HTMLOrSVGElement
,
key
:
string
,
value
:
unknown
)
{
if
(
value
===
null
||
value
===
undefined
)
{
...
...
src/vs/editor/browser/editorBrowser.ts
Просмотр файла @
3d182cf0
...
...
@@ -825,6 +825,8 @@ export interface ICodeEditor extends editorCommon.IEditor {
*/
readonly
onEndUpdate
:
Event
<
void
>
;
readonly
onDidChangeViewZones
:
Event
<
void
>
;
/**
* Saves current view state of the editor in a serializable object.
*/
...
...
src/vs/editor/browser/observableCodeEditor.ts
Просмотр файла @
3d182cf0
...
...
@@ -5,7 +5,7 @@
import
{
equalsIfDefined
,
itemsEquals
}
from
'
../../base/common/equals.js
'
;
import
{
Disposable
,
DisposableStore
,
IDisposable
,
toDisposable
}
from
'
../../base/common/lifecycle.js
'
;
import
{
DebugLocation
,
IObservable
,
IObservableWithChange
,
ITransaction
,
TransactionImpl
,
autorun
,
autorunOpts
,
derived
,
derivedOpts
,
derivedWithSetter
,
observableFromEvent
,
observableSignal
,
observableValue
,
observableValueOpts
}
from
'
../../base/common/observable.js
'
;
import
{
DebugLocation
,
IObservable
,
IObservableWithChange
,
ITransaction
,
TransactionImpl
,
autorun
,
autorunOpts
,
derived
,
derivedOpts
,
derivedWithSetter
,
observableFromEvent
,
observableSignal
,
observableSignalFromEvent
,
observableValue
,
observableValueOpts
}
from
'
../../base/common/observable.js
'
;
import
{
EditorOption
,
FindComputedEditorOptionValueById
}
from
'
../common/config/editorOptions.js
'
;
import
{
LineRange
}
from
'
../common/core/ranges/lineRange.js
'
;
import
{
OffsetRange
}
from
'
../common/core/ranges/offsetRange.js
'
;
...
...
@@ -148,6 +148,9 @@ export class ObservableCodeEditor extends Disposable {
this
.
layoutInfoVerticalScrollbarWidth
=
this
.
layoutInfo
.
map
(
l
=>
l
.
verticalScrollbarWidth
);
this
.
contentWidth
=
observableFromEvent
(
this
.
editor
.
onDidContentSizeChange
,
()
=>
this
.
editor
.
getContentWidth
());
this
.
contentHeight
=
observableFromEvent
(
this
.
editor
.
onDidContentSizeChange
,
()
=>
this
.
editor
.
getContentHeight
());
this
.
_onDidChangeViewZones
=
observableSignalFromEvent
(
this
,
this
.
editor
.
onDidChangeViewZones
);
this
.
_onDidHiddenAreasChanged
=
observableSignalFromEvent
(
this
,
this
.
editor
.
onDidChangeHiddenAreas
);
this
.
_onDidLineHeightChanged
=
observableSignalFromEvent
(
this
,
this
.
editor
.
onDidChangeLineHeight
);
this
.
_widgetCounter
=
0
;
this
.
openedPeekWidgets
=
observableValue
(
this
,
0
);
...
...
@@ -456,6 +459,37 @@ export class ObservableCodeEditor extends Disposable {
});
}
private
readonly
_onDidChangeViewZones
;
private
readonly
_onDidHiddenAreasChanged
;
private
readonly
_onDidLineHeightChanged
;
/**
* Get the vertical position (top offset) for the line's bottom w.r.t. to the first line.
*/
observeTopForLineNumber
(
lineNumber
:
number
):
IObservable
<
number
>
{
return
derived
(
reader
=>
{
this
.
layoutInfo
.
read
(
reader
);
this
.
_onDidChangeViewZones
.
read
(
reader
);
this
.
_onDidHiddenAreasChanged
.
read
(
reader
);
this
.
_onDidLineHeightChanged
.
read
(
reader
);
this
.
_versionId
.
read
(
reader
);
return
this
.
editor
.
getTopForLineNumber
(
lineNumber
);
});
}
/**
* Get the vertical position (top offset) for the line's bottom w.r.t. to the first line.
*/
observeBottomForLineNumber
(
lineNumber
:
number
):
IObservable
<
number
>
{
return
derived
(
reader
=>
{
this
.
layoutInfo
.
read
(
reader
);
this
.
_onDidChangeViewZones
.
read
(
reader
);
this
.
_onDidHiddenAreasChanged
.
read
(
reader
);
this
.
_onDidLineHeightChanged
.
read
(
reader
);
this
.
_versionId
.
read
(
reader
);
return
this
.
editor
.
getBottomForLineNumber
(
lineNumber
);
});
}
}
interface
IObservableOverlayWidget
{
...
...
src/vs/editor/browser/widget/diffEditor/features/hideUnchangedRegionsFeature.ts
Просмотр файла @
3d182cf0
...
...
@@ -31,13 +31,14 @@ import { IObservableViewZone, PlaceholderViewZone, ViewZoneOverlayWidget, applyO
* Make sure to add the view zones to the editor!
*/
export
class
HideUnchangedRegionsFeature
extends
Disposable
{
p
rivate
static
readonly
_breadcrumbsSourceFactory
=
observableValue
<
((
textModel
:
ITextModel
,
instantiationService
:
IInstantiationService
)
=>
IDiffEditorBreadcrumbsSource
)
>
(
p
ublic
static
readonly
_breadcrumbsSourceFactory
=
observableValue
<
((
textModel
:
ITextModel
,
instantiationService
:
IInstantiationService
)
=>
IDiffEditorBreadcrumbsSource
)
>
(
this
,
()
=>
({
dispose
()
{
},
getBreadcrumbItems
(
startRange
,
reader
)
{
return
[];
},
getAt
:
()
=>
[],
}));
public
static
setBreadcrumbsSourceFactory
(
factory
:
(
textModel
:
ITextModel
,
instantiationService
:
IInstantiationService
)
=>
IDiffEditorBreadcrumbsSource
)
{
this
.
_breadcrumbsSourceFactory
.
set
(
factory
,
undefined
);
...
...
@@ -491,4 +492,6 @@ class CollapsedCodeOverlayWidget extends ViewZoneOverlayWidget {
export
interface
IDiffEditorBreadcrumbsSource
extends
IDisposable
{
getBreadcrumbItems
(
startRange
:
LineRange
,
reader
:
IReader
):
{
name
:
string
;
kind
:
SymbolKind
;
startLineNumber
:
number
}[];
getAt
(
lineNumber
:
number
,
reader
:
IReader
):
{
name
:
string
;
kind
:
SymbolKind
;
startLineNumber
:
number
}[];
}
src/vs/editor/common/config/editorOptions.ts
Просмотр файла @
3d182cf0
...
...
@@ -4442,6 +4442,8 @@ export interface IInlineSuggestOptions {
showCollapsed
?:
boolean
;
showLongDistanceHint
?:
boolean
;
/**
* @internal
*/
...
...
@@ -4500,6 +4502,7 @@ class InlineEditorSuggest extends BaseEditorOption<EditorOption.inlineSuggest, I
showCollapsed
:
false
,
renderSideBySide
:
'
auto
'
,
allowCodeShifting
:
'
always
'
,
showLongDistanceHint
:
false
,
},
triggerCommandOnProviderChange
:
false
,
experimental
:
{
...
...
@@ -4599,6 +4602,12 @@ class InlineEditorSuggest extends BaseEditorOption<EditorOption.inlineSuggest, I
enum
:
[
'
always
'
,
'
horizontal
'
,
'
never
'
],
tags
:
[
'
nextEditSuggestions
'
]
},
'
editor.inlineSuggest.edits.showLongDistanceHint
'
:
{
type
:
'
boolean
'
,
default
:
defaults
.
edits
.
showLongDistanceHint
,
description
:
nls
.
localize
(
'
inlineSuggest.edits.showLongDistanceHint
'
,
"
Controls whether long distance inline suggestions are shown.
"
),
tags
:
[
'
nextEditSuggestions
'
,
'
experimental
'
]
},
'
editor.inlineSuggest.edits.renderSideBySide
'
:
{
type
:
'
string
'
,
default
:
defaults
.
edits
.
renderSideBySide
,
...
...
@@ -4650,6 +4659,7 @@ class InlineEditorSuggest extends BaseEditorOption<EditorOption.inlineSuggest, I
enabled
:
boolean
(
input
.
enabled
,
this
.
defaultValue
.
edits
.
enabled
),
showCollapsed
:
boolean
(
input
.
showCollapsed
,
this
.
defaultValue
.
edits
.
showCollapsed
),
allowCodeShifting
:
stringSet
(
input
.
allowCodeShifting
,
this
.
defaultValue
.
edits
.
allowCodeShifting
,
[
'
always
'
,
'
horizontal
'
,
'
never
'
]),
showLongDistanceHint
:
boolean
(
input
.
showLongDistanceHint
,
this
.
defaultValue
.
edits
.
showLongDistanceHint
),
renderSideBySide
:
stringSet
(
input
.
renderSideBySide
,
this
.
defaultValue
.
edits
.
renderSideBySide
,
[
'
never
'
,
'
auto
'
]),
};
}
...
...
src/vs/editor/common/core/2d/rect.ts
Просмотр файла @
3d182cf0
...
...
@@ -6,6 +6,7 @@
import
{
BugIndicatingError
}
from
'
../../../../base/common/errors.js
'
;
import
{
OffsetRange
}
from
'
../ranges/offsetRange.js
'
;
import
{
Point
}
from
'
./point.js
'
;
import
{
Size2D
}
from
'
./size.js
'
;
export
class
Rect
{
public
static
fromPoint
(
point
:
Point
):
Rect
{
...
...
@@ -204,6 +205,10 @@ export class Rect {
return
new
Rect
(
this
.
left
,
this
.
top
+
delta
,
this
.
right
,
this
.
bottom
+
delta
);
}
translate
(
point
:
Point
):
Rect
{
return
new
Rect
(
this
.
left
+
point
.
x
,
this
.
top
+
point
.
y
,
this
.
right
+
point
.
x
,
this
.
bottom
+
point
.
y
);
}
deltaRight
(
delta
:
number
):
Rect
{
return
new
Rect
(
this
.
left
,
this
.
top
,
this
.
right
+
delta
,
this
.
bottom
);
}
...
...
@@ -245,4 +250,24 @@ export class Rect {
height
:
`
${
this
.
height
}
px`
,
};
}
getHorizontalRange
():
OffsetRange
{
return
new
OffsetRange
(
this
.
left
,
this
.
right
);
}
getVerticalRange
():
OffsetRange
{
return
new
OffsetRange
(
this
.
top
,
this
.
bottom
);
}
withHorizontalRange
(
range
:
OffsetRange
):
Rect
{
return
new
Rect
(
range
.
start
,
this
.
top
,
range
.
endExclusive
,
this
.
bottom
);
}
withVerticalRange
(
range
:
OffsetRange
):
Rect
{
return
new
Rect
(
this
.
left
,
range
.
start
,
this
.
right
,
range
.
endExclusive
);
}
getSize
():
Size2D
{
return
new
Size2D
(
this
.
width
,
this
.
height
);
}
}
src/vs/editor/common/core/2d/size.ts
0 → 100644
Просмотр файла @
3d182cf0
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
IDimension
}
from
'
./dimension.js
'
;
export
class
Size2D
{
static
equals
(
a
:
Size2D
,
b
:
Size2D
):
boolean
{
return
a
.
width
===
b
.
width
&&
a
.
height
===
b
.
height
;
}
constructor
(
public
readonly
width
:
number
,
public
readonly
height
:
number
,
)
{
}
public
add
(
other
:
Size2D
):
Size2D
{
return
new
Size2D
(
this
.
width
+
other
.
width
,
this
.
height
+
other
.
height
);
}
public
deltaX
(
delta
:
number
):
Size2D
{
return
new
Size2D
(
this
.
width
+
delta
,
this
.
height
);
}
public
deltaY
(
delta
:
number
):
Size2D
{
return
new
Size2D
(
this
.
width
,
this
.
height
+
delta
);
}
public
toString
()
{
return
`(
${
this
.
width
}
,
${
this
.
height
}
)`
;
}
public
subtract
(
other
:
Size2D
):
Size2D
{
return
new
Size2D
(
this
.
width
-
other
.
width
,
this
.
height
-
other
.
height
);
}
public
scale
(
factor
:
number
):
Size2D
{
return
new
Size2D
(
this
.
width
*
factor
,
this
.
height
*
factor
);
}
public
scaleWidth
(
factor
:
number
):
Size2D
{
return
new
Size2D
(
this
.
width
*
factor
,
this
.
height
);
}
public
mapComponents
(
map
:
(
value
:
number
)
=>
number
):
Size2D
{
return
new
Size2D
(
map
(
this
.
width
),
map
(
this
.
height
));
}
public
isZero
():
boolean
{
return
this
.
width
===
0
&&
this
.
height
===
0
;
}
public
transpose
():
Size2D
{
return
new
Size2D
(
this
.
height
,
this
.
width
);
}
public
toDimension
():
IDimension
{
return
{
width
:
this
.
width
,
height
:
this
.
height
};
}
}
src/vs/editor/common/core/ranges/offsetRange.ts
Просмотр файла @
3d182cf0
...
...
@@ -208,6 +208,10 @@ export class OffsetRange implements IOffsetRange {
}
return
new
OffsetRange
(
this
.
start
,
range
.
endExclusive
);
}
public
withMargin
(
margin
:
number
):
OffsetRange
{
return
new
OffsetRange
(
this
.
start
-
margin
,
this
.
endExclusive
+
margin
);
}
}
export
class
OffsetRangeSet
{
...
...
src/vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution.ts
Просмотр файла @
3d182cf0
...
...
@@ -55,6 +55,17 @@ class DiffEditorBreadcrumbsSource extends Disposable implements IDiffEditorBread
symbols
.
sort
(
reverseOrder
(
compareBy
(
s
=>
s
.
range
.
endLineNumber
-
s
.
range
.
startLineNumber
,
numberComparator
)));
return
symbols
.
map
(
s
=>
({
name
:
s
.
name
,
kind
:
s
.
kind
,
startLineNumber
:
s
.
range
.
startLineNumber
}));
}
public
getAt
(
lineNumber
:
number
,
reader
:
IReader
):
{
name
:
string
;
kind
:
SymbolKind
;
startLineNumber
:
number
}[]
{
const
m
=
this
.
_currentModel
.
read
(
reader
);
if
(
!
m
)
{
return
[];
}
const
symbols
=
m
.
asListOfDocumentSymbols
()
.
filter
(
s
=>
new
LineRange
(
s
.
range
.
startLineNumber
,
s
.
range
.
endLineNumber
).
contains
(
lineNumber
));
if
(
symbols
.
length
===
0
)
{
return
[];
}
symbols
.
sort
(
reverseOrder
(
compareBy
(
s
=>
s
.
range
.
endLineNumber
-
s
.
range
.
startLineNumber
,
numberComparator
)));
return
symbols
.
map
(
s
=>
({
name
:
s
.
name
,
kind
:
s
.
kind
,
startLineNumber
:
s
.
range
.
startLineNumber
}));
}
}
HideUnchangedRegionsFeature
.
setBreadcrumbsSourceFactory
((
textModel
,
instantiationService
)
=>
{
...
...
src/vs/editor/contrib/inlineCompletions/browser/model/inlineCompletionsModel.ts
Просмотр файла @
3d182cf0
...
...
@@ -96,6 +96,10 @@ export class InlineCompletionsModel extends Disposable {
private
readonly
_suppressInSnippetMode
;
private
readonly
_isInSnippetMode
;
get
editor
()
{
return
this
.
_editor
;
}
constructor
(
public
readonly
textModel
:
ITextModel
,
private
readonly
_selectedSuggestItem
:
IObservable
<
SuggestItemInfo
|
undefined
>
,
...
...
@@ -1206,13 +1210,22 @@ class FadeoutDecoration extends Disposable {
}
}
function
isSuggestionInViewport
(
editor
:
ICodeEditor
,
suggestion
:
InlineSuggestionItem
):
boolean
{
export
function
isSuggestionInViewport
(
editor
:
ICodeEditor
,
suggestion
:
InlineSuggestionItem
,
reader
:
IReader
|
undefined
=
undefined
):
boolean
{
const
targetRange
=
suggestion
.
targetRange
;
// TODO make getVisibleRanges reactive!
observableCodeEditor
(
editor
).
scrollTop
.
read
(
reader
);
const
visibleRanges
=
editor
.
getVisibleRanges
();
if
(
visibleRanges
.
length
<
1
)
{
return
false
;
}
const
viewportRange
=
new
Range
(
visibleRanges
[
0
].
startLineNumber
,
visibleRanges
[
0
].
startColumn
,
visibleRanges
[
visibleRanges
.
length
-
1
].
endLineNumber
,
visibleRanges
[
visibleRanges
.
length
-
1
].
endColumn
);
const
viewportRange
=
new
Range
(
visibleRanges
[
0
].
startLineNumber
,
visibleRanges
[
0
].
startColumn
,
visibleRanges
[
visibleRanges
.
length
-
1
].
endLineNumber
,
visibleRanges
[
visibleRanges
.
length
-
1
].
endColumn
);
return
viewportRange
.
containsRange
(
targetRange
);
}
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorMenu.ts
Просмотр файла @
3d182cf0
...
...
@@ -27,7 +27,7 @@ import { asCssVariable, descriptionForeground, editorActionListForeground, edito
import
{
ObservableCodeEditor
}
from
'
../../../../../../browser/observableCodeEditor.js
'
;
import
{
EditorOption
}
from
'
../../../../../../common/config/editorOptions.js
'
;
import
{
hideInlineCompletionId
,
inlineSuggestCommitId
,
toggleShowCollapsedId
}
from
'
../../../controller/commandIds.js
'
;
import
{
I
InlineEdit
Model
}
from
'
../inlineEdits
ViewInterface
.js
'
;
import
{
ModelPer
InlineEdit
}
from
'
../inlineEdits
Model
.js
'
;
import
{
FirstFnArg
,
}
from
'
../utils/utils.js
'
;
export
class
GutterIndicatorMenuContent
{
...
...
@@ -35,7 +35,7 @@ export class GutterIndicatorMenuContent {
private
readonly
_inlineEditsShowCollapsed
:
IObservable
<
boolean
>
;
constructor
(
private
readonly
_model
:
I
InlineEdit
Model
,
private
readonly
_model
:
ModelPer
InlineEdit
,
private
readonly
_close
:
(
focusEditor
:
boolean
)
=>
void
,
private
readonly
_editorObs
:
ObservableCodeEditor
,
@
IContextKeyService
private
readonly
_contextKeyService
:
IContextKeyService
,
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/components/gutterIndicatorView.ts
Просмотр файла @
3d182cf0
...
...
@@ -24,7 +24,8 @@ import { EditorOption, RenderLineNumbersType } from '../../../../../../common/co
import
{
LineRange
}
from
'
../../../../../../common/core/ranges/lineRange.js
'
;
import
{
OffsetRange
}
from
'
../../../../../../common/core/ranges/offsetRange.js
'
;
import
{
StickyScrollController
}
from
'
../../../../../stickyScroll/browser/stickyScrollController.js
'
;
import
{
IInlineEditModel
,
InlineEditTabAction
}
from
'
../inlineEditsViewInterface.js
'
;
import
{
InlineEditTabAction
}
from
'
../inlineEditsViewInterface.js
'
;
import
{
ModelPerInlineEdit
}
from
'
../inlineEditsModel.js
'
;
import
{
getEditorBlendedColor
,
inlineEditIndicatorBackground
,
inlineEditIndicatorPrimaryBackground
,
inlineEditIndicatorPrimaryBorder
,
inlineEditIndicatorPrimaryForeground
,
inlineEditIndicatorSecondaryBackground
,
inlineEditIndicatorSecondaryBorder
,
inlineEditIndicatorSecondaryForeground
,
inlineEditIndicatorsuccessfulBackground
,
inlineEditIndicatorsuccessfulBorder
,
inlineEditIndicatorsuccessfulForeground
}
from
'
../theme.js
'
;
import
{
mapOutFalsy
,
rectToProps
}
from
'
../utils/utils.js
'
;
import
{
GutterIndicatorMenuContent
}
from
'
./gutterIndicatorMenu.js
'
;
...
...
@@ -45,7 +46,7 @@ export class InlineEditsGutterIndicator extends Disposable {
private
readonly
_editorObs
:
ObservableCodeEditor
,
private
readonly
_originalRange
:
IObservable
<
LineRange
|
undefined
>
,
private
readonly
_verticalOffset
:
IObservable
<
number
>
,
private
readonly
_model
:
IObservable
<
I
InlineEdit
Model
|
undefined
>
,
private
readonly
_model
:
IObservable
<
ModelPer
InlineEdit
|
undefined
>
,
private
readonly
_isHoveringOverInlineEdit
:
IObservable
<
boolean
>
,
private
readonly
_focusIsInMenu
:
ISettableObservable
<
boolean
>
,
@
IHoverService
private
readonly
_hoverService
:
HoverService
,
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsModel.ts
Просмотр файла @
3d182cf0
...
...
@@ -12,12 +12,15 @@ import { LineRange } from '../../../../../common/core/ranges/lineRange.js';
import
{
TextEdit
}
from
'
../../../../../common/core/edits/textEdit.js
'
;
import
{
StringText
}
from
'
../../../../../common/core/text/abstractText.js
'
;
import
{
Command
,
InlineCompletionCommand
}
from
'
../../../../../common/languages.js
'
;
import
{
InlineCompletionsModel
}
from
'
../../model/inlineCompletionsModel.js
'
;
import
{
InlineCompletionsModel
,
isSuggestionInViewport
}
from
'
../../model/inlineCompletionsModel.js
'
;
import
{
InlineCompletionItem
,
InlineSuggestHint
}
from
'
../../model/inlineSuggestionItem.js
'
;
import
{
IInlineEditHost
,
IInlineEditModel
,
InlineCompletionViewData
,
InlineCompletionViewKind
,
InlineEditTabAction
}
from
'
./inlineEditsViewInterface.js
'
;
import
{
IInlineEditHost
,
InlineCompletionViewData
,
InlineCompletionViewKind
,
InlineEditTabAction
}
from
'
./inlineEditsViewInterface.js
'
;
import
{
InlineEditWithChanges
}
from
'
./inlineEditWithChanges.js
'
;
export
class
InlineEditModel
implements
IInlineEditModel
{
/**
* Warning: This is not per inline edit id and gets created often.
*/
export
class
ModelPerInlineEdit
implements
ModelPerInlineEdit
{
readonly
action
:
Command
|
undefined
;
readonly
displayName
:
string
;
...
...
@@ -27,6 +30,9 @@ export class InlineEditModel implements IInlineEditModel {
readonly
displayLocation
:
InlineSuggestHint
|
undefined
;
readonly
showCollapsed
:
IObservable
<
boolean
>
;
/** Determines if the inline suggestion is fully in the view port */
readonly
inViewPort
:
IObservable
<
boolean
>
;
constructor
(
private
readonly
_model
:
InlineCompletionsModel
,
readonly
inlineEdit
:
InlineEditWithChanges
,
...
...
@@ -39,6 +45,8 @@ export class InlineEditModel implements IInlineEditModel {
this
.
displayLocation
=
this
.
inlineEdit
.
inlineCompletion
.
hint
;
this
.
showCollapsed
=
this
.
_model
.
showCollapsed
;
this
.
inViewPort
=
derived
(
this
,
reader
=>
isSuggestionInViewport
(
this
.
_model
.
editor
,
this
.
inlineEdit
.
inlineCompletion
,
reader
));
}
accept
()
{
...
...
@@ -68,7 +76,7 @@ export class InlineEditHost implements IInlineEditHost {
export
class
GhostTextIndicator
{
readonly
model
:
InlineEdit
Model
;
readonly
model
:
ModelPer
InlineEdit
;
constructor
(
editor
:
ICodeEditor
,
...
...
@@ -86,7 +94,7 @@ export class GhostTextIndicator {
return
InlineEditTabAction
.
Inactive
;
});
this
.
model
=
new
InlineEdit
Model
(
this
.
model
=
new
ModelPer
InlineEdit
(
model
,
new
InlineEditWithChanges
(
new
StringText
(
''
),
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsNewUsers.ts
Просмотр файла @
3d182cf0
...
...
@@ -10,7 +10,8 @@ import { autorun, autorunWithStore, derived, IObservable, observableValue, runOn
import
{
IConfigurationService
}
from
'
../../../../../../platform/configuration/common/configuration.js
'
;
import
{
IStorageService
,
StorageScope
,
StorageTarget
}
from
'
../../../../../../platform/storage/common/storage.js
'
;
import
{
InlineEditsGutterIndicator
}
from
'
./components/gutterIndicatorView.js
'
;
import
{
IInlineEditHost
,
IInlineEditModel
}
from
'
./inlineEditsViewInterface.js
'
;
import
{
IInlineEditHost
}
from
'
./inlineEditsViewInterface.js
'
;
import
{
ModelPerInlineEdit
}
from
'
./inlineEditsModel.js
'
;
import
{
InlineEditsCollapsedView
}
from
'
./inlineEditsViews/inlineEditsCollapsedView.js
'
;
enum
UserKind
{
...
...
@@ -39,7 +40,7 @@ export class InlineEditsOnboardingExperience extends Disposable {
constructor
(
private
readonly
_host
:
IObservable
<
IInlineEditHost
|
undefined
>
,
private
readonly
_model
:
IObservable
<
I
InlineEdit
Model
|
undefined
>
,
private
readonly
_model
:
IObservable
<
ModelPer
InlineEdit
|
undefined
>
,
private
readonly
_indicator
:
IObservable
<
InlineEditsGutterIndicator
|
undefined
>
,
private
readonly
_collapsedView
:
InlineEditsCollapsedView
,
@
IStorageService
private
readonly
_storageService
:
IStorageService
,
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsView.ts
Просмотр файла @
3d182cf0
...
...
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import
{
$
}
from
'
../../../../../../base/browser/dom.js
'
;
import
{
equalsIfDefined
,
itemEquals
}
from
'
../../../../../../base/common/equals.js
'
;
import
{
equalsIfDefined
,
itemEquals
,
itemsEquals
}
from
'
../../../../../../base/common/equals.js
'
;
import
{
BugIndicatingError
,
onUnexpectedError
}
from
'
../../../../../../base/common/errors.js
'
;
import
{
Event
}
from
'
../../../../../../base/common/event.js
'
;
import
{
Disposable
}
from
'
../../../../../../base/common/lifecycle.js
'
;
...
...
@@ -20,18 +20,20 @@ import { LineRange } from '../../../../../common/core/ranges/lineRange.js';
import
{
AbstractText
,
StringText
}
from
'
../../../../../common/core/text/abstractText.js
'
;
import
{
TextLength
}
from
'
../../../../../common/core/text/textLength.js
'
;
import
{
DetailedLineRangeMapping
,
lineRangeMappingFromRangeMappings
,
RangeMapping
}
from
'
../../../../../common/diff/rangeMapping.js
'
;
import
{
ITextModel
}
from
'
../../../../../common/model.js
'
;
import
{
TextModel
}
from
'
../../../../../common/model/textModel.js
'
;
import
{
InlineEditItem
}
from
'
../../model/inlineSuggestionItem.js
'
;
import
{
InlineEditItem
,
InlineSuggestionIdentity
}
from
'
../../model/inlineSuggestionItem.js
'
;
import
{
InlineEditsGutterIndicator
}
from
'
./components/gutterIndicatorView.js
'
;
import
{
InlineEditWithChanges
}
from
'
./inlineEditWithChanges.js
'
;
import
{
GhostTextIndicator
,
InlineEditHost
,
InlineEdit
Model
}
from
'
./inlineEditsModel.js
'
;
import
{
GhostTextIndicator
,
InlineEditHost
,
ModelPer
InlineEdit
}
from
'
./inlineEditsModel.js
'
;
import
{
InlineEditsOnboardingExperience
}
from
'
./inlineEditsNewUsers.js
'
;
import
{
IInlineEditModel
,
InlineCompletionViewData
,
InlineCompletionViewKind
,
InlineEditTabAction
}
from
'
./inlineEditsViewInterface.js
'
;
import
{
InlineCompletionViewData
,
InlineCompletionViewKind
,
InlineEditTabAction
}
from
'
./inlineEditsViewInterface.js
'
;
import
{
InlineEditsCollapsedView
}
from
'
./inlineEditsViews/inlineEditsCollapsedView.js
'
;
import
{
InlineEditsCustomView
}
from
'
./inlineEditsViews/inlineEditsCustomView.js
'
;
import
{
InlineEditsDeletionView
}
from
'
./inlineEditsViews/inlineEditsDeletionView.js
'
;
import
{
InlineEditsInsertionView
}
from
'
./inlineEditsViews/inlineEditsInsertionView.js
'
;
import
{
InlineEditsLineReplacementView
}
from
'
./inlineEditsViews/inlineEditsLineReplacementView.js
'
;
import
{
ILongDistanceHint
,
ILongDistanceViewState
,
InlineEditsLongDistanceHint
}
from
'
./inlineEditsViews/inlineEditsLongDistanceHint.js
'
;
import
{
InlineEditsSideBySideView
}
from
'
./inlineEditsViews/inlineEditsSideBySideView.js
'
;
import
{
InlineEditsWordReplacementView
}
from
'
./inlineEditsViews/inlineEditsWordReplacementView.js
'
;
import
{
IOriginalEditorInlineDiffViewState
,
OriginalEditorInlineDiffView
}
from
'
./inlineEditsViews/originalEditorInlineDiffView.js
'
;
...
...
@@ -53,11 +55,12 @@ export class InlineEditsView extends Disposable {
editorWidth
:
number
;
timestamp
:
number
;
}
|
undefined
;
private
readonly
_showLongDistanceHint
:
IObservable
<
boolean
>
;
constructor
(
private
readonly
_editor
:
ICodeEditor
,
private
readonly
_host
:
IObservable
<
InlineEditHost
|
undefined
>
,
private
readonly
_model
:
IObservable
<
InlineEdit
Model
|
undefined
>
,
private
readonly
_model
:
IObservable
<
ModelPer
InlineEdit
|
undefined
>
,
private
readonly
_ghostTextIndicator
:
IObservable
<
GhostTextIndicator
|
undefined
>
,
private
readonly
_focusIsInMenu
:
ISettableObservable
<
boolean
>
,
@
IInstantiationService
private
readonly
_instantiationService
:
IInstantiationService
,
...
...
@@ -73,6 +76,7 @@ export class InlineEditsView extends Disposable {
newText
:
string
;
newTextLineCount
:
number
;
isInDiffEditor
:
boolean
;
longDistanceHint
:
ILongDistanceHint
|
undefined
;
}
|
undefined
>
(
this
,
reader
=>
{
const
model
=
this
.
_model
.
read
(
reader
);
const
textModel
=
this
.
_editorObs
.
model
.
read
(
reader
);
...
...
@@ -91,6 +95,8 @@ export class InlineEditsView extends Disposable {
return
undefined
;
}
const
longDistanceHint
=
this
.
_getLongDistanceHintState
(
model
,
reader
);
if
(
state
.
kind
===
InlineCompletionViewKind
.
SideBySide
)
{
const
indentationAdjustmentEdit
=
createReindentEdit
(
newText
,
inlineEdit
.
modifiedLineRange
,
textModel
.
getOptions
().
tabSize
);
newText
=
indentationAdjustmentEdit
.
applyToString
(
newText
);
...
...
@@ -120,6 +126,7 @@ export class InlineEditsView extends Disposable {
newText
,
newTextLineCount
:
inlineEdit
.
modifiedLineRange
.
length
,
isInDiffEditor
:
model
.
isInDiffEditor
,
longDistanceHint
,
};
});
this
.
_previewTextModel
=
this
.
_register
(
this
.
_instantiationService
.
createInstance
(
...
...
@@ -160,7 +167,7 @@ export class InlineEditsView extends Disposable {
return
state
.
edit
.
displayRange
;
});
const
modelWithGhostTextSupport
=
derived
<
InlineEdit
Model
|
undefined
>
(
this
,
reader
=>
{
const
modelWithGhostTextSupport
=
derived
<
ModelPer
InlineEdit
|
undefined
>
(
this
,
reader
=>
{
/** @description modelWithGhostTextSupport */
const
model
=
this
.
_model
.
read
(
reader
);
if
(
model
)
{
...
...
@@ -260,8 +267,35 @@ export class InlineEditsView extends Disposable {
this
.
_model
.
map
((
m
,
reader
)
=>
this
.
_uiState
.
read
(
reader
)?.
state
?.
kind
===
'
custom
'
?
m
?.
displayLocation
:
undefined
),
this
.
_tabAction
,
));
this
.
_showLongDistanceHint
=
this
.
_editorObs
.
getOption
(
EditorOption
.
inlineSuggest
).
map
(
this
,
s
=>
s
.
edits
.
showLongDistanceHint
);
this
.
_longDistanceHint
=
derived
(
this
,
reader
=>
{
if
(
!
this
.
_showLongDistanceHint
.
read
(
reader
))
{
return
undefined
;
}
return
reader
.
store
.
add
(
this
.
_instantiationService
.
createInstance
(
InlineEditsLongDistanceHint
,
this
.
_editor
,
this
.
_uiState
.
map
<
ILongDistanceViewState
|
undefined
>
(
s
=>
s
?.
longDistanceHint
?
({
hint
:
s
.
longDistanceHint
,
newTextLineCount
:
s
.
newTextLineCount
,
edit
:
s
.
edit
,
diff
:
s
.
diff
,
})
:
undefined
),
this
.
_previewTextModel
,
this
.
_tabAction
,
this
.
_model
,
));
}).
recomputeInitiallyAndOnChange
(
this
.
_store
);
this
.
_inlineDiffView
=
this
.
_register
(
new
OriginalEditorInlineDiffView
(
this
.
_editor
,
this
.
_inlineDiffViewState
,
this
.
_previewTextModel
));
this
.
_wordReplacementViews
=
mapObservableArrayCached
(
this
,
this
.
_uiState
.
map
(
s
=>
s
?.
state
?.
kind
===
'
wordReplacements
'
?
s
.
state
.
replacements
:
[]),
(
e
,
store
)
=>
{
const
wordReplacements
=
derivedOpts
({
equalsFn
:
itemsEquals
(
itemEquals
())
},
reader
=>
{
const
s
=
this
.
_uiState
.
read
(
reader
);
return
s
?.
state
?.
kind
===
'
wordReplacements
'
?
s
.
state
.
replacements
:
[];
});
this
.
_wordReplacementViews
=
mapObservableArrayCached
(
this
,
wordReplacements
,
(
e
,
store
)
=>
{
return
store
.
add
(
this
.
_instantiationService
.
createInstance
(
InlineEditsWordReplacementView
,
this
.
_editorObs
,
e
,
this
.
_tabAction
));
});
this
.
_lineReplacementView
=
this
.
_register
(
this
.
_instantiationService
.
createInstance
(
InlineEditsLineReplacementView
,
...
...
@@ -348,6 +382,24 @@ export class InlineEditsView extends Disposable {
this
.
_constructorDone
.
set
(
true
,
undefined
);
// TODO: remove and use correct initialization order
}
private
_currentInlineEditCache
:
{
inlineSuggestionIdentity
:
InlineSuggestionIdentity
;
firstCursorLineNumber
:
number
;
}
|
undefined
=
undefined
;
private
_getLongDistanceHintState
(
model
:
ModelPerInlineEdit
,
reader
:
IReader
):
ILongDistanceHint
|
undefined
{
if
(
this
.
_currentInlineEditCache
?.
inlineSuggestionIdentity
!==
model
.
inlineEdit
.
inlineCompletion
.
identity
)
{
this
.
_currentInlineEditCache
=
{
inlineSuggestionIdentity
:
model
.
inlineEdit
.
inlineCompletion
.
identity
,
firstCursorLineNumber
:
model
.
inlineEdit
.
cursorPosition
.
lineNumber
,
};
}
return
model
.
inViewPort
.
read
(
reader
)
?
undefined
:
{
lineNumber
:
this
.
_currentInlineEditCache
.
firstCursorLineNumber
,
};
}
private
readonly
_constructorDone
;
private
readonly
_uiState
;
...
...
@@ -372,7 +424,8 @@ export class InlineEditsView extends Disposable {
protected
readonly
_inlineCollapsedView
;
protected
readonly
_customView
;
private
readonly
_customView
;
protected
readonly
_longDistanceHint
;
protected
readonly
_inlineDiffView
;
...
...
@@ -380,11 +433,11 @@ export class InlineEditsView extends Disposable {
protected
readonly
_lineReplacementView
;
private
getCacheId
(
model
:
I
InlineEdit
Model
)
{
private
getCacheId
(
model
:
ModelPer
InlineEdit
)
{
return
model
.
inlineEdit
.
inlineCompletion
.
identity
.
id
;
}
private
determineView
(
model
:
I
InlineEdit
Model
,
reader
:
IReader
,
diff
:
DetailedLineRangeMapping
[],
newText
:
StringText
):
InlineCompletionViewKind
{
private
determineView
(
model
:
ModelPer
InlineEdit
,
reader
:
IReader
,
diff
:
DetailedLineRangeMapping
[],
newText
:
StringText
):
InlineCompletionViewKind
{
// Check if we can use the previous view if it is the same InlineCompletion as previously shown
const
inlineEdit
=
model
.
inlineEdit
;
const
canUseCache
=
this
.
_previousView
?.
id
===
this
.
getCacheId
(
model
)
&&
!
model
.
displayLocation
?.
jumpToEdit
;
...
...
@@ -478,11 +531,10 @@ export class InlineEditsView extends Disposable {
return
InlineCompletionViewKind
.
SideBySide
;
}
private
determineRenderState
(
model
:
I
InlineEdit
Model
,
reader
:
IReader
,
diff
:
DetailedLineRangeMapping
[],
newText
:
StringText
)
{
private
determineRenderState
(
model
:
ModelPer
InlineEdit
,
reader
:
IReader
,
diff
:
DetailedLineRangeMapping
[],
newText
:
StringText
)
{
const
inlineEdit
=
model
.
inlineEdit
;
let
view
=
this
.
determineView
(
model
,
reader
,
diff
,
newText
);
if
(
this
.
_willRenderAboveCursor
(
reader
,
inlineEdit
,
view
))
{
switch
(
view
)
{
case
InlineCompletionViewKind
.
LineReplacement
:
...
...
@@ -491,7 +543,6 @@ export class InlineEditsView extends Disposable {
break
;
}
}
this
.
_previousView
=
{
id
:
this
.
getCacheId
(
model
),
view
,
editorWidth
:
this
.
_editor
.
getLayoutInfo
().
width
,
timestamp
:
Date
.
now
()
};
const
inner
=
diff
.
flatMap
(
d
=>
d
.
innerChanges
??
[]);
...
...
@@ -503,18 +554,7 @@ export class InlineEditsView extends Disposable {
modified
:
newText
.
getValueOfRange
(
m
.
modifiedRange
)
}));
const
cursorPosition
=
inlineEdit
.
cursorPosition
;
const
startsWithEOL
=
stringChanges
.
length
===
0
?
false
:
stringChanges
[
0
].
modified
.
startsWith
(
textModel
.
getEOL
());
const
viewData
:
InlineCompletionViewData
=
{
cursorColumnDistance
:
inlineEdit
.
edit
.
replacements
.
length
===
0
?
0
:
inlineEdit
.
edit
.
replacements
[
0
].
range
.
getStartPosition
().
column
-
cursorPosition
.
column
,
cursorLineDistance
:
inlineEdit
.
lineEdit
.
lineRange
.
startLineNumber
-
cursorPosition
.
lineNumber
+
(
startsWithEOL
&&
inlineEdit
.
lineEdit
.
lineRange
.
startLineNumber
>=
cursorPosition
.
lineNumber
?
1
:
0
),
lineCountOriginal
:
inlineEdit
.
lineEdit
.
lineRange
.
length
,
lineCountModified
:
inlineEdit
.
lineEdit
.
newLines
.
length
,
characterCountOriginal
:
stringChanges
.
reduce
((
acc
,
r
)
=>
acc
+
r
.
original
.
length
,
0
),
characterCountModified
:
stringChanges
.
reduce
((
acc
,
r
)
=>
acc
+
r
.
modified
.
length
,
0
),
disjointReplacements
:
stringChanges
.
length
,
sameShapeReplacements
:
stringChanges
.
every
(
r
=>
r
.
original
===
stringChanges
[
0
].
original
&&
r
.
modified
===
stringChanges
[
0
].
modified
),
};
const
viewData
=
getViewData
(
inlineEdit
,
stringChanges
,
textModel
);
switch
(
view
)
{
case
InlineCompletionViewKind
.
InsertionInline
:
return
{
kind
:
InlineCompletionViewKind
.
InsertionInline
as
const
,
viewData
};
...
...
@@ -611,6 +651,22 @@ export class InlineEditsView extends Disposable {
}
}
function
getViewData
(
inlineEdit
:
InlineEditWithChanges
,
stringChanges
:
{
originalRange
:
Range
;
modifiedRange
:
Range
;
original
:
string
;
modified
:
string
}[],
textModel
:
ITextModel
)
{
const
cursorPosition
=
inlineEdit
.
cursorPosition
;
const
startsWithEOL
=
stringChanges
.
length
===
0
?
false
:
stringChanges
[
0
].
modified
.
startsWith
(
textModel
.
getEOL
());
const
viewData
:
InlineCompletionViewData
=
{
cursorColumnDistance
:
inlineEdit
.
edit
.
replacements
.
length
===
0
?
0
:
inlineEdit
.
edit
.
replacements
[
0
].
range
.
getStartPosition
().
column
-
cursorPosition
.
column
,
cursorLineDistance
:
inlineEdit
.
lineEdit
.
lineRange
.
startLineNumber
-
cursorPosition
.
lineNumber
+
(
startsWithEOL
&&
inlineEdit
.
lineEdit
.
lineRange
.
startLineNumber
>=
cursorPosition
.
lineNumber
?
1
:
0
),
lineCountOriginal
:
inlineEdit
.
lineEdit
.
lineRange
.
length
,
lineCountModified
:
inlineEdit
.
lineEdit
.
newLines
.
length
,
characterCountOriginal
:
stringChanges
.
reduce
((
acc
,
r
)
=>
acc
+
r
.
original
.
length
,
0
),
characterCountModified
:
stringChanges
.
reduce
((
acc
,
r
)
=>
acc
+
r
.
modified
.
length
,
0
),
disjointReplacements
:
stringChanges
.
length
,
sameShapeReplacements
:
stringChanges
.
every
(
r
=>
r
.
original
===
stringChanges
[
0
].
original
&&
r
.
modified
===
stringChanges
[
0
].
modified
),
};
return
viewData
;
}
function
isSingleLineInsertion
(
diff
:
DetailedLineRangeMapping
[])
{
return
diff
.
every
(
m
=>
m
.
innerChanges
!
.
every
(
r
=>
isWordInsertion
(
r
)));
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewInterface.ts
Просмотр файла @
3d182cf0
...
...
@@ -6,9 +6,6 @@
import
{
IMouseEvent
}
from
'
../../../../../../base/browser/mouseEvent.js
'
;
import
{
Event
}
from
'
../../../../../../base/common/event.js
'
;
import
{
IObservable
}
from
'
../../../../../../base/common/observable.js
'
;
import
{
Command
,
InlineCompletionCommand
}
from
'
../../../../../common/languages.js
'
;
import
{
InlineSuggestHint
}
from
'
../../model/inlineSuggestionItem.js
'
;
import
{
InlineEditWithChanges
}
from
'
./inlineEditWithChanges.js
'
;
export
enum
InlineEditTabAction
{
Jump
=
'
jump
'
,
...
...
@@ -27,21 +24,6 @@ export interface IInlineEditHost {
inAcceptFlow
:
IObservable
<
boolean
>
;
}
export
interface
IInlineEditModel
{
displayName
:
string
;
action
:
Command
|
undefined
;
extensionCommands
:
InlineCompletionCommand
[];
isInDiffEditor
:
boolean
;
inlineEdit
:
InlineEditWithChanges
;
tabAction
:
IObservable
<
InlineEditTabAction
>
;
showCollapsed
:
IObservable
<
boolean
>
;
displayLocation
:
InlineSuggestHint
|
undefined
;
handleInlineEditShown
(
viewKind
:
string
,
viewData
?:
InlineCompletionViewData
):
void
;
accept
():
void
;
jump
():
void
;
}
// TODO: Move this out of here as it is also includes ghosttext
export
enum
InlineCompletionViewKind
{
GhostText
=
'
ghostText
'
,
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViewProducer.ts
Просмотр файла @
3d182cf0
...
...
@@ -16,7 +16,7 @@ import { TextModelText } from '../../../../../common/model/textModelText.js';
import
{
InlineCompletionsModel
}
from
'
../../model/inlineCompletionsModel.js
'
;
import
{
InlineEdit
}
from
'
../../model/inlineEdit.js
'
;
import
{
InlineEditWithChanges
}
from
'
./inlineEditWithChanges.js
'
;
import
{
GhostTextIndicator
,
InlineEditHost
,
InlineEdit
Model
}
from
'
./inlineEditsModel.js
'
;
import
{
GhostTextIndicator
,
InlineEditHost
,
ModelPer
InlineEdit
}
from
'
./inlineEditsModel.js
'
;
import
{
InlineEditsView
}
from
'
./inlineEditsView.js
'
;
import
{
InlineEditTabAction
}
from
'
./inlineEditsViewInterface.js
'
;
...
...
@@ -50,7 +50,7 @@ export class InlineEditsViewAndDiffProducer extends Disposable { // TODO: This c
return
new
InlineEditWithChanges
(
text
,
diffEdits
,
model
.
primaryPosition
.
read
(
undefined
),
model
.
allPositions
.
read
(
undefined
),
inlineEdit
.
commands
,
inlineEdit
.
inlineCompletion
);
});
private
readonly
_inlineEditModel
=
derived
<
InlineEdit
Model
|
undefined
>
(
this
,
reader
=>
{
private
readonly
_inlineEditModel
=
derived
<
ModelPer
InlineEdit
|
undefined
>
(
this
,
reader
=>
{
const
model
=
this
.
_model
.
read
(
reader
);
if
(
!
model
)
{
return
undefined
;
}
const
edit
=
this
.
_inlineEdit
.
read
(
reader
);
...
...
@@ -65,7 +65,7 @@ export class InlineEditsViewAndDiffProducer extends Disposable { // TODO: This c
return
InlineEditTabAction
.
Inactive
;
});
return
new
InlineEdit
Model
(
model
,
edit
,
tabAction
);
return
new
ModelPer
InlineEdit
(
model
,
edit
,
tabAction
);
});
private
readonly
_inlineEditHost
=
derived
<
InlineEditHost
|
undefined
>
(
this
,
reader
=>
{
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/debugVisualization.ts
Просмотр файла @
3d182cf0
...
...
@@ -16,7 +16,15 @@ export function setVisualization(data: object, visualization: IVisualizationEffe
(
data
as
any
)[
'
$$visualization
'
]
=
visualization
;
}
export
function
debugLogRects
(
rects
:
Record
<
string
,
Rect
>
,
elem
:
HTMLElement
):
object
{
export
function
debugLogRects
(
rects
:
Record
<
string
,
Rect
>
|
Rect
[],
elem
:
HTMLElement
):
object
{
if
(
Array
.
isArray
(
rects
))
{
const
record
:
Record
<
string
,
Rect
>
=
{};
rects
.
forEach
((
rect
,
index
)
=>
{
record
[
index
.
toString
()]
=
rect
;
});
rects
=
record
;
}
setVisualization
(
rects
,
new
ManyRectVisualizer
(
rects
,
elem
));
return
rects
;
}
...
...
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/flexBoxLayout.ts
0 → 100644
Просмотр файла @
3d182cf0
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export
interface
IFlexBoxPartGrowthRule
extends
IFlexBoxPartExtensionRule
{
min
?:
number
;
rules
?:
IFlexBoxPartExtensionRule
[];
}
export
interface
IFlexBoxPartExtensionRule
{
max
?:
number
;
priority
?:
number
;
share
?:
number
;
}
/**
* Distributes a total size into parts that each have a list of growth rules.
* Returns `null` if the layout is not possible.
* The sum of all returned sizes will be equal to `totalSize`.
*
* First, each part gets its minimum size.
* Then, remaining space is distributed to the rules with the highest priority, as long as the max constraint allows it (considering share).
* This continues with next lower priority rules until no space is left.
*/
export
function
distributeFlexBoxLayout
<
T
extends
Record
<
string
,
IFlexBoxPartGrowthRule
|
IFlexBoxPartGrowthRule
[]
>>
(
totalSize
:
number
,
parts
:
T
&
Record
<
string
,
IFlexBoxPartGrowthRule
|
IFlexBoxPartGrowthRule
[]
>
):
Record
<
keyof
T
,
number
>
|
null
{
// Normalize parts to always have array of rules
const
normalizedParts
:
Record
<
string
,
{
min
:
number
;
rules
:
IFlexBoxPartExtensionRule
[]
}
>
=
{};
for
(
const
[
key
,
part
]
of
Object
.
entries
(
parts
))
{
if
(
Array
.
isArray
(
part
))
{
normalizedParts
[
key
]
=
{
min
:
0
,
rules
:
part
};
}
else
{
normalizedParts
[
key
]
=
{
min
:
part
.
min
??
0
,
rules
:
part
.
rules
??
[{
max
:
part
.
max
,
priority
:
part
.
priority
,
share
:
part
.
share
}]
};
}
}
// Initialize result with minimum sizes
const
result
:
Record
<
string
,
number
>
=
{};
let
usedSize
=
0
;
for
(
const
[
key
,
part
]
of
Object
.
entries
(
normalizedParts
))
{
result
[
key
]
=
part
.
min
;
usedSize
+=
part
.
min
;
}
// Check if we can satisfy minimum constraints
if
(
usedSize
>
totalSize
)
{
return
null
;
}
let
remainingSize
=
totalSize
-
usedSize
;
// Distribute remaining space by priority levels
while
(
remainingSize
>
0
)
{
// Find all rules at current highest priority that can still grow
const
candidateRules
:
Array
<
{
partKey
:
string
;
ruleIndex
:
number
;
rule
:
IFlexBoxPartExtensionRule
;
priority
:
number
;
share
:
number
;
}
>
=
[];
for
(
const
[
key
,
part
]
of
Object
.
entries
(
normalizedParts
))
{
for
(
let
i
=
0
;
i
<
part
.
rules
.
length
;
i
++
)
{
const
rule
=
part
.
rules
[
i
];
const
currentUsage
=
result
[
key
];
const
maxSize
=
rule
.
max
??
Infinity
;
if
(
currentUsage
<
maxSize
)
{
candidateRules
.
push
({
partKey
:
key
,
ruleIndex
:
i
,
rule
,
priority
:
rule
.
priority
??
0
,
share
:
rule
.
share
??
1
});
}
}
}
if
(
candidateRules
.
length
===
0
)
{
// No rules can grow anymore, but we have remaining space
break
;
}
// Find the highest priority among candidates
const
maxPriority
=
Math
.
max
(...
candidateRules
.
map
(
c
=>
c
.
priority
));
const
highestPriorityCandidates
=
candidateRules
.
filter
(
c
=>
c
.
priority
===
maxPriority
);
// Calculate total share
const
totalShare
=
highestPriorityCandidates
.
reduce
((
sum
,
c
)
=>
sum
+
c
.
share
,
0
);
// Distribute space proportionally by share
let
distributedThisRound
=
0
;
const
distributions
:
Array
<
{
partKey
:
string
;
ruleIndex
:
number
;
amount
:
number
}
>
=
[];
for
(
const
candidate
of
highestPriorityCandidates
)
{
const
rule
=
candidate
.
rule
;
const
currentUsage
=
result
[
candidate
.
partKey
];
const
maxSize
=
rule
.
max
??
Infinity
;
const
availableForThisRule
=
maxSize
-
currentUsage
;
// Calculate ideal share
const
idealShare
=
(
remainingSize
*
candidate
.
share
)
/
totalShare
;
const
actualAmount
=
Math
.
min
(
idealShare
,
availableForThisRule
);
distributions
.
push
({
partKey
:
candidate
.
partKey
,
ruleIndex
:
candidate
.
ruleIndex
,
amount
:
actualAmount
});
distributedThisRound
+=
actualAmount
;
}
if
(
distributedThisRound
===
0
)
{
// No progress can be made
break
;
}
// Apply distributions
for
(
const
dist
of
distributions
)
{
result
[
dist
.
partKey
]
+=
dist
.
amount
;
}
remainingSize
-=
distributedThisRound
;
// Break if remaining is negligible (floating point precision)
if
(
remainingSize
<
0.0001
)
{
break
;
}
}
return
result
as
Record
<
keyof
T
,
number
>
;
}
src/vs/editor/contrib/inlineCompletions/browser/view/inlineEdits/inlineEditsViews/inlineEditsLongDistanceHint.ts
0 → 100644
Просмотр файла @
3d182cf0
Это отличие свёрнуто
Нажмите, чтобы развернуть
Пред
1
2
След
Редактирование
Предварительный просмотр
Поддерживает Markdown
0%
Попробовать снова
или
прикрепить новый файл
.
Отмена
You are about to add
0
people
to the discussion. Proceed with caution.
Сначала завершите редактирование этого сообщения!
Отмена
Пожалуйста,
зарегистрируйтесь
или
войдите
чтобы прокомментировать