JustToThePoint English Website Version
JustToThePoint en español

Python and Visual Code

Programming today is a race between software engineers striving to build bigger and better idiot-proof programs, and the Universe trying to produce bigger and better idiots. So far, the Universe is winning, Rick Cook

Introduction

Python is a simple, easy-to-understand, and minimalistic language, and yet very powerful.It is one of the easiest programming languages to learn because it has a clean and readable syntax that makes it easy for beginners to read and use. Besides, Python is free and open-source.

Python is an interpreted, high-level, and general-purpose programming language with batteries included. It is used for web development, AI, machine learning, operating systems, mobile application development, and video games.

Installation

  1. Ubuntu, Debian: sudo apt-get install python3 python3-pip python3-venv. Arch: sudo pacman -S python python-pip

  2. Install Visual Studio Code and some extensions. Arch:

        # Arch
        git clone https://aur.archlinux.org/visual-studio-code-bin.git
        cd visual-studio-code-bin
        makepkg -si
        cd ..
        rm -rf visual-studio-code-bin
        yay -S consolas-font
        # macOS
        brew install --cask visual-studio-code
        brew install --cask font-jetbrains-mono     # optional, used in the settings below
    
        # Install the extensions
        code --install-extension ms-python.python # Python, installs Pylance + Python Debugger too
        code --install-extension charliermarsh.ruff # linter + formatter + import sorter, replaces Pylint/autopep8/isort
        code --install-extension streetsidesoftware.code-spell-checker
        code --install-extension streetsidesoftware.code-spell-checker-spanish
        code --install-extension pkief.material-icon-theme
        code --install-extension oderwat.indent-rainbow
    
  3. Open a project folder: mkdir -p ~/macOS/myPython && cd ~/myPython && code .

  4. New File.

  5. Create a virtual environment (python3 -m venv venv) and activate it (source ./venv/bin/activate). Upgraded pip (python -m pip install --upgrade pip). deactivate (when you want to leave it).

Visual Studio Code

Visual Studio Code is a multiplatform source-code editor made by Microsoft. Its functionality can be extended using extensions.

  1. Create a folder (mkdir -p ~/macOS/myPython && cd ~/myPython) and open VS Code in it (code .). Alternatively, launch VS Code and go to File, Open Folder…
  2. Then, select the Python interpreter: open the Command Palette (Cmd+Shift+P) and run Python: Select Interpreter, choosing the one inside .venv. If you haven’t created the environment yet, run Python: Create Environment, pick Venv, and VS Code creates .venv for you (and installs from requirements.txt or pyproject.toml if present).
  3. Create a Python file: File, New File, save it as hello.py.
  4. Run your file. Click the Run Python File play button (top right of the editor).
  5. Run Python File in Dedicated Terminal is in the same dropdown. To run only a selection, press Shift+Enter.

Pylint in action

Debug. Press F5 and choose Python File, or use Run, Start Debugging. Step with F10 (over), F11 (into) and Shift+F11 (out).

Learn Python withVisual Studio Code

VS Code keeps debugging configuration in .vscode/launch.json (Run, Open Configurations). The debugger type is now debugpy (the old “type”: “python” still appears in older guides). To pass arguments to your program, use args:

{
    "version": "0.2.0",
    "configurations": [
        {
            "name": "Python Debugger: Current File",
            "type": "debugpy",
            "request": "launch",
            "program": "${file}",
            "args": ["myarg1", "myarg2"],      // or "${command:pickArgs}" to be asked every run
            "console": "integratedTerminal"
        }
    ]
}

Activate a virtual environment: source myProject/bin/activate. To deactivate it: deactivate

Install packages in the active environment (the integrated terminal activates it for you): python -m pip install yourPackage. You can also use the Python sidebar: Environment Managers, right-click the environment, Manage Packages.

“No pip installer available in the selected environment”: the venv was created without pip. Fix it with python -m ensurepip –upgrade, or delete .venv and recreate it. Don’t set include-system-site-packages = true, because that makes the environment see (and depend on) your global packages.

Let’s configure Visual Studio Code to your heart’s content.

{
    // —————— Workbench ——————
    "workbench.colorTheme": "Dark Modern",                 // any installed theme name
    "workbench.iconTheme": "material-icon-theme",
    "workbench.settings.editor": "json",                   // open settings.json instead of the Settings UI
    "workbench.settings.openDefaultSettings": true,        // show read-only defaults next to your overrides
    "workbench.editor.enablePreview": false,               // every opened file gets a permanent tab
    "workbench.activityBar.visible": true,
    "window.zoomLevel": 1,

    // —————— Editor ——————
    "editor.fontSize": 16,
    "editor.fontFamily": "JetBrains Mono, Menlo, Monaco, monospace",   // Consolas is not on macOS
    "editor.fontLigatures": true,                          // draw -> != == as single glyphs (visual only)
    "editor.tabSize": 4,
    "editor.insertSpaces": true,                           // PEP 8: 4 spaces, never tabs, formatters expect it
    "editor.formatOnSave": true,
    "editor.formatOnPaste": true,
    "editor.accessibilitySupport": "off",
    "editor.codeActionsOnSave": {
        "source.fixAll": "explicit",                       // only on a manual save (Cmd+S)
        "source.organizeImports": "explicit"
    },

    // —————— Files ——————
    "files.trimTrailingWhitespace": true,
    "files.trimFinalNewlines": true,
    "files.insertFinalNewline": true,                      // POSIX/PEP 8 style: exactly one final newline
    "files.autoSave": "afterDelay",                        // AUTO-SAVE
    "files.autoSaveDelay": 1000,
    "explorer.confirmDragAndDrop": false,
    "explorer.confirmDelete": false,                       // Deleted files go to the Trash, still recoverable

    // —————— Terminal ——————
    "terminal.integrated.fontSize": 16,
    "terminal.integrated.fontFamily": "JetBrains Mono, Menlo, monospace",
    "terminal.integrated.scrollback": 20000,               // 1,000,000 lines eats RAM
    "terminal.integrated.cursorStyle": "line",
    "terminal.integrated.defaultProfile.osx": "zsh",

    // —————— Python ——————
    "python.defaultInterpreterPath": "${workspaceFolder}/.venv/bin/python",   // fallback, a .venv is also auto-detected
    "python.envFile": "${workspaceFolder}/.env",
    "[python]": {
        "editor.defaultFormatter": "charliermarsh.ruff",   // or "ms-python.autopep8" / "ms-python.black-formatter"
        "editor.codeActionsOnSave": {
            "source.fixAll.ruff": "explicit",
            "source.organizeImports.ruff": "explicit"
        }
    },

    // —————— Markdown (snippets need quick suggestions on) ——————
    "[markdown]": {
        "editor.quickSuggestions": { "other": "on", "comments": "off", "strings": "on" }
    },

    // —————— Code Runner (optional extension) ——————
    "code-runner.clearPreviousOutput": true,
    "code-runner.runInTerminal": true,
    "code-runner.showExecutionMessage": false,
    "code-runner.saveFileBeforeRun": true,
    "code-runner.executorMap": {
        "python": "$pythonPath -u $fullFileName"           // uses the interpreter selected in VS Code
    },

    // —————— Spell checker ——————
    "cSpell.enabled": true,
    "cSpell.language": "en,es",
    "cSpell.diagnosticLevel": "Warning"                    // Error | Warning | Information | Hint
}
  1. Click the Source Control icon in the Activity Bar (Ctrl+Shift+G), then Initialize Repository.
     # First, one-time setup in the terminal:
     brew install git gh
     git config --global user.name "Your Name"
     git config --global user.email "you@example.com"
     git config --global init.defaultBranch
    
  2. Create a .gitignore:
        .venv/
        __pycache__/
        *.pyc
        .env
        credentials.py
        *.pkl
        *.pickle
        Backup/
        .DS_Store
    
  3. Stage all files (git add .): Changes, Stage All Changes.
  4. Commit the changes (git commit): : type a message and click ✓, Commit.
  5. Publish or push. Click Publish Branch to create a GitHub repository from VS Code, or Clone Repository and paste the URL of an existing one (you choose the parent folder).
  6. Authentication. GitHub stopped accepting account passwords for Git in August 2021. Don’t paste a token into the remote URL: it ends up in plain text in .git/config and in your shell history. The simplest option is GitHub CLI: gh auth login, choose HTTPS, and answer Y to “Authenticate Git with your GitHub credentials?”. It stores the credentials in the macOS Keychain.

Cmd+Shift+P, Snippets: Configure Snippets, then New Global Snippets file… or pick a language such as markdown.

{
    "Insert Raw HTML": {
        "prefix": "raw",
        "body": [
            "{{< raw >}}",
            "${1: markdown_content}",
            "{{< /raw >}}"
            ],
        "description": "Insert Raw HTML"
    },
    "Insert Code": {
        "prefix": "code",
        "body": [
            "``` ${1|html,python,md,bash,javascript,json|} ",
            "${2: markdown_content}",
            "```"
        ],
        "description": "Insert Code"
    },
    "Markdown link": {
        "prefix": "link",
        "body": [
            "[${1: link_text}](${2: link_url})"
        ],
        "description": "Markdown link"
    }
}

prefix defines the trigger word that display the snippet. body is one or more lines of content, and description is an optional description of the snippet.

Some snippets have placeholders, e.g. ${1:markdown_content}. Press Tab to jump to the next one. Placeholders can offer choices, e.g. ${1|html,python,md,bash,javascript,json|}: when the placeholder is selected, VS Code shows a pick list.

You can use Snippet generator to create snippets for Visual Studio Code, Sublime Text, and Atom.

  1. cd ~\macOS (macOS is where I save all my configuration files)

  2. mkdir -p "code/Library/Application Support/Code/User/snippets" where mkdir -p creates every missing folder in one go. Besides, the quotes are required because Application Support contains a space.

  3. Create (or move) your current settings into the package: code "$HOME/dotfiles/macOS/code/Library/Application Support/Code/User/snippets/markdown.json"

  4. VS Code stores language snippets as SNIPPET_LANGUAGE.json in User/snippets/. mv "$HOME/Library/Application Support/Code/User/snippets/markdown.json" "$HOME/macOS/code/Library/Application Support/Code/User/snippets/markdown.json"

  5. Dry run, then link. Always preview first. -n means “simulate”, -v means “verbose”.

    cd ~/macOS
    stow -nv --no-folding -t ~ code
    
    LINK: Library/Application Support/Code/User/settings.json => ../../../../macOS/code/Library/Application Support/Code/User/settings.json
    LINK: Library/Application Support/Code/User/snippets/markdown.json => ../../../../../macOS/code/Library/Application Support/Code/User/snippets/markdown.json
    WARNING: in simulation mode so not modifying filesystem.
    
    # No errors means it is safe. Now do it for real:
    stow -v --no-folding -t ~ code
    # where...
    # --no-folding: by default, if a whole folder doesn't exist yet, Stow links the entire folder. 
    # For Code/User, which also contains caches and workspace data, that would push VS Code's junk into your repo. 
    # With --no-folding, Stow creates real folders and links only your files.
    # -t ~: the target is your home folder.
    
    # Check
    ls -l "$HOME/Library/Application Support/Code/User/"
    [...]
    lrwxr-xr-x@  1 nmaximo7  staff   74 Oct 11 14:02 settings.json -> ../../../../macOS/code/Library/Application Support/Code/User/settings.json
    
    ls -l /Users/nmaximo7/Library/Application\ Support/Code/User/snippets/markdown.json
    lrwxr-xr-x@ 1 nmaximo7  staff  86 Oct 11 14:02 /Users/nmaximo7/Library/Application Support/Code/User/snippets/markdown.json -> ../../../../../macOS/code/Library/Application Support/Code/User/snippets/markdown.json
    
  6. The extension list. Export what is installed right now:

    cd ~/dotfiles/macOS/code
    code --list-extensions | sort > vs-code-extensions.txt
    # code --list-extensions prints one extension ID per line (publisher.name).
    # sort keeps the file stable so git diffs stay small.
    cat vs-code-extensions.txt
    
    # Problem: this file now sits inside the code package, and Stow would symlink it into ~.
    # Tell Stow to ignore it with a .stow-local-ignore file at the package root (each line is a regular expression):
    cat > .stow-local-ignore <<'EOF'
    ^/vs-code-extensions\.txt$
    ^/\.stow-local-ignore$
    EOF 
    # Re-run from ~/dotfiles/macOS (-R = restow): 
    stow -v --no-folding -t ~ -R code  
    # and check that ls -l ~/vs-code-extensions.txt says "No such file".
    
    # How you restore it on another Mac:
    xargs -L1 code --install-extension < ~/dotfiles/macOS/code/vs-code-extensions.txt
    
  7. git add . && git commit -am “my Code configuration” && git push

Start Hugo development server automatically

  1. Open a workspace, create a folder name .vscode if it does not exist.

  2. Create a file named tasks.json inside the .vscode folder.

  3. Define a custom task that will automatically run a terminal command when the workspace is opened, e.g., start the Hugo server (hugo server)

    {
    "version": "2.0.0",
    "tasks": [
        {
            // Task 1: Clean the public directory before building
            // This ensures you start with a fresh build every time
            "label": "Clean Public Directory",
            "type": "shell",
            "command": "rm",
            "args": [
                "-rf",      // Recursive force delete
                "public/"   // Hugo's output directory
            ],
            "group": {
                "kind": "build",
                "isDefault": false
            },
            "problemMatcher": [],
            "presentation": {
                "reveal": "silent",  // Don't show output for this simple task
                "panel": "shared"
            }
        },
        {
            // Task 2: Start Hugo development server
            // Runs after cleaning the public directory
            "label": "Start Hugo Server",
            "dependsOrder": "sequence",      // Run dependencies in order
            "dependsOn": "Clean Public Directory",  // First clean, then start
            "type": "shell",
            "command": "hugo",
            "args": [
                "server",
                "--disableFastRender",  // Full rebuild on changes (more reliable)
                "--bind=0.0.0.0",       // Allow access from other devices on network
                "--baseURL=dirIP:1313", // It is used to generatre absolute URL for tre site resouces, e.g., images, sitemaps, etc.
                "--poll=700ms",
                "--noBuildLock" // Don't create .hugo_build.lock file.
            ],
            "group": {
                "kind": "build",
                "isDefault": true  // This is the default build task (Ctrl+Shift+B)
            },
            "presentation": {
                "reveal": "always",          // Always show the terminal
                "panel": "dedicated",        // Use dedicated panel (better than "new")
                "showReuseMessage": false,   // Don't show reuse message
                "clear": true,               // Clear terminal before running
                "echo": true,                // Show the command being run
                "focus": false               // Don't steal focus from editor
            },
            "problemMatcher": [],
            "runOptions": {
                "runOn": "folderOpen"  // Auto-start when folder opens
            },
            "isBackground": true  // Mark as background task (keeps running)
        },
        {
            // Task 3: Build production site (no server)
            "label": "Build Production Site",
            "dependsOrder": "sequence",
            "dependsOn": "Clean Public Directory",
            "type": "shell",
            "command": "hugo",
            "args": [
                "--minify",      // Minify HTML/CSS/JS
                "--cleanDestinationDir"  // Clean destination before building
            ],
            "group": "build",
            "presentation": {
                "reveal": "always",
                "panel": "shared",
                "clear": true
            },
            "problemMatcher": []
        },
        {
            // Task 4: Stop Hugo Server
            // Useful to stop the auto-started server
            "label": "Stop Hugo Server",
            "type": "shell",
            "command": "pkill",
            "args": [
                "-f",
                "hugo server"
            ],
            "group": "none",
            "presentation": {
                "reveal": "silent",
                "panel": "shared"
            },
            "problemMatcher": []
        }
    ]
    }
    
  4. Save the configuration file and open the workspace.

  5. Add to your keybindings.json (Ctrl+Shift+P, type Open Keyboard Shortcuts):

    [
    {
        "key": "ctrl+shift+h",
        "command": "workbench.action.tasks.runTask",
        "args": "Start Hugo Server"
    },
    {
        "key": "ctrl+shift+k",
        "command": "workbench.action.tasks.runTask",
        "args": "Stop Hugo Server"
    }
    ]
    

Visual Studio Code Remote - SSH

VS Code Remote - SSH allows you to open folders on any remote machine, virtual machine, or container with a running SSH server and use the full VS Code feature set — including IntelliSense, debugging, and extensions — as if you were working locally.

While password-based authentication is supported, key-based authentication is strongly recommended for enhanced security and convenience: ssh-keygen -t rsa -b 4096 -C "your_email@example.com" / ssh-keygen -t ed25519 -C "your_email@example.com" (generate key), ssh-copy-id username@hostname (copy public key to remote server).

In Windows, ssh -i {path to private key file}\id_rsa {name}@{machine}, e.g., ssh -i C:\Users\Owner/.ssh/id_rsa {name}@{machine}.

  1. Prerequisites: A remote machine with SSH server running, VS Code installed locally, and SSH connectivity to the remote host.
  2. Install the Remote-SSH extension.
  3. In VS Code, select Remote-SSH: Connect to Host… from the Command Palette (Ctrl+Shift+P) and enter your connection string: user@hostname, e.g. nmaximo7@192.168.1.46.
    If prompted, select the platform (Linux/Windows/Mac) of the remote host. Enter your password (if using password auth) or wait for key-based authentication.
  4. Open Remote Folders. You can then open any folder or workspace on the remote machine using File, Open… or File, Open Workspace…. Navigate and select any folder on the remote machine just as you would locally.
  5. Disconnect. To close the connection when you finish editing files on the remote host, choose File, Close Remote Connection to disconnect from the host or simply close the VS Code window.
  6. If you have a set of hosts you use frequently, you can add them to a local file that follows the SSH config file format.
    Start by selecting Remote-SSH: Add New SSH Host… from the Command Palette.
    You’ll then be asked to enter the SSH connection information, e.g., ssh nmaximo7@192.168.1.46 (the full ssh command you would use to connect to the host from the command line).
    Finally, you’ll be asked to pick a config file to use, e.g., \home\nmaximo7\.ssh\config or ssh -i ~/.ssh/config yourname@dirIPAddress
    Host myserver # Alias used in VS Code (friendly name)
        HostName dirIPAddress # IP address or domain, e.g., 192.168.1.46
        User yourname # SSH username, e.g., nmaximo7
        IdentityFile ~/.ssh/id_rsa # It should point to your private key, not the config file itself.
    
  7. From this point forward, the host will appear in the list of hosts when you select Remote-SSH: Connect to Host… from the Command Palette (Ctrl+Shift+P) or in the SSH Targets section of the Remote Explorer.
  8. When using the Remote-SSH extension in VS Code, extensions installed on a local Windows machine do not automatically run on the remote (e.g., Arch Linux) environment. To get spelling correction working, you need to install a spell-checking extension directly into the remote server’s workspace via your VS Code window.
    Click the Extensions icon in the left activity bar of your VS Code window that is currently connected to your remote machine. Type ‘Code Spell Checker’ into the search bar, then click the button that says Install in SSH: [Your Hostname].

VS Code Remote-SSH settings

Edit vscode.nix (~/dotfiles/vscode.nix) as follows:

    programs.vscode = {
        userSettings = {
        [...]
            "remote.SSH.useLocalServer" = false;
            # Normally the Visual Studio Code Remote-SSH extension launches a small local helper server.
            # VS Code will connect directly via SSH, without intermediate local node process.
            "remote.SSH.defaultExtensions" = [];
            # Normally VS Code automatically installs some extensions on the remote host.
            # No extensions are auto-installed.

            "remote.SSH.remotePlatform" = {
                "myserver" = "linux";
            };
            # Host alias: myserver, platform: linux (it skips auto-detecting the OS).

            "remote.SSH.configFile" = "/home/nmaximo7/.ssh/config";
            # Use my Home-Manager generated SSH config instead of default.
            # Since I have defined programs.ssh.matchBlocks Home-Manager will generate this file automatically.

            "remote.SSH.serverInstallPath" = {
				"myserver" = "/mnt/data/justtothepoint";
			};
            # Normally VS Code installs its remote server ~/.vscode-server.
            # We override it to /mnt/data/justtothepoint

SSH configuration (Home Manager)

{ config, pkgs, ... }:
let
  username = "nmaximo7";
  dotfiles = "/home/${username}/dotfiles";
in
{
  # Enable Home Manager
  home-manager.useGlobalPkgs = true;
  home-manager.useUserPackages = true;
  home-manager.backupFileExtension = "backup";
  home-manager.users.nmaximo7 = { pkgs, ... }:
  {
    home.stateVersion = "25.05";
    [...]
    programs.ssh = {
		enable = true;
		enableDefaultConfig = false;

		matchBlocks = {
			"*" = {
				serverAliveInterval = 60;
				serverAliveCountMax = 3;
			};
			myserver = {
				hostname = "192.168.1.46";
				user = "nmaximo7";
				identityFile = "~/.ssh/id_rsa";
			};
		};
    };
    [...]
    # This generates an SSH config equivalent to:

    Host myserver
        HostName 192.168.1.46
        User nmaximo7
        IdentityFile ~/.ssh/id_rsa
Bitcoin donation

JustToThePoint Copyright © 2011 - 2026 Anawim. ALL RIGHTS RESERVED. Bilingual e-books, articles, and videos to help your child and your entire family succeed, develop a healthy lifestyle, and have a lot of fun. Social Issues, Join us.

This website uses cookies to improve your navigation experience.
By continuing, you are consenting to our use of cookies, in accordance with our Cookies Policy and Website Terms and Conditions of use.