This bundle runs various linters and checkers when you save a Python file, both formatting the code and highlighting any errors. The supported linters and checkers are as follows:
isort
: Sortsimport
statements.black
: Formats source code.pylint
: Analyses source code.flake8
: Checks source code for style guide enforcement.
python
must be installed, whether through brew
, pyenv
, or any other
method. Please check your python installation:
command -v python
Bundle checks the TM_PYTHON_FMT_PYTHON_PATH
environment variable. This
variable can be set in .tm_properties
or via the
TextMate > Preferences > Variables menu. If it is not set anywhere, the
bundle attempts to locate the python path using the command -v python
command
and TM_PYTHON_FMT_VIRTUAL_ENV
environment variable internally. If the bundle
reports that it cannot find the TM_PYTHON_FMT_PYTHON_PATH
, you need to set
it manually to the desired python path.
If you are in a virtual environment, all you need is to set
TM_PYTHON_FMT_VIRTUAL_ENV
variable. Bundle will handle all the installed
linters/checkers from the virtual environment.
If you are not in a virtual environment, you need to set all the required variables:
TM_PYTHON_FMT_PYTHON_PATH
TM_PYTHON_FMT_BLACK
TM_PYTHON_FMT_ISORT
TM_PYTHON_FMT_PYLINT
TM_PYTHON_FMT_FLAKE8
if you want to use all of it. You can disable partially by setting
TM_PYTHON_FMT_DISABLE_<NAME>
environment variable(s).
You can set the values globally from command-line:
$ defaults write com.macromates.TextMate environmentVariables \
-array-add "{enabled = 1; value = \"$(command -v python)\"; name = \"TM_PYTHON_FMT_PYTHON_PATH\"; }"
You need to restart TextMate to take effect. Now clone the bundle:
cd "${HOME}/Library/Application\ Support/TextMate/Bundles/"
git clone https://github.com/vigo/textmate2-python-fmt.git Python-FMT.tmbundle
IMPORTANT: Bundle ships with TextMate grammar: Python FMT. You must set your language scope to Python FMT for the bundle to function/work properly. Scope automatically loads
source.python
andsource.python.django
grammars. Due to TextMate’s callback flow, I was forced to create a separate scope. Otherwise, it would conflict with all bundles that usesource.python
. Due to this situation, previous version was working too slow.
If you are within a project folder, the bundle automatically uses any existing
linter configuration files you have, such as .isort
, .flake8
and all the
other configuration files.
The bundle includes a requirements.txt
file, which allows for easy
installation either into your virtual environment or system-wide:
cd Python-FMT.tmbundle/
# if you need to create new environment uncomment below
# mkvirtualenv myenv
pip install -r requirements.txt
requirements.txt
contains:
black
isort
pylint
flake8
flake8-bandit
flake8-blind-except
flake8-bugbear
flake8-builtins
flake8-commas
flake8-print
flake8-quotes
flake8-return
flake8-string-format
Bundle contains easy config creation command; hit ⌥ + T (option + T) for helper commands.
To completely disable the bundle, simply assign a value to TM_PYTHON_FMT_DISABLE
.
This allows you to proceed as if the bundle does not exist. Additionally, if
the first line of your Python file contains comment TM_PYTHON_FMT_DISABLE:
# TM_PYTHON_FMT_DISABLE
print('ok')
the bundle will also be disabled for that file. You can partially disable features by setting related environment variable:
- Set
TM_PYTHON_FMT_DISABLE_BLACK=1
to bypassblack
formatter - Set
TM_PYTHON_FMT_DISABLE_ISORT=1
to bypassisort
- Set
TM_PYTHON_FMT_DISABLE_PYLINT=1
to disablepylint
(well a bit useless :) - Set
TM_PYTHON_FMT_DISABLE_FLAKE8=1
to disableflake8
There is a helper snippet for disabling features easily, write envi<TAB>
in .tm_properties
file and select which feature to disable.
Variable | Default Value | Description |
---|---|---|
ENABLE_LOGGING |
Set for development purposes | |
TOOLTIP_LINE_LENGTH |
100 |
Width of pop-up window |
TOOLTIP_LEFT_PADDING |
2 |
Alignment value |
TOOLTIP_BORDER_CHAR |
- |
Border value |
TM_PYTHON_FMT_VIRTUAL_ENV |
Set this variable if you are in a virtual environment | |
TM_PYTHON_FMT_BLACK |
* | Binary path of black |
TM_PYTHON_FMT_ISORT |
* | Binary path of isort |
TM_PYTHON_FMT_PYLINT |
* | Binary path of pylint |
TM_PYTHON_FMT_FLAKE8 |
* | Binary path of flake8 |
TM_PYTHON_FMT_DISABLE |
Disable bundle | |
TM_PYTHON_FMT_DISABLE_BLACK |
Disable black formatter |
|
TM_PYTHON_FMT_DISABLE_ISORT |
Disable isort |
|
TM_PYTHON_FMT_DISABLE_PYLINT |
Disable pylint checker |
|
TM_PYTHON_FMT_DISABLE_FLAKE8 |
Disable flake8 style guide |
|
TM_PYTHON_FMT_BLACK_DEFAULTS |
Override current black config with extra parameters if provided |
|
TM_PYTHON_FMT_ISORT_DEFAULTS |
Override current isort config with extra parameters if parameters |
|
TM_PYTHON_FMT_PYLINT_EXTRA_OPTIONS |
Override current pylint config with extra parameters if parameters |
|
TM_PYTHON_FMT_FLAKE8_DEFAULTS |
Override current flake8 config with extra parameters if parameters |
*
: Bundle tries to find binary path, fall-back is empty/nil value, if you get
error, you need to set exact binary path.
For black
, bundle checks config files in order below, last found overrides
all!
${HOME}/.black
${TM_PROJECT_DIRECTORY}/pyproject.toml
also filenames end with .pyi
For isort
, bundle checks config file order;
${HOME}/.isort.cfg
${TM_PROJECT_DIRECTORY}/.isort.cfg
For pylint
, bundle checks config files below;
${HOME}/.pylintrc
${TM_PROJECT_DIRECTORY}/.pylintrc
For flake8
, bundle checks config files below;
${HOME}/.flake8
${TM_PROJECT_DIRECTORY}/.flake8
${TM_PROJECT_DIRECTORY}/tox.ini
${TM_PROJECT_DIRECTORY}/setup.cfg
pylint
now shows every available error. You can set extra options to
display compile-time errors only by setting TM_PYTHON_FMT_PYLINT_EXTRA_OPTIONS
variable. Space delimited arguments are required:
# .tm_properties or from TextMate > Preferences > Variables
TM_PYTHON_FMT_PYLINT_EXTRA_OPTIONS="--errors-only"
flake8
and pylint
using same error output format:
LINE_NUMBER || COLUMN_NUMBER || ERROR_CODE || ERROR_MESSAGE
Example .tm_properties
:
TM_PYTHON_FMT_VIRTUAL_ENV="/Users/YOU/.virtualenvs/YOUR_VENV" # or
TM_PYTHON_FMT_VIRTUAL_ENV="${HOME}/.virtualenvs/YOUR_VENV"
# It’s ok to use shell variables and TextMate variables but never use like this:
# ~/.virtualenvs/ENV
# overriders
TM_PYTHON_FMT_BLACK_DEFAULTS="--line-length=100"
TM_PYTHON_FMT_ISORT_DEFAULTS="--line-length=40 --multi-line=GRID"
TM_PYTHON_FMT_FLAKE8_DEFAULTS="--extend-ignore F401"
TM_PYTHON_FMT_PYLINT_EXTRA_OPTIONS="--py3k"
Also, you can set project based configurations for all of the tools. Check their official documentations:
- https://black.readthedocs.io/en/stable/
- https://pycqa.github.io/isort/
- https://pylint.pycqa.org/en/latest/
- https://flake8.pycqa.org/en/latest/
Hot Keys and TAB Completions | Description |
---|---|
⌥ + D | Bypass black formating (toggle) for selection. |
⌥ + T | Create .tm_properties or linter config files |
⌥ + G | Go to error line! New feature! |
noq + ⇥ | Choose desired bypass method |
envi + ⇥ | Inserts helpful environment variables if you are editing on .tm_properties file. Try :) |
disable + ⇥ | Inserts # TM_PYTHON_FMT_DISABLE , put this in to first line if you want to disable this bundle |
Please set/enable the logger via setting ENABLE_LOGGING=1
. Logs are written to
the /tmp/textmate-python-fmt.log
file. You can tail
while running via;
tail -f /tmp/textmate-python-fmt.log
in another Terminal tab. You can see
live what’s going on. Please provide the log information for bug reporting.
callback.document.will-save
errors are written to
/tmp/textmate-python-fmt-DOCUMENT-ID.error
.
Bundle log looks like this:
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->run_document_will_save]: will run isort
[2024-05-13 01:39:48][Python-FMT][DEBUG][linters.rb->isort]: cmd: "/Users/vigo/.virtualenvs/thesarraf.com/bin/isort" | version: 5.13.2 | args: ["--profile", "black", "--honor-noqa", "--virtual-env", "/Users/vigo/.virtualenvs/thesarraf.com", "-"]
[2024-05-13 01:39:48][Python-FMT][DEBUG][linters.rb->isort]: out:
"FOO = 1\n"
err: ""
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->find_binary]: python -> path: "/Users/vigo/.virtualenvs/thesarraf.com/bin/python"
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->find_binary]: black -> path: "/Users/vigo/.virtualenvs/thesarraf.com/bin/black"
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->find_binary]: isort -> path: "/Users/vigo/.virtualenvs/thesarraf.com/bin/isort"
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->find_binary]: pylint -> path: "/Users/vigo/.virtualenvs/thesarraf.com/bin/pylint"
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->find_binary]: flake8 -> path: "/Users/vigo/.virtualenvs/thesarraf.com/bin/flake8"
[2024-05-13 01:39:48][Python-FMT][INFO][python_fmt.rb->can_run_run_document_did_save?]: any? true
[2024-05-13 01:39:48][Python-FMT][ERROR][python_fmt.rb->can_run_run_document_did_save?]: warning_messages: []
[2024-05-13 01:39:49][Python-FMT][ERROR][python_fmt.rb->run_document_did_save]: errors_flake8: nil
[2024-05-13 01:39:49][Python-FMT][ERROR][python_fmt.rb->run_document_did_save]: all_errors: {}
[2024-05-13 01:39:49][Python-FMT][INFO][storage.rb->destroy]: storage.destroy for 1D082B22-3346-4DCE-BF76-FAE8BF4AE776 - (/tmp/textmate-python-fmt-1D082B22-3346-4DCE-BF76-FAE8BF4AE776.goto)
[2024-05-13 01:39:49][Python-FMT][INFO][storage.rb->add]: storage.add for 1D082B22-3346-4DCE-BF76-FAE8BF4AE776 (/tmp/textmate-python-fmt-1D082B22-3346-4DCE-BF76-FAE8BF4AE776.goto)
After you fix the source code (next run) bundle removes those files if there
is no error. According to you bug report, you can tail
or copy/paste the
contents of error file to issue.
Also, while running bundle script (which is TextMate’s default ruby 1.8.7), if error occurs, TextMate pops up an alert window. Please add that screen shot or try to copy error text from modal dialog.
2024-05-14
- Small improvements in project structure
2024-05-13
Another refactoring
- Add go to line with
option+G
- Implement zero-config run, if you have linter, runs w/o config file, uses defaults
- Improve error handling
- Improve code structure
- Add all the
noqa
codes forpylint
andflake8
for autocompletion.
You can read the whole story here.
- Uğur "vigo" Özyılmazel - Creator, maintainer
All PR’s are welcome!
fork
(https://github.com/vigo/textmate2-python-fmt/fork)- Create your
branch
(git checkout -b my-features
) commit
yours (git commit -am 'add awesome features'
)push
yourbranch
(git push origin my-features
)- Than create a new Pull Request!
This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the code of conduct.
This project is licensed under MIT