Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Stops working after it attempts to modify an "unmodifiable" file #44

Open
heralden opened this issue Aug 1, 2019 · 9 comments
Open

Comments

@heralden
Copy link

heralden commented Aug 1, 2019

After running nvim with parinfer-rust for many hours, parinfer will suddenly stop completing parens, fixing parens when changing indentation, and everything else the plugin usually does. This will apply to any buffer, so even when opening new files with a filetype that should trigger parinfer, it won't start again.

Since I can't find any existing issue on this, I guess there's something very specific in my init.vim that causes it to fail. Sadly, I haven't been able to find out what action causes parinfer to fail, and using a minimal init.vim for hours to test if that resolves the issue is not viable.

Using :ParinferOff and :ParinferOn has no effect. The only way I've found to get parinfer working again is by restart nvim.

Sorry for the lackluster report, but this is something I've found difficult to investigate.
I'm going to try and play with :ParinferLog and see if it prints anything interesting next time it happens. I'd also appreciate it if you have any ideas to troubleshoot this.

@heralden
Copy link
Author

heralden commented Aug 1, 2019

Here's an excerpt from the file logged by parinfer. Buffer 61 was created from a long-running nvim session where parinfer has stopped working, and buffer 1 is from a fresh nvim session where parinfer is working. I just entered the ( character into each buffer.

               event: {"bufnr": 61, "name": "BufEnter", "changedtick": 2}
               event: {"bufnr": 61, "name": "CursorMoved", "changedtick": 2}
               event: {"bufnr": 61, "name": "InsertEnter", "changedtick": 2}
               event: {"bufnr": 61, "name": "InsertCharPre", "changedtick": 2}
               event: {"bufnr": 61, "name": "TextChangedI", "changedtick": 3}
      error-response: {"parens": [], "cursorLine": 0, "cursorX": 1, "tabStops": [], "parenTrails": [], "text": "(", "error": {"inputX": 0, "name": "unclosed-paren", "inputLineNo": 0, "x": 0, "message": "Unclosed open-paren.", "lineNo": 0}, "success": false}
               event: {"bufnr": 61, "name": "CursorMoved", "changedtick": 3}
               event: {"bufnr": 61, "name": "WinEnter", "changedtick": 3}
               event: {"bufnr": 61, "name": "BufEnter", "changedtick": 3}
               event: {"bufnr": 61, "name": "CursorMoved", "changedtick": 3}
               event: {"bufnr": 8, "name": "WinEnter", "changedtick": 591}
               event: {"bufnr": 8, "name": "BufEnter", "changedtick": 591}
               event: {"bufnr": 8, "name": "CursorMoved", "changedtick": 591}
               event: {"bufnr": 1, "name": "BufEnter", "changedtick": 3}
               event: {"bufnr": 1, "name": "CursorMoved", "changedtick": 3}
               event: {"bufnr": 1, "name": "InsertEnter", "changedtick": 3}
               event: {"bufnr": 1, "name": "InsertCharPre", "changedtick": 3}
               event: {"bufnr": 1, "name": "TextChangedI", "changedtick": 4}
      change-request: {"options": {"prevCursorX": 0, "forceBalance": false, "cursorX": 1, "prevCursorLine": 0, "prevText": "", "cursorLine": 0}, "mode": "smart", "text": "("}
     change-response: {"parens": [], "cursorLine": 0, "cursorX": 1, "tabStops": [], "parenTrails": [{"endX": 2, "lineNo": 0, "startX": 1}], "text": "()", "error": null, "success": true}
    -(
    +()
               event: {"bufnr": 1, "name": "CursorMoved", "changedtick": 5}

@eraserhd
Copy link
Owner

eraserhd commented Aug 1, 2019

Hi!

There's a couple of possibilities.

It looks like g:parinfer_mode has been changed. When it's "paren", it will not fix parens (because it fixes indentation), and this will affect any buffer. The plugin tries to run paren mode the first time in a buffer to make indentation consistent with parentheses for future changes, but normally it should be "smart" or "indent".

If that's not it, make sure you are using the latest, since there were issues with reference counting the library that would make it stop working after some number of invocations. This was mostly on Mac, though it would probably affect other BSDs. If you are using a non-common OS, there's a chance that the reference counting hack is not working for your OS, so let me know what OS you are running.

@heralden
Copy link
Author

heralden commented Aug 7, 2019

Thanks for the response. I have verified I'm on the latest version, and use Void Linux 4.19.48_1.

It occured again so I echo g:parinfer_mode and it returns "paren", so your prediction was right. Running let g:parinfer_mode = "smart" makes it work again. So now I'm really happy that I have a workaround, and don't need to restart nvim when this happens!

It seems to get stuck in "paren" mode when I've been in a buffer and editing for a while. I think perhaps when I undo editing some forms.

@eraserhd
Copy link
Owner

@uosl Do you have an idea what might be triggering the mode change?

@heralden
Copy link
Author

No, sorry. I have experienced it a few more times (once today) but haven't been able to reproduce it when it happened. It definitely happens while editing in normal mode though.

@heralden
Copy link
Author

@eraserhd Great news! I finally found the culprit.

It's not related to the running length of a session, and occurs when switching into a neovim terminal with parinfer running (I set filetype=clojure on my clj sessions to get syntax highlighting). If parinfer see's something not indented right in the terminal, it will try and fix it, leading to the following error.

Error detected while processing function <SNR>108_event[2]..<SNR>108_enter_buffer[8]..<SNR>108_process_buffer:
line   29:
E21: Cannot make changes, 'modifiable' is off

When this happens, g:parinfer_mode will get stuck on paren.

I will close this issue since it's no longer relevant, but this finding leads me to two new questions:

  • Is there something I can run to only disable parinfer for one buffer (which I will add to my clj terminal)?
  • Is it possible to have parinfer not attempt to edit a buffer where modifiable is off?

If you want to reproduce this, you'll need to use neovim and evaluate the auto au TermOpen *clj set filetype=clojure and call :term clj. Then produce something that parinfer wants to fix (I just managed to do this by evaluating (doc 'foo) in a window with 118 column width).

@eraserhd
Copy link
Owner

Nice, thanks for finding this!

Yes, parinfer should definitely not try to modify a read-only buffer. I'm going to re-open this issue and update the title.

@eraserhd eraserhd reopened this Jul 15, 2020
@eraserhd eraserhd changed the title Stops working after long-running session Stops working after it attempts to modify an "unmodifiable" file Jul 15, 2020
@elzibubble
Copy link

Ah excellent, I came here to request this very feature. I often view diffs in Vim, when the original file contains an error then parinfer creates a change against the file meaning ":qa" won't close the buffer. In this case, the original file is "modifiable" but "readonly".

@viperML
Copy link

viperML commented Aug 23, 2024

As far as I understand, :ParinferOff and :ParinferOn work globally. With a per-buffer option, it should be possible to use some Lua to run :ParinferOff when a buffer is not modifiable (or matching anything else).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants