{"id":25732442,"url":"https://github.com/vigo/textmate2-ruff-linter","last_synced_at":"2025-05-07T19:02:15.498Z","repository":{"id":81424562,"uuid":"606196721","full_name":"vigo/textmate2-ruff-linter","owner":"vigo","description":"Ruff linter for TextMate2. Linter and auto fixer for python!","archived":false,"fork":false,"pushed_at":"2024-06-30T11:02:51.000Z","size":26030,"stargazers_count":6,"open_issues_count":1,"forks_count":1,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-03-31T13:05:01.759Z","etag":null,"topics":["linter","python","ruff","textmate","textmate-bundle"],"latest_commit_sha":null,"homepage":"","language":"Perl","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/vigo.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"Support/css/gfm.css","governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null},"funding":{"github":"vigo","patreon":"vigoo"}},"created_at":"2023-02-24T20:29:50.000Z","updated_at":"2024-12-10T14:31:54.000Z","dependencies_parsed_at":null,"dependency_job_id":"8e272dd8-b1a5-4f68-aeba-cb55fc3139fe","html_url":"https://github.com/vigo/textmate2-ruff-linter","commit_stats":null,"previous_names":[],"tags_count":17,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigo%2Ftextmate2-ruff-linter","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigo%2Ftextmate2-ruff-linter/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigo%2Ftextmate2-ruff-linter/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vigo%2Ftextmate2-ruff-linter/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vigo","download_url":"https://codeload.github.com/vigo/textmate2-ruff-linter/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252940883,"owners_count":21828766,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["linter","python","ruff","textmate","textmate-bundle"],"created_at":"2025-02-26T03:41:03.509Z","updated_at":"2025-05-07T19:02:15.194Z","avatar_url":"https://github.com/vigo.png","language":"Perl","funding_links":["https://github.com/sponsors/vigo","https://patreon.com/vigoo"],"categories":[],"sub_categories":[],"readme":"![Version](https://img.shields.io/badge/version-1.1.7-orange.svg?style=for-the-badge)\n![TextMate](https://img.shields.io/badge/textmate-2.0.23-green.svg?style=for-the-badge)\n![macOS](https://img.shields.io/badge/macos-ventura-yellow.svg?style=for-the-badge)\n![macOS](https://img.shields.io/badge/macos-sonoma-yellow.svg?style=for-the-badge)\n![M2](https://img.shields.io/badge/apple-M2-black.svg?style=for-the-badge)\n![M3](https://img.shields.io/badge/apple-M3-black.svg?style=for-the-badge)\n[![Ruff](https://img.shields.io/endpoint?style=for-the-badge\u0026url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)\n![Powered by Rake](https://img.shields.io/badge/powered_by-rake-blue?logo=ruby\u0026style=for-the-badge)\n\n\n# Python Ruff Linter for TextMate2\n\n[Ruff][01] is an extremely fast Python linter, written in Rust. This is the\nTextMate bundle implementation of ruff linter with fantastic features 🎉\n\n![Demo 1](screens/ruff-demo-01.gif)\n\n---\n\n## Installation\n\nYou need to install `ruff`. I prefer `brew`. It’s also available via `pip`.\nSet the `TM_PYRUFF` variable to your `ruff` binary. There is a fall-back mechanism,\nif you have already installed `ruff`, bundle check the command existance with\n`command -v ruff` if `TM_PYRUFF` is not set. If both fails, you need to set the\nvalue of `TM_PYRUFF` by hand :)\n\n```bash\nbrew install ruff\ncd \"${HOME}/Library/Application\\ Support/TextMate/Bundles/\"\ngit clone https://github.com/vigo/textmate2-ruff-linter.git Python-Ruff-Linter.tmbundle\n```\n\nTextMate sometimes doesn’t apply environment variable creation from\ncommand-line. If this doesn’t work, you need to apply/set manually from\n**TextMate \u003e Settings \u003e Variables** pull down menu.\n\n```bash\n$ defaults write com.macromates.TextMate environmentVariables \\\n    -array-add \"{enabled = 1; value = \\\"$(command -v ruff)\\\"; name = \\\"TM_PYRUFF\\\"; }\"\n\n# enable auto fix\n$ defaults write com.macromates.TextMate environmentVariables \\\n    -array-add \"{enabled = 1; value = \\\"true\\\"; name = \\\"TM_PYRUFF_ENABLE_AUTOFIX\\\"; }\"\n```\n\nYou can set environment variables on a project basis if you prefer. For this,\nyou can use the `.tm_properties` file under anywhere in your project root:\n\n`.tm_properties` example:\n\n    TM_PYRUFF=/path/to/bin/ruff\n    TM_PYRUFF_ENABLE_AUTOFIX=1   # if you want to enable autofix by default\n\nFor older users like myself, you can define the tooltip to make it easier to\nread:\n\n```bash\ndefaults write com.macromates.TextMate NSToolTipsFontSize 24\n```\n\n### Bonus\n\nWhen you press \u003ckbd\u003e⌥ (option)\u003c/kbd\u003e + \u003ckbd\u003eR\u003c/kbd\u003e error reporting pops.\nTextMate’s built-in markdown parser is super outdated, this is normal.\nI’ve modified the original `Markdown.pl` file and shared under `Goodies/`\nfolder. Just copy the file under correct location:\n\n```bash\n# backup the original first :)\ncp \"~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/bin/Markdown.pl\" \"~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/bin/Markdown-original.pl\"\n\n# replace with new one.\ncp Goodies/Markdown.pl \"~/Library/Application Support/TextMate/Managed/Bundles/Bundle Support.tmbundle/Support/shared/bin/\"\n```\n\nYou should see fancy code-blocks parsed as expected:\n\n![Better Markdown Preview](screens/error-reporting-preview.png)\n\n---\n\n## TextMate Variables\n\n| Variable | Default Value | Description | \n|:---------|:-----|:-----|\n| `ENABLE_LOGGING` |  | Set for development purposes |\n| `TM_PYRUFF` |  | Binary path of `ruff` |\n| `TM_PYRUFF_DISABLE` |  | Disable bundle |\n| `TM_PYRUFF_ENABLE_AUTOFIX` |  | Autofix fixables on save |\n| `TM_PYRUFF_OPTIONS` |  | Pass custom options if there is no config file |\n| `TM_PYRUFF_GFM_ZOOM_FACTOR` | `100%` | Zoom factor for report errors screen |\n\n---\n\n![Demo 3](screens/ruff-demo-03.gif)\n\n## Usage\n\nAfter setting the `TM_PYRUFF` variable, you need to select the language as **Python Ruff**.\n\n\u003e **IMPORTANT**: Bundle ships with TextMate grammar: **Python Ruff**. You\n**must** set your language scope to **Python Ruff** for the bundle to\nfunction/work properly. Scope automatically loads `source.python` and \n`source.python.django` grammars. Due to TextMate’s callback flow, I was forced \nto create a separate scope. Otherwise, it would conflict with all bundles that \nuse `source.python`. Due to this situation, previous version was working too\nslow.\n\nWhen you hit \u003ckbd\u003e⌘\u003c/kbd\u003e + \u003ckbd\u003eS\u003c/kbd\u003e (*save the file*) bundle runs:\n\n- Import sorting\n- Code formatting\n- Autofixing autofixable errors if `TM_PYRUFF_ENABLE_AUTOFIX` is set.\n\nYou don’t need to enable `TM_PYRUFF_ENABLE_AUTOFIX` by default. You can manually\ntrigger by pressing \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eA\u003c/kbd\u003e (Option + A)\n\nIf you have lint errors, you can directly navigate error by pressing\n\u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eG\u003c/kbd\u003e (Option + G). User cursor keys (Up/Down) and hit\nenter to jump related line:column.\n\n\n## Enable / Disable Bundle or Features\n\nTo completely disable the bundle, simply assign a value to `TM_PYRUFF_DISABLE`. \nThis allows you to proceed as if the bundle does not exist. Additionally, if \nthe first line of your Python file contains comment **TM\\_PYRUFF\\_DISABLE**:\n\n```python\n# TM_PYRUFF_DISABLE\nprint('ok')\n```\n\nIf you want to enable autofix set `TM_PYRUFF_ENABLE_AUTOFIX` variable (any value):\n\n    TM_PYRUFF_ENABLE_AUTOFIX=1\n\nYou can also pass extra options with using `TM_PYRUFF_OPTIONS` variable. If\nyou don’t have `.ruff.toml`, you can set `TM_PYRUFF_OPTIONS` for custom format\nor custom check operations (via `.tm_properties` or **TextMate \u003e Settings \u003e Variables**):\n\n`.tm_properties` file:\n\n    TM_PYRUFF_OPTIONS=\"--config \\\"format.quote-style = 'single'\\\"\"\n\n**TextMate \u003e Settings \u003e Variables** (you don’t need to escape quotes):\n\n    TM_PYRUFF_OPTIONS  --config \"format.quote-style = 'single'\"\n\nKeep in mind, `TM_PYRUFF_OPTIONS` passed on `format` and `check` operations.\n\n---\n\n## Hot Keys and Snippets\n\n| Hot Keys and TAB Completions |   | Description |\n|:-----|:-----|:-----|\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eF\u003c/kbd\u003e | \u003csmall\u003e(option + F)\u003c/small\u003e | Trigger autofix manually |\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eA\u003c/kbd\u003e | \u003csmall\u003e(option + A)\u003c/small\u003e | Add `# NOQA` to all problematic lines |\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eG\u003c/kbd\u003e | \u003csmall\u003e(option + G)\u003c/small\u003e | Go to error marked line/column |\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eT\u003c/kbd\u003e | \u003csmall\u003e(option + T)\u003c/small\u003e | `tm_properties` helper |\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eT\u003c/kbd\u003e | \u003csmall\u003e(option + T)\u003c/small\u003e | `.ruff.toml` config helper |\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eD\u003c/kbd\u003e | \u003csmall\u003e(option + D)\u003c/small\u003e | Enable / Disable (toggle) format for selected lines |\n| \u003ckbd\u003e⌥\u003c/kbd\u003e + \u003ckbd\u003eR\u003c/kbd\u003e | \u003csmall\u003e(option + R)\u003c/small\u003e | Report errors (rule descriptions) for current errors |\n| `disable` + \u003ckbd\u003e⇥\u003c/kbd\u003e | \u003csmall\u003e(type \"disable\u003cTAB\u003e\")\u003c/small\u003e | Adds `# TM_PYRUFF_DISABLE` text |\n| `noq` + \u003ckbd\u003e⇥\u003c/kbd\u003e | \u003csmall\u003e(type \"noq\u003cTAB\u003e\")\u003c/small\u003e | Some noqa options |\n| `envi` + \u003ckbd\u003e⇥\u003c/kbd\u003e | \u003csmall\u003e(type \"envi\u003cTAB\u003e\")\u003c/small\u003e | Insert environment variables, works in `tm_properties` |\n\n![Demo 2](screens/ruff-demo-02.gif)\n\n---\n\n## Bug Report\n\nPlease set/enable the logger via setting `ENABLE_LOGGING=1`. Logs are written to\nthe `/tmp/textmate-ruff.log` file. You can `tail` while running via;\n`tail -f /tmp/textmate-ruff.log` in another Terminal tab. You can see\nlive what’s going on. Please provide the log information for bug reporting.\n\nAfter you fix the source code (next run) bundle removes those files if there\nis no error. According to you bug report, you can `tail` or copy/paste the\ncontents of error file to issue.\n\nAlso, while running bundle script (*which is TextMate’s default ruby 1.8.7*),\nif error occurs, TextMate pops up an alert window. Please add that screen shot\nor try to copy error text from modal dialog.\n\nLogger output should look like this:\n\n    [2024-05-11 00:49:07][Python-RUFF][WARN][storage.rb-\u003edestroy]: storage.destroy not found for 097AA1A0-89C7-4686-A3BC-F0585962E974 - (/tmp/textmate-ruff-097AA1A0-89C7-4686-A3BC-F0585962E974.error)\n    [2024-05-11 00:49:07][Python-RUFF][INFO][storage.rb-\u003edestroy]: storage.destroy for 097AA1A0-89C7-4686-A3BC-F0585962E974 - (/tmp/textmate-ruff-097AA1A0-89C7-4686-A3BC-F0585962E974.goto)\n    [2024-05-11 00:49:07][Python-RUFF][DEBUG][linter.rb-\u003erun]: cmd: /opt/homebrew/bin/ruff | nil input: true | args: [\"check\", \"--add-noqa\"]\n    [2024-05-11 00:49:07][Python-RUFF][WARN][linter.rb-\u003enoqalize]: err: \"Added 5 noqa directives.\\n\"\n    [2024-05-11 00:49:15][Python-RUFF][WARN][storage.rb-\u003edestroy]: storage.destroy not found for 097AA1A0-89C7-4686-A3BC-F0585962E974 - (/tmp/textmate-ruff-097AA1A0-89C7-4686-A3BC-F0585962E974.error)\n    [2024-05-11 00:49:15][Python-RUFF][DEBUG][linter.rb-\u003erun]: cmd: /opt/homebrew/bin/ruff | nil input: false | args: [\"check\", \"--select\", \"I\", \"--fix\", \"-\"]\n    [2024-05-11 00:49:15][Python-RUFF][DEBUG][linter.rb-\u003erun]: cmd: /opt/homebrew/bin/ruff | nil input: false | args: [\"format\", \"-\"]\n    [2024-05-11 00:49:15][Python-RUFF][ERROR][ruff_linter.rb-\u003erun_document_will_save]: errors_format_code: nil\n    [2024-05-11 00:49:15][Python-RUFF][WARN][storage.rb-\u003eget]: storage.get not found for 097AA1A0-89C7-4686-A3BC-F0585962E974 (/tmp/textmate-ruff-097AA1A0-89C7-4686-A3BC-F0585962E974.error)\n    [2024-05-11 00:49:15][Python-RUFF][DEBUG][linter.rb-\u003erun]: cmd: /opt/homebrew/bin/ruff | nil input: true | args: [\"check\", \"--output-format\", \"grouped\"]\n\nKeep in mind that when logging is enabled, there may be some performance\ndegradation due to *file I/O* operations.\n\n---\n\n## Personal Notes\n\nI know and unfortunately, this wonderful editor, **TextMate**, is now in its\n**final days**. I could not use many of the beauties from the UI library that\nit spawned. The built-in `Ruby 1.8.7`, `Ruby 2` have always been compiled\naccording to the old CPU architecture and when I use `nib` files, TextMate\nrandomly hangs and crashes at random times. \n\nI couldn’t use the built-in autocompletion features and similar alert\nmechanisms. (*I can generate tooltips in HTML format, but it crashes after a\nwhile*).\n\nIf you are still using TextMate like me, I eagerly await your **comments**, **bug\nreports**, and **feature requests**.\n\n---\n\n## Change Log\n\n**2024-05-29**\n\n- Add `ruff` version to results\n- Add **Disable Ruff for file** with `noq`+TAB (adds `# ruff: noqa`)\n\n---\n\n**2024-05-14**\n\n- Improve code structure (modules)\n- Add report errors (rule description) preview with option+R\n- Add import sort disabler (`noq\u003cTAB\u003e`)\n\n---\n\nYou can read the whole story [here][changelog].\n\n---\n\n## Contributor(s)\n\n* [Uğur \"vigo\" Özyılmazel](https://github.com/vigo) - Creator, maintainer\n\n---\n\n## Contribute\n\nAll PR’s are welcome!\n\n1. `fork` (https://github.com/vigo/textmate2-ruff-linter/fork)\n1. Create your `branch` (`git checkout -b my-features`)\n1. `commit` yours (`git commit -am 'implement new features'`)\n1. `push` your `branch` (`git push origin my-features`)\n1. Than create a new **Pull Request**!\n\nThis project is intended to be a safe, welcoming space for collaboration, and\ncontributors are expected to adhere to the [code of conduct][coc].\n\n---\n\n## License\n\nThis project is licensed under MIT\n\n---\n\n[01]: https://docs.astral.sh/ruff/\n[changelog]: https://github.com/vigo/textmate2-ruff-linter/blob/main/CHANGELOG.md\n[coc]: https://github.com/vigo/textmate2-ruff-linter/blob/main/CODE_OF_CONDUCT.md\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvigo%2Ftextmate2-ruff-linter","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvigo%2Ftextmate2-ruff-linter","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvigo%2Ftextmate2-ruff-linter/lists"}