Function: comint-arguments
comint-arguments is a byte-compiled function defined in comint.el.gz.
Signature
(comint-arguments STRING NTH MTH)
Documentation
Return from STRING the NTH to MTH arguments.
NTH and/or MTH can be nil, which means the last argument.
NTH and MTH can be negative to count from the end; -1 means
the last argument.
Returned arguments are separated by single spaces. We assume
whitespace separates arguments, except within quotes and except
for a space or tab that immediately follows a backslash. Also, a
run of one or more of a single character in
comint-delimiter-argument-list is a separate argument.
Argument 0 is the command name.
Source Code
;; Defined in /usr/src/emacs/lisp/comint.el.gz
(defun comint-arguments (string nth mth)
"Return from STRING the NTH to MTH arguments.
NTH and/or MTH can be nil, which means the last argument.
NTH and MTH can be negative to count from the end; -1 means
the last argument.
Returned arguments are separated by single spaces. We assume
whitespace separates arguments, except within quotes and except
for a space or tab that immediately follows a backslash. Also, a
run of one or more of a single character in
`comint-delimiter-argument-list' is a separate argument.
Argument 0 is the command name."
;; The first line handles ordinary characters and backslash-sequences
;; (except with w32 msdos-like shells, where backslashes are valid).
;; The second matches "-quoted strings.
;; The third matches '-quoted strings.
;; The fourth matches `-quoted strings.
;; This seems to fit the syntax of BASH 2.0.
(let* ((backslash-escape (not (and (fboundp 'w32-shell-dos-semantics)
(w32-shell-dos-semantics))))
(first (if backslash-escape
"[^ \n\t\"'`\\]\\|\\(\\\\.\\)\\|"
"[^ \n\t\"'`]+\\|"))
(argpart (concat first
"\\(\"\\([^\"\\]\\|\\\\.\\)*\"\\|\
'[^']*'\\|\
`[^`]*`\\)"))
(quote-subexpr (if backslash-escape 2 1))
(args ()) (pos 0)
(count 0)
beg str quotes)
;; Build a list of all the args until we have as many as we want.
(while (and (or (null mth) (< mth 0) (<= count mth))
(string-match argpart string pos))
;; Apply the `literal' text property to backslash-escaped
;; characters, so that `comint-delim-arg' won't break them up.
(and backslash-escape
(match-beginning 1)
(put-text-property (match-beginning 1) (match-end 1)
'literal t string))
(if (and beg (= pos (match-beginning 0)))
;; It's contiguous, part of the same arg.
(setq pos (match-end 0)
quotes (or quotes (match-beginning quote-subexpr)))
;; It's a new separate arg.
(if beg
;; Put the previous arg, if there was one, onto ARGS.
(setq str (substring string beg pos)
args (if quotes (cons str args)
(nconc (comint-delim-arg str) args))))
(setq count (length args))
(setq quotes (match-beginning quote-subexpr))
(setq beg (match-beginning 0))
(setq pos (match-end 0))))
(if beg
(setq str (substring string beg pos)
args (if quotes (cons str args)
(nconc (comint-delim-arg str) args))))
(setq count (length args))
(let ((n (cond
((null nth) (1- count))
((>= nth 0) nth)
(t (+ count nth))))
(m (cond
((null mth) 0)
((>= mth 0) (1- (- count mth)))
(t (1- (- mth))))))
(mapconcat
(lambda (a) a) (nthcdr n (nreverse (nthcdr m args))) " "))))