From: Dmitry Gutov <dgutov@yandex.ru>
To: rms@gnu.org
Cc: monnier@iro.umontreal.ca, emacs-devel@gnu.org
Subject: Re: Exceptions for certain files in ELPA?
Date: Wed, 14 Mar 2018 00:47:00 +0200 [thread overview]
Message-ID: <7a322ec9-169f-fca2-f007-20e83f57558b@yandex.ru> (raw)
In-Reply-To: <E1evsEd-0000sX-F2@fencepost.gnu.org>
[-- Attachment #1: Type: text/plain, Size: 1100 bytes --]
On 3/14/18 12:17 AM, Richard Stallman wrote:
> [[[ To any NSA and FBI agents reading my email: please consider ]]]
> [[[ whether defending the US Constitution against all enemies, ]]]
> [[[ foreign or domestic, requires you to follow Snowden's example. ]]]
>
> Would you please email me mmm-noweb.el? I would like to see
> it before thinking about whether it can be an exception.
Please see the attachment.
> and reportedly still used by some
> people.
>
> Does this mean it is almost obsolete?
I've had to deal with a couple of bug reports regarding mmm-noweb in
2015, and resolved both more or less satisfactorily. So I'm guessing
there are people who still use it, and it won't really be obsolete until
Noweb goes away. I think it's still used at some universities.
> They are not very essential (we could release one or both separately),
> but have them to be exceptions would make my life simpler.
>
> I don't think we should make copyright exceptions for files that
> aren't really important to include.
Releasing it separately is still an option, indeed.
[-- Attachment #2: mmm-noweb.el --]
[-- Type: text/x-emacs-lisp, Size: 13702 bytes --]
;;; mmm-noweb.el --- MMM submode class for Noweb programs
;;
;; Copyright 2003, 2004, 2018 Joe Kelsey <joe@zircon.seattle.wa.us>
;;
;; The filling, completion and chunk motion commands either taken
;; directly from or inspired by code in:
;; noweb-mode.el - edit noweb files with GNU Emacs
;; Copyright 1995 by Thorsten.Ohl @ Physik.TH-Darmstadt.de
;; with a little help from Norman Ramsey <norman@bellcore.com>
;;
;;{{{ GPL
;; This file is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version.
;; This file is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GNU Emacs; see the file COPYING. If not, write to
;; the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
;; Boston, MA 02111-1307, USA.
;;}}}
;;; Commentary:
;; This file contains the definition of an MMM Mode submode class for
;; editing Noweb programs.
;;
;; FIXME: The more advanced features don't work: `mmm-name-at' and
;; `mmm-syntax-region' are undefined. Need to dig around in the bug reports
;; and/or discussions, wherever the code using them was submitted.
;;; Code:
(require 'cl-lib)
(require 'mmm-region)
(require 'mmm-vars)
(require 'mmm-mode)
;;{{{ Variables
(defvar mmm-noweb-code-mode 'fundamental-mode
"*Major mode for editing code chunks.
This is set to FUNDAMENTAL-MODE by default, but you might want to change
this in the Local Variables section of your file to something more
appropriate, like C-MODE, FORTRAN-MODE, or even INDENTED-TEXT-MODE.")
(defvar mmm-noweb-quote-mode nil
"*Major mode for quoted code chunks within documentation chunks.
If nil, defaults to `mmm-noweb-code-mode', which see.")
(defvar mmm-noweb-quote-string "quote"
"*String used to form quoted code submode region names.
See `mmm-noweb-quote'.")
(defvar mmm-noweb-quote-number 0
"*Starting value appended to `mmm-noweb-quote-string'.
See `mmm-noweb-quote'.")
(defvar mmm-noweb-narrowing nil
"*Narrow the region to the current pair of chunks.")
;;}}}
;;{{{ Support for mmm submode stuff
(defun mmm-noweb-chunk (form)
"Return the noweb code mode chosen by the user.
If the next 100 characters of the buffer contain a string of the form
\"-*- MODE -*-\", then return MODE as the chosen mode, otherwise
return the value of `mmm-noweb-code-mode'."
;; Look for -*- mode -*- in the first two lines.
;; 120 chars = 40 chars for #! + 80 chars for following line...
(if (re-search-forward "-\\*-\\s +\\(\\S-+\\)\\s +-\\*-" (+ (point) 120) t)
(let* ((string (match-string-no-properties 1))
(modestr (intern (if (string-match "mode\\'" string)
string
(concat string "-mode")))))
(or (mmm-ensure-modename modestr)
mmm-noweb-code-mode))
mmm-noweb-code-mode))
(defun mmm-noweb-quote (form)
"Create a unique name for a quoted code region within a documentation chunk."
(or mmm-noweb-quote-mode
mmm-noweb-code-mode))
(defun mmm-noweb-quote-name (form)
"Create a unique name for a quoted code region within a documentation chunk."
(setq mmm-noweb-quote-number (1+ mmm-noweb-quote-number))
(concat mmm-noweb-quote-string "-"
(number-to-string mmm-noweb-quote-number)))
(defun mmm-noweb-chunk-name (form)
"Get the chunk name from FRONT-FORM."
(string-match "<<\\(.*\\)>>=" form)
(match-string-no-properties 1 form))
;;}}}
;;{{{ mmm noweb submode group
;; We assume that the global document mode is latex or whatever, the
;; user wants. This class controls the code chunk submodes. We use
;; match-submode to either return the value in mmm-noweb-code-mode or to
;; look at the first line of the chunk for a submode setting. We reset
;; case-fold-search because chunk names are case sensitive. The front
;; string identifies the chunk name between the <<>>. Since this is
;; done, name-match can use the same functions as save-matches for back.
;; Our insert skeleton places a new code chunk and the skel-name lets us
;; optimize the skelton naming to use the inserted string.
(mmm-add-group
'noweb
'((noweb-chunk
:match-submode mmm-noweb-chunk
:case-fold-search nil
:front "^<<\\(.*\\)>>="
:match-name "~1"
:save-name 1
:front-offset (end-of-line 1)
:back "^@\\( \\|$\\|\\( %def .*$\\)\\)"
:insert ((?c noweb-code "Code Chunk Name: "
"\n" @ "<<" str ">>=" @ "\n" _ "\n" @ "@ " @ "\n"))
:skel-name t
)
(noweb-quote
:match-submode mmm-noweb-quote
:face mmm-special-submode-face
:front "\\[\\["
; :name-match mmm-noweb-quote-name
:back "\\]\\]"
:insert ((?q noweb-quote nil @ "[[" @ _ @ "]]" @))
)
))
;;}}}
;;{{{ Noweb regions
(defun mmm-noweb-regions (start stop regexp &optional delim)
"Return a liat of regions of the form \(NAME BEG END) that exclude
names which match REGEXP."
(let* ((remove-next nil)
(regions
(cl-maplist (lambda (pos-list)
(if (cdr pos-list)
(if remove-next
(setq remove-next nil)
(let ((name (or (mmm-name-at (car pos-list) 'beg)
(symbol-name mmm-primary-mode))))
(if (and regexp (string-match regexp name) )
(progn
(setq remove-next t)
nil)
(list name
(car pos-list) (cadr pos-list)))))))
(mmm-submode-changes-in start stop))))
;; The above loop leaves lots of nils in the list...
;; Removing them saves us from having to do the (last x 2)
;; trick that mmm-regions-in does.
(setq regions (delq nil regions))))
;;}}}
;;{{{ Filling, etc
(defun mmm-noweb-narrow-to-doc-chunk ()
"Narrow to the current doc chunk.
The current chunk includes all quoted code chunks (i.e., \[\[...\]\]).
This function is only valid when called with point in a doc chunk or
quoted code chunk."
(interactive)
(let ((name (mmm-name-at (point))))
(if (or (null name) (string-match "^quote" name))
(let ((prev (cond
((= (point) (point-min)) (point))
(t (cadar (last (mmm-noweb-regions (point-min) (point)
"^quote"))))))
(next (cond
((= (point) (point-max)) (point))
(t (save-excursion
(goto-char (cadr
(cadr (mmm-noweb-regions (point)
(point-max)
"^quote"))))
(forward-line -1)
(point))))))
(narrow-to-region prev next)))))
(defun mmm-noweb-fill-chunk (&optional justify)
"Fill the current chunk according to mode.
Run `fill-region' on documentation chunks and `indent-region' on code
chunks."
(interactive "P")
(save-restriction
(let ((name (mmm-name-at (point))))
(if (and name (not (string-match "^quote" name)))
(if (or indent-region-function indent-line-function)
(progn
(mmm-space-other-regions)
(indent-region (overlay-start mmm-current-overlay)
(overlay-end mmm-current-overlay) nil))
(error "No indentation functions defined in %s!" major-mode))
(progn
(mmm-word-other-regions)
(fill-paragraph justify)))
(mmm-undo-syntax-other-regions))))
(defun mmm-noweb-fill-paragraph-chunk (&optional justify)
"Fill a paragraph in the current chunk."
(interactive "P")
(save-restriction
(let ((name (mmm-name-at (point))))
(if (and name (not (string-match "^quote" name)))
(progn
(mmm-space-other-regions)
(fill-paragraph justify))
(progn
(mmm-word-other-regions)
(fill-paragraph justify)))
(mmm-undo-syntax-other-regions))))
(defun mmm-noweb-fill-named-chunk (&optional justify)
"Fill the region containing the named chunk."
(interactive "P")
(save-restriction
(let* ((name (or (mmm-name-at) (symbol-name mmm-primary-mode)))
(list (cdr (assoc name (mmm-names-alist (point-min) (point-max))))))
(if (or (string= name (symbol-name mmm-primary-mode))
(string-match "^quote" name))
(progn
(mmm-word-other-regions)
(do-auto-fill))
(progn
(mmm-space-other-regions)
(indent-region (caar list) (cadar (last list)) nil)))
(mmm-undo-syntax-other-regions))))
(defun mmm-noweb-auto-fill-doc-chunk ()
"Replacement for `do-auto-fill'."
(save-restriction
(mmm-noweb-narrow-to-doc-chunk)
(mmm-word-other-regions)
(do-auto-fill)
(mmm-undo-syntax-other-regions)))
(defun mmm-noweb-auto-fill-doc-mode ()
"Install the improved auto fill function, iff necessary."
(if auto-fill-function
(setq auto-fill-function 'mmm-noweb-auto-fill-doc-chunk)))
(defun mmm-noweb-auto-fill-code-mode ()
"Install the default auto fill function, iff necessary."
(if auto-fill-function
(setq auto-fill-function 'do-auto-fill)))
;;}}}
;;{{{ Functions on named chunks
(defun mmm-noweb-complete-chunk ()
"Try to complete the chunk name."
(interactive)
(let ((end (point))
(beg (save-excursion
(if (re-search-backward "<<"
(save-excursion
(beginning-of-line)
(point))
t)
(match-end 0)
nil))))
(if beg
(let* ((pattern (buffer-substring beg end))
(alist (mmm-names-alist (point-min) (point-max)))
(completion (try-completion pattern alist)))
(cond ((eq completion t))
((null completion)
(message "Can't find completion for \"%s\"" pattern)
(ding))
((not (string= pattern completion))
(delete-region beg end)
(insert completion)
(if (not (looking-at ">>"))
(insert ">>")))
(t
(message "Making completion list...")
(with-output-to-temp-buffer "*Completions*"
(display-completion-list
(all-completions pattern alist)))
(message "Making completion list...%s" "done"))))
(message "Not at chunk name..."))))
(defvar mmm-noweb-chunk-history nil
"History for `mmm-noweb-goto-chunk'.")
(defun mmm-noweb-goto-chunk ()
"Goto the named chunk."
(interactive)
(widen)
(let* ((completion-ignore-case t)
(alist (mmm-names-alist (point-min) (point-max)))
(chunk (completing-read
"Chunk: " alist nil t
(mmm-name-at (point))
mmm-noweb-chunk-history)))
(goto-char (caadr (assoc chunk alist)))))
(defun mmm-noweb-goto-next (&optional cnt)
"Goto the continuation of the current chunk."
(interactive "p")
(widen)
(let ((name (mmm-name-at (point))))
(if name
(let ((list (cdr (assoc name (mmm-names-alist
(overlay-end mmm-current-overlay)
(point-max))))))
(if list
(goto-char (caar (nthcdr (1- cnt) list))))))))
(defun mmm-noweb-goto-previous (&optional cnt)
"Goto the continuation of the current chunk."
(interactive "p")
(widen)
(let ((name (mmm-name-at (point))))
(if name
(let ((list (reverse
(cdr (assoc name
(mmm-names-alist (point-min)
(overlay-start
mmm-current-overlay)))))))
(if list
(goto-char (cadar (nthcdr cnt list))))))))
;;}}}
;;{{{ Key mappings
(defvar mmm-noweb-map (make-sparse-keymap))
(defvar mmm-noweb-prefix-map (make-sparse-keymap))
(define-key mmm-noweb-map mmm-mode-prefix-key mmm-noweb-prefix-map)
(mmm-define-key ?d 'mmm-noweb-narrow-to-doc-chunk mmm-noweb-prefix-map)
(mmm-define-key ?n 'mmm-noweb-goto-next mmm-noweb-prefix-map)
(mmm-define-key ?p 'mmm-noweb-goto-previous mmm-noweb-prefix-map)
(mmm-define-key ?q 'mmm-noweb-fill-chunk mmm-noweb-prefix-map)
;; Cannot use C-g as goto command, so use C-s.
(mmm-define-key ?s 'mmm-noweb-goto-chunk mmm-noweb-prefix-map)
(define-key mmm-noweb-prefix-map "\t" 'mmm-noweb-complete-chunk)
;; Don't want to add to either the mmm mode map (used in other mmm
;; buffers) or the local map (used in other major mode buffers), so we
;; make a full-buffer spanning overlay and add the map there.
(defun mmm-noweb-bind-keys ()
(save-restriction
(widen)
(let ((ovl (make-overlay (point-min) (point-max) nil nil t)))
;; 'keymap', not 'local-map'
(overlay-put ovl 'keymap mmm-noweb-map))))
(add-hook 'mmm-noweb-class-hook 'mmm-noweb-bind-keys)
;; TODO: make this overlay go away if mmm is turned off
;;}}}
;; These functions below living here temporarily until a real place is
;; found.
(defun mmm-syntax-region-list (syntax regions)
"Apply SYNTAX to a list of REGIONS of the form (BEG END).
If SYNTAX is not nil, set the syntax-table property of each region.
If SYNTAX is nil, remove the region syntax-table property.
See `mmm-syntax-region'."
(mapcar #'(lambda (reg)
(mmm-syntax-region (car reg) (cadr reg) syntax))
regions))
(defun mmm-syntax-other-regions (syntax &optional name)
"Apply SYNTAX cell to other regions.
Regions are separated by name, using either `mmm-name-at' or the
optional NAME to determine the current region name."
(if (null name)
(setq name (or (mmm-name-at)
(symbol-name mmm-primary-mode))))
(mapcar #'(lambda (reg)
(if (not (string= (car reg) name))
(mmm-syntax-region-list syntax (cdr reg))))
(mmm-names-alist (point-min) (point-max))))
(defun mmm-word-other-regions ()
"Give all other regions word syntax."
(interactive)
(mmm-syntax-other-regions '(2 . 0))
(setq parse-sexp-lookup-properties t))
(defun mmm-space-other-regions ()
"Give all other regions space syntax."
(interactive)
(mmm-syntax-other-regions '(0 . 0))
(setq parse-sexp-lookup-properties t))
(defun mmm-undo-syntax-other-regions ()
"Remove syntax-table property from other regions."
(interactive)
(mmm-syntax-other-regions nil)
(setq parse-sexp-lookup-properties nil))
(provide 'mmm-noweb)
;;; mmm-noweb.el ends here
next prev parent reply other threads:[~2018-03-13 22:47 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-03-12 21:47 Exceptions for certain files in ELPA? Dmitry Gutov
2018-03-13 0:56 ` Stefan Monnier
2018-03-13 4:36 ` Herring, Davis
2018-03-13 7:51 ` Dmitry Gutov
2018-03-13 22:17 ` Richard Stallman
2018-03-13 22:47 ` Dmitry Gutov [this message]
2018-03-13 23:09 ` Dmitry Gutov
2018-03-14 14:05 ` Richard Stallman
2018-03-14 16:37 ` Eli Zaretskii
2018-03-14 23:10 ` Richard Stallman
2018-03-14 21:02 ` Dmitry Gutov
2018-03-15 0:04 ` John Wiegley
2018-03-13 8:08 ` Dmitry Gutov
2018-03-13 13:03 ` Stefan Monnier
2018-03-13 14:42 ` Dmitry Gutov
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
List information: https://www.gnu.org/software/emacs/
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=7a322ec9-169f-fca2-f007-20e83f57558b@yandex.ru \
--to=dgutov@yandex.ru \
--cc=emacs-devel@gnu.org \
--cc=monnier@iro.umontreal.ca \
--cc=rms@gnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
Code repositories for project(s) associated with this public inbox
https://git.savannah.gnu.org/cgit/emacs.git
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).