You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
188 lines
6.1 KiB
188 lines
6.1 KiB
import * as fs from 'fs'; |
|
import * as path from 'path'; |
|
import { |
|
commands, |
|
Position, |
|
TextDocument, |
|
TextEditor, |
|
Uri, |
|
ViewColumn, |
|
window, |
|
workspace, |
|
WorkspaceConfiguration |
|
} from 'vscode'; |
|
import { FileItem } from './item'; |
|
|
|
export interface IMoveFileDialogOptions { |
|
prompt: string; |
|
showFullPath?: boolean; |
|
uri?: Uri; |
|
} |
|
|
|
export interface INewFileDialogOptions { |
|
prompt: string; |
|
relativeToRoot?: boolean; |
|
} |
|
|
|
export interface INewJekyllDialogOptions { |
|
value: string; |
|
valueSelection: [number, number]; |
|
} |
|
|
|
export interface ICreateOptions { |
|
fileItem: FileItem; |
|
isDir?: boolean; |
|
} |
|
|
|
export class FileController { |
|
|
|
public showNewJekyllFileDialog(options: INewJekyllDialogOptions): Promise<FileItem> { |
|
|
|
const { value, valueSelection } = options; |
|
let sourcePath = workspace.rootPath; |
|
if (this.sourcePath) { |
|
sourcePath = path.dirname(this.sourcePath); |
|
} |
|
|
|
if (!sourcePath) { |
|
return Promise.reject(null); |
|
} |
|
|
|
return Promise.resolve(window.showInputBox({ value, valueSelection })) |
|
.then((targetPath) => { |
|
|
|
if (targetPath) { |
|
targetPath = path.resolve(sourcePath, targetPath); |
|
return new FileItem(sourcePath, targetPath); |
|
} |
|
|
|
}); |
|
} |
|
|
|
public create(options: ICreateOptions): Promise<FileItem> { |
|
|
|
const { fileItem, isDir = false } = options; |
|
|
|
return this.ensureWritableFile(fileItem) |
|
.then(() => fileItem.create(isDir)) |
|
.catch(() => Promise.reject(`Error creating file '${fileItem.targetPath}'.`)); |
|
} |
|
|
|
public openFileInEditor(fileItem: FileItem): Promise<TextEditor> { |
|
|
|
const isDir = fs.statSync(fileItem.path).isDirectory(); |
|
|
|
if (isDir) { |
|
return; |
|
} |
|
|
|
return Promise.resolve(workspace.openTextDocument(fileItem.path)) |
|
.then((textDocument) => { |
|
return textDocument |
|
? Promise.resolve(textDocument) |
|
: Promise.reject(new Error('Could not open file!')); |
|
}) |
|
.then((textDocument) => window.showTextDocument(textDocument, ViewColumn.Active)) |
|
.then((editor) => { |
|
|
|
const date: Date = new Date(); |
|
let monthDay: string = date.getDate().toString(); // Get the day as a number (1-31) |
|
let month: number = date.getMonth(); // Get the month as a number (0-11) 2018-05-05 12:29:01 +0800 |
|
let hour: string = date.getHours().toString(); // Get the hour (0-23) |
|
let mins: string = date.getMinutes().toString(); // Get the minute (0-59) |
|
let sec: string = date.getSeconds().toString(); // Get the second (0-59) |
|
const tzOffset: number = date.getTimezoneOffset(); |
|
const delim: string = '-'; |
|
const delimTime: string = ':'; |
|
const delimSpace: string = ' '; |
|
|
|
const tzOffsetStr: string = ((tzOffset < 0 ? '+' : '-') |
|
+ this.pad(parseInt(Math.abs(tzOffset / 60).toString(), 10), 2) |
|
+ this.pad(Math.abs(tzOffset % 60), 2)); |
|
|
|
// console.log(tzOffsetStr); |
|
|
|
const fullYear: string = date.getFullYear().toString(); |
|
|
|
if (monthDay.length === 1) { |
|
monthDay = '0'.concat(monthDay); |
|
} |
|
if (hour.length === 1) { |
|
hour = '0'.concat(hour); |
|
} |
|
if (mins.length === 1) { |
|
mins = '0'.concat(mins); |
|
} |
|
if (sec.length === 1) { |
|
sec = '0'.concat(sec); |
|
} |
|
|
|
month++; |
|
let monthStr: string = month.toString(); |
|
|
|
if (monthStr.length === 1) { |
|
monthStr = '0'.concat(monthStr); |
|
} |
|
// 2018-05-05 12:29:01 +0800 |
|
const outputStr: string = fullYear.concat(delim, monthStr, delim, monthDay, delimSpace, |
|
hour, delimTime, mins, delimTime, sec, delimSpace, tzOffsetStr); |
|
|
|
const frontMatter: string = '---\nlayout: single\ntitle: \ndate: '. |
|
concat(outputStr, '\ncategories: \ntags: \nexcerpt: \n---\n'); |
|
const p: Position = new Position(0, 0); |
|
editor.edit((editBuilder) => { |
|
editBuilder.insert(p, frontMatter); |
|
}); |
|
|
|
return editor |
|
? Promise.resolve(editor) |
|
: Promise.reject(new Error('Could not show document!')); |
|
}); |
|
} |
|
|
|
public closeCurrentFileEditor(): Thenable<any> { |
|
return commands.executeCommand('workbench.action.closeActiveEditor'); |
|
} |
|
|
|
private get sourcePath(): string { |
|
|
|
const activeEditor: TextEditor = window.activeTextEditor; |
|
const document: TextDocument = activeEditor && activeEditor.document; |
|
|
|
return document && document.fileName; |
|
} |
|
|
|
private ensureWritableFile(fileItem: FileItem): Promise<FileItem> { |
|
|
|
if (!fileItem.exists) { |
|
return Promise.resolve(fileItem); |
|
} |
|
|
|
const message = `File '${fileItem.targetPath}' already exists.`; |
|
const action = 'Overwrite'; |
|
|
|
return Promise.resolve(window.showInformationMessage(message, { modal: true }, action)) |
|
.then((overwrite) => overwrite ? Promise.resolve(fileItem) : Promise.reject(null)); |
|
} |
|
|
|
private pad(num: number, length: number): string { |
|
let str = '' + num; |
|
while (str.length < length) { |
|
str = '0' + str; |
|
} |
|
return str; |
|
|
|
} |
|
|
|
private get configuration(): WorkspaceConfiguration { |
|
return workspace.getConfiguration('fileutils'); |
|
} |
|
|
|
private get useTrash(): boolean { |
|
return this.configuration.get('delete.useTrash'); |
|
} |
|
|
|
private get confirmDelete(): boolean { |
|
return this.configuration.get('delete.confirm'); |
|
} |
|
}
|
|
|