diff --git a/README.md b/README.md index 11464c0a..f2083e47 100644 --- a/README.md +++ b/README.md @@ -71,7 +71,7 @@ The following prefixes are currently available to use: - `ri` prefix holds [**Remix Icon** 2.5.0 with its 2271 icons.](https://github.com/Remix-Design/RemixIcon) -- `msc` prefix holds Microsoft's [**Codicons** 0.0.35 with its 446 icons.](https://github.com/microsoft/vscode-codicons) +- `msc` prefix holds Microsoft's [**Codicons** 0.0.35 with its 540 icons.](https://github.com/microsoft/vscode-codicons) ### Examples diff --git a/UPDATE.md b/UPDATE.md index 219369f2..478e5d04 100644 --- a/UPDATE.md +++ b/UPDATE.md @@ -236,7 +236,7 @@ To update _Codicons_ icons, one must: - check what is the latest released version here: https://github.com/microsoft/vscode-codicons/releases - update font version in \_\_init__.py - remove outdated files in the fonts dir -- run: `python setup.py update_msc` +- run: `python setup.py update_msc --msc-version X.X.X` - update Codicons version number, icon counts and URLs inside: - README.md - qtawesome/docs/source/usage.rst diff --git a/docs/environment.yml b/docs/environment.yml index 005ef1c6..04809399 100644 --- a/docs/environment.yml +++ b/docs/environment.yml @@ -7,3 +7,4 @@ dependencies: - pyqt - qtpy - sphinx_rtd_theme +- pip diff --git a/docs/source/usage.rst b/docs/source/usage.rst index b5d82e85..20040af8 100644 --- a/docs/source/usage.rst +++ b/docs/source/usage.rst @@ -32,7 +32,7 @@ The following prefixes are currently available to use: - ``ri`` prefix holds `Remix Icon 2.5.0 with its 2271 icons.`_ -- ``msc`` prefix holds Microsoft's `Codicons 0.0.35 with its 446 icons.`_ +- ``msc`` prefix holds Microsoft's `Codicons 0.0.35 with its 540 icons.`_ .. _FontAwesome: https://fontawesome.com .. _151 icons in the "regular" style.: https://fontawesome.com/v5/search?o=r&m=free&s=regular @@ -45,7 +45,7 @@ The following prefixes are currently available to use: .. _Material Design Icons 5.9.55 with its 5955 icons.: https://cdn.materialdesignicons.com/5.9.55/ .. _Phosphor 1.3.0 with its 4470 icons (894 icons * 5 weights\: Thin, Light, Regular, Bold and Fill).: https://github.com/phosphor-icons/phosphor-icons .. _Remix Icon 2.5.0 with its 2271 icons.: https://github.com/Remix-Design/RemixIcon -.. _Codicons 0.0.35 with its 446 icons.: https://github.com/microsoft/vscode-codicons +.. _Codicons 0.0.35 with its 540 icons.: https://github.com/microsoft/vscode-codicons Examples ~~~~~~~~ diff --git a/qtawesome/__init__.py b/qtawesome/__init__.py index 65a3f5ff..685e2b0e 100644 --- a/qtawesome/__init__.py +++ b/qtawesome/__init__.py @@ -77,7 +77,7 @@ 'materialdesignicons6-webfont-6.9.96.ttf': 'ecaabfbb23fdac4ddbaf897b97257a92', 'phosphor-1.3.0.ttf': '5b8dc57388b2d86243566b996cc3a789', 'remixicon-2.5.0.ttf': '888e61f04316f10bddfff7bee10c6dd0', - 'codicon-0.0.35.ttf': '2b89de3354b7768e193c0ec14571422b', + 'codicon-0.0.35.ttf': '8478f5b3df2158f7e4864473e34efda1', } diff --git a/qtawesome/fonts/codicon-0.0.35.ttf b/qtawesome/fonts/codicon-0.0.35.ttf index 8ccc0354..0694339a 100644 Binary files a/qtawesome/fonts/codicon-0.0.35.ttf and b/qtawesome/fonts/codicon-0.0.35.ttf differ diff --git a/qtawesome/fonts/codicon-charmap-0.0.35.json b/qtawesome/fonts/codicon-charmap-0.0.35.json index a35f56b2..a7fcae49 100644 --- a/qtawesome/fonts/codicon-charmap-0.0.35.json +++ b/qtawesome/fonts/codicon-charmap-0.0.35.json @@ -2,7 +2,9 @@ "account": "0xeb99", "activate-breakpoints": "0xea97", "add": "0xea60", + "alert": "0xea6c", "archive": "0xea98", + "array": "0xea8a", "arrow-both": "0xea99", "arrow-circle-down": "0xebfc", "arrow-circle-left": "0xebfd", @@ -29,6 +31,7 @@ "bold": "0xeaa3", "book": "0xeaa4", "bookmark": "0xeaa5", + "bracket": "0xeb0f", "bracket-dot": "0xebe5", "bracket-error": "0xebe6", "briefcase": "0xeaac", @@ -55,14 +58,19 @@ "circle-filled": "0xea71", "circle-large": "0xebb5", "circle-large-filled": "0xebb4", + "circle-large-outline": "0xebb5", + "circle-outline": "0xeabc", "circle-slash": "0xeabd", "circle-small": "0xec07", "circle-small-filled": "0xeb8a", "circuit-board": "0xeabe", "clear-all": "0xeabf", "clippy": "0xeac0", + "clock": "0xea82", + "clone": "0xea78", "close": "0xea76", "close-all": "0xeac1", + "close-dirty": "0xea71", "cloud": "0xebaa", "cloud-download": "0xeac2", "cloud-upload": "0xeac3", @@ -72,12 +80,15 @@ "color-mode": "0xeac6", "combine": "0xebb6", "comment": "0xea6b", + "comment-add": "0xea6b", "comment-discussion": "0xeac7", "comment-draft": "0xec0e", "comment-unresolved": "0xec0a", + "compare-changes": "0xeafd", "compass": "0xebd5", "compass-active": "0xebd7", "compass-dot": "0xebd6", + "console": "0xea85", "copilot": "0xec1e", "copy": "0xebcc", "credit-card": "0xeac9", @@ -88,20 +99,28 @@ "debug-all": "0xebdc", "debug-alt": "0xeb91", "debug-alt-small": "0xeba8", + "debug-breakpoint": "0xea71", "debug-breakpoint-conditional": "0xeaa7", + "debug-breakpoint-conditional-disabled": "0xeaa7", "debug-breakpoint-conditional-unverified": "0xeaa6", "debug-breakpoint-data": "0xeaa9", + "debug-breakpoint-data-disabled": "0xeaa9", "debug-breakpoint-data-unverified": "0xeaa8", + "debug-breakpoint-disabled": "0xea71", "debug-breakpoint-function": "0xeb88", + "debug-breakpoint-function-disabled": "0xeb88", "debug-breakpoint-function-unverified": "0xeb87", "debug-breakpoint-log": "0xeaab", + "debug-breakpoint-log-disabled": "0xeaab", "debug-breakpoint-log-unverified": "0xeaaa", "debug-breakpoint-unsupported": "0xeb8c", + "debug-breakpoint-unverified": "0xeabc", "debug-console": "0xeb9b", "debug-continue": "0xeacf", "debug-continue-small": "0xebe0", "debug-coverage": "0xebdd", "debug-disconnect": "0xead0", + "debug-hint": "0xea71", "debug-line-by-line": "0xebd0", "debug-pause": "0xead1", "debug-rerun": "0xebc0", @@ -110,6 +129,8 @@ "debug-reverse-continue": "0xeb8e", "debug-stackframe": "0xeb8b", "debug-stackframe-active": "0xeb89", + "debug-stackframe-dot": "0xeb8a", + "debug-stackframe-focused": "0xeb8b", "debug-start": "0xead3", "debug-step-back": "0xeb8f", "debug-step-into": "0xead4", @@ -119,15 +140,14 @@ "desktop-download": "0xea78", "device-camera": "0xeada", "device-camera-video": "0xead9", + "device-desktop": "0xea7a", "device-mobile": "0xeadb", "diff": "0xeae1", "diff-added": "0xeadc", "diff-ignored": "0xeadd", "diff-modified": "0xeade", - "diff-multiple": "0xec23", "diff-removed": "0xeadf", "diff-renamed": "0xeae0", - "diff-single": "0xec22", "discard": "0xeae2", "edit": "0xea73", "editor-layout": "0xeae3", @@ -141,15 +161,21 @@ "extensions": "0xeae6", "eye": "0xea70", "eye-closed": "0xeae7", + "eye-unwatch": "0xea70", + "eye-watch": "0xea70", "feedback": "0xeb96", "file": "0xea7b", + "file-add": "0xea7f", "file-binary": "0xeae8", "file-code": "0xeae9", + "file-directory": "0xea83", + "file-directory-create": "0xea80", "file-media": "0xeaea", "file-pdf": "0xeaeb", "file-submodule": "0xeaec", "file-symlink-directory": "0xeaed", "file-symlink-file": "0xeaee", + "file-text": "0xea7b", "file-zip": "0xeaef", "files": "0xeaf0", "filter": "0xeaf1", @@ -163,19 +189,33 @@ "folder-library": "0xebdf", "folder-opened": "0xeaf7", "game": "0xec17", + "gather": "0xebb6", "gear": "0xeaf8", "gift": "0xeaf9", + "gist": "0xeafb", + "gist-fork": "0xea63", + "gist-new": "0xea60", + "gist-private": "0xea75", "gist-secret": "0xeafa", + "git-branch": "0xea68", + "git-branch-create": "0xea68", + "git-branch-delete": "0xea68", "git-commit": "0xeafc", "git-compare": "0xeafd", "git-fetch": "0xec1d", + "git-fork-private": "0xea75", "git-merge": "0xeafe", "git-pull-request": "0xea64", + "git-pull-request-abandoned": "0xea64", + "git-pull-request-assignee": "0xeb99", "git-pull-request-closed": "0xebda", "git-pull-request-create": "0xebbc", "git-pull-request-draft": "0xebdb", "git-pull-request-go-to-changes": "0xec0b", + "git-pull-request-label": "0xea66", + "git-pull-request-milestone": "0xeb20", "git-pull-request-new-changes": "0xec0c", + "git-pull-request-reviewer": "0xeb96", "github": "0xea84", "github-action": "0xeaff", "github-alt": "0xeb00", @@ -200,14 +240,18 @@ "info": "0xea74", "insert": "0xec11", "inspect": "0xebd1", + "issue-closed": "0xeba4", "issue-draft": "0xebd9", + "issue-opened": "0xea74", "issue-reopened": "0xeb0b", "issues": "0xeb0c", "italic": "0xeb0d", "jersey": "0xeb0e", "json": "0xeb0f", + "kebab-horizontal": "0xea7c", "kebab-vertical": "0xeb10", "key": "0xeb11", + "keyboard": "0xea65", "law": "0xeb12", "layers": "0xebd2", "layers-active": "0xebd4", @@ -229,9 +273,9 @@ "layout-sidebar-right-off": "0xec00", "layout-statusbar": "0xebf5", "library": "0xeb9c", + "light-bulb": "0xea61", "lightbulb": "0xea61", "lightbulb-autofix": "0xeb13", - "lightbulb-sparkle": "0xec1f", "link": "0xeb15", "link-external": "0xeb14", "list-filter": "0xeb83", @@ -245,11 +289,16 @@ "location": "0xeb1a", "lock": "0xea75", "lock-small": "0xebe7", + "log-in": "0xea6f", + "log-out": "0xea6e", + "logo-github": "0xea84", "magnet": "0xebae", "mail": "0xeb1c", "mail-read": "0xeb1b", + "mail-reply": "0xea7d", "map": "0xec05", "map-filled": "0xec06", + "mark-github": "0xea84", "markdown": "0xeb1d", "megaphone": "0xeb1e", "mention": "0xeb1f", @@ -257,8 +306,12 @@ "merge": "0xebab", "mic": "0xec12", "mic-filled": "0xec1c", + "microscope": "0xea79", "milestone": "0xeb20", "mirror": "0xea69", + "mirror-private": "0xea75", + "mirror-public": "0xea69", + "more": "0xea7c", "mortar-board": "0xeb21", "move": "0xeb22", "multiple-windows": "0xeb23", @@ -274,13 +327,19 @@ "octoface": "0xeb27", "open-preview": "0xeb28", "organization": "0xea7e", + "organization-filled": "0xea7e", + "organization-outline": "0xea7e", "output": "0xeb9d", "package": "0xeb29", "paintcan": "0xeb2a", "pass": "0xeba4", "pass-filled": "0xebb3", + "pencil": "0xea73", "person": "0xea67", "person-add": "0xebcd", + "person-filled": "0xea67", + "person-follow": "0xea67", + "person-outline": "0xea67", "piano": "0xec1a", "pie-chart": "0xebe4", "pin": "0xeb2b", @@ -289,8 +348,10 @@ "play": "0xeb2c", "play-circle": "0xeba6", "plug": "0xeb2d", + "plus": "0xea60", "preserve-case": "0xeb2e", "preview": "0xeb2f", + "primitive-dot": "0xea71", "primitive-square": "0xea72", "project": "0xeb30", "pulse": "0xeb31", @@ -308,23 +369,28 @@ "remote": "0xeb3a", "remote-explorer": "0xeb39", "remove": "0xeb3b", + "remove-close": "0xea76", + "repl": "0xea85", "replace": "0xeb3d", "replace-all": "0xeb3c", "reply": "0xea7d", "repo": "0xea62", "repo-clone": "0xeb3e", + "repo-create": "0xea60", + "repo-delete": "0xea62", "repo-force-push": "0xeb3f", "repo-forked": "0xea63", "repo-pull": "0xeb40", "repo-push": "0xeb41", + "repo-sync": "0xea77", "report": "0xeb42", "request-changes": "0xeb43", - "robot": "0xec20", "rocket": "0xeb44", "root-folder": "0xeb46", "root-folder-opened": "0xeb45", "rss": "0xeb47", "ruby": "0xeb48", + "run": "0xeb2c", "run-above": "0xebbd", "run-all": "0xeb9e", "run-below": "0xebbe", @@ -336,14 +402,15 @@ "screen-normal": "0xeb4d", "search": "0xea6d", "search-fuzzy": "0xec0d", + "search-save": "0xea6d", "search-stop": "0xeb4e", + "selection": "0xeb85", "send": "0xec0f", "server": "0xeb50", "server-environment": "0xeba3", "server-process": "0xeba2", "settings": "0xeb52", "settings-gear": "0xeb51", - "share": "0xec25", "shield": "0xeb53", "sign-in": "0xea6f", "sign-out": "0xea6e", @@ -352,44 +419,62 @@ "sort-precedence": "0xeb55", "source-control": "0xea68", "sparkle": "0xec10", - "sparkle-filled": "0xec21", "split-horizontal": "0xeb56", "split-vertical": "0xeb57", "squirrel": "0xeb58", + "star": "0xea6a", + "star-add": "0xea6a", + "star-delete": "0xea6a", "star-empty": "0xea6a", "star-full": "0xeb59", "star-half": "0xeb5a", + "stop": "0xea87", "stop-circle": "0xeba5", - "surround-with": "0xec24", "symbol-array": "0xea8a", "symbol-boolean": "0xea8f", "symbol-class": "0xeb5b", "symbol-color": "0xeb5c", "symbol-constant": "0xeb5d", + "symbol-constructor": "0xea8c", "symbol-enum": "0xea95", "symbol-enum-member": "0xeb5e", "symbol-event": "0xea86", "symbol-field": "0xeb5f", "symbol-file": "0xeb60", + "symbol-folder": "0xea83", + "symbol-function": "0xea8c", "symbol-interface": "0xeb61", "symbol-key": "0xea93", "symbol-keyword": "0xeb62", "symbol-method": "0xea8c", "symbol-misc": "0xeb63", + "symbol-module": "0xea8b", "symbol-namespace": "0xea8b", + "symbol-null": "0xea8f", + "symbol-number": "0xea90", "symbol-numeric": "0xea90", + "symbol-object": "0xea8b", "symbol-operator": "0xeb64", + "symbol-package": "0xea8b", "symbol-parameter": "0xea92", "symbol-property": "0xeb65", + "symbol-reference": "0xea94", "symbol-ruler": "0xea96", "symbol-snippet": "0xeb66", "symbol-string": "0xeb8d", + "symbol-struct": "0xea91", "symbol-structure": "0xea91", + "symbol-text": "0xea93", + "symbol-type-parameter": "0xea92", + "symbol-unit": "0xea96", + "symbol-value": "0xea95", "symbol-variable": "0xea88", "sync": "0xea77", "sync-ignored": "0xeb9f", "table": "0xebb7", "tag": "0xea66", + "tag-add": "0xea66", + "tag-remove": "0xea66", "target": "0xebf8", "tasklist": "0xeb67", "telescope": "0xeb68", @@ -397,6 +482,10 @@ "terminal-bash": "0xebca", "terminal-cmd": "0xebc4", "terminal-debian": "0xebc5", + "terminal-decoration-error": "0xebfb", + "terminal-decoration-incomplete": "0xeabc", + "terminal-decoration-mark": "0xeb8a", + "terminal-decoration-success": "0xea71", "terminal-linux": "0xebc6", "terminal-powershell": "0xebc7", "terminal-tmux": "0xebc8", @@ -409,6 +498,7 @@ "thumbsup-filled": "0xec14", "tools": "0xeb6d", "trash": "0xea81", + "trashcan": "0xea81", "triangle-down": "0xeb6e", "triangle-left": "0xeb6f", "triangle-right": "0xeb70", @@ -422,6 +512,7 @@ "unlock": "0xeb74", "unmute": "0xeb75", "unverified": "0xeb76", + "variable": "0xea88", "variable-group": "0xebb8", "verified": "0xeb77", "verified-filled": "0xebe9", @@ -442,6 +533,10 @@ "workspace-trusted": "0xebc1", "workspace-unknown": "0xebc3", "workspace-untrusted": "0xebc2", + "wrench": "0xeb65", + "wrench-subaction": "0xeb65", + "x": "0xea76", + "zap": "0xea86", "zoom-in": "0xeb81", "zoom-out": "0xeb82" } \ No newline at end of file diff --git a/setupbase.py b/setupbase.py index d00df8e9..a59fe8f0 100644 --- a/setupbase.py +++ b/setupbase.py @@ -3,12 +3,9 @@ import re import io import sys -import csv import json -import shutil import hashlib import zipfile -import tempfile try: from fontTools import ttLib @@ -253,7 +250,7 @@ def run(self): class UpdateCodiconCommand(setuptools.Command): """A custom command to make updating Microsoft's Codicons easy!""" description = 'Try to update the Codicon font data in the project.' - user_options = [] + user_options = [('msc-version=', None, 'Codicon version.')] CHARMAP_PATH = os.path.join( HERE, "qtawesome", "fonts", "codicon-charmap-{version}.json" @@ -261,16 +258,19 @@ class UpdateCodiconCommand(setuptools.Command): TTF_PATH = os.path.join( HERE, "qtawesome", "fonts", "codicon-{version}.ttf" ) - DOWNLOAD_URL_TTF = 'https://raw.githubusercontent.com/microsoft/vscode-codicons/main/dist/codicon.ttf' - DOWNLOAD_URL_CSV = 'https://raw.githubusercontent.com/microsoft/vscode-codicons/main/dist/codicon.csv' - # At the time of writing this comment, vscode-codicons repo does not use git tags, but you can get the version from package.json: - DOWNLOAD_URL_JSON = 'https://raw.githubusercontent.com/microsoft/vscode-codicons/main/package.json' + DOWNLOAD_URL_TTF = 'https://raw.githubusercontent.com/microsoft/vscode-codicons/{version}/dist/codicon.ttf' + DOWNLOAD_URL_CSS = 'https://raw.githubusercontent.com/microsoft/vscode-codicons/{version}/dist/codicon.css' + DOWNLOAD_URL_JSON = 'https://raw.githubusercontent.com/microsoft/vscode-codicons/{version}/package.json' def initialize_options(self): - """Required by setuptools.""" + """Set default values for the command options.""" + self.msc_version = '' def finalize_options(self): - """Required by setuptools.""" + """Validate the command options.""" + assert bool( + self.msc_version + ), 'Codicons version is mandatory for this command.' def __print(self, msg): """Shortcut for printing with the setuptools logger.""" @@ -279,29 +279,42 @@ def __print(self, msg): def run(self): """Run command.""" - # Download .csv to a temporary path: - package_json = urlopen(self.DOWNLOAD_URL_JSON) + # Download .json to a temporary path: + download_url_json = self.DOWNLOAD_URL_JSON.format( + version=self.msc_version + ) + package_json = urlopen(download_url_json) package_info = json.load(package_json) package_version = package_info['version'] + assert self.msc_version == package_version, ( + "Codicons version does not match with `package.json` info. %s and %s" + % ( + self.msc_version, + package_version, + ) + ) self.__print('Will download codicons version: %s' % package_version) - # Download .csv to a temporary path: - with tempfile.NamedTemporaryFile(mode='wb+', suffix='.csv', prefix='codicon', delete=False) as tempCSV: - self.__print('Downloading: %s' % self.DOWNLOAD_URL_CSV) - response = urlopen(self.DOWNLOAD_URL_CSV) - shutil.copyfileobj(response, tempCSV) + # Download .css: + donwload_url_css = self.DOWNLOAD_URL_CSS.format( + version=self.msc_version + ) + req = urlopen(donwload_url_css) + if req.status != 200: + raise Exception('Failed to download CSS Charmap') - # Interpret the codicon.csv file: - charmap = {} - with open(tempCSV.name, 'r', encoding='utf-8') as tempCSV: - reader = csv.DictReader(tempCSV) - for row in reader: - code = "0x" + row['unicode'].lower() - charmap[row['short_name']] = code - self.__print('Identified %s icons in the CSV.' % len(charmap)) + rawcss = req.read().decode() + req.close() - # Remove temp file: - os.remove(tempCSV.name) + # Interpret the codicon.css file: + charmap = {} + pattern = '^\.codicon-(.+):before {\s*content: "(.+)"\s*}$' + data = re.findall(pattern, rawcss, re.MULTILINE) + for name, key in data: + key = key.replace('\\', '0x') + name = name.lower() + charmap[name] = key + self.__print('Identified %s icons in the CSS.' % len(charmap)) # Dump a .json charmap file the way we like it: charmap_path = self.CHARMAP_PATH.format(version=package_version) @@ -310,12 +323,15 @@ def run(self): json.dump(charmap, f, indent=4, sort_keys=True) # Dump a .ttf font file: + download_url_ttf = self.DOWNLOAD_URL_TTF.format( + version=self.msc_version + ) ttf_path = self.TTF_PATH.format(version=package_version) with open(ttf_path, 'wb+') as ttfFile: self.__print( - "Downloading %s --> %s" % (self.DOWNLOAD_URL_TTF, ttf_path) + "Downloading %s --> %s" % (download_url_ttf, ttf_path) ) - response = urlopen(self.DOWNLOAD_URL_TTF) + response = urlopen(download_url_ttf) data = response.read() ttfFile.write(data) md5 = hashlib.md5(data).hexdigest() @@ -325,7 +341,7 @@ def run(self): self.__print('Patching new MD5 hashes in: %s' % INIT_PY_PATH) with open(INIT_PY_PATH, 'r') as init_file: contents = init_file.read() - regex = r"('codicon-%s.ttf':\s+)'(\w+)'" % package_version + regex = r"('codicon-%s.ttf':\s+)'(\w+)'" % self.msc_version subst = r"\g<1>'" + md5 + "'" contents = re.sub(regex, subst, contents, 1) self.__print('Dumping updated file: %s' % INIT_PY_PATH)