whole_func_string: function inlineHandler(string, selectionRange, symbol) {
    let newString = string;
    const newSelectionRange = [...selectionRange];
    // insertSymbols determines whether to add the symbol to either end of the selected text
    // Stat with assuming we will insert them (we will remove as necessary)
    const insertSymbols = [symbol, symbol];
    const symbolLength = symbol.length;
    const relevantPart = string.substring(selectionRange[0] - symbolLength, selectionRange[1] + symbolLength).trim();
  
    // First check that the symbol is in the string at all
    if (relevantPart.includes(symbol)) {
      // If it is, for each index in the selection range...
      newSelectionRange.forEach((selectionIndex, j) => {
        const isStartingIndex = j === 0;
        const isEndingIndex = j === 1;
        // If the symbol immediately precedes the selection index...
        if (newString.lastIndexOf(symbol, selectionIndex) === selectionIndex - symbolLength) {
          // First trim it
          newString = newString.substring(0, selectionIndex - symbolLength) + newString.substring(selectionIndex);
  
          // Then adjust the selection range,
          // If this is the starting index in the range, we will have to adjust both
          // starting and ending indices
          if (isStartingIndex) {
            newSelectionRange[0] -= symbolLength;
            newSelectionRange[1] -= symbolLength;
          }
  
          if (isEndingIndex && !insertSymbols[0]) {
            newSelectionRange[1] -= symbol.length;
          }
  
          // Finally, disallow the symbol at this end of the selection
          insertSymbols[j] = '';
        }
  
        // If the symbol immediately follows the selection index...
        if (newString.indexOf(symbol, selectionIndex) === selectionIndex) {
          // Trim it
          newString = newString.substring(0, selectionIndex) + newString.substring(selectionIndex + symbolLength);
  
          // Then adjust the selection range,
          // If this is the starting index in the range...
          if (isStartingIndex) {
            // If the starting and ending indices are NOT the same (selection length > 0)
            // Adjust the ending selection down
            if (newSelectionRange[0] !== newSelectionRange[1]) {
              newSelectionRange[1] -= symbolLength;
            }
            // If the starting and ending indices are the same (selection length = 0)
            // Adjust the starting selection down
            if (newSelectionRange[0] === newSelectionRange[1]) {
              newSelectionRange[0] -= symbolLength;
            }
          }
  
          // If this is the ending index and the range
          // AND we're inserting the symbol at the starting index,
          // Adjust the ending selection up
          if (isEndingIndex && insertSymbols[0]) {
            newSelectionRange[1] += symbolLength;
          }
  
          // Finally, disallow the symbol at this end of the selection
          insertSymbols[j] = '';
        }
      });
    }
  
    // Put it all together
    const value = newString.substring(0, newSelectionRange[0]) + insertSymbols[0] + newString.substring(newSelectionRange[0], newSelectionRange[1]) + insertSymbols[1] + newString.substring(newSelectionRange[1]);
  
    return {
      value,
      range: [newSelectionRange[0] + insertSymbols[0].length, newSelectionRange[1] + insertSymbols[1].length]
    };
  }
func_code_string: function inlineHandler(string, selectionRange, symbol) {
    let newString = string;
    const newSelectionRange = [...selectionRange];
    // insertSymbols determines whether to add the symbol to either end of the selected text
    // Stat with assuming we will insert them (we will remove as necessary)
    const insertSymbols = [symbol, symbol];
    const symbolLength = symbol.length;
    const relevantPart = string.substring(selectionRange[0] - symbolLength, selectionRange[1] + symbolLength).trim();
  
    // First check that the symbol is in the string at all
    if (relevantPart.includes(symbol)) {
      // If it is, for each index in the selection range...
      newSelectionRange.forEach((selectionIndex, j) => {
        const isStartingIndex = j === 0;
        const isEndingIndex = j === 1;
        // If the symbol immediately precedes the selection index...
        if (newString.lastIndexOf(symbol, selectionIndex) === selectionIndex - symbolLength) {
          // First trim it
          newString = newString.substring(0, selectionIndex - symbolLength) + newString.substring(selectionIndex);
  
          // Then adjust the selection range,
          // If this is the starting index in the range, we will have to adjust both
          // starting and ending indices
          if (isStartingIndex) {
            newSelectionRange[0] -= symbolLength;
            newSelectionRange[1] -= symbolLength;
          }
  
          if (isEndingIndex && !insertSymbols[0]) {
            newSelectionRange[1] -= symbol.length;
          }
  
          // Finally, disallow the symbol at this end of the selection
          insertSymbols[j] = '';
        }
  
        // If the symbol immediately follows the selection index...
        if (newString.indexOf(symbol, selectionIndex) === selectionIndex) {
          // Trim it
          newString = newString.substring(0, selectionIndex) + newString.substring(selectionIndex + symbolLength);
  
          // Then adjust the selection range,
          // If this is the starting index in the range...
          if (isStartingIndex) {
            // If the starting and ending indices are NOT the same (selection length > 0)
            // Adjust the ending selection down
            if (newSelectionRange[0] !== newSelectionRange[1]) {
              newSelectionRange[1] -= symbolLength;
            }
            // If the starting and ending indices are the same (selection length = 0)
            // Adjust the starting selection down
            if (newSelectionRange[0] === newSelectionRange[1]) {
              newSelectionRange[0] -= symbolLength;
            }
          }
  
          // If this is the ending index and the range
          // AND we're inserting the symbol at the starting index,
          // Adjust the ending selection up
          if (isEndingIndex && insertSymbols[0]) {
            newSelectionRange[1] += symbolLength;
          }
  
          // Finally, disallow the symbol at this end of the selection
          insertSymbols[j] = '';
        }
      });
    }
  
    // Put it all together
    const value = newString.substring(0, newSelectionRange[0]) + insertSymbols[0] + newString.substring(newSelectionRange[0], newSelectionRange[1]) + insertSymbols[1] + newString.substring(newSelectionRange[1]);
  
    return {
      value,
      range: [newSelectionRange[0] + insertSymbols[0].length, newSelectionRange[1] + insertSymbols[1].length]
    };
  }
func_documentation_string: Handles wrapping format strings around a selection
  @param   {String} string         the entire string
  @param   {Number[]}  selectionRange the starting and ending positions of the selection
  @param   {String} symbol         the format string to use
  @returns {Object} the new string, the updated selectionRange