Can't get autoCloseTags to work with custom options

I’ve been trying to add the autoCloseTags addon into my editor. But I’m unable to figure out a way to prevent the autoCloseTags from creating a new line every time it closes a tag.

I’ve found that there’s an option “indentTags” but it doesn’t work when I set the autoCloseTags to an object {…}. What is the correct way to do this? Thanks a lot1

Code editor
    <link rel="stylesheet" href="./codemirror/lib/codemirror.css">
    <link rel="stylesheet" href="./codemirror/addon/scroll/simplescrollbars.css">
    <link rel="stylesheet" href="./codemirror/theme/one-dark.css">
    <link rel="stylesheet" href="./src/styles/style.css">
</head>
<body>
    <div id="editor"></div>
    <div id="result"></div>
    
    <script src="./codemirror/lib/codemirror.js"></script>
    <script src="./codemirror/mode/markdown/markdown.js"></script>
    <script src="./codemirror/mode/xml/xml.js"></script>
    <script src="./codemirror/mode/htmlmixed/htmlmixed.js"></script>
    <script src="./codemirror/addon/scroll/simplescrollbars.js"></script>
    <script src="./codemirror/addon/edit/closetag.js"></script>
    <script>
        let editor = CodeMirror(document.getElementById("editor"), {
            mode: "htmlmixed",
            lineNumbers: true,
            scrollbarStyle: "simple",
            theme: "one-dark",
            selectionPointer: true,
            lineWrapping: true,
            smartIndent: true,
            autoCloseTags: true
        })
    </script>
</body>

For HTML, the addon will add a blank line for block tags by default. You should be able to set autoCloseTags: {indentTags: []} to disable that.

1 Like

Thanks for the reply!

I have one minor problem - how can I set autoCloseTags: true? Thanks!

autoCloseTags: true,
autoCloseTags: {
    indentTags: [false]
}

You don’t need to—setting it to an object enables the feature.

Oh, okay.

Thanks for the reply once again!

I’d, however, still have one question about autoCloseTags:
When I try to create a <div> element in VScode for example, it autocompletes the tag and leaves the cursor on the same line at first (cursor being in the middle of those two tags - this works in CodeMirror).

However, if my cursor is located in the middle of those two tags and I hit enter, it moves the tag behind it on a completely new line.

(images below should visualize the current problem with codemirror)

  1. 1
  2. 2
  3. 3

However, when I try the same in VS code and if the cursor is in the middle of two tags, it will automatically put the cursor on new line and indent it so that the user could continue coding (basically the same representation just without step 2)

Would it be possible in CodeMirror? Obviously, I’m not the creator and I wasn’t able to find it in docs either. Cheers for everything you’re doing!!

// video: https://drive.google.com/file/d/1rvi5AkBjAr_ITOL1u63qL7cZ1VlnX2ep/view?usp=drivesdk

I don’t believe that’s implemented in CodeMirror. You could add your own enter key handler that does this, when appropriate.

Okay, so I’ve been able to find out that it’s already implemented in closebrackets.js. Will it by any chance be implemented in closetag.js?

I’m kind of a newbie to this kind of stuff and I’ve been able to figure out that this is the piece of code that does what I need in closebrackets.js:

  function handleEnter(cm) {
var conf = getConfig(cm);
var explode = conf && getOption(conf, "explode");
if (!explode || cm.getOption("disableInput")) return CodeMirror.Pass;

var ranges = cm.listSelections();
for (var i = 0; i < ranges.length; i++) {
  if (!ranges[i].empty()) return CodeMirror.Pass;
  var around = charsAround(cm, ranges[i].head);
  if (!around || explode.indexOf(around) % 2 != 0) return CodeMirror.Pass;
}
cm.operation(function() {
  var linesep = cm.lineSeparator() || "\n";
  cm.replaceSelection(linesep + linesep, null);
  cm.execCommand("goCharLeft");
  ranges = cm.listSelections();
  for (var i = 0; i < ranges.length; i++) {
    var line = ranges[i].head.line;
    cm.indentLine(line, null, true);
    cm.indentLine(line + 1, null, true);
  }
});}

But if I tried to implement my own event handler, it wouldn’t really work:

if(evt.keyCode == 13) {
    var linesep = editor.lineSeparator() || "\n";
    editor.replaceSelection(linesep + linesep, null);
    editor.execCommand("goCharLeft");
    ranges = editor.listSelections();
    for (var i = 0; i < ranges.length; i++) {
        var line = ranges[i].head.line;
        editor.indentLine(line, null, true);
        editor.indentLine(line + 1, null, true);
    }
}

The problem, in this case, is that it adds a new line and centres the cursor every time user hits enter. One thing I’ll have to do differently is to check whether the user has created a new tag and if they have, and the cursor is in between two tags <div>[cursor here]</div> - only then run the code…

But I’m not really sure how to, would you please help me with this? (I of course, understand that you’re a busy person, I’m still gonna try to do my best to figure it out.) Thanks for everything!