View Issue Details

IDProjectCategoryView StatusLast Update
0002294WishesEditorpublic2017-11-12 01:36
ReporterMikeMirzayanovAssigned ToDrKnS 
PrioritynormalSeverityminorReproducibilityN/A
Status assignedResolutionopen 
Product Version3.0 
Target VersionFixed in Version 
Summary0002294: Идея и реализация PreserveStyle в SearchReplace (есть патч)
DescriptionПредлагаю добавить режим «умной» замены в поиск-замену в редакторе. Прилагаю полный diff с реализацией. Вроде только не поправил документацию и не протащил PreserveStyle в EditorOptions (не уверен, что это надо). Смогу сделать и то и другое, если есть заинтересованность в использовании моего патча.

Идея.

Редактируя исходные тексты (и не только), часто надо делать замену с сохранением стиля написания (что-то вроде рефакторинга «rename»).

Простой пример. Во фразе «A number of a bytes» надо заменить «the» на «a». В идеале одной заменой надо получить «The number of the bytes». Именно с таким регистром символов.

Пример сложнее. Пусть есть следующий гипотетический код (написан просто для примера):
public class UserName {
    public static final int MAX_USER_NAME_SIZE = 100;

    /* Я так не называю поля в Java, странное имя - для полноты примера :) */
    private String m_userNameText = null;

    public void setUserNameText(String userNameText) {
        m_userNameText = userNameText;
    }

    public String getUserNameText() {
        if (m_userNameText == null) {
            return ConfigurationProperties.get("default_user_name")
                    || ConfigurationProperties.get("default.user.name")
                    || ConfigurationProperties.get("default-user-name");
        }

        return m_userNameText;
    }
}

В нем хочется заменить «UserName» на «PersonalLoginId» и получить такое (обратите внимание на регистры и стилизацию всех упоминаний PersonalLoginId):
public class PersonalLoginId {
    public static final int MAX_PERSONAL_LOGIN_ID_SIZE = 100;

    /* Я так не называю поля в Java, странное имя - для полноты примера :) */
    private String m_personalLoginIdText = null;

    public void setPersonalLoginIdText(String personalLoginIdText) {
        m_personalLoginIdText = personalLoginIdText;
    }

    public String getPersonalLoginIdText() {
        if (m_personalLoginIdText == null) {
            return ConfigurationProperties.get("default_personal_login_id")
                    || ConfigurationProperties.get("default.personal.login.id")
                    || ConfigurationProperties.get("default-personal-login-id");
        }

        return m_personalLoginIdText;
    }
}

Т.е. при замене угадывается стиль того что заменяется и заменяемый текст под этот стиль преобразуется. Оба примера работают в одну замену в пропатченном мной FAR-е.
Additional InformationЕсли надо что-то доработать/исправить/пояснить, сделаю всё что надо.

Может добавить аналогичную тему в форум в Предложения и идеи, послушать что люди скажут?
TagsNo tags attached.
Build

Activities

MikeMirzayanov

2013-02-09 03:57

reporter  

PreserveStyle.diff (26,005 bytes)
PreserveStyle.diff (26,005 bytes)

alexy

2013-02-09 04:17

administrator   bugnote:0010235

Такому место в плагине. Зачем это в фар пихать?

MikeMirzayanov

2013-02-09 04:26

reporter   bugnote:0010236

Это общая функциональность - она полезна при правке любого текста, даже литературного. Не говоря уже об исходниках. Мне кажется, что такой режим может быть часто востребован (вот Regular Expressions есть же).

alexy

2013-02-09 04:30

administrator   bugnote:0010237

Это специфичный функционал, с не совсем предвиденным результатом. В стороннем плагине (или даже макросе) ему самое место.

MikeMirzayanov

2013-02-09 04:48

reporter   bugnote:0010238

Ну ок, хотя меня не убедили. Кажется, что таким функционалом почти всегда можно пользоваться, больно уж часто проблемы как минимум с регистром при заменах. Это всегда мешает. А точки зрения пользователя даже результат Whole words тоже непредвиденный - так как какой там список сепараторов мало кто знает. А какой-нибудь встроенный Process List значительно дальше от files-and-archives, чем прокачка редактора, однако он в ядре.

Ну да ладно.

Какой плагин порекомендуете взять за основу? Что наиболее похожее из существующего уже есть, что использует современный Plugin API? Возможно ли как-то встроиться в стандартный диалог Search-Replace и процесс замены (чтобы автоматически работал доп. диалог Replace-All-Skip-Cancel)?

MikeMirzayanov

2013-02-09 04:54

reporter   bugnote:0010239

Из аргументов почему он может быть в FAR-е еще такое - эта функциональность органично встроилась в существующий функционал. Т.е. для пользователя добавилась одна галочка в одном диалоге и все. Никаких других неожиданностей нет. Она не требует доп-знаний или чтения документации, название "Preserve style" (Сохранять стиль) довольно самоописательное. Поведение довольно интуитивное.

Ну и мне просто кажется, что эта крутая фича, которая выгодно бы отличала FAR от других редакторов файлов. Вот Regular Expressions встроили же.

alexy

2013-02-09 04:57

administrator   bugnote:0010240

Можешь вырезать нужный код из самого фара и переделать его на plugin api, думаю не так уже и много работы.
Для самого близкого примера можно посмотреть на плагин EditCase.

alexy

2013-02-09 05:01

administrator   bugnote:0010241

Ну напиши на форуме, посмотрим что там скажут.

DrKnS

2013-02-09 13:47

administrator   bugnote:0010242

А мне идея нравится.

MikeMirzayanov

2013-02-09 14:08

reporter   bugnote:0010243

Спасибо. Какой план? Могу написать на форум и приложить пропатченный FAR, чтобы можно было самостоятельно без накатывания патча попробовать, как все работает.

DrKnS

2013-02-09 14:19

administrator   bugnote:0010244

Да.

DrKnS

2013-02-09 16:18

administrator   bugnote:0010260

А, и почему PreserveStyle, если это по факту PreserveCase?

MikeMirzayanov

2013-02-09 16:40

reporter   bugnote:0010261

Не совсем. Посмотрите второй пример. Он сохраняет ТАКОЙ_СПОСОБ_ИМЕНОВАНИЯ, такой_способ_именования, такой-способ-именования, такой.способ.именования и прочее (разделители настраиваются константой static const wchar_t *PreserveStyleTokenSeparators = L"_-."; в preservestyle.cpp).

Для литературных текстов он выродится в PreserveCase, а в исходниках получается помощней. Мне кажется PreserveStyle более общее и отражающее суть название.

DrKnS

2013-02-12 23:57

administrator   bugnote:0010272

Build 3182, с парой изменений, чтобы предупреждений не было.

Ждём документацию.

DAtaMan

2013-02-13 13:01

reporter   bugnote:0010277

Может, стоит сделать PreserveStyleTokenSeparators настраиваемым?
Хотя бы через far:config

MikeMirzayanov

2013-02-14 19:28

reporter  

help.diff (2,330 bytes)
Index: unicode_far/FarRus.hlf.m4
===================================================================
--- unicode_far/FarRus.hlf.m4	(revision 9639)
+++ unicode_far/FarRus.hlf.m4	(working copy)
@@ -3001,6 +3001,8 @@
       #Регулярные выражения# - ^<wrap>использовать регулярные выражения для ~поиска~@RegExp@ и ~замены~@RegExpRepl@.
 Поиск построчный, поэтому многострочные конструкции и переводы строк не будут найдены.
 
+      #Сохранять стиль#      - ^<wrap>сохранять стиль (регистр и форматирование для файлов исходных текстов) во время ~замены~@RegExpRepl@.
+
     При нажатии кнопки #Всё# будет показано ~меню~@FindAllMenu@ с результатами поиска всех вхождений.
 
 @FindAllMenu
Index: unicode_far/FarEng.hlf.m4
===================================================================
--- unicode_far/FarEng.hlf.m4	(revision 9639)
+++ unicode_far/FarEng.hlf.m4	(working copy)
@@ -2954,11 +2954,13 @@
       #Reverse search#      - ^<wrap>change the direction of search (from the end of file towards the beginning)
 
       #Regular expressions# - ^<wrap>treat input as Perl regular expression (~search~@RegExp@ and ~replace~@RegExpRepl@).
-Поиск построчный, поэтому многострочные конструкции и переводы строк не будут найдены.
+It processes lines separately, so multi-line entries line-break characters will not be found.
 
-    При нажатии кнопки #Всё# будет показано ~меню~@FindAllMenu@ с результатами поиска всех вхождений.
+      #Preserve style#      - ^<wrap>preserve style (case and code style for program source files) (~replace~@RegExpRepl@).
 
+    By pressing the button #All# it will be shown the ~menu~@FindAllMenu@ with the whole list of matched entries.
 
+
 @FindAllMenu
 $ #Редактор: меню с результатами поиска всех вхождений#
     В этом меню доступны следующие сочетания клавиш:
help.diff (2,330 bytes)

MikeMirzayanov

2013-02-14 19:28

reporter   bugnote:0010293

Загрузил файл help.diff с документацией.

vskirdin

2013-02-15 10:19

administrator   bugnote:0010296

Мне кажется (если следовать стилю, что "Help в Far Manager достаточно полно и понятно описывает..."), что "Preserve style" заслуживает отдельного топика в хелпе, описывающего более детально как ЭТО работает (пример - "@HardSymLink"). В дополнении к help.diff.

vskirdin

2013-02-18 09:55

administrator   bugnote:0010312

2MikeMirzayanov: так топик-разжовыватель этой фишки в хелпе будет?

MikeMirzayanov

2013-02-18 16:27

reporter   bugnote:0010313

2vskirdin: да, я напишу подробный текст

MikeMirzayanov

2013-02-28 01:48

reporter  

PreserveStyle-Description.diff (6,600 bytes)
Index: unicode_far/FarRus.hlf.m4
===================================================================
--- unicode_far/FarRus.hlf.m4	(revision 9730)
+++ unicode_far/FarRus.hlf.m4	(working copy)
@@ -3004,10 +3004,60 @@
       #Регулярные выражения# - ^<wrap>использовать регулярные выражения для ~поиска~@RegExp@ и ~замены~@RegExpRepl@.
 Поиск построчный, поэтому многострочные конструкции и переводы строк не будут найдены.
 
-      #Сохранять стиль#      - ^<wrap>сохранять стиль (регистр и форматирование для файлов исходных текстов) во время замены.
+      ~Сохранять стиль~@PreserveStyle@      - ^<wrap>сохранять стиль (регистр и форматирование для файлов исходных текстов) во время замены.
 
     При нажатии кнопки #Всё# будет показано ~меню~@FindAllMenu@ с результатами поиска всех вхождений.
 
+
+@PreserveStyle
+$ #Режим замены: Сохранять стиль#
+
+Режим замены #"Сохранять стиль"# позволяет осуществлять замену с сохранением регистра
+заменяемого текста и/или стиля его написания для файлов исходных текстов. Например,
+при замене в этом режиме во фразе #"Tu be or not tu be"# слова #"tu"# на слово #"to"# будет
+получен результат: #"To be or not to be"# (обратите внимание на регистр). Аналогично,
+при замене #"UserName"# на #"PersonLogin"# в следующем фрагменте:
+
+    #String writerUserName = user.name || DEFAULT_USER_NAME || configuration("default-user-name");#
+
+будет получен результат:
+
+    #String writerPersonLogin = person.login || DEFAULT_PERSON_LOGIN || configuration("default-person-login");#
+
+Обратите внимание, что замена сохранила стиль именования идентификаторов для всех вхождений.
+
+Замена с сохранением стиля использует следующий алгоритм.
+    1   Образец и результат замены разбиваются на части, используя символы #"_-."# в
+        качестве разделителей, кроме того разделением считается изменение регистра
+        буквы со строчной на прописную. Разбиение осуществляется только по одному из
+        вариантов, если существует неоднозначность в выборе правила, то данная строка
+        считается одной частью. Например, строки "testMe", "WhatIsIt", "far-manager",
+        "USER_FIRST_NAME" будут разбиты на части (две, три, две и три части
+        соответственно), а строки «test_userName”, “one.two-three” разбиты не будут
+        (остануться одной частью). Все получившиеся части как образца, так и результата
+        замены не пусты (кроме тривиальных случаев пустых строк в качестве образца
+        и/или текста замены).
+    2   Осуществляется проход по тексту и поиск таких подстрок, которые при разбиении
+        на части в соответствии с пунктом 1 дают в точности те же части, что и образец
+        (при сравнении частей регистр игнорируется).
+    3   Для всех частей найденной подстроки вычисляется набор правил форматирования
+        под которые он подходит. Возможные варианты: "все прописными", "все строчными",
+        "первая заглавная, затем все строчными", "произвольный формат". Вариант
+        "произвольный формат" добавляется в набор в любом случае. Для первой части подстроки
+        набор сохраняется как есть, а остальные наборы (для всех частей кроме первой)
+        пересекаются как множества.
+    4   Набор частей результата замены преобразуется так, что первая часть форматируется
+        в соответствии с самым сильным из правил в наборе правил первой части строки,
+        а остальные - в соответствии с самым сильным из правил в найденном пересечении
+        правил.
+    5   Набор частей замены соединяется в с сохранением того разделителя, которым разделены
+        части обрабатываемой подстроки. Результат записывается на место подстроки.
+    6   Если таким способом не получилось сделать ни одной замены, то осуществляется
+        поиск-замена стандартным способом. При замене, если и в образце и в заменяемом
+        тексте первый символ – буква, то регистр этой буквы сохраняется (то есть
+        приводится к регистру первой буквы заменяемой подстроки).
+
+
 @FindAllMenu
 $ #Редактор: меню с результатами поиска всех вхождений#
     В этом меню доступны следующие сочетания клавиш:

MikeMirzayanov

2013-02-28 01:49

reporter   bugnote:0010393

Написал подробное описание на русском. Давайте отредактируем его, затем переведу на английский.

vskirdin

2013-02-28 10:00

administrator   bugnote:0010394

> 5 Набор частей замены соединяется в с сохранением того
недописано: "в с"?
Добавил немного отформатированный вариант.

vskirdin

2013-02-28 10:00

administrator  

PreserveStyle.hlf (5,134 bytes)

DrKnS

2013-03-17 16:30

administrator   bugnote:0010535

Есть, например, текст:

свистелки.и.сопелки
Свистелки.И.Сопелки
СВИСТЕЛКИ.И.СОПЕЛКИ
Свистелки.и.Сопелки

меняю "свистелки.и.сопелки" на "bells.and.whistles" со включенной опцией.

получаю
bells.and.whistles
Bells.And.Whistles
BELLS.AND.WHISTLES
Bells.and.whistles

Почему не сохранился регистр в последней строке?

MikeMirzayanov

2013-03-17 17:11

reporter   bugnote:0010536

Потому что стиль определяется одновременно для всех токенов. В данном случае есть смешение стиля и легко ошибиться, сделав неверную замену. Например, как заменять в случае, если количество токенов в образце и результате замены не совпадает?

Как вариант, можно сделать так: если кол-во токенов одинаково, то сохранять стиль токенов отдельно по одному. Кажется, что это решит эту проблему и, возможно, это будет частый способ использования.

DrKnS

2013-03-17 17:40

administrator   bugnote:0010537

> Как вариант, можно сделать так:

Я как раз об этом. Для одинакового числа токенов неопределённости нет, и, как по мне, это более ожидаемое поведение.

MikeMirzayanov

2013-03-17 18:29

reporter   bugnote:0010538

Да, сделаю такое поведение.

alexy

2013-04-28 17:20

administrator   bugnote:0010913

Что с этим?

MikeMirzayanov

2013-04-30 03:59

reporter  

PreserveStyle-Improvement.diff (5,834 bytes)
Index: unicode_far/preservestyle.cpp
===================================================================
--- unicode_far/preservestyle.cpp	(revision 10203)
+++ unicode_far/preservestyle.cpp	(working copy)
@@ -167,30 +167,11 @@
 {
 	std::list<PreserveStyleToken> Tokens = InternalPreserveStyleTokenize(strStr, From, Length);
 
-	int Mask = -1;
-	bool First = true;
 	std::for_each(RANGE(Tokens, i)
 	{
-		if (First)
-		{
-			i.TypeMask = GetPeserveCaseStyleMask(i.Token);
-			First = false;
-		}
-		else
-		{
-			if (Mask == -1)
-				Mask = GetPeserveCaseStyleMask(i.Token);
-			else
-				Mask &= GetPeserveCaseStyleMask(i.Token);
-		}
+		i.TypeMask = GetPeserveCaseStyleMask(i.Token);
 	});
 
-	auto Start = Tokens.begin();
-	++Start;
-	std::for_each(Start, Tokens.end(), [&Mask](VALUE_TYPE(Tokens)& i)
-	{
-		i.TypeMask = Mask;
-	});
 	return Tokens;
 }
 
@@ -228,6 +209,63 @@
 	return Result;
 }
 
+void FindStyleTypeMaskAndPrependCharByExpansion(const wchar_t* Source, const size_t StrSize, const int Begin, const int End, int& TypeMask, wchar_t& PrependChar)
+{
+	/* Try to expand to the right. */
+	{
+		int Right = End;
+
+		if (static_cast<size_t>(Right) < StrSize && (IsAlphaNum(Source[Right]) || IsPreserveStyleTokenSeparator(Source[Right])))
+		{
+			Right++;
+			
+			while (static_cast<size_t>(Right) < StrSize)
+			{
+				if (!IsAlphaNum(Source[Right]) || (IsLower(Source[Right-1]) && IsUpper(Source[Right])))
+					break;
+				Right++;
+			}
+
+			const std::list<PreserveStyleToken> SegmentTokens = PreserveStyleTokenize(Source, Begin, Right-Begin);
+
+			if (SegmentTokens.size() > 1)
+			{
+				TypeMask = SegmentTokens.back().TypeMask;
+				PrependChar = SegmentTokens.back().PrependChar;
+				return;
+			}
+		}
+	}
+
+	/* Try to expand to the left. */
+	{
+		int Left = Begin - 1;
+
+		if (Left >= 1 && (IsAlphaNum(Source[Left]) || IsPreserveStyleTokenSeparator(Source[Left])))
+		{
+			Left--;
+
+			while (Left >= 0)
+			{
+				if (!IsAlphaNum(Source[Left]) || (IsLower(Source[Left]) && IsUpper(Source[Left + 1])))
+					break;
+				Left--;
+			}
+
+			Left++;
+
+			const std::list<PreserveStyleToken> SegmentTokens = PreserveStyleTokenize(Source, Left, End-Left);
+
+			if (SegmentTokens.size() > 1)
+			{
+				TypeMask = SegmentTokens.back().TypeMask;
+				PrependChar = SegmentTokens.back().PrependChar;
+				return;
+			}
+		}
+	}
+}
+
 bool PreserveStyleReplaceString(const wchar_t* Source, size_t StrSize, const string& Str, string& ReplaceStr, int& CurPos, int Position, int Case, int WholeWords, const wchar_t *WordDiv, int Reverse, int& SearchLength)
 {
 	SearchLength = 0;
@@ -338,24 +376,74 @@
 				for(auto SrcI = SourceTokens.cbegin(), StrI = StrTokens.cbegin(); Same && SrcI != SourceTokens.cend(); ++SrcI, ++StrI)
 					Same &= SrcI->Token.GetLength() == StrI->Token.GetLength();
 			}
+
 			if (Same)
 			{
 				std::list<PreserveStyleToken> ReplaceStrTokens = PreserveStyleTokenize(ReplaceStr, 0, ReplaceStr.GetLength());
-				ToPreserveStyleType(ReplaceStrTokens.front().Token, ChoosePreserveStyleType(SourceTokens.front().TypeMask));
-				ReplaceStrTokens.front().PrependChar = SourceTokens.front().PrependChar;
 
-				if (!SourceTokens.empty())
+				if (ReplaceStrTokens.size() == SourceTokens.size())
 				{
-					auto ReplaceI = ReplaceStrTokens.begin();
-					++ReplaceI;
+					int CommonTypeMask = -1;
+					std::for_each(RANGE(SourceTokens, i)
+					{
+						if (CommonTypeMask == -1)
+							CommonTypeMask = i.TypeMask;
+						else
+							CommonTypeMask &= i.TypeMask;
+					});
+
+					PreserveStyleType CommonType = ChoosePreserveStyleType(CommonTypeMask);
+					if (CommonTypeMask != -1 && CommonType == UNKNOWN)
+						CommonTypeMask = -1;
+
 					auto SourceI = SourceTokens.cbegin();
-					++SourceI;
-					for (; ReplaceI != ReplaceStrTokens.end(); ++ReplaceI, ++SourceI)
+					std::for_each(RANGE(ReplaceStrTokens, i)
 					{
-						ToPreserveStyleType(ReplaceI->Token, ChoosePreserveStyleType(SourceI->TypeMask));
-						ReplaceI->PrependChar = SourceTokens.back().PrependChar;
+						ToPreserveStyleType(i.Token, CommonTypeMask != -1 ? CommonType : ChoosePreserveStyleType(SourceI->TypeMask));
+						i.PrependChar = SourceI->PrependChar;
+						SourceI++;
+					});
+				}
+				else
+				{
+					ToPreserveStyleType(ReplaceStrTokens.front().Token, ChoosePreserveStyleType(SourceTokens.front().TypeMask));
+					ReplaceStrTokens.front().PrependChar = SourceTokens.front().PrependChar;
+
+					if (!SourceTokens.empty())
+					{
+						int AfterFirstCommonTypeMask = -1;
+						wchar_t PrependChar = SourceTokens.back().PrependChar;
+						
+						auto SourceI = SourceTokens.cbegin();
+						++SourceI;
+						for (; SourceI != SourceTokens.end(); ++SourceI)
+						{
+							if (AfterFirstCommonTypeMask == -1)
+								AfterFirstCommonTypeMask = SourceI->TypeMask;
+							else
+								AfterFirstCommonTypeMask &= SourceI->TypeMask;
+						}
+
+						if (AfterFirstCommonTypeMask == -1)
+							FindStyleTypeMaskAndPrependCharByExpansion(Source, StrSize, I, Idx, AfterFirstCommonTypeMask, PrependChar);
+
+						if (AfterFirstCommonTypeMask == -1)
+						{
+							AfterFirstCommonTypeMask = SourceTokens.front().TypeMask;
+							PrependChar = ReplaceStrTokens.back().PrependChar;
+						}
+
+						auto ReplaceI = ReplaceStrTokens.begin();
+						++ReplaceI;
+						for (; ReplaceI != ReplaceStrTokens.end(); ++ReplaceI)
+						{
+							ToPreserveStyleType(ReplaceI->Token, ChoosePreserveStyleType(AfterFirstCommonTypeMask));
+							ReplaceI->PrependChar = PrependChar;
+						}
 					}
+
 				}
+
 				ReplaceStr.Clear();
 				std::for_each(CONST_RANGE(ReplaceStrTokens, i)
 				{

MikeMirzayanov

2013-04-30 04:03

reporter   bugnote:0010924

Добавил PreserveStyle-Improvement.diff

В нем реализовано сохранение стилей по токенам, если их количество совпадает. Кроме того, значительно улучшено поведение, если заменяемый токен единственный.

Например, при замене "size" на "lengthOrCount" в MAX_SIZE=12 получится MAX_LENGTH_OR_COUNT, а раньше было плохо.

После того как получу подтверждение, что текущее поведение нравится, то могу актуализировать описание алгоритма в документации. Кстати, после этого надо английское описание написать.

DrKnS

2013-04-30 22:24

administrator   bugnote:0010928

3378

MikeMirzayanov

2013-04-30 22:53

reporter   bugnote:0010929

Я не уверен в корректности некоторых ваших правок. Например, замена int на size_t в строке "size_t Left = Begin - 1;" может быть небезопасна. При Begin=0 получим переполнение. Кроме того, код в FindStyleTypeMaskAndPrependCharByExpansion для двух случаев был максимально симметричен, а теперь стал разным. В этой же функции случай удлинения влево (второй) мне кажется исправлен неправильно. Например, мой цикл "while (Left >= 0)" завершался с постусловием, что Left указывает на 1 позицию левее разрыва (поэтому затем шел Left++), в от время как в вашем варианте цикл "for (;;)" благодаря "if (!Left) break;" завершится в Left=0 (если явного разрыва не нашлось). Это нарушает постусловие и дальше код уже неверен (например, Left++ уже делать не надо бы).

Возможно есть еще проблемы, я внимательно пока не все прочитал. Кстати, я бы к основной функции preservestyle.cpp написал бы тестов - это было бы полезно. Есть инфраструктура для тестов? Куда и как их лучше написать?

DrKnS

2013-04-30 23:22

administrator   bugnote:0010930

Там был варнинг, я поправил как смог :)

В 3379 должно быть как надо.


Тесты - это здорово, но инфраструктуры пока нет, так что всё обсуждаемо.

MikeMirzayanov

2013-04-30 23:48

reporter   bugnote:0010931

Да, теперь ОК.

Кстати, а зачем всюду исправили std::vector на std::list. Конечно, память может чуток экономите, но итерации по std::list значительно медленнее из-за cache miss + проще ухудшить производительность за счет O(n) операций size и [].

О тестах подумаю.

DrKnS

2013-04-30 23:53

administrator   bugnote:0010933

В рамках глобального рефакторинга.
Если здесь это критично по скорости - не вопрос, пусть будет вектор.

MikeMirzayanov

2013-05-01 00:10

reporter   bugnote:0010934

Думать надо, скорее ничего страшного. Я посмотрю.

Просто, кажется, это странный рефакторинг. Вроде как-раз по-дефолту лучше vector использовать из-за причин, что я описал. На StackOverflow тоже обсуждалось, вроде это общее мнение сообщества.

Еще вопрос - чем компилируете, что появлялись warnings? Я компилирую MinGW 4.7.2 вот так "build.bat gcc 32 [debug]". Может добавить "-Wextra -Wconversion" в makefile_gcc_common?

DrKnS

2013-05-01 00:42

administrator   bugnote:0010935

vc2010/2012.

-Wextra -Wconversion пока даёт слишком много лишнего, но в перспективе можно, да.

fml2

2013-05-01 22:24

reporter   bugnote:0010941

В справке по этой уникальной функции я нашел несколько опечаток. Вот они:

1. "будут (остануться одной частью).": в слове "остануться" надо убрать мягкий знак (т.е. правильно будет "останутся")

2. "...части как образца, так и результата замены не пусты...": после "части" и после "замены" я бы поставил тире

3. "набор правил форматирования под которые он подходит": после "форматирования" надо поставить запятую

DrKnS

2014-01-19 20:32

administrator   bugnote:0011722

MikeMirzayanov, проверьте пожалуйста имплементацию InternalPreserveStyleTokenize.

Там есть такое:

wchar_t Sep = 0;
...
if (Sep != 0 && strStr[I] != Sep)
{

}

Похоже, что никогда не исполняется.

MikeMirzayanov

2014-01-20 00:04

reporter   bugnote:0011723

Похоже это правда. Я перечитал код, видимо это осталось от какой-то промежуточной версии. Прикладываю патч, где вырезал этот момент.

MikeMirzayanov

2014-01-20 00:04

reporter  

preservestyle.cpp.patch (790 bytes)
Index: preservestyle.cpp
===================================================================
--- preservestyle.cpp	(revision 11364)
+++ preservestyle.cpp	(working copy)
@@ -81,23 +81,12 @@
 {
 	std::list<PreserveStyleToken> Result;
 
-	wchar_t Sep = 0;
 	std::vector<bool> Seps(Length, false);
 	for (size_t I = From+1; I+1 < From+Length; I++)
 		if (IsPreserveStyleTokenSeparator(strStr[I])
 				&& !IsPreserveStyleTokenSeparator(strStr[I-1])
 				&& !IsPreserveStyleTokenSeparator(strStr[I+1]))
 		{
-			if (Sep != 0 && strStr[I] != Sep)
-			{
-				PreserveStyleToken T;
-				T.Token = strStr.substr(From, Length);
-				T.PrependChar = 0;
-				T.TypeMask = 1 << UNKNOWN;
-				Result.emplace_back(T);
-				return Result;
-			}
-
 			Seps[I-From] = true;
 		}
 

JohnDoe

2017-11-11 19:38

updater   bugnote:0015823

Не доделано?

fml2

2017-11-12 01:36

reporter   bugnote:0015830

Ошибки в справке тоже не исправлены (см. 0002294:0010941).

Issue History

Date Modified Username Field Change
2013-02-09 03:57 MikeMirzayanov New Issue
2013-02-09 03:57 MikeMirzayanov File Added: PreserveStyle.diff
2013-02-09 04:17 alexy Note Added: 0010235
2013-02-09 04:26 MikeMirzayanov Note Added: 0010236
2013-02-09 04:30 alexy Note Added: 0010237
2013-02-09 04:48 MikeMirzayanov Note Added: 0010238
2013-02-09 04:54 MikeMirzayanov Note Added: 0010239
2013-02-09 04:57 alexy Note Added: 0010240
2013-02-09 05:01 alexy Note Added: 0010241
2013-02-09 13:47 DrKnS Note Added: 0010242
2013-02-09 14:08 MikeMirzayanov Note Added: 0010243
2013-02-09 14:19 DrKnS Note Added: 0010244
2013-02-09 16:18 DrKnS Note Added: 0010260
2013-02-09 16:40 MikeMirzayanov Note Added: 0010261
2013-02-12 23:57 DrKnS Note Added: 0010272
2013-02-13 13:01 DAtaMan Note Added: 0010277
2013-02-14 19:28 MikeMirzayanov File Added: help.diff
2013-02-14 19:28 MikeMirzayanov Note Added: 0010293
2013-02-15 10:19 vskirdin Note Added: 0010296
2013-02-16 01:13 DrKnS Assigned To => DrKnS
2013-02-16 01:13 DrKnS Status new => assigned
2013-02-18 09:55 vskirdin Note Added: 0010312
2013-02-18 16:27 MikeMirzayanov Note Added: 0010313
2013-02-28 01:48 MikeMirzayanov File Added: PreserveStyle-Description.diff
2013-02-28 01:49 MikeMirzayanov Note Added: 0010393
2013-02-28 10:00 vskirdin Note Added: 0010394
2013-02-28 10:00 vskirdin File Added: PreserveStyle.hlf
2013-03-17 16:30 DrKnS Note Added: 0010535
2013-03-17 17:11 MikeMirzayanov Note Added: 0010536
2013-03-17 17:40 DrKnS Note Added: 0010537
2013-03-17 18:29 MikeMirzayanov Note Added: 0010538
2013-04-28 17:20 alexy Note Added: 0010913
2013-04-30 03:59 MikeMirzayanov File Added: PreserveStyle-Improvement.diff
2013-04-30 04:03 MikeMirzayanov Note Added: 0010924
2013-04-30 22:24 DrKnS Note Added: 0010928
2013-04-30 22:53 MikeMirzayanov Note Added: 0010929
2013-04-30 23:22 DrKnS Note Added: 0010930
2013-04-30 23:48 MikeMirzayanov Note Added: 0010931
2013-04-30 23:53 DrKnS Note Added: 0010933
2013-05-01 00:10 MikeMirzayanov Note Added: 0010934
2013-05-01 00:42 DrKnS Note Added: 0010935
2013-05-01 22:24 fml2 Note Added: 0010941
2014-01-19 20:32 DrKnS Note Added: 0011722
2014-01-20 00:04 MikeMirzayanov Note Added: 0011723
2014-01-20 00:04 MikeMirzayanov File Added: preservestyle.cpp.patch
2017-11-11 19:38 JohnDoe Note Added: 0015823
2017-11-12 01:36 fml2 Note Added: 0015830