NumeRe v1.1.4
NumeRe: Framework für Numerische Rechnungen
searchcontroller.cpp
Go to the documentation of this file.
1/*****************************************************************************
2 NumeRe: Framework fuer Numerische Rechnungen
3 Copyright (C) 2019 Erik Haenel et al.
4
5 This program is free software: you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation, either version 3 of the License, or
8 (at your option) any later version.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with m_editor program. If not, see <http://www.gnu.org/licenses/>.
17******************************************************************************/
18
19#include "searchcontroller.hpp"
20#include "editor.h"
21#include "../terminal/terminal.hpp"
22
23using namespace std;
24
35{
37 return vector<wxString>();
38
39 // Find all "procedure" commands in the current file
40 vector<int> vMatch = FindAll("procedure", wxSTC_NPRC_COMMAND, 0, m_editor->GetLastPosition(), false);
41
42 if (!vMatch.size())
43 return vector<wxString>();
44
45 vector<wxString> vProcDef;
46
47 // Go through all matches and store the corresponding
48 // definitions in the procedure definitions vector
49 for (size_t i = 0; i < vMatch.size(); i++)
50 {
51 int pos = vMatch[i]+9;
52
53 // Find the dollar sign
54 pos = m_editor->FindText(pos, m_editor->GetLineEndPosition(m_editor->LineFromPosition(pos)), "$");
55
56 if (pos == wxSTC_INVALID_POSITION)
57 continue;
58
59 // Find the procedure definition
60 if (FindMarkedProcedure(pos+1, false).length())
61 vProcDef.push_back(FindProcedureDefinition());
62 }
63
64 return vProcDef;
65}
66
67
82vector<int> SearchController::FindAll(const wxString& sSymbol, int nStyle, int nStartPos, int nEndPos, bool bSearchInComments)
83{
84 vector<int> vMatches;
85 int nCurrentPos = 0;
86
87 if (!sSymbol.length())
88 return vMatches;
89
90 // Change the style of the string parser to the identifier
91 // style
92 if ((m_editor->m_fileType == FILE_NSCR || m_editor->m_fileType == FILE_NPRC) && nStyle == wxSTC_NSCR_STRING_PARSER)
93 nStyle = wxSTC_NSCR_IDENTIFIER;
94
95 // Search the next occurence
96 while ((nCurrentPos = m_editor->FindText(nStartPos, nEndPos, sSymbol, wxSTC_FIND_MATCHCASE | wxSTC_FIND_WHOLEWORD)) != wxSTC_INVALID_POSITION)
97 {
98 nStartPos = nCurrentPos+1;
99
100 // Is it the correct style and no field of a structure?
101 if (m_editor->GetCharAt(nCurrentPos-1) != '.'
102 && (m_editor->GetStyleAt(nCurrentPos) == nStyle
103 || ((m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_LINE, nCurrentPos) || m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_BLOCK, nCurrentPos)) && bSearchInComments)
104 || (m_editor->GetStyleAt(nCurrentPos) == wxSTC_NSCR_STRING_PARSER && (m_editor->m_fileType == FILE_NSCR || m_editor->m_fileType == FILE_NPRC))))
105 vMatches.push_back(nCurrentPos);
106 }
107
108 // return the found matches
109 return vMatches;
110}
111
112
120{
121 int charpos = m_editor->PositionFromPoint(m_editor->m_lastRightClick);
122 int startPosition = m_editor->WordStartPosition(charpos, true);
123 int endPosition = m_editor->WordEndPosition(charpos, true);
124
125 wxString clickedWord = m_editor->GetTextRange(startPosition, endPosition);
126 m_editor->m_clickedWordLength = endPosition - startPosition;
127 m_editor->m_clickedWord = clickedWord;
128 return clickedWord;
129}
130
131
142{
143 int charpos = m_editor->PositionFromPoint(m_editor->m_lastRightClick);
144 return FindMarkedInclude(charpos);
145}
146
147
159{
160 int startPosition = m_editor->WordStartPosition(charpos, true);
161 int endPosition = m_editor->WordEndPosition(startPosition + 1, true);
162
163 // Find the first position
164 while (startPosition && m_editor->GetStyleAt(startPosition - 1) == wxSTC_NSCR_INCLUDES && m_editor->GetCharAt(startPosition - 1) != '@')
165 startPosition--;
166
167 // Ignore the quotation mark
168 if (m_editor->GetCharAt(startPosition) == '"')
169 startPosition++;
170
171 // Find the last position and exclude the trailing
172 // quotation mark automatically
173 while (endPosition < m_editor->GetLastPosition() && m_editor->GetStyleAt(endPosition) == wxSTC_NSCR_INCLUDES && m_editor->GetCharAt(endPosition) != ':' && m_editor->GetCharAt(endPosition) != '"')
174 endPosition++;
175
176 // Get the name from the positions
177 wxString clickedWord = m_editor->GetTextRange(startPosition, endPosition);
178
179 // Resolve path tokens, which are probably
180 // part of the name
181 if (clickedWord.find('<') != string::npos)
182 {
183 if (clickedWord.find("<>") != string::npos)
184 clickedWord.replace(clickedWord.find("<>"), 2, m_terminal->getPathSettings()[EXEPATH]);
185
186 if (clickedWord.find("<this>") != string::npos)
187 clickedWord.replace(clickedWord.find("<this>"), 6, m_editor->GetFileName().GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR));
188
189 if (clickedWord.find("<loadpath>") != string::npos)
190 clickedWord.replace(clickedWord.find("<loadpath>"), 10, m_terminal->getPathSettings()[LOADPATH]);
191
192 if (clickedWord.find("<savepath>") != string::npos)
193 clickedWord.replace(clickedWord.find("<savepath>"), 10, m_terminal->getPathSettings()[SAVEPATH]);
194
195 if (clickedWord.find("<scriptpath>") != string::npos)
196 clickedWord.replace(clickedWord.find("<scriptpath>"), 12, m_terminal->getPathSettings()[SCRIPTPATH]);
197
198 if (clickedWord.find("<procpath>") != string::npos)
199 clickedWord.replace(clickedWord.find("<procpath>"), 10, m_terminal->getPathSettings()[PROCPATH]);
200
201 if (clickedWord.find("<plotpath>") != string::npos)
202 clickedWord.replace(clickedWord.find("<plotpath>"), 10, m_terminal->getPathSettings()[PLOTPATH]);
203 }
204
205 // Prepend the script folder, if necessary
206 if (clickedWord.length() > 2 && ((isalpha(clickedWord[0]) && clickedWord[1] == ':') || clickedWord[0] == '.'))
207 m_editor->m_clickedInclude = clickedWord + ".nscr";
208 else
209 m_editor->m_clickedInclude = m_terminal->getPathSettings()[SCRIPTPATH] + "/" + clickedWord + ".nscr";
210
211 return replacePathSeparator(clickedWord.ToStdString());
212}
213
214
225{
226 int charpos = m_editor->PositionFromPoint(m_editor->m_lastRightClick);
227 return FindMarkedProcedure(charpos);
228}
229
230
243wxString SearchController::FindMarkedProcedure(int charpos, bool ignoreDefinitions)
244{
245 int startPosition = m_editor->WordStartPosition(charpos, true);
246 int endPosition = m_editor->WordEndPosition(charpos, true);
247
248 // Search for the first procedure character
249 while (startPosition && m_editor->GetStyleAt(startPosition - 1) == wxSTC_NSCR_PROCEDURES)
250 startPosition--;
251
252 // Search for the last procedure character
253 while (endPosition < m_editor->GetLastPosition()
254 && m_editor->GetStyleAt(endPosition) == wxSTC_NSCR_PROCEDURES
255 && m_editor->GetCharAt(endPosition) != '\r'
256 && m_editor->GetCharAt(endPosition) != '\n')
257 endPosition++;
258
259 // Ignore procedure definitions, if the
260 // flag is set to true
261 if (ignoreDefinitions)
262 {
263 wxString currentline = m_editor->GetLine(m_editor->LineFromPosition(startPosition));
264
265 if (currentline.find("procedure") != string::npos && currentline[currentline.find_first_not_of(' ', currentline.find("procedure") + 9)] == '$')
266 return "";
267 }
268
269 // Extract the procedure call
270 wxString clickedWord = m_editor->GetTextRange(startPosition, endPosition);
271
272 // Insert the namespaces, if we use
273 // definition as well
274 if (!ignoreDefinitions && clickedWord.find('~') == string::npos && GetNameOfNamingProcedure() != clickedWord)
275 {
276 clickedWord.insert(1, "thisfile~");
277 }
278
279 // Search the namespace of the current call
280 // and insert it
281 if (m_editor->m_fileType == FILE_NPRC && clickedWord.find('~') == string::npos)
282 {
283 // Find the the namespace
284 wxString sNameSpace = FindNameSpaceOfProcedure(charpos);
285
286 // Fallback namespace, if we're currently also searching
287 // definitions
288 if (!sNameSpace.length() && !ignoreDefinitions)
289 sNameSpace = "this";
290
291 // Insert the namespace, if it is
292 // available
293 if (sNameSpace.length())
294 {
295 if (clickedWord[0] == '$')
296 clickedWord.insert(1, sNameSpace + "~");
297 else
298 clickedWord = "$" + sNameSpace + "~" + clickedWord;
299 }
300 }
301
302 // Store the procedure call
303 m_editor->m_clickedProcedure = clickedWord;
304
305 // Remove namespaces for the context menu
306 if (clickedWord.find('~') != string::npos)
307 clickedWord.erase(1, clickedWord.rfind('~'));
308
309 if (clickedWord[0] != '$')
310 clickedWord.insert(0, 1, '$');
311
312 // Return the string for the context menu
313 return clickedWord + "()";
314}
315
316
329{
330 wxString sNameSpace;
331
333 {
334 int minpos = 0;
335 int maxpos = charpos;
336
337 // Find the start of the current procedure
338 minpos = FindCurrentProcedureHead(charpos);
339
340 // Find all occurences of "namespace" between
341 // the minimal and the maximal position
342 vector<int> namespaces = FindAll("namespace", wxSTC_NPRC_COMMAND, minpos, maxpos, false);
343
344 // Use the last namespace command, if there
345 // are any, and decode it
346 if (namespaces.size())
347 {
348 sNameSpace = decodeNameSpace(m_editor->GetLine(m_editor->LineFromPosition(namespaces.back())).ToStdString(), "this");
349 }
350 }
351
352 return sNameSpace;
353}
354
355
367wxString SearchController::FindProceduresInCurrentFile(wxString sFirstChars, wxString sSelectedNameSpace)
368{
369 wxString sThisFileProcedures;
370
371 // Go through the whole file
372 for (int i = 0; i < m_editor->GetLineCount(); i++)
373 {
374 wxString currentline = m_editor->GetLine(i);
375
376 // Search for procedure commands
377 if (currentline.find("procedure") != string::npos
378 && currentline.find('$', currentline.find("procedure")) != string::npos
379 && !m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_LINE, m_editor->PositionFromLine(i) + currentline.find("procedure"))
380 && !m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_BLOCK, m_editor->PositionFromLine(i) + currentline.find("procedure")))
381 {
382 currentline.erase(0, currentline.find('$') + 1);
383
384 if (currentline.find('(') == string::npos)
385 continue;
386
387 currentline.erase(currentline.find('('));
388
389 // combine all matches to the list of procedures
390 if (currentline.substr(0, sFirstChars.length()) == sFirstChars)
391 sThisFileProcedures += currentline + "(?" + toString(NumeReSyntax::SYNTAX_PROCEDURE) + " ";
392 }
393 }
394
395 if (sSelectedNameSpace.length())
396 return sThisFileProcedures;
397
398 return sThisFileProcedures + m_editor->_syntax->getNameSpaceAutoCompList(sFirstChars.ToStdString());
399}
400
401
411{
412 // do nothing, if there's no currently selected procedure
413 if (!m_editor->m_clickedProcedure.length())
414 return "";
415
416 vector<std::string> vPaths = m_terminal->getPathSettings();
417 wxString pathname = m_editor->m_clickedProcedure;
418 wxString procedurename = pathname.substr(pathname.rfind('~') + 1); // contains a "$", if it's not used for the "thisfile~" case
419
420 // Handle the namespaces
421 if (pathname.find("$this~") != string::npos)
422 {
423 // This namespace (the current folder)
424 wxString thispath = m_editor->GetFileNameAndPath();
425 pathname.replace(pathname.find("$this~"), 6, thispath.substr(0, thispath.rfind('\\') + 1));
426
427 while (pathname.find('~') != string::npos)
428 pathname[pathname.find('~')] = '\\';
429 }
430 else if (pathname.find("$thisfile~") != string::npos)
431 {
432 // local namespace
433 return FindProcedureDefinitionInLocalFile(procedurename);
434 }
435 else
436 {
437 // All other namespaces
438 if (pathname.find("$main~") != string::npos)
439 pathname.erase(pathname.find("$main~") + 1, 5);
440
441 while (pathname.find('~') != string::npos)
442 pathname[pathname.find('~')] = '/';
443
444 // Add the root folders to the path name
445 if (pathname[0] == '$' && pathname.find(':') == string::npos)
446 pathname.replace(0, 1, vPaths[PROCPATH] + "/");
447 else if (pathname.find(':') == string::npos)
448 pathname.insert(0, vPaths[PROCPATH]);
449 else // pathname.find(':') != string::npos
450 {
451 // Absolute file paths
452 pathname = pathname.substr(pathname.find('\'') + 1, pathname.rfind('\'') - pathname.find('\'') - 1);
453 }
454 }
455
456 // Find the namespace in absolute procedure paths
457 while (procedurename.find('\'') != string::npos)
458 procedurename.erase(procedurename.find('\''), 1);
459
460 if (procedurename.find('/') != string::npos)
461 procedurename = "$" + procedurename.substr(procedurename.rfind('/') + 1);
462
463 if (procedurename.find('\\') != string::npos)
464 procedurename = "$" + procedurename.substr(procedurename.rfind('\\') + 1);
465
466 if (procedurename[0] != '$')
467 procedurename.insert(0, 1, '$');
468
469 // Find procedure in a global procedure file
470 NumeRe::CallTip _procDef = NumeRe::addLinebreaks(NumeRe::FindProcedureDefinition(pathname.ToStdString(), procedurename.ToStdString()));
471
472 if (_procDef.sDocumentation.length())
473 return _procDef.sDefinition + "\n" + _procDef.sDocumentation;
474
475 return _procDef.sDefinition;
476}
477
478
490wxString SearchController::FindProcedureDefinitionInLocalFile(const wxString& procedurename)
491{
492 wxString procedureline;
493
494 // Force Scintilla to style the whole document
495 if (m_editor->GetLastPosition() > m_editor->GetEndStyled() && !m_editor->GetWrapMode())
496 {
497 m_editor->SetWrapMode(wxSTC_WRAP_WORD);
498 m_editor->SetWrapMode(wxSTC_WRAP_NONE);
499 }
500
501 // Go through the whole file and search for all occurences of the procedure
502 // command
503 vector<int> procedures = FindAll("procedure", wxSTC_NSCR_COMMAND, 0, m_editor->GetLastPosition(), false);
504
505 // Examine each occurence
506 for (size_t i = 0; i < procedures.size(); i++)
507 {
508 procedureline = m_editor->GetLine(m_editor->LineFromPosition(procedures[i]));
509
510 if (procedureline.find("$" + procedurename) != string::npos && procedureline[procedureline.find_first_not_of(' ', procedureline.find("$" + procedurename) + procedurename.length() + 1)] == '(')
511 {
512 if (getMatchingParenthesis(procedureline.substr(procedureline.find("$" + procedurename)).ToStdString()) == string::npos)
513 return "";
514
515 // Extraxt the procedure definition
516 string sProcDef = procedureline.substr(procedureline.find("$" + procedurename), getMatchingParenthesis(procedureline.substr(procedureline.find("$" + procedurename)).ToStdString()) + 1).ToStdString();
517 size_t nFirstParens = sProcDef.find('(');
518 string sArgList = sProcDef.substr(nFirstParens + 1, getMatchingParenthesis(sProcDef.substr(nFirstParens)) - 1);
519 sProcDef.erase(nFirstParens + 1);
520
521 // Handle the argument list
522 while (sArgList.length())
523 {
524 string currentarg = getNextArgument(sArgList, true);
525
526 if (currentarg.front() == '_')
527 currentarg.erase(0, 1);
528
529 sProcDef += currentarg;
530
531 if (sArgList.length())
532 sProcDef += ", ";
533 }
534
535 sProcDef += ") :: local";
536
537 // Handle the flags
538 if (procedureline.find("::") != string::npos)
539 {
540 string sFlags = procedureline.substr(procedureline.find("::") + 2).ToStdString();
541
542 if (sFlags.find("##") != string::npos)
543 sFlags.erase(sFlags.find("##"));
544
545 if (sFlags.find_first_of("\r\n") != string::npos)
546 sFlags.erase(sFlags.find_first_of("\r\n"));
547
548 StripSpaces(sFlags);
549 sProcDef += " " + sFlags;
550 }
551
552 wxString sDocumentation;
553
554 // Find now the documentations - documentation lines above
555 // the current line are preferred:
556 for (int docline = m_editor->LineFromPosition(procedures[i])-1; docline >= 0; docline--)
557 {
558 if (!m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_SECTION_LINE, m_editor->GetLineIndentPosition(docline))
559 && !m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_SECTION_BLOCK, m_editor->GetLineIndentPosition(docline)))
560 {
561 if (docline < m_editor->LineFromPosition(procedures[i])-1)
562 {
563 for (int curline = docline+1; curline < m_editor->LineFromPosition(procedures[i]); curline++)
564 {
565 wxString curdocline = m_editor->GetLine(curline);
566 curdocline.erase(0, curdocline.find_first_not_of(" \t#*!"));
567 curdocline.erase(curdocline.find_first_of("\r\n"));
568
569 if (curdocline.find("*#") != string::npos)
570 curdocline.erase(curdocline.find("*#"));
571
572 AppendToDocumentation(sDocumentation, curdocline);
573 }
574 }
575 break;
576 }
577 }
578
579 // If the documentation string is still empty
580 // search below the definition
581 if (!sDocumentation.length())
582 {
583 for (int docline = m_editor->LineFromPosition(procedures[i])+1; docline < m_editor->GetLineCount(); docline++)
584 {
585 if (!m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_SECTION_LINE, m_editor->GetLineIndentPosition(docline))
586 && !m_editor->isStyleType(NumeReEditor::STYLE_COMMENT_SECTION_BLOCK, m_editor->GetLineIndentPosition(docline)))
587 {
588 if (docline > m_editor->LineFromPosition(procedures[i])+1)
589 {
590 for (int curline = m_editor->LineFromPosition(procedures[i])+1; curline < docline; curline++)
591 {
592 wxString curdocline = m_editor->GetLine(curline);
593 curdocline.erase(0, curdocline.find_first_not_of(" \t#*!"));
594 curdocline.erase(curdocline.find_first_of("\r\n"));
595
596 AppendToDocumentation(sDocumentation, curdocline);
597 }
598 }
599 break;
600 }
601 }
602 }
603
604 // clean the documentation
605 sDocumentation = CleanDocumentation(sDocumentation);
606
607 // Append the documentation if it is present
608 if (sDocumentation.length())
609 {
610 if (sDocumentation.substr(0, 3) == "-> ")
611 sProcDef += " " + sDocumentation.ToStdString();
612 else
613 sProcDef += "\n" + sDocumentation.ToStdString();
614 }
615
616 return sProcDef;
617 }
618 }
619
620 return "";
621}
622
623
631{
632 return "$" + m_editor->GetFileName().GetName();
633}
634
635
647void SearchController::AppendToDocumentation(wxString& sDocumentation, const wxString& sNewDocLine)
648{
649 static bool bBeginEnd = false;
650
651 if (sNewDocLine.find_first_not_of(" \t") == string::npos)
652 {
653 if (sDocumentation.length())
654 sDocumentation += "\n ";
655
656 return;
657 }
658
659 // Handle some special TeX commands and rudimentary lists
660 if (sNewDocLine.find("\\begin{") != string::npos && sNewDocLine.find("\\end{") == string::npos)
661 {
662 if (sDocumentation.length() && sDocumentation[sDocumentation.length()-1] != '\n')
663 sDocumentation += "\n ";
664
665 bBeginEnd = true;
666 }
667 else if (sNewDocLine.find("\\begin{") == string::npos && sNewDocLine.find("\\end{") != string::npos)
668 {
669 if (sDocumentation.length() && sDocumentation[sDocumentation.length()-1] != '\n')
670 sDocumentation += "\n ";
671
672 bBeginEnd = false;
673 }
674 else if ((sNewDocLine.length()
675 && (sNewDocLine.substr(sNewDocLine.find_first_not_of(" \t"), 2) == "- "
676 || sNewDocLine.substr(sNewDocLine.find_first_not_of(" \t"), 7) == "\\param "
677 || sNewDocLine.substr(sNewDocLine.find_first_not_of(" \t"), 8) == "\\remark ")) || bBeginEnd)
678 {
679 if (sDocumentation.length() && sDocumentation[sDocumentation.length()-1] != '\n')
680 sDocumentation += "\n ";
681 }
682 else
683 {
684 if (sDocumentation.length() && sDocumentation[sDocumentation.length()-1] != ' ')
685 sDocumentation += " ";
686 }
687
688 sDocumentation += sNewDocLine.substr(sNewDocLine.find_first_not_of(" \t"));
689 size_t nPos = sDocumentation.find("\\procedure{");
690
691 if (nPos != string::npos)
692 sDocumentation.erase(nPos, sDocumentation.find('}', nPos)+1 - nPos);
693 else if ((nPos = sDocumentation.find("\\procedure ")) != string::npos)
694 {
695 size_t nPos2 = nPos + 10;
696 nPos2 = sDocumentation.find_first_not_of(" \r\n", nPos2);
697 nPos2 = sDocumentation.find_first_of(" \r\n", nPos2);
698 sDocumentation.erase(nPos, nPos2-nPos);
699 }
700}
701
702
712string SearchController::CleanDocumentation(const wxString& __sDoc)
713{
714 string sDocumentation = __sDoc.ToStdString();
715 std::string sReturns;
716
717 if (sDocumentation.find_first_not_of(" \n") != string::npos)
718 {
719 // Clean whitespace before and after the documentation
720 sDocumentation.erase(0, sDocumentation.find_first_not_of(" \n"));
721
722 if (sDocumentation.back() == ' ' || sDocumentation.back() == '\n')
723 sDocumentation.erase(sDocumentation.find_last_not_of(" \n")+1);
724
725 size_t nPos = sDocumentation.find("\\param ");
726
727 // Resolve "\param" keywords
728 if (nPos != string::npos)
729 {
730 // Insert a headline above the first parameter
731 if (nPos > 5 && sDocumentation.substr(nPos-5, 5) != "\n ")
732 sDocumentation.insert(nPos, "\n " + toUpperCase(_guilang.get("GUI_EDITOR_CALLTIP_PROC_PARAMS")) + "\n ");
733 else
734 sDocumentation.insert(nPos, toUpperCase(_guilang.get("GUI_EDITOR_CALLTIP_PROC_PARAMS")) + "\n ");
735
736 while ((nPos = sDocumentation.find("\\param ")) != string::npos)
737 {
738 sDocumentation.replace(nPos, 6, "-");
739 size_t spacePos = sDocumentation.find(' ', sDocumentation.find_first_not_of(' ', nPos+1));
740
741 if (spacePos == std::string::npos)
742 break;
743
744 sDocumentation.insert(spacePos, ":");
745
746 if (sDocumentation[sDocumentation.find_first_not_of(' ', nPos+1)] == '_')
747 sDocumentation.erase(sDocumentation.find_first_not_of(' ', nPos+1), 1);
748 }
749 }
750
751 // Extract \return
752 while ((nPos = sDocumentation.find("\\return ")) != string::npos)
753 {
754 // Find the next \return or \remark alternatively
755 // This is a candidate for issues with new keywords
756 size_t newReturn = std::min(sDocumentation.find("\\return ", nPos+1), sDocumentation.find("\\remark ", nPos+1));
757
758 // Extract the current return statement and
759 // remove the corresponding part from the
760 // documentation
761 std::string sCurrReturn = sDocumentation.substr(nPos+8, newReturn-nPos-8);
762 sDocumentation.erase(nPos, newReturn-nPos);
763
764 while (sDocumentation.front() == ' ')
765 sDocumentation.erase(0, 1);
766
767 if (sReturns.length())
768 sReturns += ",";
769
770 sReturns += sCurrReturn.substr(0, sCurrReturn.find(' '));
771 }
772
773 // Replace \remark
774 while ((nPos = sDocumentation.find("\\remark ")) != string::npos)
775 sDocumentation.replace(nPos, 7, toUpperCase(_guilang.get("GUI_EDITOR_CALLTIP_PROC_REMARK"))+":");
776
777 // Remove doubled exclamation marks
778 while ((nPos = sDocumentation.find("!!")) != string::npos)
779 sDocumentation.erase(nPos, 2);
780
781 // Replace \begin{} and \end{} with line breaks
782 // This logic bases upon the replacements done
783 // in NumeReEditor::AppendToDocumentation
784 size_t nMatch = 0;
785
786 while ((nMatch = sDocumentation.find("\\begin{")) != string::npos)
787 {
788 sDocumentation.erase(nMatch, sDocumentation.find('}', nMatch) + 1 - nMatch);
789
790 if (sDocumentation.substr(nMatch, 5) == "\n ")
791 sDocumentation.erase(nMatch, 5);
792 }
793
794 while ((nMatch = sDocumentation.find("\\end{")) != string::npos)
795 {
796 sDocumentation.erase(nMatch, sDocumentation.find('}', nMatch) + 1 - nMatch + 1);
797 }
798
799 // Check the length of the line (will insert
800 // an additional indentation at the beginning
801 // of the documentation string)
802 sDocumentation = m_editor->addLinebreaks(sDocumentation, true);
803
804 // Insert returns
805 if (sReturns.length())
806 {
807 if (sReturns.find(',') == std::string::npos)
808 sDocumentation.insert(0, "-> " + sReturns + "\n");
809 else
810 sDocumentation.insert(0, "-> {" + sReturns + "}\n");
811 }
812 }
813 else
814 sDocumentation.clear();
815
816 return sDocumentation;
817}
818
819
830{
831 vector<int> procedureheads;
832
833 // Find all occurences of procedure heads in the current
834 // file, which are before the selected position
836 procedureheads = FindAll("procedure", wxSTC_NSCR_COMMAND, 0, pos, false);
837 else if (m_editor->m_fileType == FILE_MATLAB)
838 procedureheads = FindAll("function", wxSTC_MATLAB_KEYWORD, 0, pos, false);
839
840 // If any was found, return the last one
841 if (procedureheads.size())
842 return procedureheads.back();
843
844 return 0;
845}
846
847
858{
859 wxString sNamingProcedure = GetNameOfNamingProcedure() + "(";
860
861 // Go through the whole file and search for all occurences of
862 // the "procedure" command
863 for (int i = 0; i < m_editor->LineFromPosition(m_editor->GetLastPosition()); i++)
864 {
865 wxString currentline = m_editor->GetLine(i);
866
867 if (currentline.find("procedure") != string::npos && currentline.find(sNamingProcedure) != string::npos)
868 {
869 int linepos = m_editor->PositionFromLine(i);
870 int offset = 0;
871
872 while (currentline.find("procedure", offset) != string::npos && m_editor->GetStyleAt(linepos + currentline.find("procedure", offset) + 1) != wxSTC_NPRC_COMMAND)
873 offset = currentline.find("procedure", offset) + 10;
874
875 // If a candidate was found, check, whether it has the correct name
876 if (currentline.find("procedure", offset) != string::npos && m_editor->GetStyleAt(linepos + currentline.find("procedure", offset) + 1) == wxSTC_NPRC_COMMAND)
877 {
878 int procloc = currentline.find("procedure", offset) + 9;
879
880 while (currentline.find(sNamingProcedure, procloc) != string::npos && m_editor->GetStyleAt(linepos + currentline.find(sNamingProcedure, procloc) + 1) != wxSTC_NPRC_PROCEDURES)
881 procloc = currentline.find(sNamingProcedure, procloc) + 1 + sNamingProcedure.length();
882
883 // Return the position of this procedure, if the name is fitting
884 if (currentline.find(sNamingProcedure, procloc) != string::npos && m_editor->GetStyleAt(linepos + currentline.find(sNamingProcedure) + 1) == wxSTC_NPRC_PROCEDURES)
885 return i;
886 }
887 }
888 }
889
890 // Return not found, if nothing was found
891 return wxNOT_FOUND;
892}
893
894
std::string get(const std::string &sMessage, const std::vector< std::string > &vTokens) const
This member function returns the language string for the passed language identifier and replaces all ...
Definition: language.cpp:292
std::string addLinebreaks(const std::string &sLine, bool onlyDocumentation=false)
Adds linebreaks to the call tip language strings.
Definition: editor.cpp:8483
bool isStyleType(StyleType _type, int nPos)
Determine the syntax style type at the selected position.
Definition: editor.cpp:8249
wxString m_clickedInclude
Definition: editor.h:407
wxFileName GetFileName()
Definition: editor.cpp:4328
wxString m_clickedProcedure
Definition: editor.h:406
FileFilterType m_fileType
Definition: editor.h:446
size_t m_clickedWordLength
Definition: editor.h:408
@ STYLE_COMMENT_SECTION_BLOCK
Definition: editor.h:323
@ STYLE_COMMENT_SECTION_LINE
Definition: editor.h:322
@ STYLE_COMMENT_LINE
Definition: editor.h:320
@ STYLE_COMMENT_BLOCK
Definition: editor.h:321
wxString m_clickedWord
Definition: editor.h:405
wxPoint m_lastRightClick
Definition: editor.h:404
NumeReSyntax * _syntax
Definition: editor.h:416
wxString GetFileNameAndPath()
Definition: editor.cpp:4299
@ SYNTAX_PROCEDURE
Definition: syntax.hpp:99
std::string getNameSpaceAutoCompList(std::string sFirstChars)
This function returns the autocompletion list for the namespaces.
Definition: syntax.cpp:974
std::vector< std::string > getPathSettings()
Returns the standard paths as a STL vector.
Definition: terminal.cpp:185
void AppendToDocumentation(wxString &sDocumentation, const wxString &sNewDocLine)
Appends the text to the current documentation.
std::vector< int > FindAll(const wxString &sSymbol, int nStyle, int nStartPos=0, int nEndPos=-1, bool bSearchInComments=false)
Finds all occurences of a code symbol considering the style.
int FindNamingProcedure()
Searches the file for the naming procedure.
wxString FindProceduresInCurrentFile(wxString sFirstChars, wxString sSelectedNameSpace)
Finds procedures, which might match the passed word start.
wxString FindMarkedProcedure(int charpos, bool ignoreDefinitions=true)
Extracts the procedure call at the selected position.
wxString FindNameSpaceOfProcedure(int charpos)
Finds the current namespace for the procedure call.
std::string CleanDocumentation(const wxString &__sDoc)
Checks layout and finishes styling of the documentation string.
wxString GetNameOfNamingProcedure()
Returns the required procedure name for the current file.
wxString FindProcedureDefinition()
Searches the definition below the cursor.
NumeReEditor * m_editor
wxString FindProcedureDefinitionInLocalFile(const wxString &procedurename)
Search the procedure definition in the local file.
wxString FindMarkedInclude(int charpos)
Constructs the file name of the included file.
NumeReTerminal * m_terminal
wxString FindClickedProcedure()
Gets the name of the clicked procedure.
wxString FindClickedInclude()
Gets the name of the clicked include file.
std::vector< wxString > getProceduresInFile()
Creates a list of procedures in the current file.
int FindCurrentProcedureHead(int pos)
Find the procedure head line for the selected position.
wxString FindClickedWord()
Returns the word under the cursor while clicking.
@ SCRIPTPATH
@ EXEPATH
@ LOADPATH
@ PLOTPATH
@ PROCPATH
@ SAVEPATH
@ FILE_NPRC
@ FILE_NSCR
@ FILE_MATLAB
Language _guilang
std::string replacePathSeparator(const std::string &)
This function replaces the Windows style path sparators to UNIX style.
unsigned int getMatchingParenthesis(const StringView &)
Returns the position of the closing parenthesis.
Definition: tools.cpp:414
CallTip FindProcedureDefinition(const std::string &pathname, const std::string &procedurename)
Search the procedure definition in a global file.
CallTip addLinebreaks(CallTip _cTip, size_t maxLineLength)
Adds the necessary linebreaks to the documentation part of the CallTip to fit inside the desired maxi...
#define min(a, b)
Definition: resampler.cpp:34
void StripSpaces(std::string &)
Removes leading and trailing white spaces and tabulator characters.
std::string toUpperCase(const std::string &sLowerCase)
Converts lowercase letters to uppercase ones.
std::string getNextArgument(std::string &sArgList, bool bCut)
Definition: tools.cpp:2294
This structure contains the data for a single calltip, which might be shown in the editor or the term...
std::string sDefinition
std::string sDocumentation
std::string toString(int)
Converts an integer to a string without the Settings bloat.
string decodeNameSpace(string sCommandLine, const string &sThisNameSpace)
Definition: tools.cpp:3476