aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/ISSUE_TEMPLATE/bug_report.yml8
-rw-r--r--README.md11
-rw-r--r--doc/advanced_topics.md2
-rw-r--r--doc/debugging.md94
-rw-r--r--lua/conform/health.lua2
-rwxr-xr-xscripts/generate.py14
6 files changed, 120 insertions, 11 deletions
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
index f7c2632..33884f4 100644
--- a/.github/ISSUE_TEMPLATE/bug_report.yml
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -10,7 +10,7 @@ body:
- type: input
attributes:
label: "Neovim version (nvim -v)"
- placeholder: "0.8.0 commit db1b0ee3b30f"
+ placeholder: "NVIM v0.10.1"
validations:
required: true
- type: input
@@ -21,6 +21,12 @@ body:
required: true
- type: checkboxes
attributes:
+ label: Read [debugging tips](https://github.com/stevearc/conform.nvim/blob/master/doc/debugging.md)
+ options:
+ - label: I have read through the [debugging tips](https://github.com/stevearc/conform.nvim/blob/master/doc/debugging.md).
+ required: true
+ - type: checkboxes
+ attributes:
label: Add the debug logs
options:
- label: I have set `log_level = vim.log.levels.DEBUG` and pasted the log contents below.
diff --git a/README.md b/README.md
index 7da4e1a..8d9de18 100644
--- a/README.md
+++ b/README.md
@@ -11,6 +11,7 @@ Lightweight yet powerful formatter plugin for Neovim
- [Formatters](#formatters)
- [Customizing formatters](#customizing-formatters)
- [Recipes](#recipes)
+- [Debugging](#debugging)
- [Advanced topics](#advanced-topics)
- [Options](#options)
- [Formatter options](#formatter-options)
@@ -441,6 +442,16 @@ require("conform").formatters.shfmt = {
<!-- /RECIPES -->
+## Debugging
+
+<!-- DEBUGGING -->
+
+- [Background](doc/debugging.md#background)
+- [Tools](doc/debugging.md#tools)
+- [Testing the formatter](doc/debugging.md#testing-the-formatter)
+
+<!-- /DEBUGGING -->
+
## Advanced topics
<!-- ADVANCED -->
diff --git a/doc/advanced_topics.md b/doc/advanced_topics.md
index 4dcc421..cd02930 100644
--- a/doc/advanced_topics.md
+++ b/doc/advanced_topics.md
@@ -22,8 +22,6 @@ The way this "aftermarket" range formatting works is conform will format the ent
## Injected language formatting (code blocks)
-Requires: Neovim 0.9+
-
Sometimes you may have a file that contains small chunks of code in another language. This is most common for markup formats like markdown and neorg, but can theoretically be present in any filetype (for example, embedded SQL queries in a host language). For files like this, it would be nice to be able to format these code chunks using their language-specific formatters.
The way that conform supports this is via the `injected` formatter. If you run this formatter on a file, it will use treesitter to parse out the blocks in the file that have different languages and runs the formatters for that filetype (configured with `formatters_by_ft`). The formatters are run in parallel, one job for each language block.
diff --git a/doc/debugging.md b/doc/debugging.md
new file mode 100644
index 0000000..a9bf2b3
--- /dev/null
+++ b/doc/debugging.md
@@ -0,0 +1,94 @@
+# Debugging
+
+When you are experiencing problems with a formatter, this doc is intended to give you the background
+information and tools you need to figure out what is going wrong. It should help you answer
+questions like "why isn't my formatter working?" and "why is my formatter using the wrong format?"
+
+<!-- TOC -->
+
+- [Background](#background)
+- [Tools](#tools)
+- [Testing the formatter](#testing-the-formatter)
+
+<!-- /TOC -->
+
+## Background
+
+How does conform work?
+
+Under the hood, conform is just running a shell command, capturing the output, and replacing the
+buffer contents with that output. There are a few fancy things happening with [minimal format
+diffs](advanced_topics.md#minimal-format-diffs), but in practice there are almost never problems
+with that system so you can mostly ignore it.
+
+Conform runs the formatters using `:help jobstart()`, and does one of two things. Some formatters
+support formatting _from_ stdin and _to_ stdout. For these, we pipe the buffer text to the process
+via stdin, and read the stdout back as the new buffer contents. For formatters that don't support
+stdin/out, we create a temporary file in the same directory, write the buffer to it, run the
+formatter, and read back the modified tempfile as the new buffer contents.
+
+## Tools
+
+Conform has two very useful tools for debugging misbehaving formatters: logging and `:ConformInfo`.
+Try running `:ConformInfo` now; you should see something like the window below:
+
+<img width="1243" alt="Screenshot 2024-08-07 at 10 03 17 PM" src="https://github.com/user-attachments/assets/2dbbc2b7-05c1-4c9f-bb8c-345d039b624c">
+
+This contains a snippet of the log file, the location of the log file in case you need to see more
+logs (you can use `gf` to jump to it), available formatters for the current buffer, and a list of
+all the configured formatters. Each formatter has a status, an error message if there is something
+wrong, a list of filetypes it applies to, and the resolved path to the executable.
+
+This should be enough to fix many issues. Double check to make sure your formatter is `ready` and
+that it is configured to run on the filetype(s) you expect. Also double check the path to the
+executable. If all of those look good, then it's time to make more use of the logs.
+
+The first thing you will want to do is increase the verbosity of the logs. Do this by setting the
+`log_level` option:
+
+```lua
+require("conform").setup({
+ log_level = vim.log.levels.DEBUG,
+})
+```
+
+It is recommended to start with `DEBUG` level. You can also use `TRACE`, which will log the entire
+file input and output to the formatter. This can be helpful in some situations, but takes up a lot
+of visual space and so is not recommended until you need that information specifically.
+
+## Testing the formatter
+
+Once you set the log level, try the format operations again, then open the log file (remember, you
+can find it from `:ConformInfo`). You're looking for the lines that tell you what command is being
+run. It should look like this:
+
+```
+21:50:31[DEBUG] Run command: { "black", "--stdin-filename", "/Users/stevearc/dotfiles/vimplugins/conform.nvim/scripts/generate.py", "--quiet", "-" }
+21:50:31[DEBUG] Run default CWD: /Users/stevearc/dotfiles/vimplugins/conform.nvim
+```
+
+This is logging the lua table that is passed to `jobstart()`. The first thing to do is to take this
+command and run it directly in your shell and see what happens. For formatters using stdin/out, it
+will look like this:
+
+```
+cat path/to/file.py | black --stdin-filename path/to/file.py --quiet -
+```
+
+Note that this will print the entire formatted file to stdout. It will be much easier for you if you
+can come up with a small test file just a couple lines long that reproduces this issue. MAKE SURE
+that you `cd` into the CWD directory from the log lines, as that is the directory that conform will
+run the command from. If your formatter doesn't use stdin/out, do the same thing but omit the `cat`.
+The command in the log line will contain a path to a temporary file. Just replace that with the path
+to the real file:
+
+```
+black --quiet path/to/file.py
+```
+
+**Q:** What is the point of all of this? \
+**A:** We're trying to isolate where the problem is coming from: the formatter, the environment
+configuring the formatter, Neovim, or conform. By confirming that the format command works in the
+shell, we can eliminate some of those possibilities. If the format command _doesn't_ work in the
+shell, you will need to iterate on that until you can find one that works. Please DO NOT file an
+issue on this repo until you have a functioning format command in your shell.
diff --git a/lua/conform/health.lua b/lua/conform/health.lua
index 07ffa22..76a8609 100644
--- a/lua/conform/health.lua
+++ b/lua/conform/health.lua
@@ -113,7 +113,7 @@ M.show_window = function()
table.insert(lines, line)
table.insert(
highlights,
- { "DiagnosticInfo", #lines, formatter.name:len(), formatter.name:len() + 6 }
+ { "DiagnosticOk", #lines, formatter.name:len(), formatter.name:len() + 6 }
)
table.insert(highlights, {
"DiagnosticInfo",
diff --git a/scripts/generate.py b/scripts/generate.py
index 30c3b12..f471530 100755
--- a/scripts/generate.py
+++ b/scripts/generate.py
@@ -26,6 +26,7 @@ README = os.path.join(ROOT, "README.md")
DOC = os.path.join(ROOT, "doc")
RECIPES = os.path.join(DOC, "recipes.md")
ADVANCED = os.path.join(DOC, "advanced_topics.md")
+DEBUGGING = os.path.join(DOC, "debugging.md")
FORMATTER_OPTIONS = os.path.join(DOC, "formatter_options.md")
VIMDOC = os.path.join(DOC, "conform.txt")
OPTIONS = os.path.join(ROOT, "scripts", "options_doc.lua")
@@ -143,21 +144,22 @@ def update_readme_toc():
)
-def update_recipes_toc():
+def update_tocs():
toc = ["\n"] + generate_md_toc(RECIPES) + ["\n"]
replace_section(RECIPES, r"^<!-- TOC -->$", r"^<!-- /TOC -->$", toc)
subtoc = add_md_link_path("doc/recipes.md", toc)
replace_section(README, r"^<!-- RECIPES -->$", r"^<!-- /RECIPES -->$", subtoc)
-
-def update_advanced_toc():
toc = ["\n"] + generate_md_toc(ADVANCED) + ["\n"]
replace_section(ADVANCED, r"^<!-- TOC -->$", r"^<!-- /TOC -->$", toc)
subtoc = add_md_link_path("doc/advanced_topics.md", toc)
replace_section(README, r"^<!-- ADVANCED -->$", r"^<!-- /ADVANCED -->$", subtoc)
+ toc = ["\n"] + generate_md_toc(DEBUGGING) + ["\n"]
+ replace_section(DEBUGGING, r"^<!-- TOC -->$", r"^<!-- /TOC -->$", toc)
+ subtoc = add_md_link_path("doc/debugging.md", toc)
+ replace_section(README, r"^<!-- DEBUGGING -->$", r"^<!-- /DEBUGGING -->$", subtoc)
-def update_formatter_options_toc():
toc = ["\n"] + generate_md_toc(FORMATTER_OPTIONS) + ["\n"]
replace_section(FORMATTER_OPTIONS, r"^<!-- TOC -->$", r"^<!-- /TOC -->$", toc)
subtoc = add_md_link_path("doc/formatter_options.md", toc)
@@ -210,8 +212,6 @@ def main() -> None:
update_autocmd_md()
update_formatter_options_md()
update_md_api()
- update_recipes_toc()
- update_advanced_toc()
- update_formatter_options_toc()
+ update_tocs()
update_readme_toc()
generate_vimdoc()