home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / me34src.zip / me3 / mutt / package / picture.mut < prev    next >
Lisp/Scheme  |  1995-01-14  |  23KB  |  716 lines

  1. ;; "Picture mode" -- editing using quarter-plane screen model.
  2. ;; Copyright (C) 1985 Free Software Foundation, Inc.
  3. ;; Principal author K. Shane Hartman
  4. ;; Converted to Mutt 6/88 C Durland
  5. ;; Made changes for ME3 12/92 C Durland
  6.  
  7. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  8. ;;;;;;;;;;;;;;;;;;;; Utilities ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10.  
  11.   ;; Eliminate whitespace at ends of lines.
  12. (defun remove-trailing-whitespace
  13. {
  14.   (save-point
  15.     {{
  16.       (beginning-of-buffer)
  17.       (re-search-replace "[ ^I]+$" "")
  18.     }})
  19.   (msg "Removed trailing whitespace")
  20. })
  21.  
  22.     ; move to the next tab stop in the tabs list
  23. (defun tab-to-tab-stop (int num-tabs) (array byte tabs 1)
  24. {
  25.   (int i col)
  26.  
  27.   (col (current-column))
  28.   (for (i 0) (and (< i num-tabs)(>= col (tabs i))) (+= i 1) ())
  29.   (if (< i num-tabs) { (to-col (i (tabs i))) i } col)
  30. })
  31.  
  32. (include me.mh)
  33.  
  34. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  35. ;;;;;;;;;;;;;;;; Picture Movement Commands ;;;;;;;;;;;;;;;;;;;;;;;;;
  36. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  37.  
  38.   ;; Move to column in current line.
  39.   ;; Differs from move-to-column in that it creates or modifies whitespace
  40.   ;;   if necessary to attain exactly the specified column.
  41. (defun move-to-column-force (int column) HIDDEN
  42. {
  43.   (current-column column) (to-col column)
  44. })
  45.  
  46.   ;; Position point after last non-blank character on current line.
  47.   ;; With ARG not nil, move forward ARG - 1 lines first.
  48.   ;; If scan reaches end of buffer, stop there without error.
  49. (defun picture-end-of-line
  50. {
  51.   (if (arg-flag) (forward-line (- (arg-prefix) 1)))
  52.   (end-of-line)
  53.   (if (previous-character)
  54.   {
  55.     (while (is-space) (previous-character))
  56.     (next-character)
  57.   })
  58. })
  59.  
  60.   ;; Move cursor right, making whitespace if necessary.
  61.   ;; With argument, move that many columns.
  62. (defun picture-forward-column
  63. {
  64.   (move-to-column-force (+ (current-column) (arg-prefix)))
  65. })
  66.  
  67.   ;; Move cursor left, making whitespace if necessary.
  68.   ;; With argument, move that many columns.
  69. (defun picture-backward-column
  70. {
  71.   (move-to-column-force (- (current-column) (arg-prefix)))
  72. })
  73.  
  74.   ;; Move vertically down, making whitespace if necessary.
  75.   ;; With argument, move that many lines.
  76. (defun picture-move-down
  77. {
  78.   (int col)
  79.  
  80.   (col (current-column))
  81.   (picture-newline (arg-prefix))
  82.   (move-to-column-force col)
  83. })
  84.  
  85.   ;; Move vertically up, making whitespace if necessary.
  86.   ;; With argument, move that many lines.
  87. (defun picture-move-up
  88. {
  89.   (int col n)
  90.  
  91.   (n (arg-prefix))
  92.   (col (current-column))
  93.  
  94.   (while (>= (-= n 1) 0)
  95.     (if (not (forward-line -1))    ; at top of buffer
  96.     { (beginning-of-buffer)(open-line) })
  97.   )
  98.   (move-to-column-force col)
  99. })
  100.  
  101.   ;; Amount to move vertically after text character in Picture mode.
  102. (int picture-vertical-step)
  103.  
  104.   ;; Amount to move horizontally after text character in Picture mode.
  105. (int picture-horizontal-step)
  106.  
  107.   ;; Set VERTICAL and HORIZONTAL increments for movement in Picture mode.
  108.   ;; The mode line is updated to reflect the current direction.
  109. (defun picture-set-motion (int vert horiz) HIDDEN
  110. {
  111.   (picture-vertical-step vert)
  112.   (picture-horizontal-step horiz)
  113. ;  (setq mode-name
  114. ;    (format "Picture:%s"
  115. ;        (car (nthcdr (+ 1 (% horiz 2) (* 3 (1+ (% vert 2))))
  116. ;                 '(nw up ne left none right sw down se)))))
  117.   (major-mode
  118.     (concat "Picture:"
  119.       (switch (+ 1 horiz (* 3 (+ 1 vert)))
  120.     0 "NW"
  121.     1 "up"
  122.     2 "NE"
  123.     3 "left"
  124.     4 "none"
  125.     5 "right"
  126.     6 "SW"
  127.     7 "down"
  128.     8 "SE"
  129.       )))
  130. })
  131.  
  132.   ;; Move right after self-inserting character in Picture mode.
  133. (defun picture-movement-right { (picture-set-motion 0 1) })
  134.  
  135.   ;; Move left after self-inserting character in Picture mode.
  136. (defun picture-movement-left { (picture-set-motion 0 -1) })
  137.  
  138.   ;; Move up after self-inserting character in Picture mode.
  139. (defun picture-movement-up { (picture-set-motion -1 0) })
  140.  
  141.   ;; Move down after self-inserting character in Picture mode.
  142. (defun picture-movement-down { (picture-set-motion 1 0) })
  143.  
  144.   ;; Move up and left after self-inserting character in Picture mode.
  145. (defun picture-movement-nw { (picture-set-motion -1 -1) })
  146.  
  147.   ;; Move up and right after self-inserting character in Picture mode.
  148. (defun picture-movement-ne { (picture-set-motion -1 1) })
  149.  
  150.   ;; Move down and left after self-inserting character in Picture mode.
  151. (defun picture-movement-sw { (picture-set-motion 1 -1) })
  152.  
  153.   ;; Move down and right after self-inserting character in Picture mode.
  154. (defun picture-movement-se { (picture-set-motion 1 1) })
  155.  
  156.   ;; Move in direction of picture-vertical-step and picture-horizontal-step.
  157.   ;; With ARG do it that many times.
  158.   ;; Useful for delineating rectangles in conjunction with diagonal
  159.   ;;   picture motion.
  160.   ;; Do apropos picture-movement  to see commands which control motion.
  161. (defun picture-move
  162. {
  163.   (int col)
  164.  
  165.   (col (+ (current-column) (* picture-horizontal-step (arg-prefix))))
  166.   (cond
  167.     (< picture-vertical-step 0) (picture-move-up)
  168.     (> picture-vertical-step 0) (picture-move-down)
  169.   )
  170.   (move-to-column-force col)
  171. })
  172.  
  173.   ;; Move point in direction opposite of current picture motion in Picture mode.
  174.   ;; With ARG do it that many times.
  175.   ;; Useful for delineating rectangles in conjunction with diagonal
  176.   ;;   picture motion.
  177.   ;; Do apropos picture-movement  to see commands which control motion.
  178. (defun picture-move-reverse
  179. {
  180.   (*= picture-vertical-step -1)(*= picture-horizontal-step -1)
  181.   (picture-move)
  182.   (*= picture-vertical-step -1)(*= picture-horizontal-step -1)
  183. })
  184.  
  185. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  186. ;;;;;;;;;; Picture insertion and deletion ;;;;;;;;;;;;;;;;;;;;;;;;;;
  187. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  188.  
  189.   ;; Insert character in place of character previously at the cursor.
  190.   ;; The cursor then moves in the direction previously specified
  191.   ;;   with the picture-movement- commands.
  192.   ;; Do apropos  picture-movement  to see those commands.
  193. (defun picture-insert (string c)(int n) HIDDEN
  194. {
  195.   (int i)
  196.  
  197.   (i n)
  198.   (while (> i 0)
  199.   {
  200.     (-= i 1)
  201.     (move-to-column-force (+ 1 (current-column)))    ; break up any tabs
  202.     (delete-previous-character)
  203.     (insert-text c)
  204.     (previous-character)
  205.     (arg-prefix 1)(picture-move)
  206.   })
  207. })
  208.  
  209. (defun picture-self-insert
  210. {
  211.   (picture-insert (convert-to CHARACTER (key-pressed)) (arg-prefix))
  212. })
  213.  
  214.   ;; Clear out ARG columns after point without moving.
  215. (defun picture-clear-column
  216. {
  217.   (int col)
  218.  
  219.   (set-mark)
  220.   (col (current-column (+ (current-column) (arg-prefix))))
  221.   (delete-region)(to-col col)
  222.   (swap-marks)
  223. })
  224.  
  225.   ;; Clear out ARG columns before point, moving back over them.
  226. (defun picture-backward-clear-column
  227. {
  228.   (if (== 1 (current-column)) (done))    ; no op if at begining of line
  229.   (move-to-column-force (- (current-column) (arg-prefix)))
  230.   (picture-clear-column)
  231. })
  232.  
  233.   ;; Clear out rest of line; if at end of line, advance to next line.
  234.   ;; Cleared-out line text goes into the kill ring, as do
  235.   ;;   newlines that are advanced over.
  236.   ;; With argument, clear out (and save in kill ring) that many lines.
  237. (defun picture-clear-line
  238. {
  239.   (int n)
  240.  
  241.   (if (arg-flag)
  242.     {
  243.       (arg-prefix (n (arg-prefix))) (cut-line)
  244.       (arg-prefix n)(newline)
  245.     }
  246.     {
  247.       (if (looking-at '.+$')(cut-line))
  248.         ; tack a newline to end of cut buffer
  249.       (append-to-bag CUT-BUFFER APPEND-TEXT "^J")
  250.       (forward-line 1)
  251.     }
  252.   )
  253. })
  254.  
  255.   ;; Move to the beginning of the following line.
  256.   ;; With argument, moves that many lines (up, if negative argument).
  257.   ;; Always moves to the beginning of a line.
  258. (defun picture-newline
  259. {
  260.   (int n)
  261.  
  262.   (if (< (n (arg-prefix)) 0)    ; negative arg => move up
  263.     (forward-line n)
  264.     (while (>= (-= n 1) 0) (if (not (forward-line 1)) (newline)))
  265.   )
  266. })
  267.  
  268.   ;; Insert an empty line after the current line.
  269.   ;; With positive argument insert that many lines.
  270. (defun picture-open-line
  271. {
  272.   (save-point {{ (end-of-line)(open-line) }})
  273. })
  274.  
  275.   ;; Insert a duplicate of the current line, below it.
  276. (defun picture-duplicate-line
  277. {
  278.   (int col)
  279.  
  280.   (col (current-column))
  281.   (beginning-of-line)(clear-bag CUT-BUFFER)
  282.   (arg-prefix 1)(cut-line)
  283.   (yank)(yank)
  284.   (forward-line -2)(current-column col)
  285. })
  286.  
  287. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  288. ;;;;;;;;;;;;;;;;;; Picture Tabs ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  289. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  290.  
  291.   ;; A character set which controls behavior of commands
  292.   ;;  (picture-set-tab-stops) and (picture-tab-search).  It is NOT a
  293.   ;;  regular expression, any regexp special characters will be quoted.
  294.   ;; It defines a set of "interesting characters" to look for when setting
  295.   ;; (or searching for) tab stops, initially "!-~" (all printing characters).
  296.   ;; For example, suppose that you are editing a table which is formatted thus:
  297.   ;;    | foo        | bar + baz | 23  *
  298.   ;;    | bubbles    | and + etc | 97  *
  299.   ;;   and that picture-tab-chars is "|+*".  Then invoking
  300.   ;;   [picture-set-tab-stops] on either of the previous lines would result
  301.   ;;   in the following tab stops:
  302.   ;;            :     :     :     :
  303.   ;; Another example - "A-Za-z0-9" would produce the tab stops
  304.   ;;      :          :    :     :
  305.  
  306.   ;; Note that if you want the character `-' to be in the set, it must be
  307.   ;;   included in a range or else appear in a context where it cannot be
  308.   ;;   taken for indicating a range (e.g. "-A-Z" declares the set to be the
  309.   ;;   letters `A' through `Z' and the character `-').  If you want the
  310.   ;;   character `\' in the set it must be preceded by itself: "\\".
  311.  
  312.   ;; The command (picture-tab-search) is defined to move beneath (or to) a
  313.   ;;   character belonging to this set independent of the tab stops list.
  314.  
  315. (const default-pic-tab-chars '-!~|')
  316. (string picture-tab-chars)
  317. (array byte pic-tabs 70)
  318. (int num-pic-tabs)
  319.  
  320.   ;; Set value of  tab-stop-list  according to context of this line.
  321.   ;; This controls the behavior of (picture-tab).  A tab stop
  322.   ;;   is set at every column occupied by an "interesting character" that is
  323.   ;;   preceded by whitespace.  Interesting characters are defined by the
  324.   ;;   variable  picture-tab-chars,  see its documentation for an example
  325.   ;;   of usage.
  326.   ;; With ARG, just (re)set  tab-stop-list  to its default value.
  327.   ;; The tab stops computed are displayed in the minibuffer with `:' at
  328.   ;; each stop.
  329. (defun sleeze-ball (array byte str 1) HIDDEN
  330. {
  331.   (int i)
  332.  
  333.   (for (i 0) (< i num-pic-tabs)(+= i 1) (str (- (pic-tabs i) 1) 0x3A)) ; ":"
  334.   str
  335. })
  336. (defun picture-set-tab-stops
  337. {
  338.   (int i)
  339.   (string regexp)
  340.  
  341. ;(if arg (setq tabs (default-value 'tab-stop-list))
  342.  
  343.   (set-mark)
  344.   (regexp (concat '\ +[' picture-tab-chars "]"))
  345.   (beginning-of-line)
  346.   (for (num-pic-tabs 0)
  347.        (and (re-search-forward regexp)
  348.         (== DOT-ON-SAME-LINE-AS-MARK (compare-marks)))
  349.        (+= num-pic-tabs 1)
  350.      (pic-tabs num-pic-tabs (- (current-column) 1))
  351. ;; ??? (skip-chars-forward " \t")
  352.   )
  353.   (swap-marks)
  354.   (if (== 0 num-pic-tabs)
  355.   {
  356.     (msg "No characters in set \"" picture-tab-chars "\" on this line.")
  357.     (done)
  358.   })
  359.   (msg (sleeze-ball "                                                                             "))
  360. })
  361.  
  362.   ;; Move to column beneath next interesting char in previous line.
  363.   ;;   The cursor stays in the current line.
  364.   ;; With ARG move to column occupied by next interesting character in this
  365.   ;;   line.  The character must be preceded by whitespace.
  366.   ;; "Interesting characters" are defined by variable  picture-tab-chars.
  367.   ;; If no such character is found, move to beginning of line.
  368. (defun picture-tab-search
  369. {
  370.   (int i)
  371.   (string regexp)
  372.  
  373.   (set-mark)
  374.   (regexp (concat '\ +[' picture-tab-chars "]"))
  375.   (if (arg-flag)
  376.   {
  377.     (if (and (re-search-forward regexp)
  378.          (== DOT-ON-SAME-LINE-AS-MARK (compare-marks)))
  379.     { (previous-character)(done) })
  380.   }
  381.   {
  382.     (i (current-column))
  383.     (while TRUE        ; look for non blank line
  384.     {
  385.       (if (forward-line -1)
  386.       {
  387.     (if (looking-at '^\ *$') (continue)    ; blank line
  388.       (break)                ; non blank line
  389.     )
  390.       })
  391.       (goto done)    ; hit top of buffer
  392.     })
  393.     (current-column i)
  394.     (if (and (re-search-forward regexp)
  395.          (== DOT-ABOVE-MARK (compare-marks)))
  396.     {
  397.       (i (current-column))
  398.       (swap-marks)
  399.       (move-to-column-force (- i 1))
  400.       (done)
  401.     })
  402.   })
  403. (label done)
  404.   (swap-marks)(beginning-of-line)
  405. })
  406.  
  407.   ;; Tab transparently (move) to next tab stop.
  408.   ;; With ARG overwrite the traversed text with spaces.
  409.   ;; The tab stop list can be changed by (picture-set-tab-stops) and
  410.   ;;   (edit-tab-stops).
  411.   ;; See also documentation for variable  picture-tab-chars.
  412. (defun picture-tab
  413. {
  414.   (int target)
  415.  
  416.   (set-mark)
  417.   (target (tab-to-tab-stop num-pic-tabs pic-tabs))
  418.   (delete-region)
  419.   (move-to-column-force target)
  420.   (if (arg-flag) { (delete-region)(to-col target) })
  421. })
  422.  
  423.  
  424. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  425. ;;;;;;;;;;;;;;;;;; Picture Rectangles ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  426. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  427.  
  428.   ;; Rectangle killed or copied by (picture-clear-rectangle) in Picture mode.
  429.   ;; The contents can be retrieved by (picture-yank-rectangle)
  430. (const picture-killed-rectangle CUT-BUFFER)
  431.  
  432.  ;; Clear and save rectangle delineated by point and mark.
  433.  ;; The rectangle is saved for yanking by picture-yank-rectangle and
  434.  ;;   replaced with whitespace.  The previously saved rectangle, if any, is
  435.  ;;   lost.
  436.  ;; With prefix argument, the rectangle is actually killed, shifting
  437.  ;;   remaining text.
  438. (defun picture-clear-rectangle
  439. {
  440.   (append-to-bag picture-killed-rectangle APPEND-RECTANGLE)
  441.   (erase-rectangle (arg-flag))
  442. })
  443.  
  444.   ;; Clear rectangle delineated by point and mark into REGISTER.
  445.   ;; The rectangle is saved in REGISTER and replaced with whitespace.
  446.   ;; With prefix argument, the rectangle is actually killed, shifting
  447.   ;;   remaining text.
  448. (defun picture-clear-rectangle-to-register
  449. {
  450.   (bool clear)
  451.  
  452.   (clear (arg-flag))(arg-flag FALSE)
  453.  
  454.   (copy-region-to-rectangle)
  455.   (erase-rectangle clear)
  456. })
  457.  
  458.   ;; Overlay RECTANGLE with upper left corner at point.
  459.   ;; Optional argument INSERTP, if non-nil causes RECTANGLE to be inserted.
  460.   ;; Leaves the region surrounding the rectangle.
  461. (defun picture-insert-rectangle (int rectangle) (bool insert) HIDDEN
  462. {
  463.   (byte type)(small-int width height)(int size)    ;; struct BagInfo
  464.   (int col)
  465.  
  466.   (bag-stats rectangle (loc type))
  467.   (if (!= type 1) { (msg "Not a rectangle.") (done) })
  468.   (if (not insert)
  469.   {
  470.     (set-mark)(col (current-column))    ; set mark at upper left column
  471.     ; put dot as close as possible to lower right column
  472.     (forward-line (- height 1))(move-to-column-force (+ col width))
  473.     (erase-rectangle TRUE)
  474.   })
  475.   (insert-bag rectangle)
  476. })
  477.  
  478.   ;; Overlay rectangle saved by picture-clear-rectangle.
  479.   ;; The rectangle is positioned with upper left corner at point,
  480.   ;;   overwriting existing text.  With prefix argument, the rectangle is
  481.   ;;   inserted instead, shifting existing text.  Leaves mark at one corner
  482.   ;;   of rectangle and point at the other (diagonally opposed) corner.
  483. (defun picture-yank-rectangle
  484. {
  485.   (picture-insert-rectangle picture-killed-rectangle (arg-flag))
  486. })
  487.  
  488.   ;; Overlay rectangle saved in REGISTER.
  489.   ;; The rectangle is positioned with upper left corner at point,
  490.   ;;   overwriting existing text.
  491.   ;; With prefix argument, the rectangle is inserted instead, shifting
  492.   ;;   existing text.
  493.   ;; Leaves mark at one corner of rectangle and point at the other
  494.   ;;  (diagonally opposed) corner.
  495. (defun picture-yank-rectangle-from-register
  496. {
  497. (msg "Not currently implemented.  Use picture-clear-rectangle.")
  498. (done)
  499. ;  (picture-insert-rectangle bag-id (arg-flag))
  500. })
  501.  
  502. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  503. ;;;;;;;;;;;;;;;; Misc goodies ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  504. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  505.  
  506. (const
  507.   UPPER-LEFT-CORNER "." UPPER-EDGE "-" UPPER-RIGHT-CORNER "."
  508.   LOWER-LEFT-CORNER "`" LOWER-EDGE "-" LOWER-RIGHT-CORNER "'"
  509.   LEFT-SIDE "|" RIGHT-SIDE "|"
  510. )
  511.  
  512.   ;; Draw a box around the region-rectangle
  513. (defun picture-box
  514. {
  515.   (byte type)(small-int ulcol width height)(int size)    ;; struct RegionInfo
  516.  
  517.   (region-stats (loc type) THE-DOT THE-MARK TRUE)
  518.  
  519.   (move-to-column-force ulcol)    ;; move dot to upper left corner of box
  520.  
  521.   (if (or (< (-= width 1) 1)(< (-= height 2) 1))
  522.      { (msg "Box too small")(done) })
  523.     ;; draw top of box
  524.   (picture-movement-right)
  525.   (picture-insert UPPER-LEFT-CORNER 1)(picture-insert UPPER-EDGE width)
  526.     ;; draw right side of box
  527.   (picture-movement-down)
  528.   (picture-insert UPPER-RIGHT-CORNER 1)(picture-insert RIGHT-SIDE height)
  529.     ;; draw bottom of box
  530.   (picture-movement-left)
  531.   (picture-insert LOWER-RIGHT-CORNER 1)(picture-insert LOWER-EDGE width)
  532.     ;; draw left side of box
  533.   (picture-movement-up)
  534.   (picture-insert LOWER-LEFT-CORNER 1)(picture-insert LEFT-SIDE height)
  535.     ;; finished
  536.   (picture-movement-right)
  537. })
  538.  
  539. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  540. ;;;;;;;;;;; Picture Keymap, entry and exit points ;;;;;;;;;;;;;;;;;;
  541. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  542.  
  543. (int picture-mode-keymap)
  544.  
  545. (defun MAIN
  546. {
  547.   (int i)
  548.   (string str pkey)
  549.  
  550.   (picture-mode-keymap (create-keymap))
  551.  
  552.   (for (i 0x20) (< i 0x7F) (+= i 1)
  553.     (bind-key picture-mode-keymap
  554.     "picture-self-insert" (convert-to CHARACTER i)))
  555.  
  556.   (pkey (prefix-key 2))
  557.   (prefix-key 2 "C-C")
  558.  
  559.   (bind-key picture-mode-keymap
  560.     "picture-forward-column"        "C-f"
  561.     "picture-backward-column"        "C-b"
  562.     "picture-clear-column"            "C-d"
  563.     "delete-character"            "C-cC-d"
  564.     "picture-backward-clear-column"     "C-H"
  565.     "picture-clear-line"            "C-k"
  566.     "picture-open-line"            "C-o"
  567.     "picture-newline"            "C-m"
  568.     "picture-move-down"            "C-n"
  569.     "picture-move-up"            "C-p"
  570.     "picture-end-of-line"            "C-e"
  571.     "picture-duplicate-line"        "C-j"
  572.  
  573.     "picture-tab"                "C-I"
  574.     "picture-tab-search"            "M-C-I"
  575.     "picture-set-tab-stops"            "C-cC-i"
  576.  
  577.     "picture-mode-exit"            "C-cC-c"
  578.     "picture-move"                "C-cC-f"
  579.     "picture-move-reverse"            "C-cC-b"
  580.  
  581.     "picture-movement-left"            "C-c<"
  582.     "picture-movement-right"        "C-c>"
  583.     "picture-movement-up"            'C-c^'
  584.     "picture-movement-down"            "C-c."
  585.     "picture-movement-nw"            "C-c`"
  586.     "picture-movement-ne"            "C-c'"
  587.     "picture-movement-sw"            "C-c/"
  588.     "picture-movement-se"            "C-c\\"
  589.  
  590.     "picture-clear-rectangle"        "C-cC-k"
  591.     "picture-clear-rectangle-to-register"    "C-cC-w"
  592.     "picture-yank-rectangle"        "C-cC-y"
  593.     "picture-yank-rectangle-from-register"    "C-cC-x")
  594.  
  595.   (prefix-key 2 pkey)
  596. })
  597.  
  598.   ;; Switch to Picture mode, in which a quarter-plane screen model is used.
  599.   ;; Printing characters replace instead of inserting themselves with motion
  600.   ;;   afterwards settable by these commands:
  601.   ;;   C-c <    Move left after insertion.
  602.   ;;   C-c >    Move right after insertion.
  603.   ;;   C-c ^    Move up after insertion.
  604.   ;;   C-c .    Move down after insertion.
  605.   ;;   C-c `    Move northwest (nw) after insertion.
  606.   ;;   C-c '    Move northeast (ne) after insertion.
  607.   ;;   C-c /    Move southwest (sw) after insertion.
  608.   ;;   C-c \    Move southeast (se) after insertion.
  609.   ;; The current direction is displayed in the mode line.  The initial
  610.   ;;   direction is right.  Whitespace is inserted and tabs are changed to
  611.   ;;   spaces when required by movement.  You can move around in the buffer
  612.   ;;   with these commands:
  613.   ;;   C-p    Move vertically to SAME column in previous line.
  614.   ;;   C-n    Move vertically to SAME column in next line.
  615.   ;;   C-e    Move to column following last non-whitespace character.
  616.   ;;   C-f    Move right inserting spaces if required.
  617.   ;;   C-b    Move left changing tabs to spaces if required.
  618.   ;;   C-c C-f    Move in direction of current picture motion.
  619.   ;;   C-c C-b    Move in opposite direction of current picture motion.
  620.   ;;   Return    Move to beginning of next line.
  621.   ;; You can edit tabular text with these commands:
  622.   ;;   M-Tab    Move to column beneath (or at) next interesting character.
  623.   ;;        `Indents' relative to a previous line.
  624.   ;;   Tab    Move to next stop in tab stop list.
  625.   ;;   C-c Tab    Set tab stops according to context of this line.
  626.   ;;         With ARG resets tab stops to default (global) value.
  627.   ;;         See also documentation of variable    picture-tab-chars
  628.   ;;         which defines "interesting character".  You can manually
  629.   ;;         change the tab stop list with command [edit-tab-stops].
  630.   ;; You can manipulate text with these commands:
  631.   ;;   C-d      Clear (replace) ARG columns after point without moving.
  632.   ;;   C-c C-d    Delete char at point - the command normally assigned to C-d.
  633.   ;;   Delete    Clear (replace) ARG columns before point, moving back over them.
  634.   ;;   C-k    Clear ARG lines, advancing over them.     The cleared
  635.   ;;         text is saved in the kill ring.
  636.   ;;   C-o    Open blank line(s) beneath current line.
  637.   ;; You can manipulate rectangles with these commands:
  638.   ;;   C-c C-k    Clear (or kill) a rectangle and save it.
  639.   ;;   C-c C-w    Like C-c C-k except rectangle is saved in named register.
  640.   ;;   C-c C-y    Overlay (or insert) currently saved rectangle at point.
  641.   ;;   C-c C-x    Like C-c C-y except rectangle is taken from named register.
  642.   ;; You can return to the previous mode with:
  643.   ;;   C-c C-c    Which also strips trailing whitespace from every line.
  644.   ;;         Stripping is suppressed by supplying an argument.
  645.  
  646.   ;; Note that Picture mode commands will work outside of Picture mode, but
  647.   ;; they are not defaultly assigned to keys.
  648. (defun edit-picture
  649. {
  650.   (list context)
  651.   (string the-mode)
  652.  
  653.   (if (== "Picture" (extract-elements (major-mode) 0 7))
  654.   {
  655.     (msg "You are already editing a Picture.")
  656.     (done)
  657.   })
  658.  
  659.   (create-buffer-var LIST "pic-stuff")
  660.  
  661.   (insert-object context 10000 (the-mode (major-mode)))
  662.   (insert-object context 10000 (minor-mode))
  663.   (insert-object context 10000 (install-keymap LOCAL-KEYMAP))
  664.   (insert-object context 10000 (prefix-key 2))
  665.   (insert-object context 10000 (word-wrap))
  666.   (buffer-var "pic-stuff" context)
  667.  
  668.   (word-wrap 0)
  669.  
  670.   (picture-set-motion 0 1)
  671.   (picture-tab-chars default-pic-tab-chars)
  672.   (num-pic-tabs 0)
  673.  
  674.   (prefix-key 2 "C-C")
  675.  
  676.   (install-keymap picture-mode-keymap LOCAL-KEYMAP)
  677.  
  678.   (if (pgm-exists "edit-picture-hook") (floc "edit-picture-hook"()))
  679.  
  680.   (msg "Type C-cC-c"    ;;!!! gack - need (list-keys "picture-mode-exit")
  681.     " in this buffer to "
  682.     (if (== "" the-mode)
  683.       "exit picture mode."
  684.       (concat "return to " the-mode " mode.")))
  685. })
  686.  
  687.   ;; Undo edit-picture and return to previous major mode.
  688.   ;; With no argument strips whitespace from end of every line in Picture
  689.   ;;   buffer otherwise just return to previous mode.
  690. (defun picture-mode-exit
  691. {
  692.   (int kid)
  693.   (list context)
  694.  
  695.   (if (!= "Picture" (extract-elements (major-mode) 0 7))
  696.   {
  697.     (msg "You aren't editing a Picture.")
  698.     (done)
  699.   })
  700.  
  701.   (if (not (arg-flag)) (remove-trailing-whitespace))
  702.  
  703.   (context (buffer-var "pic-stuff"))
  704.  
  705.   (major-mode        (extract-element context 0))
  706.   (minor-mode        (extract-element context 1))
  707. ;  (install-keymap    (extract-element context 2)  LOCAL-KEYMAP)
  708.   (prefix-key 2        (extract-element context 3))
  709.   (word-wrap        (extract-element context 4))
  710.  
  711. (kid            (extract-element context 2))
  712. (install-keymap (if (!= -1 (install-keymap kid)) kid NULL-KEYMAP) LOCAL-KEYMAP)
  713.  
  714.   (msg "Picture done")
  715. })
  716.