indent-commands.sl 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227
  1. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  2. %
  3. % Indent-commands.SL - NMODE indenting commands
  4. %
  5. % Author: Alan Snyder
  6. % Hewlett-Packard/CRC
  7. % Date: 24 August 1982
  8. % Revised: 18 February 1983
  9. %
  10. % 18-Feb-83 Alan Snyder
  11. % Removed use of "obsolete" #\ names.
  12. % 11-Nov-82 Alan Snyder
  13. % DELETE-INDENTATION-COMMAND (M-^) now obeys command argument.
  14. % INDENT-CURRENT-LINE now avoids modifying buffer if indentation unchanged.
  15. % Added INDENT-REGION stuff.
  16. % General clean-up.
  17. %
  18. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  19. (CompileTime (load objects fast-int fast-strings extended-char common))
  20. (load stringx)
  21. (fluid '(nmode-command-argument
  22. nmode-command-argument-given
  23. nmode-command-number-given
  24. ))
  25. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  26. % Indenting Commands
  27. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  28. (de indent-new-line-command ()
  29. (let ((func (dispatch-table-lookup (x-char CR))))
  30. (if func (apply func NIL)))
  31. (setf nmode-command-argument 1)
  32. (setf nmode-command-argument-given NIL)
  33. (setf nmode-command-number-given NIL)
  34. (let ((func (dispatch-table-lookup (x-char TAB))))
  35. (if func (apply func NIL))))
  36. (de tab-to-tab-stop-command ()
  37. (for (from i 1 nmode-command-argument)
  38. (do (insert-character #\TAB))
  39. ))
  40. (de delete-horizontal-space-command ()
  41. (while (and (not (at-line-end?)) (char-blank? (next-character)))
  42. (delete-next-character)
  43. )
  44. (while (and (not (at-line-start?)) (char-blank? (previous-character)))
  45. (delete-previous-character)
  46. )
  47. )
  48. (de delete-blank-lines-command ()
  49. (cond ((current-line-blank?)
  50. % We are on a blank line.
  51. % Replace multiple blank lines with one.
  52. % First, search backwards for the first blank line
  53. % and save its index.
  54. (while (not (current-line-is-first?))
  55. (move-to-previous-line)
  56. (cond ((not (current-line-blank?))
  57. (move-to-next-line)
  58. (exit))
  59. ))
  60. (delete-following-blank-lines)
  61. )
  62. (t
  63. % We are on a non-blank line. Delete any blank lines
  64. % that follow this one.
  65. (delete-following-blank-lines)
  66. )
  67. ))
  68. (de back-to-indentation-command ()
  69. (move-to-start-of-line)
  70. (while (char-blank? (next-character))
  71. (move-forward)
  72. ))
  73. (de delete-indentation-command ()
  74. (if nmode-command-argument-given (move-to-next-line))
  75. (current-line-strip-indent)
  76. (move-to-start-of-line)
  77. (when (not (current-line-is-first?))
  78. (delete-previous-character)
  79. (if (and (not (at-line-start?))
  80. (not (= (previous-character) #/( ))
  81. (not (= (next-character) #/) ))
  82. )
  83. (insert-character #\SPACE)
  84. )))
  85. (de split-line-command ()
  86. (while (char-blank? (next-character))
  87. (move-forward))
  88. (if (> nmode-command-argument 0)
  89. (let ((pos (current-display-column)))
  90. (for (from i 1 nmode-command-argument)
  91. (do (insert-eol)))
  92. (indent-current-line pos)
  93. )))
  94. (de indent-region-command ()
  95. (if nmode-command-argument-given
  96. (indent-region #'indent-to-argument)
  97. ))
  98. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  99. % Basic Indenting Primitives
  100. %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
  101. (de char-blank? (ch)
  102. (or (= ch #\SPACE) (= ch #\TAB)))
  103. (de current-line-indent ()
  104. % Return the indentation of the current line, in terms of spaces.
  105. (let ((line (current-line)))
  106. (for* (from i 0 (string-upper-bound line))
  107. (with ch)
  108. (while (char-blank? (setf ch (string-fetch line i))))
  109. (sum (if (= ch #\TAB) 8 1))
  110. )))
  111. (de current-line-strip-indent ()
  112. % Strip all leading blanks and tabs from the current line.
  113. (let ((line (current-line)))
  114. (for* (from i 0 (string-upper-bound line))
  115. (while (char-blank? (string-fetch line i)))
  116. (finally
  117. (when (> i 0)
  118. (set-char-pos (- (current-char-pos) i))
  119. (current-line-replace (string-rest line i))
  120. ))
  121. )))
  122. (de strip-previous-blanks ()
  123. % Strip all blanks and tabs before point.
  124. (while (and (not (at-buffer-start?))
  125. (char-blank? (previous-character)))
  126. (delete-previous-character)
  127. ))
  128. (de indent-current-line (n)
  129. % Adjust the current line to have the specified indentation.
  130. (when (and (~= n (current-line-indent)) (>= n 0))
  131. (current-line-strip-indent)
  132. (let ((n-spaces (remainder n 8))
  133. (n-tabs (quotient n 8))
  134. (line (current-line))
  135. (cp (current-char-pos))
  136. )
  137. (for (from i 1 n-spaces)
  138. (do (setf line (string-concat #.(string #\SPACE) line))
  139. (setf cp (+ 1 cp))))
  140. (for (from i 1 n-tabs)
  141. (do (setf line (string-concat #.(string #\TAB) line))
  142. (setf cp (+ 1 cp))))
  143. (current-line-replace line)
  144. (set-char-pos cp)
  145. )))
  146. (de delete-following-blank-lines ()
  147. % Delete any blank lines that immediately follow the current one.
  148. (if (not (current-line-is-last?))
  149. (let ((old-pos (buffer-get-position))
  150. first-pos
  151. )
  152. % Advance past the current line until the next nonblank line.
  153. (move-to-next-line)
  154. (setf first-pos (buffer-get-position))
  155. (while (and (not (at-buffer-end?)) (current-line-blank?))
  156. (move-to-next-line))
  157. (extract-region T first-pos (buffer-get-position))
  158. (buffer-set-position old-pos)
  159. )))
  160. (de indent-to-argument ()
  161. % Indent the current line to the position specified by nmode-command-argument.
  162. (indent-current-line nmode-command-argument)
  163. )
  164. (de indent-region (indenting-function)
  165. % Indent the lines whose first characters are between point and mark.
  166. % Attempt to adjust point and mark appropriately should their lines
  167. % be re-indented. The function INDENTING-FUNCTION is called to indent
  168. % the current line.
  169. (let* ((point (buffer-get-position))
  170. (mark (current-mark))
  171. (bp1 point)
  172. (bp2 mark)
  173. )
  174. (if (< 0 (buffer-position-compare bp1 bp2))
  175. (psetf bp1 mark bp2 point))
  176. (let ((first-line (buffer-position-line bp1))
  177. (last-line (buffer-position-line bp2))
  178. )
  179. (if (> (buffer-position-column bp1) 0)
  180. (setf first-line (+ first-line 1)))
  181. (for (from i first-line last-line)
  182. (do
  183. (set-line-pos i)
  184. (cond
  185. ((= i (buffer-position-line point))
  186. (set-char-pos (buffer-position-column point)))
  187. ((= i (buffer-position-line mark))
  188. (set-char-pos (buffer-position-column mark)))
  189. )
  190. (apply indenting-function ())
  191. (cond
  192. ((= i (buffer-position-line point))
  193. (setf point (buffer-position-create i (current-char-pos))))
  194. ((= i (buffer-position-line mark))
  195. (setf mark (buffer-position-create i (current-char-pos))))
  196. ))))
  197. (previous-mark) % pop off old mark
  198. (set-mark mark) % push (possibly adjusted) mark
  199. (buffer-set-position point)
  200. ))