Skip to content

Commit

Permalink
Add ruff code formatter
Browse files Browse the repository at this point in the history
  • Loading branch information
joouha committed Jan 9, 2024
1 parent 54e2655 commit 44db67a
Show file tree
Hide file tree
Showing 7 changed files with 108 additions and 52 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.rst
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ Upcoming
Added
=====

- Add support for ``ruff`` code formatter
- Add support for inline LaTeX math in markdown
- Add ``ziamath`` LaTeX to SVG converter
- Set scroll offset to 1 on cell inputs
Expand Down
48 changes: 20 additions & 28 deletions euporie/core/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -948,35 +948,27 @@ def _clear_screen() -> None:
)

add_setting(
name="format_black",
flags=["--format-black"],
type_=bool,
help_="Use black when re-formatting code cells",
default=True,
description="""
Whether to use :py:mod:`black` when reformatting code cells.
""",
)

add_setting(
name="format_isort",
flags=["--format-isort"],
type_=bool,
help_="Use isort when re-formatting code cells",
default=True,
description="""
Whether to use :py:mod:`isort` when reformatting code cells.
""",
)

add_setting(
name="format_ssort",
flags=["--format-ssort"],
type_=bool,
help_="Use ssort when re-formatting code cells",
default=True,
name="formatters",
flags=["--formatters"],
type_=str,
choices=["ruff", "black", "isort", "ssort"],
help_="List formatters to use when re-formatting code cells",
default=["ruff"],
action="append",
schema={
"type": "array",
"items": {
"description": "Formatters",
"type": "string",
},
},
description="""
Whether to use :py:mod:`ssort` when reformatting code cells.
A list of the names of the formatters to use when reformatting code cells.
Supported formatters include:
- :py:mod:`ruff`
- :py:mod:`black`
- :py:mod:`isort`
- :py:mod:`ssort`
""",
)

Expand Down
55 changes: 42 additions & 13 deletions euporie/core/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,17 +212,40 @@ def _toggled() -> bool:
filter=self.cmd_filter,
)(self.toggle)

for choice in (self.choices or self.schema.get("enum", [])) or []:
add_cmd(
name=f"set-{name}-{choice}",
hidden=self.hidden,
toggled=Condition(partial(lambda x: self.value == x, choice)),
title=f"Set {self.title} to {choice}",
menu_title=str(choice).replace("_", " ").capitalize(),
description=f'Set the value of the "{self.name}" '
f'configuration option to "{choice}"',
filter=self.cmd_filter,
)(partial(setattr, self, "value", choice))
schema = self.schema
if schema.get("type") == "array":
for choice in self.choices or schema.get("items", {}).get("enum") or []:
add_cmd(
name=f"toggle-{name}-{choice}",
hidden=self.hidden,
toggled=Condition(partial(lambda x: x in self.value, choice)),
title=f"Toggle {choice} into {self.title}",
menu_title=str(choice).replace("_", " ").capitalize(),
description=f'Add or remove "{choice}" to or from the list of "{self.name}"',
filter=self.cmd_filter,
)(
partial(
lambda choice: (
self.value.remove
if choice in self.value
else self.value.append
)(choice),
choice,
)
)

else:
for choice in self.choices or schema.get("enum", []) or []:
add_cmd(
name=f"set-{name}-{choice}",
hidden=self.hidden,
toggled=Condition(partial(lambda x: self.value == x, choice)),
title=f"Set {self.title} to {choice}",
menu_title=str(choice).replace("_", " ").capitalize(),
description=f'Set the value of the "{self.name}" '
f'configuration option to "{choice}"',
filter=self.cmd_filter,
)(partial(setattr, self, "value", choice))

def toggle(self) -> None:
"""Toggle the setting's value."""
Expand Down Expand Up @@ -256,12 +279,17 @@ def value(self, new: Any) -> None:
@property
def schema(self) -> dict[str, Any]:
"""Return a json schema property for the config item."""
return {
schema = {
"description": self.help,
**({"enum": self.choices} if self.choices is not None else {}),
**({"default": self.default} if self.default is not None else {}),
**self._schema,
}
if self.choices:
if self.nargs == "*" or "items" in schema:
schema["items"]["enum"] = self.choices
else:
schema["enum"] = self.choices
return schema

@property
def menu(self) -> MenuItem:
Expand Down Expand Up @@ -427,6 +455,7 @@ def load_args(self) -> dict[str, Any]:
fastjsonschema.validate(self.schema, json_data)
except fastjsonschema.JsonSchemaValueException as error:
log.warning("Error in command line parameter `%s`: %s", name, error)
log.warning("%s: %s", name, value)
else:
result[name] = value
return result
Expand Down
12 changes: 12 additions & 0 deletions euporie/core/filters.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,18 @@
from prompt_toolkit.layout.containers import Window


@Condition
@lru_cache
def have_ruff() -> bool:
"""Determine if ruff is available."""
try:
import ruff # noqa F401
except ModuleNotFoundError:
return False
else:
return True


@Condition
@lru_cache
def have_black() -> bool:
Expand Down
28 changes: 25 additions & 3 deletions euporie/core/format.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

from __future__ import annotations

import contextlib
import logging
from typing import TYPE_CHECKING

Expand All @@ -13,6 +14,24 @@
log = logging.getLogger(__name__)


def format_ruff(text: str) -> str:
"""Format a code string using :py:mod:`ruff`."""
from ruff.__main__ import find_ruff_bin

try:
ruff_path = find_ruff_bin()
except FileNotFoundError:
pass
else:
import subprocess

with contextlib.suppress(subprocess.CalledProcessError):
text = subprocess.check_output(
[ruff_path, "format", "-"], input=text, text=True
)
return text


def format_black(text: str) -> str:
"""Format a code string using :py:mod:`black`."""
try:
Expand Down Expand Up @@ -60,10 +79,13 @@ def format_ssort(text: str) -> str:

def format_code(text: str, config: Config) -> str:
"""Format a code string using :py:mod:``."""
if config.format_ssort:
formatters = set(config.formatters)
if "ssort" in formatters:
text = format_ssort(text)
if config.format_isort:
if "isort" in formatters:
text = format_isort(text)
if config.format_black:
if "black" in formatters:
text = format_black(text)
if "ruff" in formatters:
text = format_ruff(text)
return text.strip()
7 changes: 4 additions & 3 deletions euporie/notebook/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -449,9 +449,10 @@ def load_menu_items(self) -> list[MenuItem]:
children=[
get_cmd("toggle-autoformat").menu,
separator,
get_cmd("toggle-format-black").menu,
get_cmd("toggle-format-isort").menu,
get_cmd("toggle-format-ssort").menu,
get_cmd("toggle-formatters-ruff").menu,
get_cmd("toggle-formatters-black").menu,
get_cmd("toggle-formatters-isort").menu,
get_cmd("toggle-formatters-ssort").menu,
],
),
get_cmd("toggle-autocomplete").menu,
Expand Down
9 changes: 4 additions & 5 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,18 +41,17 @@ dependencies = [
"linkify-it-py~=1.0",
"mdit-py-plugins~=0.3.0",
"flatlatex~=0.15",
"timg~=1.1",
"chafa.py~=1.0.2",
"Pillow~=9.0",
"sixelcrop~=0.1.6",
"universal-pathlib~=0.1.4",
"fsspec[http]>=2022.12.0",
"jupytext>=1.14.0",
]

[project.optional-dependencies]
hub = ["asyncssh~=2.10.1"]
format = ["black>=19.3.b0", "isort~=5.10.1"]
chafa = ["chafa.py>=1.0.2"]
jupytext = ["jupytext>=1.14.0"]
format = ["black>=19.3.b0", "isort~=5.10.1", "ruff~=0.1.0"]

[project.urls]
Documentation = "https://euporie.readthedocs.io/en/latest"
Expand Down Expand Up @@ -241,7 +240,7 @@ module = [
"_frozen_importlib", "ipykernel", "fastjsonschema",
"pyperclip", "upath.*", "chafa.*", "timg", "pylatexenc.*", "aenum", "pygments.*",
"jupytext.*",
"ssort",
"ruff", "ssort",
"flatlatex.*", "timg", "img2unicode", "cairosvg", "teimpy", "numpy", "mtable", "imagesize", "matplotlib.*", "ziamath",
"magic", "fsspec.*",
"pytest.*",
Expand Down

0 comments on commit 44db67a

Please sign in to comment.