A JupyterLab plugin to facilitate invocation of code formatters.

ryantam626, updated 🕥 2023-03-20 04:24:51

A JupyterLab plugin to facilitate invocation of code formatters.

Binder npm version npm downloads code style Github Actions Status


Documentation: Hosted on GitHub Pages


Demo


Quick Start

I recommend you going to the documentation site, but this should work too.

  1. Install the package bash pip install jupyterlab-code-formatter

  2. Install some supported formatters (isort+black are default for Python) ```bash

NOTE: Install black and isort,

JL code formatter is configured to invoke isort and black by default

pip install black isort ```

  1. Restart JupyterLab

This plugin includes a server plugin, restart JupyterLab if you have followed the above steps while it's running.

  1. Configure plugin

To configure which/how formatters are invoked, see configuration.


Your Support

I could really use your support in giving me a star on GitHub, recommending features, fixing bugs or maybe even providing monetary support!


Contributors

Massive thanks to the below list of people who made past contributions to the project!

License

This project is licensed under the terms of the MIT license.

Issues

Use `importlib.utils.find_spec`, allow to cache results

opened on 2023-03-20 04:24:50 by krassowski

Fixes https://github.com/ryantam626/jupyterlab_code_formatter/issues/293

Switches to importlib.util.find_spec which is slightly faster than reloading packages.

Exposes a new user setting allowing to cache the formatter information:

Screenshot from 2023-03-20 04-23-33

Support ruff as a formatter

opened on 2023-03-08 13:55:37 by felix-cw

Ruff is a linter for python that also has the ability to fix the lints automatically. I'm using it as an alternative to isort.

I think it would be good to add it as a supported option in this package.

Here is the code I used to add it as a custom formatter:

```python from jupyterlab_code_formatter.formatters import ( SERVER_FORMATTERS, CommandLineFormatter, )

class RuffFixFormatter(CommandLineFormatter): def init(self): try: from ruff.main import find_ruff_bin

        ruff_command = find_ruff_bin()
    except (ImportError, FileNotFoundError):
        ruff_command = "ruff"
    self.command = [ruff_command, "check", "--fix-only", "-", "--select=COM,I"]

SERVER_FORMATTERS["ruff_isort"] = RuffFixFormatter() ```

I'm not sure how to pass args to a custom function via the normal jupyter lab config, so I hardcoded my rule selection argument --select=COM,I.

Run Black formatter and Isort in one command in a regular Python file.

opened on 2023-03-07 14:37:12 by 3h4

I'm trying to run Jupyterlab_code_formatter in a regular python file in Jupyter Lab. It is not formatted on save. I Can add a shortcut to manually run it:

{ "args": {}, "command": "jupyterlab_code_formatter:black", "keys": [ "Ctrl K", "Ctrl M" ], "selector": ".jp-CodeMirrorEditor" },

Can I add a shortcut to run both Isort and Black formatter? The following setting doesn't work:

{ "shortcuts": [ { "command": "apputils:run-all-enabled", "args": { "commands": ["jupyterlab_code_formatter:black", "jupyterlab_code_formatter:isort"], }, "keys": [ "Ctrl K", "Ctrl M" ], "selector": ".jp-CodeMirrorEditor" } ] }

Remove unused imports with Autoflake?

opened on 2023-03-04 21:14:51 by 3h4

Is there a functionality to remove unused imports and variables, autoflake? I couldn't see it in the configuration page:

https://ryantam626.github.io/jupyterlab_code_formatter/configuration.html

Slow Pageloads

opened on 2023-02-27 19:54:10 by mlucool

Checklist prior to opening an issue - [X] I have followed fully the installation steps laid out in the documentation site. - [X] I have restarted jupyterlab. - [X] I have read the FAQ section in the documentation site.

Describe the bug Using this plugin adds ~1.5-2s of pageload time for my setup.

Additional context I narrowed this down by looking at the network tab. This stems from loading the my-jupyterlab.foo.com/jupyterlab_code_formatter/formatters route which in Jupyter both blocks pageload and (I think) blocks the server as it is single threaded. This network call leads to this code being called.

Below is a reproducer of the longest part of the call, which on my setup takes ~1.6s: ``` %%time

from jupyterlab_code_formatter.formatters import SERVER_FORMATTERS

json.dumps( { "formatters": { name: { "enabled": formatter.importable, "label": formatter.label, } for name, formatter in SERVER_FORMATTERS.items() } } ) ```

Digging deeper, the problem is formatter.importable does not act like property, but function which often calls this expensive function. Each call in my setup takes ~300ms.

I believe if importib.reload is called at most once per get call, that would save 4/5 of the cost. In my setup, I'm ok with this not detecting new instances installed/uninstalled after lab is started.

Would you be open to a PR that: 1. Reduced the times importib is called per get 2. Allowed users to opt for a cached version for this getter

First formatting works; second fails

opened on 2023-02-20 07:39:13 by mikeage

Checklist prior to opening an issue - [x] I have followed fully the installation steps laid out in the documentation site. - [x] I have restarted jupyterlab. - [x] I have read the FAQ section in the documentation site.

Describe the bug Given the following python code in a jupyter cell, it formats it correctly the first time, but fails the second time:

python print("Foo: %s" % (len(df.loc[(df["Cloudfront-Is-Android-Viewer"] == "true") & (df["OS_TYPE"] != "ANDROID_OS_TYPE")])))

Formats to

python print( "Foo: %s" % ( len( df.loc[ (df["Cloudfront-Is-Android-Viewer"] == "true") & (df["OS_TYPE"] != "ANDROID_OS_TYPE") ] ) ) )

But if I click the button again, I get:

Jupyterlab Code Formatter Error Cannot parse: 4:8: len( Diagnostic commands Please attach the output of the following commands (please format them properly)

  • pip freeze $ pip freeze aiofiles==22.1.0 aiosqlite==0.18.0 anyio==3.6.2 appnope==0.1.3 argon2-cffi==21.3.0 argon2-cffi-bindings==21.2.0 arrow==1.2.3 asttokens==2.2.1 attrs==22.2.0 Babel==2.11.0 backcall==0.2.0 beautifulsoup4==4.11.2 black==23.1.0 bleach==6.0.0 certifi==2022.12.7 cffi==1.15.1 charset-normalizer==3.0.1 click==8.1.3 colorama==0.4.6 comm==0.1.2 debugpy==1.6.6 decorator==5.1.1 defusedxml==0.7.1 executing==1.2.0 fastjsonschema==2.16.2 fqdn==1.5.1 gitdb==4.0.10 GitPython==3.1.30 idna==3.4 ipykernel==6.21.2 ipython==8.10.0 ipython-genutils==0.2.0 isoduration==20.11.0 isort==5.12.0 jedi==0.18.2 Jinja2==3.1.2 json5==0.9.11 jsonpointer==2.3 jsonschema==4.17.3 jupyter-events==0.5.0 jupyter-server-mathjax==0.2.6 jupyter-ydoc==0.2.2 jupyter_client==8.0.2 jupyter_core==5.2.0 jupyter_server==2.2.1 jupyter_server_fileid==0.6.0 jupyter_server_terminals==0.4.4 jupyter_server_ydoc==0.6.1 jupyterlab==3.6.1 jupyterlab-code-formatter==1.5.3 jupyterlab-git==0.41.0 jupyterlab-pygments==0.2.2 jupyterlab_server==2.19.0 MarkupSafe==2.1.2 matplotlib-inline==0.1.6 mistune==2.0.5 mypy-extensions==1.0.0 nbclassic==0.5.1 nbclient==0.7.2 nbconvert==7.2.9 nbdime==3.1.1 nbformat==5.7.3 nest-asyncio==1.5.6 notebook==6.5.2 notebook_shim==0.2.2 numpy==1.24.2 packaging==23.0 pandas==1.5.3 pandocfilters==1.5.0 parso==0.8.3 pathspec==0.11.0 pexpect==4.8.0 pickleshare==0.7.5 platformdirs==3.0.0 prometheus-client==0.16.0 prompt-toolkit==3.0.36 psutil==5.9.4 ptyprocess==0.7.0 pure-eval==0.2.2 pycparser==2.21 Pygments==2.14.0 pyrsistent==0.19.3 python-dateutil==2.8.2 python-json-logger==2.0.5 pytz==2022.7.1 PyYAML==6.0 pyzmq==25.0.0 requests==2.28.2 rfc3339-validator==0.1.4 rfc3986-validator==0.1.1 Send2Trash==1.8.0 six==1.16.0 smmap==5.0.0 sniffio==1.3.0 soupsieve==2.3.2.post1 stack-data==0.6.2 terminado==0.17.1 tinycss2==1.2.1 tornado==6.2 traitlets==5.9.0 uri-template==1.2.0 urllib3==1.26.14 wcwidth==0.2.6 webcolors==1.12 webencodings==0.5.1 websocket-client==1.5.1 y-py==0.5.5 ypy-websocket==0.8.2

  • jupyter labextension list ``` $ jupyter labextension list JupyterLab v3.6.1 /Users/mikemi/src/cloudfront-header-analysis/.venv/share/jupyter/labextensions jupyterlab_pygments v0.2.2 enabled OK (python, jupyterlab_pygments) nbdime-jupyterlab v2.1.1 enabled OK @ryantam626/jupyterlab_code_formatter v1.5.3 enabled OK (python, jupyterlab-code-formatter) @jupyterlab/git v0.41.0 enabled OK (python, jupyterlab-git)

/usr/local/share/jupyter/labextensions jupyterlab-theme-solarized-dark v2.0.0-dev.1 enabled OK (python, jupyterlab_theme_solarized_dark)

Other labextensions (built into JupyterLab) app dir: /Users/mikemi/src/cloudfront-header-analysis/.venv/share/jupyter/lab

- `jupyter serverextension list` $ jupyter serverextension list config dir: /Users/mikemi/src/cloudfront-header-analysis/.venv/etc/jupyter jupyter_server_ydoc enabled - Validating... X is jupyter_server_ydoc importable? jupyterlab enabled - Validating... jupyterlab 3.6.1 OK jupyterlab_code_formatter enabled - Validating... jupyterlab_code_formatter 1.5.3 OK jupyterlab_git enabled - Validating... jupyterlab_git 0.41.0 OK nbdime enabled - Validating... nbdime 3.1.1 OK config dir: /usr/local/etc/jupyter jupyterlab enabled - Validating... jupyterlab 3.6.1 OK jupyterlab_code_formatter enabled - Validating... jupyterlab_code_formatter 1.5.3 OK jupyterlab_git enabled - Validating... jupyterlab_git 0.41.0 OK nbdime enabled - Validating... nbdime 3.1.1 OK ``` Screenshots n/a Additional context n/a

Ryan Tam

Software Engineer at @huq-industries :metal: :cat: :hong_kong: :gb:

GitHub Repository Homepage

jupyterlab-extension jupyterlab-extensions yapf black code-formatter autopep8 python r