Tasks

Posted by agiletortoise, Last update 2 months ago

Toggle task marks on selection lines.

Steps

  • script

    // Toggle tasks marks on selected lines
    const off = "[ ]";
    const on = "[x]";
    const offState = "- [ ]";
    const onState = "- [x]";
    
    // grab state
    let [lnStart, lnLen] = editor.getSelectedLineRange();
    let lnText = editor.getTextInRange(lnStart, lnLen);
    let [selStart, selLen] = editor.getSelectedRange();
    
    // just add mark if empty line
    if (lnText.length == 0 || lnText == "\n") { 
      editor.setSelectedText(`${offState} `);
      editor.setSelectedRange(selStart + offState.length + 1, 0);
    }
    else {
      // create line array and tracking vars
      let lines = lnText.split('\n');
      let startOffset = 0;
      let lengthAdjust = 0;
      let flTrailing = false;
      if (lines[lines.length - 1] == "") { 
        lines.pop();
        flTrailing = true;
      }
      let newLines = [];
      const re = /^(\s*[-\*] )?(\[ \]|\[x\])?(.*)/;
      const containsRe = /^(\s?[-\*] )?(\[ \]|\[x\])(.*)/;
    
      // determine if we are removing or adding marks
      let flRemoving = true;
      for (let line of lines) {
       if (line.length > 0 && !line.match(containsRe)) {
         flRemoving = false;
        }
      }
    
      if (!flRemoving) {
        // add marks
        let isFirst = true;
        for (let line of lines) {
          const match = re.exec(line);
          if (match[2] || line.length == 0) {
          	  newLines.push(line);
          }
          else {
            let prefix = match[1];
            let suffix = match[3];
            if (!prefix) { prefix = ""; }
            if (!suffix) { suffix = ""; }
            let adjuster = ""
            if (prefix.endsWith("- ") || prefix.endsWith("* ")) {
              newLines.push(`${prefix}${off} ${suffix}`);
              adjuster = off;
            }
            else {
              newLines.push(`${prefix}${offState} ${suffix}`);
              adjuster = offState
            }
            if (isFirst) {
              startOffset = adjuster.length + 1;
            }
            else {
              lengthAdjust += (adjuster.length + 1);
            }
          }
          isFirst = false;
        }
      } else {
        // remove marks
        let isFirst = true;
        for (let line of lines) {
          if (line.trim() == "") {
            newLines.push(line);
            continue;
          }
          const match = re.exec(line);
          let prefix = match[1];
          let suffix = match[3];
          let state = match[2];
          if (!prefix) { prefix = ""; }
          if (!suffix) { suffix = ""; }
          if (suffix.startsWith(" ")) { 
            suffix = suffix.substr(1);
            if (isFirst) { startOffset -= 1; }
            else { lengthAdjust -= 1; }
          }
          newLines.push(`${prefix}${suffix}`);
          if (isFirst) {
            startOffset -= state.length;
          }      
          else {
          	  lengthAdjust -= state.length;
          }
          isFirst = false;
        }
      }
    
      // update text and selection
      if (flTrailing) {
        newLines.push("");
      }
      let newText = newLines.join("\n");
      editor.setTextInRange(lnStart, lnLen, newText);
      editor.setSelectedRange(selStart + startOffset, selLen + lengthAdjust);
    }
    

Options

  • After Success Nothing
    Notification Error
    Log Level Error
Actions available in the Action Directory are uploaded by community members. Use appropriate caution reviewing downloaded actions before use.