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 <atomic>
38#include <wx/wx.h>
39#include <wx/xml/xml.h>
40#include <wx/event.h>
41#include <wx/dir.h>
42#include <vector>
43#include <wx/object.h>
44#include <wx/regex.h>
45#include <wx/filename.h>
46#include <wx/hashmap.h>
47#include "Configuration.h"
48#include "precomp.h"
49#include "Compat.h"
50#include <unordered_map>
51/* The autocompletion logic
52
53 The wordlists for autocompletion for keywords come from several sources:
54
55 - wxMaxima::ReadLoadSymbols receive the contents of maxima's variables
56 "values" and "functions" after a package is loaded.
57 - all words that appear in the worksheet
58 - and a list of maxima's builtin commands.
59*/
60class AutoComplete : public wxEvtHandler
61{
62 typedef std::unordered_map <wxString, int, wxStringHash> WorksheetWords;
63public:
64 using WordList = std::vector<wxString>;
65
68 {
69 command = 0,
77 };
78 explicit AutoComplete(Configuration *configuration);
79
81 virtual ~AutoComplete();
82
84 void LoadSymbols();
85
92 void LoadBuiltinSymbols();
93
95 void AddSymbol(wxString fun, autoCompletionType type = command);
97 void AddSymbols(wxString xml);
99 void AddSymbols(wxXmlDocument xml);
101 void AddSymbols_Backgroundtask_string(stop_token stopToken, wxString xml);
103 void AddSymbols_Backgroundtask(stop_token stopToken, wxXmlDocument xmldoc);
104
105
107 void UpdateDemoFiles(wxString partial, const wxString &maximaDir);
109 void UpdateLoadFiles(wxString partial, const wxString &maximaDir);
111 void UpdateGeneralFiles(wxString partial, const wxString &maximaDir);
112
115 return (type == loadfile) || (type == demofile) || (type == generalfile);
116 }
117
126 void UpdateFiles(autoCompletionType type, const wxString &partial,
127 const wxString &maximaDir);
128
130 void AddWorksheetWords(const WordList &words);
131 void AddWorksheetWords(WordList::const_iterator begin, WordList::const_iterator end);
132
134 void ClearWorksheetWords();
136 void ClearDemofileList();
137
139 std::vector<wxString> CompleteSymbol(wxString partial, autoCompletionType type = command);
141 static wxString FixTemplate(wxString templ);
143 std::vector<wxString> GetDemoFilesList();
145 std::vector<wxString> GetSymbolList();
147 bool HasDemofile(const wxString &commandname);
148
149private:
151 Configuration *m_configuration;
153 void LoadableFiles_BackgroundTask(stop_token stopToken, wxString sharedir, wxString demodir);
155 void BuiltinSymbols_BackgroundTask(stop_token stopToken);
156
158 void UpdateLoadFiles_BackgroundTask(stop_token stopToken, wxString partial, wxString maximaDir);
160 std::vector<wxString> m_builtInLoadFiles;
162 std::vector<wxString> m_builtInDemoFiles;
164 class GetGeneralFiles : public wxDirTraverser
165 {
166 public:
167 explicit GetGeneralFiles(std::vector<wxString>& files,
168 std::mutex *lock,
169 stop_token stopToken = {},
170 const wxString &prefix = wxEmptyString) :
171 m_files(files), m_lock(lock), m_stopToken(stopToken), m_prefix(prefix) {
172 for(const auto &i : m_files)
173 m_filesHash[i];
174 }
175 wxDirTraverseResult OnFile(const wxString& filename) override
176 {
177 if (m_stopToken.stop_requested()) return wxDIR_STOP;
178 wxFileName newItemName(filename);
179 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "\"";
180 newItem.Replace(wxFileName::GetPathSeparator(), "/");
181 {
182 const std::lock_guard<std::mutex> lock(*m_lock);
183 if (m_filesHash.find(newItem) == m_filesHash.end())
184 {
185 m_files.push_back(newItem);
186 m_filesHash[newItem];
187 }
188 }
189 return wxDIR_CONTINUE;
190 }
191 wxDirTraverseResult OnDir(const wxString& dirname) override
192 {
193 if (m_stopToken.stop_requested()) return wxDIR_STOP;
194 wxFileName newItemName(dirname);
195 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "/\"";
196 newItem.Replace(wxFileName::GetPathSeparator(), "/");
197 {
198 const std::lock_guard<std::mutex> lock(*m_lock);
199 if (m_filesHash.find(newItem) == m_filesHash.end())
200 {
201 m_files.push_back(newItem);
202 m_filesHash[newItem];
203 }
204 }
205 return wxDIR_IGNORE;
206 }
207 std::vector<wxString> GetResult(){
208 const std::lock_guard<std::mutex> lock(*m_lock);
209 return m_files;
210 }
211 protected:
213 std::vector<wxString>& m_files;
215 std::unordered_map<wxString, wxEvtHandler*, wxStringHash> m_filesHash;
216 std::mutex *m_lock;
217 stop_token m_stopToken;
218 wxString m_prefix;
219 };
220
222 class GetMacFiles_includingSubdirs : public wxDirTraverser
223 {
224 public:
225 explicit GetMacFiles_includingSubdirs(std::vector<wxString>& files,
226 std::mutex *lock,
227 stop_token stopToken = {},
228 const wxString &prefix = wxEmptyString) :
229 m_files(files), m_lock(lock), m_stopToken(stopToken), m_prefix(prefix)
230 {
231 for(const auto &i : m_files)
232 m_filesHash[i];
233 }
234 wxDirTraverseResult OnFile(const wxString& filename) override
235 {
236 if (m_stopToken.stop_requested()) return wxDIR_STOP;
237 if(
238 (filename.EndsWith(".mac"))||
239 (filename.EndsWith(".lisp"))||
240 (filename.EndsWith(".wxm"))
241 )
242 {
243 wxFileName newItemName(filename);
244 wxString newItem = "\"" + m_prefix + newItemName.GetName() + "\"";
245 newItem.Replace(wxFileName::GetPathSeparator(), "/");
246 {
247 const std::lock_guard<std::mutex> lock(*m_lock);
248 if (m_filesHash.find(newItem) == m_filesHash.end())
249 {
250 m_files.push_back(newItem);
251 m_filesHash[newItem];
252 }
253 }
254 }
255 return wxDIR_CONTINUE;
256 }
257 wxDirTraverseResult OnDir(const wxString& dirname) override
258 {
259 if (m_stopToken.stop_requested()) return wxDIR_STOP;
260 if((dirname.EndsWith(".git")) ||
261 (dirname.EndsWith("/share/share")) ||
262 (dirname.EndsWith("/src/src")) ||
263 (dirname.EndsWith("/doc/doc")) ||
264 (dirname.EndsWith("/interfaces/interfaces"))
265 )
266 return wxDIR_STOP;
267 else
268 return wxDIR_CONTINUE;
269 }
270 std::vector<wxString> GetResult(){
271 const std::lock_guard<std::mutex> lock(*m_lock);
272 return m_files;
273 }
274 protected:
276 std::vector<wxString>& m_files;
278 std::unordered_map<wxString, wxEvtHandler*, wxStringHash> m_filesHash;
279 std::mutex *m_lock;
280 stop_token m_stopToken;
281 wxString m_prefix;
282 };
283
285 class GetMacFiles : public GetMacFiles_includingSubdirs
286 {
287 public:
288 explicit GetMacFiles(std::vector<wxString>& files,
289 std::mutex *lock,
290 stop_token stopToken = {},
291 const wxString &prefix = wxEmptyString) :
292 GetMacFiles_includingSubdirs(files, lock, stopToken, prefix){ }
293 wxDirTraverseResult OnDir(const wxString& dirname) override
294 {
295 if (m_stopToken.stop_requested()) return wxDIR_STOP;
296 wxFileName newItemName(dirname);
297 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "/\"";
298 newItem.Replace(wxFileName::GetPathSeparator(), "/");
299 {
300 const std::lock_guard<std::mutex> lock(*m_lock);
301 if (m_filesHash.find(newItem) == m_filesHash.end())
302 {
303 m_files.push_back(newItem);
304 m_filesHash[newItem];
305 }
306 }
307 return wxDIR_IGNORE;
308 }
309 };
310
312 class GetDemoFiles_includingSubdirs : public wxDirTraverser
313 {
314 public:
315 explicit GetDemoFiles_includingSubdirs(std::vector<wxString>& files,
316 std::mutex *lock,
317 stop_token stopToken = {},
318 const wxString &prefix = wxEmptyString) :
319 m_files(files), m_lock(lock), m_stopToken(stopToken), m_prefix(prefix)
320 {
321 for(const auto &i : m_files)
322 m_filesHash[i];
323 }
324 wxDirTraverseResult OnFile(const wxString& filename) override
325 {
326 if (m_stopToken.stop_requested()) return wxDIR_STOP;
327 if(filename.EndsWith(".dem"))
328 {
329 wxFileName newItemName(filename);
330 wxString newItem = "\"" + m_prefix + newItemName.GetName() + "\"";
331 newItem.Replace(wxFileName::GetPathSeparator(), "/");
332 {
333 const std::lock_guard<std::mutex> lock(*m_lock);
334 if (m_filesHash.find(newItem) == m_filesHash.end())
335 {
336 m_files.push_back(newItem);
337 m_filesHash[newItem];
338 }
339 }
340 }
341 return wxDIR_CONTINUE;
342 }
343 wxDirTraverseResult OnDir(const wxString& dirname) override
344 {
345 if (m_stopToken.stop_requested()) return wxDIR_STOP;
346 if((dirname.EndsWith(".git")) ||
347 (dirname.EndsWith("/share/share")) ||
348 (dirname.EndsWith("/src/src")) ||
349 (dirname.EndsWith("/doc/doc")) ||
350 (dirname.EndsWith("/interfaces/interfaces"))
351 )
352 return wxDIR_STOP;
353 else
354 return wxDIR_CONTINUE;
355 }
356 std::vector<wxString> GetResult(){
357 const std::lock_guard<std::mutex> lock(*m_lock);
358 return m_files;
359 }
360 protected:
362 std::vector<wxString>& m_files;
364 std::unordered_map<wxString, wxEvtHandler*, wxStringHash> m_filesHash;
365 std::mutex *m_lock;
366 stop_token m_stopToken;
367 wxString m_prefix;
368 };
369
371 class GetDemoFiles : public GetDemoFiles_includingSubdirs
372 {
373 public:
374 explicit GetDemoFiles(std::vector<wxString>& files,
375 std::mutex *lock,
376 stop_token stopToken = {},
377 const wxString &prefix = wxEmptyString) :
378 GetDemoFiles_includingSubdirs(files, lock, stopToken, prefix){ }
379 virtual wxDirTraverseResult OnDir(const wxString& dirname) override
380 {
381 if (m_stopToken.stop_requested()) return wxDIR_STOP;
382 wxFileName newItemName(dirname);
383 wxString newItem = "\"" + m_prefix + newItemName.GetFullName() + "/\"";
384 newItem.Replace(wxFileName::GetPathSeparator(), "/");
385 {
386 const std::lock_guard<std::mutex> lock(*m_lock);
387 if (m_filesHash.find(newItem) == m_filesHash.end())
388 {
389 m_files.push_back(newItem);
390 m_filesHash[newItem];
391 }
392 }
393 return wxDIR_IGNORE;
394 }
395 };
396
397 jthread m_addSymbols_backgroundThread;
398 jthread m_addFiles_backgroundThread;
400 std::mutex m_keywordsLock;
402 std::vector<std::vector<wxString>> m_wordList;
403 static wxRegEx m_args;
404 WorksheetWords m_worksheetWords;
405};
406
407wxDECLARE_EVENT(NEW_DEMO_FILES_EVENT, wxCommandEvent);
408
409#endif // AUTOCOMPLETE_H
Small C++ standard-library compatibility shims.
Definition: Autocomplete.h:61
std::vector< wxString > GetSymbolList()
Returns a list of Symbols we know.
Definition: Autocomplete.cpp:63
virtual ~AutoComplete()
The destructor of AutoComplete.
Definition: Autocomplete.cpp:284
void ClearDemofileList()
Clear the list of files demo() can be applied on.
Definition: Autocomplete.cpp:130
void UpdateFiles(autoCompletionType type, const wxString &partial, const wxString &maximaDir)
Re-scan the directory a file-name completion currently points into.
Definition: Autocomplete.cpp:482
std::vector< wxString > GetDemoFilesList()
Returns a list of demo files we know of.
Definition: Autocomplete.cpp:58
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:499
static bool CompletesFiles(autoCompletionType type)
Is this completion type one that completes file names?
Definition: Autocomplete.h:114
void AddSymbols_Backgroundtask(stop_token stopToken, wxXmlDocument xmldoc)
The real work of AddSymbols is made here and in the background.
Definition: Autocomplete.cpp:175
void LoadSymbols()
Load all autocomplete symbols wxMaxima knows about by itself.
Definition: Autocomplete.cpp:292
autoCompletionType
All types of things we can autocomplete.
Definition: Autocomplete.h:68
@ tmplte
Command names.
Definition: Autocomplete.h:70
@ generalfile
loadable files
Definition: Autocomplete.h:73
@ demofile
loadable files
Definition: Autocomplete.h:72
@ numberOfTypes
Unit names.
Definition: Autocomplete.h:76
@ unit
Esc commands describing symbols.
Definition: Autocomplete.h:75
@ loadfile
Function templates.
Definition: Autocomplete.h:71
@ esccommand
general files
Definition: Autocomplete.h:74
std::vector< wxString > CompleteSymbol(wxString partial, autoCompletionType type=command)
Returns a list of possible autocompletions for the string "partial".
Definition: Autocomplete.cpp:632
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:585
void LoadBuiltinSymbols()
Makes wxMaxima know all its builtin symbols.
Definition: Autocomplete.cpp:69
void UpdateGeneralFiles(wxString partial, const wxString &maximaDir)
Assemble a list of files.
Definition: Autocomplete.cpp:540
void AddSymbols(wxString xml)
Interprets the XML autocompletable symbol list maxima can send us.
Definition: Autocomplete.cpp:135
void AddWorksheetWords(const WordList &words)
Add words to the list of words that appear in the workSheet's code cells.
Definition: Autocomplete.cpp:280
static wxString FixTemplate(wxString templ)
Basically runs a regex over templates.
Definition: Autocomplete.cpp:741
bool HasDemofile(const wxString &commandname)
Does a demo file for this command exist?
Definition: Autocomplete.cpp:120
void AddSymbols_Backgroundtask_string(stop_token stopToken, wxString xml)
The real work of AddSymbols is made here and in the background.
Definition: Autocomplete.cpp:168
void AddSymbol(wxString fun, autoCompletionType type=command)
Manually add an autocompletable symbol to our symbols lists.
Definition: Autocomplete.cpp:686
void ClearWorksheetWords()
Clear the list of words that appear in the workSheet's code cells.
Definition: Autocomplete.cpp:53
The configuration storage for the current worksheet.
Definition: Configuration.h:98
Definition: Compat.h:54
Definition: Compat.h:43