2
2
* Copyright (C) Microsoft Corporation. All rights reserved.
3
3
*--------------------------------------------------------*/
4
4
5
- import os = require( "os" ) ;
6
- import path = require( "path" ) ;
7
- import vscode = require( "vscode" ) ;
5
+ import * as fs from "fs" ;
6
+ import * as os from "os" ;
7
+ import * as path from "path" ;
8
+ import * as vscode from "vscode" ;
8
9
import { LanguageClient , NotificationType , Position , Range , RequestType } from "vscode-languageclient" ;
9
10
import { IFeature } from "../feature" ;
10
11
@@ -132,7 +133,7 @@ export const CloseFileRequestType =
132
133
"editor/closeFile" ) ;
133
134
134
135
export const SaveFileRequestType =
135
- new RequestType < string , EditorOperationResponse , void , void > (
136
+ new RequestType < ISaveFileDetails , EditorOperationResponse , void , void > (
136
137
"editor/saveFile" ) ;
137
138
138
139
export const ShowErrorMessageRequestType =
@@ -151,6 +152,11 @@ export const SetStatusBarMessageRequestType =
151
152
new RequestType < IStatusBarMessageDetails , EditorOperationResponse , void , void > (
152
153
"editor/setStatusBarMessage" ) ;
153
154
155
+ export interface ISaveFileDetails {
156
+ filePath : string ;
157
+ newPath ?: string ;
158
+ }
159
+
154
160
export interface IStatusBarMessageDetails {
155
161
message : string ;
156
162
timeout ?: number ;
@@ -238,7 +244,7 @@ export class ExtensionCommandsFeature implements IFeature {
238
244
239
245
this . languageClient . onRequest (
240
246
SaveFileRequestType ,
241
- ( filePath ) => this . saveFile ( filePath ) ) ;
247
+ ( saveFileDetails ) => this . saveFile ( saveFileDetails ) ) ;
242
248
243
249
this . languageClient . onRequest (
244
250
ShowInformationMessageRequestType ,
@@ -382,24 +388,44 @@ export class ExtensionCommandsFeature implements IFeature {
382
388
return promise ;
383
389
}
384
390
385
- private saveFile ( filePath : string ) : Thenable < EditorOperationResponse > {
391
+ private async saveFile ( saveFileDetails : ISaveFileDetails ) : Promise < EditorOperationResponse > {
386
392
387
- let promise : Thenable < EditorOperationResponse > ;
388
- if ( this . findTextDocument ( this . normalizeFilePath ( filePath ) ) ) {
389
- promise =
390
- vscode . workspace . openTextDocument ( filePath )
391
- . then ( ( doc ) => {
392
- if ( doc . isDirty ) {
393
- doc . save ( ) ;
394
- }
395
- } )
396
- . then ( ( _ ) => EditorOperationResponse . Completed ) ;
397
- } else {
398
- promise = Promise . resolve ( EditorOperationResponse . Completed ) ;
393
+ // If the file to save can't be found, just complete the request
394
+ if ( ! this . findTextDocument ( this . normalizeFilePath ( saveFileDetails . filePath ) ) ) {
395
+ return EditorOperationResponse . Completed ;
399
396
}
400
397
401
- return promise ;
402
- }
398
+ // If no newFile is given, just save the current file
399
+ if ( ! saveFileDetails . newPath ) {
400
+ const doc = await vscode . workspace . openTextDocument ( saveFileDetails . filePath ) ;
401
+ if ( doc . isDirty ) {
402
+ await doc . save ( ) ;
403
+ }
404
+
405
+ return EditorOperationResponse . Completed ;
406
+ }
407
+
408
+ // Otherwise we want to save as a new file
409
+
410
+ // First turn the path we were given into an absolute path
411
+ // Relative paths are interpreted as relative to the original file
412
+ const newFileAbsolutePath = path . isAbsolute ( saveFileDetails . newPath ) ?
413
+ saveFileDetails . newPath :
414
+ path . resolve ( path . dirname ( saveFileDetails . filePath ) , saveFileDetails . newPath ) ;
415
+
416
+ // Retrieve the text out of the current document
417
+ const oldDocument = await vscode . workspace . openTextDocument ( saveFileDetails . filePath ) ;
418
+
419
+ // Write it to the new document path
420
+ fs . writeFileSync ( newFileAbsolutePath , oldDocument . getText ( ) ) ;
421
+
422
+ // Finally open the new document
423
+ const newFileUri = vscode . Uri . file ( newFileAbsolutePath ) ;
424
+ const newFile = await vscode . workspace . openTextDocument ( newFileUri ) ;
425
+ vscode . window . showTextDocument ( newFile , { preview : true } ) ;
426
+
427
+ return EditorOperationResponse . Completed ;
428
+ }
403
429
404
430
private normalizeFilePath ( filePath : string ) : string {
405
431
const platform = os . platform ( ) ;
0 commit comments