diff options
| author | Stefan Monnier | 2002-05-14 14:14:11 +0000 |
|---|---|---|
| committer | Stefan Monnier | 2002-05-14 14:14:11 +0000 |
| commit | 25ab24bcb9c0639dfca30a8dfcee4486e6b807af (patch) | |
| tree | 3bb3abdc856b53201c1c19929d9ffd457871198f | |
| parent | 51df53f840effe95be3c4ca1210a87fec1aafd53 (diff) | |
| download | emacs-25ab24bcb9c0639dfca30a8dfcee4486e6b807af.tar.gz emacs-25ab24bcb9c0639dfca30a8dfcee4486e6b807af.zip | |
(skeleton-transformation): Default to `identity'.
(skeleton-insert): Use `move-after' markers and `insert' rather
than rely on insert-before-markers.
(skeleton-internal-1): Handle `> \n' specially so that the newline
is inserted before the first line is indented.
| -rw-r--r-- | lisp/skeleton.el | 149 |
1 files changed, 79 insertions, 70 deletions
diff --git a/lisp/skeleton.el b/lisp/skeleton.el index 9c5d7173cd6..2b31194e7f1 100644 --- a/lisp/skeleton.el +++ b/lisp/skeleton.el | |||
| @@ -38,7 +38,7 @@ | |||
| 38 | ;; page 3: mirror-mode, an example for setting up paired insertion | 38 | ;; page 3: mirror-mode, an example for setting up paired insertion |
| 39 | 39 | ||
| 40 | 40 | ||
| 41 | (defvar skeleton-transformation nil | 41 | (defvar skeleton-transformation 'identity |
| 42 | "*If non-nil, function applied to literal strings before they are inserted. | 42 | "*If non-nil, function applied to literal strings before they are inserted. |
| 43 | It should take strings and characters and return them transformed, or nil | 43 | It should take strings and characters and return them transformed, or nil |
| 44 | which means no transformation. | 44 | which means no transformation. |
| @@ -301,17 +301,16 @@ When done with skeleton, but before going back to `_'-point call | |||
| 301 | (and skeleton-regions | 301 | (and skeleton-regions |
| 302 | (setq skeleton-regions | 302 | (setq skeleton-regions |
| 303 | (if (> skeleton-regions 0) | 303 | (if (> skeleton-regions 0) |
| 304 | (list (point-marker) | 304 | (list (copy-marker (point) t) |
| 305 | (save-excursion (forward-word skeleton-regions) | 305 | (save-excursion (forward-word skeleton-regions) |
| 306 | (point-marker))) | 306 | (point-marker))) |
| 307 | (setq skeleton-regions (- skeleton-regions)) | 307 | (setq skeleton-regions (- skeleton-regions)) |
| 308 | ;; copy skeleton-regions - 1 elements from `mark-ring' | 308 | ;; copy skeleton-regions - 1 elements from `mark-ring' |
| 309 | (let ((l1 (cons (mark-marker) mark-ring)) | 309 | (let ((l1 (cons (mark-marker) mark-ring)) |
| 310 | (l2 (list (point-marker)))) | 310 | (l2 (list (copy-marker (point) t)))) |
| 311 | (while (and l1 (> skeleton-regions 0)) | 311 | (while (and l1 (> skeleton-regions 0)) |
| 312 | (setq l2 (cons (car l1) l2) | 312 | (push (copy-marker (pop l1) t) l2) |
| 313 | skeleton-regions (1- skeleton-regions) | 313 | (setq skeleton-regions (1- skeleton-regions))) |
| 314 | l1 (cdr l1))) | ||
| 315 | (sort l2 '<)))) | 314 | (sort l2 '<)))) |
| 316 | (goto-char (car skeleton-regions)) | 315 | (goto-char (car skeleton-regions)) |
| 317 | (setq skeleton-regions (cdr skeleton-regions))) | 316 | (setq skeleton-regions (cdr skeleton-regions))) |
| @@ -378,13 +377,12 @@ automatically, and you are prompted to fill in the variable parts."))) | |||
| 378 | (defun skeleton-internal-list (skeleton &optional str recursive) | 377 | (defun skeleton-internal-list (skeleton &optional str recursive) |
| 379 | (let* ((start (save-excursion (beginning-of-line) (point))) | 378 | (let* ((start (save-excursion (beginning-of-line) (point))) |
| 380 | (column (current-column)) | 379 | (column (current-column)) |
| 381 | (line (buffer-substring start | 380 | (line (buffer-substring start (line-end-position))) |
| 382 | (save-excursion (end-of-line) (point)))) | ||
| 383 | opoint) | 381 | opoint) |
| 384 | (or str | 382 | (or str |
| 385 | (setq str `(setq str (skeleton-read ',(car skeleton) nil ,recursive)))) | 383 | (setq str `(setq str (skeleton-read ',(car skeleton) nil ,recursive)))) |
| 386 | (when (and (eq (cadr skeleton) '\n) | 384 | (when (and (eq (cadr skeleton) '\n) |
| 387 | (<= (current-column) (current-indentation))) | 385 | (save-excursion (skip-chars-backward " \t") (bolp))) |
| 388 | (setq skeleton (cons nil (cons '> (cddr skeleton))))) | 386 | (setq skeleton (cons nil (cons '> (cddr skeleton))))) |
| 389 | (while (setq skeleton-modified (eq opoint (point)) | 387 | (while (setq skeleton-modified (eq opoint (point)) |
| 390 | opoint (point) | 388 | opoint (point) |
| @@ -395,8 +393,8 @@ automatically, and you are prompted to fill in the variable parts."))) | |||
| 395 | (if (eq (cdr quit) 'recursive) | 393 | (if (eq (cdr quit) 'recursive) |
| 396 | (setq recursive 'quit | 394 | (setq recursive 'quit |
| 397 | skeleton (memq 'resume: skeleton)) | 395 | skeleton (memq 'resume: skeleton)) |
| 398 | ;; remove the subskeleton as far as it has been shown | 396 | ;; Remove the subskeleton as far as it has been shown |
| 399 | ;; the subskeleton shouldn't have deleted outside current line | 397 | ;; the subskeleton shouldn't have deleted outside current line. |
| 400 | (end-of-line) | 398 | (end-of-line) |
| 401 | (delete-region start (point)) | 399 | (delete-region start (point)) |
| 402 | (insert line) | 400 | (insert line) |
| @@ -410,68 +408,79 @@ automatically, and you are prompted to fill in the variable parts."))) | |||
| 410 | (signal 'quit 'recursive) | 408 | (signal 'quit 'recursive) |
| 411 | recursive)) | 409 | recursive)) |
| 412 | 410 | ||
| 413 | |||
| 414 | (defun skeleton-internal-1 (element &optional literal) | 411 | (defun skeleton-internal-1 (element &optional literal) |
| 415 | (cond ((char-or-string-p element) | 412 | (cond |
| 416 | (if (and (integerp element) ; -num | 413 | ((char-or-string-p element) |
| 417 | (< element 0)) | 414 | (if (and (integerp element) ; -num |
| 418 | (if skeleton-untabify | 415 | (< element 0)) |
| 419 | (backward-delete-char-untabify (- element)) | 416 | (if skeleton-untabify |
| 420 | (delete-backward-char (- element))) | 417 | (backward-delete-char-untabify (- element)) |
| 421 | (insert-before-markers (if (and skeleton-transformation | 418 | (delete-backward-char (- element))) |
| 422 | (not literal)) | 419 | (insert (if (and skeleton-transformation |
| 423 | (funcall skeleton-transformation element) | 420 | (not literal)) |
| 424 | element)))) | 421 | (funcall skeleton-transformation element) |
| 425 | ((eq element '\n) ; actually (eq '\n 'n) | 422 | element)))) |
| 426 | (cond | 423 | ((or (eq element '\n) ; actually (eq '\n 'n) |
| 427 | ((and skeleton-regions (eq (nth 1 skeleton) '_)) | 424 | ;; The sequence `> \n' is handled specially so as to indent the first |
| 428 | (or (eolp) (newline)) | 425 | ;; line after inserting the newline (to get the proper indentation). |
| 429 | (indent-region (line-beginning-position) | 426 | (and (eq element '>) (eq (nth 1 skeleton) '\n) (pop skeleton))) |
| 430 | (car skeleton-regions) nil)) | 427 | (let ((pos (if (eq element '>) (point)))) |
| 431 | ;; \n as last element only inserts \n if not at eol. | 428 | (cond |
| 432 | ((and (null (cdr skeleton)) (eolp)) nil) | 429 | ((and skeleton-regions (eq (nth 1 skeleton) '_)) |
| 433 | (skeleton-newline-indent-rigidly | 430 | (or (eolp) (newline)) |
| 434 | (indent-to (prog1 (current-indentation) (newline)))) | 431 | (if pos (save-excursion (goto-char pos) (indent-according-to-mode))) |
| 435 | (t (newline) (indent-according-to-mode)))) | 432 | (indent-region (line-beginning-position) |
| 436 | ((eq element '>) | 433 | (car skeleton-regions) nil)) |
| 437 | (if (and skeleton-regions (eq (nth 1 skeleton) '_)) | 434 | ;; \n as last element only inserts \n if not at eol. |
| 438 | (indent-region (line-beginning-position) | 435 | ((and (null (cdr skeleton)) (eolp)) |
| 439 | (car skeleton-regions) nil) | 436 | (if pos (indent-according-to-mode))) |
| 440 | (indent-according-to-mode))) | 437 | (skeleton-newline-indent-rigidly |
| 441 | ((eq element '_) | 438 | (let ((pt (point))) |
| 442 | (if skeleton-regions | 439 | (newline) |
| 443 | (progn | 440 | (indent-to (save-excursion |
| 444 | (goto-char (car skeleton-regions)) | 441 | (goto-char pt) |
| 445 | (setq skeleton-regions (cdr skeleton-regions)) | 442 | (if pos (indent-according-to-mode)) |
| 446 | (and (<= (current-column) (current-indentation)) | 443 | (current-indentation))))) |
| 447 | (eq (nth 1 skeleton) '\n) | 444 | (t (if pos (reindent-then-newline-and-indent) |
| 448 | (end-of-line 0))) | 445 | (newline) |
| 449 | (or skeleton-point | 446 | (indent-according-to-mode)))))) |
| 450 | (setq skeleton-point (point))))) | 447 | ((eq element '>) |
| 448 | (if (and skeleton-regions (eq (nth 1 skeleton) '_)) | ||
| 449 | (indent-region (line-beginning-position) | ||
| 450 | (car skeleton-regions) nil) | ||
| 451 | (indent-according-to-mode))) | ||
| 452 | ((eq element '_) | ||
| 453 | (if skeleton-regions | ||
| 454 | (progn | ||
| 455 | (goto-char (pop skeleton-regions)) | ||
| 456 | (and (<= (current-column) (current-indentation)) | ||
| 457 | (eq (nth 1 skeleton) '\n) | ||
| 458 | (end-of-line 0))) | ||
| 459 | (or skeleton-point | ||
| 460 | (setq skeleton-point (point))))) | ||
| 451 | ((eq element '&) | 461 | ((eq element '&) |
| 452 | (when skeleton-modified (pop skeleton))) | 462 | (when skeleton-modified (pop skeleton))) |
| 453 | ((eq element '|) | 463 | ((eq element '|) |
| 454 | (unless skeleton-modified (pop skeleton))) | 464 | (unless skeleton-modified (pop skeleton))) |
| 455 | ((eq element '@) | 465 | ((eq element '@) |
| 456 | (push (point) skeleton-positions) | 466 | (push (point) skeleton-positions) |
| 457 | (unless skeleton-point (setq skeleton-point (point)))) | 467 | (unless skeleton-point (setq skeleton-point (point)))) |
| 458 | ((eq 'quote (car-safe element)) | 468 | ((eq 'quote (car-safe element)) |
| 459 | (eval (nth 1 element))) | 469 | (eval (nth 1 element))) |
| 460 | ((or (stringp (car-safe element)) | 470 | ((or (stringp (car-safe element)) |
| 461 | (consp (car-safe element))) | 471 | (consp (car-safe element))) |
| 462 | (if (symbolp (car-safe (car element))) | 472 | (if (symbolp (car-safe (car element))) |
| 463 | (while (skeleton-internal-list element nil t)) | 473 | (while (skeleton-internal-list element nil t)) |
| 464 | (setq literal (car element)) | 474 | (setq literal (car element)) |
| 465 | (while literal | 475 | (while literal |
| 466 | (skeleton-internal-list element (car literal)) | 476 | (skeleton-internal-list element (car literal)) |
| 467 | (setq literal (cdr literal))))) | 477 | (setq literal (cdr literal))))) |
| 468 | ((null element)) | 478 | ((null element)) |
| 469 | ((skeleton-internal-1 (eval element) t)))) | 479 | (t (skeleton-internal-1 (eval element) t)))) |
| 470 | 480 | ||
| 471 | |||
| 472 | ;; Maybe belongs into simple.el or elsewhere | 481 | ;; Maybe belongs into simple.el or elsewhere |
| 473 | ;; ;###autoload | 482 | ;; ;;;###autoload |
| 474 | ;;; (define-skeleton local-variables-section | 483 | ;; (define-skeleton local-variables-section |
| 475 | ;; "Insert a local variables section. Use current comment syntax if any." | 484 | ;; "Insert a local variables section. Use current comment syntax if any." |
| 476 | ;; (completing-read "Mode: " obarray | 485 | ;; (completing-read "Mode: " obarray |
| 477 | ;; (lambda (symbol) | 486 | ;; (lambda (symbol) |