--- /dev/null
+;;; docker-cli-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "docker-cli" "docker-cli.el" (0 0 0 0))
+;;; Generated autoloads from docker-cli.el
+
+(register-definition-prefixes "docker-cli" '("docker-cli"))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; docker-cli-autoloads.el ends here
--- /dev/null
+;;; Generated package description from docker-cli.el -*- no-byte-compile: t -*-
+(define-package "docker-cli" "20190524.1624" "Running various commands in docker containers" 'nil :commit "328429219574555c5fb831a421b4b5d9a2338561" :authors '(("Boško Ivanišević" . "bosko.ivanisevicNOSPAMgmail.com")) :maintainers '(("Boško Ivanišević" . "bosko.ivanisevicNOSPAMgmail.com")) :maintainer '("Boško Ivanišević" . "bosko.ivanisevicNOSPAMgmail.com") :keywords '("processes") :url "https://github.com/bosko/docker-cli")
--- /dev/null
+;;; docker-cli.el --- Running various commands in docker containers
+
+;; Author: Boško Ivanišević <bosko.ivanisevicNOSPAMgmail.com>
+;; Version: 1.0.0
+;; Package-Version: 20190524.1624
+;; Package-Commit: 328429219574555c5fb831a421b4b5d9a2338561
+;; Keywords: processes
+;; URL: https://github.com/bosko/docker-cli
+
+;; This file is not part of GNU Emacs.
+
+;; This file is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation; either version 3, or (at your option)
+;; any later version.
+
+;; This file is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with GNU Emacs; see the file COPYING. If not, write to
+;; the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
+
+;;; Commentary:
+;;
+;; docker-cli provides mode for running commands within Docker
+;; containers in Emacs buffer. Package comes with few predefined
+;; commands for running PostgreSQL, Redis and MySQL clients. Package
+;; can easily be extended with new commands by adding elements to
+;; `docker-cli-commands-alist'. Command is ran with interactive
+;; function `docker-cli-run-cmd` which, after selecting command and
+;; container from the list, executes given command in the target
+;; Docker container.
+
+;;; Code:
+
+(require 'comint)
+
+(defcustom docker-cli-db-username ""
+ "Database username."
+ :type 'string
+ :group 'docker-cli)
+
+(defcustom docker-cli-db-name ""
+ "Database name."
+ :type 'string
+ :group 'docker-cli)
+
+(defcustom docker-cli-host ""
+ "Host name."
+ :type 'string
+ :group 'docker-cli)
+
+(defvar docker-cli-cmd "docker"
+ "Docker command.")
+
+(defvar docker-cli-exec-arguments '("exec" "-it")
+ "Commandline arguments to pass to docker.")
+
+(defvar docker-cli-curr-command nil
+ "Current selected command.")
+
+(defvar docker-cli-commands-alist
+ '((sh
+ :command "/bin/sh"
+ :arguments-compose-func nil
+ :prompt-regexp "^[[:alnum:]_]*=[#>] "
+ :prompt-cont-regexp "^[[:alnum:]_]*=[#>] ")
+
+ (bash
+ :command "/bin/bash"
+ :arguments-compose-func nil
+ :prompt-regexp "^[[:alnum:]_]*=[#>] "
+ :prompt-cont-regexp "^[[:alnum:]_]*=[#>] ")
+
+ (psql
+ :command "psql"
+ :arguments-compose-func docker-cli-psql-arguments
+ :prompt-regexp "^[[:alnum:]_]*=[#>] "
+ :prompt-cont-regexp "^[[:alnum:]_]*=[#>] ")
+
+ (mysql
+ :command "mysql"
+ :arguments-compose-func docker-cli-mysql-arguments
+ :prompt-regexp "^[[:alnum:]_]*=[#>] "
+ :prompt-cont-regexp "^[[:alnum:]_]*=[#>] ")
+
+ (redis-cli
+ :command "redis-cli"
+ :exec-arguments-func docker-cli-redis-exec-arguments
+ :arguments-compose-func nil
+ :prompt-regexp "^[a-zA-Z0-9_.-]+:[0-9]+\\(\\[[0-9]\\]\\)?> "
+ :prompt-cont-regexp "^[a-zA-Z0-9_.-]+:[0-9]+\\(\\[[0-9]\\]\\)?> "))
+ "An alist of defined commands that can be ran in docker container.
+
+Each element in the list must be of the following format:
+
+ (COMMAND-KEY FEATURE VALUE)
+
+where COMMAND-KEY is unique value that determines command and can
+be displayed in selection when `docker-run' is executed. Each key
+is followed by FEATURE-VALUE pairs. Feature can be any of following:
+
+ :command Command that will be executed in the
+ Docker container.
+
+ :exec-arguments-func Function without arguments that should
+ return Docker exec arguments. Value
+ returned by this fuction will be used
+ instead of `docker-cli-exec-arguments'.
+
+ :arguments-compose-func Function without arguments that will be
+ called in order to fetch all command
+ arguments.
+
+New commands can be supported by adding new element to this list.")
+
+(defvar docker-cli-mode-map
+ (let ((map (nconc (make-sparse-keymap) comint-mode-map)))
+ ;; example definition
+ (define-key map "\t" 'completion-at-point)
+ map)
+ "Basic mode map for `docker-cli'.")
+
+;; This value is for psql. It should be nil here and
+;; set depending of command started
+(defvar docker-cli-prompt-regexp nil
+ "Prompt for `docker-cli'.")
+
+;; This value is for psql. It should be nil here and
+;; set depending of command started
+(defvar docker-cli-prompt-cont-regexp nil
+ "Prompt pattern for continuation prompt.")
+
+(defun docker-cli-psql-arguments ()
+ "Composes arguments for running psql in docker container."
+ (setq docker-cli-db-username (read-string "Username: " docker-cli-db-username))
+ (setq docker-cli-db-name (read-string "Database: " docker-cli-db-name))
+ (setq docker-cli-host (read-string "Host: " docker-cli-host))
+ `("-U" ,docker-cli-db-username "-h" ,docker-cli-host "-P" "pager=off" ,docker-cli-db-name))
+
+(defun docker-cli-mysql-arguments ()
+ "Composes arguments for running MySQL client in Docker container."
+ (setq docker-cli-db-username (read-string "Username: " docker-cli-db-username))
+ (setq docker-cli-db-name (read-string "Database: " docker-cli-db-name))
+ (setq docker-cli-host (read-string "Host: " docker-cli-host))
+ `("-u" ,docker-cli-db-username "-h" ,docker-cli-host "-p" ,docker-cli-db-name))
+
+(defun docker-cli-redis-exec-arguments ()
+ "Composes arguments for running Redis client in docker container."
+ '("exec" "-it" "-e" "TERM=dumb"))
+
+(defun docker-cli-compose-params-for (command-name container)
+ "Composes params for given command and CONTAINER.
+Argument COMMAND-NAME unique key of command from docker-cli-command-alist.
+Argument CONTAINER name of the target Docker container."
+ (let* ((curr-command (cdr (assoc (intern command-name) docker-cli-commands-alist)))
+ (params (if (plist-get curr-command :arguments-compose-func)
+ (apply (plist-get curr-command :arguments-compose-func) nil))))
+ (setq docker-cli-prompt-regexp (or (plist-get curr-command :prompt-regexp) ""))
+ (setq docker-cli-prompt-cont-regexp (or (plist-get curr-command :prompt-cont-regexp) ""))
+ (setq params (cons (plist-get curr-command :command) (or params '())))
+ (setq params (cons container params))
+ (if (plist-get curr-command :exec-arguments-func)
+ (setq params (append (apply (plist-get curr-command :exec-arguments-func) nil) params))
+ (setq params (append docker-cli-exec-arguments params)))))
+
+(defun docker-cli ()
+ "Run an inferior instance of `docker' inside Emacs."
+ (interactive)
+ (let* ((curr-command-name (completing-read
+ "Command: "
+ (mapcar 'symbol-name (mapcar 'car docker-cli-commands-alist)) nil t))
+ (container (completing-read
+ "Container: "
+ (split-string (shell-command-to-string "docker ps --format '{{.Names}}'")) nil t))
+ (buffer-name)
+ (buffer))
+
+ (if (and (not (string= "" curr-command-name)) (not (string= "" container)))
+ (progn
+ (setq buffer-name (format "%s-%s" container curr-command-name))
+ (setq buffer (get-buffer-create (format "*%s*" buffer-name)))
+ (pop-to-buffer-same-window buffer)
+
+ ;; create the comint process
+ (unless (comint-check-proc buffer)
+ (apply 'make-comint-in-buffer buffer-name buffer
+ docker-cli-cmd nil (docker-cli-compose-params-for curr-command-name container)))
+ (docker-cli-mode)))))
+
+(defun docker-cli--initialize ()
+ "Helper function to initialize Docker."
+ (setq comint-process-echoes t)
+ (setq comint-use-prompt-regexp t))
+
+(define-derived-mode docker-cli-mode comint-mode "Docker"
+ "Major mode for running commands in Docker containers.
+
+\\<docker-cli-mode-map>"
+ ;; this sets up the prompt so it matches things like: [foo@bar]
+ (setq comint-prompt-regexp
+ (if docker-cli-prompt-cont-regexp
+ (concat "\\(" docker-cli-prompt-regexp
+ "\\|" docker-cli-prompt-cont-regexp "\\)")
+ docker-cli-prompt-regexp))
+ ;; this makes it read only; a contentious subject as some prefer the
+ ;; buffer to be overwritable.
+ (setq comint-prompt-read-only t)
+ ;; this makes it so commands like M-{ and M-} work.
+ (set (make-local-variable 'paragraph-separate) "\\'")
+ (set (make-local-variable 'paragraph-start) docker-cli-prompt-regexp))
+
+;; this has to be done in a hook. grumble grumble.
+(add-hook 'docker-cli-mode-hook 'docker-cli--initialize)
+
+(provide 'docker-cli)
+
+;;; docker-cli.el ends here
--- /dev/null
+docker-cli provides mode for running commands within Docker
+containers in Emacs buffer. Package comes with few predefined
+commands for running PostgreSQL, Redis and MySQL clients. Package
+can easily be extended with new commands by adding elements to
+`docker-cli-commands-alist'. Command is ran with interactive
+function `docker-cli-run-cmd` which, after selecting command and
+container from the list, executes given command in the target
+Docker container.
--- /dev/null
+;;; docker-tramp-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "docker-tramp" "docker-tramp.el" (0 0 0 0))
+;;; Generated autoloads from docker-tramp.el
+
+(defvar docker-tramp-docker-options nil "\
+List of docker options.")
+
+(custom-autoload 'docker-tramp-docker-options "docker-tramp" t)
+
+(defconst docker-tramp-completion-function-alist '((docker-tramp--parse-running-containers "")) "\
+Default list of (FUNCTION FILE) pairs to be examined for docker method.")
+
+(defconst docker-tramp-method "docker" "\
+Method to connect docker containers.")
+
+(autoload 'docker-tramp-cleanup "docker-tramp" "\
+Cleanup TRAMP cache for docker method." t nil)
+
+(autoload 'docker-tramp-add-method "docker-tramp" "\
+Add docker tramp method." nil nil)
+
+(eval-after-load 'tramp '(progn (docker-tramp-add-method) (tramp-set-completion-function docker-tramp-method docker-tramp-completion-function-alist)))
+
+(register-definition-prefixes "docker-tramp" '("docker-tramp-"))
+
+;;;***
+\f
+;;;### (autoloads nil nil ("docker-tramp-compat.el" "docker-tramp-pkg.el")
+;;;;;; (0 0 0 0))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; docker-tramp-autoloads.el ends here
--- /dev/null
+;;; docker-tramp-compat.el --- TRAMP integration for docker containers -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Mario Rodas <marsamNOSPAMusers.noreply.github.com>
+
+;; Author: Mario Rodas <marsamNOSPAMusers.noreply.github.com>
+;; URL: https://github.com/emacs-pe/docker-tramp.el
+;; Keywords: docker, convenience
+;; Version: 0.1
+;; Package-Requires: ((emacs "24"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+
+;;; Code:
+(require 'tramp-sh)
+
+(when (version< tramp-version "2.3")
+;; Overwrite `tramp-wait-for-output' to work with Alpine busy boxes in Tramp<2.3
+;;
+;; See:
+;; + https://lists.gnu.org/archive/html/tramp-devel/2016-05/msg00000.html
+;; + http://git.savannah.gnu.org/cgit/tramp.git/commit/?id=98a511248a9405848ed44de48a565b0b725af82c
+(defconst tramp-device-escape-sequence-regexp "\e[[0-9]+n"
+ "Terminal control escape sequences for device status.")
+
+(defun tramp-wait-for-output (proc &optional timeout)
+ "Wait for output from remote command."
+ (unless (buffer-live-p (process-buffer proc))
+ (delete-process proc)
+ (tramp-error proc 'file-error "Process `%s' not available, try again" proc))
+ (with-current-buffer (process-buffer proc)
+ (let* (;; Initially, `tramp-end-of-output' is "#$ ". There might
+ ;; be leading escape sequences, which must be ignored.
+ ;; Busyboxes built with the EDITING_ASK_TERMINAL config
+ ;; option send also escape sequences, which must be
+ ;; ignored.
+ (regexp (format "[^#$\n]*%s\\(%s\\)?\r?$"
+ (regexp-quote tramp-end-of-output)
+ tramp-device-escape-sequence-regexp))
+ ;; Sometimes, the commands do not return a newline but a
+ ;; null byte before the shell prompt, for example "git
+ ;; ls-files -c -z ...".
+ (regexp1 (format "\\(^\\|\000\\)%s" regexp))
+ (found (tramp-wait-for-regexp proc timeout regexp1)))
+ (if found
+ (let (buffer-read-only)
+ ;; A simple-minded busybox has sent " ^H" sequences.
+ ;; Delete them.
+ (goto-char (point-min))
+ (when (re-search-forward "^\\(.\b\\)+$" (point-at-eol) t)
+ (forward-line 1)
+ (delete-region (point-min) (point)))
+ ;; Delete the prompt.
+ (goto-char (point-max))
+ (re-search-backward regexp nil t)
+ (delete-region (point) (point-max)))
+ (if timeout
+ (tramp-error
+ proc 'file-error
+ "[[Remote prompt `%s' not found in %d secs]]"
+ tramp-end-of-output timeout)
+ (tramp-error
+ proc 'file-error
+ "[[Remote prompt `%s' not found]]" tramp-end-of-output)))
+ ;; Return value is whether end-of-output sentinel was found.
+ found)))
+)
+
+(provide 'docker-tramp-compat)
+
+;;; docker-tramp-compat.el ends here
--- /dev/null
+(define-package "docker-tramp" "20220219.420" "TRAMP integration for docker containers"
+ '((emacs "24")
+ (cl-lib "0.5"))
+ :commit "930d7b46c180d8a13240a028c1b40af84f2a3219" :authors
+ '(("Mario Rodas" . "marsamNOSPAMusers.noreply.github.com"))
+ :maintainers
+ '(("Mario Rodas" . "marsamNOSPAMusers.noreply.github.com"))
+ :maintainer
+ '("Mario Rodas" . "marsamNOSPAMusers.noreply.github.com")
+ :keywords
+ '("docker" "convenience")
+ :url "https://github.com/emacs-pe/docker-tramp.el")
+;; Local Variables:
+;; no-byte-compile: t
+;; End:
--- /dev/null
+;;; docker-tramp.el --- TRAMP integration for docker containers -*- lexical-binding: t; -*-
+
+;; Copyright (C) 2015 Mario Rodas <marsamNOSPAMusers.noreply.github.com>
+
+;; Author: Mario Rodas <marsamNOSPAMusers.noreply.github.com>
+;; URL: https://github.com/emacs-pe/docker-tramp.el
+;; Keywords: docker, convenience
+;; Version: 0.1.1
+;; Package-Requires: ((emacs "24") (cl-lib "0.5"))
+
+;; This file is NOT part of GNU Emacs.
+
+;;; License:
+
+;; This program is free software; you can redistribute it and/or modify
+;; it under the terms of the GNU General Public License as published by
+;; the Free Software Foundation, either version 3 of the License, or
+;; (at your option) any later version.
+
+;; This program is distributed in the hope that it will be useful,
+;; but WITHOUT ANY WARRANTY; without even the implied warranty of
+;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+;; GNU General Public License for more details.
+
+;; You should have received a copy of the GNU General Public License
+;; along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+;;; Commentary:
+;;
+;; `docker-tramp.el' offers a TRAMP method for Docker containers.
+;;
+;; > **NOTE**: `docker-tramp.el' relies in the `docker exec` command. Tested
+;; > with docker version 1.6.x but should work with versions >1.3. Podman
+;; > also works.
+;;
+;; ## Usage
+;;
+;; Offers the TRAMP method `docker` to access running containers
+;;
+;; C-x C-f /docker:user@container:/path/to/file
+;;
+;; where
+;; user is the user that you want to use inside the container (optional)
+;; container is the id or name of the container
+;;
+;; ### [Multi-hop][] examples
+;;
+;; If you container is hosted on `vm.example.net`:
+;;
+;; /ssh:vm-userNOSPAMvm.example.net|docker:user@container:/path/to/file
+;;
+;; If you need to run the `docker` command as, say, the `root` user:
+;;
+;; /sudo:root@localhost|docker:user@container:/path/to/file
+;;
+;; ## Troubleshooting
+;;
+;; ### Tramp hangs on Alpine container
+;;
+;; Busyboxes built with the `ENABLE_FEATURE_EDITING_ASK_TERMINAL' config option
+;; send also escape sequences, which `tramp-wait-for-output' doesn't ignores
+;; correctly. Tramp upstream fixed in [98a5112][] and is available since
+;; Tramp>=2.3.
+;;
+;; For older versions of Tramp you can dump [docker-tramp-compat.el][] in your
+;; `load-path' somewhere and add the following to your `init.el', which
+;; overwrites `tramp-wait-for-output' with the patch applied:
+;;
+;; (require 'docker-tramp-compat)
+;;
+;; ### Tramp does not respect remote `PATH'
+;;
+;; This is a known issue with Tramp, but is not a bug so much as a poor default
+;; setting. Adding `tramp-own-remote-path' to `tramp-remote-path' will make
+;; Tramp use the remote's `PATH' environment varialbe.
+;;
+;; (add-to-list 'tramp-remote-path 'tramp-own-remote-path)
+;;
+;; [Multi-hop]: https://www.gnu.org/software/emacs/manual/html_node/tramp/Ad_002dhoc-multi_002dhops.html
+;; [98a5112]: http://git.savannah.gnu.org/cgit/tramp.git/commit/?id=98a511248a9405848ed44de48a565b0b725af82c
+;; [docker-tramp-compat.el]: https://github.com/emacs-pe/docker-tramp.el/raw/master/docker-tramp-compat.el
+
+;;; Code:
+(eval-when-compile (require 'cl-lib))
+
+(require 'tramp)
+(require 'tramp-cache)
+
+(defgroup docker-tramp nil
+ "TRAMP integration for Docker containers."
+ :prefix "docker-tramp-"
+ :group 'applications
+ :link '(url-link :tag "Github" "https://github.com/emacs-pe/docker-tramp.el")
+ :link '(emacs-commentary-link :tag "Commentary" "docker-tramp"))
+
+(defcustom docker-tramp-docker-executable "docker"
+ "Path to docker (or compatible) executable."
+ :type '(choice
+ (const "docker")
+ (const "podman")
+ (string))
+ :group 'docker-tramp)
+
+;;;###autoload
+(defcustom docker-tramp-docker-options nil
+ "List of docker options."
+ :type '(repeat string)
+ :group 'docker-tramp)
+
+(defcustom docker-tramp-use-names nil
+ "Whether use names instead of id."
+ :type 'boolean
+ :group 'docker-tramp)
+
+;;;###autoload
+(defconst docker-tramp-completion-function-alist
+ '((docker-tramp--parse-running-containers ""))
+ "Default list of (FUNCTION FILE) pairs to be examined for docker method.")
+
+;;;###autoload
+(defconst docker-tramp-method "docker"
+ "Method to connect docker containers.")
+
+(defun docker-tramp--running-containers ()
+ "Collect docker running containers.
+
+Return a list of containers of the form: \(ID NAME\)"
+ (cl-loop for line in (cdr (ignore-errors (apply #'process-lines docker-tramp-docker-executable (append docker-tramp-docker-options (list "ps")))))
+ for info = (split-string line "[[:space:]]+" t)
+ collect (cons (car info) (last info))))
+
+(defun docker-tramp--parse-running-containers (&optional ignored)
+ "Return a list of (user host) tuples.
+
+TRAMP calls this function with a filename which is IGNORED. The
+user is an empty string because the docker TRAMP method uses bash
+to connect to the default user containers."
+ (cl-loop for (id name) in (docker-tramp--running-containers)
+ collect (list "" (if docker-tramp-use-names name id))))
+
+;;;###autoload
+(defun docker-tramp-cleanup ()
+ "Cleanup TRAMP cache for docker method."
+ (interactive)
+ (let ((containers (apply 'append (docker-tramp--running-containers))))
+ (maphash (lambda (key _)
+ (and (vectorp key)
+ (string-equal docker-tramp-method (tramp-file-name-method key))
+ (not (member (tramp-file-name-host key) containers))
+ (remhash key tramp-cache-data)))
+ tramp-cache-data))
+ (setq tramp-cache-data-changed t)
+ (if (zerop (hash-table-count tramp-cache-data))
+ (ignore-errors (delete-file tramp-persistency-file-name))
+ (tramp-dump-connection-properties)))
+
+;;;###autoload
+(defun docker-tramp-add-method ()
+ "Add docker tramp method."
+ (add-to-list 'tramp-methods
+ `(,docker-tramp-method
+ (tramp-login-program ,docker-tramp-docker-executable)
+ (tramp-login-args (,docker-tramp-docker-options ("exec" "-it") ("-u" "%u") ("%h") ("sh")))
+ (tramp-remote-shell "/bin/sh")
+ (tramp-remote-shell-args ("-i" "-c")))))
+
+;;;###autoload
+(eval-after-load 'tramp
+ '(progn
+ (docker-tramp-add-method)
+ (tramp-set-completion-function docker-tramp-method docker-tramp-completion-function-alist)))
+
+(provide 'docker-tramp)
+
+;; Local Variables:
+;; indent-tabs-mode: nil
+;; End:
+
+;;; docker-tramp.el ends here
--- /dev/null
+`docker-tramp.el' offers a TRAMP method for Docker containers.
+
+> **NOTE**: `docker-tramp.el' relies in the `docker exec` command. Tested
+> with docker version 1.6.x but should work with versions >1.3
+
+## Usage
+
+Offers the TRAMP method `docker` to access running containers
+
+ C-x C-f /docker:user@container:/path/to/file
+
+ where
+ user is the user that you want to use (optional)
+ container is the id or name of the container
+
+## Troubleshooting
+
+### Tramp hangs on Alpine container
+
+Busyboxes built with the `ENABLE_FEATURE_EDITING_ASK_TERMINAL' config option
+send also escape sequences, which `tramp-wait-for-output' doesn't ignores
+correctly. Tramp upstream fixed in [98a5112][] and is available since
+Tramp>=2.3.
+
+For older versions of Tramp you can dump [docker-tramp-compat.el][] in your
+`load-path' somewhere and add the following to your `init.el', which
+overwrites `tramp-wait-for-output' with the patch applied:
+
+ (require 'docker-tramp-compat)
+
+[98a5112]: http://git.savannah.gnu.org/cgit/tramp.git/commit/?id=98a511248a9405848ed44de48a565b0b725af82c
+[docker-tramp-compat.el]: https://github.com/emacs-pe/docker-tramp.el/raw/master/docker-tramp-compat.el
--- /dev/null
+;;; dockerfile-mode-autoloads.el --- automatically extracted autoloads -*- lexical-binding: t -*-
+;;
+;;; Code:
+
+(add-to-list 'load-path (directory-file-name
+ (or (file-name-directory #$) (car load-path))))
+
+\f
+;;;### (autoloads nil "dockerfile-mode" "dockerfile-mode.el" (0 0
+;;;;;; 0 0))
+;;; Generated autoloads from dockerfile-mode.el
+
+(autoload 'dockerfile-build-buffer "dockerfile-mode" "\
+Build an image called IMAGE-NAME based upon the buffer.
+
+If the prefix arg NO-CACHE is set, don't cache the image.
+
+The shell command used to build the image is:
+
+ sudo docker build \\
+ --no-cache \\
+ --force-rm \\
+ --pull \\
+ --tag IMAGE-NAME \\
+ --build-args args \\
+ --progress type \\
+ -f filename \\
+ directory
+
+\(fn IMAGE-NAME &optional NO-CACHE)" t nil)
+
+(autoload 'dockerfile-build-no-cache-buffer "dockerfile-mode" "\
+Build an image called IMAGE-NAME based upon the buffer without cache.
+
+\(fn IMAGE-NAME)" t nil)
+
+(autoload 'dockerfile-mode "dockerfile-mode" "\
+A major mode to edit Dockerfiles.
+\\{dockerfile-mode-map}
+
+\(fn)" t nil)
+
+(add-to-list 'auto-mode-alist (cons (concat "[/\\]" "\\(?:Containerfile\\|Dockerfile\\)" "\\(?:\\.[^/\\]*\\)?\\'") 'dockerfile-mode))
+
+(add-to-list 'auto-mode-alist '("\\.dockerfile\\'" . dockerfile-mode))
+
+(register-definition-prefixes "dockerfile-mode" '("dockerfile-"))
+
+;;;***
+\f
+;; Local Variables:
+;; version-control: never
+;; no-byte-compile: t
+;; no-update-autoloads: t
+;; coding: utf-8
+;; End:
+;;; dockerfile-mode-autoloads.el ends here
--- /dev/null
+;;; Generated package description from dockerfile-mode.el -*- no-byte-compile: t -*-
+(define-package "dockerfile-mode" "20220822.2021" "Major mode for editing Docker's Dockerfiles" '((emacs "24")) :commit "52c6c00da1d31c0b6c29c74335b3af63ed6bf06c" :keywords '("docker" "languages" "processes" "tools") :url "https://github.com/spotify/dockerfile-mode")
--- /dev/null
+;;; dockerfile-mode.el --- Major mode for editing Docker's Dockerfiles -*- lexical-binding: t -*-
+
+;; Copyright (c) 2013 Spotify AB
+;; Package-Requires: ((emacs "24"))
+;; Package-Version: 20220822.2021
+;; Package-Commit: 52c6c00da1d31c0b6c29c74335b3af63ed6bf06c
+;; Homepage: https://github.com/spotify/dockerfile-mode
+;; URL: https://github.com/spotify/dockerfile-mode
+;; Version: 1.7
+;; Keywords: docker languages processes tools
+;;
+;; Licensed under the Apache License, Version 2.0 (the "License"); you may not
+;; use this file except in compliance with the License. You may obtain a copy of
+;; the License at
+;;
+;; http://www.apache.org/licenses/LICENSE-2.0
+;;
+;; Unless required by applicable law or agreed to in writing, software
+;; distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+;; WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+;; License for the specific language governing permissions and limitations under
+;; the License.
+
+;;; Commentary:
+
+;; Provides a major mode `dockerfile-mode' for use with the standard
+;; `Dockerfile' file format. Additional convenience functions allow
+;; images to be built easily.
+
+;;; Code:
+
+(require 'sh-script)
+(require 'rx)
+
+
+(declare-function cygwin-convert-file-name-to-windows "cygw32.c" (file &optional absolute-p))
+
+(defgroup dockerfile nil
+ "Dockerfile editing commands for Emacs."
+ :link '(custom-group-link :tag "Font Lock Faces group" font-lock-faces)
+ :prefix "dockerfile-"
+ :group 'languages)
+
+(defcustom dockerfile-mode-command "docker"
+ "Which binary to use to build images."
+ :group 'dockerfile
+ :type 'string)
+
+(defcustom dockerfile-use-sudo nil
+ "Runs docker builder command with sudo."
+ :type 'boolean
+ :group 'dockerfile)
+
+(defcustom dockerfile-build-force-rm nil
+ "Runs docker builder command with --force-rm switch."
+ :type 'boolean
+ :group 'dockerfile)
+
+(defcustom dockerfile-build-pull nil
+ "Runs docker builder command with --pull switch."
+ :type 'boolean
+ :group 'dockerfile)
+
+(defcustom dockerfile-build-args nil
+ "List of --build-arg to pass to docker build.
+
+Each element of the list will be passed as a separate
+ --build-arg to the docker build command."
+ :type '(repeat string)
+ :group 'dockerfile)
+
+(defcustom dockerfile-build-progress "auto"
+ "Type of --progress output (auto, plain, tty) of docker build."
+ :group 'dockerfile
+ :type 'string)
+
+(defcustom dockerfile-use-buildkit nil
+ "Use Docker buildkit for building images?
+
+This is the new buildsystem for docker, and in time it will replace the old one
+but for now it has to be explicitly enabled to work.
+It is supported from docker 18.09"
+ :type 'boolean)
+
+(defcustom dockerfile-enable-auto-indent t
+ "Toggles the auto indentation functionality."
+ :type 'boolean)
+
+(defcustom dockerfile-indent-offset (or standard-indent 2)
+ "Dockerfile number of columns for margin-changing functions to indent."
+ :type 'integer
+ :safe #'integerp
+ :group 'dockerfile)
+
+(defface dockerfile-image-name
+ '((t (:inherit (font-lock-type-face bold))))
+ "Face to highlight the base image name after FROM instruction.")
+
+(defface dockerfile-image-alias
+ '((t (:inherit (font-lock-constant-face bold))))
+ "Face to highlight the base image alias inf FROM ... AS <alias> construct.")
+
+(defconst dockerfile--from-regex
+ (rx "from " (group (+? nonl)) (or " " eol) (? "as " (group (1+ nonl)))))
+
+(defvar dockerfile-font-lock-keywords
+ `(,(cons (rx (or line-start "onbuild ")
+ (group (or "from" "maintainer" "run" "cmd" "expose" "env" "arg"
+ "add" "copy" "entrypoint" "volume" "user" "workdir" "onbuild"
+ "label" "stopsignal" "shell" "healthcheck"))
+ word-boundary)
+ font-lock-keyword-face)
+ (,dockerfile--from-regex
+ (1 'dockerfile-image-name)
+ (2 'dockerfile-image-alias nil t))
+ ,@(sh-font-lock-keywords)
+ ,@(sh-font-lock-keywords-2)
+ ,@(sh-font-lock-keywords-1))
+ "Default `font-lock-keywords' for `dockerfile mode'.")
+
+(defvar dockerfile-mode-map
+ (let ((map (make-sparse-keymap))
+ (menu-map (make-sparse-keymap)))
+ (define-key map "\C-c\C-b" #'dockerfile-build-buffer)
+ (define-key map "\C-c\M-b" #'dockerfile-build-no-cache-buffer)
+ (define-key map "\C-c\C-c" #'comment-region)
+ (define-key map [menu-bar dockerfile-mode] (cons "Dockerfile" menu-map))
+ (define-key menu-map [dfc]
+ '(menu-item "Comment Region" comment-region
+ :help "Comment Region"))
+ (define-key menu-map [dfb]
+ '(menu-item "Build" dockerfile-build-buffer
+ :help "Send the Dockerfile to docker build"))
+ (define-key menu-map [dfb]
+ '(menu-item "Build without cache" dockerfile-build-no-cache-buffer
+ :help "Send the Dockerfile to docker build without cache"))
+ map))
+
+(defvar dockerfile-mode-syntax-table
+ (let ((table (make-syntax-table)))
+ (modify-syntax-entry ?# "<" table)
+ (modify-syntax-entry ?\n ">" table)
+ (modify-syntax-entry ?' "\"" table)
+ (modify-syntax-entry ?= "." table)
+ table)
+ "Syntax table for `dockerfile-mode'.")
+
+(define-abbrev-table 'dockerfile-mode-abbrev-table nil
+ "Abbrev table used while in `dockerfile-mode'.")
+
+(unless dockerfile-mode-abbrev-table
+ (define-abbrev-table 'dockerfile-mode-abbrev-table ()))
+
+(defun dockerfile-indent-line-function ()
+ "Indent lines in a Dockerfile.
+
+Lines beginning with a keyword are ignored, and any others are
+indented by one `dockerfile-indent-offset'. Functionality toggled
+by `dockerfile-enable-auto-indent'."
+ (when dockerfile-enable-auto-indent
+ (unless (member (get-text-property (point-at-bol) 'face)
+ '(font-lock-comment-delimiter-face font-lock-keyword-face))
+ (save-excursion
+ (beginning-of-line)
+ (skip-chars-forward "[ \t]" (point-at-eol))
+ (unless (equal (point) (point-at-eol)) ; Ignore empty lines.
+ ;; Delete existing whitespace.
+ (delete-char (- (point-at-bol) (point)))
+ (indent-to dockerfile-indent-offset))))))
+
+(defun dockerfile-build-arg-string ()
+ "Create a --build-arg string for each element in `dockerfile-build-args'."
+ (mapconcat (lambda (arg) (concat "--build-arg " (shell-quote-argument arg)))
+ dockerfile-build-args " "))
+
+(defun dockerfile-standard-filename (file)
+ "Convert the FILE name to OS standard.
+If in Cygwin environment, uses Cygwin specific function to convert the
+file name. Otherwise, uses Emacs' standard conversion function."
+ (if (fboundp 'cygwin-convert-file-name-to-windows)
+ (replace-regexp-in-string
+ (rx "\\") "\\\\" (cygwin-convert-file-name-to-windows file) t t)
+ (convert-standard-filename file)))
+
+(defun dockerfile-tag-string (image-name)
+ "Return a --tag shell-quoted IMAGE-NAME string.
+
+Returns an empty string if IMAGE-NAME is blank."
+ (if (string= image-name "") "" (format "--tag %s " (shell-quote-argument image-name))))
+
+(define-obsolete-variable-alias 'docker-image-name 'dockerfile-image-name "2017-10-22")
+
+(defvar dockerfile-image-name nil
+ "Name of the dockerfile currently being used.
+This can be set in file or directory-local variables.")
+
+(defvar dockerfile-image-name-history nil
+ "History of image names read by `dockerfile-read-image-name'.")
+
+(defun dockerfile-read-image-name ()
+ "Read a docker image name."
+ (read-string "Image name: " dockerfile-image-name 'dockerfile-image-name-history))
+
+
+;;;###autoload
+(defun dockerfile-build-buffer (image-name &optional no-cache)
+ "Build an image called IMAGE-NAME based upon the buffer.
+
+If the prefix arg NO-CACHE is set, don't cache the image.
+
+The shell command used to build the image is:
+
+ sudo docker build \\
+ --no-cache \\
+ --force-rm \\
+ --pull \\
+ --tag IMAGE-NAME \\
+ --build-args args \\
+ --progress type \\
+ -f filename \\
+ directory"
+
+ (interactive (list (dockerfile-read-image-name) prefix-arg))
+ (save-buffer)
+ (compilation-start
+ (format
+ "%s%s%s build %s %s %s %s %s --progress %s -f %s %s"
+ (if dockerfile-use-buildkit "DOCKER_BUILDKIT=1 " "")
+ (if dockerfile-use-sudo "sudo " "")
+ dockerfile-mode-command
+ (if no-cache "--no-cache" "")
+ (if dockerfile-build-force-rm "--force-rm " "")
+ (if dockerfile-build-pull "--pull " "")
+ (dockerfile-tag-string image-name)
+ (dockerfile-build-arg-string)
+ dockerfile-build-progress
+ (shell-quote-argument (dockerfile-standard-filename
+ (or (file-remote-p (buffer-file-name) 'localname)
+ (buffer-file-name))))
+ (shell-quote-argument (dockerfile-standard-filename
+ (or (file-remote-p default-directory 'localname)
+ default-directory))))
+ nil
+ (lambda (_) (format "*docker-build-output: %s *" image-name))))
+
+;;;###autoload
+(defun dockerfile-build-no-cache-buffer (image-name)
+ "Build an image called IMAGE-NAME based upon the buffer without cache."
+ (interactive (list (dockerfile-read-image-name)))
+ (dockerfile-build-buffer image-name t))
+
+(defun dockerfile--imenu-function ()
+ "Find the previous headline from point.
+
+Search for a FROM instruction. If an alias is used this is
+returned, otherwise the base image name is used."
+ (when (re-search-backward dockerfile--from-regex nil t)
+ (let ((data (match-data)))
+ (when (match-string 2)
+ ;; we drop the first match group because
+ ;; imenu-generic-expression can only use one offset, so we
+ ;; normalize to `1'.
+ (set-match-data (list (nth 0 data) (nth 1 data) (nth 4 data) (nth 5 data))))
+ t)))
+
+;;;###autoload
+(define-derived-mode dockerfile-mode prog-mode "Dockerfile"
+ "A major mode to edit Dockerfiles.
+\\{dockerfile-mode-map}"
+ (set-syntax-table dockerfile-mode-syntax-table)
+ (set (make-local-variable 'imenu-generic-expression)
+ `(("Stage" dockerfile--imenu-function 1)))
+ (set (make-local-variable 'require-final-newline) mode-require-final-newline)
+ (set (make-local-variable 'comment-start) "#")
+ (set (make-local-variable 'comment-end) "")
+ (set (make-local-variable 'comment-start-skip) "#+ *")
+ (set (make-local-variable 'parse-sexp-ignore-comments) t)
+ (set (make-local-variable 'font-lock-defaults)
+ '(dockerfile-font-lock-keywords nil t))
+ (setq local-abbrev-table dockerfile-mode-abbrev-table)
+ (set (make-local-variable 'indent-line-function) #'dockerfile-indent-line-function))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist
+ (cons (concat "[/\\]"
+ "\\(?:Containerfile\\|Dockerfile\\)"
+ "\\(?:\\.[^/\\]*\\)?\\'")
+ 'dockerfile-mode))
+
+;;;###autoload
+(add-to-list 'auto-mode-alist '("\\.dockerfile\\'" . dockerfile-mode))
+
+(provide 'dockerfile-mode)
+
+;;; dockerfile-mode.el ends here
--- /dev/null
+Provides a major mode `dockerfile-mode' for use with the standard
+`Dockerfile' file format. Additional convenience functions allow
+images to be built easily.