'use strict' ; import * as vscode from 'vscode' ; class CodicExtension { protected context : vscode . ExtensionContext ; protected request = require ( 'request-promise' ) ; protected nullsymbol : string = "<null>" ; protected cases : { [ index ] : { applyfunc : ( string , boolean ) => string ; sample : string ; } ; } = { "PascalCase" : { "applyfunc" : ( word , isFirst ) => { return word [ 0 ] . toUpperCase ( ) + word . slice ( 1 ) ; } , "sample" : "Aa" } , "camelCase" : { "applyfunc" : ( word , isFirst ) => { return isFirst ? word : ( word [ 0 ] . toUpperCase ( ) + word . slice ( 1 ) ) ; } , "sample" : "aA" } , "snake_case" : { "applyfunc" : ( word , isFirst ) => { return isFirst ? word : "_" + word ; } , "sample" : "a_a" } , "SNAKE_CASE" : { "applyfunc" : ( word , isFirst ) => { return ( isFirst ? word : "_" + word ) . toUpperCase ( ) ; } , "sample" : "A_A" , } , "hy-phen-a-tion" : { "applyfunc" : ( word , isFirst ) => { return isFirst ? word : "-" + word ; } , "sample" : "a-a" } , "no case" : { "applyfunc" : ( word , isFirst ) => { return isFirst ? word : " " + word ; } , "sample" : "a a" } } ; constructor ( context ) { this . context = context ; } public translate ( ) { if ( ! this . disposeLegacyCaseSetting ( ) ) { vscode . window . showErrorMessage ( "単語の連結方法が設定されていません。" ) ; return ; } this . getInputText ( ) . then ( ( input ) => this . sendRequest ( input , this . getAccessToken ( ) ) ) . then ( ( body ) => this . listCandidates ( body ) ) . then ( ( candidates ) => this . pickCandidates ( candidates ) ) ; } public setLocalCase ( ) { var keys = [ ] ; for ( var key in this . cases ) { keys . push ( key ) ; } vscode . window . showQuickPick ( keys ) . then ( ( choice ) => { vscode . workspace . getConfiguration ( 'codic' ) . update ( 'case' , choice , false ) ; } ) ; } public setGlobalCase ( ) { var keys = [ ] ; for ( var key in this . cases ) { keys . push ( key ) ; } vscode . window . showQuickPick ( keys ) . then ( ( choice ) => { vscode . workspace . getConfiguration ( 'codic' ) . update ( 'case' , choice , true ) ; } ) ; } public dispose ( ) { } protected getAccessToken ( ) { let ACCESS_TOKEN = vscode . workspace . getConfiguration ( 'codic' ) . get < string | undefined > ( 'ACCESS_TOKEN' ) ; if ( ! ACCESS_TOKEN ) { vscode . window . showErrorMessage ( "アクセストークンが設定されていません。" ) ; throw 'no ACCESS_TOKEN' ; } return ACCESS_TOKEN ; } protected getInputText ( ) { return vscode . window . showInputBox ( { prompt : 'Input a Japanese phrase' } ) . then ( ( input ) => { if ( input === undefined || input === "" ) { return Promise . reject ( undefined ) ; } return input ; } ) ; } protected sendRequest ( text , ACCESS_TOKEN ) { let options = { uri : 'https://api.codic.jp/v1/engine/translate.json' , method : 'GET' , qs : { text : text } , headers : { 'Authorization' : 'Bearer ' + ACCESS_TOKEN } , transform2xxonly : true , transform : ( body ) => { return JSON . parse ( body ) ; } , } ; return this . request ( options ) ; } protected listCandidates ( body ) { let candidates = [ ] ; for ( let i = 0 ; i < body [ 0 ] . words . length ; i ++ ) { let temp = [ ] ; for ( let j = 0 ; j < body [ 0 ] . words [ i ] [ 'candidates' ] . length ; j ++ ) { temp . push ( body [ 0 ] . words [ i ] [ 'candidates' ] [ j ] [ 'text' ] === null ? this . nullsymbol : body [ 0 ] . words [ i ] [ 'candidates' ] [ j ] [ 'text' ] ) ; } if ( temp . length === 0 ) { temp = [ body [ 0 ] . words [ i ] [ 'text' ] ] ; } candidates . push ( temp ) ; } return candidates ; } protected getCase ( ) { return vscode . workspace . getConfiguration ( 'codic' ) . get < string > ( 'case' ) ; } protected applyCase ( text , isFirst , case_ ) { return this . cases [ case_ ] [ "applyfunc" ] ( text , isFirst ) ; } protected pickCandidates ( candidates ) { let p = Promise . resolve ( ) ; let isFirst = true ; candidates . forEach ( ( words ) => { p = p . then ( ( ) => { return vscode . window . showQuickPick ( words ) ; } ) . then ( ( choice ) => { if ( choice === undefined ) return Promise . reject ( "user focused out" ) ; if ( choice === this . nullsymbol ) { return Promise . resolve ( null ) ; } return this . insertText ( this . applyCase ( choice , isFirst , this . getCase ( ) ) ) ; } ) . then ( ( val ) => { if ( val !== null ) { isFirst = false ; } } ) . then ( this . moveCursorToEndOfSelection ) ; } ) ; return p ; } protected insertText ( text ) { let editor = vscode . window . activeTextEditor ; let edit = new vscode . WorkspaceEdit ( ) ; edit . insert ( editor . document . uri , editor . selection . anchor , text ) ; return vscode . workspace . applyEdit ( edit ) ; } protected moveCursorToEndOfSelection ( ) { let editor = vscode . window . activeTextEditor ; editor . selection = new vscode . Selection ( editor . selection . end , editor . selection . end ) ; } protected disposeLegacyCaseSetting ( ) { let new_case = vscode . workspace . getConfiguration ( 'codic' ) . get < string > ( 'case' ) ; if ( ! new_case ) { let local_legacy_case = this . context . workspaceState . get < string | undefined > ( "codic.case" ) ; if ( local_legacy_case ) { vscode . workspace . getConfiguration ( 'codic' ) . update ( 'case' , local_legacy_case , false ) ; } let global_legacy_case = this . context . globalState . get < string | undefined > ( "codic.case" ) ; if ( global_legacy_case ) { vscode . workspace . getConfiguration ( 'codic' ) . update ( 'case' , global_legacy_case , false ) ; } return local_legacy_case !== undefined || global_legacy_case !== undefined ; } else { return true ; } } } export function activate ( context ) { let codicExtension = new CodicExtension ( context ) ; let disposable = [ ] ; disposable . push ( vscode . commands . registerCommand ( 'extension.codicTranslate' , ( ) => { codicExtension . translate ( ) ; } ) ) ; disposable . push ( vscode . commands . registerCommand ( "extension.codicSetLocalCase" , ( ) => { codicExtension . setLocalCase ( ) ; } ) ) ; disposable . push ( vscode . commands . registerCommand ( "extension.codicSetGlobalCase" , ( ) => { codicExtension . setGlobalCase ( ) ; } ) ) ; context . subscriptions . push ( codicExtension ) ; disposable . forEach ( ( item ) => { context . subscriptions . push ( item ) ; } ) ; } export function deactivate ( ) { }