bat icon indicating copy to clipboard operation
bat copied to clipboard

Feature: Support for colorizing Python trace output

Open zachriggle opened this issue 2 years ago • 2 comments

The Python stdlib module trace module is very useful for tracing what code gets executed.

It would be nice to get bat-colorized output for this.

I can work around this to some extent, by manually invoking bat -r a:b for each line that gets printed, but this is incredibly non-performant.

Alternatively, are there resources that I can look at for adding new languages? Simple regular expressions should work for the 99% use-case.

Example Script

#!/usr/bin/env python3
# simple.py
import time

def add(x=0, y=0):
    return x + y

add(13, 1)

add(-1, 33)

add(-1,
    1 << 12)

def subtract(x=0,
             y=0,
             flag=False):

    result = x - y
    if flag:
        print(f'{result} == {x} - {y}')
    return result

subtract(13, 1)

time.sleep(1)

subtract(13, 1, flag=True)

Output

$ python -m trace --timing --trace ./simple.py
 --- modulename: simple, funcname: <module>
0.00 simple.py(2): import time
0.00 simple.py(4): def add(x=0, y=0):
0.00 simple.py(7): add(13, 1)
 --- modulename: simple, funcname: add
0.00 simple.py(5):     return x + y
0.00 simple.py(9): add(-1, 33)
 --- modulename: simple, funcname: add
0.00 simple.py(5):     return x + y
0.00 simple.py(11): add(-1,
0.00 simple.py(12):     1 << 12)
0.00 simple.py(11): add(-1,
 --- modulename: simple, funcname: add
0.00 simple.py(5):     return x + y
0.00 simple.py(14): def subtract(x=0,
0.00 simple.py(23): subtract(13, 1)
 --- modulename: simple, funcname: subtract
0.00 simple.py(18):     result = x - y
0.00 simple.py(19):     if flag:
0.00 simple.py(21):     return result
0.00 simple.py(25): time.sleep(1)
1.01 simple.py(27): subtract(13, 1, flag=True)
 --- modulename: simple, funcname: subtract
1.01 simple.py(18):     result = x - y
1.01 simple.py(19):     if flag:
1.01 simple.py(20):         print(f'{result} == {x} - {y}')
12 == 13 - 1
1.01 simple.py(21):     return result

zachriggle avatar Nov 24 '21 02:11 zachriggle

Thank you for your request!

The documentation for new Sublime text syntaxes can be found here: https://www.sublimetext.com/docs/syntax.html#ver-3.2 I am linking to the 3.2 version because the latest syntax files are not supported by the syntect library.

You could start with a simple line-based syntax like:

  • https://github.com/sharkdp/bat/blob/master/assets/syntaxes/02_Extra/CpuInfo.sublime-syntax
  • https://github.com/sharkdp/bat/blob/master/assets/syntaxes/02_Extra/Resolv.sublime-syntax and modify that to your needs.

The instructions on how to integrate new syntaxes in bat can be found here: https://github.com/sharkdp/bat#adding-new-syntaxes--language-definitions

sharkdp avatar Nov 26 '21 16:11 sharkdp

I had a play around with this, and the best I could reasonably do is: image

I used ST4's extends functionality for this prototype; to try it in bat, you'd want to just copy/paste the Python syntax instead and add the contexts:

%YAML 1.2
---
name: Python-Trace
scope: source.python.trace
extends: Packages/Python/Python.sublime-syntax

contexts:
  prototype:
    - match: ^[ ]---
      scope: punctuation.definition.comment.begin.python.trace
      push: trace-comment
    - match: ^(\d+\.\d+)\s+(\w+(?:\.\w+))\((\d+)\)(:)
      captures:
        1: meta.number.float.decimal.python.trace constant.numeric.value.python.trace
        2: meta.filename.python.trace string.unquoted.python.trace
        3: meta.linenumber.python.trace meta.number.integer.decimal.python.trace constant.numeric.value.python.trace
        4: punctuation.separator.python.trace
    - match: $
      pop: true

  trace-comment:
    - meta_include_prototype: false
    - meta_scope: comment.line.double-slash.python.trace
    - match: $\n?
      pop: true

and one small modification to Python.sublime-syntax to make it less strict about def not being the first word on a line: image

keith-hall avatar Apr 19 '22 20:04 keith-hall