Index: sakura_core/CBregexp.h =================================================================== --- sakura_core/CBregexp.h (リビジョン 2138) +++ sakura_core/CBregexp.h (作業コピー) @@ -105,21 +105,42 @@ @name 結果を得るメソッドを追加し、BREGEXPを外部から隠す */ /*! + パターンに含まれる括弧(キャプチャグループ)の数。 + */ + int GetGroupCount() const + { + return m_pRegExp->nparens; + } + /*! 検索に一致した文字列の先頭位置を返す(文字列先頭なら0) @retval 検索に一致した文字列の先頭位置 */ CLogicInt GetIndex(void) { - return CLogicInt(m_pRegExp->startp[0] - m_szTarget); + return GetIndex(0); } + CLogicInt GetIndex(int groupIndex) + { + if (groupIndex < 0 || m_pRegExp->nparens < groupIndex) { // invalid arg + return CLogicInt(-1); + } + return CLogicInt(m_pRegExp->startp[groupIndex] - m_szTarget); + } /*! 検索に一致した文字列の次の位置を返す @retval 検索に一致した文字列の次の位置 */ CLogicInt GetLastIndex(void) { - return CLogicInt(m_pRegExp->endp[0] - m_szTarget); + return GetLastIndex(0); } + CLogicInt GetLastIndex(int groupIndex) + { + if (groupIndex < 0 || m_pRegExp->nparens < groupIndex) { // invalid arg + return CLogicInt(-1); + } + return CLogicInt(m_pRegExp->endp[groupIndex] - m_szTarget); + } /*! 検索に一致した文字列の長さを返す @retval 検索に一致した文字列の長さ Index: sakura_core/view/colors/CColor_Found.cpp =================================================================== --- sakura_core/view/colors/CColor_Found.cpp (リビジョン 2138) +++ sakura_core/view/colors/CColor_Found.cpp (作業コピー) @@ -4,6 +4,7 @@ #include "types/CTypeSupport.h" #include "view/CViewSelect.h" #include +#include // reverse, find_if void CColor_Select::OnStartScanLogic() @@ -74,9 +75,10 @@ void CColor_Found::OnStartScanLogic() { - m_nSearchResult = 1; m_nSearchStart = CLogicInt(-1); m_nSearchEnd = CLogicInt(-1); + strategyColor = COLORIDX_DEFAULT; + reservedHighlightRanges.clear(); this->validColorNum = 0; const CEditDoc* const pDoc = CEditDoc::GetInstance(0); @@ -98,34 +100,86 @@ return false; } + // (以前の検索により)予約されていたハイライト結果を展開する。 + while (! this->reservedHighlightRanges.empty()) { + this->m_nSearchEnd = this->reservedHighlightRanges.back().searchEnd; + this->strategyColor = this->reservedHighlightRanges.back().strategyColor; + this->reservedHighlightRanges.pop_back(); + if (nPos < this->m_nSearchEnd) { + this->m_nSearchStart = CLogicInt(nPos); + break; + } + } + // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // 検索ヒットフラグ設定 -> bSearchStringMode // // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- // // 2002.02.08 hor 正規表現の検索文字列マークを少し高速化 - if(!pcView->m_sCurSearchOption.bRegularExp || (m_nSearchResult && m_nSearchStart < nPos)){ - m_nSearchResult = pcView->IsSearchString( + if( m_nSearchStart < nPos ){ + int searchResult = pcView->IsSearchString( cStr, CLogicInt(nPos), &m_nSearchStart, &m_nSearchEnd ); + if (! searchResult) { + if (pcView->m_sCurSearchOption.bRegularExp) { + // 正規表現検索がこの行ではもう成功しないことがわかってるので、再検索を防ぐ。 + m_nSearchStart = m_nSearchEnd = CLogicInt(0x0FFFFFFF); // テキトーにありえなく大きい数。 + } else { + m_nSearchStart = m_nSearchEnd = CLogicInt(-1); + } + } + if (searchResult && this->validColorNum != 0) { + // ハイライトの色。 + this->strategyColor = this->highlightColors[ (searchResult - 1) % this->validColorNum ]; + } + if (searchResult && pcView->m_sCurSearchOption.bRegularExp && 0 < pcView->m_CurRegexp.GetGroupCount()) { + struct find_f { + CLogicInt val; + find_f(CLogicInt val) : val(val) {} + bool operator()(const HighlightRange_t& v) const + { return this->val < v.searchEnd; } + }; + // サブパターンを塗り分けるための準備。予約する。 + this->reservedHighlightRanges.reserve(pcView->m_CurRegexp.GetGroupCount() * 2 + 1); + this->reservedHighlightRanges.push_back(HighlightRange_t(pcView->m_CurRegexp.GetLastIndex(0), this->strategyColor)); + for (int gi = 1; gi <= pcView->m_CurRegexp.GetGroupCount(); ++gi) { + CLogicInt start = pcView->m_CurRegexp.GetIndex(gi); + CLogicInt end = pcView->m_CurRegexp.GetLastIndex(gi); + if (start == end) { + continue; + } + EColorIndexType color = this->highlightColors[ gi % this->validColorNum ]; + + std::vector::const_iterator it = std::find_if(this->reservedHighlightRanges.begin(), this->reservedHighlightRanges.end(), find_f(start)); + if (it == this->reservedHighlightRanges.end()) { + continue; + } + this->reservedHighlightRanges.insert(this->reservedHighlightRanges.insert(it, HighlightRange_t(end, color)), HighlightRange_t(start, it->strategyColor)); + } + std::reverse( this->reservedHighlightRanges.begin(), this->reservedHighlightRanges.end() ); + + // コピペ: (以前の検索により)予約されていたハイライト結果を展開する。 + while (! this->reservedHighlightRanges.empty()) { + this->m_nSearchEnd = this->reservedHighlightRanges.back().searchEnd; + this->strategyColor = this->reservedHighlightRanges.back().strategyColor; + this->reservedHighlightRanges.pop_back(); + if (nPos < this->m_nSearchEnd) { + this->m_nSearchStart = CLogicInt(nPos); + break; + } + } + } } - //マッチ文字列検出 - if( m_nSearchResult && m_nSearchStart==nPos){ - return true; - } - return false; + + //マッチ文字列を検出した(true)、しなかった(false)。 + return m_nSearchStart == nPos; } bool CColor_Found::EndColor(const CStringRef& cStr, int nPos) { - //マッチ文字列終了検出 - if( m_nSearchEnd <= nPos ){ //+ == では行頭文字の場合、m_nSearchEndも0であるために文字色の解除ができないバグを修正 2003.05.03 かろと - // -- -- マッチ文字列を描画 -- -- // - - return true; - } - - return false; + //マッチ文字列終了を検出した(true)、しなかった(false)。 + return m_nSearchEnd <= nPos; //+ == では行頭文字の場合、m_nSearchEndも0であるために文字色の解除ができないバグを修正 2003.05.03 かろと } Index: sakura_core/view/colors/CColor_Found.h =================================================================== --- sakura_core/view/colors/CColor_Found.h (リビジョン 2138) +++ sakura_core/view/colors/CColor_Found.h (作業コピー) @@ -24,6 +24,7 @@ #ifndef SAKURA_CCOLOR_FOUND_60044D4E_3082_4A9D_98C5_2FE626D3DA1E_H_ #define SAKURA_CCOLOR_FOUND_60044D4E_3082_4A9D_98C5_2FE626D3DA1E_H_ +#include "vector" #include "view/colors/CColorStrategy.h" class CColor_Select : public CColorStrategy{ @@ -49,7 +50,7 @@ public: CColor_Found(); virtual EColorIndexType GetStrategyColor() const - { return this->validColorNum != 0 ? this->highlightColors[ (m_nSearchResult - 1) % this->validColorNum ] : COLORIDX_DEFAULT; } + { return this->strategyColor; } //色替え virtual void InitStrategyStatus(){ } //############要検証 virtual bool BeginColor(const CStringRef& cStr, int nPos); @@ -58,9 +59,17 @@ virtual void OnStartScanLogic(); private: - int m_nSearchResult; - CLogicInt m_nSearchStart; - CLogicInt m_nSearchEnd; + CLogicInt m_nSearchStart; + CLogicInt m_nSearchEnd; + EColorIndexType strategyColor; + + struct HighlightRange_t { + CLogicInt searchEnd; + EColorIndexType strategyColor; + HighlightRange_t(CLogicInt searchEnd, EColorIndexType strategyColor): searchEnd(searchEnd), strategyColor(strategyColor) {} + }; + std::vector reservedHighlightRanges; + EColorIndexType highlightColors[ COLORIDX_SEARCHTAIL - COLORIDX_SEARCH + 1 ]; ///< チェックが付いている検索文字列色の配列。 unsigned validColorNum; ///< highlightColorsの何番目の要素までが有効か。 };