-
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
16 changed files
with
4,693 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,43 @@ | ||
# EditorConfig is awesome: https://EditorConfig.org | ||
root = true | ||
|
||
[*] | ||
charset = utf-8 | ||
end_of_line = lf | ||
indent_style = space | ||
insert_final_newline = true | ||
trim_trailing_whitespace = true | ||
|
||
[Makefile] | ||
indent_style = tab | ||
|
||
[*.sublime-{settings,commands,keymap,mousemap}] | ||
indent_style = tab | ||
indent_size = 4 | ||
|
||
[*.sublime-{menu,syntax}] | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[*.json] | ||
indent_size = 4 | ||
|
||
[*.md] | ||
indent_size = 2 | ||
trim_trailing_whitespace = false | ||
|
||
[*.py] | ||
indent_size = 4 | ||
|
||
[*.{sh,csh,tcsh,zsh,bash,fish}] | ||
indent_size = 4 | ||
|
||
[*.{yml,yaml,toml,neon}] | ||
indent_style = space | ||
indent_size = 2 | ||
|
||
[sublime-package.json] | ||
indent_size = 2 | ||
|
||
[pyproject.toml] | ||
indent_size = 2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
*.pyright-syntax-test export-ignore | ||
.dependabot export-ignore | ||
.editorconfig export-ignore | ||
.flake8 export-ignore | ||
.gitattributes export-ignore | ||
.github/ export-ignore | ||
.gitignore export-ignore | ||
.gitmodules export-ignore | ||
.style.yapf export-ignore | ||
.travis.yml export-ignore | ||
codecov.yml export-ignore | ||
docs/ export-ignore | ||
Makefile export-ignore | ||
mkdocs.yml export-ignore | ||
mypy.ini export-ignore | ||
pyproject.toml export-ignore | ||
pyrightconfig.json export-ignore | ||
requirements.txt export-ignore | ||
scripts/ export-ignore | ||
stubs/ export-ignore | ||
tests/ export-ignore | ||
tox.ini export-ignore | ||
typings/ export-ignore | ||
unittesting.json export-ignore |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
# These are supported funding model platforms | ||
|
||
github: # Replace with up to 4 GitHub Sponsors-enabled usernames e.g., [user1, user2] | ||
patreon: # Replace with a single Patreon username | ||
open_collective: # Replace with a single Open Collective username | ||
ko_fi: # Replace with a single Ko-fi username | ||
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel | ||
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry | ||
liberapay: # Replace with a single Liberapay username | ||
issuehunt: # Replace with a single IssueHunt username | ||
otechie: # Replace with a single Otechie username | ||
custom: https://www.paypal.me/jfcherng/5usd |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
# This workflow will install Python dependencies, run tests and lint with a variety of Python versions | ||
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions | ||
|
||
name: Python | ||
|
||
on: | ||
push: | ||
branches: | ||
- '**' | ||
paths: | ||
- '.github/workflows/python.yml' | ||
- '**.py' | ||
- '**.pyi' | ||
- 'Makefile' | ||
pull_request: | ||
branches: | ||
- '**' | ||
paths: | ||
- '.github/workflows/python.yml' | ||
- '**.py' | ||
- '**.pyi' | ||
- 'Makefile' | ||
|
||
jobs: | ||
job_lint: | ||
name: ${{ matrix.python-version }} | ||
runs-on: ${{ matrix.os }} | ||
|
||
strategy: | ||
matrix: | ||
os: ['ubuntu-latest'] | ||
python-version: ['3.8'] | ||
|
||
steps: | ||
- uses: actions/checkout@v4 | ||
with: | ||
submodules: recursive | ||
|
||
- name: Set up Python ${{ matrix.python-version }} | ||
uses: actions/setup-python@v5 | ||
with: | ||
python-version: ${{ matrix.python-version }} | ||
|
||
- name: Install dependencies | ||
run: | | ||
python -m pip install -U uv | ||
make UV_INSTALL_FLAGS="--system" install-dev | ||
- name: Do linting | ||
run: | | ||
make ci-check |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
.mypy_cache | ||
.tox | ||
.venv-*/ | ||
.venv/ | ||
__pycache__ | ||
node_modules |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
3.8 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
MIT License | ||
|
||
Copyright (c) 2024 Jack Cherng <[email protected]> | ||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy | ||
of this software and associated documentation files (the "Software"), to deal | ||
in the Software without restriction, including without limitation the rights | ||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell | ||
copies of the Software, and to permit persons to whom the Software is | ||
furnished to do so, subject to the following conditions: | ||
|
||
The above copyright notice and this permission notice shall be included in all | ||
copies or substantial portions of the Software. | ||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE | ||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER | ||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, | ||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE | ||
SOFTWARE. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
UV_INSTALL_FLAGS := | ||
|
||
.PHONY: all | ||
all: | ||
|
||
.PHONY: install | ||
install: install-dev | ||
|
||
.PHONY: install-dev | ||
install-dev: | ||
uv pip install $(UV_INSTALL_FLAGS) -r requirements-dev.txt | ||
|
||
.PHONY: pip-compile | ||
pip-compile: | ||
uv pip compile --upgrade requirements-dev.in -o requirements-dev.txt | ||
|
||
.PHONY: ci-check | ||
ci-check: | ||
@echo "========== check: mypy ==========" | ||
mypy -p plugin | ||
@echo "========== check: ruff (lint) ==========" | ||
ruff check --diff . | ||
@echo "========== check: ruff (format) ==========" | ||
ruff format --diff . | ||
|
||
.PHONY: ci-fix | ||
ci-fix: | ||
@echo "========== fix: ruff (lint) ==========" | ||
ruff check --fix . | ||
@echo "========== fix: ruff (format) ==========" | ||
ruff format . |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
# ST-RainbowIndent | ||
|
||
[![Required ST Build](https://img.shields.io/badge/ST-4114+-orange.svg?style=flat-square&logo=sublime-text)](https://www.sublimetext.com) | ||
[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/jfcherng-sublime/ST-RainbowIndent/python.yml?branch=st4&style=flat-square)](https://github.com/jfcherng-sublime/ST-RainbowIndent/actions) | ||
[![Package Control](https://img.shields.io/packagecontrol/dt/RainbowIndent?style=flat-square)](https://packagecontrol.io/packages/RainbowIndent) | ||
[![GitHub tag (latest by date)](https://img.shields.io/github/v/tag/jfcherng-sublime/ST-RainbowIndent?style=flat-square&logo=github)](https://github.com/jfcherng-sublime/ST-RainbowIndent/tags) | ||
[![Project license](https://img.shields.io/github/license/jfcherng-sublime/ST-RainbowIndent?style=flat-square&logo=github)](https://github.com/jfcherng-sublime/ST-RainbowIndent/blob/st4/LICENSE) | ||
[![GitHub stars](https://img.shields.io/github/stars/jfcherng-sublime/ST-RainbowIndent?style=flat-square&logo=github)](https://github.com/jfcherng-sublime/ST-RainbowIndent/stargazers) | ||
[![Donate to this project using Paypal](https://img.shields.io/badge/paypal-donate-blue.svg?style=flat-square&logo=paypal)](https://www.paypal.me/jfcherng/5usd) | ||
|
||
A very naive implementation which is just for fun... | ||
|
||
## Installation | ||
|
||
Only manually installation is supported. | ||
|
||
## Known Issues | ||
|
||
- There is no way to draw a region where is nothing there via ST's plugin APIs. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
from __future__ import annotations | ||
|
||
import sys | ||
import weakref | ||
from collections import defaultdict | ||
from dataclasses import dataclass | ||
from enum import Enum | ||
from typing import Tuple | ||
|
||
import sublime | ||
import sublime_plugin | ||
|
||
assert __package__ | ||
|
||
PLUGIN_NAME = __package__.partition(".")[0] | ||
|
||
LEVEL_COLORS = [ | ||
"region.redish", | ||
"region.orangish", | ||
"region.yellowish", | ||
"region.greenish", | ||
"region.cyanish", | ||
"region.bluish", | ||
"region.purplish", | ||
"region.pinkish", | ||
] | ||
|
||
SIMPLE_REGION = Tuple[int, int] | ||
|
||
if sys.version_info >= (3, 11): | ||
from enum import StrEnum | ||
else: | ||
|
||
class StrEnum(str, Enum): | ||
__str__ = str.__str__ # type: ignore | ||
__format__ = str.__format__ # type: ignore | ||
|
||
|
||
def get_regions_key(level: int) -> str: | ||
return f"{PLUGIN_NAME}:{level}" | ||
|
||
|
||
def get_view_indentation(view: sublime.View) -> IndentInfo: | ||
settings = view.settings() | ||
|
||
tab_size = settings.get("tab_size", 4) | ||
|
||
if settings.get("translate_tabs_to_spaces", False): | ||
style = IndentStyle.SPACE | ||
else: | ||
style = IndentStyle.TAB | ||
|
||
return IndentInfo(tab_size=tab_size, style=style) | ||
|
||
|
||
@dataclass | ||
class IndentInfo: | ||
tab_size: int | ||
style: IndentStyle | ||
|
||
@property | ||
def indent_char(self) -> str: | ||
if self.style is IndentStyle.SPACE: | ||
return " " * self.tab_size | ||
if self.style is IndentStyle.TAB: | ||
return "\t" | ||
raise ValueError(f"Unknown indent style: {self.style}") | ||
|
||
@property | ||
def indent_length(self) -> int: | ||
return len(self.indent_char) | ||
|
||
@property | ||
def indent_pattern(self) -> str: | ||
return rf"^({self.indent_char})+" | ||
|
||
|
||
class IndentStyle(StrEnum): | ||
SPACE = "space" | ||
TAB = "tab" | ||
|
||
|
||
class ViewManager: | ||
__instances: dict[weakref.ref[sublime.View], ViewManager] = {} | ||
|
||
def __init__(self, view: sublime.View, *, from_get_instance: bool = False) -> None: | ||
if not from_get_instance: | ||
raise ValueError("Use get_instance() instead.") | ||
|
||
self.view = view | ||
self.max_level = -1 | ||
|
||
@classmethod | ||
def get_instance(cls, view: sublime.View) -> ViewManager: | ||
view_proxy = weakref.proxy(view) | ||
view_ref = weakref.ref(view) | ||
if not cls.__instances.get(view_ref): | ||
cls.__instances[view_ref] = cls(view_proxy, from_get_instance=True) | ||
return cls.__instances[view_ref] | ||
|
||
def clear_view(self) -> None: | ||
for level in range(self.max_level + 1): | ||
self.view.erase_regions(get_regions_key(level)) | ||
|
||
def render_view(self) -> None: | ||
indent_info = get_view_indentation(self.view) | ||
|
||
# key = indentation level; value = list of begin point of indentation | ||
level_pts: defaultdict[int, list[int]] = defaultdict(list) | ||
for region in self.view.find_all(indent_info.indent_pattern): | ||
for level in range(region.size() // indent_info.indent_length): | ||
level_pts[level].append(region.a + level * indent_info.indent_length) | ||
|
||
for level, begin_pts in level_pts.items(): | ||
self.view.add_regions( | ||
get_regions_key(level), | ||
tuple(sublime.Region(pt, pt + indent_info.indent_length) for pt in begin_pts), | ||
scope=LEVEL_COLORS[level % len(LEVEL_COLORS)], | ||
flags=sublime.DRAW_NO_OUTLINE | sublime.HIDE_ON_MINIMAP | sublime.NO_UNDO, | ||
) | ||
|
||
self.max_level = max(level_pts.keys(), default=-1) | ||
|
||
|
||
class RainbowIndent(sublime_plugin.ViewEventListener): | ||
def on_activated_async(self) -> None: | ||
self._work(self.view) | ||
|
||
def on_load_async(self) -> None: | ||
self._work(self.view) | ||
|
||
def on_modified_async(self) -> None: | ||
self._work(self.view) | ||
|
||
def on_revert_async(self) -> None: | ||
self._work(self.view) | ||
|
||
@staticmethod | ||
def _work(view: sublime.View) -> None: | ||
vrm = ViewManager.get_instance(view) | ||
vrm.clear_view() | ||
vrm.render_view() |
Oops, something went wrong.