wxMaxima
Loading...
Searching...
No Matches
Autocomplete.h
Go to the documentation of this file.
1// -*- mode: c++; c-file-style: "linux"; c-basic-offset: 2; indent-tabs-mode: nil -*-
2//
3// Copyright (C) 2009-2015 Andrej Vodopivec <andrej.vodopivec@gmail.com>
4// Copyright (C) 2015 Gunter Königsmann <wxMaxima@physikbuch.de>
5//
6// This program is free software; you can redistribute it and/or modify
7// it under the terms of the GNU General Public License as published by
8// the Free Software Foundation; either version 2 of the License, or
9// (at your option) any later version.
10//
11// This program is distributed in the hope that it will be useful,
12// but WITHOUT ANY WARRANTY; without even the implied warranty of
13// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14// GNU General Public License for more details.
15//
16//
17// You should have received a copy of the GNU General Public License
18// along with this program; if not, write to the Free Software
19// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20//
21// SPDX-License-Identifier: GPL-2.0+
22
30#ifndef AUTOCOMPLETE_H
31#define AUTOCOMPLETE_H
32
33#include <thread>
34#include <algorithm>
35#include <memory>
36#include <mutex>
37#include <wx/wx.h>
38#include <wx/xml/xml.h>
39#include <wx/event.h>
40#include <wx/dir.h>
41#include <vector>
42#include <wx/object.h>
43#include <wx/regex.h>
44#include <wx/filename.h>
45#include <wx/hashmap.h>
46#include "Configuration.h"
47#include "precomp.h"
48#include "Version.h"
49#include <unordered_map>
50/* The autocompletion logic
51
52 The wordlists for autocompletion for keywords come from several sources:
53
54 - wxMaxima::ReadLoadSymbols receive the contents of maxima's variables
55 "values" and "functions" after a package is loaded.
56 - all words that appear in the worksheet
57 - and a list of maxima's builtin commands.
58*/
59class AutoComplete : public wxEvtHandler
60{
61 typedef std::unordered_map <wxString, int, wxStringHash> WorksheetWords;
62public:
63 using WordList = std::vector<wxString>;
64
67 {
68 command = 0,
76 };
77 explicit AutoComplete(Configuration *configuration);
78
80 virtual ~AutoComplete();
81
83 void LoadSymbols();
84
91 void LoadBuiltinSymbols();
92
94 void AddSymbol(wxString fun, autoCompletionType type = command);
96 void AddSymbols(wxString xml);
98 void AddSymbols(wxXmlDocument xml);
100 void AddSymbols_Backgroundtask_string(wxString xml);
102 void AddSymbols_Backgroundtask(wxXmlDocument xmldoc);
103
104
106 void UpdateDemoFiles(wxString partial, const wxString &maximaDir);
108 void UpdateLoadFiles(wxString partial, const wxString &maximaDir);
110 void UpdateGeneralFiles(wxString partial, const wxString &maximaDir);
111
113 void AddWorksheetWords(const WordList &words);
114 void AddWorksheetWords(WordList::const_iterator begin, WordList::const_iterator end);
115
117 void ClearWorksheetWords();
119 void ClearDemofileList();
120
122 std::vector<wxString> CompleteSymbol(wxString partial, autoCompletionType type = command);
124 static wxString FixTemplate(wxString templ);
126 std::vector<wxString> GetDemoFilesList();
128 std::vector<wxString> GetSymbolList();
130 bool HasDemofile(const wxString &commandname);
131
132private:
134 Configuration *m_configuration;
136 void LoadableFiles_BackgroundTask(wxString sharedir, wxString demodir);
138 void BuiltinSymbols_BackgroundTask();
139
141 void UpdateLoadFiles_BackgroundTask(wxString partial, wxString maximaDir);
143 std::vector<wxString> m_builtInLoadFiles;
145 std::vector<wxString> m_builtInDemoFiles;
147 class GetGeneralFiles : public wxDirTraverser
148 {
149 public:
150 explicit GetGeneralFiles(std::vector<wxString>& files,
151 std::mutex *lock,
152 const wxString &prefix = wxEmptyString) :
153 m_files(files), m_lock(lock), m_prefix(prefix) {
154 for(const auto &i : m_files)
155 m_filesHash[i];
156 }
157 wxDirTraverseResult OnFile(const wxString& filename) override
158 {
159 wxFileName newItemName(filename);
160 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "\"";
161 newItem.Replace(wxFileName::GetPathSeparator(), "/");
162 {
163 const std::lock_guard<std::mutex> lock(*m_lock);
164 if (m_filesHash.find(newItem) == m_filesHash.end())
165 {
166 m_files.push_back(newItem);
167 m_filesHash[newItem];
168 }
169 }
170 return wxDIR_CONTINUE;
171 }
172 wxDirTraverseResult OnDir(const wxString& dirname) override
173 {
174 wxFileName newItemName(dirname);
175 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "/\"";
176 newItem.Replace(wxFileName::GetPathSeparator(), "/");
177 {
178 const std::lock_guard<std::mutex> lock(*m_lock);
179 if (m_filesHash.find(newItem) == m_filesHash.end())
180 {
181 m_files.push_back(newItem);
182 m_filesHash[newItem];
183 }
184 }
185 return wxDIR_IGNORE;
186 }
187 std::vector<wxString> GetResult(){
188 const std::lock_guard<std::mutex> lock(*m_lock);
189 return m_files;
190 }
191 protected:
193 std::vector<wxString>& m_files;
195 std::unordered_map<wxString, wxEvtHandler*, wxStringHash> m_filesHash;
196 std::mutex *m_lock;
197 wxString m_prefix;
198 };
199
201 class GetMacFiles_includingSubdirs : public wxDirTraverser
202 {
203 public:
204 explicit GetMacFiles_includingSubdirs(std::vector<wxString>& files,
205 std::mutex *lock,
206 const wxString &prefix = wxEmptyString) :
207 m_files(files), m_lock(lock), m_prefix(prefix)
208 {
209 for(const auto &i : m_files)
210 m_filesHash[i];
211 }
212 wxDirTraverseResult OnFile(const wxString& filename) override
213 {
214 if(
215 (filename.EndsWith(".mac"))||
216 (filename.EndsWith(".lisp"))||
217 (filename.EndsWith(".wxm"))
218 )
219 {
220 wxFileName newItemName(filename);
221 wxString newItem = "\"" + m_prefix + newItemName.GetName() + "\"";
222 newItem.Replace(wxFileName::GetPathSeparator(), "/");
223 {
224 const std::lock_guard<std::mutex> lock(*m_lock);
225 if (m_filesHash.find(newItem) == m_filesHash.end())
226 {
227 m_files.push_back(newItem);
228 m_filesHash[newItem];
229 }
230 }
231 }
232 return wxDIR_CONTINUE;
233 }
234 wxDirTraverseResult OnDir(const wxString& dirname) override
235 {
236 if((dirname.EndsWith(".git")) ||
237 (dirname.EndsWith("/share/share")) ||
238 (dirname.EndsWith("/src/src")) ||
239 (dirname.EndsWith("/doc/doc")) ||
240 (dirname.EndsWith("/interfaces/interfaces"))
241 )
242 return wxDIR_STOP;
243 else
244 return wxDIR_CONTINUE;
245 }
246 std::vector<wxString> GetResult(){
247 const std::lock_guard<std::mutex> lock(*m_lock);
248 return m_files;
249 }
250 protected:
252 std::vector<wxString>& m_files;
254 std::unordered_map<wxString, wxEvtHandler*, wxStringHash> m_filesHash;
255 std::mutex *m_lock;
256 wxString m_prefix;
257 };
258
260 class GetMacFiles : public GetMacFiles_includingSubdirs
261 {
262 public:
263 explicit GetMacFiles(std::vector<wxString>& files,
264 std::mutex *lock,
265 const wxString &prefix = wxEmptyString) :
266 GetMacFiles_includingSubdirs(files, lock, prefix){ }
267 wxDirTraverseResult OnDir(const wxString& dirname) override
268 {
269 wxFileName newItemName(dirname);
270 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "/\"";
271 newItem.Replace(wxFileName::GetPathSeparator(), "/");
272 {
273 const std::lock_guard<std::mutex> lock(*m_lock);
274 if (m_filesHash.find(newItem) == m_filesHash.end())
275 {
276 m_files.push_back(newItem);
277 m_filesHash[newItem];
278 }
279 }
280 return wxDIR_IGNORE;
281 }
282 };
283
285 class GetDemoFiles_includingSubdirs : public wxDirTraverser
286 {
287 public:
288 explicit GetDemoFiles_includingSubdirs(std::vector<wxString>& files,
289 std::mutex *lock,
290 const wxString &prefix = wxEmptyString) :
291 m_files(files), m_lock(lock), m_prefix(prefix)
292 {
293 for(const auto &i : m_files)
294 m_filesHash[i];
295 }
296 wxDirTraverseResult OnFile(const wxString& filename) override
297 {
298 if(filename.EndsWith(".dem"))
299 {
300 wxFileName newItemName(filename);
301 wxString newItem = "\"" + m_prefix + newItemName.GetName() + "\"";
302 newItem.Replace(wxFileName::GetPathSeparator(), "/");
303 {
304 const std::lock_guard<std::mutex> lock(*m_lock);
305 if (m_filesHash.find(newItem) == m_filesHash.end())
306 {
307 m_files.push_back(newItem);
308 m_filesHash[newItem];
309 }
310 }
311 }
312 return wxDIR_CONTINUE;
313 }
314 wxDirTraverseResult OnDir(const wxString& dirname) override
315 {
316 if((dirname.EndsWith(".git")) ||
317 (dirname.EndsWith("/share/share")) ||
318 (dirname.EndsWith("/src/src")) ||
319 (dirname.EndsWith("/doc/doc")) ||
320 (dirname.EndsWith("/interfaces/interfaces"))
321 )
322 return wxDIR_STOP;
323 else
324 return wxDIR_CONTINUE;
325 }
326 std::vector<wxString> GetResult(){
327 const std::lock_guard<std::mutex> lock(*m_lock);
328 return m_files;
329 }
330 protected:
332 std::vector<wxString>& m_files;
334 std::unordered_map<wxString, wxEvtHandler*, wxStringHash> m_filesHash;
335 std::mutex *m_lock;
336 wxString m_prefix;
337 };
338
340 class GetDemoFiles : public GetDemoFiles_includingSubdirs
341 {
342 public:
343 explicit GetDemoFiles(std::vector<wxString>& files,
344 std::mutex *lock,
345 const wxString &prefix = wxEmptyString) :
346 GetDemoFiles_includingSubdirs(files, lock, prefix){ }
347 virtual wxDirTraverseResult OnDir(const wxString& dirname) override
348 {
349 wxFileName newItemName(dirname);
350 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "/\"";
351 newItem.Replace(wxFileName::GetPathSeparator(), "/");
352 {
353 const std::lock_guard<std::mutex> lock(*m_lock);
354 if (m_filesHash.find(newItem) == m_filesHash.end())
355 {
356 m_files.push_back(newItem);
357 m_filesHash[newItem];
358 }
359 }
360 return wxDIR_IGNORE;
361 }
362 };
363
364 jthread m_addSymbols_backgroundThread;
365 jthread m_addFiles_backgroundThread;
367 std::mutex m_keywordsLock;
369 std::vector<std::vector<wxString>> m_wordList;
370 static wxRegEx m_args;
371 WorksheetWords m_worksheetWords;
372};
373
374wxDECLARE_EVENT(NEW_DEMO_FILES_EVENT, wxCommandEvent);
375
376#endif // AUTOCOMPLETE_H
Definition: Autocomplete.h:60
std::vector< wxString > GetSymbolList()
Returns a list of Symbols we know.
Definition: Autocomplete.cpp:62
void AddSymbols_Backgroundtask(wxXmlDocument xmldoc)
The real work of AddSymbols is made here and in the background.
Definition: Autocomplete.cpp:142
virtual ~AutoComplete()
The destructor of AutoComplete.
Definition: Autocomplete.cpp:218
void ClearDemofileList()
Clear the list of files demo() can be applied on.
Definition: Autocomplete.cpp:103
std::vector< wxString > GetDemoFilesList()
Returns a list of demo files we know of.
Definition: Autocomplete.cpp:57
void UpdateDemoFiles(wxString partial, const wxString &maximaDir)
Replace the list of files in the directory the worksheet file is in to the demo files list.
Definition: Autocomplete.cpp:387
void LoadSymbols()
Load all autocomplete symbols wxMaxima knows about by itself.
Definition: Autocomplete.cpp:225
autoCompletionType
All types of things we can autocomplete.
Definition: Autocomplete.h:67
@ tmplte
Command names.
Definition: Autocomplete.h:69
@ generalfile
loadable files
Definition: Autocomplete.h:72
@ demofile
loadable files
Definition: Autocomplete.h:71
@ numberOfTypes
Unit names.
Definition: Autocomplete.h:75
@ unit
Esc commands describing symbols.
Definition: Autocomplete.h:74
@ loadfile
Function templates.
Definition: Autocomplete.h:70
@ esccommand
general files
Definition: Autocomplete.h:73
std::vector< wxString > CompleteSymbol(wxString partial, autoCompletionType type=command)
Returns a list of possible autocompletions for the string "partial".
Definition: Autocomplete.cpp:498
void UpdateLoadFiles(wxString partial, const wxString &maximaDir)
Replace the list of files in the directory the worksheet file is in to the load files list.
Definition: Autocomplete.cpp:456
void LoadBuiltinSymbols()
Makes wxMaxima know all its builtin symbols.
Definition: Autocomplete.cpp:68
void UpdateGeneralFiles(wxString partial, const wxString &maximaDir)
Assemble a list of files.
Definition: Autocomplete.cpp:423
void AddSymbols(wxString xml)
Interprets the XML autocompletable symbol list maxima can send us.
Definition: Autocomplete.cpp:108
void AddWorksheetWords(const WordList &words)
Add words to the list of words that appear in the workSheet's code cells.
Definition: Autocomplete.cpp:214
void AddSymbols_Backgroundtask_string(wxString xml)
The real work of AddSymbols is made here and in the background.
Definition: Autocomplete.cpp:135
static wxString FixTemplate(wxString templ)
Basically runs a regex over templates.
Definition: Autocomplete.cpp:609
bool HasDemofile(const wxString &commandname)
Does a demo file for this command exist?
Definition: Autocomplete.cpp:93
void AddSymbol(wxString fun, autoCompletionType type=command)
Manually add an autocompletable symbol to our symbols lists.
Definition: Autocomplete.cpp:553
void ClearWorksheetWords()
Clear the list of words that appear in the workSheet's code cells.
Definition: Autocomplete.cpp:52
The configuration storage for the current worksheet.
Definition: Configuration.h:84