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