Repository: spyder-ide/spyder

Issue:
Use language type icons present in Material design
Material design has icons for the most important programming languages:

![seleccion_003](https://user-images.githubusercontent.com/365293/49612494-e6e2a080-f972-11e8-88ed-0d7e1ae57c32.png)

So it'd be nice to use those icons to distinguish between several text file types.

@juanis2112, the icons shown in the File and Project explorers are defined here:

https://github.com/spyder-ide/spyder/blob/master/spyder/plugins/explorer/widgets.py#L141

so the idea would be to use the Material icons when `file_type == 'text'` and `extension` corresponds to the extensions used by each programming language.

For example: `.py` file extensions need to be associated to the Python icon, `.cpp` to the C++ icon, etc.


Discussion:

Resolving patch:
diff --git a/spyder/app/mainwindow.py b/spyder/app/mainwindow.py
--- a/spyder/app/mainwindow.py
+++ b/spyder/app/mainwindow.py
@@ -2472,7 +2472,9 @@ def about(self):
             licenses and/or originally by other authors.
             Spyder 3 theme icons derived from
             <a href="https://fontawesome.com/">Font Awesome</a> 4.7
-            (&copy; 2016 David Gandy; SIL OFL 1.1).
+            (&copy; 2016 David Gandy; SIL OFL 1.1) and
+            <a href="http://materialdesignicons.com/">Material Design</a>
+            (&copy; 2014 Austin Andrews; SIL OFL 1.1).
             Most Spyder 2 theme icons sourced from the
             <a href="https://www.everaldo.com">Crystal Project iconset</a>
             (&copy; 2006-2007 Everaldo Coelho; LGPL 2.1+).
diff --git a/spyder/plugins/explorer/widgets.py b/spyder/plugins/explorer/widgets.py
--- a/spyder/plugins/explorer/widgets.py
+++ b/spyder/plugins/explorer/widgets.py
@@ -26,13 +26,14 @@
 from qtpy.QtCore import (QDir, QFileInfo, QMimeData, QSize,
                          QSortFilterProxyModel, Qt, QTimer, QUrl,
                          Signal, Slot)
-from qtpy.QtGui import QDrag
+from qtpy.QtGui import QDrag, QIcon
 from qtpy.QtWidgets import (QFileSystemModel, QHBoxLayout, QFileIconProvider,
                             QInputDialog, QLabel, QLineEdit, QMenu,
                             QMessageBox, QToolButton, QTreeView, QVBoxLayout,
                             QWidget)
 # Local imports
-from spyder.config.base import _, get_home_dir
+from spyder.config.base import _, get_home_dir, get_image_path
+from spyder.config.gui import is_dark_interface
 from spyder.py3compat import (str_lower, to_binary_string,
                               to_text_string)
 from spyder.utils import icon_manager as ima
@@ -149,36 +150,46 @@ def icon(self, icontype_or_qfileinfo):
                 return ima.icon('DirOpenIcon')
             else:
                 basename = osp.basename(fname)
-                _, extension = osp.splitext(basename)
+                _, extension = osp.splitext(basename.lower())
                 mime_type, _ = mime.guess_type(basename)
                 icon = ima.icon('FileIcon')
 
                 if extension in self.OFFICE_FILES:
                     icon = ima.icon(self.OFFICE_FILES[extension])
 
-                if mime_type is not None:
-                    try:
-                        # Fix for issue 5080.  Even though mimetypes.guess_type
-                        # documentation states that the return value will be
-                        # None or a tuple of the form type/subtype, in the
-                        # Windows registry, .sql has a mimetype of text\plain
-                        # instead of text/plain therefore mimetypes is
-                        # returning it incorrectly.
-                        file_type, bin_name = mime_type.split('/')
-                    except ValueError:
-                        file_type = 'text'
-                    if file_type == 'text':
-                        icon = ima.icon('TextFileIcon')
-                    elif file_type == 'audio':
-                        icon = ima.icon('AudioFileIcon')
-                    elif file_type == 'video':
-                        icon = ima.icon('VideoFileIcon')
-                    elif file_type == 'image':
-                        icon = ima.icon('ImageFileIcon')
-                    elif file_type == 'application':
-                        if bin_name in self.application_icons:
-                            icon = ima.icon(self.application_icons[bin_name])
-                return icon
+                if extension in ima.LANGUAGE_ICONS:
+                    icon = ima.icon(ima.LANGUAGE_ICONS[extension])
+                else:
+                    if extension == '.ipynb':
+                        if is_dark_interface():
+                            icon = QIcon(get_image_path("notebook_dark.svg"))
+                        else:
+                            icon = QIcon(get_image_path("notebook_light.svg"))
+                    elif mime_type is not None:
+                        try:
+                            # Fix for issue 5080. Even though
+                            # mimetypes.guess_type documentation states that
+                            # the return value will be None or a tuple of
+                            # the form type/subtype, in the Windows registry,
+                            # .sql has a mimetype of text\plain
+                            # instead of text/plain therefore mimetypes is
+                            # returning it incorrectly.
+                            file_type, bin_name = mime_type.split('/')
+                        except ValueError:
+                            file_type = 'text'
+                        if file_type == 'text':
+                            icon = ima.icon('TextFileIcon')
+                        elif file_type == 'audio':
+                            icon = ima.icon('AudioFileIcon')
+                        elif file_type == 'video':
+                            icon = ima.icon('VideoFileIcon')
+                        elif file_type == 'image':
+                            icon = ima.icon('ImageFileIcon')
+                        elif file_type == 'application':
+                            if bin_name in self.application_icons:
+                                icon = ima.icon(
+                                    self.application_icons[bin_name])
+        return icon
 
 
 class DirView(QTreeView):
diff --git a/spyder/utils/icon_manager.py b/spyder/utils/icon_manager.py
--- a/spyder/utils/icon_manager.py
+++ b/spyder/utils/icon_manager.py
@@ -24,6 +24,45 @@
     MAIN_FG_COLOR = 'black'
 
 
+LANGUAGE_ICONS = {
+    '.c': 'CFileIcon',
+    '.h': 'CFileIcon',
+    '.cc': 'CppFileIcon',
+    '.hh': 'CppFileIcon',
+    '.cpp': 'CppFileIcon',
+    '.cxx': 'CppFileIcon',
+    '.c++': 'CppFileIcon',
+    '.hpp': 'CppFileIcon',
+    '.hxx': 'CppFileIcon',
+    '.h++': 'CppFileIcon',
+    '.cs': 'CsharpFileIcon',
+    '.asmx': 'CsharpFileIcon',
+    '.py': 'PythonFileIcon',
+    '.py3': 'PythonFileIcon',
+    '.pyx': 'PythonFileIcon',
+    '.pyw': 'PythonFileIcon',
+    '.java': 'JavaFileIcon',
+    '.jav': 'JavaFileIcon',
+    '.j': 'JavaFileIcon',
+    '.js': 'JavascriptFileIcon',
+    '.r': 'RFileIcon',
+    '.rnw': 'RFileIcon',
+    '.rmd': 'RFileIcon',
+    '.swift': 'SwiftFileIcon',
+    '.csv': 'GridFileIcon',
+    '.tsv': 'GridFileIcon',
+    '.bat': 'WindowsFileIcon',
+    '.psl': 'PowershellFileIcon',
+    '.sh': 'DollarFileIcon',
+    '.md': 'MarkdownFileIcon',
+    '.json': 'JsonFileIcon',
+    '.html': 'CodeFileIcon',
+    '.css': 'CodeFileIcon',
+    '.yml': 'ExclamationFileIcon',
+    '.yaml': 'ExclamationFileIcon',
+    '.xml': 'CodeFileIcon'
+}
+
 _resource = {
     'directory': osp.join(osp.dirname(osp.realpath(__file__)), '../fonts'),
     'loaded': False,
@@ -190,6 +229,22 @@
     'ArchiveFileIcon':         [('fa.file-archive-o',), {'color': MAIN_FG_COLOR}],
     'VideoFileIcon':           [('fa.file-video-o',), {'color': MAIN_FG_COLOR}],
     'TextFileIcon':            [('fa.file-text-o',), {'color': MAIN_FG_COLOR}],
+    'CFileIcon':               [('mdi.language-c',), {'color': MAIN_FG_COLOR}],
+    'CppFileIcon':             [('mdi.language-cpp',), {'color': MAIN_FG_COLOR}],
+    'CsharpFileIcon':          [('mdi.language-csharp',), {'color': MAIN_FG_COLOR}],
+    'PythonFileIcon':          [('mdi.language-python',), {'color': MAIN_FG_COLOR}],
+    'JavaFileIcon':            [('mdi.language-java',), {'color': MAIN_FG_COLOR}],
+    'JavascriptFileIcon':      [('mdi.language-javascript',), {'color': MAIN_FG_COLOR}],
+    'RFileIcon':               [('mdi.language-r',), {'color': MAIN_FG_COLOR}],
+    'SwiftFileIcon':           [('mdi.language-swift',), {'color': MAIN_FG_COLOR}],
+    'GridFileIcon':            [('mdi.grid',), {'color': MAIN_FG_COLOR}],
+    'WindowsFileIcon':         [('mdi.windows',), {'color': MAIN_FG_COLOR}],
+    'PowershellFileIcon':      [('mdi.powershell',), {'color': MAIN_FG_COLOR}],
+    'DollarFileIcon':          [('fa5s.file-invoice-dollar',), {'color': MAIN_FG_COLOR}],
+    'MarkdownFileIcon':        [('mdi.markdown',), {'color': MAIN_FG_COLOR}],
+    'JsonFileIcon':            [('mdi.json',), {'color': MAIN_FG_COLOR}],
+    'ExclamationFileIcon':     [('mdi.exclamation',), {'color': MAIN_FG_COLOR}],
+    'CodeFileIcon':             [('mdi.xml',), {'color': MAIN_FG_COLOR}],
     'project':                 [('fa.folder-open-o',), {'color': MAIN_FG_COLOR}],
     'DriveHDIcon':             [('fa.hdd-o',), {'color': MAIN_FG_COLOR}],
     'arrow':                   [('fa.arrow-right',), {'color': MAIN_FG_COLOR}],


Test patch: