├── .devcontainer ├── Dockerfile └── devcontainer.json ├── .dockerignore ├── .github ├── hack │ ├── Dockerfile │ ├── Dockerfile.code-server │ ├── Dockerfile.devcontainer │ └── modules └── workflows │ ├── build.yaml │ └── build.yaml.legacy ├── .vscode ├── extensions.json └── settings.json ├── CONTRIBUTING.md ├── LICENSE ├── README.md ├── docker ├── base │ └── Dockerfile ├── bin │ ├── connect │ ├── devcontainer-links │ └── entrypoint ├── code-server │ └── Dockerfile ├── docker-in-docker │ └── Dockerfile ├── extra │ └── Dockerfile ├── hugo │ └── Dockerfile ├── neovim │ └── Dockerfile ├── slim-all │ └── Dockerfile ├── slim-dotnet │ └── Dockerfile ├── slim-golang │ └── Dockerfile ├── slim-node │ └── Dockerfile ├── slim-python │ └── Dockerfile └── slim │ ├── Dockerfile │ └── rootfs │ ├── containers │ ├── containers.conf │ └── registries.conf │ ├── docker │ └── registry │ │ └── config.yml │ ├── environment │ ├── etc │ ├── ansible │ │ └── ansible.cfg │ ├── apt │ │ └── apt.conf.d │ │ │ └── 99config │ ├── containers │ │ └── registries.conf │ ├── docker │ │ └── registry │ │ │ └── config.yml │ ├── dpkg │ │ └── dpkg.cfg.d │ │ │ └── 01_noman │ ├── environment │ ├── skel │ │ ├── .Xresources │ │ ├── .actrc │ │ ├── .aws │ │ │ └── .gitkeep │ │ ├── .bash_profile │ │ ├── .bashrc │ │ ├── .config │ │ │ ├── fish │ │ │ │ ├── conf.d │ │ │ │ │ └── omf.fish │ │ │ │ ├── config.fish │ │ │ │ ├── fish_variables │ │ │ │ └── functions │ │ │ │ │ ├── cloc.fish │ │ │ │ │ ├── env.fish │ │ │ │ │ └── k.fish │ │ │ ├── k9s │ │ │ │ └── skin.yml │ │ │ └── starship.toml │ │ ├── .dir_colors │ │ ├── .docker.json │ │ ├── .kube │ │ │ └── .gitkeep │ │ ├── .local │ │ │ ├── bin │ │ │ │ └── .gitkeep │ │ │ └── share │ │ │ │ └── code-server │ │ │ │ └── User │ │ │ │ └── settings.json │ │ ├── .pulumi │ │ │ └── .gitkeep │ │ ├── .tmux.conf │ │ ├── .tmux │ │ │ ├── .gitkeep │ │ │ └── plugins │ │ │ │ └── tpm │ │ │ │ ├── .gitattributes │ │ │ │ ├── .gitignore │ │ │ │ ├── .gitmodules │ │ │ │ ├── .travis.yml │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── HOW_TO_PLUGIN.md │ │ │ │ ├── LICENSE.md │ │ │ │ ├── README.md │ │ │ │ ├── bin │ │ │ │ ├── clean_plugins │ │ │ │ ├── install_plugins │ │ │ │ └── update_plugins │ │ │ │ ├── bindings │ │ │ │ ├── clean_plugins │ │ │ │ ├── install_plugins │ │ │ │ └── update_plugins │ │ │ │ ├── docs │ │ │ │ ├── automatic_tpm_installation.md │ │ │ │ ├── changing_plugins_install_dir.md │ │ │ │ ├── how_to_create_plugin.md │ │ │ │ ├── managing_plugins_via_cmd_line.md │ │ │ │ └── tpm_not_working.md │ │ │ │ ├── lib │ │ │ │ └── tmux-test │ │ │ │ │ ├── .gitignore │ │ │ │ │ ├── .travis.yml │ │ │ │ │ ├── CHANGELOG.md │ │ │ │ │ ├── LICENSE.md │ │ │ │ │ ├── README.md │ │ │ │ │ ├── Vagrantfile │ │ │ │ │ ├── run_framework_tests │ │ │ │ │ ├── setup │ │ │ │ │ ├── tests │ │ │ │ │ ├── helpers │ │ │ │ │ │ └── helpers.sh │ │ │ │ │ ├── run_tests_in_isolation │ │ │ │ │ ├── test_basic_script_execution.sh │ │ │ │ │ ├── test_default_session_name.sh │ │ │ │ │ └── test_tmux_scripting.sh │ │ │ │ │ ├── vagrant_centos_provisioning.sh │ │ │ │ │ └── vagrant_ubuntu_provisioning.sh │ │ │ │ ├── scripts │ │ │ │ ├── check_tmux_version.sh │ │ │ │ ├── clean_plugins.sh │ │ │ │ ├── helpers │ │ │ │ │ ├── plugin_functions.sh │ │ │ │ │ ├── shell_echo_functions.sh │ │ │ │ │ ├── tmux_echo_functions.sh │ │ │ │ │ ├── tmux_utils.sh │ │ │ │ │ └── utility.sh │ │ │ │ ├── install_plugins.sh │ │ │ │ ├── source_plugins.sh │ │ │ │ ├── update_plugin.sh │ │ │ │ ├── update_plugin_prompt_handler.sh │ │ │ │ └── variables.sh │ │ │ │ ├── tests │ │ │ │ ├── expect_failed_plugin_download │ │ │ │ ├── expect_successful_clean_plugins │ │ │ │ ├── expect_successful_multiple_plugins_download │ │ │ │ ├── expect_successful_plugin_download │ │ │ │ ├── expect_successful_update_of_a_single_plugin │ │ │ │ ├── expect_successful_update_of_all_plugins │ │ │ │ ├── helpers │ │ │ │ │ └── tpm.sh │ │ │ │ ├── test_plugin_clean.sh │ │ │ │ ├── test_plugin_installation.sh │ │ │ │ ├── test_plugin_installation_legacy.sh │ │ │ │ ├── test_plugin_sourcing.sh │ │ │ │ └── test_plugin_update.sh │ │ │ │ └── tpm │ │ ├── .vim │ │ │ ├── colors │ │ │ │ ├── iceberg.vim │ │ │ │ └── molokai.vim │ │ │ └── pack │ │ │ │ └── vendor │ │ │ │ └── start │ │ │ │ └── nerdtree │ │ │ │ ├── .vintrc.yaml │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── LICENCE │ │ │ │ ├── README.markdown │ │ │ │ ├── _config.yml │ │ │ │ ├── autoload │ │ │ │ ├── nerdtree.vim │ │ │ │ └── nerdtree │ │ │ │ │ └── ui_glue.vim │ │ │ │ ├── doc │ │ │ │ ├── NERDTree.txt │ │ │ │ └── tags │ │ │ │ ├── lib │ │ │ │ └── nerdtree │ │ │ │ │ ├── bookmark.vim │ │ │ │ │ ├── creator.vim │ │ │ │ │ ├── event.vim │ │ │ │ │ ├── flag_set.vim │ │ │ │ │ ├── key_map.vim │ │ │ │ │ ├── menu_controller.vim │ │ │ │ │ ├── menu_item.vim │ │ │ │ │ ├── nerdtree.vim │ │ │ │ │ ├── notifier.vim │ │ │ │ │ ├── opener.vim │ │ │ │ │ ├── path.vim │ │ │ │ │ ├── tree_dir_node.vim │ │ │ │ │ ├── tree_file_node.vim │ │ │ │ │ └── ui.vim │ │ │ │ ├── nerdtree_plugin │ │ │ │ ├── exec_menuitem.vim │ │ │ │ ├── fs_menu.vim │ │ │ │ └── vcs.vim │ │ │ │ ├── plugin │ │ │ │ └── NERD_tree.vim │ │ │ │ ├── screenshot.png │ │ │ │ └── syntax │ │ │ │ └── nerdtree.vim │ │ ├── .vimrc │ │ └── .zshrc │ └── ssh │ │ └── sshd_config │ └── usr │ └── bin │ └── run_registry.sh └── docs └── readme_maintenance_prompt.md /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | # Description: This file is used to build the devcontainer at runtime. 2 | # Add additional dependencies below the `FROM` line as needed. 3 | 4 | #FROM ghcr.io/containercraft/devcontainer:nvim 5 | FROM ghcr.io/containercraft/devcontainer:code-server 6 | 7 | ################################################################################## 8 | # Install AWS CLI v2 9 | 10 | USER root 11 | RUN echo \ 12 | && ARCH=$(uname -m | awk '{ if ($1 == "x86_64") print "x86_64"; else if ($1 == "aarch64" || $1 == "arm64") print "aarch64"; else print "unknown" }') \ 13 | && NAME="aws" \ 14 | && PKG="awscli-exe-linux-${ARCH}.zip" \ 15 | && URL="https://awscli.amazonaws.com/${PKG}" \ 16 | && DIR="/tmp/awscli" \ 17 | && echo "---------------------------------------------------------"\ 18 | && echo "INFO[${NAME}] Installed:" \ 19 | && echo "INFO[${NAME}] Command: ${NAME}" \ 20 | && echo "INFO[${NAME}] Package: ${PKG}" \ 21 | && echo "INFO[${NAME}] Architecture: ${ARCH}" \ 22 | && echo "INFO[${NAME}] Source: ${URL}" \ 23 | && echo "---------------------------------------------------------"\ 24 | && mkdir -p ${DIR} \ 25 | && curl -L ${URL} --output ${DIR}/${PKG} \ 26 | && unzip ${DIR}/${PKG} -d ${DIR} \ 27 | && bash ${DIR}/aws/install \ 28 | && rm -rf ${DIR} \ 29 | && aws --version \ 30 | && echo 31 | USER vscode 32 | 33 | ################################################################################## 34 | # Install Poetry for Python dependency management 35 | #USER root 36 | #ENV POETRY_HOME="/usr/local" \ 37 | # PATH="${POETRY_HOME}/bin:${PATH}" 38 | # 39 | #RUN PYTHON_VERSION=$(python3 --version | cut -d' ' -f2 | cut -d'.' -f1,2) \ 40 | # && NAME="poetry" \ 41 | # && echo "---------------------------------------------------------" \ 42 | # && echo "INFO[${NAME}] Installing:" \ 43 | # && echo "INFO[${NAME}] Command: ${NAME}" \ 44 | # && echo "INFO[${NAME}] Python Version: ${PYTHON_VERSION}" \ 45 | # && echo "---------------------------------------------------------" \ 46 | # && curl -sSL https://install.python-poetry.org | python3 - \ 47 | # && chmod +x /usr/local/bin/poetry \ 48 | # && poetry config virtualenvs.in-project true \ 49 | # && poetry --version \ 50 | # && mkdir -p /home/vscode/.config/pypoetry \ 51 | # && chown -R vscode:vscode /home/vscode/.config \ 52 | # && echo 53 | # 54 | #USER vscode 55 | #RUN poetry config virtualenvs.in-project true \ 56 | # && poetry config virtualenvs.create true 57 | 58 | ################################################################################### 59 | # Install additional dependencies by extending the base image 60 | #ARG DEBIAN_FRONTEND=noninteractive 61 | #ARG APT_PACKAGES="\ 62 | #" 63 | # 64 | #RUN set -ex \ 65 | # && apt-get update \ 66 | # && apt-get install -y $APT_PACKAGES \ 67 | # && apt-get clean \ 68 | # && rm -rf /var/lib/apt/lists/* \ 69 | # && echo 70 | 71 | ################################################################################### 72 | ## Install Google Cloud SDK 73 | # 74 | #ENV CLOUDSDK_INSTALL_DIR /usr/local/gcloud/ 75 | #ENV PATH $PATH:/usr/local/gcloud/google-cloud-sdk/bin 76 | # 77 | #USER root 78 | #RUN echo \ 79 | # && export ARCH=$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "arm64") print "arm64"; else print "unknown" }') \ 80 | # && export NAME="gcloud" \ 81 | # && export TEST="${NAME} version" \ 82 | # && export PKG="google-cloud-sdk.tar.gz" \ 83 | # && export URL="https://dl.google.com/dl/cloudsdk/release/${PKG}" \ 84 | # && export DIR="/usr/local/gcloud" \ 85 | # && echo "---------------------------------------------------------"\ 86 | # && echo "INFO[${NAME}] Installed:" \ 87 | # && echo "INFO[${NAME}] Command: ${NAME}" \ 88 | # && echo "INFO[${NAME}] Package: ${PKG}" \ 89 | # && echo "INFO[${NAME}] Architecture: ${ARCH}" \ 90 | # && echo "INFO[${NAME}] Source: ${URL}" \ 91 | # && echo "---------------------------------------------------------"\ 92 | # && mkdir -p ${DIR} \ 93 | # && ${curl} ${URL} | tar xzvf - --directory ${DIR} \ 94 | # && /usr/local/gcloud/google-cloud-sdk/install.sh -q \ 95 | # && ${dir_clean} \ 96 | # && ${TEST} \ 97 | # && echo 98 | #USER vscode 99 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | // Dev Container JSON Reference: 3 | // https://containers.dev/implementors/json_reference/ 4 | "name": "zora", 5 | "remoteUser": "ubuntu", 6 | "containerUser": "ubuntu", 7 | "updateRemoteUserUID": false, 8 | "dockerFile": "Dockerfile", 9 | "postCreateCommand": "devcontainer-links", 10 | "shutdownAction": "stopContainer", 11 | "overrideCommand": false, 12 | "privileged": true, 13 | "init": true, 14 | "securityOpt": [ 15 | "seccomp=unconfined" 16 | ], 17 | "runArgs": [ 18 | "--privileged", 19 | "--network=host" 20 | ], 21 | "customizations": { 22 | "vscode": { 23 | "extensions": [] 24 | } 25 | }, 26 | "forwardPorts": [ 27 | 2222, 28 | 7681 29 | ], 30 | "workspaceMount": "source=${localWorkspaceFolder},target=/workspaces/${localWorkspaceFolderBasename},type=bind,consistency=cached", 31 | "workspaceFolder": "/workspaces/${localWorkspaceFolderBasename}", 32 | "mounts": [ 33 | "source=dind-var-lib-docker,target=/var/lib/docker,type=volume" 34 | ], 35 | "features": { 36 | "ghcr.io/devcontainers/features/docker-outside-of-docker:1": {} 37 | } 38 | } -------------------------------------------------------------------------------- /.dockerignore: -------------------------------------------------------------------------------- 1 | # Default to ignore all files 2 | * 3 | .* 4 | 5 | # Exceptions to the default ignore rules 6 | !.dockerignore 7 | !Dockerfile 8 | !rootfs 9 | !bin 10 | 11 | # Ignore Python cache files 12 | __pycache__/ 13 | *.py[cod] 14 | 15 | # Ignore virtual environments 16 | .env 17 | .venv 18 | env/ 19 | venv/ 20 | 21 | # Ignore temporary and backup files 22 | *.bak 23 | *.swp 24 | *.state 25 | 26 | # Ignore development environment configurations 27 | .vscode/ 28 | .idea/ 29 | 30 | # Ignore logs and databases 31 | *.log 32 | *.sqlite 33 | 34 | # Ignore OS generated files 35 | .DS_Store 36 | Thumbs.db 37 | 38 | # Ignore any sensitive files containing secrets or credentials 39 | *.secrets 40 | 41 | # Ignore build artifacts for containerization (if any) 42 | build/ 43 | local 44 | -------------------------------------------------------------------------------- /.github/hack/Dockerfile.code-server: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Add VSCode code-server to the Konductor Container Image 3 | ############################################################################### 4 | # Base Konductor Image 5 | FROM ghcr.io/containercraft/konductor:latest 6 | 7 | # Install VSCode Service 8 | EXPOSE 8080 9 | RUN set -ex \ 10 | && export arch=$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "aarch64") print "arm64"; else print "unknown" }') \ 11 | && export varVerCode=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest | awk -F '["v,]' '/tag_name/{print $5}') \ 12 | && curl --output /tmp/code-server.deb -L "https://github.com/coder/code-server/releases/download/v${varVerCode}/code-server_${varVerCode}_${arch}.deb" \ 13 | && sudo apt-get update \ 14 | && sudo apt-get install -y /tmp/code-server.deb \ 15 | && sudo apt-get clean \ 16 | && sudo apt-get autoremove -y \ 17 | && sudo apt-get purge -y --auto-remove \ 18 | && sudo rm -rf \ 19 | /var/lib/{apt,dpkg,cache,log} \ 20 | /usr/share/{doc,man,locale} \ 21 | /var/cache/apt \ 22 | /root/.cache \ 23 | /var/tmp/* \ 24 | /tmp/* \ 25 | && true 26 | 27 | # Install VSCode Extension Plugins 28 | ARG CODE_PKGS="\ 29 | golang.go \ 30 | vscodevim.vim \ 31 | github.copilot \ 32 | ms-python.python \ 33 | redhat.vscode-yaml \ 34 | esbenp.prettier-vscode \ 35 | oderwat.indent-rainbow \ 36 | ms-vscode.makefile-tools \ 37 | ms-azuretools.vscode-docker \ 38 | zhuangtongfa.Material-theme \ 39 | github.vscode-pull-request-github \ 40 | ms-vscode-remote.remote-containers \ 41 | visualstudioexptteam.vscodeintellicode \ 42 | bierner.markdown-preview-github-styles \ 43 | ms-kubernetes-tools.vscode-kubernetes-tools \ 44 | " 45 | RUN set -ex \ 46 | && for pkg in ${CODE_PKGS}; do code-server --install-extension ${pkg}; echo "Installed: ${pkg}"; done \ 47 | && true 48 | 49 | # Install OpenSSH Server 50 | EXPOSE 2222 51 | ARG APT_PKGS="\ 52 | openssh-server \ 53 | " 54 | RUN set -ex \ 55 | && sudo apt-get update \ 56 | && TERM=linux DEBIAN_FRONTEND=noninteractive \ 57 | sudo apt-get install \ 58 | --yes -q \ 59 | --force-yes \ 60 | -o Dpkg::Options::="--force-confdef" \ 61 | -o Dpkg::Options::="--force-confold" \ 62 | ${APT_PKGS} \ 63 | && sudo apt-get clean \ 64 | && sudo apt-get autoremove -y \ 65 | && sudo apt-get purge -y --auto-remove \ 66 | && sudo rm -rf \ 67 | /var/lib/{apt,dpkg,cache,log} \ 68 | /usr/share/{doc,man,locale} \ 69 | /var/cache/apt \ 70 | /root/.cache \ 71 | /var/tmp/* \ 72 | /tmp/* \ 73 | && true 74 | -------------------------------------------------------------------------------- /.github/hack/modules: -------------------------------------------------------------------------------- 1 | [submodule "rootfs/etc/skel/.tmux/plugins/tpm"] 2 | path = rootfs/etc/skel/.tmux/plugins/tpm 3 | url = https://github.com/tmux-plugins/tpm 4 | [submodule "rootfs/etc/skel/.vim/bundle/Vundle.vim"] 5 | path = rootfs/etc/skel/.vim/bundle/Vundle.vim 6 | url = https://github.com/VundleVim/Vundle.vim.git 7 | -------------------------------------------------------------------------------- /.github/workflows/build.yaml.legacy: -------------------------------------------------------------------------------- 1 | ################################################################################## 2 | # References: 3 | # Built-in arguments: 4 | # - https://docs.github.com/en/actions/learn-github-actions/contexts 5 | # Built-in environment variables: 6 | # - https://docs.github.com/en/enterprise-cloud@latest/actions/learn-github-actions/variables#default-environment-variables 7 | # 8 | # Develop this workflow locally with the following command: 9 | # ~$ gh extension install nektos/gh-act 10 | # ~$ gh act --env-file .env -s GITHUB_TOKEN=$GITHUB_TOKEN -s PULUMI_ACCESS_TOKEN=$PULUMI_ACCESS_TOKEN 11 | 12 | name: Build Konductor Devcontainer 13 | on: 14 | workflow_dispatch: 15 | push: 16 | branches: 17 | - main 18 | paths-ignore: 19 | - "Makefile" 20 | - ".devcontainer/**" 21 | - ".pulumi/**" 22 | - ".talos/**" 23 | - ".kube/**" 24 | - "docs/**" 25 | - "**.md" 26 | pull_request: 27 | paths-ignore: 28 | - "Makefile" 29 | - ".devcontainer/**" 30 | - ".pulumi/**" 31 | - ".talos/**" 32 | - ".kube/**" 33 | - "docs/**" 34 | - "**.md" 35 | branches: 36 | - main 37 | schedule: 38 | - cron: "0 2 * * *" # Daily at 2am UTC 39 | 40 | jobs: 41 | build-konductor: 42 | runs-on: ubuntu-latest 43 | permissions: 44 | contents: read 45 | packages: write 46 | actions: write 47 | 48 | steps: 49 | - name: Git Checkout 50 | uses: actions/checkout@v4 51 | id: git-checkout 52 | with: 53 | ref: "main" 54 | submodules: "shallow" 55 | 56 | - name: Set up QEMU 57 | uses: docker/setup-qemu-action@v3 58 | id: qemu 59 | 60 | - name: Install Docker Buildx 61 | uses: docker/setup-buildx-action@v3 62 | id: docker-buildx 63 | 64 | - name: repository_owner to lower case 65 | uses: Entepotenz/change-string-case-action-min-dependencies@v1 66 | id: string-owner-to-lower 67 | with: 68 | string: ${{ github.repository_owner }} 69 | 70 | - name: Transform repository name to lower case 71 | uses: Entepotenz/change-string-case-action-min-dependencies@v1 72 | id: string-repository-to-lower 73 | with: 74 | string: ${{ github.repository }} 75 | 76 | - name: Github Container Registry Login 77 | id: docker-login 78 | if: ${{ github.event_name == 'push' }} && ${{ github.ref == 'refs/heads/main' }} 79 | run: | 80 | echo ${{ secrets.GHA_GITHUB_TOKEN }} | docker login ghcr.io -u usrbinkat --password-stdin 81 | 82 | # - name: Build Konductor Container Image 83 | # uses: docker/build-push-action@v5 84 | # id: docker-build-cache 85 | # if: github.event_name == 'pull_request' || (github.event_name == 'push' && github.ref != 'refs/heads/main') 86 | # with: 87 | # push: false 88 | # cache-from: | 89 | # type=registry,ref=ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:build-cache 90 | # type=registry,ref=ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:latest 91 | # cache-to: type=inline,mode=max 92 | # context: .github/devcontainer/docker 93 | # file: .github/devcontainer/docker/Dockerfile 94 | # platforms: linux/amd64,linux/arm64 95 | # tags: "ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:latest,ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:${{ github.sha }}" 96 | 97 | - name: Publish Konductor Container Image 98 | uses: docker/build-push-action@v5 99 | id: docker-build-push 100 | #if: github.event_name == 'push' && github.ref == 'refs/heads/main' 101 | with: 102 | push: true 103 | context: .github/docker 104 | file: .github/docker/Dockerfile 105 | platforms: linux/amd64,linux/arm64 106 | tags: "ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:latest,ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:${{ github.sha }}" 107 | #cache-from: | 108 | # type=registry,ref=ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:build-cache 109 | # type=registry,ref=ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:latest 110 | #cache-to: type=registry,ref=ghcr.io/${{ steps.string-repository-to-lower.outputs.lowercase }}:build-cache,mode=max 111 | 112 | - name: Cleanup 113 | id: make-clean-all 114 | if: always() 115 | run: make clean-all 116 | env: 117 | PULUMI_ACCESS_TOKEN: ${{ secrets.PULUMI_ACCESS_TOKEN }} 118 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} 119 | -------------------------------------------------------------------------------- /.vscode/extensions.json: -------------------------------------------------------------------------------- 1 | { 2 | "recommendations": [ 3 | "vscodevim.vim", 4 | "github.copilot", 5 | "stateful.runme", 6 | "ms-python.python", 7 | "redhat.vscode-yaml", 8 | "esbenp.prettier-vscode", 9 | "oderwat.indent-rainbow", 10 | "ms-python.black-formatter", 11 | "okteto.kubernetes-context", 12 | "pulumi.pulumi-vscode-tools", 13 | "ms-vsliveshare.vsliveshare", 14 | "ms-azuretools.vscode-docker", 15 | "ms-vscode-remote.remote-containers", 16 | "ms-kubernetes-tools.vscode-kubernetes-tools", 17 | "daltonmenezes.aura-theme", 18 | "endormi.2077-theme", 19 | ], 20 | "unwantedRecommendations": [] 21 | } 22 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "workbench.colorTheme": "Aura Soft Dark", 3 | "workbench.remoteIndicator.showExtensionRecommendations": true, 4 | "editor.fontFamily": "JetBrains Mono", 5 | "editor.fontSize": 14, 6 | "editor.formatOnSave": false, 7 | "cSpell.words": [ 8 | "Zora" 9 | ], 10 | } 11 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # Contributing to ContainerCraft Devcontainer 2 | 3 | We appreciate your interest in contributing to the ContainerCraft Devcontainer project! Your contributions help improve the project for everyone. This document outlines the guidelines for contributing to the project. 4 | 5 | ## Table of Contents 6 | 7 | - [Getting Started](#getting-started) 8 | - [Prerequisites](#prerequisites) 9 | - [Setting Up the Development Environment](#setting-up-the-development-environment) 10 | - [How to Contribute](#how-to-contribute) 11 | - [Reporting Issues](#reporting-issues) 12 | - [Suggesting Enhancements](#suggesting-enhancements) 13 | - [Submitting Pull Requests](#submitting-pull-requests) 14 | - [Coding Standards](#coding-standards) 15 | - [Commit Messages](#commit-messages) 16 | - [Code Style](#code-style) 17 | - [Code of Conduct](#code-of-conduct) 18 | - [License](#license) 19 | 20 | --- 21 | 22 | ## Getting Started 23 | 24 | ### Prerequisites 25 | 26 | - **Docker**: Ensure you have [Docker](https://www.docker.com/get-started) installed on your machine. 27 | - **Git**: Install [Git](https://git-scm.com/downloads) for version control. 28 | - **VSCode (Optional)**: For development with Visual Studio Code, install [VSCode](https://code.visualstudio.com/). 29 | 30 | ### Setting Up the Development Environment 31 | 32 | 1. **Fork the Repository**: Click on the "Fork" button on the project's GitHub page to create a copy in your GitHub account. 33 | 34 | 2. **Clone the Repository**: 35 | 36 | ```bash 37 | git clone https://github.com/your-username/devcontainer.git 38 | cd devcontainer 39 | ``` 40 | 41 | 3. **Build the Docker Image**: 42 | 43 | ```bash 44 | docker build -t devcontainer:local -f docker/slim/Dockerfile ./docker 45 | ``` 46 | 47 | 4. **Run the Container**: 48 | 49 | ```bash 50 | docker run -it --rm \ 51 | --name devcontainer \ 52 | --hostname devcontainer \ 53 | --entrypoint bash \ 54 | devcontainer:local 55 | ``` 56 | 57 | ## How to Contribute 58 | 59 | ### Reporting Issues 60 | 61 | If you encounter any bugs or have suggestions for improvements, please open an issue on GitHub: 62 | 63 | - Navigate to the [Issues](https://github.com/containercraft/devcontainer/issues) tab. 64 | - Click on **New Issue**. 65 | - Provide a clear and descriptive title. 66 | - Include steps to reproduce the issue, if applicable. 67 | 68 | ### Suggesting Enhancements 69 | 70 | We welcome feature requests and ideas to improve the project: 71 | 72 | - Open an issue with the label `enhancement`. 73 | - Describe the feature, its benefits, and any implementation ideas. 74 | 75 | ### Submitting Pull Requests 76 | 77 | 1. **Create a Branch**: 78 | 79 | ```bash 80 | git checkout -b feature/your-feature-name 81 | ``` 82 | 83 | 2. **Make Changes**: Implement your changes, adhering to the coding standards outlined below. 84 | 85 | 3. **Commit Changes**: 86 | 87 | ```bash 88 | git add . 89 | git commit -m "feat: description of the feature" 90 | ``` 91 | 92 | 4. **Push to Your Fork**: 93 | 94 | ```bash 95 | git push origin feature/your-username/your-feature-name 96 | ``` 97 | 98 | 5. **Open a Pull Request**: 99 | 100 | - Go to the original repository on GitHub. 101 | - Click on **Pull Requests** and then **New Pull Request**. 102 | - Select your branch and submit the pull request. 103 | 104 | ## Coding Standards 105 | 106 | ### Commit Messages 107 | 108 | - Use clear and descriptive commit messages. 109 | - Follow the [Conventional Commits](https://www.conventionalcommits.org/) specification. 110 | 111 | Examples: 112 | 113 | - `feat: add support for Python 3.9` 114 | - `fix: resolve issue with Docker build on arm64` 115 | - `docs: update README with new usage instructions` 116 | 117 | ### Code Style 118 | 119 | - **Dockerfiles**: Follow best practices for writing Dockerfiles. 120 | - Use multi-stage builds where appropriate. 121 | - Minimize the number of layers. 122 | - Clear cache and temporary files to reduce image size. 123 | - **Shell Scripts**: 124 | - Use `#!/bin/bash` shebang. 125 | - Ensure scripts are executable (`chmod +x script.sh`). 126 | - Handle errors gracefully and use `set -e` where appropriate. 127 | 128 | ## Code of Conduct 129 | 130 | We are committed to fostering a welcoming and respectful community. Please read our [Code of Conduct](CODE_OF_CONDUCT.md) before participating. 131 | 132 | ## License 133 | 134 | By contributing to the ContainerCraft Devcontainer project, you agree that your contributions will be licensed under the [Adaptive Public License Version 1.0](LICENSE). 135 | -------------------------------------------------------------------------------- /docker/bin/connect: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -u 3 | 4 | # Default values 5 | SESSION_NAME="konductor" 6 | ENV_FILE="${HOME}/.env" 7 | 8 | # Parse command-line arguments 9 | while [[ $# -gt 0 ]]; do 10 | case "$1" in 11 | -s|--session) 12 | SESSION_NAME="$2" 13 | shift 2 14 | ;; 15 | -e|--env-file) 16 | ENV_FILE="$2" 17 | shift 2 18 | ;; 19 | -h|--help) 20 | cat < "${ENV_FILE}" || true 39 | chmod 600 "${ENV_FILE}" || true 40 | 41 | # Create tmux session if it doesn't exist 42 | if ! tmux has-session -t "$SESSION_NAME" 2>/dev/null; then 43 | tmux new-session -d -s "$SESSION_NAME" || true 44 | # Quietly source the environment file in the new session 45 | tmux send-keys -t "$SESSION_NAME" "source ${ENV_FILE} >/dev/null 2>&1" C-m || true 46 | fi 47 | 48 | # Attach to the tmux session 49 | tmux attach -t "$SESSION_NAME" 50 | -------------------------------------------------------------------------------- /docker/bin/devcontainer-links: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Change ownership of all items in /workspaces to the current user 4 | user="$(id -u)" 5 | 6 | # Iterate over directories in /workspaces 7 | run_links() { 8 | 9 | sudo chown "${user}" /workspaces/* 2>/dev/null 10 | 11 | for dir in /workspaces/*; do 12 | # Check if it's a directory 13 | if [[ -d "${dir}" ]]; then 14 | # Extract the directory name 15 | dir_name=$(basename "${dir}") 16 | 17 | # Check if a symlink already exists in the home directory 18 | if [[ -L "${HOME}/${dir_name}" ]]; then 19 | # Remove the existing symlink if it exists 20 | rm "${HOME}/${dir_name}" 21 | elif [[ -e "${HOME}/${dir_name}" ]]; then 22 | # Skip if it's not a symlink (to avoid destructive actions on actual directories or files) 23 | echo "Skipping ${HOME}/${dir_name}, as it's not a symlink." 24 | continue 25 | fi 26 | 27 | # Create a new symbolic link 28 | ln -s "${dir}" "${HOME}/${dir_name}" 29 | fi 30 | done 31 | } 32 | 33 | run_links 2>/dev/null || true 34 | 35 | # Allow direnv to set environment variables 36 | direnv allow 2>/dev/null || true 37 | -------------------------------------------------------------------------------- /docker/bin/entrypoint: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Debug configuration 4 | DEBUG=${DEBUG:-0} # Default to debug off 5 | [[ $DEBUG -eq 1 ]] && set -x 6 | 7 | # Log to both stdout and /tmp/konductor.log 8 | exec > >(tee -a /tmp/konductor.log) 2>&1 9 | 10 | ################################################################################# 11 | # Preliminary User Setup 12 | ################################################################################# 13 | # If running as root, set USER to "ubuntu"; otherwise, default to the current user. 14 | if [ "$(whoami)" = "root" ]; then 15 | USER="ubuntu" 16 | else 17 | USER="${USER:-$(whoami)}" 18 | fi 19 | 20 | # Determine the user's home directory (using getent when available) 21 | USER_HOME=$(getent passwd "${USER}" | cut -d: -f6) 22 | if [ -z "${USER_HOME}" ]; then 23 | USER_HOME="/home/${USER}" 24 | fi 25 | 26 | ################################################################################# 27 | # Configuration 28 | ################################################################################# 29 | readonly DIR_PLATFORM=".platform" 30 | readonly SSH_HOST_IDENTITY_PATH="${USER_HOME}/${DIR_PLATFORM}/secrets/ssh/host" 31 | readonly SSH_USER_IDENTITY_PATH="${USER_HOME}/${DIR_PLATFORM}/secrets/ssh/user" 32 | readonly ENV_FILE="${USER_HOME}/.env" 33 | readonly SSH_KEY_TYPES=("ecdsa" "rsa" "ed25519") 34 | readonly CHECK_INTERVAL=15 35 | 36 | ################################################################################# 37 | # Helper Functions 38 | ################################################################################# 39 | 40 | log() { 41 | echo "[$(date +'%Y-%m-%d %H:%M:%S')] $1" 42 | } 43 | 44 | debug() { 45 | [[ $DEBUG -eq 1 ]] && log "DEBUG: $1" 46 | } 47 | 48 | error() { 49 | log "ERROR: $1" 50 | } 51 | 52 | setup_user() { 53 | # We already set USER and USER_HOME above. Now verify the user exists. 54 | if [ -z "${USER}" ] || ! id "${USER}" >/dev/null 2>&1; then 55 | error "User ${USER} not found" 56 | return 1 57 | fi 58 | 59 | log "Running as user: ${USER} (current: $(whoami))" 60 | 61 | # Ensure tmux directory exists with correct permissions 62 | local tmux_dir="/tmp/tmux-$(id -u "${USER}")" 63 | mkdir -p "${tmux_dir}" 64 | chmod 700 "${tmux_dir}" 65 | chown "${USER}:${USER}" "${tmux_dir}" 66 | } 67 | 68 | save_environment() { 69 | log "Saving environment variables to ${ENV_FILE}" 70 | mkdir -p "$(dirname "${ENV_FILE}")" 71 | # Filter out session-specific and potentially sensitive variables 72 | env | grep -Ev '^(_=|PWD=|SHLVL=|SHELL=|HOME=|SSH_|AWS_|GITHUB_TOKEN)' >"${ENV_FILE}" 73 | chmod 600 "${ENV_FILE}" 74 | chown "${USER}:${USER}" "${ENV_FILE}" 2>/dev/null || true 75 | } 76 | 77 | ################################################################################# 78 | # SSH Functions 79 | ################################################################################# 80 | 81 | create_ssh_directories() { 82 | for dir in "${SSH_HOST_IDENTITY_PATH}" "${SSH_USER_IDENTITY_PATH}" "/var/run/sshd"; do 83 | mkdir -p "${dir}" 84 | chmod 0700 "${dir}" 2>/dev/null || true 85 | done 86 | } 87 | 88 | generate_ssh_host_key() { 89 | local key_type="$1" 90 | local key_file="${SSH_HOST_IDENTITY_PATH}/ssh_host_${key_type}_key" 91 | 92 | if [ ! -f "${key_file}" ]; then 93 | sudo ssh-keygen -q -t "$key_type" -f "$key_file" -C '' -N '' || true 94 | fi 95 | } 96 | 97 | setup_host_ssh_identity() { 98 | mkdir -p "${SSH_HOST_IDENTITY_PATH}" 99 | 100 | for key_type in "${SSH_KEY_TYPES[@]}"; do 101 | generate_ssh_host_key "$key_type" 102 | done 103 | 104 | if [ -d "${SSH_HOST_IDENTITY_PATH}" ] && [ "$(ls -A "${SSH_HOST_IDENTITY_PATH}" 2>/dev/null)" ]; then 105 | sudo cp -rf "${SSH_HOST_IDENTITY_PATH}"/* /etc/ssh/ 106 | sudo chmod 600 /etc/ssh/ssh_host_*_key 107 | sudo chmod 644 /etc/ssh/ssh_host_*_key.pub 108 | fi 109 | } 110 | 111 | setup_user_ssh() { 112 | local ssh_dir="${USER_HOME}/.ssh" 113 | local ssh_key_file="${ssh_dir}/id_rsa" 114 | 115 | mkdir -p "${ssh_dir}" 116 | chmod 700 "${ssh_dir}" 117 | chown "${USER}:${USER}" "${ssh_dir}" 2>/dev/null || true 118 | 119 | if [ ! -f "${ssh_key_file}" ]; then 120 | sudo -u "${USER}" ssh-keygen -t rsa -b 4096 -f "${ssh_key_file}" -q -N "" 121 | chmod 600 "${ssh_key_file}" 122 | chmod 644 "${ssh_key_file}.pub" 123 | chown "${USER}:${USER}" "${ssh_key_file}"* 2>/dev/null || true 124 | fi 125 | 126 | if [ -n "${GITHUB_USER:-}" ]; then 127 | local keys_fetched=false 128 | for i in {1..3}; do 129 | if curl -sL --connect-timeout 5 "https://github.com/${GITHUB_USER}.keys" >"${ssh_dir}/authorized_keys"; then 130 | keys_fetched=true 131 | break 132 | fi 133 | sleep 2 134 | done 135 | if ! $keys_fetched; then 136 | error "Failed to fetch GitHub keys for ${GITHUB_USER} after 3 attempts" 137 | fi 138 | chmod 600 "${ssh_dir}/authorized_keys" 139 | chown "${USER}:${USER}" "${ssh_dir}/authorized_keys" 2>/dev/null || true 140 | fi 141 | } 142 | 143 | ################################################################################# 144 | # Service Functions 145 | ################################################################################# 146 | 147 | start_sshd() { 148 | create_ssh_directories 149 | setup_host_ssh_identity 150 | sudo /usr/sbin/sshd -e -f /etc/ssh/sshd_config || true 151 | } 152 | 153 | manage_tmux_session() { 154 | local session_name="${1:-konductor}" 155 | 156 | create_tmux_session() { 157 | log "Creating new tmux session: ${session_name}" 158 | tmux new-session -d -s "${session_name}" || true 159 | log "Created tmux session: ${session_name}" 160 | } 161 | 162 | # Ensure the session exists at startup. 163 | if ! tmux has-session -t "${session_name}" 2>/dev/null; then 164 | create_tmux_session 165 | fi 166 | 167 | # Loop forever, re‑creating the session if it goes away. 168 | while :; do 169 | if ! tmux has-session -t "${session_name}" 2>/dev/null; then 170 | log "Session ${session_name} is no longer active, recreating." 171 | create_tmux_session 172 | else 173 | debug "Session ${session_name} is still active." 174 | fi 175 | sleep "${CHECK_INTERVAL}" || true 176 | done 177 | } 178 | 179 | start_ttyd() { 180 | if command -v ttyd >/dev/null 2>&1; then 181 | while :; do 182 | if ! pgrep ttyd >/dev/null; then 183 | ttyd --writable -t fontFamily=monospace connect 2>/dev/null & 184 | fi 185 | sleep "${CHECK_INTERVAL}" || true 186 | done 187 | fi 188 | } 189 | 190 | cleanup() { 191 | pkill -P $$ 2>/dev/null || true 192 | pkill ttyd 2>/dev/null || true 193 | } 194 | 195 | ################################################################################# 196 | # Main 197 | ################################################################################# 198 | 199 | main() { 200 | trap cleanup EXIT INT TERM 201 | 202 | # Core Initialization 203 | setup_user || true 204 | save_environment || true 205 | start_sshd || true 206 | setup_user_ssh || true 207 | 208 | # Start background services. 209 | start_ttyd & 210 | manage_tmux_session "konductor" & 211 | 212 | log "Container initialization complete." 213 | 214 | sleep infinity 215 | } 216 | 217 | main "$@" 218 | -------------------------------------------------------------------------------- /docker/code-server/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/containercraft/devcontainer:code-server -f docker/code-server/Dockerfile ./docker 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer --entrypoint bash ghcr.io/containercraft/devcontainer:code-server 5 | ############################################################################### 6 | FROM ghcr.io/containercraft/devcontainer:nvim 7 | LABEL tag="code-server" 8 | ENV DEVCONTAINER="code-server" 9 | 10 | # Install VSCode Service 11 | EXPOSE 8080 12 | RUN set -ex \ 13 | && export arch=$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "aarch64") print "arm64"; else print "unknown" }') \ 14 | && export varVerCode=$(curl -s https://api.github.com/repos/coder/code-server/releases/latest | awk -F '["v,]' '/tag_name/{print $5}') \ 15 | && curl --output /tmp/code-server.deb -L "https://github.com/coder/code-server/releases/download/v${varVerCode}/code-server_${varVerCode}_${arch}.deb" \ 16 | && sudo apt-get update \ 17 | && sudo apt-get install -y /tmp/code-server.deb \ 18 | && sudo apt-get clean \ 19 | && sudo apt-get autoremove -y \ 20 | && sudo apt-get purge -y --auto-remove \ 21 | && sudo rm -rf \ 22 | /var/lib/{apt,cache,log} \ 23 | /usr/share/{doc,man,locale} \ 24 | /etc/apt/sources.list.d/nodesource.list \ 25 | /var/cache/apt \ 26 | /root/.cache \ 27 | /var/tmp/* \ 28 | /tmp/* \ 29 | && true 30 | 31 | # Install VSCode Extension Plugins 32 | ARG CODE_PKGS="\ 33 | vscodevim.vim \ 34 | stateful.runme \ 35 | max-ss.cyberpunk \ 36 | ms-python.python \ 37 | esbenp.prettier-vscode \ 38 | oderwat.indent-rainbow \ 39 | ms-vsliveshare.vsliveshare \ 40 | ms-azuretools.vscode-docker \ 41 | github.vscode-github-actions \ 42 | github.vscode-pull-request-github \ 43 | ms-vscode-remote.remote-containers \ 44 | randomfractalsinc.vscode-data-table \ 45 | " 46 | 47 | RUN set -ex \ 48 | && for pkg in ${CODE_PKGS}; do code-server --install-extension ${pkg}; echo "Installed: ${pkg}"; done \ 49 | && true 50 | 51 | RUN set -ex \ 52 | && sudo rm -rf /var/lib/apt/lists/* \ 53 | && sudo mkdir -p /var/lib/apt/lists/partial \ 54 | && sudo chmod 755 /var/lib/apt/lists/partial \ 55 | && sudo apt-get clean \ 56 | && sudo apt-get update \ 57 | && true 58 | -------------------------------------------------------------------------------- /docker/docker-in-docker/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:dind -f docker/docker-in-docker/Dockerfile ./docker 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:dind 5 | ############################################################################### 6 | FROM ghcr.io/containercraft/devcontainer:base 7 | LABEL tag="dind" 8 | ENV DEVCONTAINER="dind" 9 | 10 | ################################################################################# 11 | # Base package and user configuration 12 | ################################################################################# 13 | 14 | # devcontainer docker-in-docker dependencies 15 | ARG APT_PKGS="\ 16 | docker-buildx-plugin \ 17 | docker-ce-cli \ 18 | libffi-dev \ 19 | iptables \ 20 | " 21 | RUN echo \ 22 | && ${curl} https://download.docker.com/linux/ubuntu/gpg | sudo gpg --batch --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg \ 23 | && echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list \ 24 | && ${apt_update} \ 25 | && bash -c "${apt_install} ${APT_PKGS}" \ 26 | && bash -c "${apt_clean}" \ 27 | && ${dir_clean} \ 28 | && sudo update-alternatives --set iptables /usr/sbin/iptables-legacy \ 29 | && sudo update-alternatives --set ip6tables /usr/sbin/ip6tables-legacy \ 30 | && echo 31 | 32 | # Install Kind Kubernetes-in-Docker 33 | RUN echo \ 34 | && export NAME=kind \ 35 | && export TEST="${NAME} version" \ 36 | && export REPOSITORY="kubernetes-sigs/kind" \ 37 | && export VERSION="$(${curl} https://api.github.com/repos/${REPOSITORY}/releases/latest | jq --raw-output .tag_name)" \ 38 | && export ARCH="$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "arm64") print "arm64"; else print "unknown" }')" \ 39 | && export PKG="${NAME}-linux-${ARCH}" \ 40 | && export URL="https://github.com/${REPOSITORY}/releases/download/${VERSION}/${PKG}" \ 41 | && echo "---------------------------------------------------------"\ 42 | && echo "INFO[${NAME}] Installed:" \ 43 | && echo "INFO[${NAME}] Command: ${NAME}" \ 44 | && echo "INFO[${NAME}] Package: ${PKG}" \ 45 | && echo "INFO[${NAME}] Latest Release: ${VERSION}" \ 46 | && echo "INFO[${NAME}] Architecture: ${ARCH}" \ 47 | && echo "INFO[${NAME}] Source: ${URL}" \ 48 | && echo "---------------------------------------------------------"\ 49 | && ${curl} ${URL} --output /tmp/${NAME} \ 50 | && sudo ${INSTALL} /tmp/${NAME} ${BIN}/${NAME} \ 51 | && ${dir_clean} \ 52 | && ${TEST} \ 53 | && echo 54 | -------------------------------------------------------------------------------- /docker/hugo/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:hugo . 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:hugo 5 | ############################################################################### 6 | # Based from the Pulumi Devcontainer SLIM image. 7 | FROM ghcr.io/containercraft/devcontainer:slim-all 8 | 9 | ################################################################################# 10 | # Image Metadata 11 | ################################################################################# 12 | LABEL tag="hugo" 13 | 14 | # Apt Packages 15 | ARG APT_PKGS="\ 16 | chromium-browser \ 17 | " 18 | # Apt Packages 19 | RUN echo \ 20 | && export TEST="gh version" \ 21 | && ${apt_update} \ 22 | && bash -c "${apt_install} --no-install-recommends -o Dpkg::Options::='--force-confold' ${APT_PKGS}" \ 23 | && bash -c "${apt_clean}" \ 24 | && ${dir_clean} \ 25 | && ${TEST} \ 26 | && echo 27 | 28 | # Install hugo 29 | EXPOSE 1313 30 | RUN set -ex \ 31 | && export arch=$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "arm64") print "arm64"; else print "unknown" }') \ 32 | && export urlHugoRelease="https://api.github.com/repos/gohugoio/hugo/releases/latest" \ 33 | && export urlHugoVersion=$(curl -s ${urlHugoRelease} | awk -F '["v,]' '/tag_name/{print $5}') \ 34 | && export urlHugoBase="https://github.com/gohugoio/hugo/releases/download" \ 35 | && export urlHugoBin="hugo_${urlHugoVersion}_linux-${arch}.deb" \ 36 | && export urlHugo="${urlHugoBase}/v${urlHugoVersion}/${urlHugoBin}" \ 37 | && curl --output /tmp/${urlHugoBin} -L ${urlHugo} \ 38 | && sudo dpkg -i /tmp/${urlHugoBin} \ 39 | && which hugo \ 40 | && hugo version \ 41 | && rm -rf /tmp/* \ 42 | && true 43 | -------------------------------------------------------------------------------- /docker/slim-all/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:slim-all -f docker/slim-all/Dockerfile ./docker 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:slim-all 5 | ############################################################################### 6 | # Base Image 7 | FROM ghcr.io/containercraft/devcontainer:slim 8 | LABEL tag="slim-all" 9 | ENV DEVCONTAINER="slim-all" 10 | 11 | ################################################################################# 12 | # Install Programming Language Tooling 13 | # - python 14 | ################################################################################# 15 | # Python 16 | ARG APT_PKGS="\ 17 | direnv \ 18 | python3 \ 19 | python3-dev \ 20 | python3-venv \ 21 | python3-dotenv \ 22 | python3.12 \ 23 | python3.12-venv \ 24 | python3.12-dev \ 25 | python3-pip \ 26 | " 27 | RUN echo \ 28 | && bash -c "${apt_update}" \ 29 | && bash -c "${apt_install} ${APT_PKGS}" \ 30 | && bash -c "${apt_clean}" \ 31 | && sudo update-alternatives --install \ 32 | /usr/bin/python python \ 33 | /usr/bin/python3 1 \ 34 | && ${dir_clean} \ 35 | && echo 36 | 37 | # Python Pip Packages 38 | #ARG PIP_PKGS="\ 39 | # setuptools \ 40 | # " 41 | #RUN echo \ 42 | # && sudo python3 -m pip install ${PIP_PKGS} \ 43 | # && ${dir_clean} \ 44 | # && echo 45 | 46 | # Install Poetry for Python dependency management 47 | ENV POETRY_HOME="/usr/local" 48 | ENV PATH="/usr/local/bin:${PATH}" 49 | 50 | USER root 51 | RUN PYTHON_VERSION=$(python3 --version | cut -d' ' -f2 | cut -d'.' -f1,2) \ 52 | && NAME="poetry" \ 53 | && echo "---------------------------------------------------------" \ 54 | && echo "INFO[${NAME}] Installing:" \ 55 | && echo "INFO[${NAME}] Command: ${NAME}" \ 56 | && echo "INFO[${NAME}] Python Version: ${PYTHON_VERSION}" \ 57 | && echo "---------------------------------------------------------" \ 58 | && curl -sSL https://install.python-poetry.org | python3 - \ 59 | && chmod +x /usr/local/bin/poetry \ 60 | && poetry config virtualenvs.in-project true \ 61 | && poetry --version \ 62 | && mkdir -p \ 63 | /home/ubuntu/.config/pypoetry \ 64 | /etc/skel/.config/pypoetry \ 65 | && chown -R ubuntu:ubuntu /home/ubuntu/.config \ 66 | && echo 67 | USER ubuntu 68 | 69 | ################################################################################## 70 | # Golang 71 | RUN echo ;set -ex \ 72 | && jq --version \ 73 | && export NAME="go" \ 74 | && export TEST="${NAME} version" \ 75 | && export VERSION="$(${curl} "https://go.dev/dl/?mode=json" | jq --compact-output --raw-output .[1].version)" \ 76 | && export ARCH=$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "arm64") print "arm64"; else print "unknown" }') \ 77 | && export PKG="${VERSION}.linux-${ARCH}.tar.gz" \ 78 | && export URL="https://go.dev/dl/${PKG}" \ 79 | && echo "INFO[${NAME}] Installed:" \ 80 | && echo "INFO[${NAME}] Command: ${NAME}" \ 81 | && echo "INFO[${NAME}] Package: ${PKG}" \ 82 | && echo "INFO[${NAME}] Latest Release: ${VERSION}" \ 83 | && echo "INFO[${NAME}] Architecture: ${ARCH}" \ 84 | && echo "INFO[${NAME}] Source: ${URL}" \ 85 | && ${curl} ${URL} | sudo tar -C /usr/local/ -xzvf - \ 86 | && sudo chmod 755 /usr/local/go/bin/* \ 87 | && ${TEST} \ 88 | && echo 89 | 90 | ################################################################################## 91 | # Install nodejs npm yarn 92 | RUN echo \ 93 | && export NODE_MAJOR=23 \ 94 | && ${curl} https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ 95 | | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ 96 | && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" \ 97 | | sudo tee /etc/apt/sources.list.d/nodesource.list \ 98 | && sudo apt-get update \ 99 | && sudo apt-get install nodejs \ 100 | && sudo apt-get clean \ 101 | && sudo apt-get autoremove -y \ 102 | && sudo apt-get purge -y --auto-remove \ 103 | && ${dir_clean} \ 104 | && node --version \ 105 | && npm --version \ 106 | && sudo npm install --global yarn \ 107 | && yarn --version \ 108 | && true 109 | 110 | # Install claude-code 111 | # Configure npm global packages to install in user home 112 | RUN echo \ 113 | && mkdir -p ~/.npm-global \ 114 | && npm config set prefix ~/.npm-global \ 115 | && echo 'export PATH=~/.npm-global/bin:$PATH' >> ~/.bashrc \ 116 | && export PATH=~/.npm-global/bin:$PATH \ 117 | && npm install -g @anthropic-ai/claude-code \ 118 | && echo "Claude Code installed at: $(which claude-code)" \ 119 | && true 120 | 121 | ################################################################################## 122 | # Dotnet 123 | ARG APT_PKGS="\ 124 | dotnet-sdk-8.0 \ 125 | dotnet-runtime-8.0 \ 126 | " 127 | RUN echo \ 128 | && bash -c "${apt_install} ${APT_PKGS}" \ 129 | && bash -c "${apt_clean}" \ 130 | && ${dir_clean} \ 131 | && echo 132 | -------------------------------------------------------------------------------- /docker/slim-dotnet/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:slim-dotnet -f ./docker/slim-dotnet/Dockerfile ./docker 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:slim-dotnet 5 | ############################################################################### 6 | # Base VSCode Image 7 | FROM ghcr.io/containercraft/devcontainer:slim 8 | 9 | ################################################################################# 10 | # Image Metadata 11 | LABEL tag="slim-dotnet" 12 | 13 | ################################################################################# 14 | # Install Programming Language Tooling 15 | # - dotnet 16 | ARG APT_PKGS="\ 17 | dotnet-sdk-8.0 \ 18 | dotnet-runtime-8.0 \ 19 | " 20 | RUN echo \ 21 | && sudo apt-get update \ 22 | && bash -c "${apt_install} ${APT_PKGS}" \ 23 | && bash -c "${apt_clean}" \ 24 | && ${dir_clean} \ 25 | && echo 26 | -------------------------------------------------------------------------------- /docker/slim-golang/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:slim-golang . 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:slim-golang 5 | ############################################################################### 6 | # Base VSCode Image 7 | FROM ghcr.io/containercraft/devcontainer:slim 8 | 9 | ################################################################################# 10 | # Image Metadata 11 | LABEL tag="slim-golang" 12 | 13 | ################################################################################# 14 | # Install Programming Language Tooling 15 | # - golang 16 | RUN echo ;set -ex \ 17 | && jq --version \ 18 | && export NAME="go" \ 19 | && export TEST="${NAME} version" \ 20 | && export VERSION="$(${curl} "https://go.dev/dl/?mode=json" | jq --compact-output --raw-output .[1].version)" \ 21 | && export ARCH=$(uname -m | awk '{ if ($1 == "x86_64") print "amd64"; else if ($1 == "aarch64" || $1 == "arm64") print "arm64"; else print "unknown" }') \ 22 | && export PKG="${VERSION}.linux-${ARCH}.tar.gz" \ 23 | && export URL="https://go.dev/dl/${PKG}" \ 24 | && echo "INFO[${NAME}] Installed:" \ 25 | && echo "INFO[${NAME}] Command: ${NAME}" \ 26 | && echo "INFO[${NAME}] Package: ${PKG}" \ 27 | && echo "INFO[${NAME}] Latest Release: ${VERSION}" \ 28 | && echo "INFO[${NAME}] Architecture: ${ARCH}" \ 29 | && echo "INFO[${NAME}] Source: ${URL}" \ 30 | && ${curl} ${URL} | sudo tar -C /usr/local/ -xzvf - \ 31 | && sudo chmod 755 /usr/local/go/bin/* \ 32 | && ${TEST} \ 33 | && echo 34 | -------------------------------------------------------------------------------- /docker/slim-node/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:slim-node . 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:slim-node 5 | ############################################################################### 6 | # Base VSCode Image 7 | FROM ghcr.io/containercraft/devcontainer:slim 8 | 9 | ################################################################################# 10 | # Image Metadata 11 | LABEL tag="slim-node" 12 | 13 | ################################################################################# 14 | # Install Programming Language Tooling 15 | # - nodejs 16 | # - npm 17 | # - yarn 18 | RUN echo \ 19 | && export NODE_MAJOR=20 \ 20 | && ${curl} https://deb.nodesource.com/gpgkey/nodesource-repo.gpg.key \ 21 | | sudo gpg --dearmor -o /etc/apt/keyrings/nodesource.gpg \ 22 | && echo "deb [signed-by=/etc/apt/keyrings/nodesource.gpg] https://deb.nodesource.com/node_$NODE_MAJOR.x nodistro main" \ 23 | | sudo tee /etc/apt/sources.list.d/nodesource.list \ 24 | && sudo apt-get update \ 25 | && sudo apt-get install nodejs \ 26 | && sudo apt-get clean \ 27 | && sudo apt-get autoremove -y \ 28 | && sudo apt-get purge -y --auto-remove \ 29 | && ${dir_clean} \ 30 | && node --version \ 31 | && npm --version \ 32 | && sudo npm install --global yarn \ 33 | && yarn --version \ 34 | && true 35 | -------------------------------------------------------------------------------- /docker/slim-python/Dockerfile: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Use: 3 | # - docker build --progress plain --tag ghcr.io/pulumi/devcontainer:slim-python . 4 | # - docker run --rm -d --name devcontainer --hostname devcontainer ghcr.io/pulumi/devcontainer:slim-python 5 | ############################################################################### 6 | # Base VSCode Image 7 | FROM ghcr.io/containercraft/devcontainer:slim 8 | 9 | ################################################################################# 10 | # Image Metadata 11 | LABEL tag="slim-python" 12 | 13 | ################################################################################# 14 | # Install Programming Language Tooling 15 | # - python 16 | ARG APT_PKGS="\ 17 | python3 \ 18 | python3-venv \ 19 | python3-dev \ 20 | python3.12 \ 21 | python3.12-venv \ 22 | python3.12-dev \ 23 | python3-pip \ 24 | python3-setuptools \ 25 | " 26 | RUN echo \ 27 | && sudo apt-get update \ 28 | && bash -c "${apt_install} ${APT_PKGS}" \ 29 | && bash -c "${apt_clean}" \ 30 | && sudo update-alternatives --install \ 31 | /usr/bin/python python \ 32 | /usr/bin/python3 1 \ 33 | && ${dir_clean} \ 34 | && echo 35 | 36 | ## Python Pip Packages 37 | #ARG PIP_PKGS="\ 38 | # " 39 | #RUN echo \ 40 | # && sudo python3 -m pip install ${PIP_PKGS} \ 41 | # && ${dir_clean} \ 42 | # && echo 43 | 44 | ################################################################################## 45 | # Install Poetry for Python dependency management 46 | ENV POETRY_HOME="/usr/local" 47 | ENV PATH="/usr/local/bin:${PATH}" 48 | 49 | USER root 50 | RUN PYTHON_VERSION=$(python3 --version | cut -d' ' -f2 | cut -d'.' -f1,2) \ 51 | && NAME="poetry" \ 52 | && echo "---------------------------------------------------------" \ 53 | && echo "INFO[${NAME}] Installing:" \ 54 | && echo "INFO[${NAME}] Command: ${NAME}" \ 55 | && echo "INFO[${NAME}] Python Version: ${PYTHON_VERSION}" \ 56 | && echo "---------------------------------------------------------" \ 57 | && curl -sSL https://install.python-poetry.org | python3 - \ 58 | && chmod +x /usr/local/bin/poetry \ 59 | && poetry config virtualenvs.in-project true \ 60 | && poetry --version \ 61 | && mkdir -p \ 62 | /home/ubuntu/.config/pypoetry \ 63 | /etc/skel/.config/pypoetry \ 64 | && chown -R ubuntu:ubuntu /home/ubuntu/.config \ 65 | && echo 66 | USER ubuntu 67 | 68 | -------------------------------------------------------------------------------- /docker/slim/rootfs/containers/containers.conf: -------------------------------------------------------------------------------- 1 | [engine] 2 | cgroup_manager = "cgroupfs" 3 | -------------------------------------------------------------------------------- /docker/slim/rootfs/containers/registries.conf: -------------------------------------------------------------------------------- 1 | [registries.search] 2 | registries = ['ghcr.io', 'docker.io', 'quay.io', 'registry.access.redhat.com', 'registry.redhat.io'] 3 | [registries.insecure] 4 | registries = ['localhost'] 5 | [registries.block] 6 | registries = [] 7 | -------------------------------------------------------------------------------- /docker/slim/rootfs/docker/registry/config.yml: -------------------------------------------------------------------------------- 1 | version: 0.1 2 | log: 3 | level: info 4 | accesslog: 5 | disabled: true 6 | storage: 7 | cache: 8 | blobdescriptor: inmemory 9 | filesystem: 10 | rootdirectory: /root/platform/mirror 11 | http: 12 | addr: :5000 13 | headers: 14 | X-Content-Type-Options: [nosniff] 15 | health: 16 | storagedriver: 17 | enabled: true 18 | interval: 10s 19 | threshold: 3 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/environment: -------------------------------------------------------------------------------- 1 | PATH="/root/platform/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" 2 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/ansible/ansible.cfg: -------------------------------------------------------------------------------- 1 | [defaults] 2 | inventory = inventory 3 | gathering = smart 4 | fact_caching = jsonfile 5 | fact_caching_connection = /tmp/ansible 6 | fact_caching_timeout = 86400 7 | inject_facts_as_vars = True 8 | callback_whitelist = profile_tasks, timer 9 | host_key_checking = False 10 | display_skipped_hosts = True 11 | display_args_to_stdout = True 12 | error_on_undefined_vars = True 13 | deprecation_warnings = True 14 | command_warnings = False 15 | system_warnings = False 16 | log_path = /root/bundle/koffer.log 17 | timeout = 30 18 | #roles_path = collector/roles 19 | 20 | [inventory] 21 | unparsed_is_failed = True 22 | 23 | [paramiko_connection] 24 | record_host_keys = False 25 | host_key_auto_add = False 26 | 27 | [ssh_connection] 28 | ssh_args = -o StrictHostKeyChecking=no 29 | pipelining = False 30 | 31 | [persistent_connection] 32 | connect_timeout = 30 33 | command_timeout = 30 34 | 35 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/apt/apt.conf.d/99config: -------------------------------------------------------------------------------- 1 | //// /etc/apt/apt.conf.d/99config 2 | 3 | //// Automatically answer 'yes' to prompts 4 | APT::Get::Assume-Yes "true"; 5 | APT::Get::Show-Upgraded "true"; 6 | 7 | //// Minimize the installation of recommended packages 8 | APT::Install-Recommends "false"; 9 | APT::Install-Suggests "false"; 10 | 11 | //// Set the frontend to non-interactive 12 | DPkg::Pre-Install-Pkgs {"/usr/sbin/dpkg-preconfigure --apt || true";}; 13 | DPkg::Options { 14 | "--force-confdef"; 15 | "--force-confold"; 16 | }; 17 | 18 | //// Disable the cache for downloaded packages 19 | Dir::Cache "var/cache/apt/"; 20 | Dir::Cache::archives "archives/"; 21 | Dir::Cache::pkgcache "pkgcache/"; 22 | Dir::Cache::srcpkgcache "cache/"; 23 | 24 | //// Do not store downloaded .deb files 25 | Acquire::http {No-Cache=True;}; 26 | Acquire::BrokenProxy "true"; 27 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/containers/registries.conf: -------------------------------------------------------------------------------- 1 | [registries.search] 2 | registries = ['registry.access.redhat.com', 'registry.redhat.io', 'docker.io'] 3 | [registries.insecure] 4 | registries = ['localhost'] 5 | [registries.block] 6 | registries = [] 7 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/docker/registry/config.yml: -------------------------------------------------------------------------------- 1 | version: 0.1 2 | log: 3 | fields: 4 | service: registry 5 | storage: 6 | cache: 7 | blobdescriptor: inmemory 8 | filesystem: 9 | rootdirectory: /root/deploy/mirror 10 | http: 11 | addr: :5500 12 | headers: 13 | X-Content-Type-Options: [nosniff] 14 | health: 15 | storagedriver: 16 | enabled: true 17 | interval: 10s 18 | threshold: 3 19 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/dpkg/dpkg.cfg.d/01_noman: -------------------------------------------------------------------------------- 1 | # /etc/dpkg/dpkg.cfg.d/01_nodoc 2 | 3 | # Delete locales 4 | path-exclude=/usr/share/locale/* 5 | 6 | # Delete man pages 7 | path-exclude=/usr/share/man/* 8 | 9 | # Delete docs 10 | path-exclude=/usr/share/doc/* 11 | path-include=/usr/share/doc/*/copyright 12 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/environment: -------------------------------------------------------------------------------- 1 | PATH=/root/platform/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/root/platform/bin:/usr/local/go/bin 2 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.Xresources: -------------------------------------------------------------------------------- 1 | ! Dracula Xresources palette 2 | *.foreground: #F8F8F2 3 | *.background: #282A36 4 | *.color0: #000000 5 | *.color8: #4D4D4D 6 | *.color1: #FF5555 7 | *.color9: #FF6E67 8 | *.color2: #50FA7B 9 | *.color10: #5AF78E 10 | *.color3: #F1FA8C 11 | *.color11: #F4F99D 12 | *.color4: #BD93F9 13 | *.color12: #CAA9FA 14 | *.color5: #FF79C6 15 | *.color13: #FF92D0 16 | *.color6: #8BE9FD 17 | *.color14: #9AEDFE 18 | *.color7: #BFBFBF 19 | *.color15: #E6E6E6 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.actrc: -------------------------------------------------------------------------------- 1 | -P ubuntu-latest=catthehacker/ubuntu:act-latest 2 | -P ubuntu-22.04=catthehacker/ubuntu:act-22.04 3 | -P ubuntu-20.04=catthehacker/ubuntu:act-20.04 4 | -P ubuntu-18.04=catthehacker/ubuntu:act-18.04 5 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.aws/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ContainerCraft/devcontainer/6e7ad3261e9201afd5eddb9214e84a1cb8955a81/docker/slim/rootfs/etc/skel/.aws/.gitkeep -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.bash_profile: -------------------------------------------------------------------------------- 1 | # Get the aliases and functions 2 | if [ -f ~/.bashrc ]; then 3 | . ~/.bashrc 4 | fi 5 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.bashrc: -------------------------------------------------------------------------------- 1 | # .bashrc 2 | test -r "~/.dir_colors" && eval $(dircolors ~/.dir_colors) 3 | # User specific environment and startup programs 4 | # Source items only for interactive sessions (Fixes qemu+ssh header size error) 5 | case $- in *i*) 6 | for i in $(ls ~/.bashrc.d/ 2>/dev/null); do 7 | source ~/.bashrc.d/$i 8 | done 9 | for i in $(ls ~/deploy/.profile.d/ 2>/dev/null); do 10 | source ~/deploy/profile.d/$i 11 | done 12 | esac 13 | 14 | # Git stage/commit/push function 15 | # Example: 16 | # - cd ~/Git/projectName 17 | # - touch 1.txt 18 | # - gitup add text file 19 | # Git stage/commit/push 20 | gitup () { 21 | 22 | git pull 23 | git_commit_msg="$@" 24 | git_branch=$(git branch --show-current) 25 | git_remote=$(git remote get-url --push origin) 26 | git_remote_push="$(git remote get-url --push origin | awk -F'[@]' '{print $2}')" 27 | 28 | cat </dev/null 8 | end 9 | 10 | function sshagent_testsocket 11 | if [ ! -x (command which ssh-add) ] ; 12 | echo "ssh-add is not available; agent testing aborted" 13 | return 1 14 | end 15 | 16 | if [ X"$argv[1]" != X ] ; 17 | set -xg SSH_AUTH_SOCK $argv[1] 18 | end 19 | 20 | if [ X"$SSH_AUTH_SOCK" = X ] 21 | return 2 22 | end 23 | 24 | if [ -S $SSH_AUTH_SOCK ] ; 25 | ssh-add -l > /dev/null 26 | if [ $status = 2 ] ; 27 | echo "Socket $SSH_AUTH_SOCK is dead! Deleting!" 28 | rm -f $SSH_AUTH_SOCK 29 | return 4 30 | else ; 31 | echo "Found ssh-agent $SSH_AUTH_SOCK" 32 | return 0 33 | end 34 | else ; 35 | echo "$SSH_AUTH_SOCK is not a socket!" 36 | return 3 37 | end 38 | end 39 | 40 | 41 | function ssh_agent_init 42 | # ssh agent sockets can be attached to a ssh daemon process or an 43 | # ssh-agent process. 44 | 45 | set -l AGENTFOUND 0 46 | 47 | # Attempt to find and use the ssh-agent in the current environment 48 | if sshagent_testsocket ; 49 | set AGENTFOUND 1 50 | end 51 | 52 | # If there is no agent in the environment, search /tmp for 53 | # possible agents to reuse before starting a fresh ssh-agent 54 | # process. 55 | if [ $AGENTFOUND = 0 ]; 56 | for agentsocket in (sshagent_findsockets) 57 | if [ $AGENTFOUND != 0 ] ; 58 | break 59 | end 60 | if sshagent_testsocket $agentsocket ; 61 | set AGENTFOUND 1 62 | end 63 | 64 | end 65 | end 66 | 67 | # If at this point we still haven't located an agent, it's time to 68 | # start a new one 69 | if [ $AGENTFOUND = 0 ] ; 70 | echo need to start a new agent 71 | eval (ssh-agent -c) 72 | end 73 | 74 | # Finally, show what keys are currently in the agent 75 | # ssh-add -l 76 | end 77 | 78 | # Load environment variables from a file 79 | #function envsource 80 | # for line in (cat $argv | grep -v '^#') 81 | # set item (string split -m 1 '=' $line) 82 | # set -gx $item[1] $item[2] 83 | # end 84 | #end 85 | function envsource 86 | # Set default file to ~/.env 87 | set file ~/.env 88 | 89 | # If an argument is provided, use it as the file 90 | if count $argv > /dev/null 91 | set file $argv[1] 92 | end 93 | 94 | # Load environment variables from the file 95 | for line in (cat $file | grep -v '^#') 96 | set item (string split -m 1 '=' $line) 97 | set -gx $item[1] $item[2] 98 | echo "Exported key $item[1]" 99 | end 100 | end 101 | touch ~/.env 102 | envsource ~/.env 2>&1 1>/dev/null 103 | 104 | ssh_agent_init 2>&1 1>/dev/null 105 | set fish_greeting 106 | set -gx LC_ALL en_US.UTF-8 107 | set -gx LANG en_US.UTF-8 108 | set PATH /home/k/.krew/bin $PATH 109 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.config/fish/fish_variables: -------------------------------------------------------------------------------- 1 | # This file contains fish universal variable definitions. 2 | # VERSION: 3.0 3 | SETUVAR __fish_initialized:3400 4 | SETUVAR fish_color_autosuggestion:555\x1ebrblack 5 | SETUVAR fish_color_cancel:\x2dr 6 | SETUVAR fish_color_command:blue 7 | SETUVAR fish_color_comment:red 8 | SETUVAR fish_color_cwd:green 9 | SETUVAR fish_color_cwd_root:red 10 | SETUVAR fish_color_end:green 11 | SETUVAR fish_color_error:brred 12 | SETUVAR fish_color_escape:brcyan 13 | SETUVAR fish_color_history_current:\x2d\x2dbold 14 | SETUVAR fish_color_host:normal 15 | SETUVAR fish_color_host_remote:yellow 16 | SETUVAR fish_color_normal:normal 17 | SETUVAR fish_color_operator:brcyan 18 | SETUVAR fish_color_param:cyan 19 | SETUVAR fish_color_quote:yellow 20 | SETUVAR fish_color_redirection:cyan\x1e\x2d\x2dbold 21 | SETUVAR fish_color_search_match:\x2d\x2dbackground\x3d111 22 | SETUVAR fish_color_selection:white\x1e\x2d\x2dbold\x1e\x2d\x2dbackground\x3dbrblack 23 | SETUVAR fish_color_status:red 24 | SETUVAR fish_color_user:brgreen 25 | SETUVAR fish_color_valid_path:\x2d\x2dunderline 26 | SETUVAR fish_greeting:\x1d 27 | SETUVAR fish_key_bindings:fish_default_key_bindings 28 | SETUVAR fish_pager_color_completion:normal 29 | SETUVAR fish_pager_color_description:B3A06D\x1eyellow\x1e\x2di 30 | SETUVAR fish_pager_color_prefix:cyan\x1e\x2d\x2dbold\x1e\x2d\x2dunderline 31 | SETUVAR fish_pager_color_progress:brwhite\x1e\x2d\x2dbackground\x3dcyan 32 | SETUVAR fish_pager_color_selected_background:\x2dr 33 | SETUVAR fish_user_paths:/home/k/\x2elocal/bin\x1e/home/k/\x2epulumi/bin/\x1e/home/k/\x2econfig/npm\x2dglobal/bin 34 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.config/fish/functions/cloc.fish: -------------------------------------------------------------------------------- 1 | function cloc 2 | git count | xargs wc -l 2>/dev/null 3 | end -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.config/fish/functions/env.fish: -------------------------------------------------------------------------------- 1 | # Place this in your Fish functions folder to make it available immediately 2 | # e.g. ~/.config/fish/functions/envsource.fish 3 | # 4 | # Usage: envsource 5 | 6 | #function envsource 7 | # for line in (cat $argv | grep -v '^#') 8 | # set item (string split -m 1 '=' $line) 9 | # set -gx $item[1] $item[2] 10 | # echo "Exported key $item[1]" 11 | # end 12 | #end 13 | 14 | function envsource 15 | # Set default file to ~/.env 16 | set file ~/.env 17 | 18 | # If an argument is provided, use it as the file 19 | if count $argv > /dev/null 20 | set file $argv[1] 21 | end 22 | 23 | # Load environment variables from the file 24 | for line in (cat $file | grep -v '^#') 25 | set item (string split -m 1 '=' $line) 26 | set -gx $item[1] $item[2] 27 | echo "Exported key $item[1]" 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.config/fish/functions/k.fish: -------------------------------------------------------------------------------- 1 | function k 2 | kubectl $argv 3 | end 4 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.config/k9s/skin.yml: -------------------------------------------------------------------------------- 1 | # Styles... 2 | foreground: &foreground "#f8f8f2" 3 | background: &background "#282a36" 4 | current_line: ¤t_line "#44475a" 5 | selection: &selection "#44475a" 6 | comment: &comment "#6272a4" 7 | cyan: &cyan "#8be9fd" 8 | green: &green "#50fa7b" 9 | orange: &orange "#ffb86c" 10 | pink: &pink "#ff79c6" 11 | purple: &purple "#bd93f9" 12 | red: &red "#ff5555" 13 | yellow: &yellow "#f1fa8c" 14 | 15 | # Skin... 16 | k9s: 17 | # General K9s styles 18 | body: 19 | fgColor: *foreground 20 | bgColor: *background 21 | logoColor: *purple 22 | # Command prompt styles 23 | prompt: 24 | fgColor: *foreground 25 | bgColor: *background 26 | suggestColor: *purple 27 | # ClusterInfoView styles. 28 | info: 29 | fgColor: *pink 30 | sectionColor: *foreground 31 | # Dialog styles. 32 | dialog: 33 | fgColor: *foreground 34 | bgColor: *background 35 | buttonFgColor: *foreground 36 | buttonBgColor: *purple 37 | buttonFocusFgColor: *yellow 38 | buttonFocusBgColor: *pink 39 | labelFgColor: *orange 40 | fieldFgColor: *foreground 41 | frame: 42 | # Borders styles. 43 | border: 44 | fgColor: *selection 45 | focusColor: *current_line 46 | menu: 47 | fgColor: *foreground 48 | keyColor: *pink 49 | # Used for favorite namespaces 50 | numKeyColor: *pink 51 | # CrumbView attributes for history navigation. 52 | crumbs: 53 | fgColor: *foreground 54 | bgColor: *current_line 55 | activeColor: *current_line 56 | # Resource status and update styles 57 | status: 58 | newColor: *cyan 59 | modifyColor: *purple 60 | addColor: *green 61 | errorColor: *red 62 | highlightColor: *orange 63 | killColor: *comment 64 | completedColor: *comment 65 | # Border title styles. 66 | title: 67 | fgColor: *foreground 68 | bgColor: *current_line 69 | highlightColor: *orange 70 | counterColor: *purple 71 | filterColor: *pink 72 | views: 73 | # Charts skins... 74 | charts: 75 | bgColor: default 76 | defaultDialColors: 77 | - *purple 78 | - *red 79 | defaultChartColors: 80 | - *purple 81 | - *red 82 | # TableView attributes. 83 | table: 84 | fgColor: *foreground 85 | bgColor: *background 86 | # Header row styles. 87 | header: 88 | fgColor: *foreground 89 | bgColor: *background 90 | sorterColor: *cyan 91 | # Xray view attributes. 92 | xray: 93 | fgColor: *foreground 94 | bgColor: *background 95 | cursorColor: *current_line 96 | graphicColor: *purple 97 | showIcons: false 98 | # YAML info styles. 99 | yaml: 100 | keyColor: *pink 101 | colonColor: *purple 102 | valueColor: *foreground 103 | # Logs styles. 104 | logs: 105 | fgColor: *foreground 106 | bgColor: *background 107 | indicator: 108 | fgColor: *foreground 109 | bgColor: *purple 110 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.dir_colors: -------------------------------------------------------------------------------- 1 | # Copyright (c) 2016-present Sven Greb 2 | # This source code is licensed under the MIT license found in the license file. 3 | 4 | COLOR tty 5 | 6 | TERM alacritty 7 | TERM alacritty-direct 8 | TERM ansi 9 | TERM *color* 10 | TERM con[0-9]*x[0-9]* 11 | TERM cons25 12 | TERM console 13 | TERM cygwin 14 | TERM dtterm 15 | TERM dvtm 16 | TERM dvtm-256color 17 | TERM Eterm 18 | TERM eterm-color 19 | TERM fbterm 20 | TERM gnome 21 | TERM gnome-256color 22 | TERM hurd 23 | TERM jfbterm 24 | TERM konsole 25 | TERM konsole-256color 26 | TERM kterm 27 | TERM linux 28 | TERM linux-c 29 | TERM mlterm 30 | TERM putty 31 | TERM putty-256color 32 | TERM rxvt* 33 | TERM rxvt-unicode 34 | TERM rxvt-256color 35 | TERM rxvt-unicode256 36 | TERM screen* 37 | TERM screen-256color 38 | TERM st 39 | TERM st-256color 40 | TERM terminator 41 | TERM tmux* 42 | TERM tmux-256color 43 | TERM vt100 44 | TERM xterm* 45 | TERM xterm-color 46 | TERM xterm-88color 47 | TERM xterm-256color 48 | TERM xterm-kitty 49 | 50 | #+-----------------+ 51 | #+ Global Defaults + 52 | #+-----------------+ 53 | NORMAL 00 54 | RESET 0 55 | 56 | FILE 00 57 | DIR 01;34 58 | LINK 36 59 | MULTIHARDLINK 04;36 60 | 61 | FIFO 04;01;36 62 | SOCK 04;33 63 | DOOR 04;01;36 64 | BLK 01;33 65 | CHR 33 66 | 67 | ORPHAN 31 68 | MISSING 01;37;41 69 | 70 | EXEC 01;36 71 | 72 | SETUID 01;04;37 73 | SETGID 01;04;37 74 | CAPABILITY 01;37 75 | 76 | STICKY_OTHER_WRITABLE 01;37;44 77 | OTHER_WRITABLE 01;04;34 78 | STICKY 04;37;44 79 | 80 | #+-------------------+ 81 | #+ Extension Pattern + 82 | #+-------------------+ 83 | #+--- Archives ---+ 84 | .7z 01;32 85 | .ace 01;32 86 | .alz 01;32 87 | .arc 01;32 88 | .arj 01;32 89 | .bz 01;32 90 | .bz2 01;32 91 | .cab 01;32 92 | .cpio 01;32 93 | .deb 01;32 94 | .dz 01;32 95 | .ear 01;32 96 | .gz 01;32 97 | .jar 01;32 98 | .lha 01;32 99 | .lrz 01;32 100 | .lz 01;32 101 | .lz4 01;32 102 | .lzh 01;32 103 | .lzma 01;32 104 | .lzo 01;32 105 | .rar 01;32 106 | .rpm 01;32 107 | .rz 01;32 108 | .sar 01;32 109 | .t7z 01;32 110 | .tar 01;32 111 | .taz 01;32 112 | .tbz 01;32 113 | .tbz2 01;32 114 | .tgz 01;32 115 | .tlz 01;32 116 | .txz 01;32 117 | .tz 01;32 118 | .tzo 01;32 119 | .tzst 01;32 120 | .war 01;32 121 | .xz 01;32 122 | .z 01;32 123 | .Z 01;32 124 | .zip 01;32 125 | .zoo 01;32 126 | .zst 01;32 127 | 128 | #+--- Audio ---+ 129 | .aac 32 130 | .au 32 131 | .flac 32 132 | .m4a 32 133 | .mid 32 134 | .midi 32 135 | .mka 32 136 | .mp3 32 137 | .mpa 32 138 | .mpeg 32 139 | .mpg 32 140 | .ogg 32 141 | .opus 32 142 | .ra 32 143 | .wav 32 144 | 145 | #+--- Customs ---+ 146 | .3des 01;35 147 | .aes 01;35 148 | .gpg 01;35 149 | .pgp 01;35 150 | 151 | #+--- Documents ---+ 152 | .doc 32 153 | .docx 32 154 | .dot 32 155 | .odg 32 156 | .odp 32 157 | .ods 32 158 | .odt 32 159 | .otg 32 160 | .otp 32 161 | .ots 32 162 | .ott 32 163 | .pdf 32 164 | .ppt 32 165 | .pptx 32 166 | .xls 32 167 | .xlsx 32 168 | 169 | #+--- Executables ---+ 170 | .app 01;36 171 | .bat 01;36 172 | .btm 01;36 173 | .cmd 01;36 174 | .com 01;36 175 | .exe 01;36 176 | .reg 01;36 177 | 178 | #+--- Ignores ---+ 179 | *~ 02;37 180 | .bak 02;37 181 | .BAK 02;37 182 | .log 02;37 183 | .log 02;37 184 | .old 02;37 185 | .OLD 02;37 186 | .orig 02;37 187 | .ORIG 02;37 188 | .swo 02;37 189 | .swp 02;37 190 | 191 | #+--- Images ---+ 192 | .bmp 32 193 | .cgm 32 194 | .dl 32 195 | .dvi 32 196 | .emf 32 197 | .eps 32 198 | .gif 32 199 | .jpeg 32 200 | .jpg 32 201 | .JPG 32 202 | .mng 32 203 | .pbm 32 204 | .pcx 32 205 | .pgm 32 206 | .png 32 207 | .PNG 32 208 | .ppm 32 209 | .pps 32 210 | .ppsx 32 211 | .ps 32 212 | .svg 32 213 | .svgz 32 214 | .tga 32 215 | .tif 32 216 | .tiff 32 217 | .xbm 32 218 | .xcf 32 219 | .xpm 32 220 | .xwd 32 221 | .xwd 32 222 | .yuv 32 223 | 224 | #+--- Video ---+ 225 | .anx 32 226 | .asf 32 227 | .avi 32 228 | .axv 32 229 | .flc 32 230 | .fli 32 231 | .flv 32 232 | .gl 32 233 | .m2v 32 234 | .m4v 32 235 | .mkv 32 236 | .mov 32 237 | .MOV 32 238 | .mp4 32 239 | .mpeg 32 240 | .mpg 32 241 | .nuv 32 242 | .ogm 32 243 | .ogv 32 244 | .ogx 32 245 | .qt 32 246 | .rm 32 247 | .rmvb 32 248 | .swf 32 249 | .vob 32 250 | .webm 32 251 | .wmv 32 252 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.docker.json: -------------------------------------------------------------------------------- 1 | {} 2 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.kube/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ContainerCraft/devcontainer/6e7ad3261e9201afd5eddb9214e84a1cb8955a81/docker/slim/rootfs/etc/skel/.kube/.gitkeep -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.local/bin/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ContainerCraft/devcontainer/6e7ad3261e9201afd5eddb9214e84a1cb8955a81/docker/slim/rootfs/etc/skel/.local/bin/.gitkeep -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.local/share/code-server/User/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "editor.lineNumbers": "relative", 3 | "redhat.telemetry.enabled": true, 4 | "workbench.colorTheme": "Default Dark+", 5 | "terminal.integrated.fontFamily": "FiraCode Nerd Font Mono", 6 | "vim.easymotion": true, 7 | "vim.incsearch": true, 8 | "vim.useSystemClipboard": true, 9 | "vim.useCtrlKeys": true, 10 | "vim.hlsearch": true, 11 | "vim.insertModeKeyBindings": [ 12 | { 13 | "before": ["j","j"], 14 | "after": [""] 15 | } 16 | ], 17 | "vim.otherModesKeyBindingsNonRecursive": [ 18 | { 19 | "before": ["","d"], 20 | "after": ["d", "d"] 21 | }, 22 | { 23 | "before":[""], 24 | "after":[], 25 | "commands": [ 26 | { 27 | "command": ":nohl" 28 | } 29 | ] 30 | } 31 | ], 32 | "vim.leader": "", 33 | "vim.handleKeys":{ 34 | "": false, 35 | "": false 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.pulumi/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ContainerCraft/devcontainer/6e7ad3261e9201afd5eddb9214e84a1cb8955a81/docker/slim/rootfs/etc/skel/.pulumi/.gitkeep -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux.conf: -------------------------------------------------------------------------------- 1 | set-option -g default-shell /usr/bin/bash 2 | set -g default-terminal screen-256color 3 | # List of plugins 4 | set -g @plugin 'tmux-plugins/tpm' 5 | set -g @plugin 'tmux-plugins/tmux-sensible' 6 | set -g @plugin 'tmux-plugins/tmux-resurrect' 7 | set -g @plugin 'tmux-plugins/tmux-yank' 8 | set -g @plugin 'wfxr/tmux-net-speed' 9 | set -g @tmux_power_show_upload_speed true 10 | set -g @tmux_power_show_download_speed true 11 | set -g @plugin 'wfxr/tmux-power' 12 | set -g @tmux_power_theme 'violet' 13 | set -g status-right ' %a %h-%d %H:%M ' 14 | 15 | # Start windows and panes at 1, not 0 16 | set -g base-index 1 17 | setw -g pane-base-index 1 18 | 19 | # Other examples: 20 | # set -g @plugin 'github_username/plugin_name' 21 | # set -g @plugin 'github_username/plugin_name#branch' 22 | # set -g @plugin 'git@github.com:user/plugin' 23 | # set -g @plugin 'git@bitbucket.com:user/plugin' 24 | 25 | #unbind C-b 26 | #set -g prefix C-a 27 | #bind C-a send-prefix 28 | 29 | # Initialize TMUX plugin manager (keep this line at the very bottom of 30 | # tmux.conf) 31 | run '~/.tmux/plugins/tpm/tpm' 32 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/.gitkeep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ContainerCraft/devcontainer/6e7ad3261e9201afd5eddb9214e84a1cb8955a81/docker/slim/rootfs/etc/skel/.tmux/.gitkeep -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/.gitattributes: -------------------------------------------------------------------------------- 1 | # Force text files to have unix eols, so Windows/Cygwin does not break them 2 | *.* eol=lf 3 | 4 | # These files are unfortunately not recognized as text files so 5 | # explicitly listing them here 6 | tpm eol=lf 7 | bin/* eol=lf 8 | bindings/* eol=lf 9 | tests/* eol=lf 10 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/.gitignore: -------------------------------------------------------------------------------- 1 | **/.vagrant/ 2 | run_tests 3 | tests/run_tests_in_isolation 4 | tests/helpers/helpers.sh 5 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "lib/tmux-test"] 2 | path = lib/tmux-test 3 | url = https://github.com/tmux-plugins/tmux-test.git 4 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/.travis.yml: -------------------------------------------------------------------------------- 1 | # generic packages and tmux 2 | before_install: 3 | - sudo apt-get update 4 | - sudo apt-get install -y git-core expect 5 | - sudo apt-get install -y python-software-properties software-properties-common 6 | - sudo apt-get install -y libevent-dev libncurses-dev 7 | - git clone https://github.com/tmux/tmux.git 8 | - cd tmux 9 | - git checkout 2.0 10 | - sh autogen.sh 11 | - ./configure && make && sudo make install 12 | 13 | install: 14 | - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules 15 | # manual `git clone` required for testing `tmux-test` plugin itself 16 | - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true 17 | - lib/tmux-test/setup 18 | 19 | script: ./tests/run_tests_in_isolation 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### master 4 | - upgrade to new version of `tmux-test` 5 | - bug: when using `emacs` copy mode, Enter does not quit screen after tpm 6 | installation/update. Fix by making `Escape` the key for emacs mode. 7 | - add a doc with troubleshooting instructions 8 | - add `.gitattributes` file that forces linefeed characters (classic `\n`) as 9 | line endings - helps with misconfigured git on windows/cygwin 10 | - readme update: announce Cygwin support 11 | - un-deprecate old plugin definition syntax: `set -g @tpm_plugins` 12 | 13 | ### v3.0.0, 2015-08-03 14 | - refactor `shared_set_tpm_path_constant` function 15 | - move all instructions to `docs/` dir 16 | - add `bin/install_plugins` cli executable script 17 | - improved test runner function 18 | - switch to using [tmux-test](https://github.com/tmux-plugins/tmux-test) 19 | framework 20 | - add `bin/update_plugins` cli executable script 21 | - refactor test `expect` scripts, make them simpler and ensure they properly 22 | assert expectations 23 | - refactor code that sets 'TMUX_PLUGIN_MANAGER_PATH' global env var 24 | - stop using global variable for 'tpm path' 25 | - support defining plugins via `set -g @plugin` in sourced files as well 26 | 27 | ### v2.0.0, 2015-07-07 28 | - enable overriding default key bindings 29 | - start using `C-c` to clear screen 30 | - add uninstall/clean procedure and keybinding (prefix+alt+u) (@chilicuil) 31 | - add new `set @plugin 'repo'` plugin definition syntax (@chilicuil) 32 | - revert back to using `-g` flag in new plugin definition syntax 33 | - permit leading whitespace with new plugin definition syntax (thanks @chilicuil) 34 | - make sure `TMUX_PLUGIN_MANAGER_PATH` always has trailng slash 35 | - ensure old/deprecated plugin syntax `set -g @tpm_plugins` works alongside new 36 | `set -g @plugin` syntax 37 | 38 | ### v1.2.2, 2015-02-08 39 | - set GIT_TERMINAL_PROMPT=0 when doing `git clone`, `pull` or `submodule update` 40 | to ensure git does not prompt for username/password in any case 41 | 42 | ### v1.2.1, 2014-11-21 43 | - change the way plugin name is expanded. It now uses the http username 44 | and password by default, like this: `https://git::@github.com/`. This prevents 45 | username and password prompt (and subsequently tmux install hanging) with old 46 | git versions. Fixes #7. 47 | 48 | ### v1.2.0, 2014-11-20 49 | - refactor tests so they can be used on travis 50 | - add travis.yml, add travis badge to the readme 51 | 52 | ### v1.1.0, 2014-11-19 53 | - if the plugin is not downloaded do not source it 54 | - remove `PLUGINS.md`, an obsolete list of plugins 55 | - update readme with instructions about uninstalling plugins 56 | - tilde char and `$HOME` in `TMUX_SHARED_MANAGER_PATH` couldn't be used because 57 | they are just plain strings. Fixing the problem by manually expanding them. 58 | - bugfix: fragile `*.tmux` file globbing (@majutsushi) 59 | 60 | ### v1.0.0, 2014-08-05 61 | - update readme because of github organization change to 62 | [tmux-plugins](https://github.com/tmux-plugins) 63 | - update tests to pass 64 | - update README to suggest different first plugin 65 | - update list of plugins in the README 66 | - remove README 'about' section 67 | - move key binding to the main file. Delete `key_binding.sh`. 68 | - rename `display_message` -> `echo_message` 69 | - installing plugins installs just new plugins. Already installed plugins aren't 70 | updated. 71 | - add 'update plugin' binding and functionality 72 | - add test for updating a plugin 73 | 74 | ### v0.0.2, 2014-07-17 75 | - run all *.tmux plugin files as executables 76 | - fix all redirects to /dev/null 77 | - fix bug: TPM shared path is created before sync (cloning plugins from github 78 | is done) 79 | - add test suite running in Vagrant 80 | - add Tmux version check. `TPM` won't run if Tmux version is less than 1.9. 81 | 82 | ### v0.0.1, 2014-05-21 83 | - get TPM up and running 84 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/HOW_TO_PLUGIN.md: -------------------------------------------------------------------------------- 1 | Instructions moved to 2 | [docs/how_to_create_plugin.md](docs/how_to_create_plugin.md). 3 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/LICENSE.md: -------------------------------------------------------------------------------- 1 | MIT license 2 | Copyright (C) 2014 Bruno Sutic 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining 5 | a copy of this software and associated documentation files (the "Software"), 6 | to deal in the Software without restriction, including without limitation 7 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 | and/or sell copies of the Software, and to permit persons to whom the 9 | Software is furnished to do so, subject to the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be included 12 | in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 16 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 18 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 19 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 20 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/README.md: -------------------------------------------------------------------------------- 1 | # Tmux Plugin Manager 2 | 3 | [![Build Status](https://travis-ci.org/tmux-plugins/tpm.svg?branch=master)](https://travis-ci.org/tmux-plugins/tpm) 4 | 5 | Installs and loads `tmux` plugins. 6 | 7 | Tested and working on Linux, OSX, and Cygwin. 8 | 9 | See list of plugins [here](https://github.com/tmux-plugins/list). 10 | 11 | ### Installation 12 | 13 | Requirements: `tmux` version 1.9 (or higher), `git`, `bash`. 14 | 15 | Clone TPM: 16 | 17 | ```bash 18 | $ git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm 19 | ``` 20 | 21 | Put this at the bottom of `~/.tmux.conf` (`$XDG_CONFIG_HOME/tmux/tmux.conf` 22 | works too): 23 | 24 | ```bash 25 | # List of plugins 26 | set -g @plugin 'tmux-plugins/tpm' 27 | set -g @plugin 'tmux-plugins/tmux-sensible' 28 | 29 | # Other examples: 30 | # set -g @plugin 'github_username/plugin_name' 31 | # set -g @plugin 'github_username/plugin_name#branch' 32 | # set -g @plugin 'git@github.com:user/plugin' 33 | # set -g @plugin 'git@bitbucket.com:user/plugin' 34 | 35 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) 36 | run '~/.tmux/plugins/tpm/tpm' 37 | ``` 38 | 39 | Reload TMUX environment so TPM is sourced: 40 | 41 | ```bash 42 | # type this in terminal if tmux is already running 43 | $ tmux source ~/.tmux.conf 44 | ``` 45 | 46 | That's it! 47 | 48 | ### Installing plugins 49 | 50 | 1. Add new plugin to `~/.tmux.conf` with `set -g @plugin '...'` 51 | 2. Press `prefix` + I (capital i, as in **I**nstall) to fetch the plugin. 52 | 53 | You're good to go! The plugin was cloned to `~/.tmux/plugins/` dir and sourced. 54 | 55 | ### Uninstalling plugins 56 | 57 | 1. Remove (or comment out) plugin from the list. 58 | 2. Press `prefix` + alt + u (lowercase u as in **u**ninstall) to remove the plugin. 59 | 60 | All the plugins are installed to `~/.tmux/plugins/` so alternatively you can 61 | find plugin directory there and remove it. 62 | 63 | ### Key bindings 64 | 65 | `prefix` + I 66 | - Installs new plugins from GitHub or any other git repository 67 | - Refreshes TMUX environment 68 | 69 | `prefix` + U 70 | - updates plugin(s) 71 | 72 | `prefix` + alt + u 73 | - remove/uninstall plugins not on the plugin list 74 | 75 | ### Docs 76 | 77 | - [Help, tpm not working](docs/tpm_not_working.md) - problem solutions 78 | 79 | More advanced features and instructions, regular users probably do not need 80 | this: 81 | 82 | - [How to create a plugin](docs/how_to_create_plugin.md). It's easy. 83 | - [Managing plugins via the command line](docs/managing_plugins_via_cmd_line.md) 84 | - [Changing plugins install dir](docs/changing_plugins_install_dir.md) 85 | - [Automatic TPM installation on a new machine](docs/automatic_tpm_installation.md) 86 | 87 | ### Tests 88 | 89 | Tests for this project run on [Travis CI](https://travis-ci.org/tmux-plugins/tpm). 90 | 91 | When run locally, [vagrant](https://www.vagrantup.com/) is required. 92 | Run tests with: 93 | 94 | ```bash 95 | # within project directory 96 | $ ./run_tests 97 | ``` 98 | 99 | ### License 100 | 101 | [MIT](LICENSE.md) 102 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/bin/clean_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Script intended for use via the command line. 4 | # 5 | # `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, 6 | # but does not need to be started in order to run this script. 7 | 8 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 9 | SCRIPTS_DIR="$CURRENT_DIR/../scripts" 10 | 11 | main() { 12 | "$SCRIPTS_DIR/clean_plugins.sh" # has correct exit code 13 | } 14 | main 15 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/bin/install_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Script intended for use via the command line. 4 | # 5 | # `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, 6 | # but does not need to be started in order to run this script. 7 | 8 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 9 | SCRIPTS_DIR="$CURRENT_DIR/../scripts" 10 | 11 | main() { 12 | "$SCRIPTS_DIR/install_plugins.sh" # has correct exit code 13 | } 14 | main 15 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/bin/update_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Script intended for use via the command line. 4 | # 5 | # `.tmux.conf` needs to be set for TPM. Tmux has to be installed on the system, 6 | # but does not need to be started in order to run this script. 7 | 8 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 9 | SCRIPTS_DIR="$CURRENT_DIR/../scripts" 10 | PROGRAM_NAME="$0" 11 | 12 | if [ $# -eq 0 ]; then 13 | echo "usage:" 14 | echo " $PROGRAM_NAME all update all plugins" 15 | echo " $PROGRAM_NAME tmux-foo update plugin 'tmux-foo'" 16 | echo " $PROGRAM_NAME tmux-bar tmux-baz update multiple plugins" 17 | exit 1 18 | fi 19 | 20 | main() { 21 | "$SCRIPTS_DIR/update_plugin.sh" --shell-echo "$*" # has correct exit code 22 | } 23 | main "$*" 24 | 25 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/bindings/clean_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Tmux key-binding script. 4 | # Scripts intended to be used via the command line are in `bin/` directory. 5 | 6 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 7 | SCRIPTS_DIR="$CURRENT_DIR/../scripts" 8 | HELPERS_DIR="$SCRIPTS_DIR/helpers" 9 | 10 | source "$HELPERS_DIR/tmux_echo_functions.sh" 11 | source "$HELPERS_DIR/tmux_utils.sh" 12 | 13 | main() { 14 | reload_tmux_environment 15 | "$SCRIPTS_DIR/clean_plugins.sh" --tmux-echo >/dev/null 2>&1 16 | reload_tmux_environment 17 | end_message 18 | } 19 | main 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/bindings/install_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Tmux key-binding script. 4 | # Scripts intended to be used via the command line are in `bin/` directory. 5 | 6 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 7 | SCRIPTS_DIR="$CURRENT_DIR/../scripts" 8 | HELPERS_DIR="$SCRIPTS_DIR/helpers" 9 | 10 | source "$HELPERS_DIR/tmux_echo_functions.sh" 11 | source "$HELPERS_DIR/tmux_utils.sh" 12 | 13 | main() { 14 | reload_tmux_environment 15 | "$SCRIPTS_DIR/install_plugins.sh" --tmux-echo >/dev/null 2>&1 16 | reload_tmux_environment 17 | end_message 18 | } 19 | main 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/bindings/update_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Tmux key-binding script. 4 | # Scripts intended to be used via the command line are in `bin/` directory. 5 | 6 | # This script: 7 | # - shows a list of installed plugins 8 | # - starts a prompt to enter the name of the plugin that will be updated 9 | 10 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 | SCRIPTS_DIR="$CURRENT_DIR/../scripts" 12 | HELPERS_DIR="$SCRIPTS_DIR/helpers" 13 | 14 | source "$HELPERS_DIR/plugin_functions.sh" 15 | source "$HELPERS_DIR/tmux_echo_functions.sh" 16 | source "$HELPERS_DIR/tmux_utils.sh" 17 | 18 | display_plugin_update_list() { 19 | local plugins="$(tpm_plugins_list_helper)" 20 | tmux_echo "Installed plugins:" 21 | tmux_echo "" 22 | 23 | for plugin in $plugins; do 24 | # displaying only installed plugins 25 | if plugin_already_installed "$plugin"; then 26 | local plugin_name="$(plugin_name_helper "$plugin")" 27 | tmux_echo " $plugin_name" 28 | fi 29 | done 30 | 31 | tmux_echo "" 32 | tmux_echo "Type plugin name to update it." 33 | tmux_echo "" 34 | tmux_echo "- \"all\" - updates all plugins" 35 | tmux_echo "- ENTER - cancels" 36 | } 37 | 38 | update_plugin_prompt() { 39 | tmux command-prompt -p 'plugin update:' " \ 40 | send-keys C-c; \ 41 | run-shell '$SCRIPTS_DIR/update_plugin_prompt_handler.sh %1'" 42 | } 43 | 44 | main() { 45 | reload_tmux_environment 46 | display_plugin_update_list 47 | update_plugin_prompt 48 | } 49 | main 50 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/docs/automatic_tpm_installation.md: -------------------------------------------------------------------------------- 1 | # Automatic tpm installation 2 | 3 | One of the first things we do on a new machine is cloning our dotfiles. Not everything comes with them though, so for example `tpm` most likely won't be installed. 4 | 5 | If you want to install `tpm` and plugins automatically when tmux is started, put the following snippet in `.tmux.conf` before the final `run '~/.tmux/plugins/tpm/tpm'`: 6 | 7 | ``` 8 | if "test ! -d ~/.tmux/plugins/tpm" \ 9 | "run 'git clone https://github.com/tmux-plugins/tpm ~/.tmux/plugins/tpm && ~/.tmux/plugins/tpm/bin/install_plugins'" 10 | ``` 11 | 12 | This useful tip was submitted by @acr4 and narfman0. 13 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/docs/changing_plugins_install_dir.md: -------------------------------------------------------------------------------- 1 | # Changing plugins install dir 2 | 3 | By default, TPM installs plugins in a subfolder named `plugins/` inside 4 | `$XDG_CONFIG_HOME/tmux/` if a `tmux.conf` file was found at that location, or 5 | inside `~/.tmux/` otherwise. 6 | 7 | You can change the install path by putting this in `.tmux.conf`: 8 | 9 | set-environment -g TMUX_PLUGIN_MANAGER_PATH '/some/other/path/' 10 | 11 | Tmux plugin manager initialization in `.tmux.conf` should also be updated: 12 | 13 | # initializes TMUX plugin manager in a new path 14 | run /some/other/path/tpm/tpm 15 | 16 | Please make sure that the `run` line is at the very bottom of `.tmux.conf`. 17 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/docs/how_to_create_plugin.md: -------------------------------------------------------------------------------- 1 | # How to create Tmux plugins 2 | 3 | Creating a new plugin is easy. 4 | 5 | For demonstration purposes we'll create a simple plugin that lists all 6 | installed TPM plugins. Yes, a plugin that lists plugins :) We'll bind that to 7 | `prefix + T`. 8 | 9 | The source code for this example plugin can be found 10 | [here](https://github.com/tmux-plugins/tmux-example-plugin). 11 | 12 | ### 1. create a new git project 13 | 14 | TPM depends on git for downloading and updating plugins. 15 | 16 | To create a new git project: 17 | 18 | $ mkdir tmux_my_plugin 19 | $ cd tmux_my_plugin 20 | $ git init 21 | 22 | ### 2. create a `*.tmux` plugin run file 23 | 24 | When it sources a plugin, TPM executes all `*.tmux` files in your plugins' 25 | directory. That's how plugins are run. 26 | 27 | Create a plugin run file in plugin directory: 28 | 29 | $ touch my_plugin.tmux 30 | $ chmod u+x my_plugin.tmux 31 | 32 | You can have more than one `*.tmux` file, and all will get executed. However, usually 33 | you'll need just one. 34 | 35 | ### 3. create a plugin key binding 36 | 37 | We want the behavior of the plugin to trigger when a user hits `prefix + T`. 38 | 39 | Key `T` is chosen because: 40 | - it's "kind of" a mnemonic for `TPM` 41 | - the key is not used by Tmux natively. Tmux man page, KEY BINDINGS section 42 | contains a list of all the bindings Tmux uses. There's plenty of unused keys 43 | and we don't want to override any of Tmux default key bindings. 44 | 45 | Open the plugin run file in your favorite text editor: 46 | 47 | $ vim my_plugin.tmux 48 | # or 49 | $ subl my_plugin.tmux 50 | 51 | Put the following content in the file: 52 | 53 | #!/usr/bin/env bash 54 | 55 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 56 | tmux bind-key T run-shell "$CURRENT_DIR/scripts/tmux_list_plugins.sh" 57 | 58 | As you can see, plugin run file is a simple bash script that sets up the binding. 59 | 60 | When pressed, `prefix + T` will execute another shell script: 61 | `tmux_list_plugins.sh`. That script should be in `scripts/` directory - 62 | relative to the plugin run file. 63 | 64 | 65 | ### 4. listing plugins 66 | 67 | Now that we have the binding, let's create a script that's invoked with 68 | `prefix + T`. 69 | 70 | $ mkdir scripts 71 | $ touch scripts/tmux_list_plugins.sh 72 | $ chmod u+x scripts/tmux_list_plugins.sh 73 | 74 | And here's the script content: 75 | 76 | #!/usr/bin/env bash 77 | 78 | # fetching the directory where plugins are installed 79 | plugin_path="$(tmux show-env -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" 80 | 81 | # listing installed plugins 82 | ls -1 "$plugin_path" 83 | 84 | ### 5. try it out 85 | 86 | To see if this works, execute the plugin run file: 87 | 88 | $ ./my_plugin.tmux 89 | 90 | That should set up the key binding. Now hit `prefix + T` and see if it works. 91 | 92 | ### 6. publish the plugin 93 | 94 | When everything is ready, push the plugin to an online git repository, 95 | preferably GitHub. 96 | 97 | Other users can install your plugin by just adding plugin git URL to the 98 | `@plugin` list in their `.tmux.conf`. 99 | 100 | If the plugin is on GitHub, your users will be able to use the shorthand of 101 | `github_username/repository`. 102 | 103 | ### Conclusion 104 | 105 | Hopefully, that was easy. As you can see, it's mostly shell scripting. 106 | 107 | You can use other scripting languages (ruby, python etc) but plain old shell 108 | is preferred because of portability. 109 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/docs/managing_plugins_via_cmd_line.md: -------------------------------------------------------------------------------- 1 | # Managing plugins via the command line 2 | 3 | Aside from tmux key bindings, TPM provides shell interface for managing plugins 4 | via scripts located in [bin/](../bin/) directory. 5 | 6 | Tmux does not need to be started in order to run scripts (but it's okay if it 7 | is). If you [changed tpm install dir](../docs/changing_plugins_install_dir.md) 8 | in `.tmux.conf` that should work fine too. 9 | 10 | Prerequisites: 11 | 12 | - tmux installed on the system (doh) 13 | - `.tmux.conf` set up for TPM 14 | 15 | ### Installing plugins 16 | 17 | As usual, plugins need to be specified in `.tmux.conf`. Run the following 18 | command to install plugins: 19 | 20 | ~/.tmux/plugins/tpm/bin/install_plugins 21 | 22 | ### Updating plugins 23 | 24 | To update all installed plugins: 25 | 26 | ~/.tmux/plugins/tpm/bin/update_plugins all 27 | 28 | or update a single plugin: 29 | 30 | ~/.tmux/plugins/tpm/bin/update_plugins tmux-sensible 31 | 32 | ### Removing plugins 33 | 34 | To remove plugins not on the plugin list: 35 | 36 | ~/.tmux/plugins/tpm/bin/clean_plugins 37 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/docs/tpm_not_working.md: -------------------------------------------------------------------------------- 1 | # Help, tpm not working! 2 | 3 | Here's the list of issues users had with `tpm`: 4 | 5 |
6 | 7 | > Nothing works. `tpm` key bindings `prefix + I`, `prefix + U` not even 8 | defined. 9 | 10 | Related [issue #22](https://github.com/tmux-plugins/tpm/issues/22) 11 | 12 | - Do you have required `tmux` version to run `tpm`?
13 | Check `tmux` version with `$ tmux -V` command and make sure it's higher or 14 | equal to the required version for `tpm` as stated in the readme. 15 | 16 | - ZSH tmux plugin might be causing issues.
17 | If you have it installed, try disabling it and see if `tpm` works then. 18 | 19 |
20 | 21 | > Help, I'm using custom config file with `tmux -f /path/to/my_tmux.conf` 22 | to start Tmux and for some reason plugins aren't loaded!? 23 | 24 | Related [issue #57](https://github.com/tmux-plugins/tpm/issues/57) 25 | 26 | `tpm` has a known issue when using custom config file with `-f` option. 27 | The solution is to use alternative plugin definition syntax. Here are the steps 28 | to make it work: 29 | 30 | 1. remove all `set -g @plugin` lines from tmux config file 31 | 2. in the config file define the plugins in the following way: 32 | 33 | # List of plugins 34 | set -g @tpm_plugins ' \ 35 | tmux-plugins/tpm \ 36 | tmux-plugins/tmux-sensible \ 37 | tmux-plugins/tmux-resurrect \ 38 | ' 39 | 40 | # Initialize TMUX plugin manager (keep this line at the very bottom of tmux.conf) 41 | run '~/.tmux/plugins/tpm/tpm' 42 | 43 | 3. Reload TMUX environment so TPM is sourced: `$ tmux source /path/to/my_tmux.conf` 44 | 45 | The plugins should now be working. 46 | 47 |
48 | 49 | > Weird sequence of characters show up when installing or updating plugins 50 | 51 | Related: [issue #25](https://github.com/tmux-plugins/tpm/issues/25) 52 | 53 | - This could be caused by [tmuxline.vim](https://github.com/edkolev/tmuxline.vim) 54 | plugin. Uninstall it and see if things work. 55 | 56 |
57 | 58 | > "failed to connect to server" error when sourcing .tmux.conf 59 | 60 | Related: [issue #48](https://github.com/tmux-plugins/tpm/issues/48) 61 | 62 | - Make sure `tmux source ~/.tmux.conf` command is ran from inside `tmux`. 63 | 64 |
65 | 66 | > tpm not working: '~/.tmux/plugins/tpm/tpm' returned 2 (Windows / Cygwin) 67 | 68 | Related: [issue #81](https://github.com/tmux-plugins/tpm/issues/81) 69 | 70 | This issue is most likely caused by Windows line endings. For example, if you 71 | have git's `core.autocrlf` option set to `true`, git will automatically convert 72 | all the files to Windows line endings which might cause a problem. 73 | 74 | The solution is to convert all line ending to Unix newline characters. This 75 | command handles that for all files under `.tmux/` dir (skips `.git` 76 | subdirectories): 77 | 78 | ```bash 79 | find ~/.tmux -type d -name '.git*' -prune -o -type f -print0 | xargs -0 dos2unix 80 | ``` 81 | 82 |
83 | 84 | > '~/.tmux/plugins/tpm/tpm' returned 127 (on macOS, w/ tmux installed using brew) 85 | 86 | Related: [issue #67](https://github.com/tmux-plugins/tpm/issues/67) 87 | 88 | This problem is because tmux's `run-shell` command runs a shell which doesn't read from user configs, thus tmux installed in `/usr/local/bin` will not be found. 89 | 90 | The solution is to insert the following line: 91 | 92 | ``` 93 | set-environment -g PATH "/usr/local/bin:/bin:/usr/bin" 94 | ``` 95 | 96 | before any `run-shell`/`run` commands in `~/.tmux.conf`. 97 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/.gitignore: -------------------------------------------------------------------------------- 1 | .vagrant/ 2 | lib/ 3 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/.travis.yml: -------------------------------------------------------------------------------- 1 | # generic packages and tmux 2 | before_install: 3 | - sudo apt-get update 4 | - sudo apt-get install -y git-core expect 5 | - sudo apt-get install -y python-software-properties software-properties-common 6 | - sudo apt-get install -y libevent-dev libncurses-dev 7 | - git clone https://github.com/tmux/tmux.git 8 | - cd tmux 9 | - git checkout 2.0 10 | - sh autogen.sh 11 | - ./configure && make && sudo make install 12 | 13 | install: 14 | - git fetch --unshallow --recurse-submodules || git fetch --recurse-submodules 15 | # manual `git clone` required for testing `tmux-test` plugin itself 16 | - git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test; true 17 | - lib/tmux-test/setup 18 | 19 | script: ./tests/run_tests_in_isolation 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | ### master 4 | - move `setup` task to `.travis.yml` for travis tests 5 | - "merge" travis.yml and travis_for_plugins.yml files (no need to keep em 6 | separate) 7 | - add more useful helper functions 8 | - remove tmux-test repo as a submodule from self, this causes issues with 9 | `$ git submodule update --recursive --init` command that some users use for 10 | managing other plugins 11 | - add new helper `teardown_helper` 12 | - add `run_tests` helper 13 | - change CLI syntax for choosing vagrant machine to run the tests on 14 | - enable running just a single test via `run_tests` cli interface 15 | - add `--keep-running` cli option to continue running vagrant after the tests 16 | are done executing 17 | - start using tmux 2.0 for tests 18 | 19 | ### v0.2.0, 2015-02-22 20 | - `setup` script gitignores `tests/helpers.sh` 21 | - move `tests/helpers.sh` to `tests/helpers/helpers.sh` 22 | - `setup` undo removes added lines from gitignore file 23 | 24 | ### v0.1.0, 2015-02-22 25 | - changes so that 'tmux-test' can be included with tmux plugins 26 | - do not gitignore submodules directory 27 | - add installation and usage instructions 28 | - copy `.travis.yml` to the project root when running `setup` script 29 | - add a brief mention of travis CI to the readme 30 | - add test helpers 31 | - `setup` script symlinks helpers file to `tests/` directory 32 | - `setup` script can undo most of its actions 33 | - add a tmux scripting test 34 | - `tmux-test` uses `tmux-test` to test itself 35 | - update `tmux-test` submodule 36 | - a different `travis.yml` for `tmux-test` and for plugins 37 | 38 | ### v0.0.1, 2015-02-21 39 | - git init 40 | - add vagrant provisioning scripts for ubuntu and debian 41 | - add a ".travis.yml" file 42 | - generic "run_tests" script 43 | - "run_tests_in_isolation" script 44 | - add "Vagrantfile" 45 | - enable passing VM names as arguments to "run_tests" script 46 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (C) Bruno Sutic 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the "Software"), 5 | to deal in the Software without restriction, including without limitation 6 | the rights to use, copy, modify, merge, publish, distribute, sublicense, 7 | and/or sell copies of the Software, and to permit persons to whom the 8 | Software is furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included 11 | in all copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 14 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES 15 | OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 16 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 17 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 18 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE 19 | OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 20 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/README.md: -------------------------------------------------------------------------------- 1 | # tmux-test 2 | 3 | [![Build Status](https://travis-ci.org/tmux-plugins/tmux-test.png?branch=master)](https://travis-ci.org/tmux-plugins/tmux-test) 4 | 5 | A small framework for isolated testing of tmux plugins. Isolation is achieved by 6 | running the tests in `Vagrant`. Works on [travis](travis-ci.org) too. 7 | 8 | Extracted from [tmux plugin manager](https://github.com/tmux-plugins/tpm) and 9 | [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat). 10 | 11 | Dependencies: `Vagrant` (no required when running on travis). 12 | 13 | ### Setup 14 | 15 | Let's say you made tmux plugin with the following file hierarchy: 16 | 17 | ```text 18 | /tmux-plugin 19 | |-- plugin.tmux 20 | `-- scripts 21 | `-- plugin_script.sh 22 | ``` 23 | 24 | From your project root directory (tmux-plugin/) execute the following shell 25 | command to fetch `tmux-test` and add it as a submodule: 26 | 27 | $ git submodule add https://github.com/tmux-plugins/tmux-test.git lib/tmux-test 28 | 29 | Run the `setup` script: 30 | 31 | $ lib/tmux-test/setup 32 | 33 | The project directory will now look like this (additions have comments): 34 | 35 | ```text 36 | /tmux-plugin 37 | |-- plugin.tmux 38 | |-- run_tests # symlink, gitignored 39 | |-- .gitignore # 2 lines appended to gitignore 40 | |-- .travis.yml # added 41 | |-- lib/tmux-test/ # git submodule 42 | |-- scripts 43 | | `-- plugin_script.sh 44 | `-- tests # dir to put the tests in 45 | `-- run_tests_in_isolation.sh # symlink, gitignored 46 | `-- helpers 47 | `-- helpers.sh # symlinked bash helpers, gitignored 48 | ``` 49 | 50 | `tmux-test` is now set up. You are ok to commit the additions to the repo. 51 | 52 | ### Writing and running tests 53 | 54 | A test is any executable with a name starting with `test_` in `tests/` 55 | directory. 56 | 57 | Now that you installed `tmux-test` let's create an example test. 58 | 59 | - create a `tests/test_example.sh` file with the following content (it's a 60 | `bash` script but it can be any executable): 61 | 62 | #/usr/bin/env bash 63 | 64 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 65 | 66 | # bash helpers provided by 'tmux-test' 67 | source $CURRENT_DIR/helpers/helpers.sh 68 | 69 | # installs plugin from current repo in Vagrant (or on Travis) 70 | install_tmux_plugin_under_test_helper 71 | 72 | # start tmux in background (plugin under test is sourced) 73 | tmux new -d 74 | 75 | # get first session name 76 | session_name="$(tmux list-sessions -F "#{session_name}")" 77 | 78 | # fail the test if first session name is not "0" 79 | if [ "$session_name" == "0" ]; then 80 | # fail_helper is also provided by 'tmux-test' 81 | fail_helper "First session name is not '0' by default" 82 | fi 83 | 84 | # sets the right script exit code ('tmux-test' helper) 85 | exit_helper 86 | 87 | - make the test file executable with `$ chmod +x tests/test_example.sh` 88 | - run the test by executing `./run_tests` from the project root directory 89 | - the first invocation might take some time because Vagrant's ubuntu virtual 90 | machine is downloading. You should see `Success, tests pass!` message when it's 91 | done. 92 | 93 | Check out more example test scripts in this project's [tests/ directory](tests/). 94 | 95 | ### Continuous integration 96 | 97 | The setup script (`lib/tmux-test/setup`) added a `.travis.yml` file to the 98 | project root. To setup continuous integration, just add/enable the project on 99 | [travis](travis-ci.org). 100 | 101 | ### Notes 102 | 103 | - The `tests/` directory for tests and `lib/tmux-test/` for cloning `tmux-test` 104 | into cannot be changed currently 105 | - Don't run `tests/run_tests_in_isolation` script on your local development 106 | environment. That's an internal test runner meant to be executed in an 107 | isolated environment like `vagrant` or `travis`.
108 | Use `./run_tests` script. 109 | - You can use `KEEP_RUNNING=true ./run_tests` for faster test running cycle. 110 | If this case `Vagrant` will keep running even after the tests are done. 111 | - You can use `VAGRANT_CWD=lib/tmux-text/ vagrant ssh ubuntu` for ssh login to 112 | `Vagrant`. 113 | 114 | ### Running `tmux-test` framework tests 115 | 116 | `tmux-test` uses itself to test itself. To run framework tests: 117 | 118 | - clone this project `$ git clone git@github.com:tmux-plugins/tmux-test.git` 119 | - `$ cd tmux-test` 120 | - run `$ ./run_framework_tests` 121 | 122 | ### Other goodies 123 | 124 | - [tmux-copycat](https://github.com/tmux-plugins/tmux-copycat) - a plugin for 125 | regex searches in tmux and fast match selection 126 | - [tmux-continuum](https://github.com/tmux-plugins/tmux-continuum) - automatic 127 | restoring and continuous saving of tmux env 128 | 129 | You might want to follow [@brunosutic](https://twitter.com/brunosutic) on 130 | twitter if you want to hear about new tmux plugins or feature updates. 131 | 132 | ### License 133 | 134 | [MIT](LICENSE.md) 135 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/Vagrantfile: -------------------------------------------------------------------------------- 1 | VAGRANTFILE_API_VERSION = "2" 2 | 3 | Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| 4 | 5 | config.vm.synced_folder "../../", "/vagrant" 6 | 7 | config.vm.define :ubuntu do |ubuntu| 8 | ubuntu.vm.box = "hashicorp/precise64" 9 | ubuntu.vm.provision "shell", path: "vagrant_ubuntu_provisioning.sh" 10 | end 11 | 12 | config.vm.define :centos do |centos| 13 | centos.vm.box = "chef/centos-6.5" 14 | centos.vm.provision "shell", path: "vagrant_centos_provisioning.sh" 15 | end 16 | 17 | end 18 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/run_framework_tests: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This file is used to run "tmux-test" framework tests. 4 | 5 | # "setup" script is needed to run the tests, but it overrides some working dir 6 | # files. To address that, "setup" is run before the tests and it's actions are 7 | # undone after. 8 | 9 | main() { 10 | git clone https://github.com/tmux-plugins/tmux-test lib/tmux-test 11 | lib/tmux-test/setup 12 | ./run_tests 13 | local exit_value=$? 14 | lib/tmux-test/setup "undo" 15 | exit "$exit_value" 16 | } 17 | main 18 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # invoke this script from your projects root directory 4 | 5 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | 7 | # pass "undo" as a script arg to undo most of the setup actions 8 | UNDO_SETUP="$1" 9 | undo() { 10 | [ "$UNDO_SETUP" == "undo" ] 11 | } 12 | 13 | restore() { 14 | local file="$1" 15 | rm -f "$file" 16 | git checkout -- "$file" 2>/dev/null 17 | } 18 | 19 | gitignore() { 20 | local file="$1" 21 | grep -q "^${file}$" .gitignore 2>/dev/null || echo "$file" >> .gitignore 22 | } 23 | 24 | remove_from_gitignore() { 25 | local file="$1" 26 | local escaped_filename="$(echo "$file" | sed "s,/,\\\/,g")" 27 | sed -i"" "/^${escaped_filename}$/d" .gitignore 28 | } 29 | 30 | add_files_to_gitignore() { 31 | if ! undo; then 32 | gitignore "run_tests" 33 | gitignore "tests/run_tests_in_isolation" 34 | gitignore "tests/helpers/helpers.sh" 35 | else 36 | remove_from_gitignore "run_tests" 37 | remove_from_gitignore "tests/run_tests_in_isolation" 38 | remove_from_gitignore "tests/helpers/helpers.sh" 39 | fi 40 | } 41 | 42 | symlink_user_test_runner() { 43 | local file="run_tests" 44 | if ! undo; then 45 | ln -sf "lib/tmux-test/${file}" "$file" 46 | else 47 | restore "$file" 48 | fi 49 | } 50 | 51 | create_directory_for_tests() { 52 | if ! undo; then 53 | mkdir -p tests/helpers/ 54 | fi 55 | } 56 | 57 | symlink_internal_test_runner() { 58 | local file="tests/run_tests_in_isolation" 59 | if ! undo; then 60 | ln -sf "../lib/tmux-test/${file}" "$file" 61 | else 62 | restore "$file" 63 | fi 64 | } 65 | 66 | symlink_test_helpers() { 67 | local file="tests/helpers/helpers.sh" 68 | if ! undo; then 69 | ln -sf "../../lib/tmux-test/${file}" "$file" 70 | else 71 | restore "$file" 72 | fi 73 | } 74 | 75 | copy_travis_yml() { 76 | local file=".travis.yml" 77 | if ! undo; then 78 | cp "lib/tmux-test/${file}" "$file" 79 | else 80 | restore "$file" 81 | fi 82 | } 83 | 84 | main() { 85 | add_files_to_gitignore 86 | symlink_user_test_runner 87 | create_directory_for_tests 88 | symlink_internal_test_runner 89 | symlink_test_helpers 90 | copy_travis_yml 91 | } 92 | main 93 | 94 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/tests/helpers/helpers.sh: -------------------------------------------------------------------------------- 1 | # This file is a symlink from 'tmux-test' plugin. 2 | # You probably don't want to edit it. 3 | 4 | 5 | # Global variable that keeps the value of test status (success/fail). 6 | # Suggested usage is via `fail_helper` and `exit_helper` functions. 7 | TEST_STATUS="success" 8 | 9 | # PRIVATE FUNCTIONS 10 | 11 | _clone_the_plugin() { 12 | local plugin_path="${HOME}/.tmux/plugins/tmux-plugin-under-test/" 13 | rm -rf "$plugin_path" 14 | git clone --recursive "${CURRENT_DIR}/../" "$plugin_path" >/dev/null 2>&1 15 | } 16 | 17 | _add_plugin_to_tmux_conf() { 18 | set_tmux_conf_helper<<-HERE 19 | run-shell '~/.tmux/plugins/tmux-plugin-under-test/*.tmux' 20 | HERE 21 | } 22 | 23 | # PUBLIC HELPER FUNCTIONS 24 | 25 | teardown_helper() { 26 | rm -f ~/.tmux.conf 27 | rm -rf ~/.tmux/ 28 | tmux kill-server >/dev/null 2>&1 29 | } 30 | 31 | set_tmux_conf_helper() { 32 | > ~/.tmux.conf # empty tmux.conf file 33 | while read line; do 34 | echo "$line" >> ~/.tmux.conf 35 | done 36 | } 37 | 38 | fail_helper() { 39 | local message="$1" 40 | echo "$message" >&2 41 | TEST_STATUS="fail" 42 | } 43 | 44 | exit_helper() { 45 | teardown_helper 46 | if [ "$TEST_STATUS" == "fail" ]; then 47 | echo "FAIL!" 48 | echo 49 | exit 1 50 | else 51 | echo "SUCCESS" 52 | echo 53 | exit 0 54 | fi 55 | } 56 | 57 | install_tmux_plugin_under_test_helper() { 58 | _clone_the_plugin 59 | _add_plugin_to_tmux_conf 60 | } 61 | 62 | run_tests() { 63 | # get all the functions starting with 'test_' and invoke them 64 | for test in $(compgen -A function | grep "^test_"); do 65 | "$test" 66 | done 67 | exit_helper 68 | } 69 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/tests/run_tests_in_isolation: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # This file is a symlink from 'tmux-test' plugin. 4 | # You probably don't want to edit it. 5 | 6 | # This script should be run within an isolated enviroment (Vagrant, travis). 7 | # Depending on what the tests do, it might NOT be safe to run this script 8 | # directly on the development machine. 9 | 10 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 11 | 12 | EXIT_VALUE=0 # running a test suite is successful by default 13 | 14 | all_test_files() { 15 | ls -1 "$CURRENT_DIR" | # test files are in the current dir 16 | \grep -i "^test" | # test file names start with "test" 17 | xargs # file names in a single line 18 | } 19 | 20 | set_exit_val_to_false() { 21 | EXIT_VALUE=1 22 | } 23 | 24 | run_tests() { 25 | local test_file tests_files 26 | if [ "$#" -gt 0 ]; then 27 | test_files="${@//tests\//}" # remove 'tests/' directory prefix 28 | else 29 | test_files="$(all_test_files)" 30 | fi 31 | for test_file in $test_files; do 32 | echo "Running test: $test_file" 33 | "${CURRENT_DIR}/${test_file}" 34 | 35 | # handling exit value 36 | local test_exit_value="$?" 37 | if [ "$test_exit_value" -ne 0 ]; then 38 | set_exit_val_to_false 39 | fi 40 | done 41 | } 42 | 43 | main() { 44 | run_tests "$@" 45 | exit "$EXIT_VALUE" 46 | } 47 | main "$@" 48 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/tests/test_basic_script_execution.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | exit 0 4 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/tests/test_default_session_name.sh: -------------------------------------------------------------------------------- 1 | #/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | # bash helpers provided by 'tmux-test' 6 | source $CURRENT_DIR/helpers/helpers.sh 7 | 8 | # installs plugin from current repo in Vagrant (or on Travis) 9 | install_tmux_plugin_under_test_helper 10 | 11 | # start tmux in background (plugin under test is sourced) 12 | tmux new -d 13 | 14 | # get first session name 15 | session_name="$(tmux list-sessions -F "#{session_name}")" 16 | 17 | # fail the test if first session name is not "0" 18 | if ! [ "$session_name" == "0" ]; then 19 | # fail_helper is also provided by 'tmux-test' 20 | fail_helper "First session name is not '0' by default" 21 | fi 22 | 23 | # sets the right script exit code ('tmux-test' helper) 24 | exit_helper 25 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/tests/test_tmux_scripting.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | 5 | source $CURRENT_DIR/helpers/helpers.sh 6 | 7 | number_of_windows() { 8 | tmux list-windows | 9 | wc -l | 10 | sed "s/ //g" 11 | } 12 | 13 | main() { 14 | # start tmux in the background 15 | tmux new -d 16 | tmux new-window 17 | 18 | local number_of_windows="$(number_of_windows)" 19 | if ! [ "$number_of_windows" -eq 2 ]; then 20 | fail_helper "Incorrect number of windows. Expected 2, got $number_of_windows" 21 | fi 22 | exit_helper 23 | } 24 | main 25 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/vagrant_centos_provisioning.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # libevent2 installation instructions from here 4 | # https://gist.github.com/rschuman/6168833 5 | 6 | sudo su - 7 | 8 | yum -y install gcc kernel-devel make automake autoconf ncurses-devel 9 | yum -y install git-core expect vim ruby ruby-devel ruby-irb 10 | 11 | # install libevent2 from source 12 | curl http://sourceforge.net/projects/levent/files/latest/download?source=files -L -o libevent2.tar.gz -w 'Last URL was: %{url_effective}' 13 | cd ~/downloads 14 | tar zxvf libevent2.tar.gz 15 | cd ./libevent-* 16 | ./configure --prefix=/usr/local 17 | make 18 | make install 19 | 20 | # compile tmux 21 | git clone https://github.com/tmux/tmux.git ~/tmux_source 22 | cd ~/tmux_source 23 | git checkout 2.0 24 | sh autogen.sh 25 | LDFLAGS="-L/usr/local/lib -Wl,-rpath=/usr/local/lib" ./configure --prefix=/usr/local 26 | make && sudo make install 27 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/lib/tmux-test/vagrant_ubuntu_provisioning.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | sudo apt-get update 4 | sudo apt-get install -y git-core expect vim 5 | sudo apt-get install -y python-software-properties software-properties-common 6 | sudo apt-get install -y build-essential libtool autotools-dev autoconf 7 | sudo apt-get install -y pkg-config libevent-dev libncurses-dev 8 | 9 | # install tmux 2.0 10 | git clone https://github.com/tmux/tmux.git ~/tmux_source 11 | cd ~/tmux_source 12 | git checkout 2.0 13 | sh autogen.sh 14 | ./configure && make && sudo make install 15 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/check_tmux_version.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | VERSION="$1" 4 | UNSUPPORTED_MSG="$2" 5 | 6 | get_tmux_option() { 7 | local option=$1 8 | local default_value=$2 9 | local option_value=$(tmux show-option -gqv "$option") 10 | if [ -z "$option_value" ]; then 11 | echo "$default_value" 12 | else 13 | echo "$option_value" 14 | fi 15 | } 16 | 17 | # Ensures a message is displayed for 5 seconds in tmux prompt. 18 | # Does not override the 'display-time' tmux option. 19 | display_message() { 20 | local message="$1" 21 | 22 | # display_duration defaults to 5 seconds, if not passed as an argument 23 | if [ "$#" -eq 2 ]; then 24 | local display_duration="$2" 25 | else 26 | local display_duration="5000" 27 | fi 28 | 29 | # saves user-set 'display-time' option 30 | local saved_display_time=$(get_tmux_option "display-time" "750") 31 | 32 | # sets message display time to 5 seconds 33 | tmux set-option -gq display-time "$display_duration" 34 | 35 | # displays message 36 | tmux display-message "$message" 37 | 38 | # restores original 'display-time' value 39 | tmux set-option -gq display-time "$saved_display_time" 40 | } 41 | 42 | # this is used to get "clean" integer version number. Examples: 43 | # `tmux 1.9` => `19` 44 | # `1.9a` => `19` 45 | get_digits_from_string() { 46 | local string="$1" 47 | local only_digits="$(echo "$string" | tr -dC '[:digit:]')" 48 | echo "$only_digits" 49 | } 50 | 51 | tmux_version_int() { 52 | local tmux_version_string=$(tmux -V) 53 | echo "$(get_digits_from_string "$tmux_version_string")" 54 | } 55 | 56 | unsupported_version_message() { 57 | if [ -n "$UNSUPPORTED_MSG" ]; then 58 | echo "$UNSUPPORTED_MSG" 59 | else 60 | echo "Error, Tmux version unsupported! Please install Tmux version $VERSION or greater!" 61 | fi 62 | } 63 | 64 | exit_if_unsupported_version() { 65 | local current_version="$1" 66 | local supported_version="$2" 67 | if [ "$current_version" -lt "$supported_version" ]; then 68 | display_message "$(unsupported_version_message)" 69 | exit 1 70 | fi 71 | } 72 | 73 | main() { 74 | local supported_version_int="$(get_digits_from_string "$VERSION")" 75 | local current_version_int="$(tmux_version_int)" 76 | exit_if_unsupported_version "$current_version_int" "$supported_version_int" 77 | } 78 | main 79 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/clean_plugins.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | HELPERS_DIR="$CURRENT_DIR/helpers" 5 | 6 | source "$HELPERS_DIR/plugin_functions.sh" 7 | source "$HELPERS_DIR/utility.sh" 8 | 9 | if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions 10 | source "$HELPERS_DIR/tmux_echo_functions.sh" 11 | else # shell output functions 12 | source "$HELPERS_DIR/shell_echo_functions.sh" 13 | fi 14 | 15 | clean_plugins() { 16 | local plugins plugin plugin_directory 17 | plugins="$(tpm_plugins_list_helper)" 18 | 19 | for plugin_directory in "$(tpm_path)"/*; do 20 | [ -d "${plugin_directory}" ] || continue 21 | plugin="$(plugin_name_helper "${plugin_directory}")" 22 | case "${plugins}" in 23 | *"${plugin}"*) : ;; 24 | *) 25 | [ "${plugin}" = "tpm" ] && continue 26 | echo_ok "Removing \"$plugin\"" 27 | rm -rf "${plugin_directory}" >/dev/null 2>&1 28 | [ -d "${plugin_directory}" ] && 29 | echo_err " \"$plugin\" clean fail" || 30 | echo_ok " \"$plugin\" clean success" 31 | ;; 32 | esac 33 | done 34 | } 35 | 36 | main() { 37 | ensure_tpm_path_exists 38 | clean_plugins 39 | exit_value_helper 40 | } 41 | main 42 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/helpers/plugin_functions.sh: -------------------------------------------------------------------------------- 1 | # using @tpm_plugins is now deprecated in favor of using @plugin syntax 2 | tpm_plugins_variable_name="@tpm_plugins" 3 | 4 | # manually expanding tilde char or `$HOME` variable. 5 | _manual_expansion() { 6 | local path="$1" 7 | local expanded_tilde="${path/#\~/$HOME}" 8 | echo "${expanded_tilde/#\$HOME/$HOME}" 9 | } 10 | 11 | _tpm_path() { 12 | local string_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)/" 13 | _manual_expansion "$string_path" 14 | } 15 | 16 | _CACHED_TPM_PATH="$(_tpm_path)" 17 | 18 | # Get the absolute path to the users configuration file of TMux. 19 | # This includes a prioritized search on different locations. 20 | # 21 | _get_user_tmux_conf() { 22 | # Define the different possible locations. 23 | xdg_location="${XDG_CONFIG_HOME:-$HOME/.config}/tmux/tmux.conf" 24 | default_location="$HOME/.tmux.conf" 25 | 26 | # Search for the correct configuration file by priority. 27 | if [ -f "$xdg_location" ]; then 28 | echo "$xdg_location" 29 | 30 | else 31 | echo "$default_location" 32 | fi 33 | } 34 | 35 | _tmux_conf_contents() { 36 | user_config=$(_get_user_tmux_conf) 37 | cat /etc/tmux.conf "$user_config" 2>/dev/null 38 | if [ "$1" == "full" ]; then # also output content from sourced files 39 | local file 40 | for file in $(_sourced_files); do 41 | cat $(_manual_expansion "$file") 2>/dev/null 42 | done 43 | fi 44 | } 45 | 46 | # return files sourced from tmux config files 47 | _sourced_files() { 48 | _tmux_conf_contents | 49 | sed -E -n -e "s/^[[:space:]]*source(-file)?[[:space:]]+(-q+[[:space:]]+)?['\"]?([^'\"]+)['\"]?/\3/p" 50 | } 51 | 52 | # Want to be able to abort in certain cases 53 | trap "exit 1" TERM 54 | export TOP_PID=$$ 55 | 56 | _fatal_error_abort() { 57 | echo >&2 "Aborting." 58 | kill -s TERM $TOP_PID 59 | } 60 | 61 | # PUBLIC FUNCTIONS BELOW 62 | 63 | tpm_path() { 64 | if [ "$_CACHED_TPM_PATH" == "/" ]; then 65 | echo >&2 "FATAL: Tmux Plugin Manager not configured in tmux.conf" 66 | _fatal_error_abort 67 | fi 68 | echo "$_CACHED_TPM_PATH" 69 | } 70 | 71 | tpm_plugins_list_helper() { 72 | # lists plugins from @tpm_plugins option 73 | echo "$(tmux start-server\; show-option -gqv "$tpm_plugins_variable_name")" 74 | 75 | # read set -g @plugin "tmux-plugins/tmux-example-plugin" entries 76 | _tmux_conf_contents "full" | 77 | awk '/^[ \t]*set(-option)? +-g +@plugin/ { gsub(/'\''/,""); gsub(/'\"'/,""); print $4 }' 78 | } 79 | 80 | # Allowed plugin name formats: 81 | # 1. "git://github.com/user/plugin_name.git" 82 | # 2. "user/plugin_name" 83 | plugin_name_helper() { 84 | local plugin="$1" 85 | # get only the part after the last slash, e.g. "plugin_name.git" 86 | local plugin_basename="$(basename "$plugin")" 87 | # remove ".git" extension (if it exists) to get only "plugin_name" 88 | local plugin_name="${plugin_basename%.git}" 89 | echo "$plugin_name" 90 | } 91 | 92 | plugin_path_helper() { 93 | local plugin="$1" 94 | local plugin_name="$(plugin_name_helper "$plugin")" 95 | echo "$(tpm_path)${plugin_name}/" 96 | } 97 | 98 | plugin_already_installed() { 99 | local plugin="$1" 100 | local plugin_path="$(plugin_path_helper "$plugin")" 101 | [ -d "$plugin_path" ] && 102 | cd "$plugin_path" && 103 | git remote >/dev/null 2>&1 104 | } 105 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/helpers/shell_echo_functions.sh: -------------------------------------------------------------------------------- 1 | echo_ok() { 2 | echo "$*" 3 | } 4 | 5 | echo_err() { 6 | fail_helper "$*" 7 | } 8 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/helpers/tmux_echo_functions.sh: -------------------------------------------------------------------------------- 1 | _has_emacs_mode_keys() { 2 | $(tmux show -gw mode-keys | grep -q emacs) 3 | } 4 | 5 | tmux_echo() { 6 | local message="$1" 7 | tmux run-shell "echo '$message'" 8 | } 9 | 10 | echo_ok() { 11 | tmux_echo "$*" 12 | } 13 | 14 | echo_err() { 15 | tmux_echo "$*" 16 | } 17 | 18 | end_message() { 19 | if _has_emacs_mode_keys; then 20 | local continue_key="ESCAPE" 21 | else 22 | local continue_key="ENTER" 23 | fi 24 | tmux_echo "" 25 | tmux_echo "TMUX environment reloaded." 26 | tmux_echo "" 27 | tmux_echo "Done, press $continue_key to continue." 28 | } 29 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/helpers/tmux_utils.sh: -------------------------------------------------------------------------------- 1 | HELPERS_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 2 | source "$HELPERS_DIR/plugin_functions.sh" 3 | 4 | reload_tmux_environment() { 5 | tmux source-file $(_get_user_tmux_conf) >/dev/null 2>&1 6 | } 7 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/helpers/utility.sh: -------------------------------------------------------------------------------- 1 | ensure_tpm_path_exists() { 2 | mkdir -p "$(tpm_path)" 3 | } 4 | 5 | fail_helper() { 6 | local message="$1" 7 | echo "$message" >&2 8 | FAIL="true" 9 | } 10 | 11 | exit_value_helper() { 12 | if [ "$FAIL" == "true" ]; then 13 | exit 1 14 | else 15 | exit 0 16 | fi 17 | } 18 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/install_plugins.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | HELPERS_DIR="$CURRENT_DIR/helpers" 5 | 6 | source "$HELPERS_DIR/plugin_functions.sh" 7 | source "$HELPERS_DIR/utility.sh" 8 | 9 | if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions 10 | source "$HELPERS_DIR/tmux_echo_functions.sh" 11 | else # shell output functions 12 | source "$HELPERS_DIR/shell_echo_functions.sh" 13 | fi 14 | 15 | clone() { 16 | local plugin="$1" 17 | local branch="$2" 18 | if [ -n "$branch" ]; then 19 | cd "$(tpm_path)" && 20 | GIT_TERMINAL_PROMPT=0 git clone -b "$branch" --single-branch --recursive "$plugin" >/dev/null 2>&1 21 | else 22 | cd "$(tpm_path)" && 23 | GIT_TERMINAL_PROMPT=0 git clone --single-branch --recursive "$plugin" >/dev/null 2>&1 24 | fi 25 | } 26 | 27 | # tries cloning: 28 | # 1. plugin name directly - works if it's a valid git url 29 | # 2. expands the plugin name to point to a GitHub repo and tries cloning again 30 | clone_plugin() { 31 | local plugin="$1" 32 | local branch="$2" 33 | clone "$plugin" "$branch" || 34 | clone "https://git::@github.com/$plugin" "$branch" 35 | } 36 | 37 | # clone plugin and produce output 38 | install_plugin() { 39 | local plugin="$1" 40 | local branch="$2" 41 | local plugin_name="$(plugin_name_helper "$plugin")" 42 | 43 | if plugin_already_installed "$plugin"; then 44 | echo_ok "Already installed \"$plugin_name\"" 45 | else 46 | echo_ok "Installing \"$plugin_name\"" 47 | clone_plugin "$plugin" "$branch" && 48 | echo_ok " \"$plugin_name\" download success" || 49 | echo_err " \"$plugin_name\" download fail" 50 | fi 51 | } 52 | 53 | install_plugins() { 54 | local plugins="$(tpm_plugins_list_helper)" 55 | for plugin in $plugins; do 56 | IFS='#' read -ra plugin <<< "$plugin" 57 | install_plugin "${plugin[0]}" "${plugin[1]}" 58 | done 59 | } 60 | 61 | verify_tpm_path_permissions() { 62 | local path="$(tpm_path)" 63 | # check the write permission flag for all users to ensure 64 | # that we have proper access 65 | [ -w "$path" ] || 66 | echo_err "$path is not writable!" 67 | } 68 | 69 | main() { 70 | ensure_tpm_path_exists 71 | verify_tpm_path_permissions 72 | install_plugins 73 | exit_value_helper 74 | } 75 | main 76 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/source_plugins.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | HELPERS_DIR="$CURRENT_DIR/helpers" 5 | 6 | source "$HELPERS_DIR/plugin_functions.sh" 7 | 8 | plugin_dir_exists() { 9 | [ -d "$1" ] 10 | } 11 | 12 | # Runs all *.tmux files from the plugin directory. 13 | # Files are ran as executables. 14 | # No errors if the plugin dir does not exist. 15 | silently_source_all_tmux_files() { 16 | local plugin_path="$1" 17 | local plugin_tmux_files="$plugin_path*.tmux" 18 | if plugin_dir_exists "$plugin_path"; then 19 | for tmux_file in $plugin_tmux_files; do 20 | # if the glob didn't find any files this will be the 21 | # unexpanded glob which obviously doesn't exist 22 | [ -f "$tmux_file" ] || continue 23 | # runs *.tmux file as an executable 24 | $tmux_file >/dev/null 2>&1 25 | done 26 | fi 27 | } 28 | 29 | source_plugins() { 30 | local plugin plugin_path 31 | local plugins="$(tpm_plugins_list_helper)" 32 | for plugin in $plugins; do 33 | IFS='#' read -ra plugin <<< "$plugin" 34 | plugin_path="$(plugin_path_helper "${plugin[0]}")" 35 | silently_source_all_tmux_files "$plugin_path" 36 | done 37 | } 38 | 39 | main() { 40 | source_plugins 41 | } 42 | main 43 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/update_plugin.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # this script handles core logic of updating plugins 4 | 5 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 6 | HELPERS_DIR="$CURRENT_DIR/helpers" 7 | 8 | source "$HELPERS_DIR/plugin_functions.sh" 9 | source "$HELPERS_DIR/utility.sh" 10 | 11 | if [ "$1" == "--tmux-echo" ]; then # tmux-specific echo functions 12 | source "$HELPERS_DIR/tmux_echo_functions.sh" 13 | else # shell output functions 14 | source "$HELPERS_DIR/shell_echo_functions.sh" 15 | fi 16 | 17 | # from now on ignore first script argument 18 | shift 19 | 20 | pull_changes() { 21 | local plugin="$1" 22 | local plugin_path="$(plugin_path_helper "$plugin")" 23 | cd "$plugin_path" && 24 | GIT_TERMINAL_PROMPT=0 git pull && 25 | GIT_TERMINAL_PROMPT=0 git submodule update --init --recursive 26 | } 27 | 28 | update() { 29 | local plugin="$1" 30 | $(pull_changes "$plugin" > /dev/null 2>&1) && 31 | echo_ok " \"$plugin\" update success" || 32 | echo_err " \"$plugin\" update fail" 33 | } 34 | 35 | update_all() { 36 | echo_ok "Updating all plugins!" 37 | echo_ok "" 38 | local plugins="$(tpm_plugins_list_helper)" 39 | for plugin in $plugins; do 40 | IFS='#' read -ra plugin <<< "$plugin" 41 | local plugin_name="$(plugin_name_helper "${plugin[0]}")" 42 | # updating only installed plugins 43 | if plugin_already_installed "$plugin_name"; then 44 | update "$plugin_name" & 45 | fi 46 | done 47 | wait 48 | } 49 | 50 | update_plugins() { 51 | local plugins="$*" 52 | for plugin in $plugins; do 53 | IFS='#' read -ra plugin <<< "$plugin" 54 | local plugin_name="$(plugin_name_helper "${plugin[0]}")" 55 | if plugin_already_installed "$plugin_name"; then 56 | update "$plugin_name" & 57 | else 58 | echo_err "$plugin_name not installed!" & 59 | fi 60 | done 61 | wait 62 | } 63 | 64 | main() { 65 | ensure_tpm_path_exists 66 | if [ "$1" == "all" ]; then 67 | update_all 68 | else 69 | update_plugins "$*" 70 | fi 71 | exit_value_helper 72 | } 73 | main "$*" 74 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/update_plugin_prompt_handler.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | HELPERS_DIR="$CURRENT_DIR/helpers" 5 | 6 | if [ $# -eq 0 ]; then 7 | exit 0 8 | fi 9 | 10 | source "$HELPERS_DIR/tmux_echo_functions.sh" 11 | source "$HELPERS_DIR/tmux_utils.sh" 12 | 13 | main() { 14 | "$CURRENT_DIR/update_plugin.sh" --tmux-echo "$*" 15 | reload_tmux_environment 16 | end_message 17 | } 18 | main "$*" 19 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/scripts/variables.sh: -------------------------------------------------------------------------------- 1 | install_key_option="@tpm-install" 2 | default_install_key="I" 3 | 4 | update_key_option="@tpm-update" 5 | default_update_key="U" 6 | 7 | clean_key_option="@tpm-clean" 8 | default_clean_key="M-u" 9 | 10 | SUPPORTED_TMUX_VERSION="1.9" 11 | 12 | DEFAULT_TPM_ENV_VAR_NAME="TMUX_PLUGIN_MANAGER_PATH" 13 | DEFAULT_TPM_PATH="$HOME/.tmux/plugins/" 14 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/expect_failed_plugin_download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect 2 | 3 | # disables script output 4 | log_user 0 5 | 6 | spawn tmux 7 | 8 | # Waiting for tmux to attach. If this is not done, next command, `send` will 9 | # not work properly. 10 | sleep 1 11 | 12 | # this is tmux prefix + I 13 | send "I" 14 | 15 | # cloning might take a while 16 | set timeout 20 17 | 18 | expect_after { 19 | timeout { exit 1 } 20 | } 21 | 22 | expect { 23 | "Installing \"non-existing-plugin\"" 24 | } 25 | 26 | expect { 27 | "\"non-existing-plugin\" download fail" 28 | } 29 | 30 | expect { 31 | "Done, press ENTER to continue" { 32 | exit 0 33 | } 34 | } 35 | 36 | exit 1 37 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/expect_successful_clean_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect 2 | 3 | # disables script output 4 | log_user 0 5 | 6 | spawn tmux 7 | 8 | # Waiting for tmux to attach. If this is not done, next command, `send` will 9 | # not work properly. 10 | sleep 1 11 | 12 | # this is tmux prefix + alt + u 13 | send "u" 14 | 15 | set timeout 5 16 | 17 | expect_after { 18 | timeout { exit 1 } 19 | } 20 | 21 | expect { 22 | "Removing \"tmux-example-plugin\"" 23 | } 24 | 25 | expect { 26 | "\"tmux-example-plugin\" clean success" 27 | } 28 | 29 | expect { 30 | "Done, press ENTER to continue." { 31 | exit 0 32 | } 33 | } 34 | 35 | exit 1 36 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/expect_successful_multiple_plugins_download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect 2 | 3 | # disables script output 4 | log_user 0 5 | 6 | spawn tmux 7 | 8 | # Waiting for tmux to attach. If this is not done, next command, `send` will 9 | # not work properly. 10 | sleep 1 11 | 12 | # this is tmux prefix + I 13 | send "I" 14 | 15 | # cloning might take a while 16 | set timeout 15 17 | 18 | expect_after { 19 | timeout { exit 1 } 20 | } 21 | 22 | expect { 23 | "Installing \"tmux-example-plugin\"" 24 | } 25 | 26 | expect { 27 | "\"tmux-example-plugin\" download success" 28 | } 29 | 30 | expect { 31 | "Installing \"tmux-copycat\"" 32 | } 33 | 34 | expect { 35 | "\"tmux-copycat\" download success" 36 | } 37 | 38 | expect { 39 | "Done, press ENTER to continue." { 40 | exit 0 41 | } 42 | } 43 | 44 | exit 1 45 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/expect_successful_plugin_download: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect 2 | 3 | # disables script output 4 | log_user 0 5 | 6 | spawn tmux 7 | 8 | # Waiting for tmux to attach. If this is not done, next command, `send` will 9 | # not work properly. 10 | sleep 1 11 | 12 | # this is tmux prefix + I 13 | send "I" 14 | 15 | # cloning might take a while 16 | set timeout 15 17 | 18 | expect_after { 19 | timeout { exit 1 } 20 | } 21 | 22 | expect { 23 | "Installing \"tmux-example-plugin\"" 24 | } 25 | 26 | expect { 27 | "\"tmux-example-plugin\" download success" 28 | } 29 | 30 | expect { 31 | "Done, press ENTER to continue" { 32 | send " " 33 | } 34 | } 35 | 36 | sleep 1 37 | # this is tmux prefix + I 38 | send "I" 39 | 40 | expect { 41 | "Already installed \"tmux-example-plugin\"" 42 | } 43 | 44 | expect { 45 | "Done, press ENTER to continue" { 46 | exit 0 47 | } 48 | } 49 | 50 | exit 1 51 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/expect_successful_update_of_a_single_plugin: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect 2 | 3 | # disables script output 4 | log_user 0 5 | 6 | spawn tmux 7 | 8 | # Waiting for tmux to attach. If this is not done, next command, `send` will 9 | # not work properly. 10 | sleep 1 11 | 12 | # this is tmux prefix + U 13 | send "U" 14 | 15 | set timeout 15 16 | 17 | expect_after { 18 | timeout { exit 1 } 19 | } 20 | 21 | expect { 22 | "Installed plugins" 23 | } 24 | 25 | expect { 26 | "tmux-example-plugin" 27 | } 28 | 29 | expect { 30 | "\"all\" - updates all plugins" 31 | } 32 | 33 | expect { 34 | "ENTER - cancels" 35 | } 36 | 37 | # wait for tmux to display prompt before sending characters 38 | sleep 1 39 | send "tmux-example-plugin\r" 40 | 41 | expect { 42 | "Updating \"tmux-example-plugin\"" 43 | } 44 | 45 | expect { 46 | "\"tmux-example-plugin\" update success" 47 | } 48 | 49 | expect { 50 | "Done, press ENTER to continue." { 51 | exit 0 52 | } 53 | } 54 | 55 | exit 1 56 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/expect_successful_update_of_all_plugins: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env expect 2 | 3 | # disables script output 4 | log_user 0 5 | 6 | spawn tmux 7 | 8 | # Waiting for tmux to attach. If this is not done, next command, `send` will 9 | # not work properly. 10 | sleep 1 11 | 12 | # this is tmux prefix + U 13 | send "U" 14 | 15 | set timeout 5 16 | 17 | expect_after { 18 | timeout { exit 1 } 19 | } 20 | 21 | expect { 22 | "Installed plugins" 23 | } 24 | 25 | expect { 26 | "tmux-example-plugin" 27 | } 28 | 29 | expect { 30 | "\"all\" - updates all plugins" 31 | } 32 | 33 | expect { 34 | "ENTER - cancels" 35 | } 36 | 37 | # wait for tmux to display prompt before sending characters 38 | sleep 1 39 | send "all\r" 40 | 41 | expect { 42 | "Updating all plugins!" 43 | } 44 | 45 | expect { 46 | "Updating \"tmux-example-plugin\"" 47 | } 48 | 49 | expect { 50 | "\"tmux-example-plugin\" update success" 51 | } 52 | 53 | expect { 54 | "Done, press ENTER to continue." { 55 | exit 0 56 | } 57 | } 58 | 59 | exit 1 60 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/helpers/tpm.sh: -------------------------------------------------------------------------------- 1 | check_dir_exists_helper() { 2 | [ -d "$1" ] 3 | } 4 | 5 | # runs the scripts and asserts it has the correct output and exit code 6 | script_run_helper() { 7 | local script="$1" 8 | local expected_output="$2" 9 | local expected_exit_code="${3:-0}" 10 | $script 2>&1 | 11 | grep "$expected_output" >/dev/null 2>&1 && # grep -q flag quits the script early 12 | [ "${PIPESTATUS[0]}" -eq "$expected_exit_code" ] 13 | } 14 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/test_plugin_clean.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | TPM_DIR="$PWD" 5 | PLUGINS_DIR="$HOME/.tmux/plugins" 6 | 7 | source "$CURRENT_DIR/helpers/helpers.sh" 8 | source "$CURRENT_DIR/helpers/tpm.sh" 9 | 10 | manually_install_the_plugin() { 11 | rm -rf "$PLUGINS_DIR" 12 | mkdir -p "$PLUGINS_DIR" 13 | cd "$PLUGINS_DIR" 14 | git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin 15 | } 16 | 17 | # TMUX KEY-BINDING TESTS 18 | 19 | test_plugin_uninstallation_via_tmux_key_binding() { 20 | set_tmux_conf_helper <<- HERE 21 | set -g mode-keys vi 22 | run-shell "$TPM_DIR/tpm" 23 | HERE 24 | 25 | manually_install_the_plugin 26 | 27 | "$CURRENT_DIR/expect_successful_clean_plugins" || 28 | fail_helper "[key-binding] clean fails" 29 | 30 | teardown_helper 31 | } 32 | 33 | # SCRIPT TESTS 34 | 35 | test_plugin_uninstallation_via_script() { 36 | set_tmux_conf_helper <<- HERE 37 | set -g mode-keys vi 38 | run-shell "$TPM_DIR/tpm" 39 | HERE 40 | 41 | manually_install_the_plugin 42 | 43 | script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean success' || 44 | fail_helper "[script] plugin cleaning fails" 45 | 46 | teardown_helper 47 | } 48 | 49 | test_unsuccessful_plugin_uninstallation_via_script() { 50 | set_tmux_conf_helper <<- HERE 51 | set -g mode-keys vi 52 | run-shell "$TPM_DIR/tpm" 53 | HERE 54 | 55 | manually_install_the_plugin 56 | chmod 000 "$PLUGINS_DIR/tmux-example-plugin" # disable directory deletion 57 | 58 | local expected_exit_code=1 59 | script_run_helper "$TPM_DIR/bin/clean_plugins" '"tmux-example-plugin" clean fail' "$expected_exit_code" || 60 | fail_helper "[script] unsuccessful plugin cleaning doesn't fail" 61 | 62 | chmod 755 "$PLUGINS_DIR/tmux-example-plugin" # enable directory deletion 63 | 64 | teardown_helper 65 | } 66 | 67 | run_tests 68 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/test_plugin_installation_legacy.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | PLUGINS_DIR="$HOME/.tmux/plugins" 5 | TPM_DIR="$PWD" 6 | 7 | source "$CURRENT_DIR/helpers/helpers.sh" 8 | source "$CURRENT_DIR/helpers/tpm.sh" 9 | 10 | # TMUX KEY-BINDING TESTS 11 | 12 | test_plugin_installation_via_tmux_key_binding() { 13 | set_tmux_conf_helper <<- HERE 14 | set -g mode-keys vi 15 | set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" 16 | run-shell "$TPM_DIR/tpm" 17 | HERE 18 | 19 | # opens tmux and test it with `expect` 20 | $CURRENT_DIR/expect_successful_plugin_download || 21 | fail_helper "[key-binding] plugin installation fails" 22 | 23 | # check plugin dir exists after download 24 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || 25 | fail_helper "[key-binding] plugin download fails" 26 | 27 | teardown_helper 28 | } 29 | 30 | test_legacy_and_new_syntax_for_plugin_installation_work_via_tmux_key_binding() { 31 | set_tmux_conf_helper <<- HERE 32 | set -g mode-keys vi 33 | set -g @tpm_plugins " \ 34 | tmux-plugins/tmux-example-plugin \ 35 | " 36 | set -g @plugin 'tmux-plugins/tmux-copycat' 37 | run-shell "$TPM_DIR/tpm" 38 | HERE 39 | 40 | # opens tmux and test it with `expect` 41 | "$CURRENT_DIR"/expect_successful_multiple_plugins_download || 42 | fail_helper "[key-binding] multiple plugins installation fails" 43 | 44 | # check plugin dir exists after download 45 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || 46 | fail_helper "[key-binding] plugin download fails (tmux-example-plugin)" 47 | 48 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || 49 | fail_helper "[key-binding] plugin download fails (tmux-copycat)" 50 | 51 | teardown_helper 52 | } 53 | 54 | # SCRIPT TESTS 55 | 56 | test_plugin_installation_via_script() { 57 | set_tmux_conf_helper <<- HERE 58 | set -g mode-keys vi 59 | set -g @tpm_plugins "tmux-plugins/tmux-example-plugin" 60 | run-shell "$TPM_DIR/tpm" 61 | HERE 62 | 63 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || 64 | fail_helper "[script] plugin installation fails" 65 | 66 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || 67 | fail_helper "[script] plugin download fails" 68 | 69 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-example-plugin"' || 70 | fail_helper "[script] plugin already installed message fail" 71 | 72 | teardown_helper 73 | } 74 | 75 | test_legacy_and_new_syntax_for_plugin_installation_work_via_script() { 76 | set_tmux_conf_helper <<- HERE 77 | set -g mode-keys vi 78 | set -g @tpm_plugins " \ 79 | tmux-plugins/tmux-example-plugin \ 80 | " 81 | set -g @plugin 'tmux-plugins/tmux-copycat' 82 | run-shell "$TPM_DIR/tpm" 83 | HERE 84 | 85 | script_run_helper "$TPM_DIR/bin/install_plugins" '"tmux-example-plugin" download success' || 86 | fail_helper "[script] multiple plugin installation fails" 87 | 88 | check_dir_exists_helper "$PLUGINS_DIR/tmux-example-plugin/" || 89 | fail_helper "[script] plugin download fails (tmux-example-plugin)" 90 | 91 | check_dir_exists_helper "$PLUGINS_DIR/tmux-copycat/" || 92 | fail_helper "[script] plugin download fails (tmux-copycat)" 93 | 94 | script_run_helper "$TPM_DIR/bin/install_plugins" 'Already installed "tmux-copycat"' || 95 | fail_helper "[script] multiple plugins already installed message fail" 96 | 97 | teardown_helper 98 | } 99 | 100 | run_tests 101 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/test_plugin_sourcing.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | TPM_DIR="$PWD" 5 | PLUGINS_DIR="$HOME/.tmux/plugins" 6 | 7 | CUSTOM_PLUGINS_DIR="$HOME/foo/plugins" 8 | 9 | source "$CURRENT_DIR/helpers/helpers.sh" 10 | source "$CURRENT_DIR/helpers/tpm.sh" 11 | 12 | check_binding_defined() { 13 | local binding="$1" 14 | tmux list-keys | grep -q "$binding" 15 | } 16 | 17 | create_test_plugin_helper() { 18 | local plugin_path="$PLUGINS_DIR/tmux_test_plugin/" 19 | rm -rf "$plugin_path" 20 | mkdir -p "$plugin_path" 21 | 22 | while read line; do 23 | echo "$line" >> "$plugin_path/test_plugin.tmux" 24 | done 25 | chmod +x "$plugin_path/test_plugin.tmux" 26 | } 27 | 28 | check_tpm_path() { 29 | local correct_tpm_path="$1" 30 | local tpm_path="$(tmux start-server\; show-environment -g TMUX_PLUGIN_MANAGER_PATH | cut -f2 -d=)" 31 | [ "$correct_tpm_path" == "$tpm_path" ] 32 | } 33 | 34 | test_plugin_sourcing() { 35 | set_tmux_conf_helper <<- HERE 36 | set -g mode-keys vi 37 | set -g @plugin "doesnt_matter/tmux_test_plugin" 38 | run-shell "$TPM_DIR/tpm" 39 | HERE 40 | 41 | # manually creates a local tmux plugin 42 | create_test_plugin_helper <<- HERE 43 | tmux bind-key R run-shell foo_command 44 | HERE 45 | 46 | tmux new-session -d # tmux starts detached 47 | check_binding_defined "R run-shell foo_command" || 48 | fail_helper "Plugin sourcing fails" 49 | 50 | teardown_helper 51 | } 52 | 53 | test_default_tpm_path() { 54 | set_tmux_conf_helper <<- HERE 55 | set -g mode-keys vi 56 | run-shell "$TPM_DIR/tpm" 57 | HERE 58 | 59 | check_tpm_path "${PLUGINS_DIR}/" || 60 | fail_helper "Default TPM path not correct" 61 | 62 | teardown_helper 63 | } 64 | 65 | test_custom_tpm_path() { 66 | set_tmux_conf_helper <<- HERE 67 | set -g mode-keys vi 68 | set-environment -g TMUX_PLUGIN_MANAGER_PATH '$CUSTOM_PLUGINS_DIR' 69 | run-shell "$TPM_DIR/tpm" 70 | HERE 71 | 72 | check_tpm_path "$CUSTOM_PLUGINS_DIR" || 73 | fail_helper "Custom TPM path not correct" 74 | 75 | teardown_helper 76 | } 77 | 78 | run_tests 79 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tests/test_plugin_update.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | TPM_DIR="$PWD" 5 | PLUGINS_DIR="$HOME/.tmux/plugins" 6 | 7 | source "$CURRENT_DIR/helpers/helpers.sh" 8 | source "$CURRENT_DIR/helpers/tpm.sh" 9 | 10 | manually_install_the_plugin() { 11 | mkdir -p "$PLUGINS_DIR" 12 | cd "$PLUGINS_DIR" 13 | git clone --quiet https://github.com/tmux-plugins/tmux-example-plugin 14 | } 15 | 16 | # TMUX KEY-BINDING TESTS 17 | 18 | test_plugin_update_via_tmux_key_binding() { 19 | set_tmux_conf_helper <<- HERE 20 | set -g mode-keys vi 21 | set -g @plugin "tmux-plugins/tmux-example-plugin" 22 | run-shell "$TPM_DIR/tpm" 23 | HERE 24 | 25 | manually_install_the_plugin 26 | 27 | "$CURRENT_DIR/expect_successful_update_of_all_plugins" || 28 | fail_helper "[key-binding] 'update all plugins' fails" 29 | 30 | "$CURRENT_DIR/expect_successful_update_of_a_single_plugin" || 31 | fail_helper "[key-binding] 'update single plugin' fails" 32 | 33 | teardown_helper 34 | } 35 | 36 | # SCRIPT TESTS 37 | 38 | test_plugin_update_via_script() { 39 | set_tmux_conf_helper <<- HERE 40 | set -g mode-keys vi 41 | set -g @plugin "tmux-plugins/tmux-example-plugin" 42 | run-shell "$TPM_DIR/tpm" 43 | HERE 44 | 45 | manually_install_the_plugin 46 | 47 | local expected_exit_code=1 48 | script_run_helper "$TPM_DIR/bin/update_plugins" 'usage' "$expected_exit_code" || 49 | fail_helper "[script] running update plugins without args should fail" 50 | 51 | script_run_helper "$TPM_DIR/bin/update_plugins tmux-example-plugin" '"tmux-example-plugin" update success' || 52 | fail_helper "[script] plugin update fails" 53 | 54 | script_run_helper "$TPM_DIR/bin/update_plugins all" '"tmux-example-plugin" update success' || 55 | fail_helper "[script] update all plugins fails" 56 | 57 | teardown_helper 58 | } 59 | 60 | run_tests 61 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.tmux/plugins/tpm/tpm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | CURRENT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 4 | BINDINGS_DIR="$CURRENT_DIR/bindings" 5 | SCRIPTS_DIR="$CURRENT_DIR/scripts" 6 | 7 | source "$SCRIPTS_DIR/variables.sh" 8 | 9 | get_tmux_option() { 10 | local option="$1" 11 | local default_value="$2" 12 | local option_value="$(tmux show-option -gqv "$option")" 13 | if [ -z "$option_value" ]; then 14 | echo "$default_value" 15 | else 16 | echo "$option_value" 17 | fi 18 | } 19 | 20 | tpm_path_set() { 21 | tmux show-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" >/dev/null 2>&1 22 | } 23 | 24 | # Check if configuration file exists at an XDG-compatible location, if so use 25 | # that directory for TMUX_PLUGIN_MANAGER_PATH. Otherwise use $DEFAULT_TPM_PATH. 26 | set_default_tpm_path() { 27 | local xdg_tmux_path="${XDG_CONFIG_HOME:-$HOME/.config}/tmux" 28 | local tpm_path="$DEFAULT_TPM_PATH" 29 | 30 | if [ -f "$xdg_tmux_path/tmux.conf" ]; then 31 | tpm_path="$xdg_tmux_path/plugins/" 32 | fi 33 | 34 | tmux set-environment -g "$DEFAULT_TPM_ENV_VAR_NAME" "$tpm_path" 35 | } 36 | 37 | # Ensures TMUX_PLUGIN_MANAGER_PATH global env variable is set. 38 | # 39 | # Put this in `.tmux.conf` to override the default: 40 | # `set-environment -g TMUX_PLUGIN_MANAGER_PATH "/some/other/path/"` 41 | set_tpm_path() { 42 | if ! tpm_path_set; then 43 | set_default_tpm_path 44 | fi 45 | } 46 | 47 | # 1. Fetches plugin names from `@plugin` variables 48 | # 2. Creates full plugin path 49 | # 3. Sources all *.tmux files from each of the plugin directories 50 | # - no errors raised if directory does not exist 51 | # Files are sourced as tmux config files, not as shell scripts! 52 | source_plugins() { 53 | "$SCRIPTS_DIR/source_plugins.sh" >/dev/null 2>&1 54 | } 55 | 56 | # prefix + I - downloads TPM plugins and reloads TMUX environment 57 | # prefix + U - updates a plugin (or all of them) and reloads TMUX environment 58 | # prefix + alt + u - remove unused TPM plugins and reloads TMUX environment 59 | set_tpm_key_bindings() { 60 | local install_key="$(get_tmux_option "$install_key_option" "$default_install_key")" 61 | tmux bind-key "$install_key" run-shell "$BINDINGS_DIR/install_plugins" 62 | 63 | local update_key="$(get_tmux_option "$update_key_option" "$default_update_key")" 64 | tmux bind-key "$update_key" run-shell "$BINDINGS_DIR/update_plugins" 65 | 66 | local clean_key="$(get_tmux_option "$clean_key_option" "$default_clean_key")" 67 | tmux bind-key "$clean_key" run-shell "$BINDINGS_DIR/clean_plugins" 68 | } 69 | 70 | supported_tmux_version_ok() { 71 | "$SCRIPTS_DIR/check_tmux_version.sh" "$SUPPORTED_TMUX_VERSION" 72 | } 73 | 74 | main() { 75 | if supported_tmux_version_ok; then 76 | set_tpm_path 77 | set_tpm_key_bindings 78 | source_plugins 79 | fi 80 | } 81 | main 82 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/.vintrc.yaml: -------------------------------------------------------------------------------- 1 | cmdargs: 2 | severity: style_problem 3 | color: true 4 | env: 5 | neovim: false 6 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/LICENCE: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. 14 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/_config.yml: -------------------------------------------------------------------------------- 1 | theme: jekyll-theme-cayman -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/autoload/nerdtree.vim: -------------------------------------------------------------------------------- 1 | if exists('g:loaded_nerdtree_autoload') 2 | finish 3 | endif 4 | let g:loaded_nerdtree_autoload = 1 5 | 6 | let s:rootNERDTreePath = resolve(expand(':p:h:h')) 7 | 8 | "FUNCTION: nerdtree#version(...) {{{1 9 | " If any value is given as an argument, the entire line of text from the 10 | " change log is shown for the current version; otherwise, only the version 11 | " number is shown. 12 | function! nerdtree#version(...) abort 13 | let l:text = 'Unknown' 14 | try 15 | let l:changelog = readfile(join([s:rootNERDTreePath, 'CHANGELOG.md'], nerdtree#slash())) 16 | let l:line = 0 17 | while l:line <= len(l:changelog) 18 | if l:changelog[l:line] =~# '\d\+\.\d\+' 19 | let l:text = substitute(l:changelog[l:line], '.*\(\d\+.\d\+\).*', '\1', '') 20 | let l:text .= substitute(l:changelog[l:line+1], '^.\{-}\(\.\d\+\).\{-}:\(.*\)', a:0>0 ? '\1:\2' : '\1', '') 21 | break 22 | endif 23 | let l:line += 1 24 | endwhile 25 | catch 26 | endtry 27 | return l:text 28 | endfunction 29 | 30 | " SECTION: General Functions {{{1 31 | "============================================================ 32 | 33 | " FUNCTION: nerdtree#closeTreeOnOpen() {{{2 34 | function! nerdtree#closeTreeOnOpen() abort 35 | return g:NERDTreeQuitOnOpen == 1 || g:NERDTreeQuitOnOpen == 3 36 | endfunction 37 | 38 | " FUNCTION: nerdtree#closeBookmarksOnOpen() {{{2 39 | function! nerdtree#closeBookmarksOnOpen() abort 40 | return g:NERDTreeQuitOnOpen == 2 || g:NERDTreeQuitOnOpen == 3 41 | endfunction 42 | 43 | " FUNCTION: nerdtree#slash() {{{2 44 | " Return the path separator used by the underlying file system. Special 45 | " consideration is taken for the use of the 'shellslash' option on Windows 46 | " systems. 47 | function! nerdtree#slash() abort 48 | if nerdtree#runningWindows() 49 | if exists('+shellslash') && &shellslash 50 | return '/' 51 | endif 52 | 53 | return '\' 54 | endif 55 | 56 | return '/' 57 | endfunction 58 | 59 | "FUNCTION: nerdtree#checkForBrowse(dir) {{{2 60 | "inits a window tree in the current buffer if appropriate 61 | function! nerdtree#checkForBrowse(dir) abort 62 | if !isdirectory(a:dir) 63 | return 64 | endif 65 | 66 | if s:reuseWin(a:dir) 67 | return 68 | endif 69 | 70 | call g:NERDTreeCreator.CreateWindowTree(a:dir) 71 | endfunction 72 | 73 | "FUNCTION: s:reuseWin(dir) {{{2 74 | "finds a NERDTree buffer with root of dir, and opens it. 75 | function! s:reuseWin(dir) abort 76 | let path = g:NERDTreePath.New(fnamemodify(a:dir, ':p')) 77 | 78 | for i in range(1, bufnr('$')) 79 | unlet! nt 80 | let nt = getbufvar(i, 'NERDTree') 81 | if empty(nt) 82 | continue 83 | endif 84 | 85 | if nt.isWinTree() && nt.root.path.equals(path) 86 | call nt.setPreviousBuf(bufnr('#')) 87 | exec 'buffer ' . i 88 | return 1 89 | endif 90 | endfor 91 | 92 | return 0 93 | endfunction 94 | 95 | " FUNCTION: nerdtree#completeBookmarks(A,L,P) {{{2 96 | " completion function for the bookmark commands 97 | function! nerdtree#completeBookmarks(A,L,P) abort 98 | return filter(g:NERDTreeBookmark.BookmarkNames(), 'v:val =~# "^' . a:A . '"') 99 | endfunction 100 | 101 | "FUNCTION: nerdtree#compareNodes(n1, n2) {{{2 102 | function! nerdtree#compareNodes(n1, n2) abort 103 | return nerdtree#compareNodePaths(a:n1.path, a:n2.path) 104 | endfunction 105 | 106 | "FUNCTION: nerdtree#compareNodePaths(p1, p2) {{{2 107 | function! nerdtree#compareNodePaths(p1, p2) abort 108 | let sortKey1 = a:p1.getSortKey() 109 | let sortKey2 = a:p2.getSortKey() 110 | let i = 0 111 | while i < min([len(sortKey1), len(sortKey2)]) 112 | " Compare chunks upto common length. 113 | " If chunks have different type, the one which has 114 | " integer type is the lesser. 115 | if type(sortKey1[i]) == type(sortKey2[i]) 116 | if sortKey1[i] <# sortKey2[i] 117 | return - 1 118 | elseif sortKey1[i] ># sortKey2[i] 119 | return 1 120 | endif 121 | elseif type(sortKey1[i]) == type(0) 122 | return -1 123 | elseif type(sortKey2[i]) == type(0) 124 | return 1 125 | endif 126 | let i += 1 127 | endwhile 128 | 129 | " Keys are identical upto common length. 130 | " The key which has smaller chunks is the lesser one. 131 | if len(sortKey1) < len(sortKey2) 132 | return -1 133 | elseif len(sortKey1) > len(sortKey2) 134 | return 1 135 | else 136 | return 0 137 | endif 138 | endfunction 139 | 140 | " FUNCTION: nerdtree#deprecated(func, [msg]) {{{2 141 | " Issue a deprecation warning for a:func. If a second arg is given, use this 142 | " as the deprecation message 143 | function! nerdtree#deprecated(func, ...) abort 144 | let msg = a:0 ? a:func . ' ' . a:1 : a:func . ' is deprecated' 145 | 146 | if !exists('s:deprecationWarnings') 147 | let s:deprecationWarnings = {} 148 | endif 149 | if !has_key(s:deprecationWarnings, a:func) 150 | let s:deprecationWarnings[a:func] = 1 151 | echomsg msg 152 | endif 153 | endfunction 154 | 155 | " FUNCTION: nerdtree#exec(cmd, ignoreAll) {{{2 156 | " Same as :exec cmd but, if ignoreAll is TRUE, set eventignore=all for the duration 157 | function! nerdtree#exec(cmd, ignoreAll) abort 158 | let old_ei = &eventignore 159 | if a:ignoreAll 160 | set eventignore=all 161 | endif 162 | try 163 | exec a:cmd 164 | finally 165 | let &eventignore = old_ei 166 | endtry 167 | endfunction 168 | 169 | " FUNCTION: nerdtree#has_opt(options, name) {{{2 170 | function! nerdtree#has_opt(options, name) abort 171 | return has_key(a:options, a:name) && a:options[a:name] ==# 1 172 | endfunction 173 | 174 | " FUNCTION: nerdtree#loadClassFiles() {{{2 175 | function! nerdtree#loadClassFiles() abort 176 | runtime lib/nerdtree/path.vim 177 | runtime lib/nerdtree/menu_controller.vim 178 | runtime lib/nerdtree/menu_item.vim 179 | runtime lib/nerdtree/key_map.vim 180 | runtime lib/nerdtree/bookmark.vim 181 | runtime lib/nerdtree/tree_file_node.vim 182 | runtime lib/nerdtree/tree_dir_node.vim 183 | runtime lib/nerdtree/opener.vim 184 | runtime lib/nerdtree/creator.vim 185 | runtime lib/nerdtree/flag_set.vim 186 | runtime lib/nerdtree/nerdtree.vim 187 | runtime lib/nerdtree/ui.vim 188 | runtime lib/nerdtree/event.vim 189 | runtime lib/nerdtree/notifier.vim 190 | endfunction 191 | 192 | " FUNCTION: nerdtree#postSourceActions() {{{2 193 | function! nerdtree#postSourceActions() abort 194 | call g:NERDTreeBookmark.CacheBookmarks(1) 195 | call nerdtree#ui_glue#createDefaultBindings() 196 | 197 | "load all nerdtree plugins 198 | runtime! nerdtree_plugin/**/*.vim 199 | endfunction 200 | 201 | "FUNCTION: nerdtree#runningWindows(dir) {{{2 202 | function! nerdtree#runningWindows() abort 203 | return has('win16') || has('win32') || has('win64') 204 | endfunction 205 | 206 | "FUNCTION: nerdtree#runningCygwin(dir) {{{2 207 | function! nerdtree#runningCygwin() abort 208 | return has('win32unix') 209 | endfunction 210 | 211 | " SECTION: View Functions {{{1 212 | "============================================================ 213 | 214 | "FUNCTION: nerdtree#echo {{{2 215 | "A wrapper for :echo. Appends 'NERDTree:' on the front of all messages 216 | " 217 | "Args: 218 | "msg: the message to echo 219 | function! nerdtree#echo(msg) abort 220 | redraw 221 | echomsg empty(a:msg) ? '' : ('NERDTree: ' . a:msg) 222 | endfunction 223 | 224 | "FUNCTION: nerdtree#echoError {{{2 225 | "Wrapper for nerdtree#echo, sets the message type to errormsg for this message 226 | "Args: 227 | "msg: the message to echo 228 | function! nerdtree#echoError(msg) abort 229 | echohl errormsg 230 | call nerdtree#echo(a:msg) 231 | echohl normal 232 | endfunction 233 | 234 | "FUNCTION: nerdtree#echoWarning {{{2 235 | "Wrapper for nerdtree#echo, sets the message type to warningmsg for this message 236 | "Args: 237 | "msg: the message to echo 238 | function! nerdtree#echoWarning(msg) abort 239 | echohl warningmsg 240 | call nerdtree#echo(a:msg) 241 | echohl normal 242 | endfunction 243 | 244 | "FUNCTION: nerdtree#renderView {{{2 245 | function! nerdtree#renderView() abort 246 | call b:NERDTree.render() 247 | endfunction 248 | 249 | " vim: set sw=4 sts=4 et fdm=marker: 250 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/doc/tags: -------------------------------------------------------------------------------- 1 | :NERDTree NERDTree.txt /*:NERDTree* 2 | :NERDTreeCWD NERDTree.txt /*:NERDTreeCWD* 3 | :NERDTreeClose NERDTree.txt /*:NERDTreeClose* 4 | :NERDTreeFind NERDTree.txt /*:NERDTreeFind* 5 | :NERDTreeFocus NERDTree.txt /*:NERDTreeFocus* 6 | :NERDTreeFromBookmark NERDTree.txt /*:NERDTreeFromBookmark* 7 | :NERDTreeMirror NERDTree.txt /*:NERDTreeMirror* 8 | :NERDTreeRefreshRoot NERDTree.txt /*:NERDTreeRefreshRoot* 9 | :NERDTreeToggle NERDTree.txt /*:NERDTreeToggle* 10 | :NERDTreeToggleVCS NERDTree.txt /*:NERDTreeToggleVCS* 11 | :NERDTreeVCS NERDTree.txt /*:NERDTreeVCS* 12 | NERDTree NERDTree.txt /*NERDTree* 13 | NERDTree- NERDTree.txt /*NERDTree-* 14 | NERDTree-? NERDTree.txt /*NERDTree-?* 15 | NERDTree-A NERDTree.txt /*NERDTree-A* 16 | NERDTree-B NERDTree.txt /*NERDTree-B* 17 | NERDTree-C NERDTree.txt /*NERDTree-C* 18 | NERDTree-C-J NERDTree.txt /*NERDTree-C-J* 19 | NERDTree-C-K NERDTree.txt /*NERDTree-C-K* 20 | NERDTree-CD NERDTree.txt /*NERDTree-CD* 21 | NERDTree-D NERDTree.txt /*NERDTree-D* 22 | NERDTree-F NERDTree.txt /*NERDTree-F* 23 | NERDTree-I NERDTree.txt /*NERDTree-I* 24 | NERDTree-J NERDTree.txt /*NERDTree-J* 25 | NERDTree-K NERDTree.txt /*NERDTree-K* 26 | NERDTree-O NERDTree.txt /*NERDTree-O* 27 | NERDTree-P NERDTree.txt /*NERDTree-P* 28 | NERDTree-R NERDTree.txt /*NERDTree-R* 29 | NERDTree-T NERDTree.txt /*NERDTree-T* 30 | NERDTree-U NERDTree.txt /*NERDTree-U* 31 | NERDTree-X NERDTree.txt /*NERDTree-X* 32 | NERDTree-cd NERDTree.txt /*NERDTree-cd* 33 | NERDTree-contents NERDTree.txt /*NERDTree-contents* 34 | NERDTree-e NERDTree.txt /*NERDTree-e* 35 | NERDTree-f NERDTree.txt /*NERDTree-f* 36 | NERDTree-gi NERDTree.txt /*NERDTree-gi* 37 | NERDTree-go NERDTree.txt /*NERDTree-go* 38 | NERDTree-gs NERDTree.txt /*NERDTree-gs* 39 | NERDTree-i NERDTree.txt /*NERDTree-i* 40 | NERDTree-m NERDTree.txt /*NERDTree-m* 41 | NERDTree-o NERDTree.txt /*NERDTree-o* 42 | NERDTree-p NERDTree.txt /*NERDTree-p* 43 | NERDTree-q NERDTree.txt /*NERDTree-q* 44 | NERDTree-r NERDTree.txt /*NERDTree-r* 45 | NERDTree-s NERDTree.txt /*NERDTree-s* 46 | NERDTree-t NERDTree.txt /*NERDTree-t* 47 | NERDTree-u NERDTree.txt /*NERDTree-u* 48 | NERDTree-x NERDTree.txt /*NERDTree-x* 49 | NERDTree.txt NERDTree.txt /*NERDTree.txt* 50 | NERDTreeAPI NERDTree.txt /*NERDTreeAPI* 51 | NERDTreeAbout NERDTree.txt /*NERDTreeAbout* 52 | NERDTreeAddKeyMap() NERDTree.txt /*NERDTreeAddKeyMap()* 53 | NERDTreeAddMenuItem() NERDTree.txt /*NERDTreeAddMenuItem()* 54 | NERDTreeAddMenuSeparator() NERDTree.txt /*NERDTreeAddMenuSeparator()* 55 | NERDTreeAddPathFilter() NERDTree.txt /*NERDTreeAddPathFilter()* 56 | NERDTreeAddSubmenu() NERDTree.txt /*NERDTreeAddSubmenu()* 57 | NERDTreeAutoCenter NERDTree.txt /*NERDTreeAutoCenter* 58 | NERDTreeAutoCenterThreshold NERDTree.txt /*NERDTreeAutoCenterThreshold* 59 | NERDTreeAutoDeleteBuffer NERDTree.txt /*NERDTreeAutoDeleteBuffer* 60 | NERDTreeBookmarkCommands NERDTree.txt /*NERDTreeBookmarkCommands* 61 | NERDTreeBookmarkTable NERDTree.txt /*NERDTreeBookmarkTable* 62 | NERDTreeBookmarks NERDTree.txt /*NERDTreeBookmarks* 63 | NERDTreeBookmarksFile NERDTree.txt /*NERDTreeBookmarksFile* 64 | NERDTreeBookmarksSort NERDTree.txt /*NERDTreeBookmarksSort* 65 | NERDTreeCascadeOpenSingleChildDir NERDTree.txt /*NERDTreeCascadeOpenSingleChildDir* 66 | NERDTreeCascadeSingleChildDir NERDTree.txt /*NERDTreeCascadeSingleChildDir* 67 | NERDTreeCaseSensitiveSort NERDTree.txt /*NERDTreeCaseSensitiveSort* 68 | NERDTreeChDirMode NERDTree.txt /*NERDTreeChDirMode* 69 | NERDTreeCreatePrefix NERDTree.txt /*NERDTreeCreatePrefix* 70 | NERDTreeCustomOpenArgs NERDTree.txt /*NERDTreeCustomOpenArgs* 71 | NERDTreeDirArrowCollapsible NERDTree.txt /*NERDTreeDirArrowCollapsible* 72 | NERDTreeDirArrowExpandable NERDTree.txt /*NERDTreeDirArrowExpandable* 73 | NERDTreeFunctionality NERDTree.txt /*NERDTreeFunctionality* 74 | NERDTreeGlobalCommands NERDTree.txt /*NERDTreeGlobalCommands* 75 | NERDTreeHighlightCursorline NERDTree.txt /*NERDTreeHighlightCursorline* 76 | NERDTreeHijackNetrw NERDTree.txt /*NERDTreeHijackNetrw* 77 | NERDTreeIgnore NERDTree.txt /*NERDTreeIgnore* 78 | NERDTreeInvalidBookmarks NERDTree.txt /*NERDTreeInvalidBookmarks* 79 | NERDTreeKeymapAPI NERDTree.txt /*NERDTreeKeymapAPI* 80 | NERDTreeLicense NERDTree.txt /*NERDTreeLicense* 81 | NERDTreeMapCWD NERDTree.txt /*NERDTreeMapCWD* 82 | NERDTreeMapChangeRoot NERDTree.txt /*NERDTreeMapChangeRoot* 83 | NERDTreeMapChdir NERDTree.txt /*NERDTreeMapChdir* 84 | NERDTreeMapCloseChildren NERDTree.txt /*NERDTreeMapCloseChildren* 85 | NERDTreeMapCloseDir NERDTree.txt /*NERDTreeMapCloseDir* 86 | NERDTreeMapCustomOpen NERDTree.txt /*NERDTreeMapCustomOpen* 87 | NERDTreeMapDeleteBookmark NERDTree.txt /*NERDTreeMapDeleteBookmark* 88 | NERDTreeMapHelp NERDTree.txt /*NERDTreeMapHelp* 89 | NERDTreeMapJumpFirstChild NERDTree.txt /*NERDTreeMapJumpFirstChild* 90 | NERDTreeMapJumpLastChild NERDTree.txt /*NERDTreeMapJumpLastChild* 91 | NERDTreeMapJumpNextSibling NERDTree.txt /*NERDTreeMapJumpNextSibling* 92 | NERDTreeMapJumpParent NERDTree.txt /*NERDTreeMapJumpParent* 93 | NERDTreeMapJumpPrevSibling NERDTree.txt /*NERDTreeMapJumpPrevSibling* 94 | NERDTreeMapJumpRoot NERDTree.txt /*NERDTreeMapJumpRoot* 95 | NERDTreeMapMenu NERDTree.txt /*NERDTreeMapMenu* 96 | NERDTreeMapOpenExpl NERDTree.txt /*NERDTreeMapOpenExpl* 97 | NERDTreeMapOpenInTab NERDTree.txt /*NERDTreeMapOpenInTab* 98 | NERDTreeMapOpenInTabSilent NERDTree.txt /*NERDTreeMapOpenInTabSilent* 99 | NERDTreeMapOpenRecursively NERDTree.txt /*NERDTreeMapOpenRecursively* 100 | NERDTreeMapOpenSplit NERDTree.txt /*NERDTreeMapOpenSplit* 101 | NERDTreeMapOpenVSplit NERDTree.txt /*NERDTreeMapOpenVSplit* 102 | NERDTreeMapPreviewSplit NERDTree.txt /*NERDTreeMapPreviewSplit* 103 | NERDTreeMapPreviewVSplit NERDTree.txt /*NERDTreeMapPreviewVSplit* 104 | NERDTreeMapQuit NERDTree.txt /*NERDTreeMapQuit* 105 | NERDTreeMapRefresh NERDTree.txt /*NERDTreeMapRefresh* 106 | NERDTreeMapRefreshRoot NERDTree.txt /*NERDTreeMapRefreshRoot* 107 | NERDTreeMapToggleBookmarks NERDTree.txt /*NERDTreeMapToggleBookmarks* 108 | NERDTreeMapToggleFiles NERDTree.txt /*NERDTreeMapToggleFiles* 109 | NERDTreeMapToggleFilters NERDTree.txt /*NERDTreeMapToggleFilters* 110 | NERDTreeMapToggleHidden NERDTree.txt /*NERDTreeMapToggleHidden* 111 | NERDTreeMapToggleZoom NERDTree.txt /*NERDTreeMapToggleZoom* 112 | NERDTreeMapUpdir NERDTree.txt /*NERDTreeMapUpdir* 113 | NERDTreeMapUpdirKeepOpen NERDTree.txt /*NERDTreeMapUpdirKeepOpen* 114 | NERDTreeMappings NERDTree.txt /*NERDTreeMappings* 115 | NERDTreeMarkBookmarks NERDTree.txt /*NERDTreeMarkBookmarks* 116 | NERDTreeMenu NERDTree.txt /*NERDTreeMenu* 117 | NERDTreeMenu-j NERDTree.txt /*NERDTreeMenu-j* 118 | NERDTreeMenu-k NERDTree.txt /*NERDTreeMenu-k* 119 | NERDTreeMenuAPI NERDTree.txt /*NERDTreeMenuAPI* 120 | NERDTreeMenuDown NERDTree.txt /*NERDTreeMenuDown* 121 | NERDTreeMenuUp NERDTree.txt /*NERDTreeMenuUp* 122 | NERDTreeMinimalMenu NERDTree.txt /*NERDTreeMinimalMenu* 123 | NERDTreeMinimalUI NERDTree.txt /*NERDTreeMinimalUI* 124 | NERDTreeMouseMode NERDTree.txt /*NERDTreeMouseMode* 125 | NERDTreeNaturalSort NERDTree.txt /*NERDTreeNaturalSort* 126 | NERDTreeNodeDelimiter NERDTree.txt /*NERDTreeNodeDelimiter* 127 | NERDTreePathListenerAPI NERDTree.txt /*NERDTreePathListenerAPI* 128 | NERDTreeQuitOnOpen NERDTree.txt /*NERDTreeQuitOnOpen* 129 | NERDTreeRender() NERDTree.txt /*NERDTreeRender()* 130 | NERDTreeRespectWildIgnore NERDTree.txt /*NERDTreeRespectWildIgnore* 131 | NERDTreeSettings NERDTree.txt /*NERDTreeSettings* 132 | NERDTreeSettingsDetails NERDTree.txt /*NERDTreeSettingsDetails* 133 | NERDTreeSettingsSummary NERDTree.txt /*NERDTreeSettingsSummary* 134 | NERDTreeShowBookmarks NERDTree.txt /*NERDTreeShowBookmarks* 135 | NERDTreeShowFiles NERDTree.txt /*NERDTreeShowFiles* 136 | NERDTreeShowHidden NERDTree.txt /*NERDTreeShowHidden* 137 | NERDTreeShowLineNumbers NERDTree.txt /*NERDTreeShowLineNumbers* 138 | NERDTreeSortOrder NERDTree.txt /*NERDTreeSortOrder* 139 | NERDTreeStatusline NERDTree.txt /*NERDTreeStatusline* 140 | NERDTreeUseTCD NERDTree.txt /*NERDTreeUseTCD* 141 | NERDTreeWinPos NERDTree.txt /*NERDTreeWinPos* 142 | NERDTreeWinSize NERDTree.txt /*NERDTreeWinSize* 143 | loaded_nerd_tree NERDTree.txt /*loaded_nerd_tree* 144 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/event.vim: -------------------------------------------------------------------------------- 1 | "CLASS: Event 2 | "============================================================ 3 | let s:Event = {} 4 | let g:NERDTreeEvent = s:Event 5 | 6 | function! s:Event.New(nerdtree, subject, action, params) abort 7 | let newObj = copy(self) 8 | let newObj.nerdtree = a:nerdtree 9 | let newObj.subject = a:subject 10 | let newObj.action = a:action 11 | let newObj.params = a:params 12 | return newObj 13 | endfunction 14 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/flag_set.vim: -------------------------------------------------------------------------------- 1 | "CLASS: FlagSet 2 | "============================================================ 3 | let s:FlagSet = {} 4 | let g:NERDTreeFlagSet = s:FlagSet 5 | 6 | "FUNCTION: FlagSet.addFlag(scope, flag) {{{1 7 | function! s:FlagSet.addFlag(scope, flag) 8 | let flags = self._flagsForScope(a:scope) 9 | if index(flags, a:flag) == -1 10 | call add(flags, a:flag) 11 | end 12 | endfunction 13 | 14 | "FUNCTION: FlagSet.clearFlags(scope) {{{1 15 | function! s:FlagSet.clearFlags(scope) 16 | let self._flags[a:scope] = [] 17 | endfunction 18 | 19 | "FUNCTION: FlagSet._flagsForScope(scope) {{{1 20 | function! s:FlagSet._flagsForScope(scope) 21 | if !has_key(self._flags, a:scope) 22 | let self._flags[a:scope] = [] 23 | endif 24 | return self._flags[a:scope] 25 | endfunction 26 | 27 | "FUNCTION: FlagSet.New() {{{1 28 | function! s:FlagSet.New() 29 | let newObj = copy(self) 30 | let newObj._flags = {} 31 | return newObj 32 | endfunction 33 | 34 | "FUNCTION: FlagSet.removeFlag(scope, flag) {{{1 35 | function! s:FlagSet.removeFlag(scope, flag) 36 | let flags = self._flagsForScope(a:scope) 37 | 38 | let i = index(flags, a:flag) 39 | if i >= 0 40 | call remove(flags, i) 41 | endif 42 | endfunction 43 | 44 | "FUNCTION: FlagSet.renderToString() {{{1 45 | function! s:FlagSet.renderToString() 46 | let flagstring = '' 47 | for i in values(self._flags) 48 | let flagstring .= join(i) 49 | endfor 50 | 51 | if len(flagstring) == 0 52 | return '' 53 | endif 54 | 55 | return '[' . flagstring . ']' 56 | endfunction 57 | 58 | " vim: set sw=4 sts=4 et fdm=marker: 59 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/key_map.vim: -------------------------------------------------------------------------------- 1 | "CLASS: KeyMap 2 | "============================================================ 3 | let s:KeyMap = {} 4 | let g:NERDTreeKeyMap = s:KeyMap 5 | let s:keyMaps = {} 6 | 7 | "FUNCTION: KeyMap.All() {{{1 8 | function! s:KeyMap.All() 9 | let sortedKeyMaps = values(s:keyMaps) 10 | call sort(sortedKeyMaps, s:KeyMap.Compare, s:KeyMap) 11 | 12 | return sortedKeyMaps 13 | endfunction 14 | 15 | "FUNCTION: KeyMap.Compare(keyMap1, keyMap2) {{{1 16 | function! s:KeyMap.Compare(keyMap1, keyMap2) 17 | 18 | if a:keyMap1.key >? a:keyMap2.key 19 | return 1 20 | endif 21 | 22 | if a:keyMap1.key ' notation, we 44 | " must replace each of the '<' characters with '' to ensure the string 45 | " is not translated into its corresponding keycode during the later part 46 | " of the map command below 47 | " :he <> 48 | let specialNotationRegex = '\m<\([[:alnum:]_-]\+>\)' 49 | if self.key =~# specialNotationRegex 50 | let keymapInvokeString = substitute(self.key, specialNotationRegex, '\1', 'g') 51 | else 52 | let keymapInvokeString = self.key 53 | endif 54 | let keymapInvokeString = escape(keymapInvokeString, '\"') 55 | 56 | let premap = self.key ==# '' ? ' ' : ' ' 57 | 58 | exec 'nnoremap '. self.key . premap . ':call nerdtree#ui_glue#invokeKeyMap("'. keymapInvokeString .'")' 59 | endfunction 60 | 61 | "FUNCTION: KeyMap.Remove(key, scope) {{{1 62 | function! s:KeyMap.Remove(key, scope) 63 | return remove(s:keyMaps, a:key . a:scope) 64 | endfunction 65 | 66 | "FUNCTION: KeyMap.invoke() {{{1 67 | "Call the KeyMaps callback function 68 | function! s:KeyMap.invoke(...) 69 | let l:Callback = type(self.callback) ==# type(function('tr')) ? self.callback : function(self.callback) 70 | if a:0 71 | call l:Callback(a:1) 72 | else 73 | call l:Callback() 74 | endif 75 | endfunction 76 | 77 | "FUNCTION: KeyMap.Invoke() {{{1 78 | "Find a keymapping for a:key and the current scope invoke it. 79 | " 80 | "Scope is determined as follows: 81 | " * if the cursor is on a dir node then DirNode 82 | " * if the cursor is on a file node then FileNode 83 | " * if the cursor is on a bookmark then Bookmark 84 | " 85 | "If a keymap has the scope of 'all' then it will be called if no other keymap 86 | "is found for a:key and the scope. 87 | function! s:KeyMap.Invoke(key) 88 | 89 | "required because clicking the command window below another window still 90 | "invokes the mapping - but changes the window cursor 91 | "is in first 92 | " 93 | "TODO: remove this check when the vim bug is fixed 94 | if !g:NERDTree.ExistsForBuf() 95 | return {} 96 | endif 97 | 98 | let node = g:NERDTreeFileNode.GetSelected() 99 | if !empty(node) 100 | 101 | "try file node 102 | if !node.path.isDirectory 103 | let km = s:KeyMap.FindFor(a:key, 'FileNode') 104 | if !empty(km) 105 | return km.invoke(node) 106 | endif 107 | endif 108 | 109 | "try dir node 110 | if node.path.isDirectory 111 | let km = s:KeyMap.FindFor(a:key, 'DirNode') 112 | if !empty(km) 113 | return km.invoke(node) 114 | endif 115 | endif 116 | 117 | "try generic node 118 | let km = s:KeyMap.FindFor(a:key, 'Node') 119 | if !empty(km) 120 | return km.invoke(node) 121 | endif 122 | 123 | endif 124 | 125 | "try bookmark 126 | let bm = g:NERDTreeBookmark.GetSelected() 127 | if !empty(bm) 128 | let km = s:KeyMap.FindFor(a:key, 'Bookmark') 129 | if !empty(km) 130 | return km.invoke(bm) 131 | endif 132 | endif 133 | 134 | "try all 135 | let km = s:KeyMap.FindFor(a:key, 'all') 136 | if !empty(km) 137 | return km.invoke() 138 | endif 139 | endfunction 140 | 141 | "FUNCTION: KeyMap.Create(options) {{{1 142 | function! s:KeyMap.Create(options) 143 | let opts = extend({'scope': 'all', 'quickhelpText': ''}, copy(a:options)) 144 | 145 | "dont override other mappings unless the 'override' option is given 146 | if get(opts, 'override', 0) ==# 0 && !empty(s:KeyMap.FindFor(opts['key'], opts['scope'])) 147 | return 148 | end 149 | 150 | let newKeyMap = copy(self) 151 | let newKeyMap.key = opts['key'] 152 | let newKeyMap.quickhelpText = opts['quickhelpText'] 153 | let newKeyMap.callback = opts['callback'] 154 | let newKeyMap.scope = opts['scope'] 155 | 156 | call s:KeyMap.Add(newKeyMap) 157 | endfunction 158 | 159 | "FUNCTION: KeyMap.Add(keymap) {{{1 160 | function! s:KeyMap.Add(keymap) 161 | let s:keyMaps[a:keymap.key . a:keymap.scope] = a:keymap 162 | endfunction 163 | 164 | " vim: set sw=4 sts=4 et fdm=marker: 165 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/menu_controller.vim: -------------------------------------------------------------------------------- 1 | "CLASS: MenuController 2 | "============================================================ 3 | let s:MenuController = {} 4 | let g:NERDTreeMenuController = s:MenuController 5 | 6 | "FUNCTION: MenuController.New(menuItems) {{{1 7 | "create a new menu controller that operates on the given menu items 8 | function! s:MenuController.New(menuItems) 9 | let newMenuController = copy(self) 10 | if a:menuItems[0].isSeparator() 11 | let newMenuController.menuItems = a:menuItems[1:-1] 12 | else 13 | let newMenuController.menuItems = a:menuItems 14 | endif 15 | return newMenuController 16 | endfunction 17 | 18 | " FUNCTION: s:MenuController.isMinimal() {{{1 19 | function! s:MenuController.isMinimal() 20 | return g:NERDTreeMinimalMenu 21 | endfunction 22 | 23 | " FUNCTION: MenuController.showMenu() {{{1 24 | " Enter the main loop of the NERDTree menu, prompting the user to select 25 | " a menu item. 26 | function! s:MenuController.showMenu() 27 | call self._saveOptions() 28 | 29 | try 30 | let self.selection = 0 31 | let l:done = 0 32 | 33 | while !l:done 34 | if has('nvim') 35 | mode 36 | else 37 | redraw! 38 | endif 39 | call self._echoPrompt() 40 | 41 | let l:key = nr2char(getchar()) 42 | let l:done = self._handleKeypress(l:key) 43 | endwhile 44 | finally 45 | call self._restoreOptions() 46 | 47 | " Redraw when Ctrl-C or Esc is received. 48 | if !l:done || self.selection ==# -1 49 | redraw! 50 | endif 51 | endtry 52 | 53 | if self.selection !=# -1 54 | let l:m = self._current() 55 | call l:m.execute() 56 | endif 57 | endfunction 58 | 59 | "FUNCTION: MenuController._echoPrompt() {{{1 60 | function! s:MenuController._echoPrompt() 61 | let navHelp = 'Use ' . g:NERDTreeMenuDown . '/' . g:NERDTreeMenuUp . '/enter' 62 | 63 | if self.isMinimal() 64 | let selection = self.menuItems[self.selection].text 65 | let keyword = matchstr(selection, '[^ ]*([^ ]*') 66 | 67 | let shortcuts = map(copy(self.menuItems), "v:val['shortcut']") 68 | let shortcuts[self.selection] = ' ' . keyword . ' ' 69 | 70 | echo 'Menu: [' . join(shortcuts, ',') . '] (' . navHelp . ' or shortcut): ' 71 | else 72 | echo 'NERDTree Menu. ' . navHelp . ', or the shortcuts indicated' 73 | echo '=========================================================' 74 | 75 | for i in range(0, len(self.menuItems)-1) 76 | if self.selection ==# i 77 | echo '> ' . self.menuItems[i].text 78 | else 79 | echo ' ' . self.menuItems[i].text 80 | endif 81 | endfor 82 | endif 83 | endfunction 84 | 85 | "FUNCTION: MenuController._current(key) {{{1 86 | "get the MenuItem that is currently selected 87 | function! s:MenuController._current() 88 | return self.menuItems[self.selection] 89 | endfunction 90 | 91 | "FUNCTION: MenuController._handleKeypress(key) {{{1 92 | "change the selection (if appropriate) and return 1 if the user has made 93 | "their choice, 0 otherwise 94 | function! s:MenuController._handleKeypress(key) 95 | if a:key ==# g:NERDTreeMenuDown 96 | call self._cursorDown() 97 | elseif a:key ==# g:NERDTreeMenuUp 98 | call self._cursorUp() 99 | elseif a:key ==# nr2char(27) "escape 100 | let self.selection = -1 101 | return 1 102 | elseif a:key ==# "\r" || a:key ==# "\n" "enter and ctrl-j 103 | return 1 104 | else 105 | let index = self._nextIndexFor(a:key) 106 | if index !=# -1 107 | let self.selection = index 108 | if len(self._allIndexesFor(a:key)) ==# 1 109 | return 1 110 | endif 111 | endif 112 | endif 113 | 114 | return 0 115 | endfunction 116 | 117 | "FUNCTION: MenuController._allIndexesFor(shortcut) {{{1 118 | "get indexes to all menu items with the given shortcut 119 | function! s:MenuController._allIndexesFor(shortcut) 120 | let toReturn = [] 121 | 122 | for i in range(0, len(self.menuItems)-1) 123 | if self.menuItems[i].shortcut ==# a:shortcut 124 | call add(toReturn, i) 125 | endif 126 | endfor 127 | 128 | return toReturn 129 | endfunction 130 | 131 | "FUNCTION: MenuController._nextIndexFor(shortcut) {{{1 132 | "get the index to the next menu item with the given shortcut, starts from the 133 | "current cursor location and wraps around to the top again if need be 134 | function! s:MenuController._nextIndexFor(shortcut) 135 | for i in range(self.selection+1, len(self.menuItems)-1) 136 | if self.menuItems[i].shortcut ==# a:shortcut 137 | return i 138 | endif 139 | endfor 140 | 141 | for i in range(0, self.selection) 142 | if self.menuItems[i].shortcut ==# a:shortcut 143 | return i 144 | endif 145 | endfor 146 | 147 | return -1 148 | endfunction 149 | 150 | "FUNCTION: MenuController._setCmdheight() {{{1 151 | "sets &cmdheight to whatever is needed to display the menu 152 | function! s:MenuController._setCmdheight() 153 | if self.isMinimal() 154 | let &cmdheight = 1 155 | else 156 | let &cmdheight = len(self.menuItems) + 3 157 | endif 158 | endfunction 159 | 160 | "FUNCTION: MenuController._saveOptions() {{{1 161 | "set any vim options that are required to make the menu work (saving their old 162 | "values) 163 | function! s:MenuController._saveOptions() 164 | let self._oldLazyredraw = &lazyredraw 165 | let self._oldCmdheight = &cmdheight 166 | set nolazyredraw 167 | call self._setCmdheight() 168 | endfunction 169 | 170 | "FUNCTION: MenuController._restoreOptions() {{{1 171 | "restore the options we saved in _saveOptions() 172 | function! s:MenuController._restoreOptions() 173 | let &cmdheight = self._oldCmdheight 174 | let &lazyredraw = self._oldLazyredraw 175 | endfunction 176 | 177 | "FUNCTION: MenuController._cursorDown() {{{1 178 | "move the cursor to the next menu item, skipping separators 179 | function! s:MenuController._cursorDown() 180 | let done = 0 181 | while !done 182 | if self.selection < len(self.menuItems)-1 183 | let self.selection += 1 184 | else 185 | let self.selection = 0 186 | endif 187 | 188 | if !self._current().isSeparator() 189 | let done = 1 190 | endif 191 | endwhile 192 | endfunction 193 | 194 | "FUNCTION: MenuController._cursorUp() {{{1 195 | "move the cursor to the previous menu item, skipping separators 196 | function! s:MenuController._cursorUp() 197 | let done = 0 198 | while !done 199 | if self.selection > 0 200 | let self.selection -= 1 201 | else 202 | let self.selection = len(self.menuItems)-1 203 | endif 204 | 205 | if !self._current().isSeparator() 206 | let done = 1 207 | endif 208 | endwhile 209 | endfunction 210 | 211 | " vim: set sw=4 sts=4 et fdm=marker: 212 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/menu_item.vim: -------------------------------------------------------------------------------- 1 | "CLASS: MenuItem 2 | "============================================================ 3 | let s:MenuItem = {} 4 | let g:NERDTreeMenuItem = s:MenuItem 5 | 6 | "FUNCTION: MenuItem.All() {{{1 7 | "get all top level menu items 8 | function! s:MenuItem.All() 9 | if !exists('s:menuItems') 10 | let s:menuItems = [] 11 | endif 12 | return s:menuItems 13 | endfunction 14 | 15 | "FUNCTION: MenuItem.AllEnabled() {{{1 16 | "get all top level menu items that are currently enabled 17 | function! s:MenuItem.AllEnabled() 18 | let toReturn = [] 19 | for i in s:MenuItem.All() 20 | if i.enabled() 21 | call add(toReturn, i) 22 | endif 23 | endfor 24 | return toReturn 25 | endfunction 26 | 27 | "FUNCTION: MenuItem.Create(options) {{{1 28 | "make a new menu item and add it to the global list 29 | function! s:MenuItem.Create(options) 30 | let newMenuItem = copy(self) 31 | 32 | let newMenuItem.text = a:options['text'] 33 | let newMenuItem.shortcut = a:options['shortcut'] 34 | let newMenuItem.children = [] 35 | 36 | let newMenuItem.isActiveCallback = -1 37 | if has_key(a:options, 'isActiveCallback') 38 | let newMenuItem.isActiveCallback = a:options['isActiveCallback'] 39 | endif 40 | 41 | let newMenuItem.callback = -1 42 | if has_key(a:options, 'callback') 43 | let newMenuItem.callback = a:options['callback'] 44 | endif 45 | 46 | if has_key(a:options, 'parent') 47 | call add(a:options['parent'].children, newMenuItem) 48 | else 49 | call add(s:MenuItem.All(), newMenuItem) 50 | endif 51 | 52 | return newMenuItem 53 | endfunction 54 | 55 | "FUNCTION: MenuItem.CreateSeparator(options) {{{1 56 | "make a new separator menu item and add it to the global list 57 | function! s:MenuItem.CreateSeparator(options) 58 | let standard_options = { 'text': '--------------------', 59 | \ 'shortcut': -1, 60 | \ 'callback': -1 } 61 | let options = extend(a:options, standard_options, 'force') 62 | 63 | return s:MenuItem.Create(options) 64 | endfunction 65 | 66 | "FUNCTION: MenuItem.CreateSubmenu(options) {{{1 67 | "make a new submenu and add it to global list 68 | function! s:MenuItem.CreateSubmenu(options) 69 | let standard_options = { 'callback': -1 } 70 | let options = extend(a:options, standard_options, 'force') 71 | 72 | return s:MenuItem.Create(options) 73 | endfunction 74 | 75 | "FUNCTION: MenuItem.enabled() {{{1 76 | "return 1 if this menu item should be displayed 77 | " 78 | "delegates off to the isActiveCallback, and defaults to 1 if no callback was 79 | "specified 80 | function! s:MenuItem.enabled() 81 | if self.isActiveCallback != -1 82 | return type(self.isActiveCallback) == type(function('tr')) ? self.isActiveCallback() : {self.isActiveCallback}() 83 | endif 84 | return 1 85 | endfunction 86 | 87 | "FUNCTION: MenuItem.execute() {{{1 88 | "perform the action behind this menu item, if this menuitem has children then 89 | "display a new menu for them, otherwise deletegate off to the menuitem's 90 | "callback 91 | function! s:MenuItem.execute() 92 | if len(self.children) 93 | let mc = g:NERDTreeMenuController.New(self.children) 94 | call mc.showMenu() 95 | else 96 | if self.callback != -1 97 | if type(self.callback) == type(function('tr')) 98 | call self.callback() 99 | else 100 | call {self.callback}() 101 | endif 102 | endif 103 | endif 104 | endfunction 105 | 106 | "FUNCTION: MenuItem.isSeparator() {{{1 107 | "return 1 if this menuitem is a separator 108 | function! s:MenuItem.isSeparator() 109 | return self.callback == -1 && self.children == [] 110 | endfunction 111 | 112 | "FUNCTION: MenuItem.isSubmenu() {{{1 113 | "return 1 if this menuitem is a submenu 114 | function! s:MenuItem.isSubmenu() 115 | return self.callback == -1 && !empty(self.children) 116 | endfunction 117 | 118 | " vim: set sw=4 sts=4 et fdm=marker: 119 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/nerdtree.vim: -------------------------------------------------------------------------------- 1 | "CLASS: NERDTree 2 | "============================================================ 3 | let s:NERDTree = {} 4 | let g:NERDTree = s:NERDTree 5 | 6 | "FUNCTION: s:NERDTree.AddPathFilter() {{{1 7 | function! s:NERDTree.AddPathFilter(callback) 8 | call add(s:NERDTree.PathFilters(), a:callback) 9 | endfunction 10 | 11 | "FUNCTION: s:NERDTree.changeRoot(node) {{{1 12 | function! s:NERDTree.changeRoot(node) 13 | if a:node.path.isDirectory 14 | let self.root = a:node 15 | else 16 | call a:node.cacheParent() 17 | let self.root = a:node.parent 18 | endif 19 | 20 | call self.root.open() 21 | 22 | "change dir to the dir of the new root if instructed to 23 | if g:NERDTreeChDirMode >= 2 24 | call self.root.path.changeToDir() 25 | endif 26 | 27 | call self.render() 28 | call self.root.putCursorHere(0, 0) 29 | 30 | if exists('#User#NERDTreeNewRoot') 31 | doautocmd User NERDTreeNewRoot 32 | endif 33 | endfunction 34 | 35 | "FUNCTION: s:NERDTree.Close() {{{1 36 | "Closes the tab tree window for this tab 37 | function! s:NERDTree.Close() 38 | if !s:NERDTree.IsOpen() 39 | return 40 | endif 41 | 42 | if winnr('$') !=# 1 43 | " Use the window ID to identify the currently active window or fall 44 | " back on the buffer ID if win_getid/win_gotoid are not available, in 45 | " which case we'll focus an arbitrary window showing the buffer. 46 | let l:useWinId = exists('*win_getid') && exists('*win_gotoid') 47 | 48 | if winnr() ==# s:NERDTree.GetWinNum() 49 | call nerdtree#exec('wincmd p', 1) 50 | let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr('') 51 | call nerdtree#exec('wincmd p', 1) 52 | else 53 | let l:activeBufOrWin = l:useWinId ? win_getid() : bufnr('') 54 | endif 55 | 56 | call nerdtree#exec(s:NERDTree.GetWinNum() . ' wincmd w', 1) 57 | call nerdtree#exec('close', 0) 58 | if l:useWinId 59 | call nerdtree#exec('call win_gotoid(' . l:activeBufOrWin . ')', 0) 60 | else 61 | call nerdtree#exec(bufwinnr(l:activeBufOrWin) . ' wincmd w', 0) 62 | endif 63 | else 64 | close 65 | endif 66 | endfunction 67 | 68 | "FUNCTION: s:NERDTree.CursorToBookmarkTable(){{{1 69 | "Places the cursor at the top of the bookmarks table 70 | function! s:NERDTree.CursorToBookmarkTable() 71 | if !b:NERDTree.ui.getShowBookmarks() 72 | throw 'NERDTree.IllegalOperationError: cant find bookmark table, bookmarks arent active' 73 | endif 74 | 75 | if g:NERDTreeMinimalUI 76 | return cursor(1, 2) 77 | endif 78 | 79 | let rootNodeLine = b:NERDTree.ui.getRootLineNum() 80 | 81 | let line = 1 82 | while getline(line) !~# '^>-\+Bookmarks-\+$' 83 | let line = line + 1 84 | if line >= rootNodeLine 85 | throw 'NERDTree.BookmarkTableNotFoundError: didnt find the bookmarks table' 86 | endif 87 | endwhile 88 | call cursor(line, 2) 89 | endfunction 90 | 91 | "FUNCTION: s:NERDTree.CursorToTreeWin(){{{1 92 | "Places the cursor in the nerd tree window 93 | function! s:NERDTree.CursorToTreeWin(...) 94 | call g:NERDTree.MustBeOpen() 95 | call nerdtree#exec(g:NERDTree.GetWinNum() . 'wincmd w', a:0 >0 ? a:1 : 1) 96 | endfunction 97 | 98 | " Function: s:NERDTree.ExistsForBuffer() {{{1 99 | " Returns 1 if a nerd tree root exists in the current buffer 100 | function! s:NERDTree.ExistsForBuf() 101 | return exists('b:NERDTree') 102 | endfunction 103 | 104 | " Function: s:NERDTree.ExistsForTab() {{{1 105 | " Returns 1 if a nerd tree root exists in the current tab 106 | function! s:NERDTree.ExistsForTab() 107 | if !exists('t:NERDTreeBufName') 108 | return 109 | end 110 | 111 | "check b:NERDTree is still there and hasn't been e.g. :bdeleted 112 | return !empty(getbufvar(bufnr(t:NERDTreeBufName), 'NERDTree')) 113 | endfunction 114 | 115 | function! s:NERDTree.ForCurrentBuf() 116 | if s:NERDTree.ExistsForBuf() 117 | return b:NERDTree 118 | else 119 | return {} 120 | endif 121 | endfunction 122 | 123 | "FUNCTION: s:NERDTree.ForCurrentTab() {{{1 124 | function! s:NERDTree.ForCurrentTab() 125 | if !s:NERDTree.ExistsForTab() 126 | return 127 | endif 128 | 129 | let bufnr = bufnr(t:NERDTreeBufName) 130 | return getbufvar(bufnr, 'NERDTree') 131 | endfunction 132 | 133 | "FUNCTION: s:NERDTree.getRoot() {{{1 134 | function! s:NERDTree.getRoot() 135 | return self.root 136 | endfunction 137 | 138 | "FUNCTION: s:NERDTree.GetWinNum() {{{1 139 | "gets the nerd tree window number for this tab 140 | function! s:NERDTree.GetWinNum() 141 | if exists('t:NERDTreeBufName') 142 | return bufwinnr(t:NERDTreeBufName) 143 | endif 144 | 145 | " If WindowTree, there is no t:NERDTreeBufName variable. Search all windows. 146 | for w in range(1,winnr('$')) 147 | if bufname(winbufnr(w)) =~# '^' . g:NERDTreeCreator.BufNamePrefix() . '\d\+$' 148 | return w 149 | endif 150 | endfor 151 | 152 | return -1 153 | endfunction 154 | 155 | "FUNCTION: s:NERDTree.IsOpen() {{{1 156 | function! s:NERDTree.IsOpen() 157 | return s:NERDTree.GetWinNum() !=# -1 158 | endfunction 159 | 160 | "FUNCTION: s:NERDTree.isTabTree() {{{1 161 | function! s:NERDTree.isTabTree() 162 | return self._type ==# 'tab' 163 | endfunction 164 | 165 | "FUNCTION: s:NERDTree.isWinTree() {{{1 166 | function! s:NERDTree.isWinTree() 167 | return self._type ==# 'window' 168 | endfunction 169 | 170 | "FUNCTION: s:NERDTree.MustBeOpen() {{{1 171 | function! s:NERDTree.MustBeOpen() 172 | if !s:NERDTree.IsOpen() 173 | throw 'NERDTree.TreeNotOpen' 174 | endif 175 | endfunction 176 | 177 | "FUNCTION: s:NERDTree.New() {{{1 178 | function! s:NERDTree.New(path, type) 179 | let newObj = copy(self) 180 | let newObj.ui = g:NERDTreeUI.New(newObj) 181 | let newObj.root = g:NERDTreeDirNode.New(a:path, newObj) 182 | let newObj._type = a:type 183 | return newObj 184 | endfunction 185 | 186 | "FUNCTION: s:NERDTree.PathFilters() {{{1 187 | function! s:NERDTree.PathFilters() 188 | if !exists('s:NERDTree._PathFilters') 189 | let s:NERDTree._PathFilters = [] 190 | endif 191 | return s:NERDTree._PathFilters 192 | endfunction 193 | 194 | "FUNCTION: s:NERDTree.previousBuf() {{{1 195 | function! s:NERDTree.previousBuf() 196 | return self._previousBuf 197 | endfunction 198 | 199 | function! s:NERDTree.setPreviousBuf(bnum) 200 | let self._previousBuf = a:bnum 201 | endfunction 202 | 203 | "FUNCTION: s:NERDTree.render() {{{1 204 | "A convenience function - since this is called often 205 | function! s:NERDTree.render() 206 | call self.ui.render() 207 | endfunction 208 | 209 | " vim: set sw=4 sts=4 et fdm=marker: 210 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/lib/nerdtree/notifier.vim: -------------------------------------------------------------------------------- 1 | "CLASS: Notifier 2 | "============================================================ 3 | let s:Notifier = {} 4 | 5 | function! s:Notifier.AddListener(event, funcname) 6 | let listeners = s:Notifier.GetListenersForEvent(a:event) 7 | if listeners == [] 8 | let listenersMap = s:Notifier.GetListenersMap() 9 | let listenersMap[a:event] = listeners 10 | endif 11 | call add(listeners, a:funcname) 12 | endfunction 13 | 14 | function! s:Notifier.NotifyListeners(event, path, nerdtree, params) 15 | let event = g:NERDTreeEvent.New(a:nerdtree, a:path, a:event, a:params) 16 | 17 | for Listener in s:Notifier.GetListenersForEvent(a:event) 18 | let l:Callback = type(Listener) == type(function('tr')) ? Listener : function(Listener) 19 | call l:Callback(event) 20 | endfor 21 | endfunction 22 | 23 | function! s:Notifier.GetListenersMap() 24 | if !exists('s:refreshListenersMap') 25 | let s:refreshListenersMap = {} 26 | endif 27 | return s:refreshListenersMap 28 | endfunction 29 | 30 | function! s:Notifier.GetListenersForEvent(name) 31 | let listenersMap = s:Notifier.GetListenersMap() 32 | return get(listenersMap, a:name, []) 33 | endfunction 34 | 35 | let g:NERDTreePathNotifier = deepcopy(s:Notifier) 36 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/nerdtree_plugin/exec_menuitem.vim: -------------------------------------------------------------------------------- 1 | " ============================================================================ 2 | " File: exec_menuitem.vim 3 | " Description: plugin for NERD Tree that provides an execute file menu item 4 | " Maintainer: Martin Grenfell 5 | " License: This program is free software. It comes without any warranty, 6 | " to the extent permitted by applicable law. You can redistribute 7 | " it and/or modify it under the terms of the Do What The Fuck You 8 | " Want To Public License, Version 2, as published by Sam Hocevar. 9 | " See http://sam.zoy.org/wtfpl/COPYING for more details. 10 | " 11 | " ============================================================================ 12 | if exists('g:loaded_nerdtree_exec_menuitem') 13 | finish 14 | endif 15 | let g:loaded_nerdtree_exec_menuitem = 1 16 | 17 | call NERDTreeAddMenuItem({ 18 | \ 'text': '(!)Execute file', 19 | \ 'shortcut': '!', 20 | \ 'callback': 'NERDTreeExecFile', 21 | \ 'isActiveCallback': 'NERDTreeExecFileActive' }) 22 | 23 | function! NERDTreeExecFileActive() 24 | let node = g:NERDTreeFileNode.GetSelected() 25 | return !node.path.isDirectory && node.path.isExecutable 26 | endfunction 27 | 28 | function! NERDTreeExecFile() 29 | let treenode = g:NERDTreeFileNode.GetSelected() 30 | echo "==========================================================\n" 31 | echo "Complete the command to execute (add arguments etc):\n" 32 | let cmd = treenode.path.str({'escape': 1}) 33 | let cmd = input(':!', cmd . ' ') 34 | 35 | if cmd !=# '' 36 | exec ':!' . cmd 37 | else 38 | echo 'Aborted' 39 | endif 40 | endfunction 41 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/nerdtree_plugin/vcs.vim: -------------------------------------------------------------------------------- 1 | " ============================================================================ 2 | " File: vcs.vim 3 | " Description: NERDTree plugin that provides a command to open on the root of 4 | " a version control system repository. 5 | " Maintainer: Phil Runninger 6 | " License: This program is free software. It comes without any warranty, 7 | " to the extent permitted by applicable law. You can redistribute 8 | " it and/or modify it under the terms of the Do What The Fuck You 9 | " Want To Public License, Version 2, as published by Sam Hocevar. 10 | " See http://sam.zoy.org/wtfpl/COPYING for more details. 11 | " 12 | " ============================================================================ 13 | command! -n=? -complete=dir -bar NERDTreeVCS :call CreateTabTreeVCS('') 14 | command! -n=? -complete=dir -bar NERDTreeToggleVCS :call ToggleTabTreeVCS('') 15 | 16 | " FUNCTION: s:CreateTabTreeVCS(a:name) {{{1 17 | function! s:CreateTabTreeVCS(name) 18 | let l:path = g:NERDTreeCreator._pathForString(a:name) 19 | let l:path = s:FindParentVCSRoot(l:path) 20 | call g:NERDTreeCreator.createTabTree(empty(l:path) ? '' : l:path._str()) 21 | endfunction 22 | 23 | " FUNCTION: s:ToggleTabTreeVCS(a:name) {{{1 24 | " Behaves the same as ToggleTabTree except roots directory at VCS root 25 | function! s:ToggleTabTreeVCS(name) 26 | let l:path = g:NERDTreeCreator._pathForString(a:name) 27 | let l:path = s:FindParentVCSRoot(l:path) 28 | call g:NERDTreeCreator.toggleTabTree(empty(l:path) ? '' : l:path._str()) 29 | endfunction 30 | 31 | " FUNCTION: s:FindParentVCSRoot(a:path) {{{1 32 | " Finds the root version control system folder of the given path. If a:path is 33 | " not part of a repository, return the original path. 34 | function! s:FindParentVCSRoot(path) 35 | let l:path = a:path 36 | while !empty(l:path) && 37 | \ l:path._str() !~# '^\(\a:[\\\/]\|\/\)$' && 38 | \ !isdirectory(l:path._str() . '/.git') && 39 | \ !isdirectory(l:path._str() . '/.svn') && 40 | \ !isdirectory(l:path._str() . '/.hg') && 41 | \ !isdirectory(l:path._str() . '/.bzr') && 42 | \ !isdirectory(l:path._str() . '/_darcs') 43 | let l:path = l:path.getParent() 44 | endwhile 45 | return (empty(l:path) || l:path._str() =~# '^\(\a:[\\\/]\|\/\)$') ? a:path : l:path 46 | endfunction 47 | 48 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/ContainerCraft/devcontainer/6e7ad3261e9201afd5eddb9214e84a1cb8955a81/docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/screenshot.png -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vim/pack/vendor/start/nerdtree/syntax/nerdtree.vim: -------------------------------------------------------------------------------- 1 | let s:tree_up_dir_line = '.. (up a dir)' 2 | syn match NERDTreeIgnore #\~# 3 | exec 'syn match NERDTreeIgnore #\['.g:NERDTreeGlyphReadOnly.'\]#' 4 | 5 | "highlighting for the .. (up dir) line at the top of the tree 6 | execute "syn match NERDTreeUp #\\V". s:tree_up_dir_line .'#' 7 | 8 | "quickhelp syntax elements 9 | syn match NERDTreeHelpKey #" \{1,2\}[^ ]*:#ms=s+2,me=e-1 10 | syn match NERDTreeHelpKey #" \{1,2\}[^ ]*,#ms=s+2,me=e-1 11 | syn match NERDTreeHelpTitle #" .*\~$#ms=s+2,me=e-1 12 | syn match NERDTreeToggleOn #(on)#ms=s+1,he=e-1 13 | syn match NERDTreeToggleOff #(off)#ms=e-3,me=e-1 14 | syn match NERDTreeHelpCommand #" :.\{-}\>#hs=s+3 15 | syn match NERDTreeHelp #^".*# contains=NERDTreeHelpKey,NERDTreeHelpTitle,NERDTreeIgnore,NERDTreeToggleOff,NERDTreeToggleOn,NERDTreeHelpCommand 16 | 17 | "highlighting for sym links 18 | syn match NERDTreeLinkTarget #->.*# containedin=NERDTreeDir,NERDTreeFile 19 | syn match NERDTreeLinkFile #.* ->#me=e-3 containedin=NERDTreeFile 20 | syn match NERDTreeLinkDir #.*/ ->#me=e-3 containedin=NERDTreeDir 21 | 22 | "highlighting to conceal the delimiter around the file/dir name 23 | if has('conceal') 24 | exec 'syn match NERDTreeNodeDelimiters #\%d' . char2nr(g:NERDTreeNodeDelimiter) . '# conceal containedin=ALL' 25 | setlocal conceallevel=2 concealcursor=nvic 26 | else 27 | exec 'syn match NERDTreeNodeDelimiters #\%d' . char2nr(g:NERDTreeNodeDelimiter) . '# containedin=ALL' 28 | hi! link NERDTreeNodeDelimiters Ignore 29 | endif 30 | 31 | "highlighing for directory nodes and file nodes 32 | syn match NERDTreeDirSlash #/# containedin=NERDTreeDir 33 | 34 | if g:NERDTreeDirArrowExpandable !=# '' 35 | exec 'syn match NERDTreeClosable #' . escape(g:NERDTreeDirArrowCollapsible, '~') . '\ze .*/# containedin=NERDTreeDir,NERDTreeFile' 36 | exec 'syn match NERDTreeOpenable #' . escape(g:NERDTreeDirArrowExpandable, '~') . '\ze .*/# containedin=NERDTreeDir,NERDTreeFile' 37 | let s:dirArrows = escape(g:NERDTreeDirArrowCollapsible, '~]\-').escape(g:NERDTreeDirArrowExpandable, '~]\-') 38 | exec 'syn match NERDTreeDir #[^'.s:dirArrows.' ].*/#' 39 | exec 'syn match NERDTreeExecFile #^.*'.g:NERDTreeNodeDelimiter.'\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmarkName' 40 | exec 'syn match NERDTreeFile #^[^"\.'.s:dirArrows.'] *[^'.s:dirArrows.']*# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmarkName,NERDTreeExecFile' 41 | else 42 | exec 'syn match NERDTreeDir #[^'.g:NERDTreeNodeDelimiter.']\{-}/\ze\($\|'.g:NERDTreeNodeDelimiter.'\)#' 43 | exec 'syn match NERDTreeExecFile #[^'.g:NERDTreeNodeDelimiter.']\{-}'.g:NERDTreeNodeDelimiter.'\*\($\| \)# contains=NERDTreeRO,NERDTreeBookmarkName' 44 | exec 'syn match NERDTreeFile #^.*'.g:NERDTreeNodeDelimiter.'.*[^\/]\($\|'.g:NERDTreeNodeDelimiter.'.*\)# contains=NERDTreeLink,NERDTreeRO,NERDTreeBookmarkName,NERDTreeExecFile' 45 | endif 46 | 47 | "highlighting for readonly files 48 | exec 'syn match NERDTreeRO #.*'.g:NERDTreeNodeDelimiter.'\zs.*\ze'.g:NERDTreeNodeDelimiter.'.*\['.g:NERDTreeGlyphReadOnly.'\]# contains=NERDTreeIgnore,NERDTreeBookmarkName,NERDTreeFile' 49 | 50 | exec 'syn match NERDTreeFlags #\[[^\]]*\]\ze'.g:NERDTreeNodeDelimiter.'# containedin=NERDTreeFile,NERDTreeExecFile,NERDTreeLinkFile,NERDTreeRO,NERDTreeDir' 51 | 52 | syn match NERDTreeCWD #^[# 59 | syn match NERDTreeBookmarksHeader #^>-\+Bookmarks-\+$# contains=NERDTreeBookmarksLeader 60 | syn match NERDTreeBookmarkName #^>.\{-} #he=e-1 contains=NERDTreeBookmarksLeader 61 | syn match NERDTreeBookmark #^>.*$# contains=NERDTreeBookmarksLeader,NERDTreeBookmarkName,NERDTreeBookmarksHeader 62 | 63 | hi def link NERDTreePart Special 64 | hi def link NERDTreePartFile Type 65 | hi def link NERDTreeExecFile Title 66 | hi def link NERDTreeDirSlash Identifier 67 | 68 | hi def link NERDTreeBookmarksHeader statement 69 | hi def link NERDTreeBookmarksLeader ignore 70 | hi def link NERDTreeBookmarkName Identifier 71 | hi def link NERDTreeBookmark normal 72 | 73 | hi def link NERDTreeHelp String 74 | hi def link NERDTreeHelpKey Identifier 75 | hi def link NERDTreeHelpCommand Identifier 76 | hi def link NERDTreeHelpTitle Macro 77 | hi def link NERDTreeToggleOn Question 78 | hi def link NERDTreeToggleOff WarningMsg 79 | 80 | hi def link NERDTreeLinkTarget Type 81 | hi def link NERDTreeLinkFile Macro 82 | hi def link NERDTreeLinkDir Macro 83 | 84 | hi def link NERDTreeDir Directory 85 | hi def link NERDTreeUp Directory 86 | hi def link NERDTreeFile Normal 87 | hi def link NERDTreeCWD Statement 88 | hi def link NERDTreeOpenable Directory 89 | hi def link NERDTreeClosable Directory 90 | hi def link NERDTreeIgnore ignore 91 | hi def link NERDTreeRO WarningMsg 92 | hi def link NERDTreeBookmark Statement 93 | hi def link NERDTreeFlags Number 94 | 95 | hi def link NERDTreeCurrentNode Search 96 | 97 | hi NERDTreeFile ctermbg=NONE guibg=NONE 98 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.vimrc: -------------------------------------------------------------------------------- 1 | set nocompatible " be iMproved, required 2 | filetype off " required 3 | 4 | " set the runtime path to include Vundle and initialize 5 | set rtp+=~/.vim/bundle/Vundle.vim 6 | call vundle#begin() 7 | " alternatively, pass a path where Vundle should install plugins 8 | "call vundle#begin('~/some/path/here') 9 | 10 | " https://github.com/sheerun/vim-polyglot#language-packs 11 | Plugin 'sheerun/vim-polyglot' 12 | 13 | Plugin 'raimondi/delimitmate' 14 | Plugin 'tpope/vim-surround' 15 | Plugin 'Syntastic' 16 | 17 | " HTML Plugin 18 | Plugin 'mattn/emmet-vim' 19 | 20 | " Vim Status bar 21 | Plugin 'bling/vim-airline' 22 | 23 | " let Vundle manage Vundle, required 24 | Plugin 'VundleVim/Vundle.vim' 25 | Plugin 'tiagofumo/vim-nerdtree-syntax-highlight' 26 | 27 | " The following are examples of different formats supported. 28 | " Keep Plugin commands between vundle#begin/end. 29 | " plugin on GitHub repo 30 | Plugin 'tpope/vim-fugitive' 31 | " plugin from http://vim-scripts.org/vim/scripts.html 32 | " Plugin 'L9' 33 | " Git plugin not hosted on GitHub 34 | "Plugin 'git://git.wincent.com/command-t.git' 35 | " Install L9 and avoid a Naming conflict if you've already installed a 36 | " different version somewhere else. 37 | Plugin 'ascenator/L9', {'name': 'newL9'} 38 | 39 | " https://github.com/preservim/nerdtree 40 | Plugin 'preservim/nerdtree' 41 | 42 | " Plugin 'kyoz/purify', { 'rtp': 'vim' } 43 | " Plugin 'dracula/vim', { 'name': 'dracula' } 44 | 45 | " All of your Plugins must be added before the following line 46 | call vundle#end() " required 47 | filetype plugin indent on " required 48 | " To ignore plugin indent changes, instead use: 49 | "filetype plugin on 50 | " 51 | " Brief help 52 | " :PluginList - lists configured plugins 53 | " :PluginInstall - installs plugins; append `!` to update or just :PluginUpdate 54 | " :PluginSearch foo - searches for foo; append `!` to refresh local cache 55 | " :PluginClean - confirms removal of unused plugins; append `!` to auto-approve removal 56 | " 57 | " see :h vundle for more details or wiki for FAQ 58 | " Put your non-Plugin stuff after this line 59 | 60 | " Colorscheme 61 | ":colorscheme dracula 62 | ":colorscheme purify 63 | ":colorscheme molokai 64 | ":colorscheme iceberg 65 | 66 | " Airline 67 | let g:airline_powerline_fonts=1 68 | let g:airline#extensions#tabline#enabled = 1 69 | 70 | " NerdTree 71 | nnoremap n :NERDTreeFocus 72 | nnoremap :NERDTree 73 | nnoremap :NERDTreeToggle 74 | nnoremap :NERDTreeFind 75 | autocmd StdinReadPre * let s:std_in=1 76 | autocmd VimEnter * if argc() == 0 && !exists('s:std_in') && v:this_session == '' | NERDTree | endif 77 | 78 | " Disable compatibility with vi which can cause unexpected issues. 79 | set nocompatible 80 | 81 | " Enable type file detection. Vim will be able to try to detect the type of file in use. 82 | filetype on 83 | 84 | " Enable plugins and load plugin for the detected file type. 85 | filetype plugin on 86 | 87 | " Load an indent file for the detected file type. 88 | filetype indent on 89 | 90 | " Turn syntax highlighting on. 91 | syntax on 92 | 93 | " Add numbers to each line on the left-hand side. 94 | set number 95 | set relativenumber 96 | 97 | " Highlight cursor line underneath the cursor horizontally. 98 | set cursorline 99 | 100 | " Set shift width to 4 spaces. 101 | set shiftwidth=4 102 | 103 | " Set tab width to 4 columns. 104 | set tabstop=4 105 | 106 | " Use space characters instead of tabs. 107 | set expandtab 108 | 109 | " Do not save backup files. 110 | set nobackup 111 | 112 | " Do not let cursor scroll below or above N number of lines when scrolling. 113 | set scrolloff=10 114 | 115 | " Do not wrap lines. Allow long lines to extend as far as the line goes. 116 | " set nowrap 117 | " 118 | set autoindent 119 | set textwidth=80 120 | 121 | " While searching though a file incrementally highlight matching characters as you type. 122 | set incsearch 123 | 124 | " Ignore capital letters during search. 125 | set ignorecase 126 | 127 | " Override the ignorecase option if searching for capital letters. 128 | " This will allow you to search specifically for capital letters. 129 | set smartcase 130 | 131 | " Show partial command you type in the last line of the screen. 132 | set showcmd 133 | 134 | " Show the mode you are on the last line. 135 | set showmode 136 | 137 | " Show matching words during a search. 138 | set showmatch 139 | 140 | " Use highlighting when doing a search. 141 | set hlsearch 142 | 143 | " Set the commands to save in history default number is 20. 144 | set history=1000 145 | 146 | " Enable auto completion menu after pressing TAB. 147 | set wildmenu 148 | 149 | " Make wildmenu behave like similar to Bash completion. 150 | set wildmode=list:longest 151 | 152 | " There are certain files that we would never want to edit with Vim. 153 | " Wildmenu will ignore files with these extensions. 154 | set wildignore=*.docx,*.jpg,*.png,*.gif,*.pdf,*.pyc,*.exe,*.flv,*.img,*.xlsx 155 | 156 | " Map escape to jj 157 | inoremap jj 158 | imap jj 159 | -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/skel/.zshrc: -------------------------------------------------------------------------------- 1 | eval "$(direnv hook zsh)" 2 | eval "$(starship init zsh)" 3 | alias cloc="alias cloc="git count | xargs wc -l 2>/dev/null" -------------------------------------------------------------------------------- /docker/slim/rootfs/etc/ssh/sshd_config: -------------------------------------------------------------------------------- 1 | AcceptEnv LANG LC_CTYPE 2 | Port 2222 3 | PermitRootLogin no 4 | Subsystem sftp /usr/libexec/openssh/sftp-server 5 | AuthorizedKeysFile .ssh/authorized_keys 6 | SyslogFacility AUTH 7 | #HostKey /etc/ssh/ssh_host_rsa_key 8 | #HostKey /etc/ssh/ssh_host_ecdsa_key 9 | #HostKey /etc/ssh/ssh_host_ed25519_key 10 | #PermitEmptyPasswords no 11 | PasswordAuthentication no 12 | #ChallengeResponseAuthentication no 13 | #GSSAPIAuthentication yes 14 | #GSSAPICleanupCredentials no 15 | #UsePAM yes 16 | AllowAgentForwarding yes 17 | AllowTcpForwarding yes 18 | #GatewayPorts no 19 | X11Forwarding no 20 | ##X11DisplayOffset 10 21 | ##X11UseLocalhost yes 22 | #PermitTTY yes 23 | PrintMotd no 24 | TCPKeepAlive yes 25 | #PermitUserEnvironment no 26 | #ChrootDirectory /root/deploy 27 | #ForceCommand /usr/bin/bash -c connect 28 | # 29 | ## Accept locale-related environment variables 30 | #AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 31 | #AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 32 | #AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE 33 | #AcceptEnv XMODIFIERS 34 | # 35 | ## override default of no subsystems 36 | #Subsystem sftp /usr/libexec/openssh/sftp-server 37 | #SyslogFacility AUTHPRIV 38 | 39 | #PasswordAuthentication yes 40 | ChallengeResponseAuthentication no 41 | 42 | GSSAPIAuthentication yes 43 | GSSAPICleanupCredentials no 44 | 45 | UsePAM yes 46 | 47 | #X11Forwarding yes 48 | 49 | # It is recommended to use pam_motd in /etc/pam.d/sshd instead of PrintMotd, 50 | # as it is more configurable and versatile than the built-in version. 51 | #PrintMotd no 52 | 53 | # Accept locale-related environment variables 54 | AcceptEnv LANG LC_CTYPE LC_NUMERIC LC_TIME LC_COLLATE LC_MONETARY LC_MESSAGES 55 | AcceptEnv LC_PAPER LC_NAME LC_ADDRESS LC_TELEPHONE LC_MEASUREMENT 56 | AcceptEnv LC_IDENTIFICATION LC_ALL LANGUAGE 57 | AcceptEnv XMODIFIERS 58 | 59 | -------------------------------------------------------------------------------- /docker/slim/rootfs/usr/bin/run_registry.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | start () { 3 | unset REGISTRY_AUTH_FILE 4 | registry serve /etc/docker/registry/config.yml 2>&1 1>/dev/stderr & 5 | } 6 | start 7 | -------------------------------------------------------------------------------- /docs/readme_maintenance_prompt.md: -------------------------------------------------------------------------------- 1 | **README.md Documentation Update Requirements & Instructions** 2 | 3 | --- 4 | 5 | ### Purpose 6 | 7 | Regenerate a comprehensive `README.md` by analyzing all current `README.md` content and reconciling it against all `Dockerfile` contents and auxiliary Docker image build artifacts. Carefully maintain the integrity and completeness of the `README.md` file by ensuring all relevant content is included and up-to-date. 8 | 9 | ### Core Documentation Requirements 10 | 11 | 1. **Image Variants** 12 | - Document all variants and their inheritance chain. 13 | - List supported architectures (`amd64`, `arm64`). 14 | - Detail base image specifications. 15 | 16 | 2. **Tools & Languages** 17 | - **List all installed tools with versions**: 18 | - Provide tables for CLI tools, including: 19 | - Tool Name 20 | - Version 21 | - Description 22 | - Link to official website or repository. 23 | - **Document language support and versions**. 24 | 25 | 3. **Configuration & Environment** 26 | - Document environment variables. 27 | - Detail user and permission models. 28 | - Explain volume mounts and ports. 29 | - Describe shell customizations. 30 | 31 | ### Feature Documentation 32 | 33 | 1. **Development Modes** 34 | - VSCode/Cursor AI integration. 35 | - Neovim configuration & usage. 36 | - Remote hosted Code-Server variant. 37 | - Terminal-based development. 38 | - Local Docker Desktop / Docker CLI (on Linux). 39 | - Remote GitHub Codespaces via Remote Containers extension. 40 | 41 | 2. **Language Support** 42 | - Python ecosystem. 43 | - Node.js environment. 44 | - Go toolchain. 45 | - .NET framework. 46 | 47 | 3. **Kubernetes & Cloud Native Tooling** 48 | - `kubectl` and plugins. 49 | - Helm CLI. 50 | - `k9s` interface. 51 | - Cloud provider CLI tools. 52 | - Support for adding custom layers via `.devcontainer/Dockerfile` on a per-project basis. 53 | 54 | ### Usage Documentation 55 | 56 | 1. **Quick Start Guides** 57 | - Basic usage examples. 58 | - Common operations. 59 | - Configuration examples. 60 | - Troubleshooting tips. 61 | 62 | 2. **Volume & Network** 63 | - Volume mounting strategies. 64 | - Relevant service by port usage examples. 65 | - Devcontainer mode Docker-in-Docker support. 66 | 67 | ### Technical Specifications 68 | 69 | 1. **Container Configuration** 70 | - User space setup. 71 | - Directory structure. 72 | 73 | 2. **Tool Chain Details** 74 | - Update procedures. 75 | - Compatibility notes. 76 | - Default configurations. 77 | 78 | ### Documentation Format 79 | 80 | 1. **Structure** 81 | - Use clear markdown formatting. 82 | - Hierarchical organization with headings and subheadings. 83 | - **Use tables where effective** (e.g., listing CLI tools with versions and descriptions). 84 | - Include code block examples. 85 | - Always character escape nested codeblocks with a backslash like so `\````, to remediate chat interface rendering issues. Only the first and last codeblock delimiters are written without the character escaping backslash. 86 | 87 | 2. **Content Focus** 88 | - Prioritize end-user value. 89 | - Cater to professional practitioners. 90 | - Include quick-start sections. 91 | - Highlight common use cases. 92 | 93 | 3. **Enhancements** 94 | - Use markdown-formatted inline reference hyperlinks. 95 | - Improve the ordering of sections for better flow. 96 | - Enhance readability with lists, tables, and formatting. 97 | 98 | ### Key Tools Documentation 99 | 100 | #### Core Utilities 101 | 102 | Provide a table listing core utilities with the following columns: 103 | 104 | - **Tool Name** 105 | - **Version** 106 | - **Description** 107 | - **Link** 108 | 109 | Example: 110 | 111 | | Tool Name | Version | Description | Link | 112 | |-----------|---------|--------------------------------------------|------------------------------------------| 113 | | `jq` | Latest | Command-line JSON processor | [jq](https://stedolan.github.io/jq/) | 114 | | `direnv` | Latest | Environment variable management | [direnv](https://direnv.net/) | 115 | | `starship`| Latest | Fast, customizable shell prompt | [Starship](https://starship.rs/) | 116 | | `git` | Latest | Distributed version control system | [Git](https://git-scm.com/) | 117 | | `Runme` | Latest | Execute commands directly from README.md | [Runme](https://runme.dev/) | 118 | | `task` | Latest | Task runner and build tool | [Task](https://taskfile.dev/) | 119 | | `kubecolor`| Latest | Colorized `kubectl` output | [Kubecolor](https://github.com/hidetatz/kubecolor)| 120 | 121 | #### Development Tools 122 | 123 | List and describe development tools in a similar table. 124 | 125 | #### Shell Tools 126 | 127 | List and describe shell tools, focusing on Bash and other relevant shells. 128 | 129 | #### Cloud Native Tools 130 | 131 | Provide a table for cloud-native tools: 132 | 133 | | Tool Name | Version | Description | Link | 134 | |-----------|---------|----------------------------------------|-------------------------------------------| 135 | | `kubectl` | Latest | Kubernetes command-line tool | [kubectl](https://kubernetes.io/docs/tasks/tools/) | 136 | | `helm` | Latest | Kubernetes package manager | [Helm](https://helm.sh/) | 137 | | `k9s` | Latest | Terminal UI for Kubernetes clusters | [k9s](https://k9scli.io/) | 138 | | `Pulumi` | Latest | Infrastructure as Code SDK | [Pulumi](https://www.pulumi.com/) | 139 | | ... | ... | ... | ... | 140 | 141 | ### Quality Requirements 142 | 143 | 1. **Content Quality** 144 | - Ensure the `README.md` is comprehensive yet clear. 145 | - Maintain a well-organized structure. 146 | - Focus on the needs of practitioners. 147 | - Keep information current and accurate. 148 | 149 | 2. **Technical Accuracy** 150 | - Validate all commands and examples. 151 | - Note that the devcontainer meets all prerequisites except: 152 | - VSCode 153 | - Cursor.dev 154 | - Docker Desktop / Docker CLI 155 | - Web Browser 156 | 157 | 3. **Usability** 158 | - Make the document easy to navigate. 159 | - Facilitate quick referencing. 160 | - Provide clear examples. 161 | - Include troubleshooting guides. 162 | - Add a Table of Contents. 163 | 164 | 4. **SEO Optimization** 165 | - Use clear and descriptive headings. 166 | - Include relevant keywords. 167 | - Apply proper formatting. 168 | - Use internal linking where appropriate. 169 | 170 | ### Relevant Reference Files for Context 171 | 172 | - `docker/*` 173 | 174 | ### Output Requirements 175 | 176 | Generate a top-level `./README.md` that is: 177 | 178 | 1. Comprehensive but not overwhelming. 179 | 2. Well-organized and scannable. 180 | 3. Focused on practitioner value. 181 | 4. Up-to-date with current capabilities. 182 | 5. Clear about supported features. 183 | 6. Explicit about requirements. 184 | 7. Rich with correctly written examples that account for overriding the default entrypoint when manually running the container. 185 | 8. SEO-friendly for developer discovery. 186 | 9. Is nested within normal codeblocks, and the first and last codeblock delimiters are written without the character escaping backslash. 187 | 10. Uses markdown rendering safe backslashes to escape nested codeblocks like so '\```' to remediate chat interface rendering issues (Accomodated via find/replace in final draft) 188 | --------------------------------------------------------------------------------