What are the steps to activate code suggestion with codemirror?

My goal is to implement CodeMirror for enabling users to input code in various languages like CSS, HTML, and JavaScript.

One specific requirement is to provide hints to the user when typing code in CSS mode.

div {
 padding-
}

The system should prompt the user to select from a list of available options similar to:

div {
padding-top
padding-left
padding-right
padding-bottom
}

I am looking to replicate the auto-hinting feature seen in Sublime Editor using CodeMirror. Please refer to the following image for a demo:

https://i.sstatic.net/S6lvJ.png

Below is the code snippet:

 <script src="codemirror-5.4/mode/javascript/javascript.js"></script>
  <script src="codemirror-5.4/mode/css/css.js"></script>
  <script src="codemirror-5.4/mode/htmlmixed/htmlmixed.js"></script>
  <script src="codemirror-5.4/addon/display/fullscreen.js"></script>
  <script src="codemirror-5.4/keymap/sublime.js"></script>
  <script src="codemirror-5.4/addon/hint/show-hint.js"></script>
  <script src="codemirror-5.4/addon/hint/css-hint.js"></script>
  <script src="codemirror-5.4/addon/hint/javascript.js"></script>

<h3>Editor</h3>
  <div class="control-group">
    <label class="control-label" for="textarea2">HTML</label>
    <div class="controls">
        <textarea class="code" name="code" id="codert" cols="40" rows="5" placeholder="Enter code here ..." style="width: 810px; height: 200px">
       </textarea>
        </div>
    </div>

    <div class="control-group">
        <label class="control-label" for="textarea3">CSS</label>
        <div class="controls">
          <textarea id="code" class="code" name="codeCSS"  cols="40" rows="5" placeholder="Enter code here ..." style="width: 810px; height: 200px">
        </textarea>
        </div>
    </div>
    <div class="control-group">
        <label class="control-label" for="textarea3">javascript</label>
        <div class="controls">
            <textarea id="codeJS" class="code" name="codeJS"  cols="40" rows="5" placeholder="Enter code here ..." style="width: 0px; height: 0px">
           </textarea>
        </div>
    </div>

Javascript code for CodeMirror

<script>

   function loadCSS() {
    var $head = $("#preview").contents().find("head");                
    $head.html("<style>" + editor.getValue() + "</style>");
}; 

function loadJS() {
    var scriptTag = "<script>"+editorJS.getValue()+"<";
    scriptTag +=  "/script>";

    var previewFrame2 = document.getElementById('preview');
    var preview2 =  previewFrame2.contentDocument ||  previewFrame2.contentWindow.document;
    preview2.open();
    preview2.write(editor2.getValue()+scriptTag);
    preview2.close();

    loadCSS();
};

var delay;
// Initialize CodeMirror editor with a nice html5 canvas demo.

// css editor
var editor = CodeMirror.fromTextArea(document.getElementById('code'), {
    lineNumbers: true,
    styleActiveLine: true,
    matchBrackets: true,
    mode: "text/x-scss",
    keyMap: "sublime",
    theme: 'monokai',
    autoCloseTags: true,
    lineWrapping: true,
    extraKeys: {"Ctrl-Space": "autocomplete"}
});
editor.on("change", function() {
    clearTimeout(delay);

    delay = setTimeout(updatePreview, 0);
});

function updatePreview() {
    loadCSS();
}
setTimeout(updatePreview, 0);


var delay2;
// Initialize CodeMirror editor with a nice html5 canvas demo.
var editor2 = CodeMirror.fromTextArea(document.getElementById('codert'), {
    lineNumbers: true,
    styleActiveLine: true,
    matchBrackets: true,
    mode: "text/html",
    keyMap: "sublime",
    theme: 'monokai',
    autoCloseTags: true,
    lineWrapping: true,
    extraKeys: {"Ctrl-Space": "autocomplete"}
});
editor2.on("change", function() {
    clearTimeout(delay2);

    delay2 = setTimeout(updatePreview2, 0);
});

function updatePreview2() {
    var scriptTag = "<script>"+editorJS.getValue()+"<";
    scriptTag +=  "/script>";

    var previewFrame2 = document.getElementById('preview');
    var preview2 =  previewFrame2.contentDocument ||  previewFrame2.contentWindow.document;
    preview2.open();
    preview2.write(editor2.getValue()+scriptTag);
    preview2.close();

    loadCSS();
}
setTimeout(updatePreview2, 0);


var delayJS;
// Initialize CodeMirror editor with a nice html5 canvas demo.
var editorJS = CodeMirror.fromTextArea(document.getElementById('codeJS'), {
    lineNumbers: true,
    styleActiveLine: true,
    matchBrackets: true,
    mode: 'javascript',
    keyMap: "sublime",
    theme: 'monokai',
    autoCloseTags: true,
    lineWrapping: true,
    extraKeys: {"Ctrl-Space": "autocomplete"}
});
editorJS.on("change", function() {
    clearTimeout(delayJS);

    delayJS = setTimeout(updatePreviewJS, 0);
});

function updatePreviewJS() {
    loadJS();
}
setTimeout(updatePreviewJS, 0);
</script>

Answer №1

The code snippet you provided may not be complete, but it's important to ensure that you include the show-hint.css stylesheet in the page header.

<link rel="stylesheet" href="../addon/hint/show-hint.css">

Failure to do so can result in the hints not being displayed, leading users to believe that the autocomplete feature is not functioning properly.

Answer №2

discovered on the code mirror site

function findSuggestions(token, context) {
  var discovered = [], initiate = token.string;
  function perhapsAdd(str) {
    if (str.indexOf(initiate) == 0) discovered.push(str);
  }
  function gatherSuggestions(obj) {
    if (typeof obj == "string") forEach(stringProps, perhapsAdd);
    else if (obj instanceof Array) forEach(arrayProps, perhapsAdd);
    else if (obj instanceof Function) forEach(funcProps, perhapsAdd);
    for (var name in obj) perhapsAdd(name);
  }

  if (context) {
    var obj = context.pop(), base;
    if (obj.className == "js-variable")
      base = window[obj.string];
    else if (obj.className == "js-string")
      base = "";
    else if (obj.className == "js-atom")
      base = 1;
    while (base != null && context.length)
      base = base[context.pop().string];
    if (base != null) gatherSuggestions(base);
  }
  else {
    for (var v = token.state.localVars; v; v = v.next) perhapsAdd(v.name);
    gatherSuggestions(window);
    forEach(keywords, perhapsAdd);
  }
  return discovered;
}

the shortcut to activate code suggestions is ctrl+ space.

Answer №3

Weave:

There are numerous methods available for incorporating code hinting/autocomplete functionality into your projects.

var arrows = [37, 38, 39, 40]

editor.on("keyup", function(cm, e) {
  if (arrows.indexOf(e.keyCode) < 0) {
    editor.execCommand("autocomplete")
  }
})

Official documentation on code hints/autocomplete is provided by Codemirror.
XML completion
HTML completion
JavaScript completion

To create your own hints, you can view the source of the javascript example and learn from it.

Answer №4

I successfully implemented custom code suggestion features in my application's user interface using CodeMirror 5

(this solution is a combination of various online resources and insights from the source code found at )

To begin, I integrated CodeMirror and the code hint plugin into the project

<script src="libs/codemirror-5/codemirror.min.js"></script>
<script src="libs/codemirror-5/plugins/show-hint.js"></script>

I customized the showHint command, encapsulated it within a function (it's important to note that this function will receive the instance context as an argument from CodeMirror).

function getSnippets(codemirror) {

    let snippets = [
        {text: 'SELECT', displayName: 'select'},
        {text: 'UPDATE', displayName: 'update'},
        {text: 'CREATE', displayName: 'create'},
        // other snippets for hinting
    ]

    CodeMirror.showHint(codemirror, function () {

        let cursor = codemirror.getCursor();
        let line = codemirror.getLine(cursor.line);
        let start = cursor.ch, end = cursor.ch;
        // handling trailing whitespaces removal
        while (start && /\w/.test(line.charAt(start - 1)))
                    --start;
        while (end < line.length && /\w/.test(line.charAt(end)))
                    ++end;
        const token = codemirror.getTokenAt(cursor);
        const currentWord = token.string;

        // filtering hint options based on user input
        const list = snippets.filter(function (item) {
            return item.displayText.indexOf(currentWord) >= 0;
        });

        return {
            list: list.length ? list : snippets,
            from: CodeMirror.Pos(cursor.line, start),
            to: CodeMirror.Pos(cursor.line, end)
        };
    }, {completeSingle: true});
}

Next, within the CodeMirror instance settings, I specified the command to trigger hint suggestions by pressing Ctrl+Space, which will execute the getSnippets function defined earlier

let codemirrorOptions = {
    mode: 'sql',
    extraKeys: {
        "Ctrl-Space": getSnippets
    },
    lineNumbers: false,
    lineWrapping: true
}; 

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Using Yii2, create a button with an onclick event that executes a JsExpression

I need to submit a form with an array of elements whose number is unknown. class DynamicForm extends Model { /** var string[] */ public elements[]; } In the view where the form submission takes place, I want to include a button that triggers a Ja ...

What is the best way to add a radial pattern to a ring using three.js r67?

I am facing a challenge in applying a texture to a ringGeometry using three.js r67. The issue lies in orienting the texture correctly. My goal is to apply a specific texture to a ringGeometry mesh in a radial manner, where the blue end of the texture align ...

Three.js is failing to render within a specified div

My current project involves utilizing three.js to create a cube rendering. Despite the cube appearing on the screen, I am facing issues with getting it to display within the specified div element and in the desired style. HTML: <div id="render"> & ...

How to automatically close the menu on a Wordpress theme after clicking a link

I am currently using a Wordpress theme named ichiban, which can be viewed by following this link. Within this theme, I have created custom menu items that are designed to link directly to different sections on the same page. However, I am encountering an i ...

The bootstrap modal display issue: black background visible

In my HTML file, there are two modal dialogs that seem to be causing an issue. Interestingly, whichever modal dialog is placed first in the sequence of the HTML code displays properly when the button is clicked (and vice versa). Both modal dialogs have u ...

Does aoMap function exclusively with THREE.BufferGeometry?

Can you provide guidance on setting up an aoMap for a standard THREE.Geometry object? Is there a demo available to reference? var uvCoordinates = geometry.attributes.uv.array; geometry.addAttribute('uv2', new THREE.BufferAttribute(uvCoordina ...

Creating a Masonry Gallery without any spacing between images

I'm looking to create a unique masonry gallery design that eliminates any gaps between images. I've experimented with various plugins like masonry and isotope, but they still leave gaps in the layout. Packery seems promising, however it tends to ...

Necessary form group in html [Angular]

Is there a way to make certain form fieldsets required while allowing the user to choose which inputs to fill? My idea: Users can select what they want to fill out without having to complete all of the fieldset inputs. I have these two options: 1: < ...

Does Peerjs exclusively cater to one-on-one webrtc communication?

Can PeerJS be used to implement one-to-many audio communication with WebRTC? I'm currently using Socket.io with Node.js. Is this sufficient for WebRTC integration? As a beginner in WebRTC, could you recommend some options for implementin ...

Using AngularJS controller to implement filtering functionality

I am a beginner at using Angular and have successfully implemented a filter to translate text for localization in my HTML view: <input type="button" class="btn btn-link" value="{{'weeklyOrdersPage.reposting' | translate}}" ng-click="sortBy(&a ...

Choosing a checkbox by considering the checkbox value, especially in cases where the checkbox and its label are separate elements

My goal is to click on the checkbox located next to the label "Print Method 1". Take a look at how the element appears here Below is the HTML code for reference: <div class="texter"> <div class="checkbox"/> ...

Having trouble getting CSS calc to work on a table cell? Wondering how to make two out of four columns the same width?

Is it possible that CSS calc doesn't work on a table cell? It seems that no matter what size I change 90px to, the result looks the same. Even after trying various calculations with calc, I cannot seem to achieve the desired number of 230. The goal i ...

Creating interactive PDF files using ReactJS

Is there a way to create a PDF using React that supports styling and allows the content to be hidden on the page? I need to have a link in my app that, when clicked, generates a PDF and opens it in a new tab. I've tried out various packages but none s ...

What is the best way to compare an attribute value with a JSON value in JavaScript?

I have a JSON string that looks like this: { "DocID": "NA2", "DocType": "Phase1.1 - Visa Documents (This section is applicable for HK work location only)", "DocSubType": "New Application", "DocName": "Passport / Travel Document (Soft copy only) ...

What is the significance of combining two arrays?

const customTheme = createMuiTheme({ margin: value => [0, 4, 8, 16, 32, 64][value], }); customTheme.margin(2); // = 8 This code snippet showcases how to define spacing values in a Material-UI theme configuration. For more details on customization re ...

I'm having trouble adding a background image, even though I have set it to static. What could be

I attempted to add a background image to my Django website, but unfortunately, it was not successful. I followed the steps provided in this Stack Overflow answer here, however, it did not work. I even made changes to the database by migrating them, but s ...

AngularJS presents an error: [ng:areq] The argument 'myAppCtrl' is not recognized as a function, as it returns undefined while implementing routes with ngRoute and $routeProvider

Can anyone assist me with an error I'm encountering while setting routes on two buttons? Despite having everything properly defined, the table is not displaying any data. Your insights would be greatly appreciated. Thank you for your help. Snippet f ...

Using JavaScript to detect the Facebook like button on a webpage

I am currently developing an application for Facebook using HTML and Javascript. My goal is to be able to detect when a user clicks the "Like" button on my company's Facebook page without needing to embed a separate "Like" button within my app itself. ...

"Learn how to deactivate the submit button while the form is being processed and reactivate it once the process is

I have been searching for solutions to this issue, but none seem to address my specific concern. Here is the HTML in question: <form action=".."> <input type="submit" value="download" /> </form> After submitting the form, it takes a ...

Show different material ui TextFields based on what the user chooses

My dropdown menu offers two options: BUY x AND y AND z SAVE m BUY n FOR m If I select option 1, I want to display Textfields for x, y, and z. If I choose option 2, then only Textfields for n and m should be displayed for user input. In the code snippet ...