View Issue Details
ID | Project | Category | View Status | Date Submitted | Last Update |
---|---|---|---|---|---|
0002872 | Wishes | User Menu | public | 2014-12-01 08:58 | 2015-07-08 20:32 |
Reporter | Maximus | Assigned To | DrKnS | ||
Priority | normal | Severity | minor | Reproducibility | always |
Status | closed | Resolution | fixed | ||
Product Version | 3.0 | ||||
Fixed in Version | 3.0 | ||||
Summary | 0002872: Не ломать кодовую страницу файла FarMenu.ini | ||||
Description | Мне удобно держать FarMenu.ini в UTF-8. Например, удобно изменения в гите смотреть. Фар такой файл нормально читает, но при любых изменениях через интерфейс - пересохраняет в CP_UNICODE. Приходится каждый раз его открывать в редакторе (с проблемами кодировки) и пересохранять в UTF-8. | ||||
Tags | No tags attached. | ||||
Build | 4351 | ||||
|
0001-Implement-CachedWrite-WriteStr-considering-requested.patch (2,540 bytes)
From 652083cbb2575163edb15618d92fed587754c1e6 Mon Sep 17 00:00:00 2001 From: Maximus5 <ConEmu.Maximus5@gmail.com> Date: Fri, 28 Nov 2014 20:03:44 +0300 Subject: [PATCH 1/2] Implement CachedWrite::WriteStr considering requested codepage --- unicode_far/cache.cpp | 37 +++++++++++++++++++++++++++++++++++-- unicode_far/cache.hpp | 4 +++- 2 files changed, 38 insertions(+), 3 deletions(-) diff --git a/unicode_far/cache.cpp b/unicode_far/cache.cpp index 6645a29..fa3ed2e 100644 --- a/unicode_far/cache.cpp +++ b/unicode_far/cache.cpp @@ -188,11 +188,12 @@ bool CachedRead::FillBuffer() return Result; } -CachedWrite::CachedWrite(api::File& file): +CachedWrite::CachedWrite(api::File& file, uintptr_t codepage): file(file), Buffer(0x10000), FreeSize(Buffer.size()), - Flushed(false) + Flushed(false), + codepage(codepage) { } @@ -233,6 +234,38 @@ bool CachedWrite::Write(LPCVOID Data, size_t DataSize) return Result; } +bool CachedWrite::WriteStr(const wchar_t* SaveStr, size_t Length) +{ + if (!Length) + return true; + + if (codepage == CP_UNICODE) + { + return Write(SaveStr, Length*sizeof(wchar_t)); + } + else + { + auto SwapBytes = [](const wchar_t* src, char* dst, size_t count) + { + return _swab(reinterpret_cast<char*>(const_cast<wchar_t*>(src)), dst, static_cast<int>(count)); + }; + + DWORD length = (codepage == CP_REVERSEBOM?static_cast<DWORD>(Length*sizeof(wchar_t)):WideCharToMultiByte(codepage, 0, SaveStr, Length, nullptr, 0, nullptr, nullptr)); + char_ptr SaveStrCopy(length); + + if (SaveStrCopy) + { + if (codepage == CP_REVERSEBOM) + SwapBytes(SaveStr, SaveStrCopy.get(), length); + else + WideCharToMultiByte(codepage, 0, SaveStr, Length, SaveStrCopy.get(), length, nullptr, nullptr); + + return Write(SaveStrCopy.get(),length); + } + } + return false; +} + bool CachedWrite::Flush() { if (!Flushed) diff --git a/unicode_far/cache.hpp b/unicode_far/cache.hpp index 75fa6ad..c0fadba 100644 --- a/unicode_far/cache.hpp +++ b/unicode_far/cache.hpp @@ -57,9 +57,10 @@ private: class CachedWrite: NonCopyable { public: - CachedWrite(api::File& file); + CachedWrite(api::File& file, uintptr_t codepage = CP_UNICODE); ~CachedWrite(); bool Write(LPCVOID Data, size_t DataSize); + bool WriteStr(const wchar_t* SaveStr, size_t Length); bool Flush(); private: @@ -67,4 +68,5 @@ private: std::vector<BYTE> Buffer; size_t FreeSize; bool Flushed; + uintptr_t codepage; }; -- 1.9.4.msysgit.2 |
|
0002-Don-t-break-FarMenu.ini-s-codepage-saved-by-user.patch (5,549 bytes)
From ef85be261321d03c1214f78570696ba2339aede4 Mon Sep 17 00:00:00 2001 From: Maximus5 <ConEmu.Maximus5@gmail.com> Date: Fri, 28 Nov 2014 20:04:01 +0300 Subject: [PATCH 2/2] Don't break FarMenu.ini's codepage saved by user --- unicode_far/usermenu.cpp | 66 +++++++++++++++++++++++++++++++++++------------- unicode_far/usermenu.hpp | 1 + 2 files changed, 50 insertions(+), 17 deletions(-) diff --git a/unicode_far/usermenu.cpp b/unicode_far/usermenu.cpp index 45e5d1d..b150869 100644 --- a/unicode_far/usermenu.cpp +++ b/unicode_far/usermenu.cpp @@ -129,24 +129,24 @@ static void MenuListToFile(const UserMenu::menu_container& Menu, CachedWrite& CW { std::for_each(CONST_RANGE(Menu, i) { - CW.Write(i.strHotKey.data(), static_cast<DWORD>(i.strHotKey.size()*sizeof(WCHAR))); - CW.Write(L": ", 3*sizeof(WCHAR)); - CW.Write(i.strLabel.data(), static_cast<DWORD>(i.strLabel.size()*sizeof(WCHAR))); - CW.Write(L"\r\n", 2*sizeof(WCHAR)); + CW.WriteStr(i.strHotKey.data(), static_cast<DWORD>(i.strHotKey.size())); + CW.WriteStr(L": ", 3); + CW.WriteStr(i.strLabel.data(), static_cast<DWORD>(i.strLabel.size())); + CW.WriteStr(L"\r\n", 2); if (i.Submenu) { - CW.Write(L"{\r\n", 3*sizeof(WCHAR)); + CW.WriteStr(L"{\r\n", 3); MenuListToFile(i.Menu, CW); - CW.Write(L"}\r\n", 3*sizeof(WCHAR)); + CW.WriteStr(L"}\r\n", 3); } else { std::for_each(CONST_RANGE(i.Commands, str) { - CW.Write(L" ", 4*sizeof(WCHAR)); - CW.Write(str.data(), static_cast<DWORD>(str.size()*sizeof(WCHAR))); - CW.Write(L"\r\n", 2*sizeof(WCHAR)); + CW.WriteStr(L" ", 4); + CW.WriteStr(str.data(), static_cast<DWORD>(str.size())); + CW.WriteStr(L"\r\n", 2); }); } }); @@ -216,7 +216,8 @@ static void MenuFileToList(UserMenu::menu_container& Menu, GetFileString& GetStr UserMenu::UserMenu(bool MenuType): m_MenuMode(MM_LOCAL), m_MenuModified(false), - m_ItemChanged(false) + m_ItemChanged(false), + m_MenuCP(CP_UNICODE) { ProcessUserMenu(MenuType, string()); } @@ -224,7 +225,8 @@ UserMenu::UserMenu(bool MenuType): UserMenu::UserMenu(const string& MenuFileName): m_MenuMode(MM_LOCAL), m_MenuModified(false), - m_ItemChanged(false) + m_ItemChanged(false), + m_MenuCP(CP_UNICODE) { ProcessUserMenu(false, MenuFileName); } @@ -238,6 +240,8 @@ void UserMenu::SaveMenu(const string& MenuFileName) if (m_MenuModified) { DWORD FileAttr=api::GetFileAttributes(MenuFileName); + uintptr_t MenuCP = CP_UNICODE; + api::File MenuFile; if (FileAttr != INVALID_FILE_ATTRIBUTES) { @@ -252,15 +256,41 @@ void UserMenu::SaveMenu(const string& MenuFileName) if (FileAttr & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)) api::SetFileAttributes(MenuFileName,FILE_ATTRIBUTE_NORMAL); + + if (MenuFile.Open(MenuFileName,GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING)) + { + if (!GetFileFormat(MenuFile, MenuCP)) + MenuCP = CP_UNICODE; + else + m_MenuCP = MenuCP; + MenuFile.Close(); + } } // Don't use CreationDisposition=CREATE_ALWAYS here - it kills alternate streams - api::File MenuFile; if (MenuFile.Open(MenuFileName,GENERIC_WRITE, FILE_SHARE_READ, nullptr, FileAttr==INVALID_FILE_ATTRIBUTES?CREATE_NEW:TRUNCATE_EXISTING)) { - CachedWrite CW(MenuFile); - WCHAR Data = SIGN_UNICODE; - CW.Write(&Data, 1*sizeof(WCHAR)); + DWORD dwSignature = 0; + size_t SignLength = 0, SignWritten; + switch (MenuCP) + { + case CP_UNICODE: + dwSignature = SIGN_UNICODE; + SignLength=2; + break; + case CP_REVERSEBOM: + dwSignature = SIGN_REVERSEBOM; + SignLength=2; + break; + case CP_UTF8: + dwSignature = SIGN_UTF8; + SignLength=3; + break; + } + if (SignLength) + MenuFile.Write(&dwSignature,SignLength,SignWritten,nullptr); + + CachedWrite CW(MenuFile, MenuCP); MenuListToFile(m_Menu, CW); CW.Flush(); UINT64 Size = 0; @@ -268,7 +298,7 @@ void UserMenu::SaveMenu(const string& MenuFileName) MenuFile.Close(); // ���� ���� FarMenu.ini ����, �� ������ ��� - if (Size<3) // 2 for BOM + if (Size<=SignLength) { api::DeleteFile(MenuFileName); } @@ -357,6 +387,8 @@ void UserMenu::ProcessUserMenu(bool MenuType, const string& MenuFileName) uintptr_t MenuCP; if (!GetFileFormat(MenuFile, MenuCP)) MenuCP = CP_OEMCP; + else + m_MenuCP = MenuCP; GetFileString GetStr(MenuFile, MenuCP); MenuFileToList(m_Menu, GetStr); @@ -648,7 +680,7 @@ int UserMenu::ProcessSingleMenu(std::list<UserMenuItem>& Menu, int MenuPos, std: { auto OldTitle = std::make_unique<ConsoleTitle>(); SaveMenu(MenuFileName); - auto ShellEditor = FileEditor::create(MenuFileName, CP_UNICODE, FFILEEDIT_DISABLEHISTORY, -1, -1, nullptr); + auto ShellEditor = FileEditor::create(MenuFileName, m_MenuCP, FFILEEDIT_DISABLEHISTORY, -1, -1, nullptr); OldTitle.reset(); Global->WindowManager->ExecuteModal(ShellEditor); if (!ShellEditor->IsFileChanged() || (!MenuFile.Open(MenuFileName, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING))) diff --git a/unicode_far/usermenu.hpp b/unicode_far/usermenu.hpp index 1034e2e..251aeb6 100644 --- a/unicode_far/usermenu.hpp +++ b/unicode_far/usermenu.hpp @@ -57,5 +57,6 @@ private: MENUMODE m_MenuMode; bool m_MenuModified; bool m_ItemChanged; + uintptr_t m_MenuCP; menu_container m_Menu; }; -- 1.9.4.msysgit.2 |
|
может быть просто всегда сохранять в UTF-8 ? |
|
Я за. А кому-то понадобится KOI8-R. Не? |
|
<off> KOI-8 понадобится M$ :-) У них до сих пор в клиенте Outlook эта кодировка дефолтовая. </off> |
|
Голосую за (хоть за сохранение кодировки, хоть за UTF-8 всегда). Столкнулся, как только включил некоторые свои файлы меню в гит. |
|
4351. Новое меню сохраняется в UTF-8. Сохранённое в каком-нибудь более другом юникоде таким и останется. Сохранённое не в юникоде при любом изменении пересохранится в UTF-8. |
Date Modified | Username | Field | Change |
---|---|---|---|
2014-12-01 08:58 | Maximus | New Issue | |
2014-12-01 09:03 | Maximus | File Added: 0001-Implement-CachedWrite-WriteStr-considering-requested.patch | |
2014-12-01 09:03 | Maximus | File Added: 0002-Don-t-break-FarMenu.ini-s-codepage-saved-by-user.patch | |
2014-12-01 11:20 | 2useven10 | Note Added: 0013292 | |
2014-12-01 11:24 | Maximus | Note Added: 0013293 | |
2014-12-01 11:51 | DrKnS | Assigned To | => DrKnS |
2014-12-01 11:51 | DrKnS | Status | new => assigned |
2014-12-01 12:58 | vskirdin | Note Added: 0013294 | |
2015-04-15 15:03 | NightRoman | Note Added: 0013635 | |
2015-04-15 20:18 | DrKnS | Note Added: 0013636 | |
2015-04-15 20:18 | DrKnS | Status | assigned => feedback |
2015-07-08 20:32 | DrKnS | Build | => 4351 |
2015-07-08 20:32 | DrKnS | Status | feedback => closed |
2015-07-08 20:32 | DrKnS | Resolution | open => fixed |
2015-07-08 20:32 | DrKnS | Fixed in Version | => 3.0 |