2525// ### Node.js packages
2626import assert from "assert" ;
2727import child_process from "node:child_process" ;
28+ import process from "node:process" ;
2829
2930// ### Third-party packages
3031import escape from "escape-html" ;
@@ -45,6 +46,9 @@ const MAX_MESSAGE_LENGTH = 200;
4546// The timeout for a websocket `Response`.
4647const RESPONSE_TIMEOUT = 15000 ;
4748
49+ // True on Windows, false on OS X / Linux.
50+ const is_windows = process . platform === "win32" ;
51+
4852// These globals are truly global: only one is needed for this entire plugin.
4953let websocket : WebSocket | undefined ;
5054// Where the webclient resides: `html` for a webview panel embedded in VSCode;
@@ -395,7 +399,9 @@ export const activate = (context: vscode.ExtensionContext) => {
395399 case "Update" : {
396400 const current_update =
397401 value as UpdateMessageContents ;
398- const doc = get_document ( current_update . file_path ) ;
402+ const doc = get_document (
403+ current_update . file_path
404+ ) ;
399405 if ( doc === undefined ) {
400406 send_result ( id , {
401407 Err : "No open document for this file." ,
@@ -457,7 +463,7 @@ export const activate = (context: vscode.ExtensionContext) => {
457463 // Report if this was an error.
458464 const result_contents = value as MessageResult ;
459465 if ( "Err" in result_contents ) {
460- const msg = `Error in message ${ id } : ${ result_contents . Err } . ` ;
466+ const msg = `Error in message ${ id } : ${ result_contents . Err } ` ;
461467 console . log ( msg ) ;
462468 // Warning: Calling `show_error` shuts down
463469 // the client. Do this deliberately, since
@@ -473,7 +479,8 @@ export const activate = (context: vscode.ExtensionContext) => {
473479 // Look through all open documents to see if we
474480 // have the requested file.
475481 const doc = get_document ( load_file ) ;
476- const load_file_result = doc === undefined ? null : doc . getText ( ) ;
482+ const load_file_result =
483+ doc === undefined ? null : doc . getText ( ) ;
477484 send_result ( id , {
478485 Ok : {
479486 LoadFile : load_file_result ,
@@ -511,15 +518,15 @@ export const activate = (context: vscode.ExtensionContext) => {
511518 }
512519 )
513520 ) ;
514- }
521+ } ;
515522
516523// On deactivation, close everything down.
517524export const deactivate = async ( ) => {
518525 console . log ( "CodeChat extension: deactivating." ) ;
519526 await stop_client ( ) ;
520527 webview_panel ?. dispose ( ) ;
521528 console . log ( "CodeChat extension: deactivated." ) ;
522- }
529+ } ;
523530
524531// ## Supporting functions
525532//
@@ -606,18 +613,16 @@ const start_render = () => {
606613 }
607614 } , 300 ) ;
608615 }
609- }
616+ } ;
610617
611618const current_file = ( ) => {
612619 // Only send a new current file is there's a change.
613620 const ate = vscode . window . activeTextEditor ;
614621 if ( can_render ( ) && ate !== current_editor ) {
615622 current_editor = ate ;
616- send_message (
617- {
618- CurrentFile : ate ! . document . fileName ,
619- } ,
620- ) ;
623+ send_message ( {
624+ CurrentFile : ate ! . document . fileName ,
625+ } ) ;
621626 }
622627} ;
623628
@@ -648,7 +653,7 @@ const stop_client = async () => {
648653 ) ;
649654 }
650655 current_editor = undefined ;
651- }
656+ } ;
652657
653658// Provide an error message in the panel if possible.
654659const show_error = ( message : string ) => {
@@ -667,7 +672,7 @@ const show_error = (message: string) => {
667672 message + "\nSee https://github.com/bjones1/CodeChat_Editor."
668673 ) ;
669674 }
670- }
675+ } ;
671676
672677// Only render if the window and editor are active, we have a valid render
673678// client, and the webview is visible.
@@ -676,14 +681,33 @@ const can_render = () => {
676681 vscode . window . activeTextEditor !== undefined &&
677682 websocket !== undefined &&
678683 ( codechat_client_location === CodeChatEditorClientLocation . browser ||
679- ( webview_panel !== undefined ) )
684+ webview_panel !== undefined )
680685 ) ;
681- }
686+ } ;
682687
683688const get_document = ( file_path : string ) => {
684689 // Look through all open documents to see if we have the requested file.
685690 for ( const doc of vscode . workspace . textDocuments ) {
686- if ( doc . fileName === file_path ) {
691+ // Make the possibly incorrect assumption that only Windows filesystems
692+ // are case-insensitive; I don't know how to easily determine the
693+ // case-sensitivity of the current filesystem without extra probing code
694+ // (write a file in mixed case, try to open it in another mixed case.)
695+ // Per
696+ // [How to Work with Different Filesystems](https://nodejs.org/en/learn/manipulating-files/working-with-different-filesystems#filesystem-behavior),
697+ // "Be wary of inferring filesystem behavior from `process.platform`.
698+ // For example, do not assume that because your program is running on
699+ // Darwin that you are therefore working on a case-insensitive
700+ // filesystem (HFS+), as the user may be using a case-sensitive
701+ // filesystem (HFSX)."
702+ //
703+ // The same article
704+ // [recommends](https://nodejs.org/en/learn/manipulating-files/working-with-different-filesystems#be-prepared-for-slight-differences-in-comparison-functions)
705+ // using `toUpperCase` for case-insensitive filename comparisons.
706+ if (
707+ ( ! is_windows && doc . fileName === file_path ) ||
708+ ( is_windows &&
709+ doc . fileName . toUpperCase ( ) === file_path . toUpperCase ( ) )
710+ ) {
687711 return doc ;
688712 }
689713 }
@@ -755,4 +779,4 @@ const run_server = (args: string[]) => {
755779 stderr += chunk . toString ( ) ;
756780 } ) ;
757781 } ) ;
758- }
782+ } ;
0 commit comments