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

file content is stripped when formatting with folds closed #124

Open
zanona opened this issue Apr 29, 2021 · 3 comments
Open

file content is stripped when formatting with folds closed #124

zanona opened this issue Apr 29, 2021 · 3 comments
Labels
question Further information is requested

Comments

@zanona
Copy link

zanona commented Apr 29, 2021

Related with #102, it seems that depending on the code structure coc-prettier will partially remove file contents instead of formatting whenever folding is enabled.

The file being test against is the following, however I had the same sort of behaviour with different structures, where the content is partially/fully stripped:

module.exports = function () {

return;
};

Please bear in mind this happens only with syntax folding enabled on load and running :CocCommand prettier.formatFile or through coc.preferences.formatOnSaveFiletypes

I have been able to reproduce this under a clean installation under a container with the following image:

FROM node:alpine
WORKDIR /root

RUN apk add vim git

# install coc.vim
RUN mkdir -p ~/.vim/pack/coc/start
RUN cd ~/.vim/pack/coc/start && git clone --depth 1 https://github.com/neoclide/coc.nvim.git

# define ~/.vimrc
RUN echo "set background=dark" >> ~/.vimrc
RUN echo "set foldmethod=syntax" >> ~/.vimrc
RUN echo "set foldlevelstart=0" >> ~/.vimrc
RUN echo "let javaScript_fold=1" >> ~/.vimrc

# prepare coc-prettier auto-install
RUN echo "let g:coc_global_extensions = [ 'coc-prettier' ]" >> ~/.vimrc

# add test file 
RUN printf 'module.exports = function(){\n\nreturn;\n};\n' > ~/test.js

To reproduce:

  • docker build . -t vim-coc-test
  • docker -it --rm vim-coc-test vim test.js
  • wait coc-prettier installation and press q once done
  • with test.js open and folding closed, run vim command :CocCommand prettier.formatFile
  • press any key and you will see content has been removed
@chemzqm chemzqm added the question Further information is requested label Apr 30, 2021
@chemzqm
Copy link
Member

chemzqm commented Apr 30, 2021

What do you get after format?

@zanona
Copy link
Author

zanona commented Apr 30, 2021

I'm afraid it erases the entire buffer, whereas the raw output for prettier cli correctly formats the code.
See below.

asciicast

@zanona
Copy link
Author

zanona commented May 5, 2021

After some debugging, I could find that vim will somehow delete text which is replacing a fold without an empty character right after it. I've managed to patch the registerCommand method in a way it first adds an empty space after the last character of the document and then performs the format action.

coc-prettier/src/index.ts

Lines 143 to 156 in 905e830

let edits = await format(
document.content,
document.textDocument,
{}
).then(code => {
if (code == null) return null
return [{
range: fullDocumentRange(document.textDocument),
newText: code
}]
})
if (edits && edits.length) {
await document.applyEdits(edits)
}

--- a/.config/coc/extensions/node_modules/coc-prettier/lib/index.js
+++ b/.config/coc/extensions/node_modules/coc-prettier/lib/index.js
@@ -2839,9 +2839,16 @@ var PrettierEditProvider = class {
     if (!document.uri.startsWith("untitled") && this._fileIsIgnored(fileName)) {
       return Promise.resolve([]);
     }
-    const code = await format(document.getText(), document, options);
+
+    let doc = await import_coc6.workspace.document;
+    await doc.applyEdits([{
+      range: fullDocumentRange(doc.textDocument),
+      newText: doc.content + ' '
+    }]);
+
+    const code = await format(doc.content, doc.textDocument, options);
     const edits = [{
-      range: fullDocumentRange(document),
+      range: fullDocumentRange(doc.textDocument),
       newText: code
     }];
     const {disableSuccessMessage} = getConfig();
@@ -2936,6 +2943,11 @@ async function activate(context) {
       import_coc6.window.showMessage(`Flag prettier.onlyUseLocalVersion is set, but prettier is not installed locally. No operation will be made.`, "warning");
       return;
     }
+
+   await document.applyEdits([{
+     range: fullDocumentRange(document.textDocument),
+     newText: document.content + ' '
+   }]);
     let edits = await format(document.content, document.textDocument, {}).then((code) => {
       if (code == null)
         return null;

Although, this doesn't feel like it's the best way to achieve this, so if somehow you could think on a better way to patch this, it would be really appreciated.

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

No branches or pull requests

2 participants