简体   繁体   中英

Monaco Editor: only show part of document

Is there a way to only show part of a document, or in monacos case of a model, while still getting intellisense for the whole document?

I only want a user to edit a part of a document, but the user should be able to get the right contextual intellisense.

It would be best for my usecase to hide the uneditable sections, but deactivating them would also be ok.

In case this is not possible, is there any embedded editor that can do this, or can this be achived by modifying the language server?

Monaco editor loads every line as a container under a section with the class name "view-lines". Once the editor content has loaded, set "display: none" to the corresponding container for each line that you want to hide.

Implementation: https://jsfiddle.net/renatodc/s6fxedo2/

let value = `function capitalizeFirstLetter(string) {
\treturn string.charAt(0).toUpperCase() + string.slice(1);
}

$(function() {
\tlet word = "script";
\tlet result = capitalizeFirstLetter(word);
\tconsole.log(result);
});
`
let linesToDisable = [1,2,3];
let editor = monaco.editor.create(document.getElementById('container'), {
    value,
    language: 'javascript',
    theme: 'vs-dark',
    scrollbar: {
      vertical: "hidden",
      handleMouseWheel: false
    },
    scrollBeyondLastLine: false
});

// onLoad event for Monaco Editor: https://github.com/Microsoft/monaco-editor/issues/115
let didScrollChangeDisposable = editor.onDidScrollChange(function() {
    didScrollChangeDisposable.dispose();
    setTimeout(function() {
      $(".monaco-editor .view-lines > div").each(function(i) {
        if(linesToDisable.includes(i+1)) {
          $(this).css("display","none");
          $(this).css("pointer-events","none");
        }
      });
    },1000);
 }); 

Scrolling from Monaco will render the lines again and break the implementation. To prevent this, disable the scrolling feature in Monaco, set a fixed height for the editor container, and use the browser or a parent container to scroll instead.

If you use the arrow keys 'up' or 'down' to navigate to the hidden content, the cursor will still work, and typing will break the implementation. You might be able to use the editor's onKeyDown event to prevent this.

If you're looking for a break-proof implementation, I would suggest loading Monaco editor only with the portion of the document that you wish to edit. Then extend the completion provider (Intellisense) as shown in this example: https://microsoft.github.io/monaco-editor/playground.html#extending-language-services-completion-provider-example

monaco.languages.registerCompletionItemProvider('javascript', {
    provideCompletionItems: function(model, position) {
        return {
            suggestions: [
                {
                    label: "capitalizeFirstLetter",
                    kind: monaco.languages.CompletionItemKind.Method,
                    documentation: "Capitalize the first letter of a word",
                    insertText: "capitalizeFirstLetter("
                }
            ]
        };
    }
});

monaco.editor.create(document.getElementById("container"), {
    value: `$(function() {
\tlet word = "script";
\tlet result = capitalizeFirstLetter(word);
\tconsole.log(result);
});
  `,
    language: "javascript"
});

Use an AST parser like Esprima to get the identifiers from your source document, and plug these into the suggestions array.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM