From: Micha Wiedenmann
Subject: skip SPACE based on context
Date: 
Message-ID: <wky9q76o0a.fsf@ID-56226.news.dfncis.de>
Hi,

i am new to both, English and Lisp and I would be very happy if you
could helb me. (Please correct my spelling!)

I have the following lisp problem (besides at Gnus v5.8.8 source):

I have a Gcc: line like

| Gcc: Group1, Group2, "Group 2" 

and I want to parse that line. So my code looks like:

,----
|(let* ((start-name (save-excursion	; begin of the name
|                     ;; CCC following problems:
|                     ;; Gcc: Group1, Group2, "Group 3"
|                     ;; ` ' as part of `, ' need to stop chars-backward!
|                     ;; `"' must be removed, -> part of group name
|                     (skip-chars-backward "^,\"\t\n")
|                     (point)))
`----

The problem is that based on the context SPACE has to skiped (if quoted)
or SPACE together with `,' (`, ') is a "stopp" character. Could you help
me?

TIA, Micha



(defun message-expand-group ()
  "Expand the group name under point."
  (interactive)
  (let* ((start-name (save-excursion	; begin of the name
		       ;; CCC following problems:
		       ;; Gcc: Group1, Group2, "Group 3"
		       ;; ` ' as part of `, ' need to stop chars-backward!
		       ;; `"' must be removed, -> part of group name
		       (skip-chars-backward "^,\"\t\n")
		       (point)))
		       ;; CCC seems to be not that good code:
;		       (if (save-excursion ; look if group name begins with `"'
;			     (eq (skip-chars-backward "\"") 0))
;			   (point)
;			 (1- (point)))))
;		       (point))) ; move to begin
	 (end-name (save-excursion	;end of the name
		     (skip-chars-forward "^,\"\t\n") (point)))	; move to end
	 (string (buffer-substring start-name end-name)) ; the already typed part
	 (completion-ignore-case t)	; don't consider case significant in completion
	 (hashtb (and (boundp 'gnus-active-hashtb) gnus-active-hashtb))
	 (completions (all-completions string hashtb)) ; possible name completions
	 comp)
    ;; CCC _Bug_ when evaluatet if point is not at the end of the name!
    ;; original version:
    ;; (delete-region b (point))))

    (message (concat "CCC Debug; string: " string))
    (delete-region start-name end-name)	; delete name and insert new generated name
    (message (concat "CCC Debug; length completions: " (int-to-string (length completions))))

    (cond
     ((= (length completions) 1)	; only one possible completion
      (message "CCC Debug: only possible completion")
      (if (string= (car completions) string) ; already the right name insert
	  (progn			
	    (insert string)
	    (message "Only matching group")) 
	(insert (car completions))))	; else insere right name
     ((setq comp (try-completion string hashtb)) ; common part
      (message "CCC Debug; common part")
      (insert comp)			; expand to common part
      ;; do the following only if user has already typed the whole common part
      (if (string= comp string)		; name is common part of completions
	   (save-selected-window		; show *Completions*
	     (pop-to-buffer "*Completions*")
	     (buffer-disable-undo)
	     (let ((buffer-read-only nil))
	       (erase-buffer)
	       (let ((standard-output (current-buffer)))
		 (display-completion-list (sort completions 'string<)))
	       (goto-char (point-min))
	       (delete-region (point) (progn (forward-line 3) (point)))))))
     (t
      (insert string)		; else do nothing
      (message "No matching groups")))))
From: Raymond Wiker
Subject: Re: skip SPACE based on context
Date: 
Message-ID: <86ae2mida6.fsf@raw.grenland.fast.no>
Micha Wiedenmann <················@gmx.net> writes:

> Hi,
> 
> i am new to both, English and Lisp and I would be very happy if you
> could helb me. (Please correct my spelling!)
> 
> I have the following lisp problem (besides at Gnus v5.8.8 source):
> 
> I have a Gcc: line like
> 
> | Gcc: Group1, Group2, "Group 2" 
> 
> and I want to parse that line. So my code looks like:
> 
> ,----
> |(let* ((start-name (save-excursion	; begin of the name
> |                     ;; CCC following problems:
> |                     ;; Gcc: Group1, Group2, "Group 3"
> |                     ;; ` ' as part of `, ' need to stop chars-backward!
> |                     ;; `"' must be removed, -> part of group name
> |                     (skip-chars-backward "^,\"\t\n")
> |                     (point)))
> `----
> 
> The problem is that based on the context SPACE has to skiped (if quoted)
> or SPACE together with `,' (`, ') is a "stopp" character. Could you help
> me?

        It may be more efficient asking this kind of question in the
emacs newsgroups. That said, you should look into the functions
forward-sexp and backward-sexp, in conjunction with the syntax tables.

        Briefly, forward-sexp takes you to the end of the next
structured expression ("sexp"). If the next sexp is a string, you'll
move point to the character after the string. If point is inside the
string, you'll move to the end of the next word in the string - i.e,
backward-sexp and forward-sexp can be used to examine strings
recursively. 

        If point is somewhere in front of a sexp, forward-sexp will
take you to the end of the sexp, and backward-sexp will take you to
the front of the sexp again. Thus,

(defun this-sexp ()
  (interactive)
  (save-excursion 
    (let ((e (progn (forward-sexp) (point)))
	  (b (progn (backward-sexp) (point))))
      (message "Got %s" (buffer-substring b e)))))

        You may also want to change the local syntax table (via
modify-syntax-entry) in the *Article* buffer (or whatever) so that "-"
and "." are considered as word or symbol constituents (probably the
latter). 

-- 
Raymond Wiker
·············@fast.no