1# -*- coding: utf-8 -*-
2
3# Copyright (c) 2007 - 2021 Detlev Offenbach <detlev@die-offenbachs.de>
4#
5
6"""
7Package implementing lexers for the various supported programming languages.
8"""
9
10from PyQt5.QtCore import QCoreApplication
11
12import Preferences
13import UI.PixmapCache
14
15# The lexer registry
16# Dictionary with the language name as key. Each entry is a list with
17#       0. display string (string)
18#       1. dummy filename to derive lexer name (string)
19#       2. reference to a function instantiating the specific lexer
20#          This function must take a reference to the parent as argument.
21#       3. list of open file filters (list of strings)
22#       4. list of save file filters (list of strings)
23#       5. default lexer associations (list of strings of filename wildcard
24#          patterns to be associated with the lexer)
25#       6. name of an icon file (string)
26LexerRegistry = {}
27
28
29def registerLexer(name, displayString, filenameSample, getLexerFunc,
30                  openFilters=None, saveFilters=None,
31                  defaultAssocs=None, iconFileName=""):
32    """
33    Module function to register a custom QScintilla lexer.
34
35    @param name lexer language name (string)
36    @param displayString display string (string)
37    @param filenameSample dummy filename to derive lexer name (string)
38    @param getLexerFunc reference to a function instantiating the specific
39        lexer. This function must take a reference to the parent as its only
40        argument.
41    @param openFilters list of open file filters (list of strings)
42    @param saveFilters list of save file filters (list of strings)
43    @param defaultAssocs default lexer associations (list of strings of
44        filename wildcard patterns to be associated with the lexer)
45    @param iconFileName name of an icon file (string)
46    @exception KeyError raised when the given name is already in use
47    """
48    global LexerRegistry
49    if name in LexerRegistry:
50        raise KeyError('Lexer "{0}" already registered.'.format(name))
51    else:
52        LexerRegistry[name] = [
53            displayString, filenameSample, getLexerFunc,
54            [] if openFilters is None else openFilters[:],
55            [] if saveFilters is None else saveFilters[:],
56            [] if defaultAssocs is None else defaultAssocs[:],
57            iconFileName
58        ]
59
60
61def unregisterLexer(name):
62    """
63    Module function to unregister a custom QScintilla lexer.
64
65    @param name lexer language name (string)
66    """
67    if name in LexerRegistry:
68        del LexerRegistry[name]
69
70
71def getSupportedLanguages():
72    """
73    Module function to get a dictionary of supported lexer languages.
74
75    @return dictionary of supported lexer languages. The keys are the
76        internal language names. The items are lists of three entries.
77        The first is the display string for the language, the second
78        is a dummy file name, which can be used to derive the lexer, and
79        the third is the name of an icon file.
80        (string, string, string)
81    """
82    supportedLanguages = {
83        "Bash":
84            [QCoreApplication.translate('Lexers', "Bash"), 'dummy.sh',
85             "lexerBash"],
86        "Batch":
87            [QCoreApplication.translate('Lexers', "Batch"), 'dummy.bat',
88             "lexerBatch"],
89        "C++":
90            [QCoreApplication.translate('Lexers', "C/C++"), 'dummy.cpp',
91             "lexerCPP"],
92        "C#":
93            [QCoreApplication.translate('Lexers', "C#"), 'dummy.cs',
94             "lexerCsharp"],
95        "CMake":
96            [QCoreApplication.translate('Lexers', "CMake"), 'dummy.cmake',
97             "lexerCMake"],
98        "CSS":
99            [QCoreApplication.translate('Lexers', "CSS"), 'dummy.css',
100             "lexerCSS"],
101        "Cython":
102            [QCoreApplication.translate('Lexers', "Cython"), 'dummy.pyx',
103             "lexerCython"],
104        "D":
105            [QCoreApplication.translate('Lexers', "D"), 'dummy.d',
106             "lexerD"],
107        "Diff":
108            [QCoreApplication.translate('Lexers', "Diff"), 'dummy.diff',
109             "lexerDiff"],
110        "Fortran":
111            [QCoreApplication.translate('Lexers', "Fortran"), 'dummy.f95',
112             "lexerFortran"],
113        "Fortran77":
114            [QCoreApplication.translate('Lexers', "Fortran77"), 'dummy.f',
115             "lexerFortran"],
116        "HTML":
117            [QCoreApplication.translate('Lexers', "HTML/PHP/XML"),
118             'dummy.html', "lexerHTML"],
119        "IDL":
120            [QCoreApplication.translate('Lexers', "IDL"), 'dummy.idl',
121             "lexerIDL"],
122        "Java":
123            [QCoreApplication.translate('Lexers', "Java"), 'dummy.java',
124             "lexerJava"],
125        "JavaScript":
126            [QCoreApplication.translate('Lexers', "JavaScript"), 'dummy.js',
127             "lexerJavaScript"],
128        "Lua":
129            [QCoreApplication.translate('Lexers', "Lua"), 'dummy.lua',
130             "lexerLua"],
131        "Makefile":
132            [QCoreApplication.translate('Lexers', "Makefile"), 'dummy.mak',
133             "lexerMakefile"],
134        "Matlab":
135            [QCoreApplication.translate('Lexers', "Matlab"), 'dummy.m.matlab',
136             "lexerMatlab"],
137        "Octave":
138            [QCoreApplication.translate('Lexers', "Octave"), 'dummy.m.octave',
139             "lexerOctave"],
140        "Pascal":
141            [QCoreApplication.translate('Lexers', "Pascal"), 'dummy.pas',
142             "lexerPascal"],
143        "Perl":
144            [QCoreApplication.translate('Lexers', "Perl"), 'dummy.pl',
145             "lexerPerl"],
146        "PostScript":
147            [QCoreApplication.translate('Lexers', "PostScript"), 'dummy.ps',
148             "lexerPostscript"],
149        "Povray":
150            [QCoreApplication.translate('Lexers', "Povray"), 'dummy.pov',
151             "lexerPOV"],
152        "Properties":
153            [QCoreApplication.translate('Lexers', "Properties"), 'dummy.ini',
154             "lexerProperties"],
155        "Protocol Buffer": [
156            QCoreApplication.translate('Lexers', "Protocol Buffer (protobuf)"),
157            'dummy.proto', "protobuf"],
158        "Python3":
159            [QCoreApplication.translate('Lexers', "Python3"), 'dummy.py',
160             "lexerPython3"],
161        "MicroPython":
162            [QCoreApplication.translate('Lexers', "MicroPython"), 'dummy.py',
163             "micropython"],
164        "QSS":
165            [QCoreApplication.translate('Lexers', "QSS"), 'dummy.qss',
166             "lexerCSS"],
167        "Ruby":
168            [QCoreApplication.translate('Lexers', "Ruby"), 'dummy.rb',
169             "lexerRuby"],
170        "SQL":
171            [QCoreApplication.translate('Lexers', "SQL"), 'dummy.sql',
172             "lexerSQL"],
173        "TCL":
174            [QCoreApplication.translate('Lexers', "TCL"), 'dummy.tcl',
175             "lexerTCL"],
176        "TeX":
177            [QCoreApplication.translate('Lexers', "TeX"), 'dummy.tex',
178             "lexerTeX"],
179        "VHDL":
180            [QCoreApplication.translate('Lexers', "VHDL"), 'dummy.vhd',
181             "lexerVHDL"],
182        "XML":
183            [QCoreApplication.translate('Lexers', "XML"), 'dummy.xml',
184             "lexerXML"],
185        "YAML":
186            [QCoreApplication.translate('Lexers', "YAML"), 'dummy.yml',
187             "lexerYAML"],
188        "Gettext":
189            [QCoreApplication.translate('Lexers', "Gettext"), 'dummy.po',
190             "lexerGettext"],
191        "CoffeeScript":
192            [QCoreApplication.translate('Lexers', "CoffeeScript"),
193             'dummy.coffee', "lexerCoffeeScript"],
194        "JSON":
195            [QCoreApplication.translate('Lexers', "JSON"), 'dummy.json',
196             "lexerJSON"],
197        "Markdown":
198            [QCoreApplication.translate('Lexers', "Markdown"), 'dummy.md',
199             "lexerMarkdown"],
200    }
201
202    for name in LexerRegistry:
203        if not name.startswith("Pygments|"):
204            supportedLanguages[name] = (
205                LexerRegistry[name][:2] +
206                [LexerRegistry[name][6]]
207            )
208
209    supportedLanguages["Guessed"] = [
210        QCoreApplication.translate('Lexers', "Pygments"),
211        'dummy.pygments',
212        ""
213    ]
214
215    return supportedLanguages
216
217
218def getSupportedApiLanguages():
219    """
220    Module function to get a list of supported API languages.
221
222    @return list of supported API languages
223    @rtype list of str
224    """
225    return [lang for lang in getSupportedLanguages().keys()
226            if lang != "Guessed" and not lang.startswith("Pygments|")]
227
228
229def getLanguageIcon(language, pixmap):
230    """
231    Module function to get an icon for a language.
232
233    @param language language of the lexer (string)
234    @param pixmap flag indicating to return a pixmap (boolean)
235    @return icon for the language (QPixmap or QIcon)
236    """
237    supportedLanguages = getSupportedLanguages()
238    iconFileName = (
239        supportedLanguages[language][2]
240        if language in supportedLanguages else
241        ""
242    )
243    if pixmap:
244        return UI.PixmapCache.getPixmap(iconFileName)
245    else:
246        return UI.PixmapCache.getIcon(iconFileName)
247
248
249def getLexer(language, parent=None, pyname=""):
250    """
251    Module function to instantiate a lexer object for a given language.
252
253    @param language language of the lexer (string)
254    @param parent reference to the parent object (QObject)
255    @param pyname name of the pygments lexer to use (string)
256    @return reference to the instantiated lexer object (QsciLexer)
257    """
258    if not pyname:
259        try:
260            if language in ["Python", "Python3", "Cython", "MicroPython"]:
261                from .LexerPython import LexerPython
262                return LexerPython(language, parent)
263            elif language == "C++":
264                from .LexerCPP import LexerCPP
265                return LexerCPP(
266                    parent,
267                    Preferences.getEditor("CppCaseInsensitiveKeywords"))
268            elif language == "C#":
269                from .LexerCSharp import LexerCSharp
270                return LexerCSharp(parent)
271            elif language == "IDL":
272                from .LexerIDL import LexerIDL
273                return LexerIDL(parent)
274            elif language == "Java":
275                from .LexerJava import LexerJava
276                return LexerJava(parent)
277            elif language == "JavaScript":
278                from .LexerJavaScript import LexerJavaScript
279                return LexerJavaScript(parent)
280            elif language == "SQL":
281                from .LexerSQL import LexerSQL
282                return LexerSQL(parent)
283            elif language == "HTML":
284                from .LexerHTML import LexerHTML
285                return LexerHTML(parent)
286            elif language == "Perl":
287                from .LexerPerl import LexerPerl
288                return LexerPerl(parent)
289            elif language == "Bash":
290                from .LexerBash import LexerBash
291                return LexerBash(parent)
292            elif language == "Ruby":
293                from .LexerRuby import LexerRuby
294                return LexerRuby(parent)
295            elif language == "Lua":
296                from .LexerLua import LexerLua
297                return LexerLua(parent)
298            elif language == "CSS":
299                from .LexerCSS import LexerCSS
300                return LexerCSS(parent)
301            elif language == "TeX":
302                from .LexerTeX import LexerTeX
303                return LexerTeX(parent)
304            elif language == "Diff":
305                from .LexerDiff import LexerDiff
306                return LexerDiff(parent)
307            elif language == "Makefile":
308                from .LexerMakefile import LexerMakefile
309                return LexerMakefile(parent)
310            elif language == "Properties":
311                from .LexerProperties import LexerProperties
312                return LexerProperties(parent)
313            elif language == "Batch":
314                from .LexerBatch import LexerBatch
315                return LexerBatch(parent)
316            elif language == "D":
317                from .LexerD import LexerD
318                return LexerD(parent)
319            elif language == "Povray":
320                from .LexerPOV import LexerPOV
321                return LexerPOV(parent)
322            elif language == "CMake":
323                from .LexerCMake import LexerCMake
324                return LexerCMake(parent)
325            elif language == "VHDL":
326                from .LexerVHDL import LexerVHDL
327                return LexerVHDL(parent)
328            elif language == "TCL":
329                from .LexerTCL import LexerTCL
330                return LexerTCL(parent)
331            elif language == "Fortran":
332                from .LexerFortran import LexerFortran
333                return LexerFortran(parent)
334            elif language == "Fortran77":
335                from .LexerFortran77 import LexerFortran77
336                return LexerFortran77(parent)
337            elif language == "Pascal":
338                from .LexerPascal import LexerPascal
339                return LexerPascal(parent)
340            elif language == "PostScript":
341                from .LexerPostScript import LexerPostScript
342                return LexerPostScript(parent)
343            elif language == "XML":
344                from .LexerXML import LexerXML
345                return LexerXML(parent)
346            elif language == "YAML":
347                from .LexerYAML import LexerYAML
348                return LexerYAML(parent)
349            elif language == "Matlab":
350                from .LexerMatlab import LexerMatlab
351                return LexerMatlab(parent)
352            elif language == "Octave":
353                from .LexerOctave import LexerOctave
354                return LexerOctave(parent)
355            elif language == "QSS":
356                from .LexerQSS import LexerQSS
357                return LexerQSS(parent)
358            elif language == "Gettext":
359                from .LexerPO import LexerPO
360                return LexerPO(parent)
361            elif language == "CoffeeScript":
362                from .LexerCoffeeScript import LexerCoffeeScript
363                return LexerCoffeeScript(parent)
364            elif language == "JSON":
365                from .LexerJSON import LexerJSON
366                return LexerJSON(parent)
367            elif language == "Markdown":
368                from .LexerMarkdown import LexerMarkdown
369                return LexerMarkdown(parent)
370
371            elif language == "Protocol Buffer":
372                return __getPygmentsLexer(parent, name="Protocol Buffer")
373
374            elif language in LexerRegistry:
375                return LexerRegistry[language][2](parent)
376
377            else:
378                return __getPygmentsLexer(parent)
379        except ImportError:
380            return __getPygmentsLexer(parent)
381    else:
382        return __getPygmentsLexer(parent, name=pyname)
383
384
385def __getPygmentsLexer(parent, name=""):
386    """
387    Private module function to instantiate a pygments lexer.
388
389    @param parent reference to the parent widget
390    @param name name of the pygments lexer to use (string)
391    @return reference to the lexer (LexerPygments) or None
392    """
393    from .LexerPygments import LexerPygments
394    lexer = LexerPygments(parent, name=name)
395    if lexer.canStyle():
396        return lexer
397    else:
398        return None
399
400
401def getOpenFileFiltersList(includeAll=False, asString=False,
402                           withAdditional=True):
403    """
404    Module function to get the file filter list for an open file operation.
405
406    @param includeAll flag indicating the inclusion of the
407        All Files filter (boolean)
408    @param asString flag indicating the list should be returned
409        as a string (boolean)
410    @param withAdditional flag indicating to include additional filters
411        defined by the user (boolean)
412    @return file filter list (list of strings or string)
413    """
414    openFileFiltersList = [
415        QCoreApplication.translate(
416            'Lexers',
417            'Python Files (*.py *.py3)'),
418        QCoreApplication.translate(
419            'Lexers',
420            'Python GUI Files (*.pyw *.pyw3)'),
421        QCoreApplication.translate(
422            'Lexers',
423            'Cython Files (*.pyx *.pxd *.pxi)'),
424        QCoreApplication.translate(
425            'Lexers',
426            'Quixote Template Files (*.ptl)'),
427        QCoreApplication.translate(
428            'Lexers',
429            'Ruby Files (*.rb)'),
430        QCoreApplication.translate(
431            'Lexers',
432            'IDL Files (*.idl)'),
433        QCoreApplication.translate(
434            'Lexers',
435            'Protocol Buffer Files (*.proto)'),
436        QCoreApplication.translate(
437            'Lexers',
438            'C Files (*.h *.c)'),
439        QCoreApplication.translate(
440            'Lexers',
441            'C++ Files (*.h *.hpp *.hh *.cxx *.cpp *.cc)'),
442        QCoreApplication.translate(
443            'Lexers',
444            'C# Files (*.cs)'),
445        QCoreApplication.translate(
446            'Lexers',
447            'HTML Files (*.html *.htm *.asp *.shtml)'),
448        QCoreApplication.translate(
449            'Lexers',
450            'CSS Files (*.css)'),
451        QCoreApplication.translate(
452            'Lexers',
453            'QSS Files (*.qss)'),
454        QCoreApplication.translate(
455            'Lexers',
456            'PHP Files (*.php *.php3 *.php4 *.php5 *.phtml)'),
457        QCoreApplication.translate(
458            'Lexers',
459            'XML Files (*.xml *.xsl *.xslt *.dtd *.svg *.xul *.xsd)'),
460        QCoreApplication.translate(
461            'Lexers',
462            'Qt Resource Files (*.qrc)'),
463        QCoreApplication.translate(
464            'Lexers',
465            'D Files (*.d *.di)'),
466        QCoreApplication.translate(
467            'Lexers',
468            'Java Files (*.java)'),
469        QCoreApplication.translate(
470            'Lexers',
471            'JavaScript Files (*.js)'),
472        QCoreApplication.translate(
473            'Lexers',
474            'SQL Files (*.sql)'),
475        QCoreApplication.translate(
476            'Lexers',
477            'Docbook Files (*.docbook)'),
478        QCoreApplication.translate(
479            'Lexers',
480            'Perl Files (*.pl *.pm *.ph)'),
481        QCoreApplication.translate(
482            'Lexers',
483            'Lua Files (*.lua)'),
484        QCoreApplication.translate(
485            'Lexers',
486            'Tex Files (*.tex *.sty *.aux *.toc *.idx)'),
487        QCoreApplication.translate(
488            'Lexers',
489            'Shell Files (*.sh)'),
490        QCoreApplication.translate(
491            'Lexers',
492            'Batch Files (*.bat *.cmd)'),
493        QCoreApplication.translate(
494            'Lexers',
495            'Diff Files (*.diff *.patch)'),
496        QCoreApplication.translate(
497            'Lexers',
498            'Makefiles (*makefile Makefile *.mak)'),
499        QCoreApplication.translate(
500            'Lexers',
501            'Properties Files (*.properties *.ini *.inf *.reg *.cfg'
502            ' *.cnf *.rc)'),
503        QCoreApplication.translate(
504            'Lexers',
505            'Povray Files (*.pov)'),
506        QCoreApplication.translate(
507            'Lexers',
508            'CMake Files (CMakeLists.txt *.cmake *.ctest)'),
509        QCoreApplication.translate(
510            'Lexers',
511            'VHDL Files (*.vhd *.vhdl)'),
512        QCoreApplication.translate(
513            'Lexers',
514            'TCL/Tk Files (*.tcl *.tk)'),
515        QCoreApplication.translate(
516            'Lexers',
517            'Fortran Files (*.f90 *.f95 *.f2k)'),
518        QCoreApplication.translate(
519            'Lexers',
520            'Fortran77 Files (*.f *.for)'),
521        QCoreApplication.translate(
522            'Lexers',
523            'Pascal Files (*.dpr *.dpk *.pas *.dfm *.inc *.pp)'),
524        QCoreApplication.translate(
525            'Lexers',
526            'PostScript Files (*.ps)'),
527        QCoreApplication.translate(
528            'Lexers',
529            'YAML Files (*.yaml *.yml)'),
530        QCoreApplication.translate(
531            'Lexers',
532            'TOML Files (*.toml)'),
533        QCoreApplication.translate(
534            'Lexers',
535            'Matlab Files (*.m *.m.matlab)'),
536        QCoreApplication.translate(
537            'Lexers',
538            'Octave Files (*.m *.m.octave)'),
539        QCoreApplication.translate(
540            'Lexers',
541            'Gettext Files (*.po)'),
542        QCoreApplication.translate(
543            'Lexers',
544            'CoffeeScript Files (*.coffee)'),
545        QCoreApplication.translate(
546            'Lexers',
547            'JSON Files (*.json)'),
548        QCoreApplication.translate(
549            'Lexers',
550            'Markdown Files (*.md)'),
551    ]
552
553    for name in LexerRegistry:
554        openFileFiltersList.extend(LexerRegistry[name][3])
555
556    if withAdditional:
557        openFileFiltersList.extend(
558            Preferences.getEditor("AdditionalOpenFilters"))
559
560    openFileFiltersList.sort()
561    if includeAll:
562        openFileFiltersList.append(
563            QCoreApplication.translate('Lexers', 'All Files (*)'))
564
565    if asString:
566        return ';;'.join(openFileFiltersList)
567    else:
568        return openFileFiltersList
569
570
571def getSaveFileFiltersList(includeAll=False, asString=False,
572                           withAdditional=True):
573    """
574    Module function to get the file filter list for a save file operation.
575
576    @param includeAll flag indicating the inclusion of the
577        All Files filter (boolean)
578    @param asString flag indicating the list should be returned
579        as a string (boolean)
580    @param withAdditional flag indicating to include additional filters
581        defined by the user (boolean)
582    @return file filter list (list of strings or string)
583    """
584    saveFileFiltersList = [
585        QCoreApplication.translate(
586            'Lexers',
587            "Python3 Files (*.py)"),
588        QCoreApplication.translate(
589            'Lexers',
590            "Python3 GUI Files (*.pyw)"),
591        QCoreApplication.translate(
592            'Lexers',
593            "Cython Files (*.pyx)"),
594        QCoreApplication.translate(
595            'Lexers',
596            "Cython Declaration Files (*.pxd)"),
597        QCoreApplication.translate(
598            'Lexers',
599            "Cython Include Files (*.pxi)"),
600        QCoreApplication.translate(
601            'Lexers',
602            "Quixote Template Files (*.ptl)"),
603        QCoreApplication.translate(
604            'Lexers',
605            "Ruby Files (*.rb)"),
606        QCoreApplication.translate(
607            'Lexers',
608            "IDL Files (*.idl)"),
609        QCoreApplication.translate(
610            'Lexers',
611            'Protocol Buffer Files (*.proto)'),
612        QCoreApplication.translate(
613            'Lexers',
614            "C Files (*.c)"),
615        QCoreApplication.translate(
616            'Lexers',
617            "C++ Files (*.cpp)"),
618        QCoreApplication.translate(
619            'Lexers',
620            "C++/C Header Files (*.h)"),
621        QCoreApplication.translate(
622            'Lexers',
623            "C# Files (*.cs)"),
624        QCoreApplication.translate(
625            'Lexers',
626            "HTML Files (*.html)"),
627        QCoreApplication.translate(
628            'Lexers',
629            "PHP Files (*.php)"),
630        QCoreApplication.translate(
631            'Lexers',
632            "ASP Files (*.asp)"),
633        QCoreApplication.translate(
634            'Lexers',
635            "CSS Files (*.css)"),
636        QCoreApplication.translate(
637            'Lexers',
638            "QSS Files (*.qss)"),
639        QCoreApplication.translate(
640            'Lexers',
641            "XML Files (*.xml)"),
642        QCoreApplication.translate(
643            'Lexers',
644            "XSL Files (*.xsl)"),
645        QCoreApplication.translate(
646            'Lexers',
647            "DTD Files (*.dtd)"),
648        QCoreApplication.translate(
649            'Lexers',
650            "Qt Resource Files (*.qrc)"),
651        QCoreApplication.translate(
652            'Lexers',
653            "D Files (*.d)"),
654        QCoreApplication.translate(
655            'Lexers',
656            "D Interface Files (*.di)"),
657        QCoreApplication.translate(
658            'Lexers',
659            "Java Files (*.java)"),
660        QCoreApplication.translate(
661            'Lexers',
662            "JavaScript Files (*.js)"),
663        QCoreApplication.translate(
664            'Lexers',
665            "SQL Files (*.sql)"),
666        QCoreApplication.translate(
667            'Lexers',
668            "Docbook Files (*.docbook)"),
669        QCoreApplication.translate(
670            'Lexers',
671            "Perl Files (*.pl)"),
672        QCoreApplication.translate(
673            'Lexers',
674            "Perl Module Files (*.pm)"),
675        QCoreApplication.translate(
676            'Lexers',
677            "Lua Files (*.lua)"),
678        QCoreApplication.translate(
679            'Lexers',
680            "Shell Files (*.sh)"),
681        QCoreApplication.translate(
682            'Lexers',
683            "Batch Files (*.bat)"),
684        QCoreApplication.translate(
685            'Lexers',
686            "TeX Files (*.tex)"),
687        QCoreApplication.translate(
688            'Lexers',
689            "TeX Template Files (*.sty)"),
690        QCoreApplication.translate(
691            'Lexers',
692            "Diff Files (*.diff)"),
693        QCoreApplication.translate(
694            'Lexers',
695            "Make Files (*.mak)"),
696        QCoreApplication.translate(
697            'Lexers',
698            "Properties Files (*.ini)"),
699        QCoreApplication.translate(
700            'Lexers',
701            "Configuration Files (*.cfg)"),
702        QCoreApplication.translate(
703            'Lexers',
704            'Povray Files (*.pov)'),
705        QCoreApplication.translate(
706            'Lexers',
707            'CMake Files (CMakeLists.txt)'),
708        QCoreApplication.translate(
709            'Lexers',
710            'CMake Macro Files (*.cmake)'),
711        QCoreApplication.translate(
712            'Lexers',
713            'VHDL Files (*.vhd)'),
714        QCoreApplication.translate(
715            'Lexers',
716            'TCL Files (*.tcl)'),
717        QCoreApplication.translate(
718            'Lexers',
719            'Tk Files (*.tk)'),
720        QCoreApplication.translate(
721            'Lexers',
722            'Fortran Files (*.f95)'),
723        QCoreApplication.translate(
724            'Lexers',
725            'Fortran77 Files (*.f)'),
726        QCoreApplication.translate(
727            'Lexers',
728            'Pascal Files (*.pas)'),
729        QCoreApplication.translate(
730            'Lexers',
731            'PostScript Files (*.ps)'),
732        QCoreApplication.translate(
733            'Lexers',
734            'YAML Files (*.yml)'),
735        QCoreApplication.translate(
736            'Lexers',
737            'TOML Files (*.toml)'),
738        QCoreApplication.translate(
739            'Lexers',
740            'Matlab Files (*.m)'),
741        QCoreApplication.translate(
742            'Lexers',
743            'Octave Files (*.m.octave)'),
744        QCoreApplication.translate(
745            'Lexers',
746            'Gettext Files (*.po)'),
747        QCoreApplication.translate(
748            'Lexers',
749            'CoffeeScript Files (*.coffee)'),
750        QCoreApplication.translate(
751            'Lexers',
752            'JSON Files (*.json)'),
753        QCoreApplication.translate(
754            'Lexers',
755            'Markdown Files (*.md)'),
756    ]
757
758    for name in LexerRegistry:
759        saveFileFiltersList.extend(LexerRegistry[name][4])
760
761    if withAdditional:
762        saveFileFiltersList.extend(
763            Preferences.getEditor("AdditionalSaveFilters"))
764
765    saveFileFiltersList.sort()
766
767    if includeAll:
768        saveFileFiltersList.append(
769            QCoreApplication.translate('Lexers', 'All Files (*)'))
770
771    if asString:
772        return ';;'.join(saveFileFiltersList)
773    else:
774        return saveFileFiltersList
775
776
777def getDefaultLexerAssociations():
778    """
779    Module function to get a dictionary with the default associations.
780
781    @return dictionary with the default lexer associations
782    """
783    assocs = {
784        '*.sh': "Bash",
785        '*.bash': "Bash",
786        "*.bat": "Batch",
787        "*.cmd": "Batch",
788        '*.cpp': "C++",
789        '*.cxx': "C++",
790        '*.cc': "C++",
791        '*.c': "C++",
792        '*.hpp': "C++",
793        '*.hh': "C++",
794        '*.h': "C++",
795        '*.cs': "C#",
796        'CMakeLists.txt': "CMake",
797        '*.cmake': "CMake",
798        '*.cmake.in': "CMake",
799        '*.ctest': "CMake",
800        '*.ctest.in': "CMake",
801        '*.css': "CSS",
802        '*.qss': "QSS",
803        "*.d": "D",
804        "*.di": "D",
805        "*.diff": "Diff",
806        "*.patch": "Diff",
807        '*.html': "HTML",
808        '*.htm': "HTML",
809        '*.asp': "HTML",
810        '*.shtml': "HTML",
811        '*.php': "HTML",
812        '*.php3': "HTML",
813        '*.php4': "HTML",
814        '*.php5': "HTML",
815        '*.phtml': "HTML",
816        '*.docbook': "HTML",
817        '*.ui': "HTML",
818        '*.ts': "HTML",
819        '*.qrc': "HTML",
820        '*.kid': "HTML",
821        '*.idl': "IDL",
822        '*.java': "Java",
823        '*.js': "JavaScript",
824        '*.lua': "Lua",
825        "*makefile": "Makefile",
826        "Makefile*": "Makefile",
827        "*.mak": "Makefile",
828        '*.pl': "Perl",
829        '*.pm': "Perl",
830        '*.ph': "Perl",
831        '*.pov': "Povray",
832        "*.properties": "Properties",
833        "*.ini": "Properties",
834        "*.inf": "Properties",
835        "*.reg": "Properties",
836        "*.cfg": "Properties",
837        "*.cnf": "Properties",
838        "*.rc": "Properties",
839        '*.py': "Python",
840        '*.pyw': "Python",
841        '*.py3': "Python",
842        '*.pyw3': "Python",
843        '*.pyx': "Cython",
844        '*.pxd': "Cython",
845        '*.pxi': "Cython",
846        '*.ptl': "Python",
847        '*.rb': "Ruby",
848        '*.rbw': "Ruby",
849        '*.sql': "SQL",
850        "*.tex": "TeX",
851        "*.sty": "TeX",
852        "*.aux": "TeX",
853        "*.toc": "TeX",
854        "*.idx": "TeX",
855        '*.vhd': "VHDL",
856        '*.vhdl': "VHDL",
857        "*.tcl": "TCL",
858        "*.tk": "TCL",
859        "*.f": "Fortran77",
860        "*.for": "Fortran77",
861        "*.f90": "Fortran",
862        "*.f95": "Fortran",
863        "*.f2k": "Fortran",
864        "*.dpr": "Pascal",
865        "*.dpk": "Pascal",
866        "*.pas": "Pascal",
867        "*.dfm": "Pascal",
868        "*.inc": "Pascal",
869        "*.pp": "Pascal",
870        "*.ps": "PostScript",
871        "*.xml": "XML",
872        "*.xsl": "XML",
873        "*.svg": "XML",
874        "*.xsd": "XML",
875        "*.xslt": "XML",
876        "*.dtd": "XML",
877        "*.rdf": "XML",
878        "*.xul": "XML",
879        "*.yaml": "YAML",
880        "*.yml": "YAML",
881        '*.m': "Matlab",
882        '*.m.matlab': "Matlab",
883        '*.m.octave': "Octave",
884        '*.e4c': "XML",
885        '*.e4d': "XML",
886        '*.e4k': "XML",
887        '*.e4m': "XML",
888        '*.e4p': "XML",
889        '*.e4q': "XML",
890        '*.e4s': "XML",
891        '*.e4t': "XML",
892        '*.e5d': "XML",
893        '*.e5k': "XML",
894        '*.e5m': "XML",
895        '*.e5p': "XML",
896        '*.e5q': "XML",
897        '*.e5s': "XML",
898        '*.e5t': "XML",
899        '*.e6d': "XML",
900        '*.e6k': "XML",
901        '*.e6m': "XML",
902        '*.e6p': "XML",
903        '*.e6q': "XML",
904        '*.e6s': "XML",
905        '*.e6t': "XML",
906        '*.ecj': "JSON",
907        '*.edj': "JSON",
908        '*.egj': "JSON",
909        '*.ehj': "JSON",
910        '*.ekj': "JSON",
911        '*.emj': "JSON",
912        '*.epj': "JSON",
913        '*.eqj': "JSON",
914        '*.esj': "JSON",
915        '*.etj': "JSON",
916        '*.proto': "Protocol Buffer",
917        '*.po': "Gettext",
918        '*.coffee': "CoffeeScript",
919        '*.json': "JSON",
920        '*.md': "Markdown",
921
922        '*.toml': "Pygments|TOML",
923        'Pipfile': "Pygments|TOML",
924        'poetry.lock': "Pygments|TOML",
925    }
926
927    for name in LexerRegistry:
928        for pattern in LexerRegistry[name][5]:
929            assocs[pattern] = name
930
931    return assocs
932