diff options
| author | Stefan Monnier | 2011-04-20 19:31:06 -0300 |
|---|---|---|
| committer | Stefan Monnier | 2011-04-20 19:31:06 -0300 |
| commit | c0a193ea2017fbaa6fb3e64a07125878656da156 (patch) | |
| tree | 52ecaae3b27b33e9de36b354cbc2d17e2334f411 /lisp/shell.el | |
| parent | 201133802956936332f1c4ce04eac42dfd1cf1c6 (diff) | |
| download | emacs-c0a193ea2017fbaa6fb3e64a07125878656da156.tar.gz emacs-c0a193ea2017fbaa6fb3e64a07125878656da156.zip | |
* lisp/shell.el: Use lexical-binding and std completion UI.
(shell-filter-ctrl-a-ctrl-b): Work as a preoutput filter.
(shell-mode): Put shell-filter-ctrl-a-ctrl-b on
comint-preoutput-filter-functions rather than on
comint-output-filter-functions.
(shell-command-completion, shell--command-completion-data)
(shell-filename-completion, shell-environment-variable-completion)
(shell-c-a-p-replace-by-expanded-directory): New functions.
(shell-dynamic-complete-functions, shell-dynamic-complete-command)
(shell-dynamic-complete-filename, shell-replace-by-expanded-directory)
(shell-dynamic-complete-environment-variable): Use them.
(shell-dynamic-complete-as-environment-variable)
(shell-dynamic-complete-as-command): Remove.
(shell-match-partial-variable): Match past point.
* lisp/comint.el: Clean up use of completion-at-point-functions.
(comint-completion-at-point): New function.
(comint-mode): Use it completion-at-point-functions.
(comint-dynamic-complete): Make it obsolete.
(comint-replace-by-expanded-history-before-point): Add dry-run arg.
(comint-c-a-p-replace-by-expanded-history): New function.
(comint-dynamic-complete-functions)
(comint-replace-by-expanded-history): Use it.
* lisp/minibuffer.el (completion-table-with-terminator): Allow dynamic
termination strings. Try harder to avoid second try-completion.
(completion-in-region-mode-map): Disable bindings that don't work yet.
Diffstat (limited to 'lisp/shell.el')
| -rw-r--r-- | lisp/shell.el | 217 |
1 files changed, 122 insertions, 95 deletions
diff --git a/lisp/shell.el b/lisp/shell.el index 57187b6d7f9..d6bc685618c 100644 --- a/lisp/shell.el +++ b/lisp/shell.el | |||
| @@ -1,4 +1,4 @@ | |||
| 1 | ;;; shell.el --- specialized comint.el for running the shell | 1 | ;;; shell.el --- specialized comint.el for running the shell -*- lexical-binding: t -*- |
| 2 | 2 | ||
| 3 | ;; Copyright (C) 1988, 1993-1997, 2000-2011 Free Software Foundation, Inc. | 3 | ;; Copyright (C) 1988, 1993-1997, 2000-2011 Free Software Foundation, Inc. |
| 4 | 4 | ||
| @@ -79,7 +79,7 @@ | |||
| 79 | 79 | ||
| 80 | ;; Shell Mode Commands: | 80 | ;; Shell Mode Commands: |
| 81 | ;; shell Fires up the shell process | 81 | ;; shell Fires up the shell process |
| 82 | ;; tab comint-dynamic-complete Complete filename/command/history | 82 | ;; tab completion-at-point Complete filename/command/history |
| 83 | ;; m-? comint-dynamic-list-filename-completions | 83 | ;; m-? comint-dynamic-list-filename-completions |
| 84 | ;; List completions in help buffer | 84 | ;; List completions in help buffer |
| 85 | ;; m-c-f shell-forward-command Forward a shell command | 85 | ;; m-c-f shell-forward-command Forward a shell command |
| @@ -96,6 +96,7 @@ | |||
| 96 | 96 | ||
| 97 | ;;; Code: | 97 | ;;; Code: |
| 98 | 98 | ||
| 99 | (eval-when-compile (require 'cl)) | ||
| 99 | (require 'comint) | 100 | (require 'comint) |
| 100 | 101 | ||
| 101 | ;;; Customization and Buffer Variables | 102 | ;;; Customization and Buffer Variables |
| @@ -181,12 +182,12 @@ shell buffer. The value may depend on the operating system or shell. | |||
| 181 | This is a fine thing to set in your `.emacs' file.") | 182 | This is a fine thing to set in your `.emacs' file.") |
| 182 | 183 | ||
| 183 | (defvar shell-dynamic-complete-functions | 184 | (defvar shell-dynamic-complete-functions |
| 184 | '(comint-replace-by-expanded-history | 185 | '(comint-c-a-p-replace-by-expanded-history |
| 185 | shell-dynamic-complete-environment-variable | 186 | shell-environment-variable-completion |
| 186 | shell-dynamic-complete-command | 187 | shell-command-completion |
| 187 | shell-replace-by-expanded-directory | 188 | shell-c-a-p-replace-by-expanded-directory |
| 188 | shell-dynamic-complete-filename | 189 | shell-filename-completion |
| 189 | comint-dynamic-complete-filename) | 190 | comint-filename-completion) |
| 190 | "List of functions called to perform completion. | 191 | "List of functions called to perform completion. |
| 191 | This variable is used to initialize `comint-dynamic-complete-functions' in the | 192 | This variable is used to initialize `comint-dynamic-complete-functions' in the |
| 192 | shell buffer. | 193 | shell buffer. |
| @@ -312,7 +313,7 @@ This mirrors the optional behavior of tcsh (its autoexpand and histlit). | |||
| 312 | If the value is `input', then the expansion is seen on input. | 313 | If the value is `input', then the expansion is seen on input. |
| 313 | If the value is `history', then the expansion is only when inserting | 314 | If the value is `history', then the expansion is only when inserting |
| 314 | into the buffer's input ring. See also `comint-magic-space' and | 315 | into the buffer's input ring. See also `comint-magic-space' and |
| 315 | `comint-dynamic-complete'. | 316 | `comint-dynamic-complete-functions'. |
| 316 | 317 | ||
| 317 | This variable supplies a default for `comint-input-autoexpand', | 318 | This variable supplies a default for `comint-input-autoexpand', |
| 318 | for Shell mode only." | 319 | for Shell mode only." |
| @@ -339,7 +340,7 @@ Thus, this does not include the shell's current directory.") | |||
| 339 | (let ((map (nconc (make-sparse-keymap) comint-mode-map))) | 340 | (let ((map (nconc (make-sparse-keymap) comint-mode-map))) |
| 340 | (define-key map "\C-c\C-f" 'shell-forward-command) | 341 | (define-key map "\C-c\C-f" 'shell-forward-command) |
| 341 | (define-key map "\C-c\C-b" 'shell-backward-command) | 342 | (define-key map "\C-c\C-b" 'shell-backward-command) |
| 342 | (define-key map "\t" 'comint-dynamic-complete) | 343 | (define-key map "\t" 'completion-at-point) |
| 343 | (define-key map (kbd "M-RET") 'shell-resync-dirs) | 344 | (define-key map (kbd "M-RET") 'shell-resync-dirs) |
| 344 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) | 345 | (define-key map "\M-?" 'comint-dynamic-list-filename-completions) |
| 345 | (define-key map [menu-bar completion] | 346 | (define-key map [menu-bar completion] |
| @@ -486,7 +487,7 @@ buffer." | |||
| 486 | (t "dirs"))) | 487 | (t "dirs"))) |
| 487 | ;; Bypass a bug in certain versions of bash. | 488 | ;; Bypass a bug in certain versions of bash. |
| 488 | (when (string-equal shell "bash") | 489 | (when (string-equal shell "bash") |
| 489 | (add-hook 'comint-output-filter-functions | 490 | (add-hook 'comint-preoutput-filter-functions |
| 490 | 'shell-filter-ctrl-a-ctrl-b nil t))) | 491 | 'shell-filter-ctrl-a-ctrl-b nil t))) |
| 491 | (when shell-dir-cookie-re | 492 | (when shell-dir-cookie-re |
| 492 | ;; Watch for magic cookies in the output to track the current dir. | 493 | ;; Watch for magic cookies in the output to track the current dir. |
| @@ -494,7 +495,7 @@ buffer." | |||
| 494 | 'shell-dir-cookie-watcher nil t)) | 495 | 'shell-dir-cookie-watcher nil t)) |
| 495 | (comint-read-input-ring t))) | 496 | (comint-read-input-ring t))) |
| 496 | 497 | ||
| 497 | (defun shell-filter-ctrl-a-ctrl-b (_string) | 498 | (defun shell-filter-ctrl-a-ctrl-b (string) |
| 498 | "Remove `^A' and `^B' characters from comint output. | 499 | "Remove `^A' and `^B' characters from comint output. |
| 499 | 500 | ||
| 500 | Bash uses these characters as internal quoting characters in its | 501 | Bash uses these characters as internal quoting characters in its |
| @@ -504,15 +505,10 @@ started with the `--noediting' option and Select Graphic | |||
| 504 | Rendition (SGR) control sequences (formerly known as ANSI escape | 505 | Rendition (SGR) control sequences (formerly known as ANSI escape |
| 505 | sequences) are used to color the prompt. | 506 | sequences) are used to color the prompt. |
| 506 | 507 | ||
| 507 | This function can be put on `comint-output-filter-functions'. | 508 | This function can be put on `comint-preoutput-filter-functions'." |
| 508 | The argument STRING is ignored." | 509 | (if (string-match "[\C-a\C-b]" string) |
| 509 | (let ((pmark (process-mark (get-buffer-process (current-buffer))))) | 510 | (replace-regexp-in-string "[\C-a\C-b]" "" string t t) |
| 510 | (save-excursion | 511 | string)) |
| 511 | (goto-char (or (and (markerp comint-last-output-start) | ||
| 512 | (marker-position comint-last-output-start)) | ||
| 513 | (point-min))) | ||
| 514 | (while (re-search-forward "[\C-a\C-b]" pmark t) | ||
| 515 | (replace-match ""))))) | ||
| 516 | 512 | ||
| 517 | (defun shell-write-history-on-exit (process event) | 513 | (defun shell-write-history-on-exit (process event) |
| 518 | "Called when the shell process is stopped. | 514 | "Called when the shell process is stopped. |
| @@ -1011,30 +1007,36 @@ candidates. Note that this may not be the same as the shell's idea of the | |||
| 1011 | path. | 1007 | path. |
| 1012 | 1008 | ||
| 1013 | Completion is dependent on the value of `shell-completion-execonly', plus | 1009 | Completion is dependent on the value of `shell-completion-execonly', plus |
| 1014 | those that effect file completion. See `shell-dynamic-complete-as-command'. | 1010 | those that effect file completion. |
| 1015 | 1011 | ||
| 1016 | Returns t if successful." | 1012 | Returns t if successful." |
| 1017 | (interactive) | 1013 | (interactive) |
| 1014 | (let ((data (shell-command-completion))) | ||
| 1015 | (if data | ||
| 1016 | (prog2 (unless (window-minibuffer-p (selected-window)) | ||
| 1017 | (message "Completing command name...")) | ||
| 1018 | (apply #'completion-in-region data))))) | ||
| 1019 | |||
| 1020 | (defun shell-command-completion () | ||
| 1021 | "Return the completion data for the command at point, if any." | ||
| 1018 | (let ((filename (comint-match-partial-filename))) | 1022 | (let ((filename (comint-match-partial-filename))) |
| 1019 | (if (and filename | 1023 | (if (and filename |
| 1020 | (save-match-data (not (string-match "[~/]" filename))) | 1024 | (save-match-data (not (string-match "[~/]" filename))) |
| 1021 | (eq (match-beginning 0) | 1025 | (eq (match-beginning 0) |
| 1022 | (save-excursion (shell-backward-command 1) (point)))) | 1026 | (save-excursion (shell-backward-command 1) (point)))) |
| 1023 | (prog2 (unless (window-minibuffer-p (selected-window)) | 1027 | (shell--command-completion-data)))) |
| 1024 | (message "Completing command name...")) | ||
| 1025 | (shell-dynamic-complete-as-command))))) | ||
| 1026 | 1028 | ||
| 1027 | 1029 | (defun shell--command-completion-data () | |
| 1028 | (defun shell-dynamic-complete-as-command () | 1030 | "Return the completion data for the command at point." |
| 1029 | "Dynamically complete at point as a command. | ||
| 1030 | See `shell-dynamic-complete-filename'. Returns t if successful." | ||
| 1031 | (let* ((filename (or (comint-match-partial-filename) "")) | 1031 | (let* ((filename (or (comint-match-partial-filename) "")) |
| 1032 | (start (if (zerop (length filename)) (point) (match-beginning 0))) | ||
| 1033 | (end (if (zerop (length filename)) (point) (match-end 0))) | ||
| 1032 | (filenondir (file-name-nondirectory filename)) | 1034 | (filenondir (file-name-nondirectory filename)) |
| 1033 | (path-dirs (cdr (reverse exec-path))) | 1035 | (path-dirs (cdr (reverse exec-path))) ;FIXME: Why `cdr'? |
| 1034 | (cwd (file-name-as-directory (expand-file-name default-directory))) | 1036 | (cwd (file-name-as-directory (expand-file-name default-directory))) |
| 1035 | (ignored-extensions | 1037 | (ignored-extensions |
| 1036 | (and comint-completion-fignore | 1038 | (and comint-completion-fignore |
| 1037 | (mapconcat (function (lambda (x) (concat (regexp-quote x) "$"))) | 1039 | (mapconcat (function (lambda (x) (concat (regexp-quote x) "\\'"))) |
| 1038 | comint-completion-fignore "\\|"))) | 1040 | comint-completion-fignore "\\|"))) |
| 1039 | (dir "") (comps-in-dir ()) | 1041 | (dir "") (comps-in-dir ()) |
| 1040 | (file "") (abs-file-name "") (completions ())) | 1042 | (file "") (abs-file-name "") (completions ())) |
| @@ -1058,18 +1060,31 @@ See `shell-dynamic-complete-filename'. Returns t if successful." | |||
| 1058 | (setq comps-in-dir (cdr comps-in-dir))) | 1060 | (setq comps-in-dir (cdr comps-in-dir))) |
| 1059 | (setq path-dirs (cdr path-dirs))) | 1061 | (setq path-dirs (cdr path-dirs))) |
| 1060 | ;; OK, we've got a list of completions. | 1062 | ;; OK, we've got a list of completions. |
| 1061 | (let ((success (let ((comint-completion-addsuffix nil)) | 1063 | (list |
| 1062 | (comint-dynamic-simple-complete filenondir completions)))) | 1064 | start end |
| 1063 | (if (and (memq success '(sole shortest)) comint-completion-addsuffix | 1065 | (lambda (string pred action) |
| 1064 | (not (file-directory-p (comint-match-partial-filename)))) | 1066 | (completion-table-with-terminator |
| 1065 | (insert " ")) | 1067 | " " (lambda (string pred action) |
| 1066 | success))) | 1068 | (if (string-match "/" string) |
| 1069 | (completion-file-name-table string pred action) | ||
| 1070 | (complete-with-action action completions string pred))) | ||
| 1071 | string pred action))))) | ||
| 1072 | |||
| 1073 | ;; (defun shell-dynamic-complete-as-command () | ||
| 1074 | ;; "Dynamically complete at point as a command. | ||
| 1075 | ;; See `shell-dynamic-complete-filename'. Returns t if successful." | ||
| 1076 | ;; (apply #'completion-in-region shell--command-completion-data)) | ||
| 1067 | 1077 | ||
| 1068 | (defun shell-dynamic-complete-filename () | 1078 | (defun shell-dynamic-complete-filename () |
| 1069 | "Dynamically complete the filename at point. | 1079 | "Dynamically complete the filename at point. |
| 1070 | This completes only if point is at a suitable position for a | 1080 | This completes only if point is at a suitable position for a |
| 1071 | filename argument." | 1081 | filename argument." |
| 1072 | (interactive) | 1082 | (interactive) |
| 1083 | (let ((data (shell-filename-completion))) | ||
| 1084 | (if data (apply #'completion-in-region data)))) | ||
| 1085 | |||
| 1086 | (defun shell-filename-completion () | ||
| 1087 | "Return the completion data for file name at point, if any." | ||
| 1073 | (let ((opoint (point)) | 1088 | (let ((opoint (point)) |
| 1074 | (beg (comint-line-beginning-position))) | 1089 | (beg (comint-line-beginning-position))) |
| 1075 | (when (save-excursion | 1090 | (when (save-excursion |
| @@ -1077,24 +1092,21 @@ filename argument." | |||
| 1077 | (match-end 0) | 1092 | (match-end 0) |
| 1078 | beg)) | 1093 | beg)) |
| 1079 | (re-search-forward "[^ \t][ \t]" opoint t)) | 1094 | (re-search-forward "[^ \t][ \t]" opoint t)) |
| 1080 | (comint-dynamic-complete-as-filename)))) | 1095 | (comint-filename-completion)))) |
| 1081 | 1096 | ||
| 1082 | (defun shell-match-partial-variable () | 1097 | (defun shell-match-partial-variable () |
| 1083 | "Return the shell variable at point, or nil if none is found." | 1098 | "Return the shell variable at point, or nil if none is found." |
| 1084 | (save-excursion | 1099 | (save-excursion |
| 1085 | (let ((limit (point))) | 1100 | (if (re-search-backward "[^A-Za-z0-9_{(]" nil 'move) |
| 1086 | (if (re-search-backward "[^A-Za-z0-9_{}]" nil 'move) | 1101 | (or (looking-at "\\$") (forward-char 1))) |
| 1087 | (or (looking-at "\\$") (forward-char 1))) | 1102 | (if (or (eolp) (looking-at "[^A-Za-z0-9_{($]")) |
| 1088 | ;; Anchor the search forwards. | 1103 | nil |
| 1089 | (if (or (eolp) (looking-at "[^A-Za-z0-9_{}$]")) | 1104 | (looking-at "\\$?[{(]?[A-Za-z0-9_]*[})]?") |
| 1090 | nil | 1105 | (buffer-substring (match-beginning 0) (match-end 0))))) |
| 1091 | (re-search-forward "\\$?{?[A-Za-z0-9_]*}?" limit) | ||
| 1092 | (buffer-substring (match-beginning 0) (match-end 0)))))) | ||
| 1093 | 1106 | ||
| 1094 | (defun shell-dynamic-complete-environment-variable () | 1107 | (defun shell-dynamic-complete-environment-variable () |
| 1095 | "Dynamically complete the environment variable at point. | 1108 | "Dynamically complete the environment variable at point. |
| 1096 | Completes if after a variable, i.e., if it starts with a \"$\". | 1109 | Completes if after a variable, i.e., if it starts with a \"$\". |
| 1097 | See `shell-dynamic-complete-as-environment-variable'. | ||
| 1098 | 1110 | ||
| 1099 | This function is similar to `comint-dynamic-complete-filename', except that it | 1111 | This function is similar to `comint-dynamic-complete-filename', except that it |
| 1100 | searches `process-environment' for completion candidates. Note that this may | 1112 | searches `process-environment' for completion candidates. Note that this may |
| @@ -1106,38 +1118,69 @@ called `shell-dynamic-complete-process-environment-variable'. | |||
| 1106 | 1118 | ||
| 1107 | Returns non-nil if successful." | 1119 | Returns non-nil if successful." |
| 1108 | (interactive) | 1120 | (interactive) |
| 1109 | (let ((variable (shell-match-partial-variable))) | 1121 | (let ((data (shell-environment-variable-completion))) |
| 1110 | (if (and variable (string-match "^\\$" variable)) | 1122 | (if data |
| 1111 | (prog2 (unless (window-minibuffer-p (selected-window)) | 1123 | (prog2 (unless (window-minibuffer-p (selected-window)) |
| 1112 | (message "Completing variable name...")) | 1124 | (message "Completing variable name...")) |
| 1113 | (shell-dynamic-complete-as-environment-variable))))) | 1125 | (apply #'completion-in-region data))))) |
| 1114 | 1126 | ||
| 1115 | 1127 | ||
| 1116 | (defun shell-dynamic-complete-as-environment-variable () | 1128 | (defun shell-environment-variable-completion () |
| 1117 | "Dynamically complete at point as an environment variable. | 1129 | "Completion data for an environment variable at point, if any." |
| 1118 | Used by `shell-dynamic-complete-environment-variable'. | 1130 | (let* ((var (shell-match-partial-variable)) |
| 1119 | Uses `comint-dynamic-simple-complete'." | 1131 | (end (match-end 0))) |
| 1120 | (let* ((var (or (shell-match-partial-variable) "")) | 1132 | (when (and (not (zerop (length var))) (eq (aref var 0) ?$)) |
| 1121 | (variable (substring var (or (string-match "[^$({]\\|$" var) 0))) | 1133 | (let* ((start |
| 1122 | (variables (mapcar (function (lambda (x) | 1134 | (save-excursion |
| 1123 | (substring x 0 (string-match "=" x)))) | 1135 | (goto-char (match-beginning 0)) |
| 1124 | process-environment)) | 1136 | (looking-at "\\$?[({]*") |
| 1125 | (addsuffix comint-completion-addsuffix) | 1137 | (match-end 0))) |
| 1126 | (comint-completion-addsuffix nil) | 1138 | (variables (mapcar (lambda (x) |
| 1127 | (success (comint-dynamic-simple-complete variable variables))) | 1139 | (substring x 0 (string-match "=" x))) |
| 1128 | (if (memq success '(sole shortest)) | 1140 | process-environment)) |
| 1129 | (let* ((var (shell-match-partial-variable)) | 1141 | (suffix (case (char-before start) (?\{ "}") (?\( ")") (t "")))) |
| 1130 | (variable (substring var (string-match "[^$({]" var))) | 1142 | (list |
| 1131 | (protection (cond ((string-match "{" var) "}") | 1143 | start end |
| 1132 | ((string-match "(" var) ")") | 1144 | (apply-partially |
| 1133 | (t ""))) | 1145 | #'completion-table-with-terminator |
| 1134 | (suffix (cond ((null addsuffix) "") | 1146 | (cons (lambda (comp) |
| 1135 | ((file-directory-p | 1147 | (concat comp |
| 1136 | (comint-directory (getenv variable))) "/") | 1148 | suffix |
| 1137 | (t " ")))) | 1149 | (if (file-directory-p |
| 1138 | (insert protection suffix))) | 1150 | (comint-directory (getenv comp))) |
| 1139 | success)) | 1151 | "/"))) |
| 1140 | 1152 | "\\`a\\`") | |
| 1153 | variables)))))) | ||
| 1154 | |||
| 1155 | |||
| 1156 | (defun shell-c-a-p-replace-by-expanded-directory () | ||
| 1157 | "Expand directory stack reference before point. | ||
| 1158 | For use on `completion-at-point-functions'." | ||
| 1159 | (when (comint-match-partial-filename) | ||
| 1160 | (save-excursion | ||
| 1161 | (goto-char (match-beginning 0)) | ||
| 1162 | (let ((stack (cons default-directory shell-dirstack)) | ||
| 1163 | (index (cond ((looking-at "=-/?") | ||
| 1164 | (length shell-dirstack)) | ||
| 1165 | ((looking-at "=\\([0-9]+\\)/?") | ||
| 1166 | (string-to-number | ||
| 1167 | (buffer-substring | ||
| 1168 | (match-beginning 1) (match-end 1))))))) | ||
| 1169 | (when index | ||
| 1170 | (let ((start (match-beginning 0)) | ||
| 1171 | (end (match-end 0)) | ||
| 1172 | (replacement (file-name-as-directory (nth index stack)))) | ||
| 1173 | (lambda () | ||
| 1174 | (cond | ||
| 1175 | ((>= index (length stack)) | ||
| 1176 | (error "Directory stack not that deep")) | ||
| 1177 | (t | ||
| 1178 | (save-excursion | ||
| 1179 | (goto-char start) | ||
| 1180 | (insert replacement) | ||
| 1181 | (delete-char (- end start))) | ||
| 1182 | (message "Directory item: %d" index) | ||
| 1183 | t))))))))) | ||
| 1141 | 1184 | ||
| 1142 | (defun shell-replace-by-expanded-directory () | 1185 | (defun shell-replace-by-expanded-directory () |
| 1143 | "Expand directory stack reference before point. | 1186 | "Expand directory stack reference before point. |
| @@ -1146,24 +1189,8 @@ See `default-directory' and `shell-dirstack'. | |||
| 1146 | 1189 | ||
| 1147 | Returns t if successful." | 1190 | Returns t if successful." |
| 1148 | (interactive) | 1191 | (interactive) |
| 1149 | (if (comint-match-partial-filename) | 1192 | (let ((f (shell-c-a-p-replace-by-expanded-directory))) |
| 1150 | (save-excursion | 1193 | (if f (funcall f)))) |
| 1151 | (goto-char (match-beginning 0)) | ||
| 1152 | (let ((stack (cons default-directory shell-dirstack)) | ||
| 1153 | (index (cond ((looking-at "=-/?") | ||
| 1154 | (length shell-dirstack)) | ||
| 1155 | ((looking-at "=\\([0-9]+\\)/?") | ||
| 1156 | (string-to-number | ||
| 1157 | (buffer-substring | ||
| 1158 | (match-beginning 1) (match-end 1))))))) | ||
| 1159 | (cond ((null index) | ||
| 1160 | nil) | ||
| 1161 | ((>= index (length stack)) | ||
| 1162 | (error "Directory stack not that deep")) | ||
| 1163 | (t | ||
| 1164 | (replace-match (file-name-as-directory (nth index stack)) t t) | ||
| 1165 | (message "Directory item: %d" index) | ||
| 1166 | t)))))) | ||
| 1167 | 1194 | ||
| 1168 | (provide 'shell) | 1195 | (provide 'shell) |
| 1169 | 1196 | ||