From f77f9010b71be0ae2990161815e047e6cedd790c Mon Sep 17 00:00:00 2001 From: Christophe Feijoo Date: Wed, 21 Sep 2016 01:45:41 +0200 Subject: [PATCH] First version --- .editorconfig | 6 + .gitignore | 3 + .vscode/launch.json | 28 ++ .vscode/settings.json | 10 + .vscode/tasks.json | 30 ++ .vscodeignore | 9 + LICENSE | 21 + README.md | 1 + install.sh | 17 + package.json | 55 +++ src/delimiters.ts | 56 +++ src/extension.ts | 115 +++++ src/header.ts | 169 +++++++ tsconfig.json | 15 + typings.json | 5 + typings/globals/moment/index.d.ts | 692 ++++++++++++++++++++++++++++ typings/globals/moment/typings.json | 8 + typings/index.d.ts | 1 + typings/node.d.ts | 1 + typings/vscode-typings.d.ts | 1 + 20 files changed, 1243 insertions(+) create mode 100644 .editorconfig create mode 100644 .gitignore create mode 100644 .vscode/launch.json create mode 100644 .vscode/settings.json create mode 100644 .vscode/tasks.json create mode 100644 .vscodeignore create mode 100644 LICENSE create mode 100644 README.md create mode 100644 install.sh create mode 100644 package.json create mode 100644 src/delimiters.ts create mode 100644 src/extension.ts create mode 100644 src/header.ts create mode 100644 tsconfig.json create mode 100644 typings.json create mode 100644 typings/globals/moment/index.d.ts create mode 100644 typings/globals/moment/typings.json create mode 100644 typings/index.d.ts create mode 100644 typings/node.d.ts create mode 100644 typings/vscode-typings.d.ts diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..9c71277 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,6 @@ +root = true + +[*] +indent_style = space +indent_size = 2 +insert_final_newline = true diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..76b5a59 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +out +node_modules +*.vsix diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..c77b2ad --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,28 @@ +// A launch configuration that compiles the extension and then opens it inside a new window +{ + "version": "0.1.0", + "configurations": [ + { + "name": "Launch Extension", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceRoot}" ], + "stopOnEntry": false, + "sourceMaps": true, + "outDir": "${workspaceRoot}/out/src", + "preLaunchTask": "npm" + }, + { + "name": "Launch Tests", + "type": "extensionHost", + "request": "launch", + "runtimeExecutable": "${execPath}", + "args": ["--extensionDevelopmentPath=${workspaceRoot}", "--extensionTestsPath=${workspaceRoot}/out/test" ], + "stopOnEntry": false, + "sourceMaps": true, + "outDir": "${workspaceRoot}/out/test", + "preLaunchTask": "npm" + } + ] +} diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..7877e3f --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +// Place your settings in this file to overwrite default and user settings. +{ + "files.exclude": { + "out": false // set this to true to hide the "out" folder with the compiled JS files + }, + "search.exclude": { + "out": true // set this to false to include "out" folder in search results + }, + "typescript.tsdk": "./node_modules/typescript/lib" // we want to use the TS server from our node_modules folder to control its version +} \ No newline at end of file diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..fb7f662 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,30 @@ +// Available variables which can be used inside of strings. +// ${workspaceRoot}: the root folder of the team +// ${file}: the current opened file +// ${fileBasename}: the current opened file's basename +// ${fileDirname}: the current opened file's dirname +// ${fileExtname}: the current opened file's extension +// ${cwd}: the current working directory of the spawned process + +// A task runner that calls a custom npm script that compiles the extension. +{ + "version": "0.1.0", + + // we want to run npm + "command": "npm", + + // the command is a shell script + "isShellCommand": true, + + // show the output window only if unrecognized errors occur. + "showOutput": "silent", + + // we run the custom script "compile" as defined in package.json + "args": ["run", "compile", "--loglevel", "silent"], + + // The tsc compiler is started in watching mode + "isWatching": true, + + // use the standard tsc in watch mode problem matcher to find compile problems in the output. + "problemMatcher": "$tsc-watch" +} \ No newline at end of file diff --git a/.vscodeignore b/.vscodeignore new file mode 100644 index 0000000..93e28ff --- /dev/null +++ b/.vscodeignore @@ -0,0 +1,9 @@ +.vscode/** +typings/** +out/test/** +test/** +src/** +**/*.map +.gitignore +tsconfig.json +vsc-extension-quickstart.md diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..2c9dacf --- /dev/null +++ b/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2016 Christophe Feijoo + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/README.md b/README.md new file mode 100644 index 0000000..cb56812 --- /dev/null +++ b/README.md @@ -0,0 +1 @@ +# 42 header for VSCode diff --git a/install.sh b/install.sh new file mode 100644 index 0000000..dc3f1ea --- /dev/null +++ b/install.sh @@ -0,0 +1,17 @@ + + #########. + ########",#: + #########',##". + ##'##'## .##',##. + ## ## ## # ##",#. + ## ## ## ## ##' + ## ## ## :## + ## ## ##." + +# A little install script to +# remember howto install extension +npm install +vsce package +code --uninstall-extension kube.42header +code --install-extension 42header*.vsix +rm 42header*.vsix diff --git a/package.json b/package.json new file mode 100644 index 0000000..32496be --- /dev/null +++ b/package.json @@ -0,0 +1,55 @@ +{ + "name": "42header", + "displayName": "42 Header", + "description": "42 header for VSCode : www.42.fr", + "version": "0.1.3", + "publisher": "kube", + "repository": { + "type": "git", + "url": "https://github.com/kube/vscode-42header" + }, + "bugs": { + "url": "https://github.com/kube/vscode-42header/issues" + }, + "homepage": "https://github.com/kube/vscode-42header", + "license": "MIT", + "engines": { + "vscode": "^1.4.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "*" + ], + "main": "./out/src/extension", + "contributes": { + "commands": [ + { + "command": "42header.insertHeader", + "title": "Insert 42 header", + "when": "editorTextFocus" + } + ], + "keybindings": [ + { + "command": "42header.insertHeader", + "key": "ctrl+alt+h", + "mac": "cmd+alt+h", + "when": "editorTextFocus" + } + ] + }, + "scripts": { + "vscode:prepublish": "node ./node_modules/vscode/bin/compile", + "compile": "node ./node_modules/vscode/bin/compile -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install" + }, + "devDependencies": { + "typescript": "^2.0.0", + "vscode": "^0.11.0" + }, + "dependencies": { + "moment": "^2.15.0" + } +} diff --git a/src/delimiters.ts b/src/delimiters.ts new file mode 100644 index 0000000..8bb2f6d --- /dev/null +++ b/src/delimiters.ts @@ -0,0 +1,56 @@ + + /*#######. + ########",#: + #########',##". + ##'##'## .##',##. + ## ## ## # ##",#. + ## ## ## ## ##' + ## ## ## :## + ## ## ##*/ + +const hashes = ['# ', ' #'] +const slashes = ['/* ', ' */'] +const semicolons = [';; ', ' ;;'] +const parens = ['(* ', ' *)'] +const dashes = ['-- ', ' --'] +const percents = ['%% ', ' %%'] + +export const languageDemiliters: { [index: string]: string[] | null } = { + 'c': slashes, + 'coffeescript': hashes, + 'cpp': slashes, + 'css': slashes, + 'dockerfile': hashes, + 'fsharp': parens, + 'go': slashes, + 'groovy': slashes, + 'haskell': dashes, + 'ini': semicolons, + 'jade': slashes, + 'java': slashes, + 'javascript': slashes, + 'javascriptreact': slashes, + 'latex': percents, + 'less': slashes, + 'lua': semicolons, + 'makefile': hashes, + 'objective-c': slashes, + 'ocaml': parens, + 'perl': hashes, + 'perl6': hashes, + 'php': slashes, + 'plaintext': hashes, + 'powershell': hashes, + 'python': hashes, + 'r': hashes, + 'ruby': hashes, + 'rust': slashes, + 'scss': slashes, + 'shellscript': hashes, + 'sql': hashes, + 'swift': slashes, + 'typescript': slashes, + 'typescriptreact': slashes, + 'xsl': slashes, + 'yaml': hashes +} diff --git a/src/extension.ts b/src/extension.ts new file mode 100644 index 0000000..908478a --- /dev/null +++ b/src/extension.ts @@ -0,0 +1,115 @@ + + /*#######. + ########",#: + #########',##". + ##'##'## .##',##. + ## ## ## # ##",#. + ## ## ## ## ##' + ## ## ## :## + ## ## ##*/ + +'use strict' +import * as path from 'path' +import * as vscode from 'vscode' +import * as moment from 'moment' + +import { + ExtensionContext, TextEdit, TextEditorEdit, TextDocument, Position, Range +} from 'vscode' + +import { + extractHeader, getHeaderInfo, updateHeaderInfo, renderHeader, + supportsLanguage, IHeaderInfo +} from './header' + +/** + * `insertHeader` Command Handler + */ +function insertHeaderHandler() { + let activeTextEditor = vscode.window.activeTextEditor + let document = activeTextEditor.document + let languageId = document.languageId + + if (supportsLanguage(languageId)) { + activeTextEditor.edit(editor => { + let currentHeader = extractHeader(document.getText()) + + if (currentHeader) { + let headerInfo = getHeaderInfo(currentHeader) + let updatedHeaderInfo = updateHeaderInfo(headerInfo) + let header = renderHeader(languageId, updatedHeaderInfo) + + editor.replace(new Range(0, 0, 12, 0), header) + } + else { + let user = process.env['USER'] + let headerInfo = { + filename: path.basename(document.fileName), + author: `${user} <${user}@student.42.fr>`, + createdBy: user, + createdAt: moment(), + updatedBy: user, + updatedAt: moment() + } + let header = renderHeader(languageId, headerInfo) + editor.insert(new Position(0, 0), header) + } + }) + } + else + vscode.window.showInformationMessage( + `No header support for language ${languageId}`) +} + +/** + * Start watcher for document save to update current header + * if broken by code-formatter + */ +function startHeaderUpdateOnSaveWatcher(subscriptions: vscode.Disposable[]) { + const ignoreNextSave = new WeakSet() + + // Here we use the trick from Luke Hoban Go Extension, + // But this will cause an infinite loop if another extension that + // uses the same technique is active. + // And it's really ugly. + vscode.workspace.onDidSaveTextDocument(document => { + let textEditor = vscode.window.activeTextEditor + + if (textEditor.document === document + && !ignoreNextSave.has(document)) { + let activeTextEditor = vscode.window.activeTextEditor + let languageId = document.languageId + let currentHeader = extractHeader(document.getText()) + + // If current language is supported + // and a header is present at top of document + if (supportsLanguage(languageId) && currentHeader) { + textEditor.edit(editor => { + let headerInfo = getHeaderInfo(currentHeader) + let updatedHeaderInfo = updateHeaderInfo(headerInfo) + let header = renderHeader(languageId, updatedHeaderInfo) + + editor.replace(new Range(0, 0, 12, 0), header) + }) + .then(applied => { + ignoreNextSave.add(document) + return document.save() + }) + .then(() => { + ignoreNextSave.delete(document) + }, err => { }) + } + } + }, null, subscriptions) +} + +export function activate(context: vscode.ExtensionContext) { + let disposable = vscode.commands + .registerTextEditorCommand('42header.insertHeader', insertHeaderHandler) + + context.subscriptions.push(disposable) + startHeaderUpdateOnSaveWatcher(context.subscriptions) +} + +export function deactivate() { +} diff --git a/src/header.ts b/src/header.ts new file mode 100644 index 0000000..0db9aa1 --- /dev/null +++ b/src/header.ts @@ -0,0 +1,169 @@ + + /*#######. + ########",#: + #########',##". + ##'##'## .##',##. + ## ## ## # ##",#. + ## ## ## ## ##' + ## ## ## :## + ## ## ##*/ + +import * as moment from 'moment' +import { languageDemiliters } from './delimiters' + +export interface IHeaderInfo { + filename: string, + author: string, + createdBy: string, + createdAt: moment.Moment, + updatedBy: string, + updatedAt: moment.Moment +} + +/** + * Template where each field name is prefixed by $ and is padded with _ + */ +const genericTemplate = ` +******************************************************************************** +* * +* ::: :::::::: * +* $FILENAME__________________________________ :+: :+: :+: * +* +:+ +:+ +:+ * +* By: $AUTHOR________________________________ +#+ +:+ +#+ * +* +#+#+#+#+#+ +#+ * +* Created: $CREATEDAT_________ by $CREATEDBY_ #+# #+# * +* Updated: $UPDATEDAT_________ by $UPDATEDBY_ ### ########.fr * +* * +******************************************************************************** + +`.substring(1) + +/** + * Get header template from languageId + */ +const getTemplate = (languageId: string) => { + let [left, right] = languageDemiliters[languageId] + let width = left.length + + // Replace all delimiters with ones for current language + return genericTemplate + .replace(new RegExp(`^(.{${width}})(.*)(.{${width}})$`, 'gm'), + left + '$2' + right) +} + +/** + * Fit value to correct field width, padded with spaces + */ +const pad = (value: string, width: number) => + value.concat(' '.repeat(width)).substr(0, width) + +/** + * Stringify Date to correct format for header + */ +const formatDate = (date: moment.Moment) => + date.format('YYYY/MM/DD HH:mm:ss') + +/** + * Get Date object from date string formatted for header + */ +const parseDate = (date: string) => + moment(date, 'YYYY/MM/DD HH:mm:ss') + +/** + * Check if language is supported + */ +export const supportsLanguage = (languageId: string) => + !!languageDemiliters[languageId] + +/** + * Returns current header as string if present at top of document + */ +export const extractHeader = (text: string): string | null => { + let headerRegex = `^(.{80}\n){10}` + let match = text.match(headerRegex) + + return match ? match[0] : null +} + +/** + * Regex to match field in template + * Returns [ global match, offset, field ] + */ +const fieldRegex = (name: string) => + new RegExp(`^((?:.*\\\n)*.*)(\\\$${name}_*)`, '') + +/** + * Get value by field name in header string + */ +const getFieldValue = (header: string, name: string) => { + let [_, offset, field] = genericTemplate.match(fieldRegex(name)) + + return header.substr(offset.length, field.length) +} + +/** + * Set field value in header string + */ +const setFieldValue = (header: string, name: string, value: string) => { + let [_, offset, field] = genericTemplate.match(fieldRegex(name)) + + return header.substr(0, offset.length) + .concat(pad(value, field.length)) + .concat(header.substr(offset.length + field.length)) +} + +/** + * Extract header info from header string + */ +export const getHeaderInfo = (header: string): IHeaderInfo => ({ + filename: getFieldValue(header, 'FILENAME'), + author: getFieldValue(header, 'AUTHOR'), + createdBy: getFieldValue(header, 'CREATEDBY'), + createdAt: parseDate(getFieldValue(header, 'CREATEDAT')), + updatedBy: getFieldValue(header, 'UPDATEDBY'), + updatedAt: parseDate(getFieldValue(header, 'UPDATEDAT')) +}) + +/** + * Update header info with current time and last author + */ +export const updateHeaderInfo = (info: IHeaderInfo): IHeaderInfo => ({ + filename: info.filename, + author: `${process.env['USER']} <${process.env['USER']}@student.42.fr>`, + createdBy: info.createdBy, + createdAt: info.createdAt, + updatedBy: process.env['USER'], + updatedAt: moment() +}) + +/** + * Renders a language template with header info + */ +export const renderHeader = (languageId: string, info: IHeaderInfo) => [ + { + name: 'FILENAME', + value: info.filename + }, + { + name: 'AUTHOR', + value: `${info.updatedBy} <${info.updatedBy}@student.42.fr>` + }, + { + name: 'CREATEDAT', + value: formatDate(info.createdAt) + }, + { + name: 'CREATEDBY', + value: info.createdBy + }, + { + name: 'UPDATEDAT', + value: formatDate(info.updatedAt) + }, + { + name: 'UPDATEDBY', + value: info.updatedBy + } +].reduce((header, field) => + setFieldValue(header, field.name, field.value), + getTemplate(languageId)) diff --git a/tsconfig.json b/tsconfig.json new file mode 100644 index 0000000..dd93a8f --- /dev/null +++ b/tsconfig.json @@ -0,0 +1,15 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es5", + "outDir": "out", + "noLib": true, + "noImplicitAny": true, + "sourceMap": true, + "rootDir": "." + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +} diff --git a/typings.json b/typings.json new file mode 100644 index 0000000..a827760 --- /dev/null +++ b/typings.json @@ -0,0 +1,5 @@ +{ + "globalDependencies": { + "moment": "registry:dt/moment#2.11.1+20160829143156" + } +} diff --git a/typings/globals/moment/index.d.ts b/typings/globals/moment/index.d.ts new file mode 100644 index 0000000..f0fd1a5 --- /dev/null +++ b/typings/globals/moment/index.d.ts @@ -0,0 +1,692 @@ +// Generated by typings +// Source: https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e919f89ae61ae268a19e6796b4c601173e05d1de/moment/moment.d.ts +declare namespace moment { + + type MomentComparable = Moment | string | number | Date | number[]; + + interface MomentDateObject { + years?: number; + /* One digit */ + months?: number; + /* Day of the month */ + date?: number; + hours?: number; + minutes?: number; + seconds?: number; + milliseconds?: number; + } + + interface MomentInput { + /** Year */ + years?: number; + /** Year */ + year?: number; + /** Year */ + y?: number; + + /** Month */ + months?: number; + /** Month */ + month?: number; + /** Month */ + M?: number; + + /** Week */ + weeks?: number; + /** Week */ + week?: number; + /** Week */ + w?: number; + + /** Day/Date */ + days?: number; + /** Day/Date */ + day?: number; + /** Day/Date */ + date?: number; + /** Day/Date */ + d?: number; + + /** Hour */ + hours?: number; + /** Hour */ + hour?: number; + /** Hour */ + h?: number; + + /** Minute */ + minutes?: number; + /** Minute */ + minute?: number; + /** Minute */ + m?: number; + + /** Second */ + seconds?: number; + /** Second */ + second?: number; + /** Second */ + s?: number; + + /** Millisecond */ + milliseconds?: number; + /** Millisecond */ + millisecond?: number; + /** Millisecond */ + ms?: number; + } + + interface Duration { + humanize(withSuffix?: boolean): string; + + as(units: string): number; + + milliseconds(): number; + asMilliseconds(): number; + + seconds(): number; + asSeconds(): number; + + minutes(): number; + asMinutes(): number; + + hours(): number; + asHours(): number; + + days(): number; + asDays(): number; + + weeks(): number; + asWeeks(): number; + + months(): number; + asMonths(): number; + + years(): number; + asYears(): number; + + add(n: number, p: string): Duration; + add(n: number): Duration; + add(d: Duration): Duration; + + subtract(n: number, p: string): Duration; + subtract(n: number): Duration; + subtract(d: Duration): Duration; + + toISOString(): string; + toJSON(): string; + } + + interface MomentLocale { + ordinal(n: number): string; + } + + interface MomentCreationData { + input?: string; + format?: string; + locale: MomentLocale; + isUTC: boolean; + strict?: boolean; + } + + interface Moment { + format(format: string): string; + format(): string; + + fromNow(withoutSuffix?: boolean): string; + + startOf(unitOfTime: string): Moment; + endOf(unitOfTime: string): Moment; + + /** + * Mutates the original moment by adding time. (deprecated in 2.8.0) + * + * @param unitOfTime the unit of time you want to add (eg "years" / "hours" etc) + * @param amount the amount you want to add + */ + add(unitOfTime: string, amount: number): Moment; + /** + * Mutates the original moment by adding time. + * + * @param amount the amount you want to add + * @param unitOfTime the unit of time you want to add (eg "years" / "hours" etc) + */ + add(amount: number, unitOfTime: string): Moment; + /** + * Mutates the original moment by adding time. Note that the order of arguments can be flipped. + * + * @param amount the amount you want to add + * @param unitOfTime the unit of time you want to add (eg "years" / "hours" etc) + */ + add(amount: string, unitOfTime: string): Moment; + /** + * Mutates the original moment by adding time. + * + * @param objectLiteral an object literal that describes multiple time units {days:7,months:1} + */ + add(objectLiteral: MomentInput): Moment; + /** + * Mutates the original moment by adding time. + * + * @param duration a length of time + */ + add(duration: Duration): Moment; + + /** + * Mutates the original moment by subtracting time. (deprecated in 2.8.0) + * + * @param unitOfTime the unit of time you want to subtract (eg "years" / "hours" etc) + * @param amount the amount you want to subtract + */ + subtract(unitOfTime: string, amount: number): Moment; + /** + * Mutates the original moment by subtracting time. + * + * @param unitOfTime the unit of time you want to subtract (eg "years" / "hours" etc) + * @param amount the amount you want to subtract + */ + subtract(amount: number, unitOfTime: string): Moment; + /** + * Mutates the original moment by subtracting time. Note that the order of arguments can be flipped. + * + * @param amount the amount you want to add + * @param unitOfTime the unit of time you want to subtract (eg "years" / "hours" etc) + */ + subtract(amount: string, unitOfTime: string): Moment; + /** + * Mutates the original moment by subtracting time. + * + * @param objectLiteral an object literal that describes multiple time units {days:7,months:1} + */ + subtract(objectLiteral: MomentInput): Moment; + /** + * Mutates the original moment by subtracting time. + * + * @param duration a length of time + */ + subtract(duration: Duration): Moment; + + calendar(): string; + calendar(start: Moment): string; + calendar(start: Moment, formats: MomentCalendar): string; + + clone(): Moment; + + /** + * @return Unix timestamp, or milliseconds since the epoch. + */ + valueOf(): number; + + local(): Moment; // current date/time in local mode + + utc(): Moment; // current date/time in UTC mode + + isValid(): boolean; + invalidAt(): number; + + year(y: number): Moment; + year(): number; + quarter(): number; + quarter(q: number): Moment; + month(M: number): Moment; + month(M: string): Moment; + month(): number; + day(d: number): Moment; + day(d: string): Moment; + day(): number; + date(d: number): Moment; + date(): number; + hour(h: number): Moment; + hour(): number; + hours(h: number): Moment; + hours(): number; + minute(m: number): Moment; + minute(): number; + minutes(m: number): Moment; + minutes(): number; + second(s: number): Moment; + second(): number; + seconds(s: number): Moment; + seconds(): number; + millisecond(ms: number): Moment; + millisecond(): number; + milliseconds(ms: number): Moment; + milliseconds(): number; + weekday(): number; + weekday(d: number): Moment; + isoWeekday(): number; + isoWeekday(d: number): Moment; + weekYear(): number; + weekYear(d: number): Moment; + isoWeekYear(): number; + isoWeekYear(d: number): Moment; + week(): number; + week(d: number): Moment; + weeks(): number; + weeks(d: number): Moment; + isoWeek(): number; + isoWeek(d: number): Moment; + isoWeeks(): number; + isoWeeks(d: number): Moment; + weeksInYear(): number; + isoWeeksInYear(): number; + dayOfYear(): number; + dayOfYear(d: number): Moment; + + from(f: MomentComparable, suffix?: boolean): string; + to(f: MomentComparable, suffix?: boolean): string; + toNow(withoutPrefix?: boolean): string; + + diff(b: MomentComparable): number; + diff(b: MomentComparable, unitOfTime: string): number; + diff(b: MomentComparable, unitOfTime: string, round: boolean): number; + + toArray(): number[]; + toDate(): Date; + toISOString(): string; + toJSON(): string; + unix(): number; + + isLeapYear(): boolean; + zone(): number; + zone(b: number): Moment; + zone(b: string): Moment; + utcOffset(): number; + utcOffset(b: number): Moment; + utcOffset(b: string): Moment; + daysInMonth(): number; + isDST(): boolean; + + isBefore(): boolean; + isBefore(b: MomentComparable, granularity?: string): boolean; + + isAfter(): boolean; + isAfter(b: MomentComparable, granularity?: string): boolean; + + isSame(b: MomentComparable, granularity?: string): boolean; + isBetween(a: MomentComparable, b: MomentComparable, granularity?: string, inclusivity?: string): boolean; + + /** + * @since 2.10.7+ + */ + isSameOrBefore(b: MomentComparable, granularity?: string): boolean; + isSameOrAfter(b: MomentComparable, granularity?: string): boolean; + + /** + * @deprecated since version 2.8.0 + */ + lang(language: string): Moment; + lang(reset: boolean): Moment; + lang(): MomentLanguage; + + locale(language: string): Moment; + locale(reset: boolean): Moment; + locale(): string; + + /** + * @since 2.12.0+ + */ + locales() : string[]; + localeData(language: string): Moment; + localeData(reset: boolean): Moment; + localeData(): MomentLanguage; + + /** + * @deprecated since version 2.7.0 + */ + max(date: Moment | string | number | Date | any[]): Moment; + max(date: string, format: string): Moment; + + /** + * @deprecated since version 2.7.0 + */ + min(date: Moment | string | number | Date | any[]): Moment; + min(date: string, format: string): Moment; + + get(unit: string): number; + set(unit: string, value: number): Moment; + set(objectLiteral: MomentInput): Moment; + + /** + * This returns an object containing year, month, day-of-month, hour, minute, seconds, milliseconds. + * @since 2.10.5+ + */ + toObject(): MomentDateObject; + + /** + * @since 2.10.7+ + */ + creationData(): MomentCreationData; + } + + type formatFunction = () => string; + + interface MomentCalendar { + lastDay?: string | formatFunction; + sameDay?: string | formatFunction; + nextDay?: string | formatFunction; + lastWeek?: string | formatFunction; + nextWeek?: string | formatFunction; + sameElse?: string | formatFunction; + } + + interface BaseMomentLanguage { + months?: any; + monthsShort?: any; + weekdays?: any; + weekdaysShort?: any; + weekdaysMin?: any; + relativeTime?: MomentRelativeTime; + meridiem?: (hour: number, minute: number, isLowercase: boolean) => string; + calendar?: MomentCalendar; + ordinal?: (num: number) => string; + week?: MomentLanguageWeek; + } + + interface MomentLanguage extends BaseMomentLanguage { + longDateFormat?: MomentLongDateFormat; + } + + interface MomentLanguageWeek { + dow?: number; + doy?: number; + } + + interface MomentLanguageData { + /** + * Get the full localized month name of a moment object + * @param {Moment} aMoment a moment object + * @return {string} full month name + */ + months(aMoment: Moment): string; + + /** + * Get the short localized month name of a moment object + * @param {Moment} aMoment a moment object + * @return {string} short month name + */ + monthsShort(aMoment: Moment): string; + + /** + * Parses a month name and returns the month id (0-11) + * @param {string} longOrShortMonthString string of month to parse + * @return {number} month id (0 to 11) of input + */ + monthsParse(longOrShortMonthString: string): number; + + /** + * Gets the full weekday name of a moment object (eg. Monday) + * @param {Moment} aMoment a moment object + * @return {string} full weekday name + */ + weekdays(aMoment: Moment): string; + + /** + * Gets the short weekday name of a moment object (eg. Mon) + * @param {Moment} aMoment a moment object + * @return {string} short weekday name + */ + weekdaysShort(aMoment: Moment): string; + + /** + * Gets the min weekday name of a moment object (eg. Mo) + * @param {Moment} aMoment a moment object + * @return {string} min weekday name + */ + weekdaysMin(aMoment: Moment): string; + + /** + * Parses a weekday name and returns the weekday id (0-6) + * @param {string} longOrShortMonthString string of weekday to parse + * @return {number} weekday id (0 to 6) of input + */ + weekdaysParse(longOrShortMonthString: string): number; + + /** + * Returns the full format of abbreviated date-time formats + * @param {string} dateFormat date-time format such as LT, L, LL and so on + * @return {string} full date format string + */ + longDateFormat(dateFormat: string): string; + + /** + * Returns whether a string represents PM + * @param {string} amPmString date string to check + * @return {boolean} true if string represents PM + */ + isPM(amPmString: string): boolean; + + /** + * Returns am/pm string for particular time-of-day in upper/lower case + * @param {number} hour hour + * @param {number} minute minute + * @param {boolean} isLowercase whether to return in lowercase + * @return {string} 'am' or 'pm' + */ + meridiem(hour: number, minute: number, isLowercase: boolean): string; + + /** + * Returns a format that would be used for calendar representation. + * @param {string} key one of 'sameDay', 'nextDay', 'lastDay', 'nextWeek', 'prevWeek', 'sameElse' + * @param {Moment} aMoment a moment object + * @return {string} date format string + */ + calendar(key: string, aMoment: Moment): string; + + /** + * Returns relative time string (eg. a year ago) + * @param {number} number the relative number + * @param {boolean} withoutSuffix whether to drop the suffix + * @param {string} key one of 's', 'm', 'mm', 'h', 'hh', 'd', 'dd', 'M', 'MM', 'y', 'yy'. Single letter when number is 1. + * @param {boolean} isFuture whether this represents a future date + * @return {string} humanized representation of relative time + */ + relativeTime(number: number, withoutSuffix: boolean, key: string, isFuture: boolean): string; + + /** + * Converts relative time string to past or future string depending on difference + * @param {number} diff positive or negative number + * @param {string} relTime relative time string + * @return {string} humanized representation of relative time + */ + pastFuture(diff: number, relTime: string): string; + + /** + * Convert number to ordinal string 1 -> 1st + * @param {number} number the number + * @return {string} ordinal string + */ + ordinal(number: number): string; + + /** + * Called before parsing every input string + */ + preparse(str: string): string; + + /** + * Called after formatting on every string + */ + postformat(str: string): string; + + /** + * Returns week-of-year of a moment object + * @param {Moment} aMoment a moment object + * @return {number} number of the week + */ + week(aMoment: Moment): number; + + /** + * Returns a translation of 'Invalid date' + * @return {string} translation of 'Invalid date' + */ + invalidDate(): string; + + /** + * Returns the first day of the week (0-6, Sunday to Saturday) + * @return {number} first day of the week + */ + firstDayOfWeek(): number; + + /** + * This and the first day of week are used to determine which is + * the first week of the year. dow == 1 and doy == 4 means week starts + * Monday and first week that has Thursday is the first week of the + * year (but doy is NOT simply Thursday). + * @return {number} number between 0-15 + */ + firstDayOfYear(): number; + } + + interface MomentLongDateFormat { + L: string; + LL: string; + LLL: string; + LLLL: string; + LT: string; + LTS: string; + l?: string; + ll?: string; + lll?: string; + llll?: string; + lt?: string; + lts?: string; + } + + interface MomentRelativeTime { + future: any; + past: any; + s: any; + m: any; + mm: any; + h: any; + hh: any; + d: any; + dd: any; + M: any; + MM: any; + y: any; + yy: any; + } + + interface MomentBuiltinFormat { + __momentBuiltinFormatBrand: any; + } + + type MomentFormatSpecification = string | MomentBuiltinFormat | (string | MomentBuiltinFormat)[]; + + interface MomentStatic { + version: string; + fn: Moment; + + (): Moment; + (date: number): Moment; + (date: number[]): Moment; + (date: string, format?: MomentFormatSpecification, strict?: boolean): Moment; + (date: string, format?: MomentFormatSpecification, language?: string, strict?: boolean): Moment; + (date: Date): Moment; + (date: Moment): Moment; + (date: Object): Moment; + + utc(): Moment; + utc(date: number): Moment; + utc(date: number[]): Moment; + utc(date: string, format?: string, strict?: boolean): Moment; + utc(date: string, format?: string, language?: string, strict?: boolean): Moment; + utc(date: string, formats: string[], strict?: boolean): Moment; + utc(date: string, formats: string[], language?: string, strict?: boolean): Moment; + utc(date: Date): Moment; + utc(date: Moment): Moment; + utc(date: Object): Moment; + + unix(timestamp: number): Moment; + + invalid(parsingFlags?: Object): Moment; + isMoment(): boolean; + isMoment(m: any): m is Moment; + isDate(m: any): m is Date; + isDuration(): boolean; + isDuration(d: any): d is Duration; + + /** + * @deprecated since version 2.8.0 + */ + lang(language?: string): string; + lang(language?: string, definition?: MomentLanguage): string; + + locale(language?: string): string; + locale(language?: string[]): string; + locale(language?: string, definition?: MomentLanguage): string; + + localeData(language?: string): MomentLanguageData; + + longDateFormat: any; + relativeTime: any; + meridiem: (hour: number, minute: number, isLowercase: boolean) => string; + calendar: any; + ordinal: (num: number) => string; + + duration(milliseconds: Number): Duration; + duration(num: Number, unitOfTime: string): Duration; + duration(input: MomentInput): Duration; + duration(object: any): Duration; + duration(): Duration; + + parseZone(date: string): Moment; + + months(): string[]; + months(index: number): string; + months(format: string): string[]; + months(format: string, index: number): string; + monthsShort(): string[]; + monthsShort(index: number): string; + monthsShort(format: string): string[]; + monthsShort(format: string, index: number): string; + + weekdays(): string[]; + weekdays(index: number): string; + weekdays(format: string): string[]; + weekdays(format: string, index: number): string; + weekdaysShort(): string[]; + weekdaysShort(index: number): string; + weekdaysShort(format: string): string[]; + weekdaysShort(format: string, index: number): string; + weekdaysMin(): string[]; + weekdaysMin(index: number): string; + weekdaysMin(format: string): string[]; + weekdaysMin(format: string, index: number): string; + + min(...moments: Moment[]): Moment; + min(moments: Moment[]): Moment; + max(...moments: Moment[]): Moment; + max(moments: Moment[]): Moment; + + normalizeUnits(unit: string): string; + relativeTimeThreshold(threshold: string): number | boolean; + relativeTimeThreshold(threshold: string, limit: number): boolean; + + /** + * @since 2.10.7+ + */ + now(): number; + + /** + * Constant used to enable explicit ISO_8601 format parsing. + */ + ISO_8601: MomentBuiltinFormat; + + defaultFormat: string; + } + +} + +declare module 'moment' { + var moment: moment.MomentStatic; + export = moment; +} + +declare module 'moment/moment' { + var moment: moment.MomentStatic; + export = moment; +} + +declare var moment: moment.MomentStatic; diff --git a/typings/globals/moment/typings.json b/typings/globals/moment/typings.json new file mode 100644 index 0000000..28dc888 --- /dev/null +++ b/typings/globals/moment/typings.json @@ -0,0 +1,8 @@ +{ + "resolution": "main", + "tree": { + "src": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e919f89ae61ae268a19e6796b4c601173e05d1de/moment/moment.d.ts", + "raw": "registry:dt/moment#2.11.1+20160829143156", + "typings": "https://raw.githubusercontent.com/DefinitelyTyped/DefinitelyTyped/e919f89ae61ae268a19e6796b4c601173e05d1de/moment/moment.d.ts" + } +} diff --git a/typings/index.d.ts b/typings/index.d.ts new file mode 100644 index 0000000..f67face --- /dev/null +++ b/typings/index.d.ts @@ -0,0 +1 @@ +/// diff --git a/typings/node.d.ts b/typings/node.d.ts new file mode 100644 index 0000000..5ed7730 --- /dev/null +++ b/typings/node.d.ts @@ -0,0 +1 @@ +/// \ No newline at end of file diff --git a/typings/vscode-typings.d.ts b/typings/vscode-typings.d.ts new file mode 100644 index 0000000..5590dc8 --- /dev/null +++ b/typings/vscode-typings.d.ts @@ -0,0 +1 @@ +///