frankh@durin.sparta.COM (Frank Halsema) (06/16/89)
Does emacs have or does someone else have a function that will isert a string in a region at a specified column. The function would be similiar to one that exists in a editor that I have used. The syntax of the old editor was ic 20-40 c5 hello This command would insert the string hello starting in column 5 between line 20 and 40. In emacs one would use a region instead of a line range. The lack of (or ignorance as the case may be) such a function has been the only complaint about emacs (at least the only one worth giving credence). Thanks for any help. * * * Frank Halsema /\* * SPARTA, Inc. / .\* / /\.\ / .\. \ \...\ / *\.\/ / * *\ / durin!frankh *** \/
quiroz@cs.rochester.edu (06/22/89)
This bounced in the mail, so I'd better post it. Enjoy, ------- Forwarded Message Received: from cayuga.cs.rochester.edu by sol.cs.rochester.edu (3.2/m) id AA19717; Wed, 21 Jun 89 18:05:59 EDT Received: by cayuga.cs.rochester.edu (5.59/m) id AA25064; Wed, 21 Jun 89 18:03:24 EDT Date: Wed, 21 Jun 89 18:03:24 EDT From: Mail Delivery Subsystem <MAILER-DAEMON> Subject: Returned mail: Cannot send message for 3 days Message-Id: <8906212203.AA25064@cayuga.cs.rochester.edu> To: <quiroz> ----- Transcript of session follows ----- ----- Unsent message follows ----- Received: from lesath.cs.rochester.edu by cayuga.cs.rochester.edu (5.59/m) id AA11374; Sun, 18 Jun 89 18:04:48 EDT Received: from loopback by lesath.cs.rochester.edu (3.2/m) id AA00924; Sun, 18 Jun 89 18:05:12 EDT Message-Id: <8906182205.AA00924@lesath.cs.rochester.edu> To: frankh@durin.sparta.COM (Frank Halsema) Subject: Re: Looking for an insert at column function In-Reply-To: Your message of 16 Jun 89 07:28:57 +0000. <1220@durin.sparta.COM> Date: Sun, 18 Jun 89 18:05:07 -0400 From: quiroz Out of curiosity, I consed up a function the responds directly your interactive needs. Hope you find it useful. Cesar - ---The Legendary Dashed Line--------------------------------------- (defun ic (start end column string) "For lines in the range of numbers START and END (START <= END), insert at column COLUMN the string STRING. Extend the file, if needed, to make the ranges implied possible." (interactive "nStarting line: \nnEnding line: \nnColumn: \nsString: ") (let* ((lastline (count-lines (point-min) (point-max))) (deficit (- end lastline))) (if (< end start) (error "End (%d) should be greater or equal to start (%d)" end start)) (goto-char (point-max)) (while (plusp deficit) (insert "\n") (setq deficit (- deficit 1))) (let ((current-line start)) (while (<= current-line end) (goto-line current-line) (goto-column column) (insert string) (setq current-line (+ current-line 1)))))) (defun goto-column (n) "Go to column N in this line, extend line at end with spaces if needed. Interactively, take the prefix argument as a column number or query in the minibuffer if none given." (interactive "p") (if (and (interactive-p) (null current-prefix-arg)) (setq n (call-interactively '(lambda (n) (interactive "nColumn to go to? ") n)))) (if (< n 0) (error "Negative column `%d' given to goto-column." n)) (let* ((line-length (save-excursion (end-of-line) (current-column))) (difference (- n line-length))) (cond ((<= difference 0) (move-to-column n)) (t (end-of-line) (while (> difference 0) (insert " ") (setq difference (- difference 1))))))) ------- End of Forwarded Message
quiroz@cs.rochester.edu (07/22/89)
At the end of this posting is a program (generic-code-mode) I use whenever dealing with roughly block strutured files (like shell scripts, awk programs, etc.), for which there is no specific mode that knows their syntax. The General Public License applies, as usual. I haven't done much work on it for a while, but I use it frequently. I don't expect bugs, but I am not happy with the fake unix-script-mode. So I am posting it in `pre-release' condition, for criticism and improvement from the user community. Frank: The function you need can be synthesized from `goto-column'. (I think you can separate goto-column from the rest, you may not need the bulk of generic-code-mode for this application). Suppose you need to insert a string at column N (remember it is 0-based) _in the current line_, you would just go there and insert. So, if you need to navigate by lines and columns, I would use something like this (vastly untested, careful): ;;; Bug: if line LINE does not exist, you get to the end of the ;;; buffer. Exercise for the reader: using count-lines or its ;;; friends, first figure out if the buffer needs to be stretched. ;;; Another exercise: figure out a reasonable interactive setting. (defun go-and-insert (string column &optional line) "Drop STRING at COLUMN of LINE. Omitting LINE defaults to the current line, the line point is on. LINE counts from 1 at the top of the buffer, COLUMN counts from 0 at the left edge. Point is left at the end of the inserted string." ;; you wouldn't want this to be (interactive), now would you? (if line (goto-line line)) (goto-column column) (insert string)) The peculiar argument order is justified by the desire to make the line number optional, of course. Cesar ;; Editing generic block structured files ;; Pre-release. ;; Copyright (C) 1989 Free Software Foundation, Inc. ;; Although this file is not yet part of GNU Emacs, it is ;; distributed in the same spirit. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY. No author or distributor ;; accepts responsibility to anyone for the consequences of using it ;; or for whether it serves any particular purpose or works at all, ;; unless he says so in writing. Refer to the GNU Emacs General Public ;; License for full details. ;; Everyone is granted permission to copy, modify and redistribute ;; GNU Emacs, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is ;; supposed to have been given to you along with GNU Emacs so you ;; can know your rights and responsibilities. It should be in a ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. ;;; Generic code mode for EMACS. ;;; ;;; Integrated more stuff. Point-to-tab-stop lets you move point ;;; without adding whitespace. Goto-column lets you go to a column of ;;; your choice, even when the line is shorter than that. CQ, 14 sep 88. ;;; ;;; This library lets the user deal with editing inputs that look ;;; block structured and have optional comments. It cannot be too ;;; bright, as there is little or no indication of the intended ;;; syntax, but the user can indicate his preferences via syntactic ;;; classes, abbrevs and such. CQ, 30 sep 87. (provide 'generic-code-mode) (require 'cl) (defvar generic-code-mode-hook nil) (defvar generic-code-mode-syntax-table nil) (defvar generic-code-mode-abbrev-table nil) (defvar generic-code-mode-map nil) (define-abbrev-table 'generic-code-mode-abbrev-table ()) (cond ((null generic-code-mode-map) (setq generic-code-mode-map (copy-keymap indented-text-mode-map)) (define-key generic-code-mode-map "\M-o" 'indent-to-point) (define-key generic-code-mode-map "\C-i" 'indent-to-tab-stop) (define-key generic-code-mode-map "\M-\C-i" 'tab-to-tab-stop) (define-key generic-code-mode-map "\M-i" 'point-to-tab-stop) (define-key generic-code-mode-map "\C-x|" 'goto-column) )) (defun generic-code-mode () "Sets generic code mode, essentially indented-text mode with no fill. TAB is rebound to run indent-to-tab-stop (q.v.), which is used to advance or retreat the indentation of the current line. See the function `set-scripts-syntax' for a simple customization useful when editing shell scripts, awk programs or icon programs, and the function `unix-script-mode' for a simple way to use it. See `right-adjust-line' too. \\{generic-code-mode-map}" (interactive) (indented-text-mode) ;; the variables specific to generic code mode are made buffer-local ;; in order to preserve the possibility of editing simultaneously ;; with slightly different `less-generic' modes based on this one. (make-local-variable 'generic-code-mode-map) (use-local-map generic-code-mode-map) (auto-fill-mode -1) (setq major-mode 'generic-code-mode) (setq mode-name "Code") (make-local-variable 'generic-code-mode-syntax-table) (setq generic-code-mode-syntax-table (make-syntax-table)) (make-local-variable 'generic-code-mode-syntax-table) (set-syntax-table generic-code-mode-syntax-table) (make-local-variable 'generic-code-mode-abbrev-table) (setq local-abbrev-table generic-code-mode-abbrev-table) ;; (make-local-variable 'comment-start) (make-local-variable 'comment-end) (make-local-variable 'comment-start-skip) (make-local-variable 'comment-indent-hook) ;; (run-hooks 'generic-code-mode-hook)) (defun indent-to-tab-stop (n) "Advance or retreat the indentation of this line. A positive argument (interactive default) advances, a negative argument retreats, a zero argument aligns with the previous nonblank line. The number of tab stops actually moved is the absolute value of the argument. Just using \C-u as prefix means the same as -1." (interactive "p") ;; Special case suggested by Neil: Just giving ;; `C-u' means `-', instead of `M- 4'. (when (consp current-prefix-arg) ;Any number of `C-u's (setq n -1)) (let ((here (point-marker)) (do-not-return nil)) (back-to-indentation) (setq do-not-return (looking-at "[ \t]*$")) (multiple-value-bind (prev-tab next-tab) (find-neighboring-tabs (current-column)) ;; Depending on sign of n, move forward or backward (cond ((> n 0) (indent-to-column next-tab) (when (> (decf n) 0) (indent-to-tab-stop n))) ((= n 0) (delete-horizontal-space) (indent-relative-maybe)) ((< n 0) (delete-horizontal-space) (indent-to-column prev-tab) (when (< (incf n) 0) (indent-to-tab-stop n))))) ;; go back to the correct relative position (unless do-not-return (goto-char (marker-position here))))) (defun point-to-tab-stop (n) "Advance or retreat the current-column to a near tab stop. Just move the cursor, don't add nor delete anything. Compare with tab-to-tab-stop, that pushes things to the right. A positive argument (interactive default) advances, a negative argument retreats. The number of tab stops actually moved is the absolute value of the argument. Giving it \C-u means `-', not 4." (interactive "p") ;; Special case suggested by Neil: Just giving ;; `C-u' means `-', instead of `M- 4'. (when (consp current-prefix-arg) ;Any number of `C-u's (setq n -1)) (multiple-value-bind (prev-tab next-tab) (find-neighboring-tabs (current-column)) ;; Depending on sign of n, move forward or backward (cond ((> n 0) (goto-column next-tab) (when (> (decf n) 0) (point-to-tab-stop n))) ((< n 0) (goto-column prev-tab) (when (< (incf n) 0) (point-to-tab-stop n)))))) (defun find-neighboring-tabs (column) "Return previous and next tab positions, when at position COLUMN. The values returned are chosen from tab-stop-list (if not null) or computed as exact multiples of tab-width. If COLUMN is outside the range of tab-stop-list, either 0 or (+ Column Tab-Width) are used as the missing bounds." (cond ((null tab-stop-list) ; have to use multiples of tab-width (cond ((= (mod column tab-width) 0) ;exact match (values (max 0 (- column tab-width)) (+ column tab-width))) (t ;in between matches (let* ((prev (floor column tab-width)) (next (+ prev tab-width))) (values prev next))))) (t ;there is a tab-stop-list (do* ((tabs ;add special terminator (append tab-stop-list (list (+ column tab-width))) (cdr tabs)) (past 0 this) (this (car tabs) (car tabs)) (next) ;used to store the values (prev) ; to return. (done nil)) (done (values prev next)) ;; we compare the current column against each tab stop ;; (the tab-stop-list being augmented by a catch-all ;; terminator) until the current column either matches one ;; of the tab stops or is precisely contained between two ;; of them. (cond ((= column this) ;; column matches a tab-stop=>return surrounding ones. (setf prev past ;need to protect value of past! next (cadr tabs) ;cadr won't ever fail here done t)) ((and (>= column past) (< column this)) ;; column is in between past and this (setf prev past ;need to protect value of past! next this done t)) (t ;; no need to do anything, do* will step for us )))))) (defun indent-to-point (here) "Move indentation of this line to the column of point. Used to force indentation to a given spot. When called from a program, give it a character position. The line that contains that position will be indented to the column of that position in it." (interactive "d") ;; Make sure you are really HERE (in the line containing HERE) (goto-char here) (let ((indentation (current-column))) (beginning-of-line) (delete-horizontal-space) (indent-to-column indentation))) ;;; Customizations of code mode (defun unix-script-mode () "This function sets up generic-code-mode with the syntax for scripts that is provided by set-scripts-syntax. It is not a real major mode, so it appears to be generic-code-mode for all intents and purposes." (interactive) (generic-code-mode) (set-scripts-syntax)) (defun set-scripts-syntax () "Establish # as a comment character, etc... Modifies generic-code-mode such that it is useful for scripts to be fed to sh, csh, awk, icont and the like." (interactive) ;; special commenting conventions (modify-syntax-entry ?# "<") (modify-syntax-entry ?\n ">") (modify-syntax-entry ?\f ">") (setq comment-start "#") (setq comment-end "") (setq comment-start-skip "#+ *") (setq comment-indent-hook 'generic-code-hash-comment-indent)) (defun generic-code-hash-comment-indent () "Indent comments that begin with at least one #. Comments at the beginning of a line or that begin with more than one hash are left alone. Move them around with indent-to-tab-stop, if you must." (if (or (bolp) (looking-at "##")) (current-column) (skip-chars-backward " \t") (max (if (bolp) 0 (1+ (current-column))) comment-column))) ;;; This routine provides absolute motions in a line, with possible ;;; extension of the line if so requested. Note that the standard ;;; `move-to-column' stops at line end. I bind this usually to `C-x |'. (defun goto-column (n) "Go to column N in this line, extend line at end with spaces if needed. Interactively, take the prefix argument as a column number or query in the minibuffer if none given." (interactive "p") (if (and (interactive-p) (null current-prefix-arg)) (setq n (call-interactively '(lambda (n) (interactive "nColumn to go to? ") n)))) (if (< n 0) (error "Negative column `%d' given to goto-column." n)) (let* ((line-length (save-excursion (end-of-line) (current-column))) (difference (- n line-length))) (cond ((<= difference 0) (move-to-column n)) (t (end-of-line) (while (> difference 0) (insert " ") (setq difference (- difference 1))))))) (defun right-adjust-line () "Have the current line end in a non-whitespace character aligned to the rightmost position. Rightmost here means 'at the fill-column or at window end'. Sort of complements any usage of `center-line' and the usage of `delete-horizontal-space' at the beginning of a line." (interactive) (beginning-of-line) (let ((had-fill-prefix (and fill-prefix (looking-at fill-prefix))) (fill-prefix-length (length fill-prefix))) (if had-fill-prefix (delete-char fill-prefix-length)) ;; trim horizontal space around the remaining text (delete-horizontal-space) (end-of-line) (delete-horizontal-space) ;; ASSERTION: Cursor is now at end of line (let* ((text-length (current-column)) (line-length (if fill-column fill-column (window-width))) (slack (- line-length text-length))) (beginning-of-line) (if (> slack 0) (indent-to-column slack)) ;; restore fill-prefix, if removed earlier (cond (had-fill-prefix (beginning-of-line) (cond ((> slack fill-prefix-length) (delete-char fill-prefix-length) (insert fill-prefix)) (t ;give up on this (delete-char slack) (insert fill-prefix))))) ;; have to put the cursor somewhere... (end-of-line)))) ;;; end of generic-code-mode.el
quiroz@cs.rochester.edu (Cesar Quiroz) (07/22/89)
At the end of this posting is a program (generic-code-mode) I use whenever dealing with roughly block structured files (like shell scripts, awk programs, etc.), for which there is no specific mode that knows their syntax. The General Public License applies, as usual. I haven't done much work on it for a while, but I use it frequently. I don't expect bugs, but I am not happy with the fake unix-script-mode. So I am posting it in `pre-release' condition, for criticism and improvement from the user community. Frank: The function you need can be synthesized from `goto-column'. (I think you can separate goto-column from the rest, you may not need the bulk of generic-code-mode for this application). Suppose you need to insert a string at column N (remember it is 0-based) _in the current line_, you would just go there and insert. So, if you need to navigate by lines and columns, I would use something like this (vastly untested, careful): ;;; Bug: if line LINE does not exist, you get to the end of the ;;; buffer. Exercise for the reader: using count-lines or its ;;; friends, first figure out if the buffer needs to be stretched. ;;; Another exercise: figure out a reasonable interactive setting. (defun go-and-insert (string column &optional line) "Drop STRING at COLUMN of LINE. Omitting LINE defaults to the current line, the line point is on. LINE counts from 1 at the top of the buffer, COLUMN counts from 0 at the left edge. Point is left at the end of the inserted string." ;; you wouldn't want this to be (interactive), now would you? (if line (goto-line line)) (goto-column column) (insert string)) The peculiar argument order is justified by the desire to make the line number optional, of course. The function you need requires more work (has to drop the string more than once, etc.), but it shouldn't be hard to modify go-and-insert to accomplish it. Cesar ;; Editing generic block structured files ;; Pre-release. ;; Copyright (C) 1989 Free Software Foundation, Inc. ;; Although this file is not yet part of GNU Emacs, it is ;; distributed in the same spirit. ;; GNU Emacs is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY. No author or distributor ;; accepts responsibility to anyone for the consequences of using it ;; or for whether it serves any particular purpose or works at all, ;; unless he says so in writing. Refer to the GNU Emacs General Public ;; License for full details. ;; Everyone is granted permission to copy, modify and redistribute ;; GNU Emacs, but only under the conditions described in the ;; GNU Emacs General Public License. A copy of this license is ;; supposed to have been given to you along with GNU Emacs so you ;; can know your rights and responsibilities. It should be in a ;; file named COPYING. Among other things, the copyright notice ;; and this notice must be preserved on all copies. ;;; Generic code mode for EMACS. ;;; ;;; Integrated more stuff. Point-to-tab-stop lets you move point ;;; without adding whitespace. Goto-column lets you go to a column of ;;; your choice, even when the line is shorter than that. CQ, 14 sep 88. ;;; ;;; This library lets the user deal with editing inputs that look ;;; block structured and have optional comments. It cannot be too ;;; bright, as there is little or no indication of the intended ;;; syntax, but the user can indicate his preferences via syntactic ;;; classes, abbrevs and such. CQ, 30 sep 87. (provide 'generic-code-mode) (require 'cl) (defvar generic-code-mode-hook nil) (defvar generic-code-mode-syntax-table nil) (defvar generic-code-mode-abbrev-table nil) (defvar generic-code-mode-map nil) (define-abbrev-table 'generic-code-mode-abbrev-table ()) (cond ((null generic-code-mode-map) (setq generic-code-mode-map (copy-keymap indented-text-mode-map)) (define-key generic-code-mode-map "\M-o" 'indent-to-point) (define-key generic-code-mode-map "\C-i" 'indent-to-tab-stop) (define-key generic-code-mode-map "\M-\C-i" 'tab-to-tab-stop) (define-key generic-code-mode-map "\M-i" 'point-to-tab-stop) (define-key generic-code-mode-map "\C-x|" 'goto-column) )) (defun generic-code-mode () "Sets generic code mode, essentially indented-text mode with no fill. TAB is rebound to run indent-to-tab-stop (q.v.), which is used to advance or retreat the indentation of the current line. See the function `set-scripts-syntax' for a simple customization useful when editing shell scripts, awk programs or icon programs, and the function `unix-script-mode' for a simple way to use it. See `right-adjust-line' too. \\{generic-code-mode-map}" (interactive) (indented-text-mode) ;; the variables specific to generic code mode are made buffer-local ;; in order to preserve the possibility of editing simultaneously ;; with slightly different `less-generic' modes based on this one. (make-local-variable 'generic-code-mode-map) (use-local-map generic-code-mode-map) (auto-fill-mode -1) (setq major-mode 'generic-code-mode) (setq mode-name "Code") (make-local-variable 'generic-code-mode-syntax-table) (setq generic-code-mode-syntax-table (make-syntax-table)) (make-local-variable 'generic-code-mode-syntax-table) (set-syntax-table generic-code-mode-syntax-table) (make-local-variable 'generic-code-mode-abbrev-table) (setq local-abbrev-table generic-code-mode-abbrev-table) ;; (make-local-variable 'comment-start) (make-local-variable 'comment-end) (make-local-variable 'comment-start-skip) (make-local-variable 'comment-indent-hook) ;; (run-hooks 'generic-code-mode-hook)) (defun indent-to-tab-stop (n) "Advance or retreat the indentation of this line. A positive argument (interactive default) advances, a negative argument retreats, a zero argument aligns with the previous nonblank line. The number of tab stops actually moved is the absolute value of the argument. Just using \C-u as prefix means the same as -1." (interactive "p") ;; Special case suggested by Neil: Just giving ;; `C-u' means `-', instead of `M- 4'. (when (consp current-prefix-arg) ;Any number of `C-u's (setq n -1)) (let ((here (point-marker)) (do-not-return nil)) (back-to-indentation) (setq do-not-return (looking-at "[ \t]*$")) (multiple-value-bind (prev-tab next-tab) (find-neighboring-tabs (current-column)) ;; Depending on sign of n, move forward or backward (cond ((> n 0) (indent-to-column next-tab) (when (> (decf n) 0) (indent-to-tab-stop n))) ((= n 0) (delete-horizontal-space) (indent-relative-maybe)) ((< n 0) (delete-horizontal-space) (indent-to-column prev-tab) (when (< (incf n) 0) (indent-to-tab-stop n))))) ;; go back to the correct relative position (unless do-not-return (goto-char (marker-position here))))) (defun point-to-tab-stop (n) "Advance or retreat the current-column to a near tab stop. Just move the cursor, don't add nor delete anything. Compare with tab-to-tab-stop, that pushes things to the right. A positive argument (interactive default) advances, a negative argument retreats. The number of tab stops actually moved is the absolute value of the argument. Giving it \C-u means `-', not 4." (interactive "p") ;; Special case suggested by Neil: Just giving ;; `C-u' means `-', instead of `M- 4'. (when (consp current-prefix-arg) ;Any number of `C-u's (setq n -1)) (multiple-value-bind (prev-tab next-tab) (find-neighboring-tabs (current-column)) ;; Depending on sign of n, move forward or backward (cond ((> n 0) (goto-column next-tab) (when (> (decf n) 0) (point-to-tab-stop n))) ((< n 0) (goto-column prev-tab) (when (< (incf n) 0) (point-to-tab-stop n)))))) (defun find-neighboring-tabs (column) "Return previous and next tab positions, when at position COLUMN. The values returned are chosen from tab-stop-list (if not null) or computed as exact multiples of tab-width. If COLUMN is outside the range of tab-stop-list, either 0 or (+ Column Tab-Width) are used as the missing bounds." (cond ((null tab-stop-list) ; have to use multiples of tab-width (cond ((= (mod column tab-width) 0) ;exact match (values (max 0 (- column tab-width)) (+ column tab-width))) (t ;in between matches (let* ((prev (floor column tab-width)) (next (+ prev tab-width))) (values prev next))))) (t ;there is a tab-stop-list (do* ((tabs ;add special terminator (append tab-stop-list (list (+ column tab-width))) (cdr tabs)) (past 0 this) (this (car tabs) (car tabs)) (next) ;used to store the values (prev) ; to return. (done nil)) (done (values prev next)) ;; we compare the current column against each tab stop ;; (the tab-stop-list being augmented by a catch-all ;; terminator) until the current column either matches one ;; of the tab stops or is precisely contained between two ;; of them. (cond ((= column this) ;; column matches a tab-stop=>return surrounding ones. (setf prev past ;need to protect value of past! next (cadr tabs) ;cadr won't ever fail here done t)) ((and (>= column past) (< column this)) ;; column is in between past and this (setf prev past ;need to protect value of past! next this done t)) (t ;; no need to do anything, do* will step for us )))))) (defun indent-to-point (here) "Move indentation of this line to the column of point. Used to force indentation to a given spot. When called from a program, give it a character position. The line that contains that position will be indented to the column of that position in it." (interactive "d") ;; Make sure you are really HERE (in the line containing HERE) (goto-char here) (let ((indentation (current-column))) (beginning-of-line) (delete-horizontal-space) (indent-to-column indentation))) ;;; Customizations of code mode (defun unix-script-mode () "This function sets up generic-code-mode with the syntax for scripts that is provided by set-scripts-syntax. It is not a real major mode, so it appears to be generic-code-mode for all intents and purposes." (interactive) (generic-code-mode) (set-scripts-syntax)) (defun set-scripts-syntax () "Establish # as a comment character, etc... Modifies generic-code-mode such that it is useful for scripts to be fed to sh, csh, awk, icont and the like." (interactive) ;; special commenting conventions (modify-syntax-entry ?# "<") (modify-syntax-entry ?\n ">") (modify-syntax-entry ?\f ">") (setq comment-start "#") (setq comment-end "") (setq comment-start-skip "#+ *") (setq comment-indent-hook 'generic-code-hash-comment-indent)) (defun generic-code-hash-comment-indent () "Indent comments that begin with at least one #. Comments at the beginning of a line or that begin with more than one hash are left alone. Move them around with indent-to-tab-stop, if you must." (if (or (bolp) (looking-at "##")) (current-column) (skip-chars-backward " \t") (max (if (bolp) 0 (1+ (current-column))) comment-column))) ;;; This routine provides absolute motions in a line, with possible ;;; extension of the line if so requested. Note that the standard ;;; `move-to-column' stops at line end. I bind this usually to `C-x |'. (defun goto-column (n) "Go to column N in this line, extend line at end with spaces if needed. Interactively, take the prefix argument as a column number or query in the minibuffer if none given." (interactive "p") (if (and (interactive-p) (null current-prefix-arg)) (setq n (call-interactively '(lambda (n) (interactive "nColumn to go to? ") n)))) (if (< n 0) (error "Negative column `%d' given to goto-column." n)) (let* ((line-length (save-excursion (end-of-line) (current-column))) (difference (- n line-length))) (cond ((<= difference 0) (move-to-column n)) (t (end-of-line) (while (> difference 0) (insert " ") (setq difference (- difference 1))))))) (defun right-adjust-line () "Have the current line end in a non-whitespace character aligned to the rightmost position. Rightmost here means 'at the fill-column or at window end'. Sort of complements any usage of `center-line' and the usage of `delete-horizontal-space' at the beginning of a line." (interactive) (beginning-of-line) (let ((had-fill-prefix (and fill-prefix (looking-at fill-prefix))) (fill-prefix-length (length fill-prefix))) (if had-fill-prefix (delete-char fill-prefix-length)) ;; trim horizontal space around the remaining text (delete-horizontal-space) (end-of-line) (delete-horizontal-space) ;; ASSERTION: Cursor is now at end of line (let* ((text-length (current-column)) (line-length (if fill-column fill-column (window-width))) (slack (- line-length text-length))) (beginning-of-line) (if (> slack 0) (indent-to-column slack)) ;; restore fill-prefix, if removed earlier (cond (had-fill-prefix (beginning-of-line) (cond ((> slack fill-prefix-length) (delete-char fill-prefix-length) (insert fill-prefix)) (t ;give up on this (delete-char slack) (insert fill-prefix))))) ;; have to put the cursor somewhere... (end-of-line)))) ;;; end of generic-code-mode.el -- Cesar Augusto Quiroz Gonzalez Department of Computer Science University of Rochester Rochester, NY 14627