diff options
author | elfmz <fenix1905@tut.by> | 2022-01-02 01:45:08 +0300 |
---|---|---|
committer | elfmz <fenix1905@tut.by> | 2022-01-02 01:45:08 +0300 |
commit | db8e1fe3581314575b2e1c7f76ca768a6a5e0302 (patch) | |
tree | 0812f74bc8a8eaba1b1d851d881f813433e7e2b3 /far2l/src/mix | |
parent | c8fe1f5c03630903c56bf9c019bb0d1320285888 (diff) |
backport help F7 functionality (touch #1162) and editor search refactor
Diffstat (limited to 'far2l/src/mix')
-rw-r--r-- | far2l/src/mix/strmix.cpp | 129 | ||||
-rw-r--r-- | far2l/src/mix/strmix.hpp | 2 |
2 files changed, 131 insertions, 0 deletions
diff --git a/far2l/src/mix/strmix.cpp b/far2l/src/mix/strmix.cpp index b2af2383..00dd62de 100644 --- a/far2l/src/mix/strmix.cpp +++ b/far2l/src/mix/strmix.cpp @@ -39,6 +39,8 @@ THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. #include "language.hpp" #include "config.hpp" #include "pathmix.hpp" +#include "RegExp.hpp" +#include "StackHeapArray.hpp" FARString &FormatNumber(const wchar_t *Src, FARString &strDest, int NumDigits) { @@ -1377,3 +1379,130 @@ std::string UnescapeUnprintable(const std::string &str) } return out; } + +bool SearchString(const wchar_t *Source, int StrSize, const FARString& Str, FARString& ReplaceStr,int& CurPos, int Position,int Case,int WholeWords,int Reverse,int Regexp, int *SearchLength,const wchar_t* WordDiv) +{ + *SearchLength = 0; + + if (!WordDiv) + WordDiv=Opt.strWordDiv; + + if (Reverse) + { + Position--; + + if (Position>=StrSize) + Position=StrSize-1; + + if (Position<0) + return false; + } + + if ((Position<StrSize || (!Position && !StrSize)) && !Str.IsEmpty()) + { + if (Regexp) + { + FARString strSlash(Str); + InsertRegexpQuote(strSlash); + RegExp re; + // Q: что важнее: опция диалога или опция RegExp`а? + if (!re.Compile(strSlash, OP_PERLSTYLE|OP_OPTIMIZE|(!Case?OP_IGNORECASE:0))) + return false; + + int n = re.GetBracketsCount(); + StackHeapArray<RegExpMatch> m(n); + RegExpMatch *pm = m.Get(); + + bool found = false; + int half = 0; + if (!Reverse) + { + if (re.SearchEx(ReStringView(Source, StrSize),Position,pm,n)) + found = true; + } + else + { + int pos = 0; + for (;;) + { + if (!re.SearchEx(ReStringView(Source, StrSize), pos,pm+half,n)) + break; + pos = static_cast<int>(pm[half].start); + if (pos > Position) + break; + + found = true; + ++pos; + half = n - half; + } + half = n - half; + } + if (found) + { + *SearchLength = pm[half].end - pm[half].start; + CurPos = pm[half].start; + ReplaceStr=ReplaceBrackets(Source,ReplaceStr,pm+half,n); + } + + return found; + } + + if (Position==StrSize) + return false; + + int Length = *SearchLength = (int)Str.GetLength(); + + for (int I=Position; (Reverse && I>=0) || (!Reverse && I<StrSize); Reverse ? I--:I++) + { + for (int J=0;; J++) + { + if (!Str[J]) + { + CurPos=I; + return true; + } + + if (WholeWords) + { + int locResultLeft=FALSE; + int locResultRight=FALSE; + wchar_t ChLeft=Source[I-1]; + + if (I>0) + locResultLeft=(IsSpace(ChLeft) || wcschr(WordDiv,ChLeft)); + else + locResultLeft=TRUE; + + if (I+Length<StrSize) + { + wchar_t ChRight=Source[I+Length]; + locResultRight=(IsSpace(ChRight) || wcschr(WordDiv,ChRight)); + } + else + { + locResultRight=TRUE; + } + + if (!locResultLeft || !locResultRight) + break; + } + + wchar_t Ch=Source[I+J]; + + if (Case) + { + if (Ch!=Str[J]) + break; + } + else + { + if (Upper(Ch)!=Upper(Str[J])) + break; + } + } + } + } + + return false; +} + diff --git a/far2l/src/mix/strmix.hpp b/far2l/src/mix/strmix.hpp index e9ec6e5a..2c84649e 100644 --- a/far2l/src/mix/strmix.hpp +++ b/far2l/src/mix/strmix.hpp @@ -122,3 +122,5 @@ void Transform(FARString &strBuffer,const wchar_t *ConvStr,wchar_t TransformType wchar_t GetDecimalSeparator(); FARString ReplaceBrackets(const FARString& SearchStr,const FARString& ReplaceStr,RegExpMatch* Match,int Count); + +bool SearchString(const wchar_t *Source, int StrSize, const FARString& Str, FARString& ReplaceStr,int& CurPos, int Position,int Case,int WholeWords,int Reverse,int Regexp, int *SearchLength,const wchar_t* WordDiv=nullptr); |