1+ import { Range , Position , TextDocument , workspace } from 'vscode' ;
2+ import { JupyterLanguageSetting } from './contracts' ;
3+ import { EOL } from 'os' ;
4+
5+ /**
6+ * Language providers
7+ *
8+ * @export
9+ * @interface LanguageProvider
10+ */
11+ export interface LanguageProvider {
12+ /**
13+ * Returns a Regular Expression used to determine whether a line is a Cell delimiter or not
14+ *
15+ * @type {RegExp }
16+ * @memberOf LanguageProvider
17+ */
18+ cellIdentifier : RegExp ;
19+
20+ /**
21+ * Returns the selected code
22+ * If not implemented, then the currently active line or selected code is taken.
23+ * Can be implemented to ensure valid blocks of code are selected.
24+ * E.g if user selects only the If statement, code can be impelemented to ensure all code within the if statement (block) is returned
25+ * @param {string } selectedCode The selected code as identified by this extension.
26+ * @param {Range } [currentCell] Range of the currently active cell
27+ * @returns {Promise<string> } The code selected. If nothing is to be done, return the parameter value.
28+ *
29+ * @memberOf LanguageProvider
30+ */
31+ getSelectedCode ( selectedCode : string , currentCell ?: Range ) : Promise < string > ;
32+
33+ /**
34+ * Gets the first line (position) of executable code within a range
35+ *
36+ * @param {TextDocument } document
37+ * @param {number } startLine
38+ * @param {number } endLine
39+ * @returns {Promise<Position> }
40+ *
41+ * @memberOf LanguageProvider
42+ */
43+ getFirstLineOfExecutableCode ( document : TextDocument , range : Range ) : Promise < Position > ;
44+ }
45+
46+ export class LanguageProviders {
47+ private static providers : Map < string , LanguageProvider > = new Map < string , LanguageProvider > ( ) ;
48+ public static registerLanguageProvider ( language : string , provider : LanguageProvider ) {
49+ if ( typeof language !== 'string' || language . length === 0 ) {
50+ throw new Error ( `Argument 'language' is invalid` ) ;
51+ }
52+ if ( typeof provider !== 'object' || language === null ) {
53+ throw new Error ( `Argument 'provider' is invalid` ) ;
54+ }
55+ LanguageProviders . providers . set ( language , provider ) ;
56+ }
57+ public static cellIdentifier ( language : string ) : RegExp {
58+ return LanguageProviders . providers . has ( language ) ?
59+ LanguageProviders . providers . get ( language ) . cellIdentifier : null ;
60+ }
61+ public static getSelectedCode ( language : string , selectedCode : string , currentCell ?: Range ) : Promise < string > {
62+ return LanguageProviders . providers . has ( language ) ?
63+ LanguageProviders . providers . get ( language ) . getSelectedCode ( selectedCode , currentCell ) :
64+ Promise . resolve ( selectedCode ) ;
65+ }
66+ public static getFirstLineOfExecutableCode ( language : string , defaultRange : Range , document : TextDocument , range : Range ) : Promise < Position > | Promise < Range > {
67+ return LanguageProviders . providers . has ( language ) ?
68+ LanguageProviders . providers . get ( language ) . getFirstLineOfExecutableCode ( document , range ) :
69+ Promise . resolve ( defaultRange ) ;
70+ }
71+ private static getLanguageSetting ( language : string ) : JupyterLanguageSetting {
72+ let jupyterConfig = workspace . getConfiguration ( 'jupyter' ) ;
73+ let langSettings = jupyterConfig . get ( 'languages' ) as JupyterLanguageSetting [ ] ;
74+ let lowerLang = language . toLowerCase ( ) ;
75+ return langSettings . find ( setting => setting . languageId . toLowerCase ( ) === lowerLang ) ;
76+ }
77+
78+ public static getDefaultKernel ( language : string ) : string {
79+ let langSetting = LanguageProviders . getLanguageSetting ( language ) ;
80+ return langSetting ? langSetting . defaultKernel : null ;
81+ }
82+ public static getStartupCode ( language : string ) : string {
83+ let langSetting = LanguageProviders . getLanguageSetting ( language ) ;
84+ if ( ! langSetting || langSetting . startupCode . length === 0 ) {
85+ return null ;
86+ }
87+ return langSetting . startupCode . join ( EOL ) ;
88+ }
89+ }
0 commit comments