Compare commits

..
28 changed files with 344 additions and 1870 deletions

162
.gitignore vendored
View file

@ -1,162 +1,4 @@
## Python gitignore *.pyc
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/ build/
develop-eggs/
dist/ dist/
downloads/ colout.egg-info/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
.hypothesis/
.pytest_cache/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
target/
# Jupyter Notebook
.ipynb_checkpoints
# pyenv
.python-version
# celery beat schedule file
celerybeat-schedule
# SageMath parsed files
*.sage.py
# Environments
.env
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
## Jetbrains
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
# User-specific stuff
.idea/**/workspace.xml
.idea/**/tasks.xml
.idea/**/usage.statistics.xml
.idea/**/dictionaries
.idea/**/shelf
# Sensitive or high-churn files
.idea/**/dataSources/
.idea/**/dataSources.ids
.idea/**/dataSources.local.xml
.idea/**/sqlDataSources.xml
.idea/**/dynamic.xml
.idea/**/uiDesigner.xml
.idea/**/dbnavigator.xml
# Gradle
.idea/**/gradle.xml
.idea/**/libraries
# Mongo Explorer plugin
.idea/**/mongoSettings.xml
# Editor-based Rest Client
.idea/httpRequests
# SonarLint
.idea/sonarlint
# CMake
cmake-build-*/
# File-based project format
*.iws
# IntelliJ
out/
# mpeltonen/sbt-idea plugin
.idea_modules/
# JIRA plugin
atlassian-ide-plugin.xml
# Cursive Clojure plugin
.idea/replstate.xml
# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties

View file

@ -1,12 +0,0 @@
language: python
python:
- "3.5"
- "3.6"
- "3.7"
- "3.8"
- "pypy3"
install:
- pip install .
script:
- colout --help
- echo heyoo | colout hey yellow

View file

@ -1 +0,0 @@
include LICENSE

234
README.md
View file

@ -1,24 +1,16 @@
colout — Color Up Arbitrary Command Output colout(1) -- Color Up Arbitrary Command Output
========================================== ==============================================
<p align="center"> ## SYNOPSIS
<img
width="640"
src="https://raw.githubusercontent.com/nojhan/colout/master/colout_logo.svg"
alt="Colout logo"
/>
</p>
## Synopsis `colout` [-h] [-r RESOURCE]
`colout [-h] [-r [RESOURCE]]` `colout` [-g] [-c] [-l min,max] [-a] [-t] [-T DIR] [-P DIR] [-d COLORMAP] [-s] [--debug] PATTERN [COLOR(S) [STYLE(S)]]
`colout [-g] [-c] [-l min,max] [-a] [-t] [-T DIR] [-P DIR] [-d COLORMAP] [-s] [-e CHAR] [-E CHAR] [--debug] PATTERN [COLOR(S) [STYLE(S)]]` ## DESCRIPTION
## Description
`colout` read lines of text stream on the standard input and output characters `colout` read lines of text stream on the standard input and output characters
matching a given regular expression *PATTERN* in given *COLOR* and *STYLE*. matching a given regular expression *PATTERN* in given <COLOR> and *STYLE*.
If groups are specified in the regular expression pattern, only them are taken If groups are specified in the regular expression pattern, only them are taken
into account, else the whole matching pattern is colored. into account, else the whole matching pattern is colored.
@ -33,13 +25,9 @@ rainbow, random, Random, Spectrum, spectrum, scale, Scale, hash, Hash, none, an
RGB hexadecimal triplet (`#11aaff`, for example) or any number between 0 and 255. RGB hexadecimal triplet (`#11aaff`, for example) or any number between 0 and 255.
Available styles are: normal, bold, faint, italic, underline, blink, Available styles are: normal, bold, faint, italic, underline, blink,
rapid_blink, reverse, conceal or random (some styles may have no effect, depending rapid\_blink, reverse, conceal or random (some styles may have no effect, depending
on your terminal). on your terminal).
In some case, you can indicate a foreground and a background color, by indicating both colors
separated by a period (for example: `red.blue`). You can also use this system to combine two styles
(for example, for a bold style that also blinks: `bold.blink`).
`rainbow` will cycle over a the default colormap at each matching pattern. `rainbow` will cycle over a the default colormap at each matching pattern.
`Rainbow` will do the same over the default colormap for the 256-colors mode `Rainbow` will do the same over the default colormap for the 256-colors mode
(this requires a terminal that supports the 256 color escape sequences). (this requires a terminal that supports the 256 color escape sequences).
@ -64,10 +52,10 @@ Before interpreting the matched string as a number, colout will remove any
character not supposed to be used to write down numbers. This permits to apply character not supposed to be used to write down numbers. This permits to apply
this special color on a large group, while interpreting only its numerical part. this special color on a large group, while interpreting only its numerical part.
You can use the name of a syntax-coloring ["lexer"](http://pygments.org/docs/lexers/) If the python3-pygments library is installed, you can use the name of a
as a color (for example: "Cpp", "ruby", "xml+django", etc.). syntax-coloring "lexer" as a color (for example: "Cpp", "ruby", "xml+django", etc.).
If GIMP palettes files (*.gpl) are available, you can also use their names as a If GIMP palettes files (\*.gpl) are available, you can also use their names as a
colormap (see the `-P` switch below). colormap (see the `-P` switch below).
Note that the RGB colors (either the hex triplets or the palettes's colors) will Note that the RGB colors (either the hex triplets or the palettes's colors) will
@ -78,7 +66,8 @@ When not specified, a *COLOR* defaults to _red_ and a *STYLE* defaults to _bold_
`colout` comes with some predefined themes to rapidly color well-known outputs `colout` comes with some predefined themes to rapidly color well-known outputs
(see the `-t` switch below). (see the `-t` switch below).
`colout` can be used as an interface to pygments (see also the `--source` switch below). If the python3-pygments library is available, `colout` can be used as an interface
to it (see also the `-s` switch below).
To have a list of all colors, styles, special colormaps, themes, palettes and lexers, To have a list of all colors, styles, special colormaps, themes, palettes and lexers,
use the `-r` switch (see below). use the `-r` switch (see below).
@ -86,29 +75,37 @@ use the `-r` switch (see below).
`colout` is released under the GNU Public License v3. `colout` is released under the GNU Public License v3.
## Installation ## INSTALLATION
The recomended method is using pip to install the package for the local user: sudo python3 setup.py install
```console and then soft link `/usr/local/bin/colout` to your colout.py under your installation
$ pip install --user colout directory, which is usually something like
```
Another method is using [pipsi](https://github.com/mitsuhiko/pipsi) /usr/local/lib/python3/dist-packages/colout-0.1-py3.egg/colout/colout.py
(_pipsi is no longer maintained, <https://github.com/mitsuhiko/pipsi/blob/db3e3fccbe4f8f9ed1104ed7293ec8fec6579efc/README.md#L3>_)
```console
$ pipsi install colout
```
There is also a PPA for Ubuntu 16.04 (Xenial)/18.04 (Bionic) (@`0.6.1-3~dist7`, not actively maintained)
```console ## OTHER INSTALLATION METHOD
$ sudo add-apt-repository ppa:csaba-kertesz/random
$ sudo apt-get update
$ sudo apt-get/aptitude install colout
```
## Options Pypi (the Python Package Index)
sudo pip install colout
or
sudo easy_install colout
Ubuntu 13.04's ppa
sudo add-apt-repository ppa:ciici123/colout
sudo apt-get update
sudo apt-get/aptitude install colout
Gentoo
sudo emerge colout
## OPTIONS
* `-h`, `--help`: * `-h`, `--help`:
Show a help message and exit Show a help message and exit
@ -120,9 +117,8 @@ $ sudo apt-get/aptitude install colout
Use the given list of comma-separated colors as a colormap (cycle the colors at each match). Use the given list of comma-separated colors as a colormap (cycle the colors at each match).
* `-l min,max`, `--scale min,max`: * `-l min,max`, `--scale min,max`:
When using the 'scale' colormap, parse matches as decimal numbers (taking your locale into When using the 'scale' colormap, parse matches as decimal numbers (taking your locale into account)
account) or as arithmetic expression (like "1+2/0.9*3") and apply the rainbow colormap linearly and apply the rainbow colormap linearly between the given min,max (0,100, by default).
between the given min,max (0,100, by default).
* `-a`, `--all`: * `-a`, `--all`:
Color the whole input at once instead of line per line Color the whole input at once instead of line per line
@ -132,10 +128,10 @@ $ sudo apt-get/aptitude install colout
Interpret PATTERN as a predefined theme (perm, cmake, g++, etc.). Interpret PATTERN as a predefined theme (perm, cmake, g++, etc.).
* `-T DIR`, `--themes-dir DIR`: * `-T DIR`, `--themes-dir DIR`:
Search for additional themes (colout_*.py files) in this directory. Search for additional themes (colout\_\*.py files) in this directory.
* `-P DIR`, `--palettes-dir DIR`: * `-P DIR`, `--palettes-dir DIR`:
Search for additional palettes (*.gpl files) in this directory. Search for additional palettes (\*.gpl files) in this directory.
* `-d COLORMAP`, `--default COLORMAP`: * `-d COLORMAP`, `--default COLORMAP`:
When using special colormaps (`random`, `scale` or `hash`), use this COLORMAP instead of the default one. When using special colormaps (`random`, `scale` or `hash`), use this COLORMAP instead of the default one.
@ -145,27 +141,21 @@ $ sudo apt-get/aptitude install colout
Also, external palettes are converted from RGB to 256-ANSI and will thus not work if you use Also, external palettes are converted from RGB to 256-ANSI and will thus not work if you use
them as default colormaps for a 8-colors mode special color. them as default colormaps for a 8-colors mode special color.
* `-r [TYPE(S)]`, `--resources [TYPE(S)]`: * `-r TYPE(S)`, `--resources TYPE(S)`:
Print the names of available resources. Use a comma-separated list of resources names Print the names of available resources. Use a comma-separated list of resources names
(styles, colors, special, themes, palettes, colormaps or lexers), (styles, colors, special, themes, palettes, colormaps or lexers),
use 'all' (or no argument) to print all resources. use 'all' to print everything.
* `-s`, `--source`: * `-s`, `--source`:
Interpret PATTERN as source code readable by the Pygments library. If the first letter of PATTERN Interpret PATTERN as source code readable by the Pygments library. If the first letter of PATTERN
is upper case, use the 256 color mode, if it is lower case, use the 8 colors mode. is upper case, use the 256 color mode, if it is lower case, use the 8 colors mode.
In 256 color mode, interpret COLOR as a Pygments style (e.g. "default"). In 256 color mode, interpret COLOR as a Pygments style (e.g. "default").
* `-e CHAR`, `--sep-list CHAR`:
Use this character as a separator for list of colors/resources/numbers (instead of comma).
* `-E CHAR`, `--sep-pair CHAR`:
Use this character as a separator for foreground/background pairs (instead of period).
* `--debug`: * `--debug`:
Debug mode: print what's going on internally, if you want to check what features are available. Debug mode: print what's going on internally, if you want to check what features are available.
## Regular expressions ## REGULAR EXPRESSIONS
A regular expression (or _regex_) is a pattern that describes a set of strings A regular expression (or _regex_) is a pattern that describes a set of strings
that matches it. that matches it.
@ -175,25 +165,25 @@ that matches it.
special characters that would be recognize by your shell. special characters that would be recognize by your shell.
## Dependencies ## DEPENDENCIES
Necessary Python modules: Recommended packages:
* `argparse` for a usable arguments parsing
* `pygments` for the source code syntax coloring * `pygments` for the source code syntax coloring
* `babel` for a locale-aware number parsing * `babel` for a locale-aware number parsing
## Limitations ## LIMITATIONS
Don't use nested groups or colout will duplicate the corresponding input text Don't use nested groups or colout will duplicate the corresponding input text
with each matching colors. with each matching colors.
Using a default colormap that is incompatible with the special colormap's mode Using a default colormap that is incompatible with the special colormap's mode
(i.e. number of colors) will end badly. will end badly.
Color pairs (`foreground.background`) work in 8-colors mode for simple coloring, but may fail with `--colormap`.
## Examples ## EXAMPLES
### Simple ### Simple
@ -203,7 +193,7 @@ Color pairs (`foreground.background`) work in 8-colors mode for simple coloring,
* Color in bold violet home directories in _/etc/passwd_: * Color in bold violet home directories in _/etc/passwd_:
`colout '/home/[a-z]+' 135 < /etc/passwd` `colout '/home/[a-z]+' 135 < /etc/passwd`
* Color in yellow user/groups id, in bold green name and in bold red home directories in `/etc/passwd`: * Color in yellow user/groups id, in bold green name and in bold red home directories in _/etc/passwd_:
`colout ':x:([0-9]+:[0-9]+):([^:]+).*(/home/[a-z]+)' yellow,green,red normal,bold < /etc/passwd` `colout ':x:([0-9]+:[0-9]+):([^:]+).*(/home/[a-z]+)' yellow,green,red normal,bold < /etc/passwd`
* Color in yellow file permissions with read rights for everyone: * Color in yellow file permissions with read rights for everyone:
@ -267,131 +257,31 @@ Color pairs (`foreground.background`) work in 8-colors mode for simple coloring,
The following bash function color the output of any command with the The following bash function color the output of any command with the
cmake and g++ themes: cmake and g++ themes:
```bash function cm()
function cm() {
{
set -o pipefail set -o pipefail
$@ 2>&1 | colout -t cmake | colout -t g++ $@ 2>&1 | colout -t cmake | colout -t g++
} }
```
You then can use the `cm` alias as a prefix to your build command, You then can use the `cm` alias as a prefix to your build command,
for example: `cm make test` for example: `cm make test`
### GDB integration
You can use `colout` within the GNU debuger (`gbd`) to color its output.
For example, the following script `.gdbinit` configuration will color
the output of the backtrace command:
```gdb
set confirm off
# Don't wrap line or the coloring regexp won't work.
set width 0
# Create a named pipe to get outputs from gdb
shell test -e /tmp/coloutPipe && rm /tmp/coloutPipe
shell mkfifo /tmp/coloutPipe
define logging_on
# Instead of printing on stdout only, log everything...
set logging redirect on
# ... in our named pipe.
set logging on /tmp/coloutPipe
end
define logging_off
set logging off
set logging redirect off
# Because both gdb and our commands are writing on the same pipe at the same
# time, it is more than probable that gdb will end before our (higher level)
# commands. The gdb prompt will thus render before the result of the command,
# which is highly akward. To prevent this, we need to wait before displaying
# the prompt again. The more your commands are complex, the higher you will
# need to set this.
shell sleep 0.4s
end
define hook-backtrace
# Note: match path = [path]file[.ext] = (.*/)?(?:$|(.+?)(?:(\.[^.]*)|))
# This line color highlights:
# – lines that link to source code,
# – function call in green,
# – arguments names in yellow, values in magenta,
# — the parent directory in bold red (assuming that the debug session would be in a "project/build/" directory).
shell cat /tmp/coloutPipe | colout "^(#)([0-9]+)\s+(0x\S+ )*(in )*(.*) (\(.*\)) (at) (.*/)?(?:$|(.+?)(?:(\.[^.]*)|)):([0-9]+)" red,red,blue,red,green,magenta,red,none,white,white,yellow normal,bold,normal,normal,normal,normal,normal,bold,bold,bold | colout "([\w\s]*?)(=)([^,]*?)([,\)])" yellow,blue,magenta,blue normal | colout "/($(basename $(dirname $(pwd))))/" red bold &
logging_on
end
define hookpost-backtrace
logging_off
end
# Don't forget to clean the adhoc pipe.
define hook-quit
set confirm off
shell rm -f /tmp/coloutPipe
end
```
Take a look at the `example.gdbinit` file distributed with colout for more gdb commands.
### Themes ### Themes
You can easily add your own theme to colout. You can easily add your own theme to colout.
A theme is basically a module with a function named `theme` that take the configuration context as A theme is basically a module with a function named `theme` that take the configuration context as an argument and
an argument and return back the (modified) context and a list of triplets. return back the (modified) context and a list of triplets.
Each triplet figures the same arguments than those of the command line interface. Each triplet figures the same arguments than those of the command line interface.
```python def theme(context):
def theme(context):
return context,[ [regexp, colors, styles] ] return context,[ [regexp, colors, styles] ]
```
With the context dictionary at hand, you have access to the internal configuration of colout, you With the context dictionary at hand, you have access to the internal configuration of colout, you can thus change colormaps for
can thus change colormaps for special keywords, the scale, even the available colors, styles or special keywords, the scale, even the available colors, styles or themes.
themes.
See the cmake them for how to modify an existing colormap if (and only if) the user didn't ask for an alternative one. See the cmake theme for how to modify an existing colormap if (and only if) the user didn't ask for an
alternative one.
See the ninja theme for how to extend an existing theme with more regexps and a different configuration. See the ninja theme for how to extend an existing theme with more regexps and a different configuration.
See the gcc theme for an example of how to use the localization of existing softwares to build translated regexp. See the gcc theme for an example of how to use the localization of existing softwares to build translated regexp.
### Buffering
Note that when you use colout within real time streams (like `tail -f X | grep Y | colout Z`) of
commands, you may observe that the lines are printed by large chunks and not one by one, in real
time.
This is not due to colout but to the buffering behavior of your shell.
To fix that, use `stdbuf`, for example: `tail -f X | stdbuf -o0 grep Y | colout Z`.
## Authors
* nojhan <nojhan@nojhan.net>: original idea, main developer, maintainer.
* Adrian Sadłocha <adrian.adek@gmail.com>
* Alex Burka <aburka@seas.upenn.edu>
* Brian Foley <bpfoley@gmail.com>
* Charles Lewis <noodle@umich.edu>
* DainDwarf <daindwarf@gmail.com>
* Dimitri Merejkowsky <dmerejkowsky@aldebaran-robotics.com>
* Dong Wei Ming <ciici123@gmail.com>
* Fabien MARTY <fabien.marty@gmail.com>
* Jason Green <jason@green.io>
* John Anderson <sontek@gmail.com>
* Jonathan Poelen <jonathan.poelen@gmail.com>
* Louis-Kenzo Furuya Cahier <louiskenzo@gmail.com>
* Mantas <sirexas@gmail.com>
* Martin Ueding <dev@martin-ueding.de>
* Nicolas Pouillard <nicolas.pouillard@gmail.com>
* Nurono <while0pass@yandex.ru>
* Oliver Bristow <obristow@mintel.com>
* orzrd <61966225@qq.com>
* Philippe Daouadi <p.daouadi@free.fr>
* Piotr Staroszczyk <piotr.staroszczyk@get24.org>
* Scott Lawrence <oz@lindenlab.com>
* Xu Di <xudifsd@gmail.com>
* https://github.com/stdedos: maintainer.

11
bin/colout Normal file
View file

@ -0,0 +1,11 @@
#!/bin/bash
# Copyright (c) 2013 Martin Ueding <dev@martin-ueding.de>
# Small launcher script for the main module.
# Licence: GPL 3
set -e
set -u
python3 -m colout.colout "$@"

View file

@ -1,26 +1,22 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
#encoding: utf-8 #encoding: utf-8
# Color Up Arbitrary Command Output # Color Up Arbitrary Command Ouput
# Licensed under the GPL version 3 # Licensed under the GPL version 3
# 2012 (c) nojhan <nojhan@nojhan.net> # 2012 (c) nojhan <nojhan@nojhan.net>
import os
import re
import sys import sys
import copy import re
import random
import os
import glob import glob
import math import math
import pprint import importlib
import random import logging
import signal import signal
import string import string
import hashlib import hashlib
import logging
import argparse
import importlib
import functools import functools
import babel.numbers as bn
# set the SIGPIPE handler to kill the program instead of # set the SIGPIPE handler to kill the program instead of
# ending in a write error when a broken pipe occurs # ending in a write error when a broken pipe occurs
@ -41,23 +37,11 @@ context["styles"] = {
"reverse": 7, "conceal": 8 "reverse": 7, "conceal": 8
} }
error_codes = {"UnknownColor": 1, "DuplicatedPalette": 2, "MixedModes": 3, "UnknownLexer": 4, "UnknownResource": 5} # Available color names in 8-colors mode
context["colors"] = {
# Available color names in 8-colors mode. "black": 0, "red": 1, "green": 2, "yellow": 3, "orange":3, "blue": 4,
eight_colors = ["black","red","green","yellow","blue","magenta","cyan","white"] "magenta": 5, "purple": 5, "cyan": 6, "white": 7, "none": -1
# Given in that order, the ASCII code is the index. }
eight_color_codes = {n:i for i,n in enumerate(eight_colors)}
# One can add synonyms.
eight_color_codes["orange"] = eight_color_codes["yellow"]
eight_color_codes["purple"] = eight_color_codes["magenta"]
# Foreground colors has a special "none" item.
# Note: use copy to avoid having the same reference over fore/background.
context["colors"] = copy.copy(eight_color_codes)
context["colors"]["none"] = -1
# Background has the same colors than foreground, but without the none code.
context["backgrounds"] = copy.copy(eight_color_codes)
context["themes"] = {} context["themes"] = {}
@ -93,11 +77,6 @@ context["scale"] = (0,100)
context["lexers"] = [] context["lexers"] = []
# Character use as a delimiter
# between foreground and background.
context["sep_pair"]="."
context["sep_list"]=","
class UnknownColor(Exception): class UnknownColor(Exception):
pass pass
@ -107,27 +86,13 @@ class DuplicatedPalette(Exception):
class DuplicatedTheme(Exception): class DuplicatedTheme(Exception):
pass pass
class MixedModes(Exception):
pass
############################################################################### ###############################################################################
# Ressource parsing helpers # Ressource parsing helpers
############################################################################### ###############################################################################
def make_colormap( colors, sep_list = context["sep_list"] ):
cmap = colors.split(sep_list)
# Check unicity of mode. def set_special_colormaps( cmap ):
modes = [mode(c) for c in cmap]
if len(uniq(modes)) > 1:
# Format a list of color:mode, for error display.
raise MixedModes(", ".join(["%s:%s" % cm for cm in zip(cmap,modes)]))
return cmap
def set_special_colormaps( cmap, sep_list = context["sep_list"] ):
"""Change all the special colors to a single colormap (which must be a list of colors).""" """Change all the special colors to a single colormap (which must be a list of colors)."""
global context global context
context["colormaps"]["scale"] = cmap context["colormaps"]["scale"] = cmap
@ -139,7 +104,7 @@ def set_special_colormaps( cmap, sep_list = context["sep_list"] ):
context["colormaps"]["random"] = cmap context["colormaps"]["random"] = cmap
context["colormaps"]["Random"] = cmap context["colormaps"]["Random"] = cmap
context["user_defined_colormaps"] = True context["user_defined_colormaps"] = True
logging.debug("user-defined special colormap: %s" % sep_list.join([str(i) for i in cmap]) ) logging.debug("user-defined special colormap: %s" % ",".join([str(i) for i in cmap]) )
def parse_gimp_palette( filename ): def parse_gimp_palette( filename ):
@ -177,7 +142,7 @@ def parse_gimp_palette( filename ):
palette = [] palette = []
for line in lines: for line in lines:
# skip lines with only a comment # skip lines with only a comment
if re.match(r"^\s*#.*$", line ): if re.match("^\s*#.*$", line ):
continue continue
# decode the columns-ths codes. Generally [R G B] followed by a comment # decode the columns-ths codes. Generally [R G B] followed by a comment
colors = [ int(c) for c in line.split()[:columns] ] colors = [ int(c) for c in line.split()[:columns] ]
@ -249,13 +214,12 @@ def hex_to_rgb(h):
def load_themes( themes_dir): def load_themes( themes_dir):
global context global context
logging.debug("search for themes in: %s" % themes_dir) logging.debug("search for themes in: %s" % themes_dir)
sys.path.append( themes_dir ) os.chdir( themes_dir )
# load available themes # load available themes
for f in glob.iglob(os.path.join(themes_dir, "colout_*.py")): for f in glob.iglob("colout_*.py"):
basename = os.path.basename(f) # Remove path. module = ".".join(f.split(".")[:-1]) # remove extension
module = os.path.splitext(basename)[0] # Remove extension. name = "_".join(module.split("_")[1:]) # remove the prefix
name = "_".join(module.split("_")[1:]) # Remove the 'colout_' prefix.
if name in context["themes"]: if name in context["themes"]:
raise DuplicatedTheme(name) raise DuplicatedTheme(name)
logging.debug("load theme %s" % name) logging.debug("load theme %s" % name)
@ -265,9 +229,10 @@ def load_themes( themes_dir):
def load_palettes( palettes_dir, ignore_duplicates = True ): def load_palettes( palettes_dir, ignore_duplicates = True ):
global context global context
logging.debug("search for palettes in: %s" % palettes_dir) logging.debug("search for palettes in: %s" % palettes_dir)
os.chdir( palettes_dir )
# load available colormaps (GIMP palettes format) # load available colormaps (GIMP palettes format)
for p in glob.iglob(os.path.join(palettes_dir, "*.gpl")): for p in glob.iglob("*.gpl"):
try: try:
name,palette = parse_gimp_palette(p) name,palette = parse_gimp_palette(p)
except Exception as e: except Exception as e:
@ -290,6 +255,7 @@ def load_lexers():
global context global context
# load available pygments lexers # load available pygments lexers
lexers = [] lexers = []
try:
global get_lexer_by_name global get_lexer_by_name
from pygments.lexers import get_lexer_by_name from pygments.lexers import get_lexer_by_name
@ -303,28 +269,19 @@ def load_lexers():
from pygments.formatters import TerminalFormatter from pygments.formatters import TerminalFormatter
from pygments.lexers import get_all_lexers from pygments.lexers import get_all_lexers
try: except ImportError:
logging.warning("the pygments module has not been found, syntax coloring is not available")
pass
else:
for lexer in get_all_lexers(): for lexer in get_all_lexers():
l = None try:
# If the tuple has one-word aliases lexers.append(lexer[1][0])
# (which are usually a better option than the long names except IndexError:
# for a command line argument).
if lexer[1]:
l = lexer[1][0] # Take the first one.
else:
assert(lexer[0])
l = lexer[0] # Take the long name, which should alway exists.
if not l:
logging.warning("cannot load lexer: %s" % lexer[1][0]) logging.warning("cannot load lexer: %s" % lexer[1][0])
pass # Forget about this lexer. pass
else: else:
assert(" " not in l) # Should be very rare, but probably a source of bugs. logging.debug("loaded lexer %s" % lexer[1][0])
lexers.append(l)
except:
logging.warning("error while executing the pygment module, syntax coloring is not available")
lexers.sort() lexers.sort()
logging.debug("loaded %i lexers: %s" % (len(lexers), ", ".join(lexers)))
context["lexers"] = lexers context["lexers"] = lexers
@ -366,17 +323,17 @@ def mode( color ):
raise UnknownColor(color) raise UnknownColor(color)
def next_in_map( name ): def next_in_map( color ):
global context global context
# loop over indices in colormap # loop over indices in colormap
return (context["colormap_idx"]+1) % len(context["colormaps"][name]) return (context["colormap_idx"]+1) % len(context["colormaps"][color])
def color_random( color ): def color_random( color ):
global context global context
m = mode(color) m = mode(color)
if m == 8: if m == 8:
color_name = random.choice(list(context["colormaps"]["random"])) color_name = random.choice(context["colormaps"]["random"])
color_code = context["colors"][color_name] color_code = context["colors"][color_name]
color_code = str(30 + color_code) color_code = str(30 + color_code)
@ -415,11 +372,23 @@ def color_scale( name, text ):
nb = "".join([i for i in filter(allowed.__contains__, text)]) nb = "".join([i for i in filter(allowed.__contains__, text)])
# interpret as decimal # interpret as decimal
# First, try with the babel module, if available
# if not, use python itself,
# if thoses fails, try to `eval` the string
# (this allow strings like "1/2+0.9*2")
f = None f = None
try:
# babel is a specialized module
import babel.numbers as bn
try: try:
f = float(bn.parse_decimal(nb)) f = float(bn.parse_decimal(nb))
except bn.NumberFormatError: except bn.NumberFormatError:
pass pass
except ImportError:
try:
f = float(nb)
except ValueError:
pass
if f is not None: if f is not None:
# normalize with scale if it's a number # normalize with scale if it's a number
f = (f - context["scale"][0]) / (context["scale"][1]-context["scale"][0]) f = (f - context["scale"][0]) / (context["scale"][1]-context["scale"][0])
@ -473,7 +442,7 @@ def color_hash( name, text ):
def color_map(name): def color_map(name):
global context global context
# current color # current color
color = context["colormaps"][name][ context["colormap_idx"] ] color = context["colormaps"][name][context["colormap_idx"]]
m = mode(color) m = mode(color)
if m == 8: if m == 8:
@ -483,9 +452,9 @@ def color_map(name):
assert( 0 <= color_nb <= 255 ) assert( 0 <= color_nb <= 255 )
color_code = str(color_nb) color_code = str(color_nb)
context["colormap_idx"] = next_in_map(name) context["colormap_idx"] = next_in_map(color)
return color,color_code return color_code
def color_lexer( name, style, text ): def color_lexer( name, style, text ):
@ -509,14 +478,10 @@ def color_lexer( name, style, text ):
return "<"+name+">"+ highlight(text, lexer, formatter)[:-1] + "</"+name+">" return "<"+name+">"+ highlight(text, lexer, formatter)[:-1] + "</"+name+">"
def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]): def colorin(text, color="red", style="normal"):
""" """
Return the given text, surrounded by the given color ASCII markers. Return the given text, surrounded by the given color ASCII markers.
The given color may be either a single name, encoding the foreground color,
or a pair of names, delimited by the given sep_pair,
encoding foreground and background, e.g. "red.blue".
If the given color is a name that exists in available colors, If the given color is a name that exists in available colors,
a 8-colors mode is assumed, else, a 256-colors mode. a 8-colors mode is assumed, else, a 256-colors mode.
@ -541,24 +506,18 @@ def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]):
color_code = "" color_code = ""
style_code = "" style_code = ""
background_code = ""
style_codes = []
# Convert the style code # Convert the style code
if style == "random" or style == "Random": if style == "random" or style == "Random":
style = random.choice(list(context["styles"].keys())) style = random.choice(list(context["styles"].keys()))
else: else:
styles = style.split(sep_pair) if style in context["styles"]:
for astyle in styles: style_code = str(context["styles"][style])
if astyle in context["styles"]:
style_codes.append(str(context["styles"][astyle]))
style_code = ";".join(style_codes)
color_pair = color.strip().split(sep_pair) color = color.strip()
color = color_pair[0] m = mode(color)
background = color_pair[1] if len(color_pair) == 2 else "none"
if color == "none" and background == "none": if color == "none":
# if no color, style cannot be applied # if no color, style cannot be applied
if not debug: if not debug:
return text return text
@ -575,10 +534,10 @@ def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]):
elif color.lower() == "hash": elif color.lower() == "hash":
color_code = color_hash( color, text ) color_code = color_hash( color, text )
# The user can change the "colormap" variable to its favorite one before calling colorin. # Really useful only when using colout as a library
# thus you can change the "colormap" variable to your favorite one before calling colorin
elif color == "colormap": elif color == "colormap":
# "default" should have been set to the user-defined colormap. color_code = color_map(color)
color,color_code = color_map("default")
# Registered colormaps should be tested after special colors, # Registered colormaps should be tested after special colors,
# because special tags are also registered as colormaps, # because special tags are also registered as colormaps,
@ -611,28 +570,14 @@ def colorin(text, color="red", style="normal", sep_pair=context["sep_pair"]):
else: else:
raise UnknownColor(color) raise UnknownColor(color)
m = mode(color)
if background in context["backgrounds"] and m == 8:
background_code = endmarks[m] + str(40 + context["backgrounds"][background])
elif background == "none":
background_code = ""
else:
raise UnknownColor(background)
if color_code is not None: if color_code is not None:
if not debug: if not debug:
return start + style_code + endmarks[m] + color_code + background_code + "m" + text + stop return start + style_code + endmarks[m] + color_code + "m" + text + stop
else: else:
return start + style_code + endmarks[m] + color_code + background_code + "m" \ return start + style_code + endmarks[m] + color_code + "m" \
+ "<color name=" + str(color) \ + "<color name=" + str(color) + " code=" + color_code \
+ " code=" + color_code \ + " style=" + str(style) + " stylecode=" + style_code \
+ " style=" + str(style) \ + " mode=" + str(m) + ">" \
+ " stylecode=" + style_code \
+ " background=" + str(background) \
+ " backgroundcode=" + background_code.strip(endmarks[m]) \
+ " mode=" + str(m) \
+ ">" \
+ text + "</color>" + stop + text + "</color>" + stop
else: else:
if not debug: if not debug:
@ -654,7 +599,7 @@ def colorout(text, match, prev_end, color="red", style="normal", group=0):
return colored_text, end return colored_text, end
def colorup(text, pattern, color="red", style="normal", on_groups=False, sep_list=context["sep_list"]): def colorup(text, pattern, color="red", style="normal", on_groups=False):
""" """
Color up every characters that match the given regexp patterns. Color up every characters that match the given regexp patterns.
If groups are specified, only color up them and not the whole pattern. If groups are specified, only color up them and not the whole pattern.
@ -663,8 +608,20 @@ def colorup(text, pattern, color="red", style="normal", on_groups=False, sep_lis
in which case the different matching groups may be formatted differently. in which case the different matching groups may be formatted differently.
If there is less colors/styles than groups, the last format is used If there is less colors/styles than groups, the last format is used
for the additional groups. for the additional groups.
"""
>>> colorup("Fetchez la vache", "vache", "red", "bold")
'Fetchez la \x1b[1;31mvache\x1b[0m'
>>> colorup("Faites chier la vache", "[Fv]a", "red", "bold")
'\x1b[1;31mFa\x1b[0mites chier la \x1b[1;31mva\x1b[0mche'
>>> colorup("Faites Chier la Vache", "[A-Z](\S+)\s", "red", "bold")
'F\x1b[1;31maites\x1b[0m C\x1b[1;31mhier\x1b[0m la Vache'
>>> colorup("Faites Chier la Vache", "([A-Z])(\S+)\s", "red,green", "bold")
'\x1b[1;31mF\x1b[0m\x1b[1;32maites\x1b[0m \x1b[1;31mC\x1b[0m\x1b[1;32mhier\x1b[0m la Vache'
>>> colorup("Faites Chier la Vache", "([A-Z])(\S+)\s", "green")
'\x1b[0;32mF\x1b[0m\x1b[0;32maites\x1b[0m \x1b[0;32mC\x1b[0m\x1b[0;32mhier\x1b[0m la Vache'
>>> colorup("Faites Chier la Vache", "([A-Z])(\S+)\s", "blue", "bold,italic")
'\x1b[1;34mF\x1b[0m\x1b[3;34maites\x1b[0m \x1b[1;34mC\x1b[0m\x1b[3;34mhier\x1b[0m la Vache'
"""
global context global context
global debug global debug
@ -690,11 +647,11 @@ def colorup(text, pattern, color="red", style="normal", on_groups=False, sep_lis
# Build a list of colors that match the number of grouped, # Build a list of colors that match the number of grouped,
# if there is not enough colors, duplicate the last one. # if there is not enough colors, duplicate the last one.
colors_l = color.split(sep_list) colors_l = color.split(",")
group_colors = colors_l + [colors_l[-1]] * (nb_groups - len(colors_l)) group_colors = colors_l + [colors_l[-1]] * (nb_groups - len(colors_l))
# Same for styles # Same for styles
styles_l = style.split(sep_list) styles_l = style.split(",")
group_styles = styles_l + [styles_l[-1]] * (nb_groups - len(styles_l)) group_styles = styles_l + [styles_l[-1]] * (nb_groups - len(styles_l))
# If we want to iterate colormaps on groups instead of patterns # If we want to iterate colormaps on groups instead of patterns
@ -774,7 +731,7 @@ def map_write( stream_in, stream_out, function, *args ):
write( function(item, *args), stream_out ) write( function(item, *args), stream_out )
def colorgen(stream, pattern, color="red", style="normal", on_groups=False, sep_list=context["sep_list"]): def colorgen(stream, pattern, color="red", style="normal", on_groups=False):
""" """
A generator that colors the items given in an iterable input. A generator that colors the items given in an iterable input.
@ -790,14 +747,71 @@ def colorgen(stream, pattern, color="red", style="normal", on_groups=False, sep_
break break
if not item: if not item:
break break
yield colorup(item, pattern, color, style, on_groups, sep_list) yield colorup(item, pattern, color, style, on_groups)
###################### ######################
# Command line tools # # Command line tools #
###################### ######################
def _args_parse(argv, usage=""): def __args_dirty__(argv, usage=""):
"""
Roughly extract options from the command line arguments.
To be used only when argparse is not available.
Returns a tuple of (pattern,color,style,on_stderr).
>>> colout.__args_dirty__(["colout","pattern"],"usage")
('pattern', 'red', 'normal', False)
>>> colout.__args_dirty__(["colout","pattern","colors","styles"],"usage")
('pattern', 'colors', 'styles', False)
>>> colout.__args_dirty__(["colout","pattern","colors","styles","True"],"usage")
('pattern', 'colors', 'styles', True)
"""
# Use a dirty argument picker
# Check for bad usage or an help flag
if len(argv) < 2 \
or len(argv) > 10 \
or argv[1] == "--help" \
or argv[1] == "-h":
print(usage+"\n")
print("Usage:", argv[0], "<pattern> <color(s)> [<style(s)>] [<print on stderr?>] [<iterate over groups?>]")
print("\tAvailable colors:", " ".join(context["colors"]))
print("\tAvailable styles:", " ".join(context["styles"]))
print("Example:", argv[0], "'^(def)\s+(\w*).*$' blue,magenta italic,bold < colout.py")
sys.exit(1)
assert(len(argv) >= 2)
# Get mandatory arguments
pattern = argv[1]
# default values for optional args
color = "red"
style = "normal"
on_stderr = False
if len(argv) >= 3:
color = argv[2]
if len(argv) >= 4:
style = argv[3]
if len(argv) == 5:
on_groups = bool(argv[4])
if len(argv) == 6:
as_colormap = bool(argv[5])
if len(argv) == 7:
as_theme = bool(argv[6])
if len(argv) == 8:
as_source = bool(argv[7])
if len(argv) == 9:
as_all = bool(argv[8])
if len(argv) == 10:
scale = bool(argv[9])
return pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, scale
def __args_parse__(argv, usage=""):
""" """
Parse command line arguments with the argparse library. Parse command line arguments with the argparse library.
Returns a tuple of (pattern,color,style,on_stderr). Returns a tuple of (pattern,color,style,on_stderr).
@ -809,6 +823,11 @@ def _args_parse(argv, usage=""):
help="A regular expression") help="A regular expression")
pygments_warn=" You can use a language name to activate syntax coloring (see `-r all` for a list)." pygments_warn=" You can use a language name to activate syntax coloring (see `-r all` for a list)."
try:
import pygments
except ImportError:
pygments_warn=" (WARNING: python3-pygments is not available, \
install it if you want to be able to use syntax coloring)"
parser.add_argument("color", metavar="COLOR", type=str, nargs='?', parser.add_argument("color", metavar="COLOR", type=str, nargs='?',
default="red", default="red",
@ -828,6 +847,12 @@ def _args_parse(argv, usage=""):
(cycle the colors at each match)") (cycle the colors at each match)")
babel_warn=" (numbers will be parsed according to your locale)" babel_warn=" (numbers will be parsed according to your locale)"
try:
# babel is a specialized module
import babel.numbers
except ImportError:
babel_warn=" (WARNING: python3-babel is not available, install it \
if you want to be able to parse numbers according to your locale)"
parser.add_argument("-l", "--scale", metavar="SCALE", parser.add_argument("-l", "--scale", metavar="SCALE",
help="When using the 'scale' colormap, parse matches as decimal numbers \ help="When using the 'scale' colormap, parse matches as decimal numbers \
@ -850,8 +875,7 @@ def _args_parse(argv, usage=""):
parser.add_argument("-d", "--default", metavar="COLORMAP", default=None, parser.add_argument("-d", "--default", metavar="COLORMAP", default=None,
help="When using special colormaps (`random`, `scale` or `hash`), use this COLORMAP. \ help="When using special colormaps (`random`, `scale` or `hash`), use this COLORMAP. \
This can be either one of the available colormaps or a comma-separated list of colors. \ This can be either one of the available colormaps or a comma-separated list of colors. \
WARNING: be sure to specify a default colormap that is compatible with the special colormap's mode \ WARNING: be sure to specify a default colormap that is compatible with the special colormap's mode.")
(8 or 256 colors).")
# This normally should be an option with an argument, but this would end in an error, # This normally should be an option with an argument, but this would end in an error,
# as no regexp is supposed to be passed after calling this option, # as no regexp is supposed to be passed after calling this option,
@ -868,24 +892,14 @@ def _args_parse(argv, usage=""):
if it is lower case, use the 8 colors mode. \ if it is lower case, use the 8 colors mode. \
Interpret COLOR as a Pygments style." + pygments_warn) Interpret COLOR as a Pygments style." + pygments_warn)
parser.add_argument("-e", "--sep-list", metavar="CHAR", default=",", type=str,
help="Use this character as a separator for list of colors/resources/numbers (instead of comma).")
parser.add_argument("-E", "--sep-pair", metavar="CHAR", default=".", type=str,
help="Use this character as a separator for foreground/background pairs (instead of period).")
parser.add_argument("--debug", action="store_true", parser.add_argument("--debug", action="store_true",
help="Debug mode: print what's going on internally, useful if you want to check what features are available.") help="Debug mode: print what's going on internally, useful if you want to check what features are available.")
# HACK: Mock up "--resources ALL" if just "--resources" on command line
if (len(sys.argv) == 2 and (sys.argv[1] in ["-r", "--resources"])):
sys.argv.append("ALL")
args = parser.parse_args() args = parser.parse_args()
return args.pattern[0], args.color, args.style, args.groups, \ return args.pattern[0], args.color, args.style, args.groups, \
args.colormap, args.theme, args.source, args.all, args.scale, args.debug, args.resources, args.palettes_dir, \ args.colormap, args.theme, args.source, args.all, args.scale, args.debug, args.resources, args.palettes_dir, \
args.themes_dir, args.default, args.sep_list, args.sep_pair args.themes_dir, args.default
def write_all( as_all, stream_in, stream_out, function, *args ): def write_all( as_all, stream_in, stream_out, function, *args ):
@ -899,16 +913,28 @@ def write_all( as_all, stream_in, stream_out, function, *args ):
map_write( stream_in, stream_out, function, *args ) map_write( stream_in, stream_out, function, *args )
def main(): if __name__ == "__main__":
global context
error_codes = {"UnknownColor":1, "DuplicatedPalette":2}
usage = "A regular expression based formatter that color up an arbitrary text stream." usage = "A regular expression based formatter that color up an arbitrary text stream."
##################### #####################
# Arguments parsing # # Arguments parsing #
##################### #####################
try:
import argparse
# if argparse is not installed
except ImportError:
pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale \
= __args_dirty__(sys.argv, usage)
# if argparse is available
else:
pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale, \ pattern, color, style, on_groups, as_colormap, as_theme, as_source, as_all, myscale, \
debug, resources, palettes_dirs, themes_dirs, default_colormap, sep_list, sep_pair \ debug, resources, palettes_dirs, themes_dirs, default_colormap \
= _args_parse(sys.argv, usage) = __args_parse__(sys.argv, usage)
if debug: if debug:
lvl = logging.DEBUG lvl = logging.DEBUG
@ -921,12 +947,6 @@ def main():
################## ##################
# Load resources # # Load resources #
################## ##################
context["sep_list"] = sep_list
logging.debug("Color list separator: '%s'" % context["sep_list"])
context["sep_pair"] = sep_pair
logging.debug("Color pair separator: '%s'" % context["sep_pair"])
try: try:
# Search for available resources files (themes, palettes) # Search for available resources files (themes, palettes)
# in the same dir as the colout.py script # in the same dir as the colout.py script
@ -938,28 +958,30 @@ def main():
# try additional directories if asked # try additional directories if asked
if palettes_dirs: if palettes_dirs:
for adir in palettes_dirs: for adir in palettes_dirs:
if os.path.isdir(adir): try:
load_palettes( adir ) os.chdir( adir )
else: except OSError as e:
logging.warning("cannot read palettes directory %s, ignore it" % adir) logging.warning("cannot read palettes directory %s, ignore it" % adir)
continue
else:
load_palettes( adir )
if themes_dirs: if themes_dirs:
for adir in themes_dirs: for adir in themes_dirs:
if os.path.isdir(adir): try:
load_themes( adir ) os.chdir( adir )
else: except OSError as e:
logging.warning("cannot read themes directory %s, ignore it" % adir) logging.warning("cannot read themes directory %s, ignore it" % adir)
continue
else:
load_themes( adir )
except DuplicatedPalette as e: except DuplicatedPalette as e:
logging.error( "duplicated palette file name: %s" % e ) logging.error( "duplicated palette file name: %s" % e )
sys.exit( error_codes["DuplicatedPalette"] ) sys.exit( error_codes["DuplicatedPalette"] )
# if debug:
# setting = pprint.pformat(context, depth=2)
# logging.debug(setting)
if resources: if resources:
asked=[r.lower() for r in pattern.split(context["sep_list"])] asked=[r.lower() for r in pattern.split(",")]
def join_sort( l ): def join_sort( l ):
""" """
@ -973,49 +995,33 @@ def main():
return ", ".join(sorted(l, key=lambda s: s.lower()+s)) return ", ".join(sorted(l, key=lambda s: s.lower()+s))
# print("Available resources:") # print("Available resources:")
resources_not_found = []
for res in asked: for res in asked:
resource_found = False
if "style" in res or "all" in res: if "style" in res or "all" in res:
print("STYLES: %s" % join_sort(context["styles"]) ) print("STYLES: %s" % join_sort(context["styles"]) )
resource_found = True
if "color" in res or "all" in res: if "color" in res or "all" in res:
print("COLORS: %s" % join_sort(context["colors"]) ) print("COLORS: %s" % join_sort(context["colors"]) )
resource_found = True
if "special" in res or "all" in res: if "special" in res or "all" in res:
print("SPECIAL: %s" % join_sort(["random", "Random", "scale", "Scale", "hash", "Hash", "colormap"]) ) print("SPECIAL: %s" % join_sort(["random", "Random", "scale", "Scale", "hash", "Hash", "colormap"]) )
resource_found = True
if "theme" in res or "all" in res: if "theme" in res or "all" in res:
if len(context["themes"]) > 0: if len(themes) > 0:
print("THEMES: %s" % join_sort(context["themes"].keys()) ) print("THEMES: %s" % join_sort(context["themes"].keys()) )
else: else:
print("NO THEME") print("NO THEME")
resource_found = True
if "colormap" in res or "all" in res: if "colormap" in res or "all" in res:
if len(context["colormaps"]) > 0: if len(context["colormaps"]) > 0:
print("COLORMAPS: %s" % join_sort(context["colormaps"]) ) print("COLORMAPS: %s" % join_sort(context["colormaps"]) )
else: else:
print("NO COLORMAPS") print("NO COLORMAPS")
resource_found = True
if "lexer" in res or "all" in res: if "lexer" in res or "all" in res:
if len(context["lexers"]) > 0: if len(lexers) > 0:
print("SYNTAX COLORING: %s" % join_sort(context["lexers"]) ) print("SYNTAX COLORING: %s" % join_sort(lexers) )
else: else:
print("NO SYNTAX COLORING (check that python3-pygments is installed)") print("NO SYNTAX COLORING (check that python3-pygments is installed)")
resource_found = True
if not resource_found:
resources_not_found.append(res)
if resources_not_found:
logging.error( "Unknown resources: %s" % ", ".join(resources_not_found) )
sys.exit( error_codes["UnknownResource"] )
sys.exit(0) # not an error, we asked for help sys.exit(0) # not an error, we asked for help
@ -1025,25 +1031,25 @@ def main():
try: try:
if myscale: if myscale:
context["scale"] = tuple([float(i) for i in myscale.split(context["sep_list"])]) context["scale"] = tuple([float(i) for i in myscale.split(",")])
logging.debug("user-defined scale: %f,%f" % context["scale"]) logging.debug("user-defined scale: %f,%f" % context["scale"])
# Default color maps # Default color maps
if default_colormap: if default_colormap:
if default_colormap not in context["colormaps"]: if default_colormap not in context["colormaps"]:
cmap = make_colormap(default_colormap,context["sep_list"]) cmap = default_colormap.split(",")
elif default_colormap in context["colormaps"]: elif default_colormap in context["colormaps"]:
cmap = context["colormaps"][default_colormap] cmap = context["colormaps"][default_colormap]
set_special_colormaps( cmap, context["sep_list"] ) set_special_colormaps( cmap )
# explicit color map # explicit color map
if as_colormap is True and color not in context["colormaps"]: if as_colormap is True and color not in context["colormaps"]:
context["colormaps"]["Default"] = make_colormap(color,context["sep_list"]) # replace the colormap by the given colors context["colormaps"]["Default"] = color.split(",") # replace the colormap by the given colors
context["colormaps"]["default"] = make_colormap(color,context["sep_list"]) # replace the colormap by the given colors context["colormaps"]["default"] = color.split(",") # replace the colormap by the given colors
color = "colormap" # use the keyword to switch to colormap instead of list of colors color = "colormap" # use the keyword to switch to colormap instead of list of colors
logging.debug("used-defined default colormap: %s" % context["sep_list"].join(context["colormaps"]["Default"]) ) logging.debug("used-defined default colormap: %s" % ",".join(context["colormaps"]["Default"]) )
# if theme # if theme
if as_theme: if as_theme:
@ -1055,9 +1061,7 @@ def main():
# if pygments # if pygments
elif as_source: elif as_source:
logging.debug("asked for lexer: %s" % pattern.lower()) logging.debug("asked for lexer: %s" % pattern.lower())
if pattern.lower() not in context["lexers"]: assert(pattern.lower() in lexers)
logging.error("Lexer %r is not available. Run with \"--resources all\" to see the options.")
sys.exit(error_codes["UnknownLexer"])
lexer = get_lexer_by_name(pattern.lower()) lexer = get_lexer_by_name(pattern.lower())
# Python => 256 colors, python => 8 colors # Python => 256 colors, python => 8 colors
ask_256 = pattern[0].isupper() ask_256 = pattern[0].isupper()
@ -1076,20 +1080,14 @@ def main():
# if color # if color
else: else:
write_all( as_all, sys.stdin, sys.stdout, colorup, pattern, color, style, on_groups, context["sep_list"] ) write_all( as_all, sys.stdin, sys.stdout, colorup, pattern, color, style, on_groups )
except UnknownColor as e: except UnknownColor as e:
if debug: if debug:
import traceback import traceback
for var in context:
print(var,context[var])
print(traceback.format_exc()) print(traceback.format_exc())
logging.error("Unknown color: %s (maybe you forgot to install python3-pygments?)" % e ) logging.error("unknown color: %s" % e )
sys.exit( error_codes["UnknownColor"] ) sys.exit( error_codes["UnknownColor"] )
except MixedModes as e:
logging.error("You cannot mix up color modes when defining your own colormap." \
+ " Check the following 'color:mode' pairs: %s." % e )
sys.exit( error_codes["MixedModes"] )
if __name__ == "__main__":
main()

View file

@ -1,23 +0,0 @@
def theme(context):
return context,[
["^ (Start)(.*): (.*):(.*)$", "yellow", "normal,normal,normal,bold"], # Test start.
# path file ext:line :
["^(tests): (/.*?)/([^/:]+):([0-9]+): (.*)", "yellow,none,white,yellow,red", "bold,normal,bold,normal,bold"],
["(`)(.*)('.*)", "red,Cpp,red", "bold,normal,bold"],
[r"^\.+$", "yellow", "bold"],
["^=+$", "yellow", "bold"],
["(/.*?)/([^/:]+):([0-9]+): (FAILED):", "white,white,yellow,red", "normal,bold,normal,bold"],
[r"(REQUIRE\(|CHECK\(|REQUIRE_THAT\()(.*)(\))$","yellow,Cpp,yellow","bold,normal,bold"],
# Hide uninteresting stuff:
["[0-9]+/[0-9]+ Test.*","blue"],
["^Filters:.*","blue"],
["^Randomness seeded to:.*","blue"],
["^tests is a Catch2.*","blue"],
["^Run with.*", "blue"],
["^~+$","blue"],
["^-+$","blue"],
[r"^\s*(Scenario:|Given:|When:|Then:).*","blue"],
["^(/.*?)/([^/:]+):([0-9]+)", "blue"],
["^(test cases|assertions)(.*)", "blue"],
]

View file

@ -1,85 +0,0 @@
#encoding: utf-8
def default_gettext( msg ):
return msg
def theme(context):
import os
import gettext
import locale
section="blue"
# get g++ version
gv = os.popen("g++ -dumpversion").read().strip()
# get the current translations of gcc
try:
t = gettext.translation("gcc-"+gv)
except IOError:
_ = default_gettext
else:
_ = t.gettext
# _("msg") will return the given message, translated
# if the locale is unicode
enc = locale.getpreferredencoding()
if "UTF" in enc:
# gcc will use unicode quotes
qo = "[‘`]"
qc = "[’']"
else:
# rather than ascii ones
qo = "['`]"
qc = "'"
return context,[
# Command line
[ r"[/\s]([cg]\+\+-*[0-9]*\.*[0-9]*)", "white", "bold" ],
[ r"\s(\-D)(\s*[^\s]+)", "none,green", "normal,bold" ],
[ r"\s(-g)", "green", "normal" ],
[ r"\s-O[0-4]", "green", "normal" ],
[ r"\s-[Wf][^\s]*", "magenta", "normal" ],
[ r"\s-pedantic", "magenta", "normal" ],
[ r"\s(-I)(/*[^\s]+/)([^/\s]+)", "none,blue", "normal,normal,bold" ],
[ r"\s(-L)(/*[^\s]+/)([^/\s]+)", "none,cyan", "normal,normal,bold" ],
[ r"\s(-l)([^/\s]+)", "none,cyan", "normal,bold" ],
[ r"\s-[oc]", "red", "bold" ],
[ r"\s(-+std(?:lib)?)=?([^\s]+)", "red", "normal,bold" ],
# Important messages
[ _("error: "), "red", "bold" ],
[ _("fatal error: "), "red", "bold" ],
[ _("warning: "), "magenta", "bold" ],
[ _("undefined reference to "), "red", "bold" ],
# [-Wflag]
[ r"\[-W.*\]", "magenta"],
# Highlight message start:
# path file ext : line : col …
[ "(/.*?)/([^/:]+): (In .*)"+qo,
section,
"normal,normal,bold" ],
[ "(/.*?)/([^/:]+): (At .*)",
section,
"normal,normal,bold" ],
[ _("In file included from"), section ],
# Highlight locations:
# path file ext : line : col …
[ "(/.*?)/([^/:]+):([0-9]+):*([0-9]*)(.*)",
"none,white,yellow,none,none",
"normal,normal,normal,normal" ],
# source code in single quotes
[ qo+"(.*?)"+qc, "Cpp", "monokai" ],
# source code after a "note: candidate are/is:"
[ _("note: ")+"((?!.*("+qo+"|"+qc+")).*)$", "Cpp", "monokai" ],
# [ _("note: ")+"(candidate:)(.*)$", "green,Cpp", "normal,monokai" ],
# after the code part, to avoid matching ANSI escape chars
[ _("note: "), "green", "normal" ]
]

View file

@ -25,31 +25,26 @@ def theme(context):
[ "^-- Configuring incomplete, errors occurred!", "red" ], [ "^-- Configuring incomplete, errors occurred!", "red" ],
[ "^--.*", performing ], [ "^--.*", performing ],
# Errors # Errors
[ "CMake Error", "red" ], [ "CMake Error:", "red" ],
[ "CMake Warning", "magenta" ], [ "CMake Warning", "yellow" ],
[ "CMake Deprecation Warning", "magenta" ],
# Scan # Scan
[ "^(Scanning dependencies of target)(.*)$", [ "^(Scanning dependencies of target)(.*)$",
performing, "normal,bold" ], performing, "normal,bold" ],
# Link (make) # Link (make)
# [ "^(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$", [ "^(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$",
[ "^(Linking .* )(library|executable) (.*)$",
untimed, "normal,normal,bold" ], untimed, "normal,normal,bold" ],
# [percent] Creating something
[ r"^\[\s*[0-9/]+%?\]\s(.*Creating.*)$",
performing, "normal" ],
# [percent] Built # [percent] Built
[ r"^\[\s*[0-9/]+%?\]\s(Built target)(\s.*)$", [ "^\[\s*[0-9/]+%?\]\s(Built target)(\s.*)$",
performed, "normal,bold" ], performed, "normal,bold" ],
# [percent] Building # [percent] Building
[ r"^\[\s*[0-9/]+%?\]\s(Building \w* object)\s+(.*)(\.dir)(.*/)([-\w]+).c.*.o$", [ "^\[\s*[0-9/]+%?\]\s(Building \w* object)(\s+.*/)([-\w]+.c.*)(.o)$",
performing+","+performing+","+performing+",Hash,"+performing, "normal,normal,normal,normal,bold"], performing, "normal,normal,bold,normal"],
# [percent] Generating # [percent] Generating
[ r"^\[\s*[0-9/]+%?\]\s(Generating)(\s+.*)$", [ "^\[\s*[0-9/]+%?\]\s(Generating)(\s+.*)$",
performing, "normal,bold"], performing, "normal,bold"],
# make errors # make errors
[ r"make\[[0-9]+\].*", "yellow"], [ "make\[[0-9]+\].*", "yellow"],
[ r"(make: \*\*\* \[.+\] )(.* [0-9]+)", "red", "normal,bold"], [ "(make: \*\*\* \[.+\] )(.* [0-9]+)", "red", "normal,bold"],
# progress percentage (make) # progress percentage (make)
[ r"^(\[\s*[0-9]+%\])","Scale" ] [ "^(\[\s*[0-9]+%\])","Scale" ]
] ]

View file

@ -1,16 +0,0 @@
#encoding: utf-8
def theme(context):
return context, [
["^(checking .*)(yes|found|ok)$","green", "normal,bold"],
["^(checking .*)(no|none)$", "yellow", "normal,bold"],
["^(configure:) (error:)(.*)", "red","normal,bold"],
["^(configure:)(.*)", "magenta","normal,bold"],
["^(checking .*)", "blue",""],
["^(config.status:) (creating|linking)(.*)", "cyan,blue","normal,normal,bold"],
["^(config.status:) (executing )(.*)", "cyan,green","normal,normal,bold"],
["^(config.status:) (.*)(is unchanged)", "cyan,green","normal,normal,bold"],
[r"^\s*(Build.*)(yes)$","green", "normal,bold"],
[r"^\s*(Build.*)(no)$","yellow", "normal,bold"],
]

View file

@ -1,19 +0,0 @@
def theme(context):
# CTest theme:
passed="green"
notrun="yellow"
notpassed="red"
# If the user do not ask for his own colormap
# if not context["user_defined_colormaps"]:
# # A palette that goes: purple, orange, white
# percs = [45, 39, 33, 27, 21, 57, 63, 62, 98, 97, 133, 132, 138, 173, 172, 208, 214, 220, 226, 228, 229, 230, 231, 255]
# context["colormaps"]["Scale"] = percs
return context,[
# Passed
[ r"^\s*[0-9]+/[0-9]+ Test\s+#[0-9]+: (.*)\s+\.+\s+(Passed)", "blue,"+passed],
[ r"^\s*[0-9]+/[0-9]+ Test\s+#[0-9]+: (.*)\s+\.+(\*{3}Not Run.*)\s+.*", "blue,"+notrun],
[ r"^\s*[0-9]+/[0-9]+ Test\s+#[0-9]+: (.*)\s+\.+(.*\*{3}.*)\s+.*", "blue,"+notpassed],
]

View file

@ -1,36 +0,0 @@
def theme(context):
return context,[
# Waiting
["^Waiting for .*$", "red", "bold"],
[".*Sending.*", "green"],
# Watches
[r"^(Watching) (\S*) (.*)", "yellow", "bold,bold,normal"],
[".*reloading.$","yellow"],
# File from python/lib
[r"^(File) (/.*/lib/python[^/]*/site-packages/)([^/]*)\S* (first seen) (with mtime [0-9]*.*)$",
"blue,blue,white,blue,blue", "bold,normal,bold,bold,normal"],
# File from app (last 3 name highlighted)
[r"^(File) (/\S*/)(\S*/\S*/)(\S*) (first seen) (with mtime [0-9]*.*)$",
"magenta,magenta,white,white,magenta,magenta", "bold,normal,normal,bold,bold,normal"],
# SQL
["(.*)(SELECT)(.*)(FROM)(.*)",
"green", "normal,bold,normal,bold,normal"],
["(.*)(SELECT)(.*)(FROM)(.*)(WHERE)(.*)",
"green", "normal,bold,normal,bold,normal,bold,normal"],
# HTTP
[r"\"(GET) (\S*) (HTTP\S*)\" ([0-9]+) (.*)$",
"green,white,green,green,green", "bold,bold,normal,bold,normal"],
# Errors
["(Exception) (while .*) '(.*)' (in) (.*) '(.*)'", "red,red,white,red,red,white", "bold,normal,bold,bold,normal,bold"],
["(.*Error): (.*) '(.*)'", "red,red,white", "bold,normal,bold"],
[r"(django[^:\s]*)\.([^.:\s]*): (.*)", "red","normal,bold,normal"],
["Traceback.*:","yellow"],
["During handling.*","yellow"],
# File, line, in
[
r"^\s{2}(File \")(/*.*?/)*([^/:]+)(\", line) ([0-9]+)(, in) (.*)$",
"blue, none, white,blue, yellow,blue",
"normal,normal,bold, normal,normal,bold"
],
]

View file

@ -35,17 +35,16 @@ def theme(context):
return context,[ return context,[
# Command line # Command line
[ r"[/\s]([cg]\+\+-*[0-9]*\.*[0-9]*)", "white", "bold" ], [ "[/\s]([cg]\+\+-*[0-9]*\.*[0-9]*)", "white", "bold" ],
[ r"\s(\-D)(\s*[^\s]+)", "none,green", "normal,bold" ], [ "\s(\-D)(\s*[^\s]+\s)", "none,green", "normal,bold" ],
[ r"\s(-g)", "green", "normal" ], [ "\s-g\s", "green", "normal" ],
[ r"\s-O[0-4]", "green", "normal" ], [ "\s-O[0-4]*\s", "green", "normal" ],
[ r"\s-[Wf][^\s]*", "magenta", "normal" ], [ "\s-[Wf][^\s]*", "magenta", "normal" ],
[ r"\s-pedantic", "magenta", "normal" ], [ "\s(-I)(/*[^\s]+/)([^/\s]+)", "none,blue", "normal,normal,bold" ],
[ r"\s(-I)(/*[^\s]+/)([^/\s]+)", "none,blue", "normal,normal,bold" ], [ "\s(-L)(/*[^\s]+/)([^/\s]+)", "none,cyan", "normal,normal,bold" ],
[ r"\s(-L)(/*[^\s]+/)([^/\s]+)", "none,cyan", "normal,normal,bold" ], [ "\s(-l)([^/\s]+)", "none,cyan", "normal,bold" ],
[ r"\s(-l)([^/\s]+)", "none,cyan", "normal,bold" ], [ "\s-[oc]", "red", "bold" ],
[ r"\s-[oc]", "red", "bold" ], [ "\s(-+std)=*([^s]+)", "red", "normal,bold" ],
[ r"\s(-+std(?:lib)?)=?([^\s]+)", "red", "normal,bold" ],
# Important messages # Important messages
[ _("error: "), "red", "bold" ], [ _("error: "), "red", "bold" ],
@ -53,7 +52,7 @@ def theme(context):
[ _("warning: "), "magenta", "bold" ], [ _("warning: "), "magenta", "bold" ],
[ _("undefined reference to "), "red", "bold" ], [ _("undefined reference to "), "red", "bold" ],
# [-Wflag] # [-Wflag]
[ r"\[-W.*\]", "magenta"], [ "\[-W.*\]", "magenta"],
# Highlight message start: # Highlight message start:
# path file ext : line : col … # path file ext : line : col …
@ -77,8 +76,7 @@ def theme(context):
[ qo+"(.*?)"+qc, "Cpp", "monokai" ], [ qo+"(.*?)"+qc, "Cpp", "monokai" ],
# source code after a "note: candidate are/is:" # source code after a "note: candidate are/is:"
[ _("note: ")+"((?!.*("+qo+"|"+qc+")).*)$", "Cpp", "monokai" ], [ _("note: ")+"((?!.*(candidate|"+qo+"|"+qc+")).*)$", "Cpp", "monokai" ],
# [ _("note: ")+"(candidate:)(.*)$", "green,Cpp", "normal,monokai" ],
# after the code part, to avoid matching ANSI escape chars # after the code part, to avoid matching ANSI escape chars
[ _("note: "), "green", "normal" ] [ _("note: "), "green", "normal" ]
] ]

View file

@ -3,13 +3,13 @@
def theme(context): def theme(context):
style="monokai" style="monokai"
return context,[ return context,[
[ r"^(.*\.java):([0-9]+):\s*(warning:.*)$", "white,yellow,magenta", "normal,normal,bold" ], [ "^(.*\.java):([0-9]+):\s*(warning:.*)$", "white,yellow,magenta", "normal,normal,bold" ],
[ r"^(.*\.java):([0-9]+):(.*)$", "white,yellow,red", "normal,normal,bold" ], [ "^(.*\.java):([0-9]+):(.*)$", "white,yellow,red", "normal,normal,bold" ],
[ r"^(symbol|location)\s*:\s*(.*)$", "blue,Java", "bold,"+style ], [ "^(symbol|location)\s*:\s*(.*)$", "blue,Java", "bold,"+style ],
[ r"^(found)\s*:\s*(.*)", "red,Java", "bold,"+style ], [ "^(found)\s*:\s*(.*)", "red,Java", "bold,"+style ],
[ r"^(required)\s*:\s*(.*)", "green,Java", "bold,"+style ], [ "^(required)\s*:\s*(.*)", "green,Java", "bold,"+style ],
[ r"^\s*\^$", "cyan", "bold" ], [ "^\s*\^$", "cyan", "bold" ],
[ r"^\s+.*$", "Java", style ], [ "^\s+.*$", "Java", style ],
[ "[0-9]+ error[s]*", "red", "bold" ], [ "[0-9]+ error[s]*", "red", "bold" ],
[ "[0-9]+ warning[s]*", "magenta", "bold" ], [ "[0-9]+ warning[s]*", "magenta", "bold" ],
] ]

View file

@ -3,10 +3,10 @@ def theme(context):
# This theme expect a formatted JSON input, with items spread across lines. # This theme expect a formatted JSON input, with items spread across lines.
# See tools like "python -m json.tool" or "json_xs" # See tools like "python -m json.tool" or "json_xs"
return context,[ return context,[
[ r'[\[\]{}],*\s*\n' ], [ '[\[\]{}],*\s*\n' ],
[ '" (:) ', "yellow" ], [ '" (:) ', "yellow" ],
[ r'[\]}"](,)', "yellow" ], [ '[\]}"](,)', "yellow" ],
[ r"\"(-*[0-9]+\.*[0-9]*e*-*[0-9]*)\"", "blue" ], [ "\"(-*[0-9]+\.*[0-9]*e*-*[0-9]*)\"", "blue" ],
[ '"(.*)"', "green" ], [ '"(.*)"', "green" ],
[ """["']""", "cyan" ] [ """["']""", "cyan" ]
] ]

View file

@ -6,21 +6,17 @@ def theme(context):
["(LaTeX Warning): (.*) `(.*)' on page [0-9] (.*) on input line [0-9]+.$", ["(LaTeX Warning): (.*) `(.*)' on page [0-9] (.*) on input line [0-9]+.$",
"magenta,magenta,white,magenta", "normal,bold,normal" ], "magenta,magenta,white,magenta", "normal,bold,normal" ],
["(LaTeX Warning): (.*)", "magenta", "normal,bold" ], ["(LaTeX Warning): (.*)", "magenta", "normal,bold" ],
["(LaTeX Error): (.*)", "red", "normal,bold" ],
[r"^(.*\.tex):([0-9]+): (.*)", "white,yellow,red", "normal,normal,bold" ],
# ["on (page [0-9]+)", "yellow", "normal" ], # ["on (page [0-9]+)", "yellow", "normal" ],
["on input (line [0-9]+)", "yellow", "normal" ], ["on input (line [0-9]+)", "yellow", "normal" ],
["^! .*$", "red", "bold"], ["^! .*$", "red", "bold"],
[r"(.*erfull) ([^\s]+).* in [^\s]+ at (lines [0-9]+--[0-9]+)", ["(.*erfull) ([^\s]+).* in [^\s]+ at (lines [0-9]+--[0-9]+)",
"magenta,magenta,yellow", "normal"], "magenta,magenta,yellow", "normal"],
[r"\\[^\s]+\s", "white", "bold"], ["\\[^\s]+\s", "white", "bold"],
[r"^l\.([0-9]+) (.*)", "yellow,tex"], ["^l\.([0-9]+) ", "yellow"],
[r"^\s+(.*)", "tex"], ["(Output written on) (.*) \(([0-9]+ pages), [0-9]+ bytes\).",
[r"(Output written on) (.*) \(([0-9]+ pages), [0-9]+ bytes\).",
"blue,white,blue", "normal,bold,normal"], "blue,white,blue", "normal,bold,normal"],
["WARNING.*", "magenta", "normal"], ["WARNING.*", "magenta", "normal"],
["[wW]arning.*", "magenta", "normal"], ["warning.*", "magenta", "normal"],
["No pages of output", "red", "bold"],
# BiBTeX # BiBTeX
["^(I couldn't) (.*)", "red", "normal,bold"], ["^(I couldn't) (.*)", "red", "normal,bold"],

View file

@ -11,9 +11,9 @@ def theme(context):
context["scale"] = (0,1) context["scale"] = (0,1)
# Link (ninja) # Link (ninja)
th.append( [ r"^\[[0-9/]+\]\s?(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$", th.append( [ "^\[[0-9/]+\]\s?(Linking .* )(library|executable) (.*/)*(.+(\.[aso]+)*)$",
"blue", "normal,normal,bold" ] ) "blue", "normal,normal,bold" ] )
# progress percentage (ninja) # progress percentage (ninja)
th.append( [ r"^(\[[0-9]+/[0-9]+\])","Scale" ] ) th.append( [ "^(\[[0-9]+/[0-9]+\])","Scale" ] )
return context,th return context,th

View file

@ -1,7 +1,7 @@
def theme(context): def theme(context):
p="([-rwxsStT])" p="([rwxs-])"
reg=r"^([-dpcCDlMmpPs?])"+p*9+r"\s.*$" reg="^([d-])"+p*9+"\s.*$"
colors="blue"+",green"*3+",yellow"*3+",red"*3 colors="blue"+",green"*3+",yellow"*3+",red"*3
styles="normal"+ ",normal,italic,bold"*3 styles="normal"+ ",normal,italic,bold"*3
return context,[ [reg, colors, styles] ] return context,[ [reg, colors, styles] ]

View file

@ -5,16 +5,16 @@ def theme(context):
["^Traceback .*$", "blue" ], ["^Traceback .*$", "blue" ],
# File, line, in # File, line, in
[ [
r"^\s{2}(File \")(/*.*?/)*([^/:]+)(\", line) ([0-9]+)(, in) (.*)$", "^\s{2}(File \")(/*.*?/)*([^/:]+)(\", line) ([0-9]+)(, in) (.*)$",
"blue, none, white,blue, yellow,blue", "blue, none, white,blue, yellow,blue",
"normal,normal,bold, normal,normal,bold" "normal,normal,bold, normal,normal,bold"
], ],
# [r"^\s{2}File \"(.*)\", line ([0-9]+), in (.*)$", "white,yellow,white", "normal,normal,bold" ], # ["^\s{2}File \"(.*)\", line ([0-9]+), in (.*)$", "white,yellow,white", "normal,normal,bold" ],
# Error name # Error name
["^([A-Za-z]*Error):*", "red", "bold" ], ["^([A-Za-z]*Error):*", "red", "bold" ],
["^([A-Za-z]*Exception):*", "red", "bold" ], ["^([A-Za-z]*Exception):*", "red", "bold" ],
# any quoted things # any quoted things
[r"Error.*['\"](.*)['\"]", "magenta" ], ["Error.*['\"](.*)['\"]", "magenta" ],
# python code # python code
[r"^\s{4}.*$", "Python", "monokai" ], ["^\s{4}.*$", "Python", "monokai" ],
] ]

View file

@ -1,117 +0,0 @@
def theme(context):
# SLURM's states (from squeue manual).
col_width = 9
COMPLETED =r"\bCOMPLETED"
PENDING =r"\bPENDING"
RUNNING =r"\bRUNNING"
CONFIGURING =r"\bCONFIGURING"
COMPLETING =r"\bCOMPLETING"
FAILED =r"\bFAILED"
DEADLINE =r"\bDEADLINE"
OUT_OF_MEMORY=r"\bOUT_OF_MEMORY"
TIMEOUT =r"\bTIMEOUT"
CANCELLED =r"\bCANCELLED"
BOOT_FAIL =r"\bBOOT_FAIL"
NODE_FAIL =r"\bNODE_FAIL"
PREEMPTED =r"\bPREEMPTED"
RESV_DEL_HOLD=r"\bRESV_DEL_HOLD"
REQUEUE_FED =r"\bREQUEUE_FED"
REQUEUE_HOLD =r"\bREQUEUE_HOLD"
REQUEUED =r"\bREQUEUED"
RESIZING =r"\bRESIZING"
REVOKED =r"\bREVOKED"
SIGNALING =r"\bSIGNALING"
SPECIAL_EXIT =r"\bSPECIAL_EXIT"
STAGE_OUT =r"\bSTAGE_OUT"
STOPPED =r"\bSTOPPED"
SUSPENDED =r"\bSUSPENDED"
return context,[
## No problem: greens
#Job has terminated all processes on all nodes with an exit code of zero.
[r"\bCD\b", "22"],
[COMPLETED[0:col_width]+r"\w*\b", "22"],
#Job is awaiting resource allocation.
[r"\bPD\b", "28"],
[PENDING[0:col_width]+r"\w*\b", "28"],
#Job currently has an allocation.
[r"\bR\b", "34"],
[RUNNING[0:col_width]+r"\w*\b", "34"],
#Job has been allocated resources, but are waiting for them to become ready for use (e.g. booting).
[r"\bCF\b", "58"],
[CONFIGURING[0:col_width]+r"\w*\b", "58"],
#Job is in the process of completing. Some processes on some nodes may still be active.
[r"\bCG\b", "23"],
[COMPLETING[0:col_width]+r"\w*\b", "23"],
## Problem for the user: bold reds
#Job terminated with non-zero exit code or other failure condition.
[r"\bF\b", "196"],
[FAILED[0:col_width]+r"\w*\b", "196", "bold"],
#Job terminated on deadline.
[r"\bDL\b", "160"],
[DEADLINE[0:col_width]+r"\w*\b", "160", "bold"],
#Job experienced out of memory error.
[r"\bOO\b", "197"],
[OUT_OF_MEMORY[0:col_width]+r"\w*\b", "197", "bold"],
#Job terminated upon reaching its time limit.
[r"\bTO\b", "161"],
[TIMEOUT[0:col_width]+r"\w*\b", "161", "bold"],
## Problem for the sysadmin: oranges
#Job was explicitly cancelled by the user or system administrator. The job may or may not have been initiated.
[r"\bCA\b", "202"],
[CANCELLED[0:col_width]+r"\w*\b", "202", "bold"],
#Job terminated due to launch failure, typically due to a hardware failure (e.g. unable to boot the node or block and the job can not be requeued).
[r"\bBF\b", "166"],
[BOOT_FAIL[0:col_width]+r"\w*\b", "166"],
#Job terminated due to failure of one or more allocated nodes.
[r"\bNF\b", "208"],
[NODE_FAIL[0:col_width]+r"\w*\b", "208"],
## Non-blocking events: blues
#Job terminated due to preemption.
[r"\bPR\b", "105"],
[PREEMPTED[0:col_width]+r"\w*\b", "105", "bold"],
#Job is being held after requested reservation was deleted.
[r"\bRD\b", "25"],
[RESV_DEL_HOLD[0:col_width]+r"\w*\b", "25"],
#Job is being requeued by a federation.
[r"\bRF\b", "26"],
[REQUEUE_FED[0:col_width]+r"\w*\b", "26"],
#Held job is being requeued.
[r"\bRH\b", "27"],
[REQUEUE_HOLD[0:col_width]+r"\w*\b", "27"],
#Completing job is being requeued.
[r"\bRQ\b", "31"],
[REQUEUED[0:col_width]+r"\w*\b", "31"],
#Job is about to change size.
[r"\bRS\b", "32"],
[RESIZING[0:col_width]+r"\w*\b", "32"],
#Sibling was removed from cluster due to other cluster starting the job.
[r"\bRV\b", "33"],
[REVOKED[0:col_width]+r"\w*\b", "33"],
#Job is being signaled.
[r"\bSI\b", "37"],
[SIGNALING[0:col_width]+r"\w*\b", "37"],
#The job was requeued in a special state. This state can be set by users, typically in EpilogSlurmctld, if the job has terminated with a particular exit value.
[r"\bSE\b", "38"],
[SPECIAL_EXIT[0:col_width]+r"\w*\b", "38"],
#Job is staging out files.
[r"\bSO\b", "39"],
[STAGE_OUT[0:col_width]+r"\w*\b", "39"],
#Job has an allocation, but execution has been stopped with SIGSTOP signal. CPUS have been retained by this job.
[r"\bST\b", "44"],
[STOPPED[0:col_width]+r"\w*\b", "44"],
#Job has an allocation, but execution has been suspended and CPUs have been released for other jobs.
[r"\bS\b", "45"],
[SUSPENDED[0:col_width]+r"\w*\b", "45"],
]

Some files were not shown because too many files have changed in this diff Show more