Red Riding Hood
Red Riding Hood

Reputation: 2444

Write initial settings to settings.json

I am looking for a way to write initial settings to settings.json for when my extension is installed.

I found WorkspaceConfiguration API, but that seems to retrieving/updating values at runtime.

I'm looking to get my settings + comments into the default settings file

e.g. How TSLint does it: enter image description here

Upvotes: 1

Views: 1810

Answers (2)

eeasterly
eeasterly

Reputation: 774

One approach includes using default configuration files that will be copied completely into the settings.json file. Consider the following modern bash function running on a mac with jq and node installed. It allows settings.json and keybindings.json to be revised to match the default where there is not already a setting. Just configure the default folder and filename for the default settings and keybindings.

setup_vscode_defaults() {
  #configure the below variables to the desired settings and keybindings
  local settings_defaults="<default_folder/vs_code_settings.json>";
  local keybindings_defaults="<default_folder/vs_code_keybindings.json>";

  echo -e "\nSetting up default settings and keybindings for Visual Studio Code, without clobbering any preexisting settings.\n";
  local vscode_user_folder=$HOME/Library/Application\ Support/Code/User; local backup_timestamp=$(date +%s);
  local settings_file="${vscode_user_folder}/settings.json";       ln -s "${settings_file}" sf;    local settings_backup="${vscode_user_folder}/settings_${backup_timestamp}.json";
  local keybindings_file="${vscode_user_folder}/keybindings.json"; ln -s "${keybindings_file}" kf; local keybindings_backup="${vscode_user_folder}/keybindings_${backup_timestamp}.json";
  local tmp_settings=/tmp/settings.json
  local tmp_keybindings=/tmp/keybindings.json

  #check if files exist or are empty and use complete default file in each case
  if (! test -f sf ) || [[ $(cat "${settings_file}" | jq length) -eq 0 ]]; then cat "${settings_defaults}" > sf;  fi
  if (! test -f kf ) || [[ $(cat "${keybindings_file}" | jq length) -eq 0 ]]; then cat "${keybindings_deftauls}" > kf;  fi

  #checks to see if the exact default settings file is being used, and adds anything missing if not using the default
  settings_adder() {
    local set_file_type="${1}"; local set_file="${2}"; local set_file_backup="${3}"; local set_file_defaults="${4}"; local set_file_temp="${5}";

    #backup settings file just in case
    cp "${set_file}" "${set_file_backup}";

    #install underscore node package for working with json if not already installed
    if [ $(npm list -g | grep -c underscore-cli) -eq 0 ]; then npm install -g underscore-cli; fi

    #creates arrays for settings vs. default settings, removing braces for settings and brackets for keybindings
    unset arrSettings;    local -a arrSettings=();     readarray -t arrSettings    < <(cat "${set_file}"          | jq -S | underscore --wrapwidth 500 print | perl -pe 's/^{\n$|^}\n$|^\[\n$|^\]\n$|,$//g' | sort);
    unset arrDefSettings; local -a arrDefSettings=();  readarray -t arrDefSettings < <(cat "${set_file_defaults}" | jq -S | underscore --wrapwidth 500 print | perl -pe 's/^{\n$|^}\n$|^\[\n$|^\]\n$|,$//g' | sort);

    for settingDef in "${arrDefSettings[@]}"; do
      #add any settings from the default settings file that was not found in the user settings.json, by f-grepping the setting key (the first part, not the value, "key_s")-- fgrep does not interpret the string to grep, it is 'fixed'
      if   [[ "${set_file_type}" == "settings" ]] ;    then key_s=$(echo "${settingDef}" | perl -pe 's/"([^:]+)":.+\n/\1/' );           fb="{";  lb="}";
      elif [[ "${set_file_type}" == "keybindings" ]] ; then key_s=$(echo "${settingDef}" | perl -pe 's/^.+key": "([^"]+)".+\n/"\1"/g' );  fb="[";  lb="]"; fi

      #debug statement to show the setting, key for searching, and fgrep result: --> echo "${settingDef} - ${key_s}: $(fgrep -c ${key_s} ${set_file})"

      if [[ $(fgrep -c ${key_s} ${set_file} ) -eq 0 ]]; then
        arrSettings+=("${settingDef}")
      fi
    done

    #now output the settings array into a file, starting with the first brace/bracket then the settings/bindings
    for setting in "${arrSettings[@]}"; do
      echo "${setting}," >> "${set_file_temp}_${backup_timestamp}"
    done
    echo "${fb}" > "${set_file_temp}"
    # remove extra commas, last comma and add closing brace
    cat "${set_file_temp}_${backup_timestamp}" | perl -pe 's/^,\n//g' | sort >> "${set_file_temp}"
    sed -i '' '$ s/.$//' "${set_file_temp}"
    echo "${lb}" >> "${set_file_temp}"

    cat "${set_file_temp}" | jq -S | underscore --wrapwidth 500 print > "${set_file}";
  }

  if [[ $(md5sum  ${settings_defaults} | perl -pe 's/ .+//') != $(md5sum sf | perl -pe 's/ .+//') ]]; then
    settings_adder "settings" sf "${settings_backup}" "${settings_defaults}" "${tmp_settings}"
  fi

  if [[ $(md5sum  ${keybindings_defaults} | perl -pe 's/ .+//') != $(md5sum kf | perl -pe 's/ .+//') ]]; then
    settings_adder "keybindings" kf "${keybindings_backup}" "${keybindings_defaults}" "${tmp_keybindings}"
  fi

  unlink sf;
  unlink kf;
}

Upvotes: 0

Hans B&#228;uml
Hans B&#228;uml

Reputation: 229

I hope I get your question correctly: I assume you mean the User Settings settings.json you can get via File>Preferences>User Settings.

If you know that TSLint does it, you can go to your extensions folder (windows: $USERFOLDER/.vscode/extensions), pick the extension (in my case it was the folder "eg2.tslint-0.6.7") and peek the files.

...
"contributes": {
    "configuration": {
        "type": "object",
        "title": "TSLint",
        "properties": {
            "tslint.enable": {
                "type": "boolean",
                "default": true,
                "description": "Control whether tslint is enabled for TypeScript files or not."
            },
            "tslint.rulesDirectory": {
                "type": [
                    "string",
                    "array"
                ],
                "items": {
                    "type": "string"
                },
                "description": "An additional rules directory",
                "default": ""
            },
            "tslint.validateWithDefaultConfig": {
                "type": "boolean",
                "description": "Validate a file when there is only a default tslint configuration is found",
                "default": false
            },
            "tslint.configFile": {
                "type": "string",
                "description": "The path to the rules configuration file",
                "default": ""
            },
            "tslint.ignoreDefinitionFiles": {
                "type": "boolean",
                "default": true,
                "description": "Control if TypeScript definition files should be ignored"
            },
            "tslint.exclude": {
                "type": [
                    "string",
                    "array"
                ],
                "items": {
                    "type": "string"
                },
                "description": "Configure glob patterns of file paths to exclude from linting"
            },
            "tslint.run": {
                "type": "string",
                "enum": [
                    "onSave",
                    "onType"
                ],
                "default": "onType",
                "description": "Run the linter on save (onSave) or on type (onType)"
            },
            "tslint.nodePath": {
                "type": "string",
                "default": "",
                "description": "A path added to NODE_PATH when resolving the tslint module."
            },
            "tslint.autoFixOnSave": {
                "type": "boolean",
                "default": false,
                "description": "Turns auto fix on save on or off."
            }
        }
    }
...

Hope this helps

Upvotes: 1

Related Questions