diff --git a/PowerEditor/src/Notepad_plus.cpp b/PowerEditor/src/Notepad_plus.cpp index 1447744bf..946906295 100644 --- a/PowerEditor/src/Notepad_plus.cpp +++ b/PowerEditor/src/Notepad_plus.cpp @@ -7322,6 +7322,7 @@ static const QuoteParams quotes[] = {TEXT("Anonymous #195"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Why do programmers always mix up Halloween and Christmas?\nBecause Oct 31 == Dec 25\n") }, {TEXT("Anonymous #196"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("What happened to the function that ran away?\nIt never returned.\n") }, {TEXT("Anonymous #197"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("When I am tasked with sorting through a stack of résumés, I throw about half of them in the garbage.\nI do not want unlucky people working in our company.\n") }, + {TEXT("Anonymous #198"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("The reason why we write SQL commands all in CAPITAL letters is because it stands for Screaming Query Language.\n") }, {TEXT("xkcd"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Never have I felt so close to another soul\nAnd yet so helplessly alone\nAs when I Google an error\nAnd there's one result\nA thread by someone with the same problem\nAnd no answer\nLast posted to in 2003\n\n\"Who were you, DenverCoder9?\"\n\"What did you see?!\"\n\n(ref: https://xkcd.com/979/)") }, {TEXT("A developer"), QuoteParams::slow, false, SC_CP_UTF8, L_TEXT, TEXT("No hugs & kisses.\nOnly bugs & fixes.") }, {TEXT("Elon Musk"), QuoteParams::rapid, false, SC_CP_UTF8, L_TEXT, TEXT("Don't set your password as your child's name.\nName your child after your password.") }, diff --git a/PowerEditor/src/ScintillaComponent/Buffer.cpp b/PowerEditor/src/ScintillaComponent/Buffer.cpp index 241443aad..1f2b009ef 100644 --- a/PowerEditor/src/ScintillaComponent/Buffer.cpp +++ b/PowerEditor/src/ScintillaComponent/Buffer.cpp @@ -79,7 +79,7 @@ Buffer::Buffer(FileManager * pManager, BufferID id, Document doc, DocFileStatus _currentStatus = type; - setFileName(fileName, ndds._lang); + setFileName(fileName); updateTimeStamp(); checkFileState(); @@ -177,8 +177,7 @@ void Buffer::updateTimeStamp() // Set full path file name in buffer object, // and determinate its language by its extension. -// If the ext is not in the list, the defaultLang passed as argument will be set. -void Buffer::setFileName(const TCHAR *fn, LangType defaultLang) +void Buffer::setFileName(const TCHAR *fn) { NppParameters& nppParamInst = NppParameters::getInstance(); if (_fullPathName == fn) @@ -192,7 +191,7 @@ void Buffer::setFileName(const TCHAR *fn, LangType defaultLang) _fileName = PathFindFileName(_fullPathName.c_str()); // for _lang - LangType newLang = defaultLang; + LangType determinatedLang = L_TEXT; TCHAR *ext = PathFindExtension(_fullPathName.c_str()); if (*ext == '.') // extension found { @@ -202,36 +201,34 @@ void Buffer::setFileName(const TCHAR *fn, LangType defaultLang) const TCHAR* langName = nppParamInst.getUserDefinedLangNameFromExt(ext, _fileName); if (langName) { - newLang = L_USER; + determinatedLang = L_USER; _userLangExt = langName; } else // if it's not user lang, then check if it's supported lang { _userLangExt.clear(); - newLang = nppParamInst.getLangFromExt(ext); + determinatedLang = nppParamInst.getLangFromExt(ext); } } - else if (!isUntitled()) // existing file with no extension - newLang = L_TEXT; - if (newLang == defaultLang || newLang == L_TEXT) //language can probably be refined + if (determinatedLang == L_TEXT) //language can probably be refined { if ((OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("makefile")) == 0) || (OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("GNUmakefile")) == 0)) - newLang = L_MAKEFILE; + determinatedLang = L_MAKEFILE; else if (OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("CmakeLists.txt")) == 0) - newLang = L_CMAKE; + determinatedLang = L_CMAKE; else if ((OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("SConstruct")) == 0) || (OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("SConscript")) == 0) || (OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("wscript")) == 0)) - newLang = L_PYTHON; + determinatedLang = L_PYTHON; else if ((OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("Rakefile")) == 0) || (OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("Vagrantfile")) == 0)) - newLang = L_RUBY; + determinatedLang = L_RUBY; else if ((OrdinalIgnoreCaseCompareStrings(_fileName, TEXT("crontab")) == 0)) - newLang = L_BASH; + determinatedLang = L_BASH; } updateTimeStamp(); BufferStatusInfo lang2Change = BufferChangeNone; - if (!_hasLangBeenSetFromMenu && (newLang != _lang || _lang == L_USER)) + if (!_hasLangBeenSetFromMenu && (determinatedLang != _lang || _lang == L_USER)) { if (_isLargeFile) { @@ -239,7 +236,7 @@ void Buffer::setFileName(const TCHAR *fn, LangType defaultLang) } else { - _lang = newLang; + _lang = determinatedLang; lang2Change = BufferChangeLanguage; } } @@ -743,7 +740,7 @@ BufferID FileManager::loadFile(const TCHAR* filename, Document doc, int encoding // restore the encoding (ANSI based) while opening the existing file buf->setEncoding(-1); - // if no file extension, and the language has been detected, we use the detected value + // if not a large file, no file extension, and the language has been detected, we use the detected value if (!newBuf->_isLargeFile && ((buf->getLangType() == L_TEXT) && (loadedFileFormat._language != L_TEXT))) buf->setLangType(loadedFileFormat._language); @@ -1158,9 +1155,6 @@ SavingStatus FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool i } } - // check the language du fichier - LangType language = detectLanguageFromTextBegining((unsigned char *)buf, lengthDoc); - UnicodeConvertor.closeFile(); // Error, we didn't write the entire document to disk. @@ -1179,12 +1173,28 @@ SavingStatus FileManager::saveBuffer(BufferID id, const TCHAR * filename, bool i return SavingStatus::SaveOK; //all done } - buffer->setFileName(fullpath, language); + buffer->setFileName(fullpath); + + // if not a large file and language is normal text (not defined) + // we may try determinate its language from its content + if (!buffer->isLargeFile() && buffer->_lang == L_TEXT) + { + LangType detectedLang = detectLanguageFromTextBegining((unsigned char*)buf, lengthDoc); + + // if a language is detected from the content + if (detectedLang != L_TEXT) + { + buffer->_lang = detectedLang; + buffer->doNotify(BufferChangeFilename | BufferChangeTimestamp | BufferChangeLanguage); + } + } buffer->setDirty(false); buffer->setUnsync(false); buffer->setSavePointDirty(false); buffer->setStatus(DOC_REGULAR); buffer->checkFileState(); + + _pscratchTilla->execute(SCI_SETSAVEPOINT); _pscratchTilla->execute(SCI_SETDOCPOINTER, 0, _scratchDocDefault); @@ -1260,6 +1270,11 @@ BufferID FileManager::newEmptyDocument() Document doc = (Document)_pscratchTilla->execute(SCI_CREATEDOCUMENT); //this already sets a reference for filemanager Buffer* newBuf = new Buffer(this, _nextBufferID, doc, DOC_UNNAMED, newTitle.c_str(), false); + + NppParameters& nppParamInst = NppParameters::getInstance(); + const NewDocDefaultSettings& ndds = (nppParamInst.getNppGUI()).getNewDocDefaultSettings(); + newBuf->_lang = ndds._lang; + BufferID id = static_cast(newBuf); newBuf->_id = id; _buffers.push_back(newBuf); @@ -1509,7 +1524,8 @@ bool FileManager::loadFileData(Document doc, int64_t fileSize, const TCHAR * fil fileFormat._encoding = detectCodepage(data, lenFile); } - if (fileFormat._language == L_TEXT) + bool isLargeFile = fileSize >= NPP_STYLING_FILESIZE_LIMIT; + if (!isLargeFile && fileFormat._language == L_TEXT) { // check the language du fichier fileFormat._language = detectLanguageFromTextBegining((unsigned char *)data, lenFile); diff --git a/PowerEditor/src/ScintillaComponent/Buffer.h b/PowerEditor/src/ScintillaComponent/Buffer.h index 4f065b58a..5b29408ca 100644 --- a/PowerEditor/src/ScintillaComponent/Buffer.h +++ b/PowerEditor/src/ScintillaComponent/Buffer.h @@ -155,7 +155,7 @@ public: // this method 1. copies the file name // 2. determinates the language from the ext of file name // 3. gets the last modified time - void setFileName(const TCHAR *fn, LangType defaultLang = L_TEXT); + void setFileName(const TCHAR *fn); const TCHAR * getFullPathName() const { return _fullPathName.c_str(); }