branch: elpa/bash-completion
commit f7bfc68ea28525f1ff4428d6c1859f6d1c10ac17
Author: Stephane Zermatten <[email protected]>
Commit: Stephane Zermatten <[email protected]>
bash completion
---
bash-complete.el | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 91 insertions(+)
diff --git a/bash-complete.el b/bash-complete.el
new file mode 100644
index 0000000000..b15daea8d9
--- /dev/null
+++ b/bash-complete.el
@@ -0,0 +1,91 @@
+
+(defun bash-complete-dynamic-complete ()
+ "Bash completion function for `comint-complete-dynamic-functions'.
+
+Call bash to do the completion."
+ (when (comint-match-partial-filename)
+ (unless (window-minibuffer-p (selected-window))
+ (message "Bash completion..."))
+ (bash-complete-dynamic-complete-0)))
+
+(defun bash-complete-dynamic-complete-0 ()
+ (save-excursion
+ (let* ( (pos (point))
+ (start (comint-line-beginning-position))
+ (end (line-end-position))
+ (line (buffer-substring-no-properties start end))
+ (wordsplit (bash-complete-split start end pos))
+ (words (car wordsplit))
+ (cword (cdr wordsplit))
+ (stub (nth cword words)) )
+ (comint-simple-complete stub
+ (bash-complete-comm
+ line pos words cword)))))
+
+(defun bash-complete-split (start end pos)
+ "Split LINE like bash would do, keep track of current word at POS.
+
+Return a list containing the words and the number of the word
+at POS, the current word: ( (word1 word2 ...) . wordnum )"
+ (save-excursion
+ (goto-char start)
+ (nreverse (bash-complete-split-0 start end pos nil))))
+
+(defun bash-complete-split-0 (start end pos accum)
+ (let ( (char-start (char-after))
+ (quote nil) )
+ (when (or (= char-start ?') (= char-start ?\"))
+ (forward-char)
+ (setq quote char-start))
+ (bash-complete-split-1 start end pos quote accum)))
+
+;; "hell o" wor\ ld 'baa baaaa'a"hell o"world a
+
+;; (progn
+;; (load-library "~/.emacs.d/bash-complete.el")
+;; (let ((start 64) (end 108))
+;; (bash-complete-split start end 80)))
+
+(defun bash-complete-split-1 (start end pos quote accum)
+ (skip-chars-forward (bash-complete-nonsep quote) end)
+ (cond
+ ;; an escaped char, skip, whatever it is
+ ((= ?\\ (char-before))
+ (forward-char)
+ (bash-complete-split-1 start end pos (if (and quote (= quote
(char-before))) nil quote) accum))
+ ;; opening quote
+ ((and (not quote) (or (= ?' (char-after)) (= ?\" (char-after))))
+ (bash-complete-split-0 start end pos accum))
+ ;; closing quote
+ ((and quote (= quote (char-after)))
+ (forward-char)
+ (bash-complete-split-0 start end pos accum))
+ ;; space inside a quote
+ ((and quote (not (= quote (char-after))))
+ (forward-char)
+ (bash-complete-split-1 start end pos quote accum))
+ ;; word end
+ (t
+ (let ((str (buffer-substring-no-properties start (point))))
+ (when str
+ (push str accum)))
+ (skip-chars-forward " \t\n\r" end)
+ (if (< (point) end)
+ (bash-complete-split-0 (point) end pos accum)
+ accum))))
+
+(defun bash-complete-nonsep (quote)
+ (if quote
+ (concat "^ \t\n\r" (char-to-string quote))
+ "^ \t\n\r'\""))
+
+(defun bash-complete-comm (line pos words cword)
+ "Set LINE, POS, WORDS and CWORD, call bash completion, return the result.
+
+This function starts a separate bash process if necessary, sets up the
+completion environment (COMP_LINE, COMP_POINT, COMP_WORDS, COMP_CWORD) and
+calls compgen.
+
+The result is a list of candidates, which might be empty."
+
+ )