diff options
| author | Nick Roberts | 2005-01-18 11:28:19 +0000 |
|---|---|---|
| committer | Nick Roberts | 2005-01-18 11:28:19 +0000 |
| commit | b6d0e4dad049bd1c3ea3a153c6cb8cebf04ea714 (patch) | |
| tree | 4e9b1a6e7baaf8f20e1760a49052c5313f840afd | |
| parent | 83c7f8065ce04ced5cfa8954189bfb2c1eed1b08 (diff) | |
| download | emacs-b6d0e4dad049bd1c3ea3a153c6cb8cebf04ea714.tar.gz emacs-b6d0e4dad049bd1c3ea3a153c6cb8cebf04ea714.zip | |
(gdb-put-string): Copy/create strings so
that enable/disabled state of breakpoints is shown correctly in
fringe and on ttys.
(gdb-put-breakpoint-icon, gdb-info-breakpoints-custom):
Add breakpoint information as text properties.
(gdb-mouse-toggle-breakpoint):
Rename to gdb-mouse-set-clear-breakpoint.
(gdb-mouse-toggle-breakpoint): New function. Enable/disable
breakpoints in the margin.
(gdb-remove-strings): Simplify.
| -rw-r--r-- | lisp/progmodes/gdb-ui.el | 127 |
1 files changed, 83 insertions, 44 deletions
diff --git a/lisp/progmodes/gdb-ui.el b/lisp/progmodes/gdb-ui.el index aef997d2a66..ad081c2ac9e 100644 --- a/lisp/progmodes/gdb-ui.el +++ b/lisp/progmodes/gdb-ui.el | |||
| @@ -33,24 +33,28 @@ | |||
| 33 | ;; Emacs 21 such as the fringe/display margin for breakpoints, and the toolbar | 33 | ;; Emacs 21 such as the fringe/display margin for breakpoints, and the toolbar |
| 34 | ;; (see the GDB Graphical Interface section in the Emacs info manual). | 34 | ;; (see the GDB Graphical Interface section in the Emacs info manual). |
| 35 | 35 | ||
| 36 | ;; Start the debugger with M-x gdba. | 36 | ;; By default, M-x gdb will start the debugger. However, if you have customised |
| 37 | 37 | ;; gud-gdb-command-name, then start it with M-x gdba. | |
| 38 | ;; This file has evolved from gdba.el from GDB 5.0 written by Tom Lord and Jim | 38 | |
| 39 | ;; Kingdon and uses GDB's annotation interface. You don't need to know about | 39 | ;; This file has evolved from gdba.el that was included with GDB 5.0 and |
| 40 | ;; annotations to use this mode as a debugger, but if you are interested | 40 | ;; written by Tom Lord and Jim Kingdon. It uses GDB's annotation interface. |
| 41 | ;; developing the mode itself, then see the Annotations section in the GDB | 41 | ;; You don't need to know about annotations to use this mode as a debugger, |
| 42 | ;; info manual. | 42 | ;; but if you are interested developing the mode itself, then see the |
| 43 | ;; Annotations section in the GDB info manual. | ||
| 43 | ;; | 44 | ;; |
| 44 | ;; GDB developers plan to make the annotation interface obsolete. A new | 45 | ;; GDB developers plan to make the annotation interface obsolete. A new |
| 45 | ;; interface called GDB/MI (machine interface) has been designed to replace | 46 | ;; interface called GDB/MI (machine interface) has been designed to replace |
| 46 | ;; it. Some GDB/MI commands are used in this file through the CLI command | 47 | ;; it. Some GDB/MI commands are used in this file through the CLI command |
| 47 | ;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included in the | 48 | ;; 'interpreter mi <mi-command>'. A file called gdb-mi.el is included with |
| 48 | ;; GDB repository for future releases (6.2 onwards) that uses GDB/MI as the | 49 | ;; GDB (6.2 onwards) that uses GDB/MI as the primary interface to GDB. It is |
| 49 | ;; primary interface to GDB. It is still under development and is part of a | 50 | ;; still under development and is part of a process to migrate Emacs from |
| 50 | ;; process to migrate Emacs from annotations to GDB/MI. | 51 | ;; annotations to GDB/MI. |
| 51 | ;; | 52 | ;; |
| 52 | ;; Known Bugs: | 53 | ;; Known Bugs: |
| 53 | ;; | 54 | ;; |
| 55 | ;; TODO: | ||
| 56 | ;; Use tree-widget.el instead of the speedbar for watch-expressions? | ||
| 57 | ;; Mark breakpoint locations on scroll-bar of source buffer? | ||
| 54 | 58 | ||
| 55 | ;;; Code: | 59 | ;;; Code: |
| 56 | 60 | ||
| @@ -169,13 +173,13 @@ detailed description of this mode. | |||
| 169 | (defvar gdb-debug-log nil) | 173 | (defvar gdb-debug-log nil) |
| 170 | 174 | ||
| 171 | (defcustom gdb-enable-debug-log nil | 175 | (defcustom gdb-enable-debug-log nil |
| 172 | "Non-nil means record the process input and output in `gdb-debug-log'." | 176 | "Non-nil means record the process input and output in `gdb-debug-log'." |
| 173 | :type 'boolean | 177 | :type 'boolean |
| 174 | :group 'gud | 178 | :group 'gud |
| 175 | :version "21.4") | 179 | :version "21.4") |
| 176 | 180 | ||
| 177 | (defcustom gdb-use-inferior-io-buffer nil | 181 | (defcustom gdb-use-inferior-io-buffer nil |
| 178 | "Non-nil means display output from the inferior in a separate buffer." | 182 | "Non-nil means display output from the inferior in a separate buffer." |
| 179 | :type 'boolean | 183 | :type 'boolean |
| 180 | :group 'gud | 184 | :group 'gud |
| 181 | :version "21.4") | 185 | :version "21.4") |
| @@ -210,9 +214,13 @@ detailed description of this mode. | |||
| 210 | "\C-u" "Continue to current line or address.") | 214 | "\C-u" "Continue to current line or address.") |
| 211 | 215 | ||
| 212 | (define-key gud-minor-mode-map [left-margin mouse-1] | 216 | (define-key gud-minor-mode-map [left-margin mouse-1] |
| 213 | 'gdb-mouse-toggle-breakpoint) | 217 | 'gdb-mouse-set-clear-breakpoint) |
| 214 | (define-key gud-minor-mode-map [left-fringe mouse-1] | 218 | (define-key gud-minor-mode-map [left-fringe mouse-1] |
| 219 | 'gdb-mouse-set-clear-breakpoint) | ||
| 220 | (define-key gud-minor-mode-map [left-margin mouse-3] | ||
| 215 | 'gdb-mouse-toggle-breakpoint) | 221 | 'gdb-mouse-toggle-breakpoint) |
| 222 | ; (define-key gud-minor-mode-map [left-fringe mouse-3] | ||
| 223 | ; 'gdb-mouse-toggle-breakpoint) | ||
| 216 | 224 | ||
| 217 | (setq comint-input-sender 'gdb-send) | 225 | (setq comint-input-sender 'gdb-send) |
| 218 | ;; | 226 | ;; |
| @@ -281,7 +289,7 @@ detailed description of this mode. | |||
| 281 | (Info-goto-node "(emacs)GDB Graphical Interface")) | 289 | (Info-goto-node "(emacs)GDB Graphical Interface")) |
| 282 | 290 | ||
| 283 | (defconst gdb-var-create-regexp | 291 | (defconst gdb-var-create-regexp |
| 284 | "name=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",type=\"\\(.*?\\)\"") | 292 | "name=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\",type=\"\\(.*?\\)\"") |
| 285 | 293 | ||
| 286 | (defun gdb-var-create-handler (expr) | 294 | (defun gdb-var-create-handler (expr) |
| 287 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) | 295 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) |
| @@ -328,7 +336,7 @@ detailed description of this mode. | |||
| 328 | `(lambda () (gdb-var-list-children-handler ,varnum))))) | 336 | `(lambda () (gdb-var-list-children-handler ,varnum))))) |
| 329 | 337 | ||
| 330 | (defconst gdb-var-list-children-regexp | 338 | (defconst gdb-var-list-children-regexp |
| 331 | "name=\"\\(.*?\\)\",exp=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\"") | 339 | "name=\"\\(.*?\\)\",exp=\"\\(.*?\\)\",numchild=\"\\(.*?\\)\"") |
| 332 | 340 | ||
| 333 | (defun gdb-var-list-children-handler (varnum) | 341 | (defun gdb-var-list-children-handler (varnum) |
| 334 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) | 342 | (with-current-buffer (gdb-get-create-buffer 'gdb-partial-output-buffer) |
| @@ -1038,7 +1046,8 @@ happens to be appropriate." | |||
| 1038 | 1046 | ||
| 1039 | (defvar gdb-cdir nil "Compilation directory.") | 1047 | (defvar gdb-cdir nil "Compilation directory.") |
| 1040 | 1048 | ||
| 1041 | (defconst breakpoint-xpm-data "/* XPM */ | 1049 | (defconst breakpoint-xpm-data |
| 1050 | "/* XPM */ | ||
| 1042 | static char *magick[] = { | 1051 | static char *magick[] = { |
| 1043 | /* columns rows colors chars-per-pixel */ | 1052 | /* columns rows colors chars-per-pixel */ |
| 1044 | \"10 10 2 1\", | 1053 | \"10 10 2 1\", |
| @@ -1059,7 +1068,7 @@ static char *magick[] = { | |||
| 1059 | "XPM data used for breakpoint icon.") | 1068 | "XPM data used for breakpoint icon.") |
| 1060 | 1069 | ||
| 1061 | (defconst breakpoint-enabled-pbm-data | 1070 | (defconst breakpoint-enabled-pbm-data |
| 1062 | "P1 | 1071 | "P1 |
| 1063 | 10 10\", | 1072 | 10 10\", |
| 1064 | 0 0 0 0 1 1 1 1 0 0 0 0 | 1073 | 0 0 0 0 1 1 1 1 0 0 0 0 |
| 1065 | 0 0 0 1 1 1 1 1 1 0 0 0 | 1074 | 0 0 0 1 1 1 1 1 1 0 0 0 |
| @@ -1074,7 +1083,7 @@ static char *magick[] = { | |||
| 1074 | "PBM data used for enabled breakpoint icon.") | 1083 | "PBM data used for enabled breakpoint icon.") |
| 1075 | 1084 | ||
| 1076 | (defconst breakpoint-disabled-pbm-data | 1085 | (defconst breakpoint-disabled-pbm-data |
| 1077 | "P1 | 1086 | "P1 |
| 1078 | 10 10\", | 1087 | 10 10\", |
| 1079 | 0 0 1 0 1 0 1 0 0 0 | 1088 | 0 0 1 0 1 0 1 0 0 0 |
| 1080 | 0 1 0 1 0 1 0 1 0 0 | 1089 | 0 1 0 1 0 1 0 1 0 0 |
| @@ -1116,8 +1125,7 @@ static char *magick[] = { | |||
| 1116 | 1125 | ||
| 1117 | ;;-put breakpoint icons in relevant margins (even those set in the GUD buffer) | 1126 | ;;-put breakpoint icons in relevant margins (even those set in the GUD buffer) |
| 1118 | (defun gdb-info-breakpoints-custom () | 1127 | (defun gdb-info-breakpoints-custom () |
| 1119 | (let ((flag)) | 1128 | (let ((flag) (bptno)) |
| 1120 | ;; | ||
| 1121 | ;; remove all breakpoint-icons in source buffers but not assembler buffer | 1129 | ;; remove all breakpoint-icons in source buffers but not assembler buffer |
| 1122 | (dolist (buffer (buffer-list)) | 1130 | (dolist (buffer (buffer-list)) |
| 1123 | (with-current-buffer buffer | 1131 | (with-current-buffer buffer |
| @@ -1131,12 +1139,13 @@ static char *magick[] = { | |||
| 1131 | (forward-line 1) | 1139 | (forward-line 1) |
| 1132 | (if (looking-at "[^\t].*breakpoint") | 1140 | (if (looking-at "[^\t].*breakpoint") |
| 1133 | (progn | 1141 | (progn |
| 1134 | (looking-at "[0-9]*\\s-*\\S-*\\s-*\\S-*\\s-*\\(.\\)") | 1142 | (looking-at "\\([0-9]+\\)\\s-+\\S-+\\s-+\\S-+\\s-+\\(.\\)") |
| 1135 | (setq flag (char-after (match-beginning 1))) | 1143 | (setq bptno (match-string 1)) |
| 1144 | (setq flag (char-after (match-beginning 2))) | ||
| 1136 | (beginning-of-line) | 1145 | (beginning-of-line) |
| 1137 | (if (re-search-forward "in\\s-+\\S-+\\s-+at\\s-+" nil t) | 1146 | (if (re-search-forward "in\\s-+\\S-+\\s-+at\\s-+" nil t) |
| 1138 | (progn | 1147 | (progn |
| 1139 | (looking-at "\\(\\S-*\\):\\([0-9]+\\)") | 1148 | (looking-at "\\(\\S-+\\):\\([0-9]+\\)") |
| 1140 | (let ((line (match-string 2)) (buffer-read-only nil) | 1149 | (let ((line (match-string 2)) (buffer-read-only nil) |
| 1141 | (file (match-string 1))) | 1150 | (file (match-string 1))) |
| 1142 | (add-text-properties (point-at-bol) (point-at-eol) | 1151 | (add-text-properties (point-at-bol) (point-at-eol) |
| @@ -1153,12 +1162,12 @@ static char *magick[] = { | |||
| 1153 | ;; only want one breakpoint icon at each location | 1162 | ;; only want one breakpoint icon at each location |
| 1154 | (save-excursion | 1163 | (save-excursion |
| 1155 | (goto-line (string-to-number line)) | 1164 | (goto-line (string-to-number line)) |
| 1156 | (gdb-put-breakpoint-icon (eq flag ?y))))))))) | 1165 | (gdb-put-breakpoint-icon (eq flag ?y) bptno)))))))) |
| 1157 | (end-of-line))))) | 1166 | (end-of-line))))) |
| 1158 | (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) | 1167 | (if (gdb-get-buffer 'gdb-assembler-buffer) (gdb-assembler-custom))) |
| 1159 | 1168 | ||
| 1160 | (defun gdb-mouse-toggle-breakpoint (event) | 1169 | (defun gdb-mouse-set-clear-breakpoint (event) |
| 1161 | "Toggle breakpoint in left fringe/margin with mouse click." | 1170 | "Set/clear breakpoint in left fringe/margin with mouse click." |
| 1162 | (interactive "e") | 1171 | (interactive "e") |
| 1163 | (mouse-minibuffer-check event) | 1172 | (mouse-minibuffer-check event) |
| 1164 | (let ((posn (event-end event))) | 1173 | (let ((posn (event-end event))) |
| @@ -1172,6 +1181,31 @@ static char *magick[] = { | |||
| 1172 | (gud-remove nil) | 1181 | (gud-remove nil) |
| 1173 | (gud-break nil))))))) | 1182 | (gud-break nil))))))) |
| 1174 | 1183 | ||
| 1184 | (defun gdb-mouse-toggle-breakpoint (event) | ||
| 1185 | "Enable/disable breakpoint in left fringe/margin with mouse click." | ||
| 1186 | (interactive "e") | ||
| 1187 | (mouse-minibuffer-check event) | ||
| 1188 | (let ((posn (event-end event))) | ||
| 1189 | (if (numberp (posn-point posn)) | ||
| 1190 | (with-selected-window (posn-window posn) | ||
| 1191 | (save-excursion | ||
| 1192 | (goto-char (posn-point posn)) | ||
| 1193 | (if | ||
| 1194 | ; (or | ||
| 1195 | (posn-object posn) | ||
| 1196 | ; (eq (car (fringe-bitmaps-at-pos (posn-point posn))) | ||
| 1197 | ; 'breakpoint)) | ||
| 1198 | (gdb-enqueue-input | ||
| 1199 | (list | ||
| 1200 | (let ((bptno (get-text-property | ||
| 1201 | 0 'gdb-bptno (car (posn-string posn))))) | ||
| 1202 | (concat | ||
| 1203 | (if (get-text-property | ||
| 1204 | 0 'gdb-enabled (car (posn-string posn))) | ||
| 1205 | "disable " | ||
| 1206 | "enable ") | ||
| 1207 | bptno "\n")) 'ignore)))))))) | ||
| 1208 | |||
| 1175 | (defun gdb-breakpoints-buffer-name () | 1209 | (defun gdb-breakpoints-buffer-name () |
| 1176 | (with-current-buffer gud-comint-buffer | 1210 | (with-current-buffer gud-comint-buffer |
| 1177 | (concat "*breakpoints of " (gdb-get-target-string) "*"))) | 1211 | (concat "*breakpoints of " (gdb-get-target-string) "*"))) |
| @@ -1227,7 +1261,7 @@ static char *magick[] = { | |||
| 1227 | 'gdbmi-invalidate-breakpoints)) | 1261 | 'gdbmi-invalidate-breakpoints)) |
| 1228 | 1262 | ||
| 1229 | (defun gdb-toggle-breakpoint () | 1263 | (defun gdb-toggle-breakpoint () |
| 1230 | "Enable/disable the breakpoint at current line." | 1264 | "Enable/disable breakpoint at current line." |
| 1231 | (interactive) | 1265 | (interactive) |
| 1232 | (save-excursion | 1266 | (save-excursion |
| 1233 | (beginning-of-line 1) | 1267 | (beginning-of-line 1) |
| @@ -1707,7 +1741,7 @@ of the inferior. Non-nil means display the layout shown for | |||
| 1707 | :version "21.4") | 1741 | :version "21.4") |
| 1708 | 1742 | ||
| 1709 | (defun gdb-many-windows (arg) | 1743 | (defun gdb-many-windows (arg) |
| 1710 | "Toggle the number of windows in the basic arrangement." | 1744 | "Toggle the number of windows in the basic arrangement." |
| 1711 | (interactive "P") | 1745 | (interactive "P") |
| 1712 | (setq gdb-many-windows | 1746 | (setq gdb-many-windows |
| 1713 | (if (null arg) | 1747 | (if (null arg) |
| @@ -1777,14 +1811,15 @@ buffers." | |||
| 1777 | PUTSTRING is displayed by putting an overlay into the current buffer with a | 1811 | PUTSTRING is displayed by putting an overlay into the current buffer with a |
| 1778 | `before-string' STRING that has a `display' property whose value is | 1812 | `before-string' STRING that has a `display' property whose value is |
| 1779 | PUTSTRING." | 1813 | PUTSTRING." |
| 1780 | (let ((gdb-string "x") | 1814 | (let ((string (make-string 1 ?x)) |
| 1781 | (buffer (current-buffer))) | 1815 | (buffer (current-buffer))) |
| 1816 | (setq putstring (copy-sequence putstring)) | ||
| 1782 | (let ((overlay (make-overlay pos pos buffer)) | 1817 | (let ((overlay (make-overlay pos pos buffer)) |
| 1783 | (prop (or dprop | 1818 | (prop (or dprop |
| 1784 | (list (list 'margin 'left-margin) putstring)))) | 1819 | (list (list 'margin 'left-margin) putstring)))) |
| 1785 | (put-text-property 0 (length gdb-string) 'display prop gdb-string) | 1820 | (put-text-property 0 (length string) 'display prop string) |
| 1786 | (overlay-put overlay 'put-break t) | 1821 | (overlay-put overlay 'put-break t) |
| 1787 | (overlay-put overlay 'before-string gdb-string)))) | 1822 | (overlay-put overlay 'before-string string)))) |
| 1788 | 1823 | ||
| 1789 | ;;from remove-images | 1824 | ;;from remove-images |
| 1790 | (defun gdb-remove-strings (start end &optional buffer) | 1825 | (defun gdb-remove-strings (start end &optional buffer) |
| @@ -1793,25 +1828,27 @@ Remove only strings that were put in BUFFER with calls to `gdb-put-string'. | |||
| 1793 | BUFFER nil or omitted means use the current buffer." | 1828 | BUFFER nil or omitted means use the current buffer." |
| 1794 | (unless buffer | 1829 | (unless buffer |
| 1795 | (setq buffer (current-buffer))) | 1830 | (setq buffer (current-buffer))) |
| 1796 | (let ((overlays (overlays-in start end))) | 1831 | (dolist (overlay (overlays-in start end)) |
| 1797 | (while overlays | ||
| 1798 | (let ((overlay (car overlays))) | ||
| 1799 | (when (overlay-get overlay 'put-break) | 1832 | (when (overlay-get overlay 'put-break) |
| 1800 | (delete-overlay overlay))) | 1833 | (delete-overlay overlay)))) |
| 1801 | (setq overlays (cdr overlays))))) | ||
| 1802 | 1834 | ||
| 1803 | (defun gdb-put-breakpoint-icon (enabled) | 1835 | (defun gdb-put-breakpoint-icon (enabled bptno) |
| 1804 | (let ((start (progn (beginning-of-line) (- (point) 1))) | 1836 | (let ((start (progn (beginning-of-line) (- (point) 1))) |
| 1805 | (end (progn (end-of-line) (+ (point) 1)))) | 1837 | (end (progn (end-of-line) (+ (point) 1))) |
| 1838 | (putstring (if enabled "B" "b"))) | ||
| 1839 | (if enabled (add-text-properties | ||
| 1840 | 0 1 `(gdb-bptno ,bptno gdb-enabled t) putstring) | ||
| 1841 | (add-text-properties | ||
| 1842 | 0 1 `(gdb-bptno ,bptno gdb-enabled nil) putstring)) | ||
| 1806 | (gdb-remove-breakpoint-icons start end) | 1843 | (gdb-remove-breakpoint-icons start end) |
| 1807 | (if (display-images-p) | 1844 | (if (display-images-p) |
| 1808 | (if (>= (car (window-fringes)) 8) | 1845 | (if (>= (car (window-fringes)) 8) |
| 1809 | (gdb-put-string | 1846 | (gdb-put-string |
| 1810 | nil (1+ start) | 1847 | nil (1+ start) |
| 1811 | `(left-fringe breakpoint | 1848 | `(left-fringe breakpoint |
| 1812 | ,(if enabled | 1849 | ,(if enabled |
| 1813 | 'breakpoint-enabled-bitmap-face | 1850 | 'breakpoint-enabled-bitmap-face |
| 1814 | 'breakpoint-disabled-bitmap-face))) | 1851 | 'breakpoint-disabled-bitmap-face))) |
| 1815 | (when (< left-margin-width 2) | 1852 | (when (< left-margin-width 2) |
| 1816 | (save-current-buffer | 1853 | (save-current-buffer |
| 1817 | (setq left-margin-width 2) | 1854 | (setq left-margin-width 2) |
| @@ -1838,7 +1875,9 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1838 | (:type pbm :data | 1875 | (:type pbm :data |
| 1839 | ,breakpoint-disabled-pbm-data | 1876 | ,breakpoint-disabled-pbm-data |
| 1840 | :ascent 100)))))) | 1877 | :ascent 100)))))) |
| 1841 | (+ start 1) nil 'left-margin)) | 1878 | (+ start 1) |
| 1879 | putstring | ||
| 1880 | 'left-margin)) | ||
| 1842 | (when (< left-margin-width 2) | 1881 | (when (< left-margin-width 2) |
| 1843 | (save-current-buffer | 1882 | (save-current-buffer |
| 1844 | (setq left-margin-width 2) | 1883 | (setq left-margin-width 2) |
| @@ -1846,7 +1885,7 @@ BUFFER nil or omitted means use the current buffer." | |||
| 1846 | (set-window-margins | 1885 | (set-window-margins |
| 1847 | (get-buffer-window (current-buffer) 0) | 1886 | (get-buffer-window (current-buffer) 0) |
| 1848 | left-margin-width right-margin-width)))) | 1887 | left-margin-width right-margin-width)))) |
| 1849 | (gdb-put-string (if enabled "B" "b") (1+ start))))) | 1888 | (gdb-put-string putstring (1+ start))))) |
| 1850 | 1889 | ||
| 1851 | (defun gdb-remove-breakpoint-icons (start end &optional remove-margin) | 1890 | (defun gdb-remove-breakpoint-icons (start end &optional remove-margin) |
| 1852 | (gdb-remove-strings start end) | 1891 | (gdb-remove-strings start end) |