Autocomplete: Always Show Suggestions


#1

Hi.

I’m curious if there’s a way to always show the autocomplete suggestions while CodeMirror has focus. For my use case, I’d like the suggestions to always be shown without having to press a key combo (like Ctrl-Space). I’ve tried the following but get “too much recursion” errors in Firefox. Any help would be greatly appreciated. Thanks!

let editor = CodeMirror((el) => {
      $('form').prepend(el);
    }, {
      extraKeys: {
        'Ctrl-Space': 'autocomplete'
      },
      hintOptions: {
        alignWithWord: false,
        tables: {
          foo: ['a', 'b', 'c', 'd'],
          bar: ['z', 'y', 'x', 'w', 'v']
        }
      },
      matchBrackets: true,
      mode: 'text/x-sql',
      scrollbarStyle: 'null',
    });

    editor.on('focus', (cm, eventObj) => {
      cm.execCommand('autocomplete');
    });

    editor.on('endCompletion', (cm) => {
      cm.execCommand('autocomplete');
    });

#2

The show-hint plugin isn’t really built for this (it will immediately close itself when there are no suggestions, which I guess might be causing this infinite recursion), but you might be able to mostly get it to work by binding an event handler for cursorActivity that calls showHint when cm.state.completeActive is falsy. You’ll also want to set the completeSingle to false in hintOptions, so that, when there’s only one candidate, it isn’t immediately chosen.


#3

@marijn thanks! It’s working a lot more like I want now.

For anyone else interested, here’s my JavaScript snippet:

let editor = CodeMirror((el) => {
  $('form').prepend(el);
}, {
  cursorBlinkRate: 700,
  extraKeys: {
    'Ctrl-Space': 'autocomplete'
  },
  hintOptions: {
    alignWithWord: false,
    completeSingle: false,
    tables: {
      foo: ['a', 'b', 'c', 'd'],
      bar: ['z', 'y', 'x', 'w', 'v']
    }
  },
  matchBrackets: true,
  mode: 'text/x-sql',
  scrollbarStyle: 'null',
});

editor.on('beforeChange', (cm, changeObj) => {
  // don't allow newlines
  if (changeObj.text.length === 2 && changeObj.text[0] === ''
      && changeObj.text[1] === '') {
  
    changeObj.cancel();
  }
});

editor.on('cursorActivity', (cm) => {
  if (!cm.state.completeActive) {
    cm.showHint();
  }
});