1212 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
1313 *
1414 */
15-
15+ import * as vscode from "vscode" ;
1616import { commands , window , workspace , TextDocument , ViewColumn } from "vscode" ;
1717import { Command } from "../../core/command" ;
1818import { isQuartoDoc , kQuartoLanguageId } from "../../core/doc" ;
19+ import * as quarto from "quarto-core" ;
20+ import fs from "node:fs" ;
21+ import * as path from 'path' ;
22+ import yaml from "js-yaml" ;
1923import { VisualEditorProvider } from "./editor" ;
2024
2125
26+ export async function determineMode ( doc : TextDocument , config : string | undefined ) : Promise < boolean > {
27+ const text = doc . getText ( )
28+
29+ let editorOpener = undefined ;
30+
31+ // check if file itself has a mode
32+ if ( hasEditorMode ( text , "source" ) ) {
33+ editorOpener = "source" ;
34+ }
35+ else if ( hasEditorMode ( text , "visual" ) ) {
36+ editorOpener = "visual" ;
37+ }
38+ // check if has a _quarto.yml or _quarto.yaml file with editor specified
39+ else {
40+ editorOpener = workspaceHasQuartoYaml ( ) ;
41+ }
42+ if ( editorOpener && editorOpener != config ) {
43+ editorOpener = editorOpener === 'visual' ? VisualEditorProvider . viewType : 'textEditor' ;
44+ await vscode . commands . executeCommand ( 'workbench.action.closeActiveEditor' ) ;
45+ await vscode . commands . executeCommand ( "vscode.openWith" ,
46+ doc . uri ,
47+ editorOpener
48+ ) ;
49+ return true ;
50+ }
51+
52+ return false ;
53+ }
54+
55+ export async function setEditorOpener ( ) {
56+ const config = vscode . workspace . getConfiguration ( 'quarto' ) . get < string > ( 'defaultEditor' ) ;
57+ const viewType = config === 'visual' ? VisualEditorProvider . viewType : 'textEditor' ;
58+ vscode . workspace . getConfiguration ( 'workbench' ) . update ( 'editor.defaultView' , viewType , true ) ;
59+ await vscode . commands . executeCommand ( "workbench.action.setDefaultEditor" ,
60+ vscode . Uri . file ( 'filename.qmd' ) ,
61+ viewType
62+ ) ;
63+ }
64+
65+ export function workspaceHasQuartoYaml ( ) {
66+ const workspaceFolders = vscode . workspace . workspaceFolders ;
67+
68+ if ( workspaceFolders && workspaceFolders . length > 0 ) {
69+ const rootPath = workspaceFolders [ 0 ] . uri . fsPath ; // Only look in the root directory of the first workspace folder
2270
71+ const quartoFilePathYml = path . join ( rootPath , '_quarto.yml' ) ;
72+ const quartoFilePathYaml = path . join ( rootPath , '_quarto.yaml' ) ;
2373
24- export function editInVisualModeCommand ( ) : Command {
74+ let fileContent : string | null = null ;
75+
76+ if ( fs . existsSync ( quartoFilePathYml ) ) {
77+ fileContent = fs . readFileSync ( quartoFilePathYml , 'utf8' ) ;
78+ } else if ( fs . existsSync ( quartoFilePathYaml ) ) {
79+ fileContent = fs . readFileSync ( quartoFilePathYaml , 'utf8' ) ;
80+ }
81+
82+ if ( fileContent ) {
83+ const parsedYaml = yaml . load ( fileContent ) as any ;
84+ if ( parsedYaml . editor === 'visual' || parsedYaml . editor === 'source' ) {
85+ return parsedYaml . editor ;
86+ }
87+ }
88+ }
89+
90+ return undefined ;
91+ }
92+
93+ export function hasEditorMode ( doc : string , mode : string ) {
94+ if ( doc ) {
95+ const match = doc . match ( quarto . kRegExYAML ) ;
96+ if ( match ) {
97+ const yaml = match [ 0 ] ;
98+ return (
99+ ! ! yaml . match ( new RegExp ( "^editor:\\s+" + mode + "\\s*$" , "gm" ) ) ||
100+ ! ! yaml . match ( new RegExp ( "^[ \\t]*" + mode + ":\\s*(default)?\\s*$" , "gm" ) )
101+ ) ;
102+ }
103+ }
104+ return false ;
105+ }
106+
107+ export function editInVisualModeCommand ( ) : Command {
25108 return {
26109 id : "quarto.editInVisualMode" ,
27110 execute ( ) {
@@ -33,14 +116,14 @@ export function editInVisualModeCommand() : Command {
33116 } ;
34117}
35118
36- export function editInSourceModeCommand ( ) : Command {
119+ export function editInSourceModeCommand ( ) : Command {
37120 return {
38121 id : "quarto.editInSourceMode" ,
39122 execute ( ) {
40123 const activeVisual = VisualEditorProvider . activeEditor ( ) ;
41124 if ( activeVisual ) {
42125 reopenEditorInSourceMode ( activeVisual . document , '' , activeVisual . viewColumn ) ;
43- }
126+ }
44127 }
45128 } ;
46129}
@@ -49,14 +132,14 @@ export async function reopenEditorInVisualMode(
49132 document : TextDocument ,
50133 viewColumn ?: ViewColumn
51134) {
52-
135+
53136 // save then close
54137 await commands . executeCommand ( "workbench.action.files.save" ) ;
55138 await commands . executeCommand ( 'workbench.action.closeActiveEditor' ) ;
56139
57140 // open in visual mode
58- await commands . executeCommand ( "vscode.openWith" ,
59- document . uri ,
141+ await commands . executeCommand ( "vscode.openWith" ,
142+ document . uri ,
60143 VisualEditorProvider . viewType ,
61144 {
62145 viewColumn
@@ -65,8 +148,8 @@ export async function reopenEditorInVisualMode(
65148}
66149
67150export async function reopenEditorInSourceMode (
68- document : TextDocument ,
69- untitledContent ?: string ,
151+ document : TextDocument ,
152+ untitledContent ?: string ,
70153 viewColumn ?: ViewColumn
71154) {
72155 if ( ! document . isUntitled ) {
@@ -91,5 +174,5 @@ export async function reopenEditorInSourceMode(
91174 await window . showTextDocument ( doc , viewColumn , false ) ;
92175 }
93176 } ) ;
94-
177+
95178}
0 commit comments