2529 |
new line-end line-beg) |
new line-end line-beg) |
2530 |
(unwind-protect |
(unwind-protect |
2531 |
(progn |
(progn |
2532 |
(if (not (or (eq last-command 'next-line) |
(if (not (memq last-command '(next-line previous-line))) |
|
(eq last-command 'previous-line))) |
|
2533 |
(setq temporary-goal-column |
(setq temporary-goal-column |
2534 |
(if (and track-eol (eolp) |
(if (and track-eol (eolp) |
2535 |
;; Don't count beg of empty line as end of line |
;; Don't count beg of empty line as end of line |
2742 |
and drag it forward past ARG other words (backward if ARG negative). |
and drag it forward past ARG other words (backward if ARG negative). |
2743 |
If ARG is zero, the words around or after point and around or after mark |
If ARG is zero, the words around or after point and around or after mark |
2744 |
are interchanged." |
are interchanged." |
2745 |
|
;; FIXME: `foo a!nd bar' should transpose into `bar and foo'. |
2746 |
(interactive "*p") |
(interactive "*p") |
2747 |
(transpose-subr 'forward-word arg)) |
(transpose-subr 'forward-word arg)) |
2748 |
|
|
2751 |
Does not work on a sexp that point is in the middle of |
Does not work on a sexp that point is in the middle of |
2752 |
if it is a list or string." |
if it is a list or string." |
2753 |
(interactive "*p") |
(interactive "*p") |
2754 |
(transpose-subr 'forward-sexp arg)) |
(transpose-subr |
2755 |
|
(lambda (arg) |
2756 |
|
;; Here we should try to simulate the behavior of |
2757 |
|
;; (cons (progn (forward-sexp x) (point)) |
2758 |
|
;; (progn (forward-sexp (- x)) (point))) |
2759 |
|
;; Except that we don't want to rely on the second forward-sexp |
2760 |
|
;; putting us back to where we want to be, since forward-sexp-function |
2761 |
|
;; might do funny things like infix-precedence. |
2762 |
|
(if (if (> arg 0) |
2763 |
|
(looking-at "\\sw\\|\\s_") |
2764 |
|
(and (not (bobp)) |
2765 |
|
(save-excursion (forward-char -1) (looking-at "\\sw\\|\\s_")))) |
2766 |
|
;; Jumping over a symbol. We might be inside it, mind you. |
2767 |
|
(progn (funcall (if (> arg 0) |
2768 |
|
'skip-syntax-backward 'skip-syntax-forward) |
2769 |
|
"w_") |
2770 |
|
(cons (save-excursion (forward-sexp arg) (point)) (point))) |
2771 |
|
;; Otherwise, we're between sexps. Take a step back before jumping |
2772 |
|
;; to make sure we'll obey the same precedence no matter which direction |
2773 |
|
;; we're going. |
2774 |
|
(funcall (if (> arg 0) 'skip-syntax-backward 'skip-syntax-forward) " .") |
2775 |
|
(cons (save-excursion (forward-sexp arg) (point)) |
2776 |
|
(progn (while (or (forward-comment (if (> arg 0) 1 -1)) |
2777 |
|
(not (zerop (funcall (if (> arg 0) |
2778 |
|
'skip-syntax-forward |
2779 |
|
'skip-syntax-backward) |
2780 |
|
"."))))) |
2781 |
|
(point))))) |
2782 |
|
arg 'special)) |
2783 |
|
|
2784 |
(defun transpose-lines (arg) |
(defun transpose-lines (arg) |
2785 |
"Exchange current line and previous line, leaving point after both. |
"Exchange current line and previous line, leaving point after both. |
2968 |
;; Determine where to split the line. |
;; Determine where to split the line. |
2969 |
(let* (after-prefix |
(let* (after-prefix |
2970 |
(fill-point |
(fill-point |
2971 |
(let ((opoint (point)) |
(let ((opoint (point))) |
|
bounce |
|
|
(first t)) |
|
2972 |
(save-excursion |
(save-excursion |
2973 |
(beginning-of-line) |
(beginning-of-line) |
2974 |
(setq after-prefix (point)) |
(setq after-prefix (point)) |
2976 |
(looking-at (regexp-quote fill-prefix)) |
(looking-at (regexp-quote fill-prefix)) |
2977 |
(setq after-prefix (match-end 0))) |
(setq after-prefix (match-end 0))) |
2978 |
(move-to-column (1+ fc)) |
(move-to-column (1+ fc)) |
2979 |
;; Move back to the point where we can break the line. |
(fill-move-to-break-point after-prefix) |
|
;; We break the line between word or |
|
|
;; after/before the character which has character |
|
|
;; category `|'. We search space, \c| followed by |
|
|
;; a character, or \c| following a character. If |
|
|
;; not found, place the point at beginning of line. |
|
|
(while (or first |
|
|
(and (not (bobp)) |
|
|
(not bounce) |
|
|
(fill-nobreak-p))) |
|
|
(setq first nil) |
|
|
(re-search-backward "[ \t]\\|\\c|.\\|.\\c|\\|^") |
|
|
;; If we find nowhere on the line to break it, |
|
|
;; break after one word. Set bounce to t |
|
|
;; so we will not keep going in this while loop. |
|
|
(if (<= (point) after-prefix) |
|
|
(progn |
|
|
(goto-char after-prefix) |
|
|
(re-search-forward "[ \t]" opoint t) |
|
|
(setq bounce t)) |
|
|
(if (looking-at "[ \t]") |
|
|
;; Break the line at word boundary. |
|
|
(skip-chars-backward " \t") |
|
|
;; Break the line after/before \c|. |
|
|
(forward-char 1)))) |
|
|
(if enable-multibyte-characters |
|
|
;; If we are going to break the line after or |
|
|
;; before a non-ascii character, we may have |
|
|
;; to run a special function for the charset |
|
|
;; of the character to find the correct break |
|
|
;; point. |
|
|
(if (not (and (eq (charset-after (1- (point))) 'ascii) |
|
|
(eq (charset-after (point)) 'ascii))) |
|
|
(fill-find-break-point after-prefix))) |
|
|
|
|
|
;; Let fill-point be set to the place where we end up. |
|
|
;; But move back before any whitespace here. |
|
|
(skip-chars-backward " \t") |
|
2980 |
(point))))) |
(point))))) |
2981 |
|
|
2982 |
;; See whether the place we found is any good. |
;; See whether the place we found is any good. |
2983 |
(if (save-excursion |
(if (save-excursion |
2984 |
(goto-char fill-point) |
(goto-char fill-point) |
2985 |
(and (not (bolp)) |
(or (bolp) |
2986 |
;; There is no use breaking at end of line. |
;; There is no use breaking at end of line. |
2987 |
(not (save-excursion (skip-chars-forward " ") (eolp))) |
(save-excursion (skip-chars-forward " ") (eolp)) |
2988 |
;; It is futile to split at the end of the prefix |
;; It is futile to split at the end of the prefix |
2989 |
;; since we would just insert the prefix again. |
;; since we would just insert the prefix again. |
2990 |
(not (and after-prefix (<= (point) after-prefix))) |
(and after-prefix (<= (point) after-prefix)) |
2991 |
;; Don't split right after a comment starter |
;; Don't split right after a comment starter |
2992 |
;; since we would just make another comment starter. |
;; since we would just make another comment starter. |
2993 |
(not (and comment-start-skip |
(and comment-start-skip |
2994 |
(let ((limit (point))) |
(let ((limit (point))) |
2995 |
(beginning-of-line) |
(beginning-of-line) |
2996 |
(and (re-search-forward comment-start-skip |
(and (re-search-forward comment-start-skip |
2997 |
limit t) |
limit t) |
2998 |
(eq (point) limit))))))) |
(eq (point) limit)))))) |
2999 |
;; Ok, we have a useful place to break the line. Do it. |
;; No good place to break => stop trying. |
3000 |
(let ((prev-column (current-column))) |
(setq give-up t) |
3001 |
;; If point is at the fill-point, do not `save-excursion'. |
;; Ok, we have a useful place to break the line. Do it. |
3002 |
;; Otherwise, if a comment prefix or fill-prefix is inserted, |
(let ((prev-column (current-column))) |
3003 |
;; point will end up before it rather than after it. |
;; If point is at the fill-point, do not `save-excursion'. |
3004 |
(if (save-excursion |
;; Otherwise, if a comment prefix or fill-prefix is inserted, |
3005 |
(skip-chars-backward " \t") |
;; point will end up before it rather than after it. |
3006 |
(= (point) fill-point)) |
(if (save-excursion |
3007 |
(funcall comment-line-break-function t) |
(skip-chars-backward " \t") |
3008 |
|
(= (point) fill-point)) |
3009 |
|
(funcall comment-line-break-function t) |
3010 |
|
(save-excursion |
3011 |
|
(goto-char fill-point) |
3012 |
|
(funcall comment-line-break-function t))) |
3013 |
|
;; Now do justification, if required |
3014 |
|
(if (not (eq justify 'left)) |
3015 |
(save-excursion |
(save-excursion |
|
(goto-char fill-point) |
|
|
(funcall comment-line-break-function t))) |
|
|
;; Now do justification, if required |
|
|
(if (not (eq justify 'left)) |
|
|
(save-excursion |
|
3016 |
(end-of-line 0) |
(end-of-line 0) |
3017 |
(justify-current-line justify nil t))) |
(justify-current-line justify nil t))) |
3018 |
;; If making the new line didn't reduce the hpos of |
;; If making the new line didn't reduce the hpos of |
3019 |
;; the end of the line, then give up now; |
;; the end of the line, then give up now; |
3020 |
;; trying again will not help. |
;; trying again will not help. |
3021 |
(if (>= (current-column) prev-column) |
(if (>= (current-column) prev-column) |
3022 |
(setq give-up t))) |
(setq give-up t)))))) |
|
;; No good place to break => stop trying. |
|
|
(setq give-up t)))) |
|
3023 |
;; Justify last line. |
;; Justify last line. |
3024 |
(justify-current-line justify t t) |
(justify-current-line justify t t) |
3025 |
t))) |
t))) |
4068 |
(define-key ctl-x-4-map "c" 'clone-indirect-buffer-other-window) |
(define-key ctl-x-4-map "c" 'clone-indirect-buffer-other-window) |
4069 |
|
|
4070 |
|
|
|
;;; Syntax stuff. |
|
|
|
|
|
(defconst syntax-code-table |
|
|
'((?\ 0 "whitespace") |
|
|
(?- 0 "whitespace") |
|
|
(?. 1 "punctuation") |
|
|
(?w 2 "word") |
|
|
(?_ 3 "symbol") |
|
|
(?\( 4 "open parenthesis") |
|
|
(?\) 5 "close parenthesis") |
|
|
(?\' 6 "expression prefix") |
|
|
(?\" 7 "string quote") |
|
|
(?$ 8 "paired delimiter") |
|
|
(?\\ 9 "escape") |
|
|
(?/ 10 "character quote") |
|
|
(?< 11 "comment start") |
|
|
(?> 12 "comment end") |
|
|
(?@ 13 "inherit") |
|
|
(nil 14 "comment fence") |
|
|
(nil 15 "string fence")) |
|
|
"Alist of forms (CHAR CODE DESCRIPTION) mapping characters to syntax info. |
|
|
CHAR is a character that is allowed as first char in the string |
|
|
specifying the syntax when calling `modify-syntax-entry'. CODE is the |
|
|
corresponing syntax code as it is stored in a syntax cell, and |
|
|
can be used as value of a `syntax-table' property. |
|
|
DESCRIPTION is the descriptive string for the syntax.") |
|
|
|
|
|
|
|
4071 |
;;; Handling of Backspace and Delete keys. |
;;; Handling of Backspace and Delete keys. |
4072 |
|
|
4073 |
(defcustom normal-erase-is-backspace nil |
(defcustom normal-erase-is-backspace nil |