Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
xxadev
vscode
提交
cef3c064
V
vscode
项目概览
xxadev
/
vscode
与 Fork 源项目一致
从无法访问的项目Fork
通知
2
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
V
vscode
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
cef3c064
编写于
2月 25, 2020
作者:
R
rebornix
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
find widget attempt
上级
298461ed
变更
14
隐藏空白更改
内联
并排
Showing
14 changed file
with
382 addition
and
60 deletion
+382
-60
src/vs/editor/common/model.ts
src/vs/editor/common/model.ts
+6
-0
src/vs/editor/common/model/textModel.ts
src/vs/editor/common/model/textModel.ts
+5
-0
src/vs/editor/contrib/find/findController.ts
src/vs/editor/contrib/find/findController.ts
+5
-0
src/vs/workbench/api/browser/mainThreadNotebook.ts
src/vs/workbench/api/browser/mainThreadNotebook.ts
+14
-0
src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts
...rkbench/contrib/notebook/browser/notebook.contribution.ts
+2
-1
src/vs/workbench/contrib/notebook/browser/notebookActions.ts
src/vs/workbench/contrib/notebook/browser/notebookActions.ts
+73
-29
src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts
src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts
+3
-0
src/vs/workbench/contrib/notebook/browser/notebookEditor.ts
src/vs/workbench/contrib/notebook/browser/notebookEditor.ts
+56
-18
src/vs/workbench/contrib/notebook/browser/notebookEditorInput.ts
...workbench/contrib/notebook/browser/notebookEditorInput.ts
+5
-0
src/vs/workbench/contrib/notebook/browser/notebookFindWidget.ts
.../workbench/contrib/notebook/browser/notebookFindWidget.ts
+92
-0
src/vs/workbench/contrib/notebook/browser/output/transforms/richTransform.ts
...ntrib/notebook/browser/output/transforms/richTransform.ts
+39
-2
src/vs/workbench/contrib/notebook/browser/renderers/cellViewModel.ts
...bench/contrib/notebook/browser/renderers/cellViewModel.ts
+77
-8
src/vs/workbench/contrib/notebook/browser/renderers/codeCell.ts
.../workbench/contrib/notebook/browser/renderers/codeCell.ts
+3
-2
src/vs/workbench/contrib/notebook/common/notebookCommon.ts
src/vs/workbench/contrib/notebook/common/notebookCommon.ts
+2
-0
未找到文件。
src/vs/editor/common/model.ts
浏览文件 @
cef3c064
...
...
@@ -623,6 +623,12 @@ export interface ITextModel {
*/
equalsTextBuffer
(
other
:
ITextBuffer
):
boolean
;
/**
* Get the underling text buffer.
* @internal
*/
getTextBuffer
():
ITextBuffer
;
/**
* Get the text in a certain range.
* @param range The range describing what text to get.
...
...
src/vs/editor/common/model/textModel.ts
浏览文件 @
cef3c064
...
...
@@ -389,6 +389,11 @@ export class TextModel extends Disposable implements model.ITextModel {
return
this
.
_buffer
.
equals
(
other
);
}
public
getTextBuffer
():
model
.
ITextBuffer
{
this
.
_assertNotDisposed
();
return
this
.
_buffer
;
}
private
_emitContentChangedEvent
(
rawChange
:
ModelRawContentChangedEvent
,
change
:
IModelContentChangedEvent
):
void
{
if
(
this
.
_isDisposing
)
{
// Do not confuse listeners by emitting any event after disposing
...
...
src/vs/editor/contrib/find/findController.ts
浏览文件 @
cef3c064
...
...
@@ -66,6 +66,7 @@ export interface IFindStartOptions {
shouldFocus
:
FindStartFocusAction
;
shouldAnimate
:
boolean
;
updateSearchScope
:
boolean
;
shouldReveal
?:
boolean
;
}
export
class
CommonFindController
extends
Disposable
implements
IEditorContribution
{
...
...
@@ -264,6 +265,10 @@ export class CommonFindController extends Disposable implements IEditorContribut
isRevealed
:
true
};
if
(
opts
.
shouldReveal
!==
undefined
)
{
stateChanges
.
isRevealed
=
opts
.
shouldReveal
;
}
if
(
opts
.
seedSearchStringFromSelection
)
{
let
selectionSearchString
=
getSelectionSearchString
(
this
.
_editor
);
if
(
selectionSearchString
)
{
...
...
src/vs/workbench/api/browser/mainThreadNotebook.ts
浏览文件 @
cef3c064
...
...
@@ -11,6 +11,7 @@ import { INotebookService, IMainNotebookController } from 'vs/workbench/contrib/
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
ICell
,
IOutput
,
INotebook
,
INotebookMimeTypeSelector
,
NOTEBOOK_DISPLAY_ORDER
,
NotebookCellsSplice
,
NotebookCellOutputsSplice
,
generateCellPath
}
from
'
vs/workbench/contrib/notebook/common/notebookCommon
'
;
import
{
IConfigurationService
}
from
'
vs/platform/configuration/common/configuration
'
;
import
{
PieceTreeTextBufferFactory
,
PieceTreeTextBufferBuilder
}
from
'
vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder
'
;
export
class
MainThreadCell
implements
ICell
{
private
_onDidChangeOutputs
=
new
Emitter
<
NotebookCellOutputsSplice
[]
>
();
...
...
@@ -38,6 +39,8 @@ export class MainThreadCell implements ICell {
readonly
uri
:
URI
;
private
_buffer
:
PieceTreeTextBufferFactory
|
null
=
null
;
constructor
(
parent
:
MainThreadNotebookDocument
,
public
handle
:
number
,
...
...
@@ -66,6 +69,17 @@ export class MainThreadCell implements ICell {
save
()
{
this
.
_isDirty
=
false
;
}
resolveTextBufferFactory
():
PieceTreeTextBufferFactory
{
if
(
this
.
_buffer
)
{
return
this
.
_buffer
;
}
let
builder
=
new
PieceTreeTextBufferBuilder
();
builder
.
acceptChunk
(
this
.
source
.
join
(
'
\n
'
));
this
.
_buffer
=
builder
.
finish
(
true
);
return
this
.
_buffer
;
}
}
export
class
MainThreadNotebookDocument
extends
Disposable
implements
INotebook
{
...
...
src/vs/workbench/contrib/notebook/browser/notebook.contribution.ts
浏览文件 @
cef3c064
...
...
@@ -161,8 +161,9 @@ class CellContentProvider implements ITextModelContentProvider {
}
for
(
let
cell
of
notebook
.
cells
)
{
if
(
cell
.
uri
.
toString
()
===
resource
.
toString
())
{
let
bufferFactory
=
cell
.
resolveTextBufferFactory
();
return
this
.
_modelService
.
createModel
(
cell
.
source
.
join
(
'
\n
'
)
,
bufferFactory
,
cell
.
language
?
this
.
_modeService
.
create
(
cell
.
language
)
:
this
.
_modeService
.
createByFilepathOrFirstLine
(
resource
,
cell
.
source
[
0
]),
resource
);
...
...
src/vs/workbench/contrib/notebook/browser/notebookActions.ts
浏览文件 @
cef3c064
...
...
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
KeyCode
}
from
'
vs/base/common/keyCodes
'
;
import
{
KeyCode
,
KeyMod
}
from
'
vs/base/common/keyCodes
'
;
import
{
MenuRegistry
,
MenuId
,
Action2
,
registerAction2
}
from
'
vs/platform/actions/common/actions
'
;
import
{
ContextKeyExpr
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
InputFocusedContext
,
InputFocusedContextKey
}
from
'
vs/platform/contextkey/common/contextkeys
'
;
...
...
@@ -12,6 +12,7 @@ import { INotebookService } from 'vs/workbench/contrib/notebook/browser/notebook
import
{
IEditorService
}
from
'
vs/workbench/services/editor/common/editorService
'
;
import
{
NOTEBOOK_EDITOR_FOCUSED
,
NotebookEditor
}
from
'
vs/workbench/contrib/notebook/browser/notebookEditor
'
;
import
{
ServicesAccessor
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED
}
from
'
vs/workbench/contrib/notebook/browser/notebookBrowser
'
;
registerAction2
(
class
extends
Action2
{
constructor
()
{
...
...
@@ -82,25 +83,15 @@ registerAction2(class extends Action2 {
async
run
(
accessor
:
ServicesAccessor
):
Promise
<
void
>
{
let
editorService
=
accessor
.
get
(
IEditorService
);
let
notebookService
=
accessor
.
get
(
INotebookService
);
let
editor
=
getActiveNotebookEditor
(
editorService
,
notebookService
);
let
resource
=
editorService
.
activeEditor
?.
resource
;
let
editorControl
=
editorService
.
activeControl
;
let
notebookProviders
=
notebookService
.
getContributedNotebookProviders
(
resource
!
);
if
(
!
resource
||
!
editorControl
||
notebookProviders
.
length
===
0
)
{
return
;
}
let
editorViewType
=
(
editorControl
!
as
NotebookEditor
).
viewType
;
let
viewType
=
notebookProviders
[
0
].
id
;
if
(
viewType
!==
editorViewType
)
{
if
(
!
editor
)
{
return
;
}
let
activeCell
=
(
editorControl
!
as
NotebookEditor
)
.
getActiveCell
();
let
activeCell
=
editor
.
getActiveCell
();
if
(
activeCell
)
{
(
editorControl
!
as
NotebookEditor
)
.
focusNotebookCell
(
activeCell
,
false
);
editor
.
focusNotebookCell
(
activeCell
,
false
);
}
}
});
...
...
@@ -125,29 +116,62 @@ registerAction2(class extends Action2 {
async
run
(
accessor
:
ServicesAccessor
):
Promise
<
void
>
{
let
editorService
=
accessor
.
get
(
IEditorService
);
let
notebookService
=
accessor
.
get
(
INotebookService
);
let
editor
=
getActiveNotebookEditor
(
editorService
,
notebookService
);
let
resource
=
editorService
.
activeEditor
?.
resource
;
let
editorControl
=
editorService
.
activeControl
;
let
notebookProviders
=
notebookService
.
getContributedNotebookProviders
(
resource
!
);
if
(
!
resource
||
!
editorControl
||
notebookProviders
.
length
===
0
)
{
return
;
}
let
editorViewType
=
(
editorControl
!
as
NotebookEditor
).
viewType
;
let
viewType
=
notebookProviders
[
0
].
id
;
if
(
viewType
!==
editorViewType
)
{
if
(
!
editor
)
{
return
;
}
let
activeCell
=
(
editorControl
!
as
NotebookEditor
)
.
getActiveCell
();
let
activeCell
=
editor
.
getActiveCell
();
if
(
activeCell
)
{
(
editorControl
!
as
NotebookEditor
)
.
editNotebookCell
(
undefined
,
activeCell
);
editor
.
editNotebookCell
(
undefined
,
activeCell
);
}
}
});
registerAction2
(
class
extends
Action2
{
constructor
()
{
super
({
id
:
'
workbench.action.notebook.hideFind
'
,
title
:
'
Hide Find in Notebook
'
,
keybinding
:
{
when
:
ContextKeyExpr
.
and
(
NOTEBOOK_EDITOR_FOCUSED
,
KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED
),
primary
:
KeyCode
.
Escape
,
weight
:
KeybindingWeight
.
WorkbenchContrib
}
});
}
async
run
(
accessor
:
ServicesAccessor
):
Promise
<
void
>
{
let
editorService
=
accessor
.
get
(
IEditorService
);
let
notebookService
=
accessor
.
get
(
INotebookService
);
let
editor
=
getActiveNotebookEditor
(
editorService
,
notebookService
);
editor
?.
hideFind
();
}
});
registerAction2
(
class
extends
Action2
{
constructor
()
{
super
({
id
:
'
workbench.action.notebook.find
'
,
title
:
'
Find in Notebook
'
,
keybinding
:
{
when
:
NOTEBOOK_EDITOR_FOCUSED
,
primary
:
KeyCode
.
KEY_F
|
KeyMod
.
CtrlCmd
,
weight
:
KeybindingWeight
.
WorkbenchContrib
}
});
}
async
run
(
accessor
:
ServicesAccessor
):
Promise
<
void
>
{
let
editorService
=
accessor
.
get
(
IEditorService
);
let
notebookService
=
accessor
.
get
(
INotebookService
);
let
editor
=
getActiveNotebookEditor
(
editorService
,
notebookService
);
editor
?.
showFind
();
}
});
MenuRegistry
.
appendMenuItem
(
MenuId
.
EditorTitle
,
{
command
:
{
id
:
'
workbench.action.executeNotebook
'
,
...
...
@@ -170,3 +194,23 @@ MenuRegistry.appendMenuItem(MenuId.EditorTitle, {
group
:
'
navigation
'
,
when
:
NOTEBOOK_EDITOR_FOCUSED
});
function
getActiveNotebookEditor
(
editorService
:
IEditorService
,
notebookService
:
INotebookService
):
NotebookEditor
|
undefined
{
let
resource
=
editorService
.
activeEditor
?.
resource
;
let
editorControl
=
editorService
.
activeControl
;
let
notebookProviders
=
notebookService
.
getContributedNotebookProviders
(
resource
!
);
if
(
!
resource
||
!
editorControl
||
notebookProviders
.
length
===
0
)
{
return
;
}
let
editorViewType
=
(
editorControl
!
as
NotebookEditor
).
viewType
;
let
viewType
=
notebookProviders
[
0
].
id
;
if
(
viewType
!==
editorViewType
)
{
return
;
}
return
editorControl
!
as
NotebookEditor
;
}
src/vs/workbench/contrib/notebook/browser/notebookBrowser.ts
浏览文件 @
cef3c064
...
...
@@ -10,6 +10,9 @@ import { CodeEditorWidget } from 'vs/editor/browser/widget/codeEditorWidget';
import
{
CellViewModel
}
from
'
vs/workbench/contrib/notebook/browser/renderers/cellViewModel
'
;
import
{
OutputRenderer
}
from
'
vs/workbench/contrib/notebook/browser/output/outputRenderer
'
;
import
{
IOutput
}
from
'
vs/workbench/contrib/notebook/common/notebookCommon
'
;
import
{
RawContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
export
const
KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED
=
new
RawContextKey
<
boolean
>
(
'
notebookFindWidgetFocused
'
,
false
);
export
interface
INotebookEditor
{
viewType
:
string
|
undefined
;
...
...
src/vs/workbench/contrib/notebook/browser/notebookEditor.ts
浏览文件 @
cef3c064
...
...
@@ -28,7 +28,7 @@ import { OutputRenderer } from 'vs/workbench/contrib/notebook/browser/output/out
import
{
BackLayerWebView
}
from
'
vs/workbench/contrib/notebook/browser/renderers/backLayerWebView
'
;
import
{
CodeCellRenderer
,
MarkdownCellRenderer
,
NotebookCellListDelegate
}
from
'
vs/workbench/contrib/notebook/browser/renderers/cellRenderer
'
;
import
{
CellViewModel
}
from
'
vs/workbench/contrib/notebook/browser/renderers/cellViewModel
'
;
import
{
CELL_MARGIN
,
INotebook
,
NotebookCellsSplice
,
IOutput
,
parseCellUri
}
from
'
vs/workbench/contrib/notebook/common/notebookCommon
'
;
import
{
CELL_MARGIN
,
NotebookCellsSplice
,
IOutput
,
parseCellUri
}
from
'
vs/workbench/contrib/notebook/common/notebookCommon
'
;
import
{
IWebviewService
}
from
'
vs/workbench/contrib/webview/browser/webview
'
;
import
{
getExtraColor
}
from
'
vs/workbench/contrib/welcome/walkThrough/common/walkThroughUtils
'
;
import
{
IEditorGroup
,
IEditorGroupsService
}
from
'
vs/workbench/services/editor/common/editorGroupsService
'
;
...
...
@@ -37,6 +37,8 @@ import { IEditor } from 'vs/editor/common/editorCommon';
import
{
IResourceInput
}
from
'
vs/platform/editor/common/editor
'
;
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
NotebookCellList
}
from
'
vs/workbench/contrib/notebook/browser/notebookCellList
'
;
import
{
NotebookFindWidget
,
NotebookFindDelegate
,
CellFindMatch
}
from
'
vs/workbench/contrib/notebook/browser/notebookFindWidget
'
;
import
{
FindMatch
}
from
'
vs/editor/common/model
'
;
const
$
=
DOM
.
$
;
const
NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY
=
'
NotebookEditorViewState
'
;
...
...
@@ -107,7 +109,7 @@ class NotebookCodeEditors implements ICompositeCodeEditor {
}
}
export
class
NotebookEditor
extends
BaseEditor
implements
INotebookEditor
{
export
class
NotebookEditor
extends
BaseEditor
implements
INotebookEditor
,
NotebookFindDelegate
{
static
readonly
ID
:
string
=
'
workbench.editor.notebook
'
;
private
rootElement
!
:
HTMLElement
;
private
body
!
:
HTMLElement
;
...
...
@@ -118,7 +120,6 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
private
control
:
ICompositeCodeEditor
|
undefined
;
private
renderedEditors
:
Map
<
CellViewModel
,
ICodeEditor
|
undefined
>
=
new
Map
();
private
model
:
NotebookEditorModel
|
undefined
;
private
notebook
:
INotebook
|
undefined
;
viewType
:
string
|
undefined
;
private
viewCells
:
CellViewModel
[]
=
[];
private
localStore
:
DisposableStore
=
this
.
_register
(
new
DisposableStore
());
...
...
@@ -128,6 +129,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
private
dimension
:
DOM
.
Dimension
|
null
=
null
;
private
editorFocus
:
IContextKey
<
boolean
>
|
null
=
null
;
private
outputRenderer
:
OutputRenderer
;
private
findWidget
:
NotebookFindWidget
;
constructor
(
@
ITelemetryService
telemetryService
:
ITelemetryService
,
...
...
@@ -145,9 +147,10 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
this
.
editorMemento
=
this
.
getEditorMemento
<
INotebookEditorViewState
>
(
editorGroupService
,
NOTEBOOK_EDITOR_VIEW_STATE_PREFERENCE_KEY
);
this
.
outputRenderer
=
new
OutputRenderer
(
this
,
this
.
instantiationService
);
this
.
findWidget
=
this
.
instantiationService
.
createInstance
(
NotebookFindWidget
,
this
);
this
.
findWidget
.
updateTheme
(
this
.
themeService
.
getTheme
());
}
get
minimumWidth
():
number
{
return
375
;
}
get
maximumWidth
():
number
{
return
Number
.
POSITIVE_INFINITY
;
}
...
...
@@ -186,6 +189,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
this
.
contentWidgets
=
document
.
createElement
(
'
div
'
);
DOM
.
addClass
(
this
.
contentWidgets
,
'
notebook-content-widgets
'
);
DOM
.
append
(
this
.
body
,
this
.
contentWidgets
);
DOM
.
append
(
this
.
body
,
this
.
findWidget
.
getDomNode
());
}
private
createCellList
():
void
{
...
...
@@ -242,7 +246,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
}
onHide
()
{
this
.
editorFocus
?.
set
(
false
);
if
(
this
.
webview
)
{
this
.
localStore
.
clear
();
this
.
list
?.
rowsContainer
.
removeChild
(
this
.
webview
?.
element
);
...
...
@@ -253,9 +257,8 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
this
.
list
?.
splice
(
0
,
this
.
list
?.
length
);
if
(
this
.
model
&&
!
this
.
model
.
isDirty
())
{
this
.
notebookService
.
destoryNotebookDocument
(
this
.
viewType
!
,
this
.
notebook
!
);
this
.
notebookService
.
destoryNotebookDocument
(
this
.
viewType
!
,
this
.
model
!
.
notebook
!
);
this
.
model
=
undefined
;
this
.
notebook
=
undefined
;
this
.
viewType
=
undefined
;
}
...
...
@@ -273,6 +276,11 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
}
}
focus
()
{
super
.
focus
();
this
.
editorFocus
?.
set
(
true
);
}
setInput
(
input
:
NotebookEditorInput
,
options
:
EditorOptions
|
undefined
,
token
:
CancellationToken
):
Promise
<
void
>
{
if
(
this
.
input
instanceof
NotebookEditorInput
)
{
this
.
saveTextEditorViewState
(
this
.
input
);
...
...
@@ -306,12 +314,11 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
}));
let
viewState
=
this
.
loadTextEditorViewState
(
input
);
this
.
notebook
=
model
.
getNotebook
();
this
.
webview
.
updateRendererPreloads
(
this
.
notebook
.
renderers
);
this
.
webview
.
updateRendererPreloads
(
this
.
model
!
.
notebook
.
renderers
);
this
.
viewType
=
input
.
viewType
;
this
.
viewCells
=
await
Promise
.
all
(
this
.
notebook
!
.
cells
.
map
(
async
cell
=>
{
this
.
viewCells
=
await
Promise
.
all
(
this
.
model
!
.
notebook
!
.
cells
.
map
(
async
cell
=>
{
const
isEditing
=
viewState
&&
viewState
.
editingCells
[
cell
.
handle
];
const
viewCell
=
this
.
instantiationService
.
createInstance
(
CellViewModel
,
input
.
viewType
!
,
this
.
notebook
!
.
handle
,
cell
,
!!
isEditing
);
const
viewCell
=
this
.
instantiationService
.
createInstance
(
CellViewModel
,
input
.
viewType
!
,
this
.
model
!
.
notebook
!
.
handle
,
cell
,
!!
isEditing
);
this
.
localStore
.
add
(
viewCell
);
return
viewCell
;
}));
...
...
@@ -395,6 +402,37 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
//#endregion
//#region Find Delegate
startFind
(
value
:
string
):
CellFindMatch
[]
{
let
matches
:
CellFindMatch
[]
=
[];
this
.
viewCells
.
forEach
(
cell
=>
{
let
cellMatches
=
cell
.
startFind
(
value
);
matches
.
push
(...
cellMatches
);
});
return
matches
;
}
stopFind
(
keepSelection
?:
boolean
|
undefined
):
void
{
}
focusNext
(
match
:
CellFindMatch
)
{
let
cell
=
match
.
cell
;
let
index
=
this
.
viewCells
.
indexOf
(
cell
);
this
.
list
?.
reveal
(
index
);
}
public
showFind
()
{
this
.
findWidget
.
reveal
();
}
public
hideFind
()
{
this
.
findWidget
.
hide
();
}
//#endregion
//#region Cell operations
layoutNotebookCell
(
cell
:
CellViewModel
,
height
:
number
)
{
let
relayout
=
(
cell
:
CellViewModel
,
height
:
number
)
=>
{
...
...
@@ -413,7 +451,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
updateViewCells
(
splices
:
NotebookCellsSplice
[])
{
let
update
=
()
=>
splices
.
reverse
().
forEach
((
diff
)
=>
{
this
.
list
?.
splice
(
diff
[
0
],
diff
[
1
],
diff
[
2
].
map
(
cell
=>
{
return
this
.
instantiationService
.
createInstance
(
CellViewModel
,
this
.
viewType
!
,
this
.
notebook
!
.
handle
,
cell
,
false
);
return
this
.
instantiationService
.
createInstance
(
CellViewModel
,
this
.
viewType
!
,
this
.
model
!
.
notebook
!
.
handle
,
cell
,
false
);
}));
});
...
...
@@ -433,7 +471,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
}
async
insertEmptyNotebookCell
(
listIndex
:
number
|
undefined
,
cell
:
CellViewModel
,
type
:
'
code
'
|
'
markdown
'
,
direction
:
'
above
'
|
'
below
'
):
Promise
<
void
>
{
let
newLanguages
=
this
.
notebook
!
.
languages
;
let
newLanguages
=
this
.
model
!
.
notebook
!
.
languages
;
let
language
=
'
markdown
'
;
if
(
newLanguages
&&
newLanguages
.
length
)
{
language
=
newLanguages
[
0
];
...
...
@@ -442,8 +480,8 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
let
index
=
listIndex
?
listIndex
:
this
.
model
!
.
getNotebook
().
cells
.
indexOf
(
cell
.
cell
);
const
insertIndex
=
direction
===
'
above
'
?
index
:
index
+
1
;
let
newModeCell
=
await
this
.
notebookService
.
createNotebookCell
(
this
.
viewType
!
,
this
.
notebook
!
.
uri
,
insertIndex
,
language
,
type
);
let
newCell
=
this
.
instantiationService
.
createInstance
(
CellViewModel
,
this
.
viewType
!
,
this
.
notebook
!
.
handle
,
newModeCell
!
,
false
);
let
newModeCell
=
await
this
.
notebookService
.
createNotebookCell
(
this
.
viewType
!
,
this
.
model
!
.
notebook
!
.
uri
,
insertIndex
,
language
,
type
);
let
newCell
=
this
.
instantiationService
.
createInstance
(
CellViewModel
,
this
.
viewType
!
,
this
.
model
!
.
notebook
!
.
handle
,
newModeCell
!
,
false
);
this
.
viewCells
!
.
splice
(
insertIndex
,
0
,
newCell
);
this
.
model
!
.
insertCell
(
newCell
.
cell
,
insertIndex
);
...
...
@@ -498,8 +536,8 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
async
deleteNotebookCell
(
listIndex
:
number
|
undefined
,
cell
:
CellViewModel
):
Promise
<
void
>
{
let
index
=
this
.
model
!
.
getNotebook
().
cells
.
indexOf
(
cell
.
cell
);
// await this.notebookService.createNotebookCell(this.viewType!, this.notebook!.uri, insertIndex, language, type);
await
this
.
notebookService
.
deleteNotebookCell
(
this
.
viewType
!
,
this
.
notebook
!
.
uri
,
index
);
// await this.notebookService.createNotebookCell(this.viewType!, this.
model!.
notebook!.uri, insertIndex, language, type);
await
this
.
notebookService
.
deleteNotebookCell
(
this
.
viewType
!
,
this
.
model
!
.
notebook
!
.
uri
,
index
);
this
.
viewCells
!
.
splice
(
index
,
1
);
this
.
model
!
.
deleteCell
(
cell
.
cell
);
this
.
list
?.
splice
(
index
,
1
);
...
...
@@ -526,7 +564,7 @@ export class NotebookEditor extends BaseEditor implements INotebookEditor {
return
;
}
let
preloads
=
this
.
notebook
!
.
renderers
;
let
preloads
=
this
.
model
!
.
notebook
!
.
renderers
;
if
(
!
this
.
webview
!
.
insetMapping
.
has
(
output
))
{
let
index
=
this
.
model
!
.
getNotebook
().
cells
.
indexOf
(
cell
.
cell
);
...
...
src/vs/workbench/contrib/notebook/browser/notebookEditorInput.ts
浏览文件 @
cef3c064
...
...
@@ -18,6 +18,11 @@ export class NotebookEditorModel extends EditorModel {
private
readonly
_onDidChangeCells
=
new
Emitter
<
NotebookCellsSplice
[]
>
();
get
onDidChangeCells
():
Event
<
NotebookCellsSplice
[]
>
{
return
this
.
_onDidChangeCells
.
event
;
}
get
notebook
()
{
return
this
.
_notebook
;
}
constructor
(
private
_notebook
:
INotebook
)
{
...
...
src/vs/workbench/contrib/notebook/browser/notebookFindWidget.ts
0 → 100644
浏览文件 @
cef3c064
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
SimpleFindWidget
}
from
'
vs/workbench/contrib/codeEditor/browser/find/simpleFindWidget
'
;
import
{
IContextViewService
}
from
'
vs/platform/contextview/browser/contextView
'
;
import
{
IContextKeyService
,
IContextKey
}
from
'
vs/platform/contextkey/common/contextkey
'
;
import
{
KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED
}
from
'
vs/workbench/contrib/notebook/browser/notebookBrowser
'
;
import
{
Event
}
from
'
vs/base/common/event
'
;
import
{
CellViewModel
}
from
'
vs/workbench/contrib/notebook/browser/renderers/cellViewModel
'
;
import
{
FindMatch
}
from
'
vs/editor/common/model
'
;
export
interface
CellFindMatch
{
cell
:
CellViewModel
,
match
:
FindMatch
}
export
interface
NotebookFindDelegate
{
startFind
(
value
:
string
):
CellFindMatch
[];
stopFind
(
keepSelection
?:
boolean
):
void
;
focus
():
void
;
focusNext
(
nextMatch
:
CellFindMatch
):
void
;
}
export
class
NotebookFindWidget
extends
SimpleFindWidget
{
protected
_findWidgetFocused
:
IContextKey
<
boolean
>
;
private
_findMatches
:
CellFindMatch
[]
=
[];
private
_currentMatch
:
CellFindMatch
|
null
=
null
;
constructor
(
private
readonly
_delegate
:
NotebookFindDelegate
,
@
IContextViewService
contextViewService
:
IContextViewService
,
@
IContextKeyService
contextKeyService
:
IContextKeyService
)
{
super
(
contextViewService
,
contextKeyService
);
this
.
_findWidgetFocused
=
KEYBINDING_CONTEXT_NOTEBOOK_FIND_WIDGET_FOCUSED
.
bindTo
(
contextKeyService
);
}
protected
onInputChanged
():
boolean
{
const
val
=
this
.
inputValue
;
if
(
val
)
{
this
.
_findMatches
=
this
.
_delegate
.
startFind
(
val
);
if
(
this
.
_findMatches
.
length
)
{
this
.
_currentMatch
=
this
.
_findMatches
[
0
];
return
true
;
}
else
{
this
.
_currentMatch
=
null
;
return
false
;
}
}
else
{
this
.
_delegate
.
stopFind
(
false
);
}
return
false
;
}
protected
find
(
previous
:
boolean
):
void
{
if
(
this
.
_currentMatch
&&
this
.
_findMatches
.
length
)
{
let
len
=
this
.
_findMatches
.
length
;
let
index
=
this
.
_findMatches
.
indexOf
(
this
.
_currentMatch
);
let
nextIndex
=
previous
?
(
index
-
1
+
len
)
%
len
:
index
+
1
%
len
;
let
nextMatch
=
this
.
_findMatches
[
nextIndex
];
this
.
_delegate
.
focusNext
(
nextMatch
);
this
.
_currentMatch
=
nextMatch
;
}
return
;
}
public
hide
()
{
super
.
hide
();
this
.
_delegate
.
stopFind
(
true
);
this
.
_delegate
.
focus
();
}
protected
findFirst
():
void
{
}
protected
onFocusTrackerFocus
()
{
this
.
_findWidgetFocused
.
set
(
true
);
}
protected
onFocusTrackerBlur
()
{
this
.
_findWidgetFocused
.
reset
();
}
protected
onFindInputFocusTrackerFocus
():
void
{
}
protected
onFindInputFocusTrackerBlur
():
void
{
}
}
src/vs/workbench/contrib/notebook/browser/output/transforms/richTransform.ts
浏览文件 @
cef3c064
...
...
@@ -34,6 +34,7 @@ class RichRenderer implements IOutputTransformContribution {
this
.
_richMimeTypeRenderers
.
set
(
'
image/png
'
,
this
.
renderPNG
.
bind
(
this
));
this
.
_richMimeTypeRenderers
.
set
(
'
image/jpeg
'
,
this
.
renderJavaScript
.
bind
(
this
));
this
.
_richMimeTypeRenderers
.
set
(
'
text/plain
'
,
this
.
renderPlainText
.
bind
(
this
));
this
.
_richMimeTypeRenderers
.
set
(
'
text/x-javascript
'
,
this
.
renderCode
.
bind
(
this
));
}
render
(
output
:
any
,
container
:
HTMLElement
,
preferredMimeType
:
string
|
undefined
):
IRenderOutput
{
...
...
@@ -73,7 +74,7 @@ class RichRenderer implements IOutputTransformContribution {
let
str
=
JSON
.
stringify
(
data
,
null
,
'
\t
'
);
const
editor
=
this
.
instantiationService
.
createInstance
(
CodeEditorWidget
,
container
,
{
...
get
JSON
SimpleEditorOptions
(),
...
get
Output
SimpleEditorOptions
(),
dimension
:
{
width
:
0
,
height
:
0
...
...
@@ -103,6 +104,41 @@ class RichRenderer implements IOutputTransformContribution {
};
}
renderCode
(
output
:
any
,
container
:
HTMLElement
)
{
let
data
=
output
.
data
[
'
text/x-javascript
'
];
let
str
=
isArray
(
data
)
?
data
.
join
(
''
)
:
data
;
const
editor
=
this
.
instantiationService
.
createInstance
(
CodeEditorWidget
,
container
,
{
...
getOutputSimpleEditorOptions
(),
dimension
:
{
width
:
0
,
height
:
0
}
},
{
isSimpleWidget
:
true
});
let
mode
=
this
.
modeService
.
create
(
'
javascript
'
);
let
resource
=
URI
.
parse
(
`notebook-output-
${
Date
.
now
()}
.js`
);
const
textModel
=
this
.
modelService
.
createModel
(
str
,
mode
,
resource
,
false
);
editor
.
setModel
(
textModel
);
let
width
=
this
.
notebookEditor
.
getListDimension
()
!
.
width
;
let
fontInfo
=
this
.
notebookEditor
.
getFontInfo
();
let
height
=
Math
.
min
(
textModel
.
getLineCount
(),
16
)
*
(
fontInfo
?.
lineHeight
||
18
);
editor
.
layout
({
height
,
width
});
container
.
style
.
height
=
`
${
height
+
16
}
px`
;
return
{
hasDynamicHeight
:
true
};
}
renderJavaScript
(
output
:
any
,
container
:
HTMLElement
)
{
let
data
=
output
.
data
[
'
application/javascript
'
];
let
str
=
isArray
(
data
)
?
data
.
join
(
''
)
:
data
;
...
...
@@ -188,8 +224,9 @@ class RichRenderer implements IOutputTransformContribution {
registerOutputTransform
(
'
notebook.output.rich
'
,
[
'
display_data
'
,
'
execute_result
'
],
RichRenderer
);
export
function
get
JSON
SimpleEditorOptions
():
IEditorOptions
{
export
function
get
Output
SimpleEditorOptions
():
IEditorOptions
{
return
{
readOnly
:
true
,
wordWrap
:
'
on
'
,
overviewRulerLanes
:
0
,
glyphMargin
:
false
,
...
...
src/vs/workbench/contrib/notebook/browser/renderers/cellViewModel.ts
浏览文件 @
cef3c064
...
...
@@ -3,15 +3,19 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import
{
Emitter
,
Event
}
from
'
vs/base/common/event
'
;
import
{
Disposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
ITextModel
}
from
'
vs/editor/common/model
'
;
import
{
Emitter
}
from
'
vs/base/common/event
'
;
import
*
as
UUID
from
'
vs/base/common/uuid
'
;
import
{
MarkdownRenderer
}
from
'
vs/workbench/contrib/notebook/browser/renderers/mdRender
er
'
;
import
{
ICell
,
NotebookCellOutputsSplice
,
IOutput
}
from
'
vs/workbench/contrib/notebook/common/notebookCommon
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
ICodeEditor
}
from
'
vs/editor/browser/editorBrows
er
'
;
import
{
Range
}
from
'
vs/editor/common/core/range
'
;
import
*
as
model
from
'
vs/editor/common/model
'
;
import
{
ITextModelService
}
from
'
vs/editor/common/services/resolverService
'
;
import
{
PrefixSumComputer
}
from
'
vs/editor/common/viewModel/prefixSumComputer
'
;
import
{
IInstantiationService
}
from
'
vs/platform/instantiation/common/instantiation
'
;
import
{
CellFindMatch
}
from
'
vs/workbench/contrib/notebook/browser/notebookFindWidget
'
;
import
{
MarkdownRenderer
}
from
'
vs/workbench/contrib/notebook/browser/renderers/mdRenderer
'
;
import
{
EDITOR_BOTTOM_PADDING
,
EDITOR_TOP_PADDING
,
ICell
,
IOutput
,
NotebookCellOutputsSplice
}
from
'
vs/workbench/contrib/notebook/common/notebookCommon
'
;
import
{
SearchParams
}
from
'
vs/editor/common/model/textModelSearch
'
;
export
class
CellViewModel
extends
Disposable
{
...
...
@@ -63,7 +67,10 @@ export class CellViewModel extends Disposable {
return
this
.
_editorHeight
;
}
private
_textModel
?:
ITextModel
;
private
_textModel
?:
model
.
ITextModel
;
private
_textEditor
?:
ICodeEditor
;
private
_buffer
:
model
.
ITextBuffer
|
null
;
readonly
id
:
string
=
UUID
.
generateUuid
();
constructor
(
...
...
@@ -84,7 +91,60 @@ export class CellViewModel extends Disposable {
}
this
.
_outputCollection
=
new
Array
(
this
.
cell
.
outputs
.
length
);
this
.
_buffer
=
null
;
}
//#region Search
private
readonly
_hasFindResult
=
this
.
_register
(
new
Emitter
<
boolean
>
());
public
readonly
hasFindResult
:
Event
<
boolean
>
=
this
.
_hasFindResult
.
event
;
startFind
(
value
:
string
):
CellFindMatch
[]
{
let
cellMatches
:
model
.
FindMatch
[]
=
[];
if
(
this
.
assertTextModelAttached
())
{
cellMatches
=
this
.
_textModel
!
.
findMatches
(
value
,
false
,
false
,
false
,
null
,
false
);
}
else
{
if
(
!
this
.
_buffer
)
{
this
.
_buffer
=
this
.
cell
.
resolveTextBufferFactory
().
create
(
model
.
DefaultEndOfLine
.
LF
);
}
const
lineCount
=
this
.
_buffer
.
getLineCount
();
const
fullRange
=
new
Range
(
1
,
1
,
lineCount
,
this
.
_buffer
.
getLineLength
(
lineCount
)
+
1
);
const
searchParams
=
new
SearchParams
(
value
,
false
,
false
,
null
);
const
searchData
=
searchParams
.
parseSearchRequest
();
if
(
!
searchData
)
{
return
[];
}
cellMatches
=
this
.
_buffer
.
findMatchesLineByLine
(
fullRange
,
searchData
,
false
,
1000
);
}
return
cellMatches
.
map
(
match
=>
({
cell
:
this
,
match
:
match
}));
}
stopFind
(
keepSelection
?:
boolean
|
undefined
):
void
{
if
(
!
this
.
assertTextModelAttached
())
{
return
;
}
}
focus
():
void
{
}
assertTextModelAttached
():
boolean
{
if
(
this
.
_textModel
&&
this
.
_textEditor
&&
this
.
_textEditor
.
getModel
()
===
this
.
_textModel
)
{
return
true
;
}
return
false
;
}
//#endregion
hasDynamicHeight
()
{
if
(
this
.
_dynamicHeight
!==
null
)
{
return
false
;
...
...
@@ -118,7 +178,7 @@ export class CellViewModel extends Disposable {
return
100
;
}
else
{
return
this
.
lineCount
*
lineHeight
+
16
;
return
this
.
lineCount
*
lineHeight
+
16
+
EDITOR_TOP_PADDING
+
EDITOR_BOTTOM_PADDING
;
}
}
setText
(
strs
:
string
[])
{
...
...
@@ -132,6 +192,10 @@ export class CellViewModel extends Disposable {
}
}
getText
():
string
{
if
(
this
.
_textModel
)
{
return
this
.
_textModel
.
getValue
();
}
return
this
.
cell
.
source
.
join
(
'
\n
'
);
}
...
...
@@ -147,10 +211,11 @@ export class CellViewModel extends Disposable {
return
null
;
}
async
resolveTextModel
():
Promise
<
ITextModel
>
{
async
resolveTextModel
():
Promise
<
model
.
ITextModel
>
{
if
(
!
this
.
_textModel
)
{
const
ref
=
await
this
.
_modelService
.
createModelReference
(
this
.
cell
.
uri
);
this
.
_textModel
=
ref
.
object
.
textEditorModel
;
this
.
_buffer
=
this
.
_textModel
.
getTextBuffer
();
this
.
_register
(
ref
);
this
.
_register
(
this
.
_textModel
.
onDidChangeContent
(()
=>
{
this
.
cell
.
isDirty
=
true
;
...
...
@@ -159,6 +224,10 @@ export class CellViewModel extends Disposable {
return
this
.
_textModel
;
}
attachTextEditor
(
editor
:
ICodeEditor
)
{
this
.
_textEditor
=
editor
;
}
getMarkdownRenderer
()
{
if
(
!
this
.
_mdRenderer
)
{
this
.
_mdRenderer
=
this
.
_instaService
.
createInstance
(
MarkdownRenderer
);
...
...
src/vs/workbench/contrib/notebook/browser/renderers/codeCell.ts
浏览文件 @
cef3c064
...
...
@@ -47,8 +47,9 @@ export class CodeCell extends Disposable {
const
cts
=
new
CancellationTokenSource
();
this
.
_register
({
dispose
()
{
cts
.
dispose
(
true
);
}
});
raceCancellation
(
viewCell
.
resolveTextModel
(),
cts
.
token
).
then
(
model
=>
{
if
(
model
)
{
templateData
.
editor
?.
setModel
(
model
);
if
(
model
&&
templateData
.
editor
)
{
templateData
.
editor
.
setModel
(
model
);
viewCell
.
attachTextEditor
(
templateData
.
editor
);
let
realContentHeight
=
templateData
.
editor
?.
getContentHeight
();
let
width
:
number
;
...
...
src/vs/workbench/contrib/notebook/common/notebookCommon.ts
浏览文件 @
cef3c064
...
...
@@ -7,6 +7,7 @@ import { Event } from 'vs/base/common/event';
import
{
IDisposable
}
from
'
vs/base/common/lifecycle
'
;
import
{
URI
}
from
'
vs/base/common/uri
'
;
import
{
IRelativePattern
}
from
'
vs/base/common/glob
'
;
import
{
PieceTreeTextBufferFactory
}
from
'
vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBufferBuilder
'
;
export
const
NOTEBOOK_DISPLAY_ORDER
=
[
'
application/json
'
,
...
...
@@ -103,6 +104,7 @@ export interface ICell {
outputs
:
IOutput
[];
onDidChangeOutputs
?:
Event
<
NotebookCellOutputsSplice
[]
>
;
isDirty
:
boolean
;
resolveTextBufferFactory
():
PieceTreeTextBufferFactory
;
}
/**
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录