Mercurial > hg > xemacs-beta
annotate lisp/rect.el @ 5559:f3ab0c29c246
Use a better, more portable approach to the shift-F11 problem.
src/ChangeLog addition:
2011-08-28 Aidan Kehoe <kehoea@parhasard.net>
* event-Xt.c (x_to_emacs_keysym):
Take a new pointer argument, X_KEYSYM_OUT, where we store the X11
keysym that we actually used.
* event-Xt.c (x_event_to_emacs_event):
Call x_to_emacs_keysym with its new pointer argument, so we have
access to the X11 keysym used.
When checking whether a keysym obeys caps lock, use the X11 keysym
rather than the XEmacs keysym.
When checking whether a key has two distinct keysyms depending on
whether shift is pressed or not, use the X11 keysym passed back by
x_to_emacs_keysym rather than working it out again using
XLookupKeysym().
* event-Xt.c (keysym_obeys_caps_lock_p):
Use XConvertCase() in this function, now we're receiving the
actual X keysym used.
| author | Aidan Kehoe <kehoea@parhasard.net> |
|---|---|
| date | Sun, 28 Aug 2011 10:34:54 +0100 |
| parents | 308d34e9f07d |
| children |
| rev | line source |
|---|---|
| 428 | 1 ;;; rect.el --- rectangle functions for XEmacs. |
| 2 | |
| 442 | 3 ;; Copyright (C) 1985-2000 Free Software Foundation, Inc. |
| 428 | 4 |
| 442 | 5 ;; Maintainer: Didier Verna <didier@xemacs.org> |
| 428 | 6 ;; Keywords: internal |
| 7 | |
| 8 ;; This file is part of XEmacs. | |
| 9 | |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
10 ;; XEmacs is free software: you can redistribute it and/or modify it |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
11 ;; under the terms of the GNU General Public License as published by the |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
12 ;; Free Software Foundation, either version 3 of the License, or (at your |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
13 ;; option) any later version. |
| 428 | 14 |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
15 ;; XEmacs is distributed in the hope that it will be useful, but WITHOUT |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
16 ;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
17 ;; FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License |
|
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
18 ;; for more details. |
| 428 | 19 |
| 20 ;; You should have received a copy of the GNU General Public License | |
|
5402
308d34e9f07d
Changed bulk of GPLv2 or later files identified by script
Mats Lidell <matsl@xemacs.org>
parents:
686
diff
changeset
|
21 ;; along with XEmacs. If not, see <http://www.gnu.org/licenses/>. |
| 428 | 22 |
| 23 ;;; Synched up with: to be incorporated in a forthcoming GNU Emacs | |
| 24 | |
| 25 ;;; Commentary: | |
| 26 | |
| 27 ;; This package provides the operations on rectangles that are documented | |
| 28 ;; in the XEmacs Reference Manual. | |
| 29 | |
| 440 | 30 ;; #### NOTE: this file has been almost completely rewritten by Didier Verna |
| 442 | 31 ;; <didier@xemacs.org>, Jul 99. The purpose of this rewrite is to be less |
| 428 | 32 ;; intrusive and fill lines with whitespaces only when needed. A few functions |
| 33 ;; are untouched though, as noted above their definition. | |
| 34 | |
| 35 | |
| 36 ;;; Code: | |
| 37 | |
| 440 | 38 ;; #### NOTE: this function is untouched, but not used anymore. |
| 428 | 39 ;; `apply-on-rectangle' is used instead. It's still there because it's |
| 40 ;; documented so people might use it in their code, so I've decided not to | |
| 41 ;; touch it. --dv | |
| 42 ;; XEmacs: extra-args | |
| 43 (defun operate-on-rectangle (function start end coerce-tabs &rest extra-args) | |
| 44 "Call FUNCTION for each line of rectangle with corners at START, END. | |
| 45 If COERCE-TABS is non-nil, convert multi-column characters | |
| 46 that span the starting or ending columns on any line | |
| 47 to multiple spaces before calling FUNCTION. | |
| 48 FUNCTION is called with three arguments: | |
| 49 position of start of segment of this line within the rectangle, | |
| 50 number of columns that belong to rectangle but are before that position, | |
| 51 number of columns that belong to rectangle but are after point. | |
| 52 Point is at the end of the segment of this line within the rectangle." | |
| 53 (let (startcol startlinepos endcol endlinepos) | |
| 54 (save-excursion | |
| 55 (goto-char start) | |
| 56 (setq startcol (current-column)) | |
| 57 (beginning-of-line) | |
| 58 (setq startlinepos (point))) | |
| 59 (save-excursion | |
| 60 (goto-char end) | |
| 61 (setq endcol (current-column)) | |
| 62 (forward-line 1) | |
| 63 (setq endlinepos (point-marker))) | |
| 64 (if (< endcol startcol) | |
| 65 ;; XEmacs | |
| 66 (let ((tem startcol)) | |
| 67 (setq startcol endcol endcol tem))) | |
| 68 (save-excursion | |
| 69 (goto-char startlinepos) | |
| 70 (while (< (point) endlinepos) | |
| 71 (let (startpos begextra endextra) | |
| 72 (move-to-column startcol coerce-tabs) | |
| 73 (setq begextra (- (current-column) startcol)) | |
| 74 (setq startpos (point)) | |
| 75 (move-to-column endcol coerce-tabs) | |
| 76 (setq endextra (- endcol (current-column))) | |
| 77 (if (< begextra 0) | |
| 78 (setq endextra (+ endextra begextra) | |
| 79 begextra 0)) | |
| 80 (if (< endextra 0) (setq endextra 0)) | |
| 81 (apply function startpos begextra endextra extra-args)) | |
| 82 (forward-line 1))) | |
| 83 (- endcol startcol))) | |
| 84 | |
| 85 ;; The replacement for `operate-on-rectangle' -- dv | |
| 86 (defun apply-on-rectangle (function start end &rest args) | |
| 87 "Call FUNCTION for each line of rectangle with corners at START and END. | |
| 88 FUNCTION is called with two arguments: the start and end columns of the | |
| 89 rectangle, plus ARGS extra arguments. Point is at the beginning of line | |
| 90 when the function is called." | |
| 91 (let (startcol startpt endcol endpt) | |
| 92 (save-excursion | |
| 93 (goto-char start) | |
| 94 (setq startcol (current-column)) | |
| 95 (beginning-of-line) | |
| 96 (setq startpt (point)) | |
| 97 (goto-char end) | |
| 98 (setq endcol (current-column)) | |
| 99 (forward-line 1) | |
| 100 (setq endpt (point-marker)) | |
| 101 ;; ensure the start column is the left one. | |
| 102 (if (< endcol startcol) | |
| 103 (let ((col startcol)) | |
| 104 (setq startcol endcol endcol col))) | |
| 105 ;; start looping over lines | |
| 106 (goto-char startpt) | |
| 107 (while (< (point) endpt) | |
| 108 (apply function startcol endcol args) | |
| 109 (forward-line 1))) | |
| 110 )) | |
| 111 | |
| 112 | |
| 442 | 113 (defun delete-rectangle-line (startcol endcol fill) |
| 114 (let ((pt (point-at-eol))) | |
| 115 (when (= (move-to-column startcol (or fill 'coerce)) startcol) | |
| 116 (if (and (not fill) (<= pt endcol)) | |
| 117 (delete-region (point) pt) | |
| 118 ;; else | |
| 119 (setq pt (point)) | |
| 120 (move-to-column endcol t) | |
| 121 (delete-region pt (point)))) | |
| 122 )) | |
| 428 | 123 |
| 124 ;;;###autoload | |
| 125 (defun delete-rectangle (start end &optional fill) | |
| 126 "Delete the text in the region-rectangle without saving it. | |
| 127 The same range of columns is deleted in each line starting with the line | |
| 128 where the region begins and ending with the line where the region ends. | |
| 129 | |
| 130 When called from a program, the rectangle's corners are START and END. | |
| 131 With a prefix (or FILL) argument, also fill lines where nothing has to be | |
| 132 deleted." | |
| 133 (interactive "*r\nP") | |
| 134 (apply-on-rectangle 'delete-rectangle-line start end fill)) | |
| 135 | |
| 136 | |
| 442 | 137 ;; I love ascii art ;-) |
| 138 (defconst spaces-strings '["" | |
| 139 " " | |
| 140 " " | |
| 141 " " | |
| 142 " " | |
| 143 " " | |
| 144 " " | |
| 145 " " | |
| 146 " "]) | |
| 428 | 147 |
| 442 | 148 ;; This function is untouched --dv |
| 149 (defun spaces-string (n) | |
| 150 (if (<= n 8) (aref spaces-strings n) | |
| 151 (let ((val "")) | |
| 152 (while (> n 8) | |
| 153 (setq val (concat " " val) | |
| 154 n (- n 8))) | |
| 155 (concat val (aref spaces-strings n))))) | |
| 156 | |
| 428 | 157 |
| 158 (defun delete-extract-rectangle-line (startcol endcol lines fill) | |
| 159 (let ((pt (point-at-eol))) | |
| 160 (if (< (move-to-column startcol (or fill 'coerce)) startcol) | |
| 161 (setcdr lines (cons (spaces-string (- endcol startcol)) | |
| 162 (cdr lines))) | |
| 163 ;; else | |
| 164 (setq pt (point)) | |
| 165 (move-to-column endcol t) | |
| 166 (setcdr lines (cons (buffer-substring pt (point)) (cdr lines))) | |
| 167 (delete-region pt (point))) | |
| 168 )) | |
| 169 | |
| 170 ;;;###autoload | |
| 442 | 171 (defun delete-extract-rectangle (start end &optional fill) |
| 172 "Delete the contents of the rectangle with corners at START and END, and | |
| 173 return it as a list of strings, one for each line of the rectangle. | |
| 174 | |
| 175 With an optional FILL argument, also fill lines where nothing has to be | |
| 176 deleted." | |
| 428 | 177 (let ((lines (list nil))) |
| 442 | 178 (apply-on-rectangle 'delete-extract-rectangle-line start end lines fill) |
| 428 | 179 (nreverse (cdr lines)))) |
| 180 | |
| 442 | 181 |
| 440 | 182 ;; #### NOTE: this is actually the only function that needs to do complicated |
| 428 | 183 ;; stuff like what's happening in `operate-on-rectangle', because the buffer |
| 184 ;; might be read-only. --dv | |
| 185 (defun extract-rectangle-line (startcol endcol lines) | |
| 186 (let (start end begextra endextra line) | |
| 187 (move-to-column startcol) | |
| 188 (setq start (point) | |
| 189 begextra (- (current-column) startcol)) | |
| 190 (move-to-column endcol) | |
| 191 (setq end (point) | |
| 192 endextra (- endcol (current-column))) | |
| 193 (setq line (buffer-substring start (point))) | |
| 194 (if (< begextra 0) | |
| 195 (setq endextra (+ endextra begextra) | |
| 196 begextra 0)) | |
| 197 (if (< endextra 0) | |
| 198 (setq endextra 0)) | |
| 199 (goto-char start) | |
| 200 (while (search-forward "\t" end t) | |
| 201 (let ((width (- (current-column) | |
| 446 | 202 (save-excursion (backward-char 1) |
| 428 | 203 (current-column))))) |
| 204 (setq line (concat (substring line 0 (- (point) end 1)) | |
| 205 (spaces-string width) | |
| 206 (substring line (+ (length line) | |
| 207 (- (point) end))))))) | |
| 208 (if (or (> begextra 0) (> endextra 0)) | |
| 209 (setq line (concat (spaces-string begextra) | |
| 210 line | |
| 211 (spaces-string endextra)))) | |
| 212 (setcdr lines (cons line (cdr lines))))) | |
| 213 | |
| 442 | 214 ;;;###autoload |
| 215 (defun extract-rectangle (start end) | |
| 216 "Return the contents of the rectangle with corners at START and END, | |
| 217 as a list of strings, one for each line of the rectangle." | |
| 218 (let ((lines (list nil))) | |
| 219 (apply-on-rectangle 'extract-rectangle-line start end lines) | |
| 220 (nreverse (cdr lines)))) | |
| 221 | |
| 222 | |
| 223 ;;;###autoload | |
| 224 (defvar killed-rectangle nil | |
| 225 "Rectangle for `yank-rectangle' to insert.") | |
| 226 | |
| 227 ;;;###autoload | |
| 228 (defun kill-rectangle (start end &optional fill) | |
| 229 "Delete the region-rectangle and save it as the last killed one. | |
| 230 You might prefer to use `delete-extract-rectangle' from a program. | |
| 231 | |
| 232 When called from a program, the rectangle's corners are START and END. | |
| 233 With a prefix (or FILL) argument, also fill lines where nothing has to be | |
| 234 deleted." | |
| 235 (interactive "*r\nP") | |
| 236 (when buffer-read-only | |
| 237 (setq killed-rectangle (extract-rectangle start end)) | |
| 238 (barf-if-buffer-read-only)) | |
| 239 (setq killed-rectangle (delete-extract-rectangle start end fill))) | |
| 240 | |
| 428 | 241 ;; This function is untouched --dv |
| 242 ;;;###autoload | |
| 243 (defun yank-rectangle () | |
| 244 "Yank the last killed rectangle with upper left corner at point." | |
| 245 (interactive "*") | |
| 246 (insert-rectangle killed-rectangle)) | |
| 247 | |
| 442 | 248 |
| 428 | 249 ;; This function is untouched --dv |
| 250 ;;;###autoload | |
| 251 (defun insert-rectangle (rectangle) | |
| 252 "Insert text of RECTANGLE with upper left corner at point. | |
| 253 RECTANGLE's first line is inserted at point, its second | |
| 254 line is inserted at a point vertically under point, etc. | |
| 255 RECTANGLE should be a list of strings. | |
| 256 After this command, the mark is at the upper left corner | |
| 257 and point is at the lower right corner." | |
| 258 (let ((lines rectangle) | |
| 259 (insertcolumn (current-column)) | |
| 260 (first t)) | |
| 261 (push-mark) | |
| 262 (while lines | |
| 263 (or first | |
| 264 (progn | |
| 265 (forward-line 1) | |
| 266 (or (bolp) (insert ?\n)) | |
| 267 (move-to-column insertcolumn t))) | |
| 268 (setq first nil) | |
| 269 (insert (car lines)) | |
| 270 (setq lines (cdr lines))))) | |
| 271 | |
| 442 | 272 |
| 273 (defun open-rectangle-line (startcol endcol fill) | |
| 274 (when (= (move-to-column startcol (or fill 'coerce)) startcol) | |
| 275 (unless (and (not fill) | |
| 276 (= (point) (point-at-eol))) | |
| 277 (indent-to endcol)))) | |
| 278 | |
| 428 | 279 ;;;###autoload |
| 280 (defun open-rectangle (start end &optional fill) | |
| 281 "Blank out the region-rectangle, shifting text right. | |
| 282 | |
| 283 When called from a program, the rectangle's corners are START and END. | |
| 284 With a prefix (or FILL) argument, fill with blanks even if there is no text | |
| 285 on the right side of the rectangle." | |
| 286 (interactive "*r\nP") | |
| 287 (apply-on-rectangle 'open-rectangle-line start end fill) | |
| 288 (goto-char start)) | |
| 289 | |
| 442 | 290 |
| 291 (defun string-rectangle-line (startcol endcol string delete) | |
| 292 (move-to-column startcol t) | |
| 293 (if delete | |
| 294 (delete-rectangle-line startcol endcol nil)) | |
| 295 (insert string)) | |
| 428 | 296 |
| 297 ;;;###autoload | |
| 298 (defun string-rectangle (start end string) | |
| 299 "Insert STRING on each line of the region-rectangle, shifting text right. | |
| 442 | 300 The left edge of the rectangle specifies the column for insertion. |
| 301 | |
| 302 If `pending-delete-mode' is active the string replace the region. | |
| 303 Otherwise this command does not delete or overwrite any existing text. | |
| 428 | 304 |
| 305 When called from a program, the rectangle's corners are START and END." | |
| 306 (interactive "*r\nsString rectangle: ") | |
| 442 | 307 (defvar pending-delete-mode) |
| 308 (apply-on-rectangle 'string-rectangle-line start end string | |
| 309 (and (boundp 'pending-delete-mode) pending-delete-mode))) | |
| 428 | 310 |
| 686 | 311 ;;;###autoload |
| 442 | 312 (defun replace-rectangle (start end string) |
| 313 "Like `string-rectangle', but unconditionally replace the original region, | |
| 314 as if `pending-delete-mode' were active." | |
| 315 (interactive "*r\nsString rectangle: ") | |
| 316 (apply-on-rectangle 'string-rectangle-line start end string t)) | |
| 428 | 317 |
| 318 | |
| 319 (defun clear-rectangle-line (startcol endcol fill) | |
| 320 (let ((pt (point-at-eol)) | |
| 321 spaces) | |
| 322 (when (= (move-to-column startcol (or fill 'coerce)) startcol) | |
| 323 (if (and (not fill) | |
| 324 (<= (save-excursion (goto-char pt) (current-column)) endcol)) | |
| 325 (delete-region (point) pt) | |
| 326 ;; else | |
| 327 (setq pt (point)) | |
| 328 (move-to-column endcol t) | |
| 329 (setq spaces (- (point) pt)) | |
| 330 (delete-region pt (point)) | |
| 331 (indent-to (+ (current-column) spaces)))) | |
| 332 )) | |
| 333 | |
| 442 | 334 ;;;###autoload |
| 335 (defun clear-rectangle (start end &optional fill) | |
| 336 "Blank out the region-rectangle. | |
| 337 The text previously in the region is overwritten with blanks. | |
| 338 | |
| 339 When called from a program, the rectangle's corners are START and END. | |
| 340 With a prefix (or FILL) argument, also fill with blanks the parts of the | |
| 341 rectangle which were empty." | |
| 342 (interactive "*r\nP") | |
| 343 (apply-on-rectangle 'clear-rectangle-line start end fill)) | |
| 344 | |
| 345 | |
| 428 | 346 (provide 'rect) |
| 347 | |
| 348 ;;; rect.el ends here |
