home *** CD-ROM | disk | FTP | other *** search
- Path: tut.cis.ohio-state.edu!UUNET.UU.NET!telotech!bsa%hal
- From: telotech!bsa%hal@UUNET.UU.NET (Brandon S. Allbery)
- Newsgroups: gnu.emacs
- Subject: (repost) simple-indent mode
- Message-ID: <8910030848.AA03962@telotech.UUCP>
- Date: 2 Oct 89 12:19:33 GMT
- Sender: daemon@tut.cis.ohio-state.edu
- Distribution: gnu
- Organization: GNUs Not Usenet
- Lines: 143
-
- I sent this out yesterday, but something seems to have broken suddenly in the
- kluge that forces smail and mh to work in a rational way on a Xenix-descended
- system that is more a hybrid of everything than compatible with any one. So
- here it is again, via another mailer.
-
- Someone was looking for a perl mode. I don't have one, but I have a major
- mode I whipped up to handle random script-like languages: shell, perl,
- Makefiles, SQL, Accell/Language, etc. To use it, put (load "sindent") in
- your .emacs and set up your auto-mode-alist to invoke simple-indent-mode on
- whatever files. It's not perfect, but it works far better than just text mode
- and uses a rigid indent, unlike indented-text mode.
-
- ++Brandon
- ------------------------------------------------------------------------------
- ;;; Major mode to do simple indentation
- ;;; based on text mode, but redefines TAB to use tab-stop
- ;;; obeys left-margin
-
- (defvar tab-stop 8
- "*Size of a TAB in simple-indent mode.")
- (make-variable-buffer-local 'tab-stop)
-
- (defvar sindent-obey-all-tabs nil
- "*If non-nil, all TABs in simple-indent mode use tab-stop.")
-
- (defvar sindent-mode-syntax-table nil
- "Syntax table used while in simple-indent mode.")
-
- (defvar sindent-mode-abbrev-table nil
- "Abbrev table used while in sindent mode.")
- (define-abbrev-table 'sindent-mode-abbrev-table ())
-
- (if sindent-mode-syntax-table
- ()
- (setq sindent-mode-syntax-table (make-syntax-table))
- (modify-syntax-entry ?\" ". " sindent-mode-syntax-table)
- (modify-syntax-entry ?\\ ". " sindent-mode-syntax-table)
- (modify-syntax-entry ?' "w " sindent-mode-syntax-table))
-
- (defvar sindent-mode-map nil "")
- (if sindent-mode-map
- ()
- (setq sindent-mode-map (make-sparse-keymap))
- (define-key sindent-mode-map "\t" 'simple-tab)
- (define-key sindent-mode-map "\177" 'sindent-backward-delete-char)
- (define-key sindent-mode-map "\es" 'center-line)
- (define-key sindent-mode-map "\eS" 'center-paragraph))
-
- (defun simple-indent-mode ()
- "Major mode to do simple indentation. Based on Text mode.
- In this mode, TAB moves tab-width spaces in the indentation area of a line,
- compacting spaces to real tabs as it goes. Commands:\\{sindent-mode-map}
- Turning on this mode runs text-mode-hook and sindent-mode-hook."
- (interactive)
- (kill-all-local-variables)
- (use-local-map sindent-mode-map)
- (setq mode-name "Simple")
- (setq major-mode 'simple-indent-mode)
- (setq local-abbrev-table sindent-mode-abbrev-table)
- (set (make-local-variable 'indent-line-function) 'simple-indent-line)
- (set-syntax-table sindent-mode-syntax-table)
- (run-hooks 'text-mode-hook 'sindent-mode-hook))
-
- ;;; Indent this line to the previous line's indentation.
- (defun simple-indent-line ()
- "Indent current line like the previous line, provided that it is empty."
- (and (bolp)
- (eolp)
- (not (bobp))
- (indent-to
- (save-excursion
- (forward-line -1)
- (skip-chars-forward " \t")
- (current-column)))))
-
- ;;; Indent to the next tab stop, as defined by the tab-stop variable
- (defun simple-tab (arg)
- "Indent to the next tab-stop, as defined by the `tab-stop' variable."
- (interactive "P")
- (if arg
- (let ((count (prefix-numeric-value arg)))
- (and (< count 0)
- (error "Can't tab by negative amount"))
- (while (/= count 0)
- (simple-tab-1)
- (setq count (1- count))))
- (simple-tab-1)))
-
- ;;; Do a single tab.
- (defun simple-tab-1 ()
- "Perform a single simple tab."
- (if (or sindent-obey-all-tabs
- (save-excursion
- (skip-chars-backward " \t")
- (bolp)))
- (let (goal here)
- (skip-chars-forward " \t")
- (setq here (point))
- (setq goal (+ (- (current-column) left-margin) tab-stop))
- (setq goal (+ (- goal (% goal tab-stop)) left-margin))
- (skip-chars-backward " \t")
- (delete-region (point) here)
- (indent-to goal))
- (tab-to-tab-stop)))
-
- ;;; Delete backwards as (delete-backward-char), but if in indent only back
- ;;; to previous tab stop
- (defun sindent-backward-delete-char (arg &optional killp)
- "Delete charaters backward, obeying simple-indent's tab stops.
- Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
- Interactively, ARG is the prefix arg (default 1)
- and KILLP is t if prefix arg is was specified."
- (interactive "*p\nP")
- (let ((count arg)
- (del-count arg))
- (save-excursion
- (while (and (> count 0) (not (bobp)))
- (if (and (not (bolp))
- (save-excursion
- (skip-chars-backward " \t")
- (bolp)))
- (progn
- (and (= (preceding-char) ?\t)
- (let ((col (current-column)))
- (forward-char -1)
- (setq col (- col (current-column)))
- (insert-char ?\ col)
- (delete-char 1)))
- (if (= (current-column) left-margin)
- (progn
- (setq del-count (+ del-count left-margin -2))
- (forward-char (- (+ 2 left-margin))))
- (let ((cols (% (- (current-column) left-margin) tab-stop)))
- (and (= cols 0)
- (setq cols tab-stop))
- (forward-char (- cols))
- (setq del-count (+ del-count (1- cols))))))
- (forward-char -1))
- (setq count (1- count))))
- (delete-backward-char del-count killp)))
-
- (provide 'sindent)
-
-
-