--- a\np2src\src\Notepad2.c Thu Nov 06 11:49:18 2008 +++ b\np2src\src\Notepad2.c Thu Nov 06 11:49:30 2008 @@ -257,8 +257,9 @@ int flagSingleFileInstance = 0; int flagStartAsTrayIcon = 0; int flagNoFadeHidden = 0; int flagSimpleIndentGuides = 0; int fNoHTMLGuess = 0; +int fNoScriptGuess = 0; int fNoFileVariables = 0; int flagPosParam = 0; int flagDefaultPos = 0; int flagNewFromClipboard = 0; @@ -4859,8 +4860,11 @@ void LoadFlags() flagSimpleIndentGuides = 1; if (IniSectionGetInt(pIniSection,L"NoHTMLGuess",0)) fNoHTMLGuess = 1; + + if (IniSectionGetInt(pIniSection,L"NoScriptGuess",0)) + fNoScriptGuess = 1; if (IniSectionGetInt(pIniSection,L"NoFileVariables",0)) fNoFileVariables = 1; --- a\np2src\src\Styles.c Thu Nov 06 11:49:18 2008 +++ b\np2src\src\Styles.c Thu Nov 06 12:35:48 2008 @@ -1618,8 +1618,9 @@ void Style_SetCurrentLineBackground(HWND // // Style_SetLexerFromFile() // extern int fNoHTMLGuess; +extern int fNoScriptGuess; extern FILEVARS fvCurFile; void Style_SetLexerFromFile(HWND hwnd,LPCWSTR lpszFile,BOOL bSupersedeAutoSelect) { @@ -1709,15 +1710,49 @@ void Style_SetLexerFromFile(HWND hwnd,LP pLexNew = &lexMAK; bFound = TRUE; } - if (!bFound && (bSupersedeAutoSelect || bAutoSelect) && !fNoHTMLGuess) { + if (!bFound && (bSupersedeAutoSelect || bAutoSelect)) { char tchText[256]; SendMessage(hwnd,SCI_GETTEXT,(WPARAM)COUNTOF(tchText)-1,(LPARAM)tchText); StrTrimA(tchText," \t\n\r"); - if (tchText[0] == '<') { - pLexNew = &lexHTML; + if (!fNoHTMLGuess && tchText[0] == '<') { + // Check for the XML prolog; 0x6C6D783F == "?xml" + pLexNew = (*((UNALIGNED PDWORD)(tchText + 1)) == 0x6C6D783F) ? &lexXML : &lexHTML; bFound = TRUE; + } + else if (!fNoScriptGuess && *((UNALIGNED PWORD)tchText) == 0x2123) { + // A shebang (0x2123 == "#!") was found + PSTR psz = tchText + 2; + while (*psz && (*psz == ' ' || *psz == '\t')) + ++psz; // skip any whitespace following the "#!" + while (*psz && *psz != ' ' && *psz != '\t' && *psz != '\n' && *psz != '\r') + ++psz; // find the end of the shebang command + if ((psz - tchText) >= 5 && *((UNALIGNED PDWORD)(psz - 3)) == 0x20766E65) { + // Special case: If the token ends in "env " (0x20766E65) (we check for + // a trailing space to make sure there is still more on this line), + // then we should sniff the next token instead + while (*psz && *psz == ' ') + ++psz; // skip spaces following the first token + while (*psz && *psz != ' ' && *psz != '\t' && *psz != '\n' && *psz != '\r') + ++psz; // find the end of the second token + } + + // Unix is case-sensitive, and the shebang should be too; to make it + // case-insensitive, bitwise-or by 0x20202020 before comparing + // 0x6C726570 == "perl", 0x6E6F6874 == "thon", and 0x6873 == "sh" + if ((psz - tchText) >= 6) { + switch (*((UNALIGNED PDWORD)(psz - 4))) { + case 0x6C726570: + pLexNew = &lexPL; + bFound = TRUE; + break; + case 0x6E6F6874: + pLexNew = &lexPY; + bFound = TRUE; + break; + } + } } } // Apply the new lexer