| 1 | ;;; longlines.el --- automatically wrap long lines |
| 2 | |
| 3 | ;; Copyright (C) 2000, 2001, 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc. |
| 4 | |
| 5 | ;; Authors: Kai Grossjohann <Kai.Grossjohann@CS.Uni-Dortmund.DE> |
| 6 | ;; Alex Schroeder <alex@gnu.org> |
| 7 | ;; Chong Yidong <cyd@stupidchicken.com> |
| 8 | ;; Maintainer: Chong Yidong <cyd@stupidchicken.com> |
| 9 | ;; Keywords: convenience, wp |
| 10 | |
| 11 | ;; This file is part of GNU Emacs. |
| 12 | |
| 13 | ;; GNU Emacs is free software; you can redistribute it and/or modify |
| 14 | ;; it under the terms of the GNU General Public License as published by |
| 15 | ;; the Free Software Foundation; either version 3, or (at your option) |
| 16 | ;; any later version. |
| 17 | |
| 18 | ;; GNU Emacs is distributed in the hope that it will be useful, |
| 19 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 21 | ;; GNU General Public License for more details. |
| 22 | |
| 23 | ;; You should have received a copy of the GNU General Public License |
| 24 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
| 25 | ;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, |
| 26 | ;; Boston, MA 02110-1301, USA. |
| 27 | |
| 28 | ;;; Commentary: |
| 29 | |
| 30 | ;; Some text editors save text files with long lines, and they |
| 31 | ;; automatically break these lines at whitespace, without actually |
| 32 | ;; inserting any newline characters. When doing `M-q' in Emacs, you |
| 33 | ;; are inserting newline characters. Longlines mode provides a file |
| 34 | ;; format which wraps the long lines when reading a file and unwraps |
| 35 | ;; the lines when saving the file. It can also wrap and unwrap |
| 36 | ;; automatically as editing takes place. |
| 37 | |
| 38 | ;; Special thanks to Rod Smith for many useful bug reports. |
| 39 | |
| 40 | ;;; Code: |
| 41 | |
| 42 | (defgroup longlines nil |
| 43 | "Automatic wrapping of long lines when loading files." |
| 44 | :group 'fill) |
| 45 | |
| 46 | (defcustom longlines-auto-wrap t |
| 47 | "Non-nil means long lines are automatically wrapped after each command. |
| 48 | Otherwise, you can perform filling using `fill-paragraph' or |
| 49 | `auto-fill-mode'. In any case, the soft newlines will be removed |
| 50 | when the file is saved to disk." |
| 51 | :group 'longlines |
| 52 | :type 'boolean) |
| 53 | |
| 54 | (defcustom longlines-wrap-follows-window-size nil |
| 55 | "Non-nil means wrapping and filling happen at the edge of the window. |
| 56 | Otherwise, `fill-column' is used, regardless of the window size. This |
| 57 | does not work well when the buffer is displayed in multiple windows |
| 58 | with differing widths. |
| 59 | |
| 60 | If the value is an integer, that specifies the distance from the |
| 61 | right edge of the window at which wrapping occurs. For any other |
| 62 | non-nil value, wrapping occurs 2 characters from the right edge." |
| 63 | :group 'longlines |
| 64 | :type 'boolean) |
| 65 | |
| 66 | (defcustom longlines-show-hard-newlines nil |
| 67 | "Non-nil means each hard newline is marked on the screen. |
| 68 | \(The variable `longlines-show-effect' controls what they look like.) |
| 69 | You can also enable the display temporarily, using the command |
| 70 | `longlines-show-hard-newlines'." |
| 71 | :group 'longlines |
| 72 | :type 'boolean) |
| 73 | |
| 74 | (defcustom longlines-show-effect (propertize "|\n" 'face 'escape-glyph) |
| 75 | "A string to display when showing hard newlines. |
| 76 | This is used when `longlines-show-hard-newlines' is on." |
| 77 | :group 'longlines |
| 78 | :type 'string) |
| 79 | |
| 80 | ;; Internal variables |
| 81 | |
| 82 | (defvar longlines-wrap-beg nil) |
| 83 | (defvar longlines-wrap-end nil) |
| 84 | (defvar longlines-wrap-point nil) |
| 85 | (defvar longlines-showing nil) |
| 86 | (defvar longlines-decoded nil) |
| 87 | |
| 88 | (make-variable-buffer-local 'longlines-wrap-beg) |
| 89 | (make-variable-buffer-local 'longlines-wrap-end) |
| 90 | (make-variable-buffer-local 'longlines-wrap-point) |
| 91 | (make-variable-buffer-local 'longlines-showing) |
| 92 | (make-variable-buffer-local 'longlines-decoded) |
| 93 | |
| 94 | ;; Mode |
| 95 | |
| 96 | (defvar message-indent-citation-function) |
| 97 | |
| 98 | ;;;###autoload |
| 99 | (define-minor-mode longlines-mode |
| 100 | "Toggle Long Lines mode. |
| 101 | In Long Lines mode, long lines are wrapped if they extend beyond |
| 102 | `fill-column'. The soft newlines used for line wrapping will not |
| 103 | show up when the text is yanked or saved to disk. |
| 104 | |
| 105 | If the variable `longlines-auto-wrap' is non-nil, lines are automatically |
| 106 | wrapped whenever the buffer is changed. You can always call |
| 107 | `fill-paragraph' to fill individual paragraphs. |
| 108 | |
| 109 | If the variable `longlines-show-hard-newlines' is non-nil, hard newlines |
| 110 | are indicated with a symbol." |
| 111 | :group 'longlines :lighter " ll" |
| 112 | (if longlines-mode |
| 113 | ;; Turn on longlines mode |
| 114 | (progn |
| 115 | (use-hard-newlines 1 'never) |
| 116 | (set (make-local-variable 'require-final-newline) nil) |
| 117 | (add-to-list 'buffer-file-format 'longlines) |
| 118 | (add-hook 'change-major-mode-hook 'longlines-mode-off nil t) |
| 119 | (add-hook 'before-revert-hook 'longlines-before-revert-hook nil t) |
| 120 | (make-local-variable 'buffer-substring-filters) |
| 121 | (make-local-variable 'longlines-auto-wrap) |
| 122 | (set (make-local-variable 'isearch-search-fun-function) |
| 123 | 'longlines-search-function) |
| 124 | (add-to-list 'buffer-substring-filters 'longlines-encode-string) |
| 125 | (when longlines-wrap-follows-window-size |
| 126 | (let ((dw (if (and (integerp longlines-wrap-follows-window-size) |
| 127 | (>= longlines-wrap-follows-window-size 0) |
| 128 | (< longlines-wrap-follows-window-size |
| 129 | (window-width))) |
| 130 | longlines-wrap-follows-window-size |
| 131 | 2))) |
| 132 | (set (make-local-variable 'fill-column) |
| 133 | (- (window-width) dw))) |
| 134 | (add-hook 'window-configuration-change-hook |
| 135 | 'longlines-window-change-function nil t)) |
| 136 | (let ((buffer-undo-list t) |
| 137 | (inhibit-read-only t) |
| 138 | (after-change-functions nil) |
| 139 | (mod (buffer-modified-p)) |
| 140 | buffer-file-name buffer-file-truename) |
| 141 | ;; Turning off undo is OK since (spaces + newlines) is |
| 142 | ;; conserved, except for a corner case in |
| 143 | ;; longlines-wrap-lines that we'll never encounter from here |
| 144 | (save-restriction |
| 145 | (widen) |
| 146 | (unless longlines-decoded |
| 147 | (longlines-decode-buffer) |
| 148 | (setq longlines-decoded t)) |
| 149 | (longlines-wrap-region (point-min) (point-max))) |
| 150 | (set-buffer-modified-p mod)) |
| 151 | (when (and longlines-show-hard-newlines |
| 152 | (not longlines-showing)) |
| 153 | (longlines-show-hard-newlines)) |
| 154 | |
| 155 | ;; Hacks to make longlines play nice with various modes. |
| 156 | (cond ((eq major-mode 'mail-mode) |
| 157 | (add-hook 'mail-setup-hook 'longlines-decode-buffer nil t) |
| 158 | (or mail-citation-hook |
| 159 | (add-hook 'mail-citation-hook 'mail-indent-citation nil t)) |
| 160 | (add-hook 'mail-citation-hook 'longlines-decode-region nil t)) |
| 161 | ((eq major-mode 'message-mode) |
| 162 | (add-hook 'message-setup-hook 'longlines-decode-buffer nil t) |
| 163 | (make-local-variable 'message-indent-citation-function) |
| 164 | (if (not (listp message-indent-citation-function)) |
| 165 | (setq message-indent-citation-function |
| 166 | (list message-indent-citation-function))) |
| 167 | (add-to-list 'message-indent-citation-function |
| 168 | 'longlines-decode-region t))) |
| 169 | |
| 170 | (add-hook 'after-change-functions 'longlines-after-change-function nil t) |
| 171 | (add-hook 'post-command-hook 'longlines-post-command-function nil t) |
| 172 | (when longlines-auto-wrap |
| 173 | (auto-fill-mode 0))) |
| 174 | ;; Turn off longlines mode |
| 175 | (setq buffer-file-format (delete 'longlines buffer-file-format)) |
| 176 | (if longlines-showing |
| 177 | (longlines-unshow-hard-newlines)) |
| 178 | (let ((buffer-undo-list t) |
| 179 | (after-change-functions nil) |
| 180 | (inhibit-read-only t) |
| 181 | buffer-file-name buffer-file-truename) |
| 182 | (if longlines-decoded |
| 183 | (save-restriction |
| 184 | (widen) |
| 185 | (longlines-encode-region (point-min) (point-max)) |
| 186 | (setq longlines-decoded nil)))) |
| 187 | (remove-hook 'change-major-mode-hook 'longlines-mode-off t) |
| 188 | (remove-hook 'after-change-functions 'longlines-after-change-function t) |
| 189 | (remove-hook 'post-command-hook 'longlines-post-command-function t) |
| 190 | (remove-hook 'before-revert-hook 'longlines-before-revert-hook t) |
| 191 | (remove-hook 'window-configuration-change-hook |
| 192 | 'longlines-window-change-function t) |
| 193 | (when longlines-wrap-follows-window-size |
| 194 | (kill-local-variable 'fill-column)) |
| 195 | (kill-local-variable 'isearch-search-fun-function) |
| 196 | (kill-local-variable 'require-final-newline) |
| 197 | (kill-local-variable 'buffer-substring-filters) |
| 198 | (kill-local-variable 'use-hard-newlines))) |
| 199 | |
| 200 | (defun longlines-mode-off () |
| 201 | "Turn off longlines mode. |
| 202 | This function exists to be called by `change-major-mode-hook' when the |
| 203 | major mode changes." |
| 204 | (longlines-mode 0)) |
| 205 | |
| 206 | ;; Showing the effect of hard newlines in the buffer |
| 207 | |
| 208 | (defun longlines-show-hard-newlines (&optional arg) |
| 209 | "Make hard newlines visible by adding a face. |
| 210 | With optional argument ARG, make the hard newlines invisible again." |
| 211 | (interactive "P") |
| 212 | (if arg |
| 213 | (longlines-unshow-hard-newlines) |
| 214 | (setq longlines-showing t) |
| 215 | (longlines-show-region (point-min) (point-max)))) |
| 216 | |
| 217 | (defun longlines-show-region (beg end) |
| 218 | "Make hard newlines between BEG and END visible." |
| 219 | (let* ((pmin (min beg end)) |
| 220 | (pmax (max beg end)) |
| 221 | (pos (text-property-not-all pmin pmax 'hard nil)) |
| 222 | (mod (buffer-modified-p)) |
| 223 | (buffer-undo-list t) |
| 224 | (inhibit-read-only t) |
| 225 | (inhibit-modification-hooks t) |
| 226 | buffer-file-name buffer-file-truename) |
| 227 | (while pos |
| 228 | (put-text-property pos (1+ pos) 'display |
| 229 | (copy-sequence longlines-show-effect)) |
| 230 | (setq pos (text-property-not-all (1+ pos) pmax 'hard nil))) |
| 231 | (restore-buffer-modified-p mod))) |
| 232 | |
| 233 | (defun longlines-unshow-hard-newlines () |
| 234 | "Make hard newlines invisible again." |
| 235 | (interactive) |
| 236 | (setq longlines-showing nil) |
| 237 | (let ((pos (text-property-not-all (point-min) (point-max) 'hard nil)) |
| 238 | (mod (buffer-modified-p)) |
| 239 | (buffer-undo-list t) |
| 240 | (inhibit-read-only t) |
| 241 | (inhibit-modification-hooks t) |
| 242 | buffer-file-name buffer-file-truename) |
| 243 | (while pos |
| 244 | (remove-text-properties pos (1+ pos) '(display)) |
| 245 | (setq pos (text-property-not-all (1+ pos) (point-max) 'hard nil))) |
| 246 | (restore-buffer-modified-p mod))) |
| 247 | |
| 248 | ;; Wrapping the paragraphs. |
| 249 | |
| 250 | (defun longlines-wrap-region (beg end) |
| 251 | "Wrap each successive line, starting with the line before BEG. |
| 252 | Stop when we reach lines after END that don't need wrapping, or the |
| 253 | end of the buffer." |
| 254 | (let ((mod (buffer-modified-p))) |
| 255 | (setq longlines-wrap-point (point)) |
| 256 | (goto-char beg) |
| 257 | (forward-line -1) |
| 258 | ;; Two successful longlines-wrap-line's in a row mean successive |
| 259 | ;; lines don't need wrapping. |
| 260 | (while (null (and (longlines-wrap-line) |
| 261 | (or (eobp) |
| 262 | (and (>= (point) end) |
| 263 | (longlines-wrap-line)))))) |
| 264 | (goto-char longlines-wrap-point) |
| 265 | (set-buffer-modified-p mod))) |
| 266 | |
| 267 | (defun longlines-wrap-line () |
| 268 | "If the current line needs to be wrapped, wrap it and return nil. |
| 269 | If wrapping is performed, point remains on the line. If the line does |
| 270 | not need to be wrapped, move point to the next line and return t." |
| 271 | (if (longlines-set-breakpoint) |
| 272 | (progn (insert-before-markers ?\n) |
| 273 | (backward-char 1) |
| 274 | (delete-char -1) |
| 275 | (forward-char 1) |
| 276 | nil) |
| 277 | (if (longlines-merge-lines-p) |
| 278 | (progn (end-of-line) |
| 279 | ;; After certain commands (e.g. kill-line), there may be two |
| 280 | ;; successive soft newlines in the buffer. In this case, we |
| 281 | ;; replace these two newlines by a single space. Unfortunately, |
| 282 | ;; this breaks the conservation of (spaces + newlines), so we |
| 283 | ;; have to fiddle with longlines-wrap-point. |
| 284 | (if (or (prog1 (bolp) (forward-char 1)) (eolp)) |
| 285 | (progn |
| 286 | (delete-char -1) |
| 287 | (if (> longlines-wrap-point (point)) |
| 288 | (setq longlines-wrap-point |
| 289 | (1- longlines-wrap-point)))) |
| 290 | (insert-before-markers-and-inherit ?\s) |
| 291 | (backward-char 1) |
| 292 | (delete-char -1) |
| 293 | (forward-char 1)) |
| 294 | nil) |
| 295 | (forward-line 1) |
| 296 | t))) |
| 297 | |
| 298 | (defun longlines-set-breakpoint () |
| 299 | "Place point where we should break the current line, and return t. |
| 300 | If the line should not be broken, return nil; point remains on the |
| 301 | line." |
| 302 | (move-to-column fill-column) |
| 303 | (if (and (re-search-forward "[^ ]" (line-end-position) 1) |
| 304 | (> (current-column) fill-column)) |
| 305 | ;; This line is too long. Can we break it? |
| 306 | (or (longlines-find-break-backward) |
| 307 | (progn (move-to-column fill-column) |
| 308 | (longlines-find-break-forward))))) |
| 309 | |
| 310 | (defun longlines-find-break-backward () |
| 311 | "Move point backward to the first available breakpoint and return t. |
| 312 | If no breakpoint is found, return nil." |
| 313 | (and (search-backward " " (line-beginning-position) 1) |
| 314 | (save-excursion |
| 315 | (skip-chars-backward " " (line-beginning-position)) |
| 316 | (null (bolp))) |
| 317 | (progn (forward-char 1) |
| 318 | (if (and fill-nobreak-predicate |
| 319 | (run-hook-with-args-until-success |
| 320 | 'fill-nobreak-predicate)) |
| 321 | (progn (skip-chars-backward " " (line-beginning-position)) |
| 322 | (longlines-find-break-backward)) |
| 323 | t)))) |
| 324 | |
| 325 | (defun longlines-find-break-forward () |
| 326 | "Move point forward to the first available breakpoint and return t. |
| 327 | If no break point is found, return nil." |
| 328 | (and (search-forward " " (line-end-position) 1) |
| 329 | (progn (skip-chars-forward " " (line-end-position)) |
| 330 | (null (eolp))) |
| 331 | (if (and fill-nobreak-predicate |
| 332 | (run-hook-with-args-until-success |
| 333 | 'fill-nobreak-predicate)) |
| 334 | (longlines-find-break-forward) |
| 335 | t))) |
| 336 | |
| 337 | (defun longlines-merge-lines-p () |
| 338 | "Return t if part of the next line can fit onto the current line. |
| 339 | Otherwise, return nil. Text cannot be moved across hard newlines." |
| 340 | (save-excursion |
| 341 | (end-of-line) |
| 342 | (and (null (eobp)) |
| 343 | (null (get-text-property (point) 'hard)) |
| 344 | (let ((space (- fill-column (current-column)))) |
| 345 | (forward-line 1) |
| 346 | (if (eq (char-after) ? ) |
| 347 | t ; We can always merge some spaces |
| 348 | (<= (if (search-forward " " (line-end-position) 1) |
| 349 | (current-column) |
| 350 | (1+ (current-column))) |
| 351 | space)))))) |
| 352 | |
| 353 | (defun longlines-decode-region (&optional beg end) |
| 354 | "Turn all newlines between BEG and END into hard newlines. |
| 355 | If BEG and END are nil, the point and mark are used." |
| 356 | (if (null beg) (setq beg (point))) |
| 357 | (if (null end) (setq end (mark t))) |
| 358 | (save-excursion |
| 359 | (let ((reg-max (max beg end))) |
| 360 | (goto-char (min beg end)) |
| 361 | (while (search-forward "\n" reg-max t) |
| 362 | (set-hard-newline-properties |
| 363 | (match-beginning 0) (match-end 0)))))) |
| 364 | |
| 365 | (defun longlines-decode-buffer () |
| 366 | "Turn all newlines in the buffer into hard newlines." |
| 367 | (longlines-decode-region (point-min) (point-max))) |
| 368 | |
| 369 | (defun longlines-encode-region (beg end &optional buffer) |
| 370 | "Replace each soft newline between BEG and END with exactly one space. |
| 371 | Hard newlines are left intact. The optional argument BUFFER exists for |
| 372 | compatibility with `format-alist', and is ignored." |
| 373 | (save-excursion |
| 374 | (let ((reg-max (max beg end)) |
| 375 | (mod (buffer-modified-p))) |
| 376 | (goto-char (min beg end)) |
| 377 | (while (search-forward "\n" reg-max t) |
| 378 | (unless (get-text-property (match-beginning 0) 'hard) |
| 379 | (replace-match " "))) |
| 380 | (set-buffer-modified-p mod) |
| 381 | end))) |
| 382 | |
| 383 | (defun longlines-encode-string (string) |
| 384 | "Return a copy of STRING with each soft newline replaced by a space. |
| 385 | Hard newlines are left intact." |
| 386 | (let* ((str (copy-sequence string)) |
| 387 | (pos (string-match "\n" str))) |
| 388 | (while pos |
| 389 | (if (null (get-text-property pos 'hard str)) |
| 390 | (aset str pos ? )) |
| 391 | (setq pos (string-match "\n" str (1+ pos)))) |
| 392 | str)) |
| 393 | |
| 394 | ;; Auto wrap |
| 395 | |
| 396 | (defun longlines-auto-wrap (&optional arg) |
| 397 | "Toggle automatic line wrapping. |
| 398 | With optional argument ARG, turn on line wrapping if and only if ARG is positive. |
| 399 | If automatic line wrapping is turned on, wrap the entire buffer." |
| 400 | (interactive "P") |
| 401 | (setq arg (if arg |
| 402 | (> (prefix-numeric-value arg) 0) |
| 403 | (not longlines-auto-wrap))) |
| 404 | (if arg |
| 405 | (progn |
| 406 | (setq longlines-auto-wrap t) |
| 407 | (longlines-wrap-region (point-min) (point-max)) |
| 408 | (message "Auto wrap enabled.")) |
| 409 | (setq longlines-auto-wrap nil) |
| 410 | (message "Auto wrap disabled."))) |
| 411 | |
| 412 | (defun longlines-after-change-function (beg end len) |
| 413 | "Update `longlines-wrap-beg' and `longlines-wrap-end'. |
| 414 | This is called by `after-change-functions' to keep track of the region |
| 415 | that has changed." |
| 416 | (when (and longlines-auto-wrap (not undo-in-progress)) |
| 417 | (setq longlines-wrap-beg |
| 418 | (if longlines-wrap-beg (min longlines-wrap-beg beg) beg)) |
| 419 | (setq longlines-wrap-end |
| 420 | (if longlines-wrap-end (max longlines-wrap-end end) end)))) |
| 421 | |
| 422 | (defun longlines-post-command-function () |
| 423 | "Perform line wrapping on the parts of the buffer that have changed. |
| 424 | This is called by `post-command-hook' after each command." |
| 425 | (when (and longlines-auto-wrap longlines-wrap-beg) |
| 426 | (if (or (eq this-command 'yank) |
| 427 | (eq this-command 'yank-pop)) |
| 428 | (longlines-decode-region (point) (mark t))) |
| 429 | (if longlines-showing |
| 430 | (longlines-show-region longlines-wrap-beg longlines-wrap-end)) |
| 431 | (unless (or (eq this-command 'fill-paragraph) |
| 432 | (eq this-command 'fill-region)) |
| 433 | (longlines-wrap-region longlines-wrap-beg longlines-wrap-end)) |
| 434 | (setq longlines-wrap-beg nil) |
| 435 | (setq longlines-wrap-end nil))) |
| 436 | |
| 437 | (defun longlines-window-change-function () |
| 438 | "Re-wrap the buffer if the window width has changed. |
| 439 | This is called by `window-configuration-change-hook'." |
| 440 | (let ((dw (if (and (integerp longlines-wrap-follows-window-size) |
| 441 | (>= longlines-wrap-follows-window-size 0) |
| 442 | (< longlines-wrap-follows-window-size (window-width))) |
| 443 | longlines-wrap-follows-window-size |
| 444 | 2))) |
| 445 | (when (/= fill-column (- (window-width) dw)) |
| 446 | (setq fill-column (- (window-width) dw)) |
| 447 | (longlines-wrap-region (point-min) (point-max))))) |
| 448 | |
| 449 | ;; Isearch |
| 450 | |
| 451 | (defun longlines-search-function () |
| 452 | (cond |
| 453 | (isearch-word |
| 454 | (if isearch-forward 'word-search-forward 'word-search-backward)) |
| 455 | (isearch-regexp |
| 456 | (if isearch-forward 're-search-forward 're-search-backward)) |
| 457 | (t |
| 458 | (if isearch-forward |
| 459 | 'longlines-search-forward |
| 460 | 'longlines-search-backward)))) |
| 461 | |
| 462 | (defun longlines-search-forward (string &optional bound noerror count) |
| 463 | (let ((search-spaces-regexp "[ \n]+")) |
| 464 | (re-search-forward (regexp-quote string) bound noerror count))) |
| 465 | |
| 466 | (defun longlines-search-backward (string &optional bound noerror count) |
| 467 | (let ((search-spaces-regexp "[ \n]+")) |
| 468 | (re-search-backward (regexp-quote string) bound noerror count))) |
| 469 | |
| 470 | ;; Loading and saving |
| 471 | |
| 472 | (defun longlines-before-revert-hook () |
| 473 | (add-hook 'after-revert-hook 'longlines-after-revert-hook nil t) |
| 474 | (longlines-mode 0)) |
| 475 | |
| 476 | (defun longlines-after-revert-hook () |
| 477 | (remove-hook 'after-revert-hook 'longlines-after-revert-hook t) |
| 478 | (longlines-mode 1)) |
| 479 | |
| 480 | (add-to-list |
| 481 | 'format-alist |
| 482 | (list 'longlines "Automatically wrap long lines." nil nil |
| 483 | 'longlines-encode-region t nil)) |
| 484 | |
| 485 | (provide 'longlines) |
| 486 | |
| 487 | ;; arch-tag: 3489d225-5506-47b9-8659-d8807b77c624 |
| 488 | ;;; longlines.el ends here |