├── README.md ├── package.json ├── LICENSE └── index.d.ts /README.md: -------------------------------------------------------------------------------- 1 | # cloudstudio-extension 2 | 3 | 此模块提供了 Cloud Studio 插件 API 的声明文件(cloudstudio.d.ts)。通过使用此模块,你可以方便地编写并测试你的 Cloud Studio 插件。 4 | 5 | 想了解开发 CloudStudio 插件的更多信息,请参阅 [Cloud Studio 插件开发文档](https://studio.dev.tencent.com/plugins-docs/)。 6 | 7 | ## License 8 | MIT 9 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "cloudstudio-extension", 3 | "version": "1.0.4", 4 | "description": "The cloudstudio.d.ts node module", 5 | "repository": { 6 | "type": "git", 7 | "url": "git+https://github.com/Coding/cloudstudio-extension.git" 8 | }, 9 | "author": "coding", 10 | "license": "MIT", 11 | "bugs": { 12 | "url": "https://github.com/Coding/cloudstudio-extension/issues" 13 | }, 14 | "homepage": "https://github.com/Coding/cloudstudio-extension#readme" 15 | } 16 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Coding 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /index.d.ts: -------------------------------------------------------------------------------- 1 | /// 2 | 3 | declare module "cloudstudio-extension" { 4 | /** 5 | * 编辑器相关 API 6 | */ 7 | export namespace editor { 8 | /** 9 | * 编辑器参数 10 | */ 11 | interface IEditorConfig { 12 | /** 13 | * 文件路径 14 | */ 15 | path: string; 16 | /** 17 | * 编辑器 id 18 | */ 19 | id?: string; 20 | /** 21 | * 文件内容 22 | */ 23 | content: string; 24 | } 25 | 26 | interface IActiveEditor { 27 | uri: string | null; 28 | editor: monaco.editor.IStandaloneCodeEditor | null; 29 | } 30 | /** 31 | * 获取当前激活的编辑器实例 32 | * @return {monaco.editor.IStandaloneCodeEditor} monaco 编辑器实例 33 | * 34 | * **Note:** 此方法需要确保编辑器已经正确加载,在 pluginWillMount 生命周期方法中可能无法获取实例 35 | * 36 | * ```javascript 37 | * class MyComponent extends React.Component { 38 | * componentDidMount() { 39 | * const editor = Editor.getActiveEditor(); 40 | * } 41 | * } 42 | * ``` 43 | */ 44 | export function getActiveEditor(): IActiveEditor; 45 | 46 | /** 47 | * 打开一个新的编辑器 48 | * 49 | * @param {IEditorConfig} config 编辑器配置 50 | * 51 | * **Note:** 文件路径和内容为必要参数,可自定义编辑器唯一 id 52 | * 53 | * ```javascript 54 | * const path = '/src/index.js'; 55 | * File.getFileContent(path) 56 | * .then((data) => { 57 | * const { content } = data; 58 | * openNewEditor({ path, content, id: `editor_${path}` }); 59 | * }); 60 | * ``` 61 | */ 62 | export function openNewEditor(config: IEditorConfig): void; 63 | 64 | interface ILangImpl { 65 | conf: monaco.languages.LanguageConfiguration; 66 | language: monaco.languages.IMonarchLanguage; 67 | } 68 | 69 | interface ILang extends monaco.languages.ILanguageExtensionPoint { 70 | loader: () => monaco.Promise; 71 | } 72 | 73 | interface ILanguageConfig { 74 | contribution: ILang; 75 | } 76 | /** 77 | * 注册自定义语言 78 | * @param {ILanguageConfig} languageConf 自定义语言配置 79 | * 80 | * **Note:** 向 monaco 编辑器注册自定义语言的语法高亮,如插件类型为语法高亮,则只需在 `pluginWillMount` 生命周期中调用此方法 81 | * 82 | * monaco 的语法高亮基于 monarch 实现,这是一个声明式的词法规范(JSON 格式),具有很强的表现力,可以指定复杂的状态转换,动态括号匹配,自动完成等语法细节。 83 | * monarch 规范具体细节可以前往 https://microsoft.github.io/monaco-editor/monarch.html 查看 84 | * 此方法相关参数及具体用法可以参考 https://github.com/Microsoft/monaco-languages 仓库中的其他语言实现 85 | * 86 | * ```javascript 87 | * // 定义编辑器在该语言下的括号匹配规则、注释及自动缩进等配置 88 | * const myLanguageConf = { 89 | * wordPattern: /(-?\d*\.\d\w*)|([^\`\~\!\#\%\^\&\*\(\)\-\=\+\[\{\]\}\\\|\;\:\'\"\,\.\<\>\/\?\s]+)/g, 90 | * comments: { 91 | * lineComment: "//", 92 | * blockComment: ["*", "*\\"] 93 | * }, 94 | * brackets: [["{", "}"], ["[", "]"], ["(", ")"]], 95 | * autoClosingPairs: [ 96 | * { open: "{", close: "}" }, 97 | * { open: "[", close: "]" }, 98 | * { open: "(", close: ")" }, 99 | * { open: '"', close: '"' }, 100 | * { open: "'", close: "'" } 101 | * ], 102 | * surroundingPairs: [ 103 | * { open: "{", close: "}" }, 104 | * { open: "[", close: "]" }, 105 | * { open: "(", close: ")" }, 106 | * { open: '"', close: '"' }, 107 | * { open: "'", close: "'" }, 108 | * { open: "<", close: ">" } 109 | * ] 110 | * }; 111 | * const myLanguage = { 112 | * defaultToken: "", 113 | * tokenPostfix: ".ml", 114 | * keywords: [ 115 | * "class", 116 | * "break", 117 | * "func", 118 | * "switch", 119 | * "continue", 120 | * "extends", 121 | * "interface", 122 | * "type" 123 | * ] 124 | * }; 125 | * const languageContribution = { 126 | * id: "myLanguage", // 自定义语言名 127 | * extensions: [".ml"], // 自定语言文件扩展名,支持多个扩展名 128 | * aliases: ["myLang", "ml"], // 自定义语言别名,支持多个别名 129 | * loader: () => monaco.Promise.wrap({ language: myLanguage, conf: myLanguageConf }) // 语法高亮配置 130 | * }; 131 | * registerLanguage({ contribution: languageContribution }); 132 | * ``` 133 | */ 134 | export function registerLanguage(languageConf: ILanguageConfig): void; 135 | 136 | interface IEditorViewConfig { 137 | contentTypes?: Array, 138 | extensions?: Array, 139 | } 140 | /** 141 | * 注册自定义编辑器 142 | * @param editor 需要注册的编辑器组件 143 | * @param config 配置对象,设置拦截条件。contentTypes 是文件类型集合,比如 ['image/png', 'image/webp'],extensions 是文件后缀集合,比如 ['js', 'jsx', 'vue'] 144 | */ 145 | export function registerEditorView( 146 | editor: any, 147 | config: IEditorViewConfig, 148 | ): any 149 | 150 | interface IContentProvider { 151 | name: string; 152 | [propName: string]: any; 153 | } 154 | 155 | interface IContentProviderDetail { 156 | editorType: string; 157 | activate: (editorType: string, title: string) => string; 158 | dispose: (tabId) => void; 159 | } 160 | /** 161 | * 注册 Content Provider 162 | * @param component 需要注册的编辑器视图组件 163 | * @param {IContentProvider} conf 视图配置,name 为必传项 164 | * @return {IContentProviderDetail} 编辑器视图类型及打开/关闭方法 165 | * 166 | * **Note:** 此方法并不是自定义一个编辑器类型,虽然你可以用它来注册一个自定义的编辑器 167 | * 168 | * 准确说这个方法允许你在编辑器区域注册一个自定义的视图组件,用来显示一些内容 169 | * 例如你可以注册一个 Git Diff 视图,展示某个文件不同版本的对比差异(可以借助 Git 模块相应的 API 来实现这个功能) 170 | */ 171 | export function registerContentProvider( 172 | component: any, 173 | conf: IContentProvider 174 | ): IContentProviderDetail; 175 | 176 | interface IColor { 177 | [propName: string]: string; 178 | } 179 | interface ITokenColorSettings { 180 | fontStyle?: string; 181 | foreground?: string; 182 | background?: string; 183 | [propName: string]: any; 184 | } 185 | /** 186 | * 指定标记颜色 187 | */ 188 | interface ITokenColor { 189 | name?: string | any[]; 190 | scope?: Array | string; 191 | settings?: ITokenColorSettings; 192 | } 193 | export interface IThemeDefine { 194 | colors: IColor; 195 | tokenColors: ITokenColor[]; 196 | [propName: string]: any; 197 | } 198 | /** 199 | * 自定义主题配置 200 | * @param name 主题名 201 | * @param {IThemeDefine} theme 主题配置信息 202 | * @return named 注册功能的主题名称 203 | * 204 | * 此方法允许你自定义一个语法高亮主题,这个主题只会应用于编辑器部分,无法影响界面其他组件主题 205 | * 自定义主题配置应当至少包含一个 colors 和一个 tokenColors 206 | * 可以参考 https://github.com/Binaryify/OneDark-Pro 来学习如何自定义主题配色 207 | */ 208 | export function defineTheme(name: string, theme: IThemeDefine): string; 209 | 210 | type IEditorDidMountHandler = (editor: monaco.editor.IStandaloneCodeEditor) => void; 211 | /** 212 | * 注册编辑器实例被创建时的回调函数 213 | * 214 | * @param {IEditorDidMountHandler} fn 回调函数 215 | * @return dispose 清除函数 216 | * ```javascript 217 | * const dispose = Editor.registerEditorDidMountHandler((editor) => { 218 | * // editor 219 | * }); 220 | * ``` 221 | */ 222 | export function registerEditorDidMountHandler( 223 | fn: IEditorDidMountHandler 224 | ): IDisposable; 225 | 226 | interface IEditorActiveArgs { 227 | uri: string; 228 | editor: monaco.editor.IStandaloneCodeEditor; 229 | } 230 | type IEditorActiveHandler = (arg: IEditorActiveArgs) => void; 231 | 232 | /** 233 | * 注册活动编辑器被改变时的回调函数 234 | * @param {IEditorActiveHandler} fn 回调函数 235 | * @return {IDisposable} dispose 清除函数 236 | */ 237 | export function registerActiveEditorChangeHandler( 238 | fn: IEditorActiveHandler 239 | ): IDisposable; 240 | 241 | /** 242 | * 代码片段自动完成种类 243 | */ 244 | export enum SnippetsItemKind { 245 | /** 246 | * 文本 247 | */ 248 | Text = 0, 249 | /** 250 | * 方法 251 | */ 252 | Method = 1, 253 | /** 254 | * 函数 255 | */ 256 | Function = 2, 257 | /** 258 | * 构造函数 259 | */ 260 | Constructor = 3, 261 | /** 262 | * 成员属性 263 | */ 264 | Field = 4, 265 | /** 266 | * 变量 267 | */ 268 | Variable = 5, 269 | /** 270 | * 类 271 | */ 272 | Class = 6, 273 | /** 274 | * 接口 275 | */ 276 | Interface = 7, 277 | /** 278 | * 模块 279 | */ 280 | Module = 8, 281 | /** 282 | * 属性 283 | */ 284 | Property = 9, 285 | /** 286 | * 单元 287 | */ 288 | Unit = 10, 289 | /** 290 | * 值 291 | */ 292 | Value = 11, 293 | /** 294 | * 枚举 295 | */ 296 | Enum = 12, 297 | /** 298 | * 关键字 299 | */ 300 | Keyword = 13, 301 | /** 302 | * 片段 303 | */ 304 | Snippet = 14, 305 | /** 306 | * 颜色 307 | */ 308 | Color = 15, 309 | /** 310 | * 文件 311 | */ 312 | File = 16, 313 | /** 314 | * 引用 315 | */ 316 | Reference = 17, 317 | /** 318 | * 文件夹 319 | */ 320 | Folder = 18 321 | } 322 | interface ISnippetsString { 323 | value: string; 324 | } 325 | 326 | type SnippetsItemKindType = SnippetsItemKind 327 | /** 328 | * 代码片段实体 329 | */ 330 | interface ISnippets { 331 | /** 332 | * 触发自动完成提示的字符 333 | */ 334 | label: string; 335 | /** 336 | * 代码片段文档,描述这段代码的作用 337 | */ 338 | documentation?: string; 339 | /** 340 | * 将会插入的代码片段 341 | */ 342 | insertText: ISnippetsString; 343 | /** 344 | * 指代这段代码的类型,提供了18种可选类型,这将会在自动完成提示框内显示不同的图标 345 | */ 346 | kind?: SnippetsItemKindType; 347 | } 348 | interface ISnippetsProvirder { 349 | (): Array; 350 | } 351 | /** 352 | * 注册自动完成代码片段 353 | * @param {Array | string} languages 指定的语言 354 | * @param {ISnippetsProvirder | Array} snippetsProvider 自动完成提供者 355 | * 356 | * 在指定语言的编辑器中提供可以自动完成的代码片段 357 | * 358 | * ```javascript 359 | * Editor.registerCodeSnippetsProvider(['javascript', 'typescript'], () => { 360 | * return [ 361 | * { 362 | * label: 'react', 363 | * documention: '生成一个 React 组件', 364 | * insertText: { 365 | * value: 'import React, { PureComponent } from 'react';\n\nclass ${0:componentName} extends PureComponent {\n\n}\n\nexport default ${0:componentName};' 366 | * }, 367 | * kind: SnippetsItemKind.Class 368 | * } 369 | * ] 370 | * }); 371 | * ``` 372 | * 这段代码将会注册一个名为 react 的代码片段,在编辑器中输入 react ,会出现自动完成列表,按下 `Tab` 键将生成一段模板代码 373 | * 374 | * ```javascript 375 | * import React, { PureComponent } from 'react'; 376 | * 377 | * 378 | * class ${0:componentName} extends PureComponent { 379 | * 380 | * } 381 | * 382 | * export default ${0:componentName}; 383 | * 384 | * ``` 385 | * 386 | * 注意其中语法类似于 es6 模板字符串的部分,代码片段中包含 ${number:string} 插入点,即表示生成代码片段后光标会自动聚焦在此处,如果有多个相同的片段,则光标会同时聚焦在多个位置 387 | * 其中 `:` 前的数字表示光标聚焦的次序,从0开始,按下 Tab 键光标会跳转到下一个插入点。 388 | * 冒号后面的字符为可选参数,光标聚焦之后会自动被选中,用于描述此处需要输入的值。 389 | */ 390 | export function registerCodeSnippetsProvider( 391 | languages: Array | string, 392 | snippetsProvider: ISnippetsProvirder | Array 393 | ): monaco.IDisposable[]; 394 | } 395 | 396 | /** 397 | * Modal 模态框 398 | */ 399 | export namespace modal { 400 | /** 401 | * 注册一个模态框 402 | * @param {string} name 模态框名称 403 | * @param component 模态框组件 404 | * @param {string} command 打开模态框命令 405 | * 406 | * 第三个参数 command 可以调用 Command 模块中的 executeCommand 方法来弹出模态框 407 | */ 408 | export function modalRegister( 409 | name: string, 410 | component: any, 411 | command: string 412 | ): void; 413 | 414 | /** 415 | * 模态框位置参数 416 | */ 417 | enum IModalPosition { 418 | /** 419 | * 顶部 420 | */ 421 | top = "top", 422 | /** 423 | * 底部 424 | */ 425 | bottom = "bottom", 426 | /** 427 | * 中间 428 | */ 429 | center = "center" 430 | } 431 | /** 432 | * 模态框选项 433 | */ 434 | interface IModalShowConf { 435 | /** 436 | * 模态框类型,等同于模态框名称 437 | */ 438 | type: string; 439 | position?: IModalPosition; 440 | otherProps?: any; 441 | } 442 | /** 443 | * @param config 弹出模态框基本参数 444 | * 445 | * **Note:** 如不传入 position 参数,则默认在顶部弹出 446 | */ 447 | export function showModal(config: IModalShowConf): void; 448 | } 449 | 450 | /** 451 | * Git 相关操作 API 452 | * 453 | * **Note:** 此模块下方法调用时需要确保项目已经绑定远端仓库 454 | */ 455 | export namespace git { 456 | interface IFileLogsConfig { 457 | filePath: string; 458 | page?: number; 459 | } 460 | 461 | interface IGitAuthor { 462 | name: string; 463 | emailAddress: string; 464 | when: number; 465 | } 466 | 467 | interface IGitLog { 468 | id: string; 469 | author: IGitAuthor; 470 | date: Date; 471 | message: string; 472 | parentIds: Array; 473 | } 474 | 475 | /** 476 | * 获取指定文件的 Git 提交日志 477 | * @param {IFileLogsConfig} config 文件路径及返回页码 478 | * @return {Promise | null>} gitLog 该文件 Git 提交日志 479 | */ 480 | export function gitFileLogs( 481 | config: IFileLogsConfig 482 | ): Promise | null>; 483 | 484 | interface IGitRef { 485 | id: string; 486 | name: string; 487 | } 488 | /** 489 | * 获取项目的所有 GitRefs 490 | * 491 | * 查看 https://git-scm.com/book/zh/v2/Git-%E5%86%85%E9%83%A8%E5%8E%9F%E7%90%86-Git-%E5%BC%95%E7%94%A8 了解 GitRefs 细节 492 | * @return {Promise | null>} gitRef 项目 GitRefs 493 | */ 494 | export function gitRefs(): Promise | null>; 495 | 496 | interface IFileContentParams { 497 | filePath: string; 498 | ref: string; 499 | } 500 | interface IFileContent { 501 | base64: boolean; 502 | content: string; 503 | filePath: string; 504 | } 505 | /** 506 | * 获取文件在指定 commitId 的文本内容 507 | * 508 | * @param {IFileContentParams} params 指定文件及 commitId 509 | * @return {Promise} fileContent 文件内容 510 | * 511 | * 通过调用 gitFileLogs 方法先获取所有提交记录 512 | */ 513 | export function gitFileContentWithRef( 514 | params: IFileContentParams 515 | ): Promise; 516 | 517 | interface IFileDiffParams { 518 | filePath: string; 519 | oldRef: string; 520 | newRef: string; 521 | } 522 | interface IFileDiff { 523 | diff: string; 524 | } 525 | /** 526 | * 获取文件在新/旧 commitId 下的文本 diff 527 | * 528 | * @param {IFileDiffParams} params 文件路径及新旧 commitId 529 | * @return {Promise} 文件原始 diff 信息 530 | * 531 | * 此方法的返回值与在终端执行 git diff 命令的格式相同 532 | */ 533 | export function gitFileDiffWithRef( 534 | params: IFileDiffParams 535 | ): Promise; 536 | 537 | interface ICommitDiffParams { 538 | rev: string; 539 | } 540 | 541 | /** 542 | * 文件状态 543 | */ 544 | enum ChangeType { 545 | ADD = "ADD", 546 | COPY = "COPY", 547 | DELETE = "DELETE", 548 | MODIFY = "MODIFY", 549 | RENAME = "RENAME" 550 | } 551 | 552 | interface ICommitDiff { 553 | changeType: ChangeType; 554 | newPath: string; 555 | oldPath: string; 556 | } 557 | /** 558 | * 获取指定 Ref 下项目中的提交差异列表 559 | * 560 | * @param {ICommitDiffParams} params 指定 Ref 561 | * 562 | * 可以调用 gitRefs 获取项目所有 GitRefs 563 | */ 564 | export function gitCommitDiff( 565 | params: ICommitDiffParams 566 | ): Promise>; 567 | 568 | interface IGitBlame { 569 | author: IGitAuthor; 570 | shortName: string; 571 | when: number; 572 | } 573 | /** 574 | * 获取指定文件的 GitBlame 575 | * 576 | * @param {string} filePath 文件路径 577 | * @return {Promise>} gitBlame 578 | * 579 | * 查看 https://git-scm.com/docs/git-blame 了解 GitBlame 具体细节 580 | */ 581 | export function gitBlame(filePath: string): Promise>; 582 | } 583 | 584 | export namespace terminal { 585 | /** 586 | * 一个终端实例 587 | */ 588 | interface ITerminal { 589 | /** 590 | * 终端名 591 | */ 592 | name: string; 593 | /** 594 | * 向终端中写入命令,这会自动执行命令 595 | * @param text 命令 596 | */ 597 | sendText(text: string): void; 598 | /** 599 | * 将当前终端设为活动终端 600 | */ 601 | active(): void; 602 | /** 603 | * 退出终端,这将断开终端会话,并销毁终端实例 604 | */ 605 | exit(): void; 606 | } 607 | /** 608 | * 当一个终端被打开时的回调函数 609 | */ 610 | 611 | type ITerminalOpenFn = (terminal: ITerminal) => void; 612 | /** 613 | * 注册终端打开事件回调函数 614 | * 615 | * @param {ITerminalOpenFn} fn 回调函数 616 | * @return {ITerminalOpenDispose} disposable 取消回调函数 617 | * 618 | * 新建一个终端实例后会被自动调用 619 | * 620 | * ```javascript 621 | * const dispose = Terminal.regiserTerminalOpenHandler((terminal) => { 622 | * terminal.emit('data', ['npm', 'install']) 623 | * }); 624 | * ``` 625 | */ 626 | export function registerTerminalOpenHandler( 627 | fn: ITerminalOpenFn 628 | ): IDisposable; 629 | 630 | /** 631 | * 创建一个新的终端 632 | * 633 | * @param {string} id 唯一 id 634 | * @param {string} shellpath 终端默认启动目录 635 | * @return {Promise} terminal 新建的终端 636 | * ```javascript 637 | * Terminal.createTerminal('my-terminal', '/home/coding/workspace/java') 638 | * .then(term => term.sendText('npm install')) 639 | * ``` 640 | */ 641 | export function createTerminal(id: string, shellPath?: string): Promise; 642 | } 643 | /** 644 | * 文件操作 API 645 | */ 646 | export namespace file { 647 | 648 | type IHandler = (IFileNode) => void; 649 | /** 650 | * 一个文件节点 651 | */ 652 | interface IFileNode { 653 | /** 654 | * 文件路径(相对) 655 | */ 656 | path: string; 657 | /** 658 | * 文件类型 659 | */ 660 | contentType: string; 661 | /** 662 | * 文件内容 663 | */ 664 | content: string; 665 | /** 666 | * 是否为文件夹 667 | */ 668 | isDir: boolean; 669 | /** 670 | * 是否已同步 671 | */ 672 | isSynced: boolean; 673 | /** 674 | * 文件的 Git 状态 675 | */ 676 | gitStatus: string; 677 | /** 678 | * 文件大小 679 | */ 680 | size: number; 681 | /** 682 | * 是否正在加载 683 | */ 684 | isEditorLoading: boolean; 685 | /** 686 | * 文件名 687 | */ 688 | _name: any; 689 | /** 690 | * 文件名 691 | */ 692 | name: string; 693 | /** 694 | * 文件 Id 695 | */ 696 | id: string; 697 | /** 698 | * 是否为根目录 699 | */ 700 | isRoot: boolean; 701 | /** 702 | * 文件所在目录层级 703 | */ 704 | depth: number; 705 | /** 706 | * 文件父节点 707 | */ 708 | parent: IFileNode; 709 | /** 710 | * 文件夹所哟子节点 711 | */ 712 | children: Array; 713 | /** 714 | * 兄弟节点 715 | */ 716 | siblings: Array; 717 | /** 718 | * 第一个子节点 719 | */ 720 | firstChild: IFileNode; 721 | /** 722 | * 最后一个子节点 723 | */ 724 | lastChild: IFileNode; 725 | /** 726 | * 上一个节点 727 | */ 728 | prev: IFileNode; 729 | /** 730 | * 下一个节点 731 | */ 732 | next: IFileNode; 733 | /** 734 | * 遍历文件节点 735 | */ 736 | forEachDescendant: (handler: IHandler) => void; 737 | } 738 | 739 | // 打开文件创建弹窗 740 | export function openCreateFileModal(): void; 741 | 742 | /** 743 | * 获取指定路径的文件 FileNode 实例 744 | * 745 | * @param {string} filePath 文件路径 746 | * @return {Promise} 文件 FileNode 实例 747 | */ 748 | export function getFileNode(filePath: string): IFileNode; 749 | 750 | /** 751 | * 获取指定路径的文件内容 752 | * @param {string} filePath 文件路径 753 | * @returns {Promise} 文件内容 754 | */ 755 | export function getFileContent(filePath: string): Promise; 756 | 757 | type LanguageDetail = { 758 | id: string; 759 | [propName: string]: any; 760 | } 761 | export function findLanguageByextension(ext: string): LanguageDetail 762 | interface IFileNodeCreatedFn { 763 | (IFileNode): void; 764 | } 765 | /** 766 | * 注册 FileNode 创建时的回调函数 767 | * 768 | * @param {IFileNodeCreatedFn} fn 回调函数 769 | * 770 | * FileNode 是 CS 中文件的基本结构,当文件被新建或是获取到项目中文件列表后都会触发此回调函数 771 | * 可以获取到创建的 FileNode 772 | */ 773 | export function onDidFileNodeCreated(fn: IFileNodeCreatedFn): void; 774 | 775 | interface IIcons { 776 | [propName: string]: string; 777 | } 778 | 779 | type IDidFileOpenFn = (fileNode: IFileNode) => void; 780 | 781 | export function onDidFileOpen (fn: IDidFileOpenFn): IDisposable; 782 | /** 783 | * 具体文件及文件扩展名的图标映射 784 | * 例如指定 785 | * 786 | * ```javascript 787 | * { 788 | * name: 'javascript', 789 | * fileExtendsions: ['js', 'jsx', 'mjs'], 790 | * fileNames: ['index.js', 'main.js'], 791 | * } 792 | * ``` 793 | * 则表示文件扩展名为 `js`、`jsx`、`mjs`或者文件名为 `index.js`、`main.js` 时使用 `javascript.svg` 作为图标 794 | */ 795 | interface IFileIconMapping { 796 | /** 797 | * 图标名(应当与 icons 目录下的图标文件同名) 798 | */ 799 | name: string; 800 | /** 801 | * 文件扩展类型 802 | */ 803 | fileExtensions?: Array; 804 | /** 805 | * 文件名 806 | */ 807 | fileNames?: Array; 808 | } 809 | /** 810 | * 具体文件夹图标映射 811 | * 例如指定 812 | * 813 | * ```javascript 814 | * { 815 | * name: 'redux-action', 816 | * folderNames: ['actions'] 817 | * } 818 | * ``` 819 | * 表示如果文件夹名为 `actions`,则使用 `folder-redux-action.svg` 和 `folder-redux-action-open.svg` 作为展开/闭合状态的图标 820 | */ 821 | interface IFolderIconMapping { 822 | name: string; 823 | folderNames: Array; 824 | } 825 | interface IFileNodeIcons { 826 | /** 827 | * 默认图标 828 | */ 829 | defaultIcon: string; 830 | icons: Array; 831 | } 832 | /** 833 | * 文件图标配置 834 | */ 835 | interface IFileIcon { 836 | /** 837 | * 文件映射 838 | */ 839 | fileicons: IFileNodeIcons; 840 | /** 841 | * 文件夹映射 842 | */ 843 | foldericons: IFileNodeIcons; 844 | /** 845 | * 所有图标 846 | */ 847 | icons: IIcons; 848 | } 849 | /** 850 | * 文件图标提供者 851 | */ 852 | interface IFileIconProvider { 853 | (): IFileIcon; 854 | } 855 | /** 856 | * 注册自定义文件图标主题 857 | * 858 | * @param {string} name 主题名称 859 | * @param {IFileIconProvider} provider 主题图标映射 860 | * 861 | * 主题图标注册成功后可在 CS 设置->样式->文件图标进行设置 862 | * 仅支持转换为 base64 字符串的 svg 图标,图标文件应放在 src/icons 目录下 863 | * 图标可分为文件图标与文件夹图标两类,其中文件夹图标建议包含展开/闭合两种状态 864 | * 文件夹图标文件名以 `folder` 开始,例如 `folder-javascript` 对应的展开图标文件名为 `folder-javascript-open` 865 | * 点击查看[文件图标主图插件示例](https://coding.net/u/codingide/p/CloudStudio-Plugin-FileIcon) 866 | * 867 | * ```javascript 868 | * file.registerFileIconProvider('material-ui-icons', () => { 869 | * return { 870 | * icons: { 871 | * // icons 文件夹下导出的所有图标文件 872 | * }, 873 | * fileicons: { 874 | * defaultIcon: 'doc', 875 | * icons: [ 876 | * { 877 | * name: 'javascript', 878 | * fileExtendsions: ['js', 'jsx', 'mjs'], 879 | * fileNames: ['index.js', 'main.js'], 880 | * }, 881 | * { 882 | * name: 'css', 883 | * fileExtendsions: ['css'], 884 | * } 885 | * ] 886 | * }, 887 | * foldericons: { 888 | * defaultIcon: 'folder', 889 | * icons: [ 890 | * { 891 | * name: 'folder-android', 892 | * folderNames: ['android'], 893 | * }, 894 | * { 895 | * name: 'folder-src', 896 | * folderNames: ['src', 'resource'] 897 | * }, 898 | * { 899 | * name: 'folder-config', 900 | * folderNames: ['config', 'configuration'] 901 | * } 902 | * ] 903 | * } 904 | * } 905 | * }) 906 | * ``` 907 | */ 908 | export function registerFileIconProvider(name: string, provider: IFileIconProvider); 909 | } 910 | 911 | /** 912 | * 菜单模块 913 | */ 914 | export namespace menu { 915 | interface IMenuItem { 916 | key: string; // 菜单项的唯一 key 917 | name: string | any; // 菜单显示名称 918 | command: string; // 点击菜单项触发的命令,可以通过 Command 模块的 registerCommand 方法注册命令 919 | icon?: string; // 菜单项左侧需显示的 icon ,支持 fontawesome 的 icon 920 | items?: Array; // 子项 921 | showMore?: boolean; // 是否需要在菜单项名称右侧显示 ...,这表示点击菜单后需要后续操作,例如会弹出模态框 922 | } 923 | /** 924 | * 注册一个新的菜单或在已有菜单中注册子项 925 | * @param {IMenuItem} menuItem 菜单项 926 | * @param {striung} target 注入位置 927 | * 928 | * 目前 CS 仅支持在顶部菜单栏注入新的菜单项,target 表示注入菜单项的位置,你可以注入一个新的菜单,也可以作为子项注入到其他已存在的菜单项中 929 | * 例如:窗口菜单的 key 为 'window',target 参数写作 'window',这会把你的自定义菜单作为窗口菜单的子项插入 930 | * target 为空或空字符串,会作为新菜单项插入到顶部菜单右侧 931 | */ 932 | export function registerMenu( 933 | menuItem: Array | IMenuItem, 934 | target?: string 935 | ): void; 936 | } 937 | 938 | /** 939 | * 命令模块 940 | */ 941 | export namespace command { 942 | interface ICommandHandlerArg { 943 | context: any; 944 | data: any; 945 | type: string; 946 | } 947 | interface ICommandHandler { 948 | (arg: ICommandHandlerArg): any; 949 | } 950 | /** 951 | * 注册一个命令 952 | * @param {string} commandType 命令名称 953 | * @param {handler} 命令回调函数 954 | * 955 | * 命令注册成功后会在 CS 全局可用,建议命令名以 '模块.具体操作' 格式注册,例如 'Editor.Close' 956 | */ 957 | export function registerCommand( 958 | commandType: string, 959 | handler: ICommandHandler 960 | ): IDisposable; 961 | 962 | /** 963 | * 手动触发一个已注册的命令 964 | * @param {string} commandType 命令名称 965 | * @param payload 命令参数,会传入到注册的命令回调函数中 966 | * 967 | * ```javascript 968 | * registerCommand('Git.Commit', (commitMessage) => { 969 | * // ... 970 | * }); 971 | * 972 | * const CommitBtn = (props) => { 973 | *
974 | * 977 | *
978 | * } 979 | * ``` 980 | */ 981 | export function executeCommand(commandType: string, payload?: any): void; 982 | 983 | /** 984 | * 一个组合键实例 985 | */ 986 | interface IKeyMaps { 987 | /** 988 | * 按下组合键后触发的命令 989 | */ 990 | command: string; 991 | /** 992 | * mac os键位 993 | */ 994 | mac: string; 995 | /** 996 | * windows 键位 997 | */ 998 | win: string; 999 | /** 1000 | * 名称 1001 | */ 1002 | label: any; 1003 | } 1004 | interface IKeyBinding { 1005 | /** 1006 | * 组合名 1007 | */ 1008 | name: string; 1009 | keymaps: Array; 1010 | } 1011 | /** 1012 | * 注册快捷键组合 1013 | * 1014 | * @param {IKeyBinding} keyBindings 快捷键组合 1015 | * @return {IDisposable} 清除快捷键 1016 | * 1017 | * **Note:** 快捷键只能用于手动触发 registerCommand 函数注册的命令 1018 | * 1019 | * 例如 'ctrl+c' 表示一个快捷键组合 1020 | * 如果组合键已被占用将无法注册,可在 CS 设置面板->快捷键查看已注册的插件快捷键和系统快捷键 1021 | * 1022 | * 目前暂不支持修改已注册的快捷键 1023 | */ 1024 | export function registerKeyBindings(keyBindings: IKeyBinding): IDisposable; 1025 | } 1026 | 1027 | /** 1028 | * 窗口相关方法 1029 | */ 1030 | export namespace actions { 1031 | interface INotify { 1032 | notifyType: "ERROR" | "INFO"; 1033 | message: any; 1034 | } 1035 | /** 1036 | * 弹出一个通知 1037 | * @param {INotify} notify 通知 1038 | * 1039 | * 此方法需要传入通知类型,目前支持 ERROR 和 INFO 1040 | */ 1041 | export function notification(notify: INotify): void; 1042 | 1043 | /** 1044 | * 弹出一个错误通知 1045 | * @param {string} message 通知消息 1046 | */ 1047 | export function errorNotify(message: string | object): void; 1048 | 1049 | /** 1050 | * 弹出一个默认通知 1051 | * @param {string} message 通知消息 1052 | */ 1053 | export function infoNotify(message: string | object): void; 1054 | 1055 | /** 1056 | * 在左下角状态栏显示一条消息,不传入 hideAfterTimeout 默认 3000 ms 后自动隐藏消息 1057 | * 1058 | * @param {string} text 要显示的消息 1059 | * @param {number} hideAfterTimeout 显示时间,单位 ms 1060 | * @return {IStatusBarMsgDispose} 清除函数,调用后立即隐藏消息 1061 | * 1062 | * ```javascript 1063 | * const dipose = actions.setStatusBarMessage('一条调皮的状态消息', 10000); 1064 | * setTimeout(() => { 1065 | * dipose(); 1066 | * }, 2000) 1067 | * ``` 1068 | */ 1069 | export function setStatusBarMessage( 1070 | text: string, 1071 | hideAfterTimeout: number | Promise 1072 | ): IDisposable; 1073 | 1074 | /** 1075 | * 在左下角状态栏显示一条消息,不传入 hideWhenDone 默认 3000 ms 后自动隐藏消息 1076 | * 1077 | * @param {string} text 要显示的消息 1078 | * @param {number} hideWhenDone Promise 执行完毕自动隐藏消息 1079 | * @return {IStatusBarMsgDispose} 清除函数,调用后立即隐藏消息 1080 | * 1081 | * ```javascript 1082 | * const task = new Promise((resolve, reject) => { 1083 | * setTimeout(() => { 1084 | * resolve() 1085 | * }, 5000) 1086 | * }); 1087 | * 1088 | * const dispose = actions.setStatusBarMessage('第二条调皮的消息', task); 1089 | * ``` 1090 | */ 1091 | export function setStatusBarMessage( 1092 | text: string, 1093 | hideWhenDone: Promise 1094 | ): IDisposable; 1095 | } 1096 | 1097 | /** 1098 | * 插件注册相关 1099 | */ 1100 | interface IInjectLabel { 1101 | [propName: string]: any; 1102 | } 1103 | 1104 | interface IComponentGetter { 1105 | (extensions: any): any; 1106 | } 1107 | 1108 | interface IPluginChildren { 1109 | position: string; 1110 | key: string; 1111 | label: any; 1112 | view: any; 1113 | } 1114 | 1115 | type IAppRegisterCallBackFn = (...args: Array) => any; 1116 | 1117 | type IAppUnRegisterCallBackFn = IAppRegisterCallBackFn; 1118 | 1119 | type IPluginRegisterFn = (children: IPluginChildren, callback: IAppRegisterCallBackFn) => void; 1120 | 1121 | /** 1122 | * 组件注入方法 1123 | */ 1124 | interface IInjectFn { 1125 | ( 1126 | /** 1127 | * 位置 1128 | */ 1129 | position: string, 1130 | /** 1131 | * 显示标签 1132 | */ 1133 | label: IInjectLabel, 1134 | /** 1135 | * 返回组件的回调函数 1136 | */ 1137 | getComponent: IComponentGetter, 1138 | /** 1139 | * 注入组件后的回调函数 1140 | */ 1141 | callback?: IAppRegisterCallBackFn 1142 | ): IPluginRegisterFn; 1143 | } 1144 | 1145 | /** 1146 | * 卸载插件 1147 | */ 1148 | type IPluginUnRegisterFn = (children: any, callback?: IAppUnRegisterCallBackFn) => void; 1149 | 1150 | /** 1151 | * 菜单栏注入点 1152 | */ 1153 | interface IMENUBAR { 1154 | // 插件将在菜单栏右侧以 widget 形式显示 1155 | WIDGET: string; 1156 | } 1157 | 1158 | /** 1159 | * 侧边栏注入点 1160 | */ 1161 | interface ISIDEBAR { 1162 | // 右侧边栏 1163 | RIGHT: string; 1164 | // 左侧边栏 1165 | LEFT: string; 1166 | // 下边栏 1167 | BOTTOM: string; 1168 | } 1169 | 1170 | /** 1171 | * 顶部面包屑导航 1172 | */ 1173 | interface ITOPBAR { 1174 | // 右侧以 widget 形式显示 1175 | WIDGET: string; 1176 | } 1177 | 1178 | interface ICONTAINERS { 1179 | UTILITIES: string; 1180 | } 1181 | 1182 | interface ISTATUSBAR { 1183 | WIDGET: string; 1184 | } 1185 | 1186 | interface IEDITOR { 1187 | CENTER: string; 1188 | VIEW: string; 1189 | } 1190 | 1191 | interface IPluginPosition { 1192 | MENUBAR: IMENUBAR; 1193 | SIDEBAR: ISIDEBAR; 1194 | TOPBAR: ITOPBAR; 1195 | CONTAINERS: ICONTAINERS; 1196 | STATUSBAR: ISTATUSBAR; 1197 | EDITOR: IEDITOR; 1198 | } 1199 | 1200 | interface IInjectComponent { 1201 | inject: IInjectFn; 1202 | register: IPluginRegisterFn; 1203 | unregister: IPluginUnRegisterFn; 1204 | PluginArea: any; 1205 | position: IPluginPosition; 1206 | } 1207 | 1208 | interface IRequest { 1209 | (options: any): Promise; 1210 | get: (options: any) => Promise; 1211 | postJSON: (options: any) => Promise; 1212 | } 1213 | 1214 | interface ILangProp { 1215 | [propName: string]: string; 1216 | } 1217 | interface ILanguage { 1218 | [propName: string]: ILangProp; 1219 | } 1220 | 1221 | interface ILanguagePool { 1222 | zh_CN: ILanguage; 1223 | en_US: ILanguage; 1224 | } 1225 | 1226 | export interface II18nConf { 1227 | customLanguagePool: ILanguagePool; 1228 | } 1229 | 1230 | interface IStylusObject { 1231 | use: () => void; 1232 | unuse: () => void; 1233 | } 1234 | interface IStyles { 1235 | dark: IStylusObject; 1236 | light: IStylusObject; 1237 | } 1238 | interface IPluginContextConf { 1239 | i18n?: II18nConf; 1240 | styles?: IStyles; 1241 | [propName: string]: any; 1242 | } 1243 | 1244 | interface II18nScope { 1245 | get: any; 1246 | } 1247 | 1248 | interface I18n { 1249 | get: (template: string) => string; 1250 | (template: string): any; 1251 | } 1252 | 1253 | export class PluginContext { 1254 | constructor(config: IPluginContextConf); 1255 | inializeData: any; 1256 | injectComponent: IInjectComponent; 1257 | request: IRequest; 1258 | i18n: I18n; 1259 | sdk: any; 1260 | } 1261 | 1262 | interface IAppManager { 1263 | pluginWillMount?: () => void; 1264 | pluginWillUnMount?: () => void; 1265 | [propName: string]: any; 1266 | } 1267 | interface IAppRegisterConf { 1268 | key: string; 1269 | Manager: IAppManager; 1270 | app?: any; 1271 | } 1272 | 1273 | interface IPluginProperties { 1274 | [propkey: string]: IProperties; 1275 | } 1276 | 1277 | /** 1278 | * 自定义设置项 1279 | */ 1280 | interface IProperties { 1281 | /** 1282 | * 标题 1283 | */ 1284 | title: string; 1285 | /** 1286 | * 描述 1287 | */ 1288 | description?: string; 1289 | /** 1290 | * 值类型 1291 | */ 1292 | type: string; 1293 | /** 1294 | * 默认值 1295 | */ 1296 | default: Array | string | boolean | null; 1297 | /** 1298 | * 枚举值,可选 1299 | */ 1300 | enum?: Array; 1301 | } 1302 | interface IPluginConfiguration { 1303 | /** 1304 | * 插件唯一 key 1305 | */ 1306 | key: string; 1307 | /** 1308 | * 需要显示在设置面板中的标签页标题 1309 | */ 1310 | title: string; 1311 | /** 1312 | * 注册的设置项,包含设置项的唯一 key、title、默认值、类型及描述等信息 1313 | */ 1314 | properties: IPluginProperties; 1315 | } 1316 | 1317 | type IPluginConfigChangeHandler = (propKey: string, oldValue: any, newValue: any) => void; 1318 | 1319 | /** 1320 | * 注册一系列插件自定义设置项,该设置会在 CS -> 设置面板中以单独的标签展示 1321 | * @param {IPluginConfiguration} configuration 设置项 1322 | * 1323 | * 相同插件 key 多次注册的设置项会被替换 1324 | * 1325 | * **Note:** 请分清 type 属性表示设置项值的属性类型,用字符串表示 1326 | * 1327 | * 设置项的书写规则非常简单,例如你的设置项负责管理启动/禁用某功能,则其中 type 值应为 boolean,default 为 true/false 1328 | * 这将会被渲染为一个 checkbox 1329 | * 1330 | * 又或者你希望设置项是一个下拉选择框,就需要包含 enum 属性,并提供所有可选项 1331 | * 1332 | * 而如果设置项 type 为 string ,default 为 null 或 空串,则会被渲染为一个普通的输入框 1333 | * ```javascript 1334 | * const mySettings = { 1335 | * key: 'my-plugin', 1336 | * title; ‘My Plugin Setting’, 1337 | * properties: { 1338 | * 'enable.autofocus': { 1339 | * type: boolean, 1340 | * title: '启用自动聚焦' 1341 | * default: false, 1342 | * description: 'enable autofocus', 1343 | * }, 1344 | * 'render.mode': { 1345 | * type: string, 1346 | * enum: [ 1347 | * 'canvas', 1348 | * 'dom', 1349 | * 'auto', 1350 | * ], 1351 | * default: 'auto', 1352 | * title: '选择渲染模式', 1353 | * description: 'some secription...', 1354 | * } 1355 | * } 1356 | * } 1357 | * registerPluginConfiguration(mySettings) 1358 | * ``` 1359 | */ 1360 | export function registerPluginConfiguration( 1361 | configuration: IPluginConfiguration 1362 | ): void; 1363 | interface IPluginKVProperties { 1364 | [propName: string]: any; 1365 | } 1366 | /** 1367 | * 获取指定插件 key 注册的所有设置项的 key/value 对象 1368 | * 1369 | * @param {string} pluginKey 插件唯一 key 1370 | * @return {IPluginKVProperties} key/value 对象 1371 | * 1372 | */ 1373 | export function getPluginConfiguration( 1374 | pluginKey: string 1375 | ): IPluginKVProperties; 1376 | /** 1377 | * 注册指定插件所注册设置项被修改时的回调函数 1378 | * 1379 | * @param {string} pluginKey 插件唯一 key 1380 | * @param {IPluginConfigChangeHandler} fn 回调函数 1381 | * @return {IDisposable} dispose 清除回调函数 1382 | * 1383 | * 回调函数会在对应插件的自定义设置项发生改变时被调用 1384 | * 可以获取到包括发生改变设置项的唯一 key, 以及新/旧值 1385 | */ 1386 | export function registerPluginConfigChangeHandler( 1387 | pluginKey: string, 1388 | fn: IPluginConfigChangeHandler 1389 | ): IDisposable; 1390 | export function appRegistry( 1391 | registerConf: Array, 1392 | callbackfn?: IAppRegisterCallBackFn 1393 | ): void; 1394 | 1395 | type IDisposable = () => void; 1396 | 1397 | interface IAdvanceProviderConnect { 1398 | Provider: any 1399 | connect: any 1400 | } 1401 | export function createAdvancedProviderAndConnect(storeKey: string): IAdvanceProviderConnect 1402 | /** 1403 | * 生成插件唯一 pluginKey 1404 | */ 1405 | export function generatePluginKey():string; 1406 | } 1407 | --------------------------------------------------------------------------------