eraserhd / parinfer-rust

A Rust port of parinfer.
ISC License
539 stars 41 forks source link

Don't modify newly opened buffer (provide as option)? #43

Open AlexChalk opened 5 years ago

AlexChalk commented 5 years ago

When I open a file for the first time, parinfer immediately performs modifications if the parens don't meet parinfer spec.

Whilst this is fine for a personal project, it does not work well with other software that has its own formatting conventions.

Some of these changes can actually break source code, e.g. parinfer added a closing parenthesis to the end of this first line when I opened the file:

(throw (ex-info "Mismatch in embedding size"
      {:input-embedding-size embedding-size
        :word2vec-embedding-size dim})))

My current workaround is to use :let g:parinfer_mode = "off" (I could use any string that isn't one of the official settings), and hit u until the changes are reversed.

However, this workaround has its limits. e.g. if I try to open a readonly file, like a vim-fugitive diff, and parinfer doesn't like its parens, the buffer will fail to open altogether, with some variant of

E21: Cannot make changes, 'modifiable' is off

Parinfer will also start messing with the formatting again as soon as I turn it back on and navigate to the line, even if all I'm doing is hitting h/j/k/l.

I think a nice solution here would be an option to prevent modifications to buffers upon opening/navigating through them, something like g:parinfer_modify_on_navigate that could optionally be set to 0.

Then parinfer would only be run whilst actually editing the buffer, i.e. changing the characters it contains.

eraserhd commented 5 years ago

The first run of parinfer in a buffer is supposed to use paren mode... so it should change the indentation, not the parentheses, preserving the structure of the original file. So it seems like there is a bug here.

But, I really like the idea of deferring this first run until a change has been made to the file. Like you say, it will play better with third-party projects.

AlexChalk commented 5 years ago

I just git pulled and I no longer observe the breaking behaviour @eraserhd, my bad. Would still be very happy about this feature though for the reasons we've both mentioned.

iyedb commented 5 years ago

Do you have any plans to fix this. When opening files in the leiningen project for example, the newly opened buffer is marked as modified.

image

Moreover with nvim 0.3.8 you can't even undo the changes. You can reproduce with nvim src/leiningen/check.clj

iyedb commented 5 years ago

When using Go to file on a symbol in vim fireplace, the file is opened in a new buffer get modified, even if the clojure file is inside a jar dependency. There is no way to move back to another buffer.

andreyorst commented 4 years ago

I think there should be a check if any modification from Parinfer is needed on first interaction with a buffer. If something doesn't look good from Parinfer stand point, instead of running in paren-mode it should prompt confirmation dialog in which user either selects to adjust indentation or disable Parinfer, as done in Atom editor. All editors that parinfer-rust supports have this ability, so I think is not a big deal to implement additional check.

AlexChalk commented 4 years ago

I haven't been doing much Clojure lately, but I did add a slightly hacky solution to this in my dotfiles. I am basically using an autocmd FileType to switch the plugin off when opening a clojure file, and an autocmd InsertEnter to switch it on when I start editing.

I can now browse things like clojure lib definitions and previous git revisions of a file without parinfer trying to edit files that should be readonly, which was probably my biggest pain point previously. It's a bit clunky (what if my first modification is in normal mode, what if the project i'm working on has a linter that's incompatible with parinfer?) but perhaps others will also find this strategy helpful, or hopefully improve it!

andreyorst commented 3 years ago

BTW, this is a feature of Emacs plugin for parinfer-rust for quite a some time and it works great:

image

Relevant parts of the code:

I think that this can easilly be implemented in Kakoune plugin, and in Vim, but I don't remember vimscript good enough to contribute, and no longer use Kakoune, so I guess someone else can do that :)

TimoKramer commented 3 years ago

What's the current status? It seems you merged the change that avoids modifying the buffer when it is inside a jar/zip?! But the change to avoid modifying the buffer before anything is actually changed was reverted, right?

So avoiding to modify a buffer when it is only read is still TODO?

eraserhd commented 3 years ago

@TimoKramer Yes, still a TODO for Vim and Kakoune. The problem is that parinfer must be run in paren-mode to fix indentation once before normal operation, so it needs to detect the user attempting to change the file and fix it, but still honor the user's editing intent.

TimoKramer commented 3 years ago

Is this interesting for solving this feature? https://github.com/vim/vim/commit/f1e8876fa2359b572d262772747405d3616db670