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))) " "))))